[ Mini Kiebo ]
Server: Windows NT DESKTOP-5B8S0D4 6.2 build 9200 (Windows 8 Professional Edition) i586
Path:
D:
/
Backup
/
14082024
/
Data
/
htdocs
/
htdocs
/
jurnal-kesmas
/
lib
/
pkp
/
classes
/
submission
/
[
Home
]
File: Repository.php
<?php /** * @file classes/submission/Repository.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 Repository * * @brief A repository to find and manage submissions. */ namespace PKP\submission; use APP\author\Author; use APP\core\Application; use APP\core\Request; use APP\core\Services; use APP\facades\Repo; use APP\publication\Publication; use APP\section\Section; use APP\submission\Collector; use APP\submission\DAO; use APP\submission\Submission; use Illuminate\Support\Enumerable; use Illuminate\Support\LazyCollection; use PKP\context\Context; use PKP\core\Core; use PKP\db\DAORegistry; use PKP\doi\exceptions\DoiException; use PKP\facades\Locale; use PKP\observers\events\SubmissionSubmitted; use PKP\plugins\Hook; use PKP\query\QueryDAO; use PKP\security\Role; use PKP\security\RoleDAO; use PKP\services\PKPSchemaService; use PKP\stageAssignment\StageAssignmentDAO; use PKP\submission\reviewAssignment\ReviewAssignmentDAO; use PKP\submissionFile\SubmissionFile; use PKP\user\User; use PKP\validation\ValidatorFactory; abstract class Repository { public const STAGE_STATUS_SUBMISSION_UNASSIGNED = 1; /** @var DAO $dao */ public $dao; /** @var string $schemaMap The name of the class to map this entity to its schema */ public $schemaMap = maps\Schema::class; /** @var Request $request */ protected $request; /** @var PKPSchemaService<Submission> $schemaService */ protected $schemaService; public function __construct(DAO $dao, Request $request, PKPSchemaService $schemaService) { $this->dao = $dao; $this->request = $request; $this->schemaService = $schemaService; } /** @copydoc DAO::newDataObject() */ public function newDataObject(array $params = []): Submission { $object = $this->dao->newDataObject(); if (!empty($params)) { $object->setAllData($params); } return $object; } /** @copydoc DAO::exists() */ public function exists(int $id, int $contextId = null): bool { return $this->dao->exists($id, $contextId); } /** @copydoc DAO::get() */ public function get(int $id, int $contextId = null): ?Submission { return $this->dao->get($id, $contextId); } /** @copydoc DAO::getCollector() */ public function getCollector(): Collector { return app(Collector::class); } /** * Get an instance of the map class for mapping * submissions to their schema */ public function getSchemaMap(): maps\Schema { return app('maps')->withExtensions($this->schemaMap); } /** * Get a submission by "best" submission id -- url path if it exists, * falling back on the internal submission ID otherwise. */ public function getByBestId(string $idOrUrlPath, int $contextId = null): ?Submission { return ctype_digit((string) $idOrUrlPath) ? $this->get((int) $idOrUrlPath, $contextId) : $this->getByUrlPath($idOrUrlPath, $contextId); } /** * Get a submission by its urlPath * * This returns a submission if any of its publications have a * matching urlPath. */ public function getByUrlPath(string $urlPath, int $contextId): ?Submission { $submissionId = $this->dao->getIdByUrlPath($urlPath, $contextId); return $submissionId ? $this->get($submissionId) : null; } /** * Gets a submission by its current publication's DOI * * */ public function getByDoi(string $doi, int $contextId): ?Submission { return $this->dao->getByDoi($doi, $contextId); } /** @copydoc DAO::getIdsBySetting() */ public function getIdsBySetting(string $settingName, $settingValue, int $contextId): Enumerable { return $this->dao->getIdsBySetting($settingName, $settingValue, $contextId); } /** * Get the correct access URL for a submission's workflow based on a user's * role. * * The returned URL will point to the correct workflow page based on whether * the user should be treated as an author, reviewer or editor/assistant for * this submission. */ public function getWorkflowUrlByUserRoles(Submission $submission, ?int $userId = null): string { $request = Application::get()->getRequest(); if (is_null($userId)) { $user = $request->getUser(); } else { $user = Repo::user()->get($userId); } if (is_null($user)) { return ''; } $submissionContext = $request->getContext(); if (!$submissionContext || $submissionContext->getId() != $submission->getData('contextId')) { $submissionContext = Services::get('context')->get($submission->getData('contextId')); } $dispatcher = $request->getDispatcher(); // Check if the user is an author of this submission $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /** @var StageAssignmentDAO $stageAssignmentDao */ $authorUserGroupIds = Repo::userGroup()->getArrayIdByRoleId(Role::ROLE_ID_AUTHOR); $stageAssignmentsFactory = $stageAssignmentDao->getBySubmissionAndStageId($submission->getId(), null, null, $user->getId()); $authorDashboard = false; while ($stageAssignment = $stageAssignmentsFactory->next()) { if (in_array($stageAssignment->getUserGroupId(), $authorUserGroupIds)) { $authorDashboard = true; } } // Send authors, journal managers and site admins to the submission // wizard for incomplete submissions if ($submission->getSubmissionProgress() && ($authorDashboard || $user->hasRole([Role::ROLE_ID_MANAGER], $submissionContext->getId()) || $user->hasRole([Role::ROLE_ID_SITE_ADMIN], Application::CONTEXT_SITE))) { return $dispatcher->url( $request, Application::ROUTE_PAGE, $submissionContext->getPath(), 'submission', null, null, ['id' => $submission->getId()] ); } // Send authors to author dashboard if ($authorDashboard) { return $dispatcher->url( $request, Application::ROUTE_PAGE, $submissionContext->getPath(), 'authorDashboard', 'submission', $submission->getId() ); } // Send reviewers to review wizard $reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */ $reviewAssignment = $reviewAssignmentDao->getLastReviewRoundReviewAssignmentByReviewer($submission->getId(), $user->getId()); if ($reviewAssignment && !$reviewAssignment->getCancelled() && !$reviewAssignment->getDeclined()) { return $dispatcher->url( $request, Application::ROUTE_PAGE, $submissionContext->getPath(), 'reviewer', 'submission', $submission->getId() ); } // Give any other users the editorial workflow URL. If they can't access // it, they'll be blocked there. return $dispatcher->url( $request, Application::ROUTE_PAGE, $submissionContext->getPath(), 'workflow', 'access', $submission->getId() ); } /** * Validate properties for a submission * * Perform validation checks on data used to add or edit a submission. * * @param Submission|null $submission The submission being edited. Pass `null` if creating a new submission * @param array $props A key/value array with the new data to validate * * @return array A key/value array with validation errors. Empty if no errors */ public function validate(?Submission $submission, array $props, Context $context): array { $primaryLocale = $props['locale'] ?? $submission?->getLocale() ?? $context->getPrimaryLocale(); $allowedLocales = $context->getSupportedSubmissionLocales(); $errors = []; $validator = ValidatorFactory::make( $props, $this->schemaService->getValidationRules(PKPSchemaService::SCHEMA_SUBMISSION, $allowedLocales) ); // Check required fields ValidatorFactory::required( $validator, $submission, $this->schemaService->getRequiredProps(PKPSchemaService::SCHEMA_SUBMISSION), $this->schemaService->getMultilingualProps(PKPSchemaService::SCHEMA_SUBMISSION), $primaryLocale, $allowedLocales ); // Check for input from disallowed locales ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps(PKPSchemaService::SCHEMA_SUBMISSION), $allowedLocales); // The submission's locale must be one of the context's supported submission locales $validator->after(function ($validator) use ($props, $allowedLocales) { if (isset($props['locale']) && !$validator->errors()->get('locale')) { if (!in_array($props['locale'], $allowedLocales)) { $validator->errors()->add('locale', __('validator.locale')); } } }); // The contextId must match an existing context $validator->after(function ($validator) use ($props) { if (isset($props['contextId']) && !$validator->errors()->get('contextId')) { $submissionContext = Services::get('context')->exists($props['contextId']); if (!$submissionContext) { $validator->errors()->add('contextId', __('submission.submit.noContext')); } } }); // The sectionId must match an existing section in this context $validator->after(function ($validator) use ($props, $submission) { $propName = Application::getSectionIdPropName(); if ($validator->errors()->get($propName)) { return; } $sectionId = $props[$propName] ?? ($submission ? $submission->getCurrentPublication()->getData($propName) : null); if (!$sectionId) { return; } $contextId = $props['contextId'] ?? ($submission ? $submission->getData('contextId') : null); if (!Repo::section()->exists($sectionId, $contextId)) { $validator->errors()->add($propName, __('submission.sectionNotFound')); return; } }); // Comments for the editors are invalid after a submission has been submitted if ($submission && !$submission->getData('submissionProgress')) { $validator->after(function ($validator) use ($props, $submission) { if (isset($props['commentsForTheEditors']) && !$validator->errors()->get('commentsForTheEditors')) { $validator->errors()->add('commentsForTheEditors', __('form.disallowedProp')); } }); } if ($validator->fails()) { $errors = $this->schemaService->formatValidationErrors($validator->errors()); } Hook::call('Submission::validate', [&$errors, $submission, $props, $allowedLocales, $primaryLocale]); return $errors; } /** * Check if a submission meets all requirements to be submitted * * @return array A key/value array with validation errors. Empty if no errors */ public function validateSubmit(Submission $submission, Context $context): array { $locale = $submission->getData('locale'); $publication = $submission->getCurrentPublication(); $errors = []; // Can't submit a submission twice or a submission with the wrong status if (!$submission->getData('submissionProgress') || ($submission->getData('status') !== Submission::STATUS_QUEUED)) { $errors['submissionProgress'] = __( 'submission.wizard.alreadySubmitted', [ 'url' => Application::get() ->getDispatcher() ->url( Application::get()->getRequest(), Application::ROUTE_PAGE, $context->getData('path'), 'submissions' ) ] ); } // Title required in submission locale if (!$publication->getData('title', $locale)) { $errors['title'] = [$locale => [__('validator.required')]]; } // Author names required in submission locale foreach ($publication->getData('authors') as $author) { /** @var Author $author */ if (!$author->getGivenName($submission->getLocale())) { if (!isset($errors['contributors'])) { $errors['contributors'] = []; } $errors['contributors'][] = __('submission.wizard.missingContributorLanguage', ['language' => Locale::getMetadata($locale)->getDisplayName()]); break; } } // Required metadata $publicationSchema = $this->schemaService->get(PKPSchemaService::SCHEMA_PUBLICATION); foreach ($context->getRequiredMetadata() as $metadata) { // The `citations` metadata is received and validated at `citationsRaw` if ($metadata === 'citations') { $metadata = 'citationsRaw'; } // The `supportingAgencies` metadata is called `agencies` on the context if ($metadata === 'agencies') { $metadata = 'supportingAgencies'; } $schema = $publicationSchema->properties?->{$metadata}; if (!$schema) { continue; } if (empty($schema->multilingual) && empty($publication->getData($metadata))) { $errors[$metadata] = [__('validator.required')]; } elseif (!empty($schema->multilingual) && empty($publication->getData($metadata, $locale))) { $errors[$metadata] = [$locale => [__('validator.required')]]; } } // Required submission files $genreDao = DAORegistry::getDAO('GenreDAO'); /** @var GenreDAO $genreDao */ $requiredGenres = $genreDao->getRequiredToSubmit($context->getId()); if (!$requiredGenres->isEmpty()) { $submissionFiles = Repo::submissionFile() ->getCollector() ->filterBySubmissionIds([$submission->getId()]) ->filterByGenreIds( $requiredGenres->map( function (Genre $genre) { return $genre->getId(); } )->toArray() ) ->getMany(); $missingGenres = $submissionFiles->isEmpty() ? clone $requiredGenres : $requiredGenres->filter( function (Genre $genre) use ($submissionFiles) { $exists = $submissionFiles->first( function (SubmissionFile $submissionFile) use ($genre) { return $submissionFile->getData('genreId') === $genre->getId(); } ); return !$exists; } ); if ($missingGenres->count()) { $missingGenreNames = $missingGenres->map( function (Genre $genre) { return $genre->getLocalizedName(); } ); $errors['files'] = [ $missingGenres->count() > 1 ? __('submission.files.required.genres', [ 'genres' => $missingGenreNames->join(__('common.commaListSeparator')) ]) : __('submission.files.required.genre', ['genre' => $missingGenreNames->first()]) ]; } } Hook::call('Submission::validateSubmit', [&$errors, $submission, $context]); return $errors; } /** * Check if a user can delete a submission */ public function canCurrentUserDelete(Submission $submission): bool { $this->request = Application::get()->getRequest(); $contextId = $submission->getData('contextId'); $currentUser = $this->request->getUser(); if (!$currentUser) { return false; } $canDelete = false; // Only allow admins and journal managers to delete submissions, except // for authors who can delete their own incomplete submissions if ($currentUser->hasRole([Role::ROLE_ID_MANAGER], $contextId) || $currentUser->hasRole([Role::ROLE_ID_SITE_ADMIN], Application::CONTEXT_SITE)) { $canDelete = true; } else { if ($submission->getData('submissionProgress')) { $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /** @var StageAssignmentDAO $stageAssignmentDao */ $assignments = $stageAssignmentDao->getBySubmissionAndRoleIds($submission->getId(), [Role::ROLE_ID_AUTHOR], WORKFLOW_STAGE_ID_SUBMISSION, $currentUser->getId()); $assignment = $assignments->next(); if ($assignment) { $canDelete = true; } } } return $canDelete; } /** * Check if a user can edit the publication metadata of a submission */ public function canEditPublication(int $submissionId, int $userId): bool { $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /** @var StageAssignmentDAO $stageAssignmentDao */ $stageAssignments = $stageAssignmentDao->getBySubmissionAndUserIdAndStageId($submissionId, $userId, null)->toArray(); // Check for permission from stage assignments foreach ($stageAssignments as $stageAssignment) { if ($stageAssignment->getCanChangeMetadata()) { return true; } } // If user has no stage assigments, check if user can edit anyway ie. is manager $context = Application::get()->getRequest()->getContext(); if (count($stageAssignments) == 0 && $this->_canUserAccessUnassignedSubmissions($context->getId(), $userId)) { return true; } // Else deny access return false; } /** * Checks if this user is granted reader access to pre-publication submissions * based on their roles in the context (i.e. Manager, Editor, etc). */ public function canPreview(?User $user, Submission $submission): bool { // Only grant access when in copyediting or production stage if (!in_array($submission->getData('stageId'), [WORKFLOW_STAGE_ID_EDITING, WORKFLOW_STAGE_ID_PRODUCTION])) { return false; } if ($this->_roleCanPreview($user, $submission)) { return true; } if ($user) { /** @var StageAssignmentDAO */ $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); $stageAssignments = $stageAssignmentDao->getBySubmissionAndRoleId($submission->getId(), Role::ROLE_ID_AUTHOR, null, $user->getId()); $stageAssignment = $stageAssignments->next(); if ($stageAssignment) { return true; } } return false; } /** * Add a new submission */ public function add(Submission $submission, Publication $publication, Context $context): int { $submission->stampLastActivity(); $submission->stampModified(); if (!$submission->getData('dateSubmitted') && !$submission->getData('submissionProgress')) { $submission->setData('dateSubmitted', Core::getCurrentDate()); } if (!$submission->getData('status')) { $submission->setData('status', Submission::STATUS_QUEUED); } if (!$submission->getData('locale')) { $submission->setData('locale', $context->getPrimaryLocale()); } $submissionId = $this->dao->insert($submission); $submission = Repo::submission()->get($submissionId); $publication->setData('submissionId', $submission->getId()); $publication->setData('version', 1); if (!$publication->getData('status')) { $publication->setData('status', $submission->getData('status')); } $publicationId = Repo::publication()->add($publication); $this->edit($submission, ['currentPublicationId' => $publicationId]); Hook::call('Submission::add', [$submission]); return $submission->getId(); } /** @copydoc DAO::update */ public function edit(Submission $submission, array $params) { $newSubmission = Repo::submission()->newDataObject(array_merge($submission->_data, $params)); $newSubmission->stampLastActivity(); $newSubmission->stampModified(); Hook::call('Submission::edit', [$newSubmission, $submission, $params]); $this->dao->update($newSubmission); } /** * Submit a submission * * Changes the submissionProgress property, creates the comments * for the editors discussion, and fires the SubmissionSubmitted * event. */ public function submit(Submission $submission, Context $context): void { $this->edit($submission, [ 'submissionProgress' => '', 'dateSubmitted' => Core::getCurrentDate(), ]); $submission = $this->get($submission->getId()); event( new SubmissionSubmitted( $submission, $context ) ); if ($submission->getData('commentsForTheEditors')) { /** @var QueryDAO $queryDao */ $queryDao = DAORegistry::getDAO('QueryDAO'); $queryDao->addCommentsForEditorsQuery($submission); } } /** @copydoc DAO::delete */ public function delete(Submission $submission) { Hook::call('Submission::delete::before', [&$submission]); $this->dao->delete($submission); Hook::call('Submission::delete', [$submission]); } /** * Delete all submissions in a context */ public function deleteByContextId(int $contextId) { $submissionIds = Repo::submission()->getCollector()->filterByContextIds([$contextId])->getIds(); foreach ($submissionIds as $submissionId) { $this->dao->deleteById($submissionId); } } /** * Update a submission's status * * Changes a submission's status. Or, if no new status is provided, * sets the appropriate status based on all of the submission's * publications. * * This method performs any actions necessary when a submission's * status changes, such as changing the current publication ID * and creating or deleting tombstones. * * @param ?Section $section If this submission is being deleted, its previous section ID should be specified * in order to ensure a correctly created tombstone. */ public function updateStatus(Submission $submission, ?int $newStatus = null, ?Section $section = null) { $status = $submission->getData('status'); if ($newStatus === null) { $newStatus = $this->getStatusByPublications($submission); } Hook::call('Submission::updateStatus', [&$newStatus, $status, $submission]); if ($status !== $newStatus) { $submission->setData('status', $newStatus); } $currentPublicationId = $newCurrentPublicationId = $submission->getData('currentPublicationId'); $newCurrentPublicationId = $this->getCurrentPublicationIdByPublications($submission); if ($currentPublicationId !== $newCurrentPublicationId) { $submission->setData('currentPublicationId', $newCurrentPublicationId); } // Use the DAO instead of the Repository to prevent // calling this method over and over again. $this->dao->update($submission); } /** * Set license information for all submissions in a context * to the context's default license. */ public function resetPermissions(int $contextId) { $submissions = Repo::submission()->getCollector()->filterByContextIds([$contextId])->getMany(); foreach ($submissions as $submission) { $publications = $submission->getData('publications'); if (empty($publications)) { continue; } $params = [ 'copyrightYear' => $submission->_getContextLicenseFieldValue(null, Submission::PERMISSIONS_FIELD_COPYRIGHT_YEAR), 'copyrightHolder' => $submission->_getContextLicenseFieldValue(null, Submission::PERMISSIONS_FIELD_COPYRIGHT_HOLDER), 'licenseUrl' => $submission->_getContextLicenseFieldValue(null, Submission::PERMISSIONS_FIELD_LICENSE_URL), ]; foreach ($publications as $publication) { Repo::publication()->edit($publication, $params); } } } /** * Get an array of sort options used in forms when configuring * how published submissions are displayed */ public function getSortSelectOptions(): array { return [ $this->getSortOption(Collector::ORDERBY_TITLE, Collector::ORDER_DIR_ASC) => __('catalog.sortBy.titleAsc'), $this->getSortOption(Collector::ORDERBY_TITLE, Collector::ORDER_DIR_DESC) => __('catalog.sortBy.titleDesc'), $this->getSortOption(Collector::ORDERBY_DATE_PUBLISHED, Collector::ORDER_DIR_ASC) => __('catalog.sortBy.datePublishedAsc'), $this->getSortOption(Collector::ORDERBY_DATE_PUBLISHED, Collector::ORDER_DIR_DESC) => __('catalog.sortBy.datePublishedDesc'), ]; } /** * Get the default sort option used in forms when configuring * how published submissions are displayed * * @see self::getSortSelectOptions() */ public function getDefaultSortOption(): string { return $this->getSortOption(Collector::ORDERBY_DATE_PUBLISHED, Collector::ORDER_DIR_DESC); } /** * Get the URL to the API endpoint for a submission */ public function getUrlApi(Context $context, ?int $submissionId = null): string { return Application::get()->getDispatcher()->url( Application::get()->getRequest(), Application::ROUTE_API, $context->getData('urlPath'), 'submissions' . ($submissionId ? '/' . $submissionId : ''), ); } /** * Get the URL to the author workflow for a submission */ public function getUrlAuthorWorkflow(Context $context, int $submissionId): string { return Application::get()->getDispatcher()->url( Application::get()->getRequest(), Application::ROUTE_PAGE, $context->getData('urlPath'), 'authorDashboard', 'submission', $submissionId ); } /** * Get the URL to the editorial workflow for a submission */ public function getUrlEditorialWorkflow(Context $context, int $submissionId): string { return Application::get()->getDispatcher()->url( Application::get()->getRequest(), Application::ROUTE_PAGE, $context->getData('urlPath'), 'workflow', 'access', $submissionId ); } /** * Get the URL to the submission wizard for a submission */ public function getUrlSubmissionWizard(Context $context, ?int $submissionId = null): string { return Application::get()->getDispatcher()->url( Application::get()->getRequest(), Application::ROUTE_PAGE, $context->getData('urlPath'), 'submission', null, null, $submissionId ? ['id' => $submissionId] : null ); } /** * Creates and assigns DOIs to all sub-objects if: * 1) the suffix pattern can currently be created, and * 2) it does not already exist. * * @return DoiException[] */ abstract public function createDois(Submission $submission): array; /** * Compile the sort orderBy and orderDirection into an option * used in forms */ protected function getSortOption(string $sortBy, string $sortDir): string { return $sortBy . '-' . $sortDir; } /** * Check if a user is allowed to edit publication metadata for submissions * they are not assigned to */ protected function _canUserAccessUnassignedSubmissions(int $contextId, int $userId): bool { $roleDao = DAORegistry::getDAO('RoleDAO'); /** @var RoleDAO $roleDao */ $roles = $roleDao->getByUserId($userId, $contextId); $allowedRoles = Repo::userGroup()::NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES; foreach ($roles as $role) { if (in_array($role->getRoleId(), $allowedRoles)) { return true; } } return false; } /** * Get the appropriate status of a submission based on the * statuses of its publications */ protected function getStatusByPublications(Submission $submission): int { $publications = $submission->getData('publications'); /** @var LazyCollection $publications */ // Declined submissions should remain declined regardless of their publications' statuses if ($submission->getData('status') === Submission::STATUS_DECLINED) { return Submission::STATUS_DECLINED; } // If there are no publications, we are probably in the process of deleting a submission. // To be safe, reset the status anyway. if (!$publications->count()) { return Submission::STATUS_DECLINED ? Submission::STATUS_DECLINED : Submission::STATUS_QUEUED; } $newStatus = Submission::STATUS_QUEUED; foreach ($publications as $publication) { if ($publication->getData('status') === Submission::STATUS_PUBLISHED) { $newStatus = Submission::STATUS_PUBLISHED; break; } if ($publication->getData('status') === Submission::STATUS_SCHEDULED) { $newStatus = Submission::STATUS_SCHEDULED; continue; } } return $newStatus; } /** * Get the appropriate currentPublicationId for a submission based on the * statues of its publications */ protected function getCurrentPublicationIdByPublications(Submission $submission): ?int { $publications = $submission->getData('publications'); /** @var LazyCollection $publications */ if (!$publications->count()) { return null; } // Use the latest published publication $newCurrentPublicationId = $publications->reduce(function ($a, $b) { return $b->getData('status') === Submission::STATUS_PUBLISHED && $b->getId() > $a ? $b->getId() : $a; }, 0); // If there is no published publication, use the latest publication if (!$newCurrentPublicationId) { $newCurrentPublicationId = $publications->reduce(function ($a, $b) { return $a > $b->getId() ? $a : $b->getId(); }, 0); } return $newCurrentPublicationId ?? $submission->getData('currentPublicationId'); } /** * Checks if this user is granted access to preview * based on their roles in the context (i.e. Manager, Editor, etc). * * @param User $user * */ protected function _roleCanPreview(?User $user, Submission $submission): bool { if (!$user) { return false; } $subscriptionAssumedRoles = [ Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT, Role::ROLE_ID_SUBSCRIPTION_MANAGER ]; /** @var RoleDAO */ $roleDao = DAORegistry::getDAO('RoleDAO'); $roles = $roleDao->getByUserId($user->getId(), $submission->getData('contextId')); foreach ($roles as $role) { if (in_array($role->getRoleId(), $subscriptionAssumedRoles)) { return true; } } return false; } }