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
@@ -0,0 +1,116 @@
<?php
/**
* @file controllers/grid/eventLog/EventLogGridCellProvider.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 EventLogGridCellProvider
*
* @ingroup controllers_grid_publicationEntry
*
* @brief Cell provider for event log entries.
*/
namespace PKP\controllers\grid\eventLog;
use APP\core\Application;
use APP\facades\Repo;
use PKP\controllers\grid\DataObjectGridCellProvider;
use PKP\controllers\grid\GridColumn;
use PKP\db\DAORegistry;
use PKP\log\event\EventLogEntry;
use PKP\log\event\PKPSubmissionEventLogEntry;
use PKP\submission\reviewAssignment\ReviewAssignment;
use PKP\submission\reviewAssignment\ReviewAssignmentDAO;
use PKP\submissionFile\SubmissionFile;
class EventLogGridCellProvider extends DataObjectGridCellProvider
{
/** @var bool Is the current user assigned as an author to this submission */
public $_isCurrentUserAssignedAuthor;
/**
* Constructor
*
* @param bool $isCurrentUserAssignedAuthor Is the current user assigned
* as an author to this submission?
*/
public function __construct($isCurrentUserAssignedAuthor)
{
parent::__construct();
$this->_isCurrentUserAssignedAuthor = $isCurrentUserAssignedAuthor;
}
//
// Template methods from GridCellProvider
//
/**
* Extracts variables for a given column from a data element
* so that they may be assigned to template before rendering.
*
* @param \PKP\controllers\grid\GridRow $row
* @param GridColumn $column
*
* @return array
*/
public function getTemplateVarsFromRowColumn($row, $column)
{
$element = $row->getData();
$columnId = $column->getId();
assert($element instanceof \PKP\core\DataObject && !empty($columnId));
/** @var EventLogEntry $element */
switch ($columnId) {
case 'date':
return ['label' => $element instanceof EventLogEntry ? $element->getDateLogged() : $element->getDateSent()];
case 'event':
return ['label' => $element instanceof EventLogEntry ? $element->getTranslatedMessage(null, $this->_isCurrentUserAssignedAuthor) : $element->getPrefixedSubject()];
case 'user':
if ($element instanceof EventLogEntry) {
$userName = $element->getUserFullName();
// Anonymize reviewer details where necessary
if ($this->_isCurrentUserAssignedAuthor) {
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
// Maybe anonymize reviewer log entries
$reviewerLogTypes = [
PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_ACCEPT,
PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_DECLINE,
PKPSubmissionEventLogEntry::SUBMISSION_LOG_REVIEW_UNCONSIDERED,
];
if (in_array($element->getEventType(), $reviewerLogTypes)) {
$userName = __('editor.review.anonymousReviewer');
if ($reviewAssignmentId = $element->getData('reviewAssignmentId')) {
$reviewAssignment = $reviewAssignmentDao->getById($reviewAssignmentId);
if ($reviewAssignment && $reviewAssignment->getReviewMethod() === ReviewAssignment::SUBMISSION_REVIEW_METHOD_OPEN) {
$userName = $element->getUserFullName();
}
}
}
// Maybe anonymize files submitted by reviewers
$fileStage = $element->getData('fileStage');
if ($fileStage && $fileStage === SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT) {
$submissionFileId = $element->getData('submissionFileId');
assert($element->getData('fileId') && $element->getData('submissionId') && $submissionFileId);
$submissionFile = Repo::submissionFile()->get($submissionFileId);
if ($submissionFile && $submissionFile->getData('assocType') === Application::ASSOC_TYPE_REVIEW_ASSIGNMENT) {
$reviewAssignment = $reviewAssignmentDao->getById($submissionFile->getData('assocId'));
if (!$reviewAssignment || in_array($reviewAssignment->getReviewMethod(), [ReviewAssignment::SUBMISSION_REVIEW_METHOD_ANONYMOUS, ReviewAssignment::SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS])) {
$userName = __('editor.review.anonymousReviewer');
}
}
}
}
} else {
$userName = $element->getSenderFullName();
}
return ['label' => $userName];
default:
assert(false);
}
}
}
@@ -0,0 +1,116 @@
<?php
/**
* @file controllers/grid/eventLog/EventLogGridRow.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 EventLogGridRow
*
* @ingroup controllers_grid_eventLog
*
* @brief EventLog grid row definition
*/
namespace PKP\controllers\grid\eventLog;
use APP\core\Application;
use APP\facades\Repo;
use APP\submission\Submission;
use PKP\controllers\api\file\linkAction\DownloadFileLinkAction;
use PKP\controllers\grid\eventLog\linkAction\EmailLinkAction;
use PKP\controllers\grid\GridRow;
use PKP\db\DAORegistry;
use PKP\log\EmailLogEntry;
use PKP\log\event\EventLogEntry;
use PKP\log\event\SubmissionFileEventLogEntry;
use PKP\submission\reviewAssignment\ReviewAssignment;
use PKP\submission\reviewAssignment\ReviewAssignmentDAO;
use PKP\submissionFile\SubmissionFile;
class EventLogGridRow extends GridRow
{
/** @var Submission */
public $_submission;
/** @var bool Is the current user assigned as an author to this submission */
public $_isCurrentUserAssignedAuthor;
/**
* Constructor
*
* @param Submission $submission
* @param bool $isCurrentUserAssignedAuthor Is the current user assigned
* as an author to this submission?
*/
public function __construct($submission, $isCurrentUserAssignedAuthor)
{
$this->_submission = $submission;
$this->_isCurrentUserAssignedAuthor = $isCurrentUserAssignedAuthor;
parent::__construct();
}
//
// Overridden methods from GridRow
//
/**
* @copydoc GridRow::initialize()
*
* @param null|mixed $template
*/
public function initialize($request, $template = null)
{
parent::initialize($request, $template);
$logEntry = $this->getData(); // a Category object
assert($logEntry != null && ($logEntry instanceof EventLogEntry || $logEntry instanceof EmailLogEntry));
if ($logEntry instanceof EventLogEntry) {
switch ($logEntry->getEventType()) {
case SubmissionFileEventLogEntry::SUBMISSION_LOG_FILE_REVISION_UPLOAD:
case SubmissionFileEventLogEntry::SUBMISSION_LOG_FILE_UPLOAD:
$submissionFileId = $logEntry->getData('submissionFileId');
$fileId = $logEntry->getData('fileId');
$submissionFile = $submissionFileId ? Repo::submissionFile()->get($submissionFileId) : null;
if (!$submissionFile) {
break;
}
$filename = $logEntry->getLocalizedData('filename') ?? $submissionFile->getLocalizedData('name');
if ($submissionFile) {
$anonymousAuthor = false;
$maybeAnonymousAuthor = $this->_isCurrentUserAssignedAuthor && $submissionFile->getData('fileStage') === SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT;
if ($maybeAnonymousAuthor && $submissionFile->getData('assocType') === Application::ASSOC_TYPE_REVIEW_ASSIGNMENT) {
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var ReviewAssignmentDAO $reviewAssignmentDao */
$reviewAssignment = $reviewAssignmentDao->getById($submissionFile->getData('assocId'));
if ($reviewAssignment && in_array($reviewAssignment->getReviewMethod(), [ReviewAssignment::SUBMISSION_REVIEW_METHOD_ANONYMOUS, ReviewAssignment::SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS])) {
$anonymousAuthor = true;
}
}
if (!$anonymousAuthor) {
$workflowStageId = Repo::submissionFile()->getWorkflowStageId($submissionFile);
// If a submission file is attached to a query that has been deleted, we cannot
// determine its stage. Don't present a download link in this case.
if ($workflowStageId || $submissionFile->getData('fileStage') != SubmissionFile::SUBMISSION_FILE_QUERY) {
$this->addAction(new DownloadFileLinkAction($request, $submissionFile, $workflowStageId, __('common.download'), $fileId, $filename));
}
}
}
break;
}
} elseif ($logEntry instanceof EmailLogEntry) {
$this->addAction(
new EmailLinkAction(
$request,
__('submission.event.viewEmail'),
[
'submissionId' => $logEntry->getAssocId(),
'emailLogEntryId' => $logEntry->getId(),
]
)
);
}
}
}
@@ -0,0 +1,270 @@
<?php
/**
* @file controllers/grid/eventLog/SubmissionEventLogGridHandler.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 SubmissionEventLogGridHandler
*
* @ingroup controllers_grid_eventLog
*
* @brief Grid handler presenting the submission event log grid.
*/
namespace PKP\controllers\grid\eventLog;
use APP\core\Application;
use APP\facades\Repo;
use APP\submission\Submission;
use PKP\controllers\grid\DateGridCellProvider;
use PKP\controllers\grid\GridColumn;
use PKP\controllers\grid\GridHandler;
use PKP\core\JSONMessage;
use PKP\core\PKPApplication;
use PKP\core\PKPRequest;
use PKP\core\PKPString;
use PKP\db\DAORegistry;
use PKP\log\EmailLogEntry;
use PKP\log\SubmissionEmailLogDAO;
use PKP\log\event\EventLogEntry;
use PKP\security\authorization\internal\UserAccessibleWorkflowStageRequiredPolicy;
use PKP\security\authorization\SubmissionAccessPolicy;
use PKP\security\Role;
class SubmissionEventLogGridHandler extends GridHandler
{
/** @var Submission */
public $_submission;
/** @var int The current workflow stage */
public $_stageId;
/** @var bool Is the current user assigned as an author to this submission */
public $_isCurrentUserAssignedAuthor;
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->addRoleAssignment(
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR],
['fetchGrid', 'fetchRow', 'viewEmail']
);
}
//
// Getters/Setters
//
/**
* Get the submission associated with this grid.
*
* @return Submission
*/
public function getSubmission()
{
return $this->_submission;
}
/**
* Set the Submission
*
* @param Submission $submission
*/
public function setSubmission($submission)
{
$this->_submission = $submission;
}
//
// Overridden methods from PKPHandler
//
/**
* @see PKPHandler::authorize()
*
* @param PKPRequest $request
* @param array $args
* @param array $roleAssignments
*/
public function authorize($request, &$args, $roleAssignments)
{
$this->addPolicy(new SubmissionAccessPolicy($request, $args, $roleAssignments));
$this->addPolicy(new UserAccessibleWorkflowStageRequiredPolicy($request, PKPApplication::WORKFLOW_TYPE_EDITORIAL));
$success = parent::authorize($request, $args, $roleAssignments);
// Prevent authors from accessing review details, even if they are also
// assigned as an editor, sub-editor or assistant.
$userAssignedRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ACCESSIBLE_WORKFLOW_STAGES);
$this->_isCurrentUserAssignedAuthor = false;
foreach ($userAssignedRoles as $stageId => $roles) {
if (in_array(Role::ROLE_ID_AUTHOR, $roles)) {
$this->_isCurrentUserAssignedAuthor = true;
break;
}
}
return $success;
}
/**
* @copydoc GridHandler::initialize()
*
* @param null|mixed $args
*/
public function initialize($request, $args = null)
{
parent::initialize($request, $args);
// Retrieve the authorized monograph.
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
$this->setSubmission($submission);
$this->_stageId = (int) ($args['stageId'] ?? null);
// Columns
$cellProvider = new EventLogGridCellProvider($this->_isCurrentUserAssignedAuthor);
$this->addColumn(
new GridColumn(
'date',
'common.date',
null,
null,
new DateGridCellProvider(
$cellProvider,
Application::get()->getRequest()->getContext()->getLocalizedDateFormatShort()
)
)
);
$this->addColumn(
new GridColumn(
'user',
'common.user',
null,
null,
$cellProvider
)
);
$this->addColumn(
new GridColumn(
'event',
'common.event',
null,
null,
$cellProvider,
['width' => 60]
)
);
}
//
// Overridden methods from GridHandler
//
/**
* @see GridHandler::getRowInstance()
*
* @return EventLogGridRow
*/
protected function getRowInstance()
{
return new EventLogGridRow($this->getSubmission(), $this->_isCurrentUserAssignedAuthor);
}
/**
* Get the arguments that will identify the data in the grid
* In this case, the monograph.
*
* @return array
*/
public function getRequestArgs()
{
$submission = $this->getSubmission();
return [
'submissionId' => $submission->getId(),
'stageId' => $this->_stageId,
];
}
/**
* @copydoc GridHandler::loadData
*
* @param null|mixed $filter
*/
protected function loadData($request, $filter = null)
{
$submissionEmailLogDao = DAORegistry::getDAO('SubmissionEmailLogDAO'); /** @var SubmissionEmailLogDAO $submissionEmailLogDao */
$submission = $this->getSubmission();
$eventLogEntries = Repo::eventLog()->getCollector()
->filterByAssoc(PKPApplication::ASSOC_TYPE_SUBMISSION, [$submission->getId()])
->getMany();
$emailLogEntries = $submissionEmailLogDao->getBySubmissionId($submission->getId());
$entries = array_merge($eventLogEntries->toArray(), $emailLogEntries->toArray());
// Sort the merged data by date, most recent first
usort($entries, function ($a, $b) {
$aDate = $a instanceof EventLogEntry ? $a->getDateLogged() : $a->getDateSent();
$bDate = $b instanceof EventLogEntry ? $b->getDateLogged() : $b->getDateSent();
if ($aDate == $bDate) {
return 0;
}
return $aDate < $bDate ? 1 : -1;
});
return $entries;
}
/**
* Get the contents of the email
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage JSON object
*/
public function viewEmail($args, $request)
{
$submissionEmailLogDao = DAORegistry::getDAO('SubmissionEmailLogDAO'); /** @var SubmissionEmailLogDAO $submissionEmailLogDao */
$emailLogEntry = $submissionEmailLogDao->getById((int) $args['emailLogEntryId']);
return new JSONMessage(true, $this->_formatEmail($emailLogEntry));
}
/**
* Format the contents of the email
*
*
* @return string Formatted email
*/
public function _formatEmail(EmailLogEntry $emailLogEntry)
{
$text = [];
$text[] = __('email.from') . ': ' . htmlspecialchars($emailLogEntry->getFrom());
$text[] = __('email.to') . ': ' . htmlspecialchars($emailLogEntry->getRecipients());
if ($emailLogEntry->getCcs()) {
$text[] = __('email.cc') . ': ' . htmlspecialchars($emailLogEntry->getCcs());
}
if ($emailLogEntry->getBccs()) {
$text[] = __('email.bcc') . ': ' . htmlspecialchars($emailLogEntry->getBccs());
}
$text[] = __('email.subject') . ': ' . htmlspecialchars($emailLogEntry->getSubject());
return
'<div class="pkp_workflow_email_log_view">'
. nl2br(join(PHP_EOL, $text)) . '<br><br>'
. PKPString::stripUnsafeHtml($emailLogEntry->getBody())
. '</div>';
}
}
@@ -0,0 +1,146 @@
<?php
/**
* @file controllers/grid/eventLog/SubmissionFileEventLogGridHandler.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 SubmissionFileEventLogGridHandler
*
* @ingroup controllers_grid_eventLog
*
* @brief Grid handler presenting the submission file event log grid.
*/
namespace PKP\controllers\grid\eventLog;
use APP\core\Application;
use APP\facades\Repo;
use PKP\core\PKPApplication;
use PKP\core\PKPRequest;
use PKP\security\authorization\SubmissionFileAccessPolicy;
use PKP\security\Role;
use PKP\submissionFile\SubmissionFile;
class SubmissionFileEventLogGridHandler extends SubmissionEventLogGridHandler
{
/** @var SubmissionFile SubmissionFile */
public $_submissionFile;
//
// Getters/Setters
//
/**
* Get the submission file associated with this grid.
*
* @return SubmissionFile
*/
public function getSubmissionFile()
{
return $this->_submissionFile;
}
/**
* Set the submission file
*
* @param SubmissionFile $submissionFile
*/
public function setSubmissionFile($submissionFile)
{
$this->_submissionFile = $submissionFile;
}
//
// Overridden methods from PKPHandler
//
/**
* @see PKPHandler::authorize()
*
* @param PKPRequest $request
* @param array $args
* @param array $roleAssignments
*/
public function authorize($request, &$args, $roleAssignments)
{
$this->addPolicy(new SubmissionFileAccessPolicy($request, $args, $roleAssignments, SubmissionFileAccessPolicy::SUBMISSION_FILE_ACCESS_READ, (int) $args['submissionFileId']));
return parent::authorize($request, $args, $roleAssignments);
}
/**
* Configure the grid
*
* @see SubmissionEventLogGridHandler::initialize
*
* @param null|mixed $args
*/
public function initialize($request, $args = null)
{
parent::initialize($request, $args);
// Retrieve the authorized monograph.
$submission = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION);
$submissionFile = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_SUBMISSION_FILE);
$this->setSubmissionFile($submissionFile);
}
//
// Overridden methods from GridHandler
//
/**
* Get the arguments that will identify the data in the grid
* In this case, the monograph.
*
* @return array
*/
public function getRequestArgs()
{
$submissionFile = $this->getSubmissionFile();
return [
'submissionId' => $submissionFile->getData('submissionId'),
'submissionFileId' => $submissionFile->getId(),
'stageId' => $this->_stageId,
];
}
/**
* @copydoc GridHandler::loadData
*
* @param null|mixed $filter
*/
protected function loadData($request, $filter = null)
{
return Repo::eventLog()->getCollector()
->filterByAssoc(PKPApplication::ASSOC_TYPE_SUBMISSION_FILE, [$this->getSubmissionFile()->getId()])
->getMany()
->toArray();
}
/**
* @copydoc GridHandler::getFilterForm()
*
* @return string Filter template.
*/
protected function getFilterForm()
{
// If the user only has an author role, do not permit access
// to earlier stages.
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
if (array_intersect([Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_SUB_EDITOR, Role::ROLE_ID_ASSISTANT], $userRoles)) {
return 'controllers/grid/eventLog/eventLogGridFilter.tpl';
}
return parent::getFilterForm();
}
/**
* @copydoc GridHandler::getFilterSelectionData()
*/
public function getFilterSelectionData($request)
{
return ['allEvents' => $request->getUserVar('allEvents') ? true : false];
}
}
@@ -0,0 +1,51 @@
<?php
/**
* @file controllers/grid/eventLog/linkAction/EmailLinkAction.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 EmailLinkAction
*
* @ingroup controllers_api_submission
*
* @brief An action to open up a modal to view an email sent to a user.
*/
namespace PKP\controllers\grid\eventLog\linkAction;
use APP\core\Request;
use PKP\linkAction\LinkAction;
use PKP\linkAction\request\AjaxModal;
class EmailLinkAction extends LinkAction
{
/**
* Constructor
*
* @param Request $request
* @param string $modalTitle Title of the modal
* @param array $actionArgs The action arguments.
*/
public function __construct($request, $modalTitle, $actionArgs)
{
$router = $request->getRouter();
// Instantiate the view email modal.
$ajaxModal = new AjaxModal(
$router->url($request, null, null, 'viewEmail', null, $actionArgs),
$modalTitle,
'modal_email'
);
// Configure the link action.
parent::__construct(
'viewEmail',
$ajaxModal,
$modalTitle,
'notify'
);
}
}