Files
CHIEFSOFT\ameye df3a033196 first commit
2024-06-08 17:09:23 -04:00

439 lines
13 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* @file classes/publication/PKPPublication.php
*
* Copyright (c) 2016-2021 Simon Fraser University
* Copyright (c) 2003-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPPublication
*
* @ingroup publication
*
* @see DAO
*
* @brief Base class for Publication.
*/
namespace PKP\publication;
use APP\author\Author;
use APP\facades\Repo;
use PKP\core\Core;
use PKP\core\PKPString;
use PKP\facades\Locale;
use PKP\userGroup\UserGroup;
class PKPPublication extends \PKP\core\DataObject
{
/**
* Get the default/fall back locale the values should exist for
*/
public function getDefaultLocale(): ?string
{
return $this->getData('locale');
}
/**
* Combine the localized title, prefix and subtitle
*
* @param string $preferredLocale Override the publication's default locale and return the title in a specified locale.
* @param string $format Define the return data format as text or html
*
* @return string
*/
public function getLocalizedFullTitle($preferredLocale = null, string $format = 'text')
{
$fullTitle = $this->getLocalizedTitle($preferredLocale, $format);
$subtitle = $this->getLocalizedSubTitle($preferredLocale, $format);
if ($subtitle) {
return PKPString::concatTitleFields([$fullTitle, $subtitle]);
}
return $fullTitle;
}
/**
* Return the combined prefix, title and subtitle for all locales
*
* @param string $format Define the return data format as text or html
*
* @return array
*/
public function getFullTitles(string $format = 'text')
{
$allTitles = (array) $this->getData('title');
$return = [];
foreach ($allTitles as $locale => $title) {
if (!$title) {
continue;
}
$return[$locale] = $this->getLocalizedFullTitle($locale, $format);
}
return $return;
}
/**
* Combine the localized title and prefix
*
* @param string $preferredLocale Override the publication's default locale and return the title in a specified locale.
* @param string $format Define the return data format as text or html
*
* @return string
*/
public function getLocalizedTitle($preferredLocale = null, string $format = 'text')
{
$usedLocale = null;
$title = $this->getLocalizedData('title', $preferredLocale, $usedLocale);
$prefix = $this->getData('prefix', $usedLocale);
switch (strtolower($format)) {
case 'html':
// Title is already in HTML, prefix is in text. Convert prefix.
if ($prefix) {
$prefix = htmlspecialchars($prefix);
}
break;
case 'text':
// Title is in HTML, prefix is already in text. Convert title.
$title = strip_tags($title);
break;
default: throw new \Exception('Invalid format!');
}
if ($prefix) {
$title = $prefix . ' ' . $title;
}
return $title;
}
/**
* Get the localized sub title
*
* @param string $preferredLocale Override the publication's default locale and return the title in a specified locale.
* @param string $format Define the return data format as text or html
*
* @return string
*/
public function getLocalizedSubTitle($preferredLocale = null, string $format = 'text')
{
$subTitle = $this->getLocalizedData('subtitle', $preferredLocale);
if ($subTitle) {
return strtolower($format) === 'text' ? strip_tags($subTitle) : $subTitle;
}
return '';
}
/**
* Return the combined title and prefix for all locales
*
* @param string $format Define the return data format as text or html
*
* @return array
*/
public function getTitles(string $format = 'text')
{
$allTitles = $this->getData('title');
$return = [];
foreach ($allTitles as $locale => $title) {
if (!$title) {
continue;
}
$return[$locale] = $this->getLocalizedTitle($locale, $format);
}
return $return;
}
/**
* Return all the sub titles
*
* @param string $format Define the return data format as text or html
*
* @return array
*/
public function getSubTitles(string $format = 'text')
{
$allSubTitles = $this->getData('subtitle');
$return = [];
foreach ($allSubTitles ?? [] as $locale => $subTitle) {
if (!$subTitle) {
continue;
}
$return[$locale] = $this->getLocalizedSubTitle($locale, $format);
}
return $return;
}
/**
* Combine author names and roles into a string
*
* Eg - Daniel Barnes, Carlo Corino (Author); Alan Mwandenga (Translator)
*
* @param \Traversable<UserGroup> $userGroups List of UserGroup objects
* @param bool $includeInBrowseOnly true if only the includeInBrowse Authors will be contained
*
* @return string
*/
public function getAuthorString(\Traversable $userGroups, $includeInBrowseOnly = false)
{
$authors = $this->getData('authors');
if (empty($authors)) {
return '';
}
if ($includeInBrowseOnly) {
$authors = $authors->filter(function ($author, $key) {
return $author->getData('includeInBrowse');
});
}
$str = '';
$lastUserGroupId = null;
foreach ($authors as $author) {
if (!empty($str)) {
if ($lastUserGroupId != $author->getData('userGroupId')) {
foreach ($userGroups as $userGroup) {
if ($lastUserGroupId === $userGroup->getId()) {
if ($userGroup->getData('showTitle')) {
$str .= ' (' . $userGroup->getLocalizedData('name') . ')';
}
break;
}
}
$str .= __('common.semicolonListSeparator');
} else {
$str .= __('common.commaListSeparator');
}
}
$str .= $author->getFullName();
$lastUserGroupId = $author->getUserGroupId();
}
// If there needs to be a trailing user group title, add it
if (isset($author)) {
foreach ($userGroups as $userGroup) {
if ($author->getData('userGroupId') === $userGroup->getId()) {
if ($userGroup->getData('showTitle')) {
$str .= ' (' . $userGroup->getLocalizedData('name') . ')';
}
break;
}
}
}
return $str;
}
/**
* Combine the author names into a shortened string
*
* Eg - Barnes, et al.
*
* @param string|null $defaultLocale
*
* @return string
*/
public function getShortAuthorString($defaultLocale = null)
{
$authors = $this->getData('authors');
if (!$authors->count()) {
return '';
}
$firstAuthor = $authors->first();
$str = $firstAuthor->getLocalizedData('familyName', $defaultLocale);
if (!$str) {
$str = $firstAuthor->getLocalizedData('givenName', $defaultLocale);
}
if ($authors->count() > 1) {
return __('submission.shortAuthor', ['author' => $str], $defaultLocale);
}
return $str;
}
/**
* Get the primary contact
*
* @return Author|null
*/
public function getPrimaryAuthor()
{
if (empty($this->getData('authors'))) {
return null;
}
foreach ($this->getData('authors') as $author) {
if ($author->getId() === $this->getData('primaryContactId')) {
return $author;
}
}
}
/**
* Stamp the date of the last modification to the current time.
*/
public function stampModified()
{
return $this->setData('lastModified', Core::getCurrentDate());
}
/**
* Get the starting page of this publication
*
* Note the return type of string - this is not to be used for
* page counting.
*
* @return string
*/
public function getStartingPage()
{
$ranges = $this->getPageArray();
$firstRange = array_shift($ranges);
if (is_array($firstRange)) {
return array_shift($firstRange);
}
return '';
}
/**
* Get ending page of a this publication
*
* Note the return type of string - this is not to be used for
* page counting.
*
* @return string
*/
public function getEndingPage()
{
$ranges = $this->getPageArray();
$lastRange = array_pop($ranges);
$lastPage = is_array($lastRange) ? array_pop($lastRange) : '';
return $lastPage ?? '';
}
/**
* Get pages converted to a nested array of page ranges
*
* For example, pages of "pp. ii-ix, 9,15-18,a2,b2-b6" will return:
*
* [
* ['ii', 'ix'],
* ['9'],
* ['15', '18'],
* ['a2'],
* ['b2', 'b6'],
* ]
*
* @return array
*/
public function getPageArray()
{
$pages = $this->getData('pages') ?? '';
// Strip any leading word
if (preg_match('/^[[:alpha:]]+\W/', $pages)) {
// but don't strip a leading roman numeral
if (!preg_match('/^[MDCLXVUI]+\W/i', $pages)) {
// strip the word or abbreviation, including the period or colon
$pages = preg_replace('/^[[:alpha:]]+[:.]?/', '', $pages);
}
}
// strip leading and trailing space
$pages = trim($pages);
// shortcut the explode/foreach if the remainder is an empty value
if ($pages === '') {
return [];
}
// commas indicate distinct ranges
$ranges = explode(',', $pages);
$pageArray = [];
foreach ($ranges as $range) {
// hyphens (or double-hyphens) indicate range spans
$pageArray[] = array_map('trim', explode('-', str_replace(['--', ''], '-', $range), 2));
}
return $pageArray;
}
/**
* Is the license for copyright on this publication a Creative Commons license?
*
* @return bool
*/
public function isCCLicense()
{
return preg_match('/creativecommons\.org/i', $this->getData('licenseUrl'));
}
/**
* Helper method to fetch current DOI
*
*/
public function getDoi(): ?string
{
$doiObject = $this->getData('doiObject');
if (empty($doiObject)) {
return null;
} else {
return $doiObject->getData('doi');
}
}
/**
* Get stored public ID of the publication
*
* This helper function is required by PKPPubIdPlugins.
* NB: To maintain backwards compatability, getDoi() is called from here
*
* @see Submission::getStoredPubId()
*/
public function getStoredPubId($pubIdType)
{
if ($pubIdType === 'doi') {
return $this->getDoi();
} else {
return $this->getData('pub-id::' . $pubIdType);
}
}
/**
* Set stored public issue id.
*
* @param string $pubIdType One of the NLM pub-id-type values or
* 'other::something' if not part of the official NLM list
* (see <http://dtd.nlm.nih.gov/publishing/tag-library/n-4zh0.html>).
* @param string $pubId
*/
public function setStoredPubId($pubIdType, $pubId)
{
if ($pubIdType == 'doi') {
if ($doiObject = $this->getData('doiObject')) {
Repo::doi()->edit($doiObject, ['doi' => $pubId]);
} else {
$newDoiObject = Repo::doi()->newDataObject(
[
'doi' => $pubId,
'contextId' => Repo::submission()->get($this->getData('submissionId'))->getData('contextId')
]
);
$doiId = Repo::doi()->add($newDoiObject);
$this->setData('doiId', $doiId);
}
} else {
$this->setData('pub-id::' . $pubIdType, $pubId);
}
}
}
if (!PKP_STRICT_MODE) {
class_alias('\PKP\publication\PKPPublication', '\PKPPublication');
}