File Manager
Upload
Current Directory: /home/lartcid/public_html/journal.lartc.id
[Back]
..
[Open]
Hapus
Rename
.htaccess
[Edit]
Hapus
Rename
.well-known
[Open]
Hapus
Rename
README.md
[Edit]
Hapus
Rename
api
[Open]
Hapus
Rename
cache
[Open]
Hapus
Rename
cgi-bin
[Open]
Hapus
Rename
classes
[Open]
Hapus
Rename
config.TEMPLATE.inc.php
[Edit]
Hapus
Rename
config.inc.php
[Edit]
Hapus
Rename
controllers
[Open]
Hapus
Rename
cypress.json
[Edit]
Hapus
Rename
dbscripts
[Open]
Hapus
Rename
docs
[Open]
Hapus
Rename
error_log
[Edit]
Hapus
Rename
favicon.ico
[Edit]
Hapus
Rename
index.php
[Edit]
Hapus
Rename
js
[Open]
Hapus
Rename
lib
[Open]
Hapus
Rename
locale
[Open]
Hapus
Rename
mini.php
[Edit]
Hapus
Rename
pages
[Open]
Hapus
Rename
php.ini
[Edit]
Hapus
Rename
plugins
[Open]
Hapus
Rename
public
[Open]
Hapus
Rename
registry
[Open]
Hapus
Rename
scheduledTaskLogs
[Open]
Hapus
Rename
schemas
[Open]
Hapus
Rename
styles
[Open]
Hapus
Rename
templates
[Open]
Hapus
Rename
tools
[Open]
Hapus
Rename
Edit File
<?php /** * @file classes/services/PKPSubmissionService.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 SubmissionService * @ingroup services * * @brief Helper class that encapsulates submission business logic */ namespace PKP\Services; use function PHP81_BC\strftime; use \Core; use \DBResultRange; use \Application; use \DAOResultFactory; use \DAORegistry; use \Illuminate\Database\Capsule\Manager as Capsule; use \Services; use \PKP\Services\interfaces\EntityPropertyInterface; use \PKP\Services\interfaces\EntityReadInterface; use \PKP\Services\interfaces\EntityWriteInterface; use \APP\Services\QueryBuilders\SubmissionQueryBuilder; define('STAGE_STATUS_SUBMISSION_UNASSIGNED', 1); abstract class PKPSubmissionService implements EntityPropertyInterface, EntityReadInterface, EntityWriteInterface { /** * @copydoc \PKP\Services\interfaces\EntityReadInterface::get() */ public function get($submissionId) { $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */ return $submissionDao->getById($submissionId); } /** * Get a submission by the urlPath of its publications * * @param string $urlPath * @param int $contextId * @return Submission|null */ public function getByUrlPath($urlPath, $contextId) { $qb = new \PKP\Services\QueryBuilders\PKPPublicationQueryBuilder(); $firstResult = $qb->getQueryByUrlPath($urlPath, $contextId)->first(); if (!$firstResult) { return null; } return $this->get($firstResult->submission_id); } /** * @copydoc \PKP\Services\interfaces\EntityReadInterface::getCount() */ public function getCount($args = []) { return $this->getQueryBuilder($args)->getCount(); } /** * @copydoc \PKP\Services\interfaces\EntityReadInterface::getIds() */ public function getIds($args = []) { return $this->getQueryBuilder($args)->getIds(); } /** * Get a collection of Submission objects limited, filtered * and sorted by $args * * @param array $args * @option int contextId If not supplied, CONTEXT_ID_NONE will be used and * no submissions will be returned. To retrieve submissions from all * contexts, use CONTEXT_ID_ALL. * @option string orderBy * @option string orderDirection * @option int assignedTo * @option int|array status * @option string searchPhrase * @option int count * @option int offset * @return \Iterator */ public function getMany($args = []) { $range = null; if (isset($args['count'])) { import('lib.pkp.classes.db.DBResultRange'); $range = new \DBResultRange($args['count'], null, isset($args['offset']) ? $args['offset'] : 0); } // Pagination is handled by the DAO, so don't pass count and offset // arguments to the QueryBuilder. if (isset($args['count'])) unset($args['count']); if (isset($args['offset'])) unset($args['offset']); $submissionListQO = $this->getQueryBuilder($args)->getQuery(); $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */ $result = $submissionDao->retrieveRange($sql = $submissionListQO->toSql(), $params = $submissionListQO->getBindings(), $range); $queryResults = new DAOResultFactory($result, $submissionDao, '_fromRow', [], $sql, $params, $range); return $queryResults->toIterator(); } /** * @copydoc \PKP\Services\interfaces\EntityReadInterface::getMax() */ public function getMax($args = []) { // Don't accept args to limit the results if (isset($args['count'])) unset($args['count']); if (isset($args['offset'])) unset($args['offset']); return $this->getQueryBuilder($args)->getCount(); } /** * @copydoc \PKP\Services\interfaces\EntityReadInterface::getQueryBuilder() * @return SubmissionQueryBuilder */ public function getQueryBuilder($args = []) { $defaultArgs = array( 'contextId' => CONTEXT_ID_NONE, 'orderBy' => 'dateSubmitted', 'orderDirection' => 'DESC', 'assignedTo' => [], 'status' => null, 'stageIds' => null, 'searchPhrase' => null, 'isIncomplete' => false, 'isOverdue' => false, 'daysInactive' => null, ); $args = array_merge($defaultArgs, $args); $submissionListQB = new SubmissionQueryBuilder(); $submissionListQB ->filterByContext($args['contextId']) ->orderBy($args['orderBy'], $args['orderDirection']) ->assignedTo($args['assignedTo']) ->filterByStatus($args['status']) ->filterByStageIds($args['stageIds']) ->filterByIncomplete($args['isIncomplete']) ->filterByOverdue($args['isOverdue']) ->filterByDaysInactive($args['daysInactive']) ->filterByCategories(isset($args['categoryIds'])?$args['categoryIds']:null) ->searchPhrase($args['searchPhrase']); if (isset($args['count'])) { $submissionListQB->limitTo($args['count']); } if (isset($args['offset'])) { $submissionListQB->offsetBy($args['count']); } \HookRegistry::call('Submission::getMany::queryBuilder', array(&$submissionListQB, $args)); return $submissionListQB; } /** * @copydoc \PKP\Services\interfaces\EntityPropertyInterface::getProperties() */ public function getProperties($submission, $props, $args = null) { \AppLocale::requireComponents(LOCALE_COMPONENT_APP_SUBMISSION, LOCALE_COMPONENT_PKP_SUBMISSION); $values = array(); $request = $args['request']; $dispatcher = $request->getDispatcher(); // Retrieve the submission's context for properties that require it if (array_intersect(['_href', 'urlAuthorWorkflow', 'urlEditorialWorkflow'], $props)) { $submissionContext = $request->getContext(); if (!$submissionContext || $submissionContext->getId() != $submission->getData('contextId')) { $submissionContext = Services::get('context')->get($submission->getData('contextId')); } } foreach ($props as $prop) { switch ($prop) { case '_href': $values[$prop] = $dispatcher->url( $request, ROUTE_API, $submissionContext->getData('urlPath'), 'submissions/' . $submission->getId() ); break; case 'publications': $values[$prop] = array_map( function($publication) use ($args, $submission, $submissionContext) { return Services::get('publication')->getSummaryProperties( $publication, $args + [ 'submission' => $submission, 'context' => $submissionContext, 'currentUserReviewAssignment' => DAORegistry::getDAO('ReviewAssignmentDAO') ->getLastReviewRoundReviewAssignmentByReviewer( $submission->getId(), $args['request']->getUser()->getId() ), ]); }, $submission->getData('publications') ); break; case 'reviewAssignments': $values[$prop] = $this->getPropertyReviewAssignments($submission); break; case 'reviewRounds': $values[$prop] = $this->getPropertyReviewRounds($submission); break; case 'stages': $values[$prop] = $this->getPropertyStages($submission); break; case 'statusLabel': $values[$prop] = __($submission->getStatusKey()); break; case 'urlAuthorWorkflow': $values[$prop] = $dispatcher->url( $request, ROUTE_PAGE, $submissionContext->getData('urlPath'), 'authorDashboard', 'submission', $submission->getId() ); break; case 'urlEditorialWorkflow': $values[$prop] = $dispatcher->url( $request, ROUTE_PAGE, $submissionContext->getData('urlPath'), 'workflow', 'access', $submission->getId() ); break; case 'urlWorkflow': $values[$prop] = $this->getWorkflowUrlByUserRoles($submission); break; default: $values[$prop] = $submission->getData($prop); break; } } $values = Services::get('schema')->addMissingMultilingualValues(SCHEMA_SUBMISSION, $values, $request->getContext()->getSupportedSubmissionLocales()); \HookRegistry::call('Submission::getProperties::values', array(&$values, $submission, $props, $args)); ksort($values); return $values; } /** * @copydoc \PKP\Services\interfaces\EntityPropertyInterface::getSummaryProperties() */ public function getSummaryProperties($submission, $args = null) { $props = Services::get('schema')->getSummaryProps(SCHEMA_SUBMISSION); return $this->getProperties($submission, $props, $args); } /** * @copydoc \PKP\Services\interfaces\EntityPropertyInterface::getFullProperties() */ public function getFullProperties($submission, $args = null) { $props = Services::get('schema')->getFullProps(SCHEMA_SUBMISSION); return $this->getProperties($submission, $props, $args); } /** * Returns properties for custom API endpoints used in the backend * @param Submission $submission * @param array extra arguments * $args['request'] PKPRequest Required * $args['slimRequest'] SlimRequest */ public function getBackendListProperties($submission, $args = null) { \PluginRegistry::loadCategory('pubIds', true); $props = array ( '_href', 'contextId', 'currentPublicationId','dateLastActivity','dateSubmitted','id', 'lastModified','publications','reviewAssignments','reviewRounds','stageId','stages','status', 'statusLabel','submissionProgress','urlAuthorWorkflow','urlEditorialWorkflow','urlWorkflow','urlPublished', ); \HookRegistry::call('Submission::getBackendListProperties::properties', array(&$props, $submission, $args)); return $this->getProperties($submission, $props, $args); } /** * Get details about the review assignments for a submission * * @todo account for extra review stage in omp * @param $submission Submission */ public function getPropertyReviewAssignments($submission) { $reviewAssignments = $this->getReviewAssignments($submission); $reviews = array(); foreach($reviewAssignments as $reviewAssignment) { if ($reviewAssignment->getDeclined() || $reviewAssignment->getCancelled()) { continue; } $request = \Application::get()->getRequest(); $currentUser = $request->getUser(); $context = $request->getContext(); $dateFormatShort = $context->getLocalizedDateFormatShort(); $due = is_null($reviewAssignment->getDateDue()) ? null : strftime($dateFormatShort, strtotime($reviewAssignment->getDateDue())); $responseDue = is_null($reviewAssignment->getDateResponseDue()) ? null : strftime($dateFormatShort, strtotime($reviewAssignment->getDateResponseDue())); $reviews[] = array( 'id' => (int) $reviewAssignment->getId(), 'isCurrentUserAssigned' => $currentUser->getId() == (int) $reviewAssignment->getReviewerId(), 'statusId' => (int) $reviewAssignment->getStatus(), 'status' => __($reviewAssignment->getStatusKey()), 'due' => $due, 'responseDue' => $responseDue, 'round' => (int) $reviewAssignment->getRound(), 'roundId' => (int) $reviewAssignment->getReviewRoundId(), ); } return $reviews; } /** * Get details about the review rounds for a submission * * @todo account for extra review stage in omp * @param $submission Submission * @return array */ public function getPropertyReviewRounds($submission) { $reviewRounds = $this->getReviewRounds($submission); $rounds = array(); foreach ($reviewRounds as $reviewRound) { $rounds[] = array( 'id' => $reviewRound->getId(), 'round' => $reviewRound->getRound(), 'stageId' => $reviewRound->getStageId(), 'statusId' => $reviewRound->determineStatus(), 'status' => __($reviewRound->getStatusKey()), ); } return $rounds; } /** * Get details about a submission's stage(s) * * @param $submission Submission * @param $stageIds array|int|null One or more stages to retrieve. * Default: null. Will return data on all app stages. * @return array { * `id` int stage id * `label` string translated stage name * `queries` array [{ * `id` int query id * `assocType` int * `assocId` int * `stageId` int * `seq` int * `closed` bool * }] * `statusId` int stage status. note: on review stage, this refers to the * status of the latest round. * `status` string translated stage status name * `files` array { * `count` int number of files attached to stage. note: this only counts * revision files. * } */ public function getPropertyStages($submission, $stageIds = null) { if (is_null($stageIds)) { $stageIds = Application::get()->getApplicationStages(); } elseif (is_int($stageIds)) { $stageIds = array($stageIds); } $currentUser = \Application::get()->getRequest()->getUser(); $context = \Application::get()->getRequest()->getContext(); $contextId = $context ? $context->getId() : CONTEXT_ID_NONE; $stages = array(); foreach ($stageIds as $stageId) { import('lib.pkp.classes.workflow.WorkflowStageDAO'); $workflowStageDao = DAORegistry::getDAO('WorkflowStageDAO'); /* @var $workflowStageDao WorkflowStageDAO */ $stage = array( 'id' => (int) $stageId, 'label' => __($workflowStageDao->getTranslationKeyFromId($stageId)), 'isActiveStage' => $submission->getStageId() == $stageId, ); // Discussions in this stage $stage['queries'] = array(); $request = Application::get()->getRequest(); import('lib.pkp.classes.query.QueryDAO'); $queryDao = DAORegistry::getDAO('QueryDAO'); /* @var $queryDao QueryDAO */ $queries = $queryDao->getByAssoc( ASSOC_TYPE_SUBMISSION, $submission->getId(), $stageId, $request->getUser()->getId() // Current user restriction should prevent unauthorized access ); while ($query = $queries->next()) { $stage['queries'][] = array( 'id' => (int) $query->getId(), 'assocType' => (int) $query->getAssocType(), 'assocId' => (int) $query->getAssocId(), 'stageId' => $stageId, 'seq' => (int) $query->getSequence(), 'closed' => (bool) $query->getIsClosed(), ); } $currentUserAssignedRoles = array(); if ($currentUser) { $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmentDao StageAssignmentDAO */ $stageAssignmentsResult = $stageAssignmentDao->getBySubmissionAndUserIdAndStageId($submission->getId(), $currentUser->getId(), $stageId); $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); /* @var $userGroupDao UserGroupDAO */ while ($stageAssignment = $stageAssignmentsResult->next()) { $userGroup = $userGroupDao->getById($stageAssignment->getUserGroupId(), $contextId); $currentUserAssignedRoles[] = (int) $userGroup->getRoleId(); } } $stage['currentUserAssignedRoles'] = array_values(array_unique($currentUserAssignedRoles)); // Stage-specific statuses switch ($stageId) { case WORKFLOW_STAGE_ID_SUBMISSION: import('lib.pkp.classes.stageAssignment.StageAssignmentDAO'); $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmentDao StageAssignmentDAO */ $assignedEditors = $stageAssignmentDao->editorAssignedToStage($submission->getId(), $stageId); if (!$assignedEditors) { $stage['statusId'] = STAGE_STATUS_SUBMISSION_UNASSIGNED; $stage['status'] = __('submissions.queuedUnassigned'); } // Submission stage never has revisions $stage['files'] = array( 'count' => 0, ); break; case WORKFLOW_STAGE_ID_INTERNAL_REVIEW: case WORKFLOW_STAGE_ID_EXTERNAL_REVIEW: import('lib.pkp.classes.submission.reviewRound.ReviewRoundDAO'); $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); /* @var $reviewRoundDao ReviewRoundDAO */ $reviewRound = $reviewRoundDao->getLastReviewRoundBySubmissionId($submission->getId(), $stageId); if ($reviewRound) { $stage['statusId'] = $reviewRound->determineStatus(); $stage['status'] = __($reviewRound->getStatusKey()); // Revision files in this round. $stage['files'] = [ 'count' => Services::get('submissionFile')->getCount([ 'submissionIds' => [$submission->getId()], 'fileStages' => [SUBMISSION_FILE_REVIEW_REVISION], 'reviewRounds' => [$reviewRound->getId()], ]), ]; // See if the curent user can only recommend: $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmentDao StageAssignmentDAO */ $user = $request->getUser(); $editorsStageAssignments = $stageAssignmentDao->getEditorsAssignedToStage($submission->getId(), $stageId); // if the user is assigned several times in the editorial role, and // one of the assignments have recommendOnly option set, consider it here $stage['currentUserCanRecommendOnly'] = false; foreach ($editorsStageAssignments as $editorsStageAssignment) { if ($editorsStageAssignment->getUserId() == $user->getId() && $editorsStageAssignment->getRecommendOnly()) { $stage['currentUserCanRecommendOnly'] = true; break; } } } else { // workaround for pkp/pkp-lib#4231, pending formal data model $stage['files'] = [ 'count' => 0 ]; } break; // Get revision files for editing and production stages. // Review rounds are handled separately in the review stage below. case WORKFLOW_STAGE_ID_EDITING: case WORKFLOW_STAGE_ID_PRODUCTION: import('lib.pkp.classes.submission.SubmissionFile'); // Import constants $stage['files'] = [ 'count' => Services::get('submissionFile')->getCount([ 'submissionIds' => [$submission->getId()], 'fileStages' => [WORKFLOW_STAGE_ID_EDITING ? SUBMISSION_FILE_COPYEDIT : SUBMISSION_FILE_PROOF], ]), ]; break; } $stages[] = $stage; } return $stages; } /** * 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. * * @param $submission Submission * @param $userId an optional user id * @return string|false URL; false if the user does not exist or an * appropriate access URL could not be determined */ public function getWorkflowUrlByUserRoles($submission, $userId = null) { $request = Application::get()->getRequest(); if (is_null($userId)) { $user = $request->getUser(); } else { $userDao = DAORegistry::getDAO('UserDAO'); /* @var $userDao UserDAO */ $user = $userDao->getById($userId); } if (is_null($user)) { return false; } $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 $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); /* @var $userGroupDao UserGroupDAO */ $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmentDao StageAssignmentDAO */ $authorUserGroupIds = $userGroupDao->getUserGroupIdsByRoleId(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() > 0 && ($authorDashboard || $user->hasRole(array(ROLE_ID_MANAGER), $submissionContext->getId()) || $user->hasRole(array(ROLE_ID_SITE_ADMIN), CONTEXT_SITE))) { return $dispatcher->url( $request, ROUTE_PAGE, $submissionContext->getPath(), 'submission', 'wizard', $submission->getSubmissionProgress(), array('submissionId' => $submission->getId()) ); } // Send authors to author dashboard if ($authorDashboard) { return $dispatcher->url( $request, 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, 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, ROUTE_PAGE, $submissionContext->getPath(), 'workflow', 'access', $submission->getId() ); } /** * Check if a user can delete a submission * * @param $submission Submission|int Submission object or submission ID * @return bool */ public function canCurrentUserDelete($submission) { if (!is_a($submission, 'Submission')) { $submission = $this->get((int) $submission); if (!$submission) { return false; } } $request = Application::get()->getRequest(); $contextId = $submission->getContextId(); $currentUser = $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(array(ROLE_ID_MANAGER), $contextId) || $currentUser->hasRole(array(ROLE_ID_SITE_ADMIN), CONTEXT_SITE)) { $canDelete = true; } else { if ($submission->getSubmissionProgress() != 0 ) { $stageAssignmentDao = DAORegistry::getDAO('StageAssignmentDAO'); /* @var $stageAssignmentDao StageAssignmentDAO */ $assignments = $stageAssignmentDao->getBySubmissionAndRoleId($submission->getId(), ROLE_ID_AUTHOR, WORKFLOW_STAGE_ID_SUBMISSION, $currentUser->getId()); $assignment = $assignments->next(); if ($assignment) { $canDelete = true; } } } return $canDelete; } /** * Get review rounds for a submission * * @param $submission Submission * @return \Iterator */ public function getReviewRounds($submission) { $reviewRoundDao = DAORegistry::getDAO('ReviewRoundDAO'); /* @var $reviewRoundDao ReviewRoundDAO */ return $reviewRoundDao->getBySubmissionId($submission->getId())->toIterator(); } /** * Get review assignments for a submission * * @param $submission Submission * @return array */ public function getReviewAssignments($submission) { import('lib.pkp.classes.submission.reviewAssignment.ReviewAssignmentDAO'); $reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /* @var $reviewAssignmentDao ReviewAssignmentDAO */ return $reviewAssignmentDao->getBySubmissionId($submission->getId()); } /** * @copydoc \PKP\Services\EntityProperties\EntityWriteInterface::validate() */ public function validate($action, $props, $allowedLocales, $primaryLocale) { $schemaService = Services::get('schema'); import('lib.pkp.classes.validation.ValidatorFactory'); $validator = \ValidatorFactory::make( $props, $schemaService->getValidationRules(SCHEMA_SUBMISSION, $allowedLocales) ); // Check required fields \ValidatorFactory::required( $validator, $action, $schemaService->getRequiredProps(SCHEMA_SUBMISSION), $schemaService->getMultilingualProps(SCHEMA_SUBMISSION), $primaryLocale, $allowedLocales ); // Check for input from disallowed locales \ValidatorFactory::allowedLocales($validator, $schemaService->getMultilingualProps(SCHEMA_SUBMISSION), $allowedLocales); // 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')->get($props['contextId']); if (!$submissionContext) { $validator->errors()->add('contextId', __('submission.submit.noContext')); } } }); if ($validator->fails()) { $errors = $schemaService->formatValidationErrors($validator->errors(), $schemaService->get(SCHEMA_SUBMISSION), $allowedLocales); } \HookRegistry::call('Submission::validate', [&$errors, $action, $props, $allowedLocales, $primaryLocale]); return $errors; } /** * @copydoc \PKP\Services\EntityProperties\EntityWriteInterface::add() */ public function add($submission, $request) { $submission->stampLastActivity(); $submission->stampModified(); if (!$submission->getData('dateSubmitted') && !$submission->getData('submissionProgress')) { $submission->setData('dateSubmitted', Core::getCurrentDate()); } $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */ $submissionId = $submissionDao->insertObject($submission); $submission = $this->get($submissionId); \HookRegistry::call('Submission::add', [&$submission, $request]); return $submission; } /** * @copydoc \PKP\Services\EntityProperties\EntityWriteInterface::edit() */ public function edit($submission, $params, $request) { $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */ $newSubmission = $submissionDao->newDataObject(); $newSubmission->_data = array_merge($submission->_data, $params); $submission->stampLastActivity(); $submission->stampModified(); \HookRegistry::call('Submission::edit', [&$newSubmission, $submission, $params, $request]); $submissionDao->updateObject($newSubmission); $newSubmission = $this->get($newSubmission->getId()); return $newSubmission; } /** * @copydoc \PKP\Services\EntityProperties\EntityWriteInterface::delete() */ public function delete($submission) { \HookRegistry::call('Submission::delete::before', [&$submission]); $submissionDao = DAORegistry::getDAO('SubmissionDAO'); /* @var $submissionDao SubmissionDAO */ $submissionDao->deleteObject($submission); \HookRegistry::call('Submission::delete', [&$submission]); } /** * Check if a user can edit a publications metadata * * @param int $submissionId * @param int $userId * @return boolean */ public function canEditPublication($submissionId, $userId) { $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; } /** * Check whether the user is by default allowed to edit publications metadata * @param $contextId int * @param $userId int * @return boolean true if the user is allowed to edit metadata by default */ private static function _canUserAccessUnassignedSubmissions($contextId, $userId) { $roleDao = DAORegistry::getDAO('RoleDAO'); /* @var $roleDao RoleDAO */ $roles = $roleDao->getByUserId($userId, $contextId); $userGroupDao = DAORegistry::getDAO('UserGroupDAO'); /* @var $userGroupDao UserGroupDAO */ $allowedRoles = $userGroupDao->getNotChangeMetadataEditPermissionRoles(); foreach ($roles as $role) { if (in_array($role->getRoleId(), $allowedRoles)) return true; } return false; } /** * Update a submission's status and current publication id if necessary * * Checks the status of the submission's publications and sets * the appropriate status and current publication id. * * @param Submission $submission * @return Submission */ public function updateStatus($submission) { $status = $newStatus = $submission->getData('status'); $currentPublicationId = $submission->getData('currentPublicationId'); $publications = $submission->getData('publications'); // There should always be at least one publication for a submission. If // not, an error has occurred in the code and will cause problems. if (empty($publications)) { throw new \Exception('Tried to update the status of submission ' . $submission->getId() . ' and no publications were found.'); } // Get the new current publication after status changes or deletions // Use the latest published publication or, failing that, the latest publication $newCurrentPublicationId = array_reduce($publications, function($a, $b) { return $b->getData('status') === STATUS_PUBLISHED && $b->getId() > $a ? $b->getId() : $a; }, 0); if (!$newCurrentPublicationId) { $newCurrentPublicationId = array_reduce($publications, function($a, $b) { return $a > $b->getId() ? $a : $b->getId(); }, 0); } // Declined submissions should remain declined even if their // publications change if ($status !== STATUS_DECLINED) { $newStatus = STATUS_QUEUED; foreach ($publications as $publication) { if ($publication->getData('status') === STATUS_PUBLISHED) { $newStatus = STATUS_PUBLISHED; break; } if ($publication->getData('status') === STATUS_SCHEDULED) { $newStatus = STATUS_SCHEDULED; continue; } } } \HookRegistry::call('Submission::updateStatus', [&$status, $submission]); $updateParams = []; if ($status !== $newStatus) { $updateParams['status'] = $newStatus; } if ($currentPublicationId !== $newCurrentPublicationId) { $updateParams['currentPublicationId'] = $newCurrentPublicationId; } if (!empty($updateParams)) { $submission = $this->edit($submission, $updateParams, Application::get()->getRequest()); } return $submission; } }
Simpan