first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-06-08 17:09:23 -04:00
commit df3a033196
17887 changed files with 8637778 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
<?php
/**
* @file classes/submission/Collector.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2000-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Collector
*
* @brief A helper class to configure a Query Builder to get a collection of submissions
*/
namespace APP\submission;
use APP\facades\Repo;
use Illuminate\Database\Query\Builder;
use PKP\doi\Doi;
class Collector extends \PKP\submission\Collector
{
public ?array $issueIds = null;
public ?array $sectionIds = null;
public function __construct(DAO $dao)
{
$this->dao = $dao;
}
/**
* Limit results to submissions assigned to these issues
*/
public function filterByIssueIds(array $issueIds): self
{
$this->issueIds = $issueIds;
return $this;
}
/**
* Limit results to submissions assigned to these sections
*/
public function filterBySectionIds(array $sectionIds): self
{
$this->sectionIds = $sectionIds;
return $this;
}
/**
* @copydoc CollectorInterface::getQueryBuilder()
*/
public function getQueryBuilder(): Builder
{
$q = parent::getQueryBuilder();
// By issue IDs
if (is_array($this->issueIds)) {
$q->whereIn('s.submission_id', function ($query) {
$query->select('issue_p.submission_id')
->from('publications AS issue_p')
->join('publication_settings as issue_ps', 'issue_p.publication_id', '=', 'issue_ps.publication_id')
->where('issue_ps.setting_name', '=', 'issueId')
->whereIn('issue_ps.setting_value', array_map('strval', $this->issueIds));
});
}
// By section IDs
if (is_array($this->sectionIds)) {
$q->whereIn('s.submission_id', function ($query) {
$query->select('section_p.submission_id')
->from('publications AS section_p')
->whereIn('section_p.section_id', $this->sectionIds);
});
}
return $q;
}
/**
* Add APP-specific filtering methods for submission sub objects DOI statuses
*
*
*/
protected function addDoiStatusFilterToQuery(Builder $q)
{
$q->whereIn('s.current_publication_id', function (Builder $q) {
$q->select('current_p.publication_id')
->from('publications as current_p')
->leftJoin('publication_galleys as current_g', 'current_g.publication_id', '=', 'current_p.publication_id')
->leftJoin('dois as pd', 'pd.doi_id', '=', 'current_p.doi_id')
->leftJoin('dois as gd', 'gd.doi_id', '=', 'current_g.doi_id')
->whereIn('pd.status', $this->doiStatuses)
->orWhereIn('gd.status', $this->doiStatuses);
});
}
/**
* Add APP-specific filtering methods for checking if submission sub objects have DOIs assigned
*/
protected function addHasDoisFilterToQuery(Builder $q)
{
$q->whereIn('s.current_publication_id', function (Builder $q) {
$q->select('current_p.publication_id')
->from('publications', 'current_p')
->leftJoin('submissions as current_s', 'current_s.current_publication_id', '=', 'current_p.publication_id')
->leftJoin('publication_galleys as current_g', 'current_g.publication_id', '=', 'current_p.publication_id')
->where(function (Builder $q) {
$q->when($this->hasDois === true, function (Builder $q) {
$q->when(in_array(Repo::doi()::TYPE_PUBLICATION, $this->enabledDoiTypes), function (Builder $q) {
$q->whereNotNull('current_p.doi_id');
});
$q->when(in_array(Repo::doi()::TYPE_REPRESENTATION, $this->enabledDoiTypes), function (Builder $q) {
$q->orWhereNotNull('current_g.doi_id');
});
});
$q->when($this->hasDois === false, function (Builder $q) {
$q->when(in_array(Repo::doi()::TYPE_PUBLICATION, $this->enabledDoiTypes), function (Builder $q) {
$q->whereNull('current_p.doi_id');
});
$q->when(in_array(Repo::doi()::TYPE_REPRESENTATION, $this->enabledDoiTypes), function (Builder $q) {
$q->orWhere(function (Builder $q) {
$q->whereNull('current_g.doi_id');
$q->whereNotNull('current_g.galley_id');
});
});
});
});
});
}
}
+106
View File
@@ -0,0 +1,106 @@
<?php
/**
* @file classes/submission/DAO.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2000-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class DAO
*
* @brief Read and write submissions to the database.
*/
namespace APP\submission;
use PKP\db\DAOResultFactory;
use PKP\db\DBResultRange;
use PKP\identity\Identity;
use PKP\observers\events\SubmissionDeleted;
class DAO extends \PKP\submission\DAO
{
/**
* @copydoc \PKP\core\EntityDAO::deleteById()
*/
public function deleteById(int $id)
{
event(new SubmissionDeleted($id));
parent::deleteById($id);
}
/**
* Get all published submissions (eventually with a pubId assigned and) matching the specified settings.
*
* @param null|mixed $pubIdType
* @param null|mixed $title
* @param null|mixed $author
* @param null|mixed $issueId
* @param null|mixed $pubIdSettingName
* @param null|mixed $pubIdSettingValue
* @param ?DBResultRange $rangeInfo
*
* @return DAOResultFactory<Submission>
*/
public function getExportable(
$contextId,
$pubIdType = null,
$title = null,
$author = null,
$issueId = null,
$pubIdSettingName = null,
$pubIdSettingValue = null,
$rangeInfo = null
) {
$params = [];
if ($pubIdSettingName) {
$params[] = $pubIdSettingName;
}
$params[] = Submission::STATUS_PUBLISHED;
$params[] = $contextId;
if ($pubIdType) {
$params[] = 'pub-id::' . $pubIdType;
}
if ($title) {
$params[] = 'title';
$params[] = '%' . $title . '%';
}
if ($author) {
$params[] = $author;
$params[] = $author;
}
if ($issueId) {
$params[] = $issueId;
}
if ($pubIdSettingName && $pubIdSettingValue && $pubIdSettingValue != EXPORT_STATUS_NOT_DEPOSITED) {
$params[] = $pubIdSettingValue;
}
$sql = 'SELECT s.*
FROM submissions s
LEFT JOIN publications p ON s.current_publication_id = p.publication_id
LEFT JOIN publication_settings ps ON p.publication_id = ps.publication_id'
. ($issueId ? ' LEFT JOIN publication_settings psi ON p.publication_id = psi.publication_id AND psi.setting_name = \'issueId\' AND psi.locale = \'\'' : '')
. ($pubIdType != null ? ' LEFT JOIN publication_settings pspidt ON (p.publication_id = pspidt.publication_id)' : '')
. ($title != null ? ' LEFT JOIN publication_settings pst ON (p.publication_id = pst.publication_id)' : '')
. ($author != null ? ' LEFT JOIN authors au ON (p.publication_id = au.publication_id)
LEFT JOIN author_settings asgs ON (asgs.author_id = au.author_id AND asgs.setting_name = \'' . Identity::IDENTITY_SETTING_GIVENNAME . '\')
LEFT JOIN author_settings asfs ON (asfs.author_id = au.author_id AND asfs.setting_name = \'' . Identity::IDENTITY_SETTING_FAMILYNAME . '\')
' : '')
. ($pubIdSettingName != null ? ' LEFT JOIN submission_settings pss ON (s.submission_id = pss.submission_id AND pss.setting_name = ?)' : '')
. ' WHERE s.status = ?
AND s.context_id = ?'
. ($pubIdType != null ? ' AND pspidt.setting_name = ? AND pspidt.setting_value IS NOT NULL' : '')
. ($title != null ? ' AND (pst.setting_name = ? AND pst.setting_value LIKE ?)' : '')
. ($author != null ? ' AND (asgs.setting_value LIKE ? OR asfs.setting_value LIKE ?)' : '')
. ($issueId != null ? ' AND psi.setting_value = ?' : '')
. (($pubIdSettingName != null && $pubIdSettingValue != null && $pubIdSettingValue == EXPORT_STATUS_NOT_DEPOSITED) ? ' AND pss.setting_value IS NULL' : '')
. (($pubIdSettingName != null && $pubIdSettingValue != null && $pubIdSettingValue != EXPORT_STATUS_NOT_DEPOSITED) ? ' AND pss.setting_value = ?' : '')
. (($pubIdSettingName != null && is_null($pubIdSettingValue)) ? ' AND (pss.setting_value IS NULL OR pss.setting_value = \'\')' : '')
. ' GROUP BY s.submission_id
ORDER BY MAX(p.date_published) DESC, s.submission_id DESC';
$rows = $this->deprecatedDao->retrieveRange($sql, $params, $rangeInfo);
return new DAOResultFactory($rows, $this, 'fromRow', [], $sql, $params, $rangeInfo);
}
}
+180
View File
@@ -0,0 +1,180 @@
<?php
/**
* @file classes/submission/Repository.php
*
* Copyright (c) 2014-2021 Simon Fraser University
* Copyright (c) 2000-2021 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Repository
*
* @brief A repository to find and manage submissions.
*/
namespace APP\submission;
use APP\article\ArticleTombstoneManager;
use APP\core\Services;
use APP\facades\Repo;
use APP\journal\JournalDAO;
use APP\section\Section;
use PKP\context\Context;
use PKP\core\PKPString;
use PKP\db\DAORegistry;
use PKP\doi\exceptions\DoiException;
use PKP\tombstone\DataObjectTombstoneDAO;
class Repository extends \PKP\submission\Repository
{
/** @copydoc \PKP\submission\Repository::$schemaMap */
public $schemaMap = maps\Schema::class;
/**
* Get submissions ordered by section id
*
* @return array [int $sectionId => [?Submission, ...]]
*/
public function getInSections(int $issueId, int $contextId): array
{
$submissions = $this->getCollector()
->filterByContextIds([$contextId])
->filterByIssueIds([$issueId])
->filterByStatus([Submission::STATUS_PUBLISHED, Submission::STATUS_SCHEDULED])
->orderBy(Collector::ORDERBY_SEQUENCE, Collector::ORDER_DIR_ASC)
->getMany();
$bySections = [];
foreach ($submissions as $submission) {
$sectionId = $submission->getCurrentPublication()->getData('sectionId');
if (empty($bySections[$sectionId])) {
$section = Repo::section()->get($sectionId);
$bySections[$sectionId] = [
'articles' => [],
'title' => $section->getData('hideTitle') ? '' : $section->getLocalizedData('title'),
'abstractsNotRequired' => $section->getData('abstractsNotRequired'),
'hideAuthor' => $section->getData('hideAuthor'),
];
}
$bySections[$sectionId]['articles'][] = $submission;
}
return $bySections;
}
public function validateSubmit(Submission $submission, Context $context): array
{
$errors = parent::validateSubmit($submission, $context);
$locale = $submission->getData('locale');
$publication = $submission->getCurrentPublication();
$section = Repo::section()->get($submission->getCurrentPublication()->getData('sectionId'), $context->getId());
// Required abstract
if (!$section->getAbstractsNotRequired() && !$publication->getData('abstract', $locale)) {
$errors['abstract'] = [$locale => [__('validator.required')]];
}
// Abstract word limit
if ($section->getAbstractWordCount()) {
$abstracts = $publication->getData('abstract');
if ($abstracts) {
$abstractErrors = [];
foreach ($context->getSupportedSubmissionLocales() as $localeKey) {
$abstract = $publication->getData('abstract', $localeKey);
$wordCount = $abstract ? PKPString::getWordCount($abstract) : 0;
if ($wordCount > $section->getAbstractWordCount()) {
$abstractErrors[$localeKey] = [
__(
'publication.wordCountLong',
[
'limit' => $section->getAbstractWordCount(),
'count' => $wordCount
]
)
];
}
}
if (count($abstractErrors)) {
$errors['abstract'] = $abstractErrors;
}
}
}
return $errors;
}
public function updateStatus(Submission $submission, ?int $newStatus = null, ?Section $section = null)
{
$oldStatus = $submission->getData('status');
parent::updateStatus($submission, $newStatus, $section);
$newStatus = $submission->getData('status');
// Add or remove tombstones when submission is published or unpublished
if ($newStatus === Submission::STATUS_PUBLISHED && $newStatus !== $oldStatus) {
$tombstoneDao = DAORegistry::getDAO('DataObjectTombstoneDAO'); /** @var DataObjectTombstoneDAO $tombstoneDao */
$tombstoneDao->deleteByDataObjectId($submission->getId());
} elseif ($oldStatus === Submission::STATUS_PUBLISHED && $newStatus !== $oldStatus) {
$requestContext = $this->request->getContext();
if ($requestContext && $requestContext->getId() === $submission->getData('contextId')) {
$context = $requestContext;
} else {
$context = Services::get('context')->get($submission->getData('contextId'));
}
$articleTombstoneManager = new ArticleTombstoneManager();
if (!$section) {
$section = Repo::section()->get($submission->getCurrentPublication()->getData('sectionId'), $submission->getData('contextId'));
}
$articleTombstoneManager->insertArticleTombstone($submission, $context, $section);
}
}
/**
* Creates and assigns DOIs to all sub-objects if:
* 1) the suffix pattern can currently be created, and
* 2) it does not already exist.
*
*
* @throws \Exception
*/
public function createDois(Submission $submission): array
{
/** @var JournalDAO $contextDao */
$contextDao = DAORegistry::getDAO('JournalDAO');
$context = $contextDao->getById($submission->getData('contextId'));
// Article
$publication = $submission->getCurrentPublication();
$doiCreationFailures = [];
if ($context->isDoiTypeEnabled(Repo::doi()::TYPE_PUBLICATION) && empty($publication->getData('doiId'))) {
try {
$doiId = Repo::doi()->mintPublicationDoi($publication, $submission, $context);
Repo::publication()->edit($publication, ['doiId' => $doiId]);
} catch (DoiException $exception) {
$doiCreationFailures[] = $exception;
}
}
// Galleys
if ($context->isDoiTypeEnabled(Repo::doi()::TYPE_REPRESENTATION)) {
$galleys = Repo::galley()->getCollector()
->filterByPublicationIds(['publicationIds' => $publication->getId()])
->getMany();
foreach ($galleys as $galley) {
if (empty($galley->getData('doiId'))) {
try {
$doiId = Repo::doi()->mintGalleyDoi($galley, $publication, $submission, $context);
Repo::galley()->edit($galley, ['doiId' => $doiId]);
} catch (DoiException $exception) {
$doiCreationFailures[] = $exception;
}
}
}
}
return $doiCreationFailures;
}
}
+262
View File
@@ -0,0 +1,262 @@
<?php
/**
* @defgroup submission Submission
* Articles, OJS's extension of the generic Submission class in lib-pkp, are
* implemented here.
*/
/**
* @file classes/submission/Submission.php
*
* Copyright (c) 2014-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 Submission
*
* @ingroup submission
*
* @see DAO
*
* @brief Article class.
*/
namespace APP\submission;
use APP\core\Services;
use APP\facades\Repo;
use APP\publication\Publication;
use PKP\facades\Locale;
use PKP\submission\PKPSubmission;
class Submission extends PKPSubmission
{
// Author display in ToC
public const AUTHOR_TOC_DEFAULT = 0;
public const AUTHOR_TOC_HIDE = 1;
public const AUTHOR_TOC_SHOW = 2;
// Article access constants -- see Publication::getData('accessStatus')
public const ARTICLE_ACCESS_ISSUE_DEFAULT = 0;
public const ARTICLE_ACCESS_OPEN = 1;
//
// Get/set methods
//
/**
* Get the value of a license field from the containing context.
*
* @param string $locale Locale code
* @param int $field PERMISSIONS_FIELD_...
* @param Publication $publication
*
* @return string|array|null
*/
public function _getContextLicenseFieldValue($locale, $field, $publication = null)
{
$context = Services::get('context')->get($this->getData('contextId'));
$fieldValue = null; // Scrutinizer
switch ($field) {
case self::PERMISSIONS_FIELD_LICENSE_URL:
$fieldValue = $context->getData('licenseUrl');
break;
case self::PERMISSIONS_FIELD_COPYRIGHT_HOLDER:
switch ($context->getData('copyrightHolderType')) {
case 'author':
// Override based on context settings
if (!$publication) {
$publication = $this->getCurrentPublication();
}
$authorUserGroups = Repo::userGroup()->getCollector()->filterByRoleIds([\PKP\security\Role::ROLE_ID_AUTHOR])->filterByContextIds([$context->getId()])->getMany();
$fieldValue = [$context->getPrimaryLocale() => $publication->getAuthorString($authorUserGroups)];
break;
case 'context':
case null:
$fieldValue = $context->getName(null);
break;
default:
$fieldValue = $context->getData('copyrightHolderOther');
break;
}
break;
case self::PERMISSIONS_FIELD_COPYRIGHT_YEAR:
// Default copyright year to current year
$fieldValue = date('Y');
// Override based on context settings
if (!$publication) {
$publication = $this->getCurrentPublication();
}
if ($publication) {
switch ($context->getData('copyrightYearBasis')) {
case 'submission':
// override to the submission's year if published as you go
$fieldValue = date('Y', strtotime($publication->getData('datePublished')));
break;
case 'issue':
if ($publication->getData('issueId')) {
// override to the issue's year if published as issue-based
$issue = Repo::issue()->get($publication->getData('issueId'));
if ($issue && $issue->getDatePublished()) {
$fieldValue = date('Y', strtotime($issue->getDatePublished()));
}
}
break;
default: assert(false);
}
}
break;
default: assert(false);
}
// Return the fetched license field
if ($locale === null) {
return $fieldValue;
}
if (isset($fieldValue[$locale])) {
return $fieldValue[$locale];
}
return null;
}
/**
* @see PKPSubmission::getBestId()
* @deprecated 3.2.0.0
*
* @return string
*/
public function getBestArticleId()
{
return parent::getBestId();
}
/**
* Get ID of journal.
*
* @deprecated 3.2.0.0
*
* @return int
*/
public function getJournalId()
{
return $this->getData('contextId');
}
/**
* Set ID of journal.
*
* @deprecated 3.2.0.0
*
* @param int $journalId
*/
public function setJournalId($journalId)
{
return $this->setData('contextId', $journalId);
}
/**
* Get ID of article's section.
*
* @return int
*/
public function getSectionId()
{
$publication = $this->getCurrentPublication();
if (!$publication) {
return 0;
}
return $publication->getData('sectionId');
}
/**
* Set ID of article's section.
*
* @param int $sectionId
*/
public function setSectionId($sectionId)
{
$publication = $this->getCurrentPublication();
if ($publication) {
$publication->setData('sectionId', $sectionId);
}
}
/**
* Get the galleys for an article.
*
* @return array Galley
*
* @deprecated 3.2.0.0
*/
public function getGalleys()
{
if (!is_null($this->getData('galleys'))) {
return $this->getData('galleys');
}
$this->setData(
'galleys',
Repo::galley()->getCollector()
->filterByPublicationIds([$this->getData('currentPublicationId')])
->getMany()
->toArray()
);
return $this->getData('galleys');
}
/**
* Get the localized galleys for an article.
*
* @return array Galley
*
* @deprecated 3.2.0.0
*/
public function getLocalizedGalleys()
{
$allGalleys = $this->getGalleys();
$galleys = [];
foreach ([Locale::getLocale(), Locale::getPrimaryLocale()] as $tryLocale) {
foreach (array_keys($allGalleys) as $key) {
if ($allGalleys[$key]->getLocale() == $tryLocale) {
$galleys[] = $allGalleys[$key];
}
}
}
return $galleys;
}
/**
* Return option selection indicating if author should be hidden in issue ToC.
*
* @return int AUTHOR_TOC_...
*
* @deprecated 3.2.0.0
*/
public function getHideAuthor()
{
$publication = $this->getCurrentPublication();
if (!$publication) {
return 0;
}
return $publication->getData('hideAuthor');
}
}
if (!PKP_STRICT_MODE) {
class_alias('\APP\submission\Submission', '\Submission');
foreach ([
'AUTHOR_TOC_DEFAULT',
'AUTHOR_TOC_HIDE',
'AUTHOR_TOC_SHOW',
'ARTICLE_ACCESS_ISSUE_DEFAULT',
'ARTICLE_ACCESS_OPEN',
] as $constantName) {
define($constantName, constant('\Submission::' . $constantName));
}
}
+45
View File
@@ -0,0 +1,45 @@
<?php
/**
* @file classes/submission/maps/Schema.php
*
* Copyright (c) 2014-2020 Simon Fraser University
* Copyright (c) 2000-2020 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Schema
*
* @brief Map submissions to the properties defined in the submission schema
*/
namespace APP\submission\maps;
use APP\core\Application;
use APP\submission\Submission;
class Schema extends \PKP\submission\maps\Schema
{
/**
* @copydoc \PKP\submission\maps\Schema::mapByProperties()
*/
protected function mapByProperties(array $props, Submission $submission): array
{
$output = parent::mapByProperties($props, $submission);
if (in_array('urlPublished', $props)) {
$output['urlPublished'] = $this->request->getDispatcher()->url(
$this->request,
Application::ROUTE_PAGE,
$this->context->getPath(),
'article',
'view',
$submission->getBestId()
);
}
$output = $this->schemaService->addMissingMultilingualValues($this->schemaService::SCHEMA_SUBMISSION, $output, $this->context->getSupportedSubmissionLocales());
ksort($output);
return $this->withExtensions($output, $submission);
}
}
@@ -0,0 +1,40 @@
<?php
/**
* @file classes/submission/reviewer/form/ReviewerReviewStep3Form.php
*
* Copyright (c) 2014-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 ReviewerReviewStep3Form
*
* @ingroup submission_reviewer_form
*
* @brief Form for Step 3 of a review in OJS.
*/
namespace APP\submission\reviewer\form;
use APP\submission\Submission;
use PKP\core\PKPRequest;
use PKP\submission\reviewAssignment\ReviewAssignment;
use PKP\submission\reviewer\form\PKPReviewerReviewStep3Form;
class ReviewerReviewStep3Form extends PKPReviewerReviewStep3Form
{
/**
* @copydoc PKPReviewerReviewStep3Form::__construct()
*/
public function __construct(PKPRequest $request, Submission $reviewSubmission, ReviewAssignment $reviewAssignment)
{
parent::__construct($request, $reviewSubmission, $reviewAssignment);
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'recommendation', 'required', 'reviewer.submission.reviewFormResponse.form.recommendationRequired', function ($recommendation) {
return isset($recommendation);
}));
}
}
if (!PKP_STRICT_MODE) {
class_alias('\APP\submission\reviewer\form\ReviewerReviewStep3Form', '\ReviewerReviewStep3Form');
}