first commit
This commit is contained in:
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/log/EmailLogDAO.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 EmailLogDAO
|
||||
*
|
||||
* @ingroup log
|
||||
*
|
||||
* @see EmailLogEntry, Log
|
||||
*
|
||||
* @brief Class for inserting/accessing email log entries.
|
||||
*/
|
||||
|
||||
namespace PKP\log;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use PKP\db\DAOResultFactory;
|
||||
use PKP\plugins\Hook;
|
||||
|
||||
class EmailLogDAO extends \PKP\db\DAO
|
||||
{
|
||||
/**
|
||||
* Retrieve a log entry by ID.
|
||||
*
|
||||
* @param int $logId
|
||||
* @param int $assocType optional
|
||||
* @param int $assocId optional
|
||||
*
|
||||
* @return EmailLogEntry
|
||||
*/
|
||||
public function getById($logId, $assocType = null, $assocId = null)
|
||||
{
|
||||
$params = [(int) $logId];
|
||||
if (isset($assocType)) {
|
||||
$params[] = (int) $assocType;
|
||||
$params[] = (int) $assocId;
|
||||
}
|
||||
|
||||
$result = $this->retrieve(
|
||||
'SELECT * FROM email_log WHERE log_id = ?' .
|
||||
(isset($assocType) ? ' AND assoc_type = ? AND assoc_id = ?' : ''),
|
||||
$params
|
||||
);
|
||||
$row = $result->current();
|
||||
return $row ? $this->build((array) $row) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a log entry by event type.
|
||||
*
|
||||
* @param int $assocType
|
||||
* @param int $assocId
|
||||
* @param int $eventType
|
||||
* @param int $userId optional
|
||||
* @param ?\PKP\db\DBResultRange $rangeInfo optional
|
||||
*
|
||||
* @return DAOResultFactory<EmailLogEntry>
|
||||
*/
|
||||
public function _getByEventType($assocType, $assocId, $eventType, $userId = null, $rangeInfo = null)
|
||||
{
|
||||
$params = [
|
||||
(int) $assocType,
|
||||
(int) $assocId,
|
||||
(int) $eventType
|
||||
];
|
||||
if ($userId) {
|
||||
$params[] = $userId;
|
||||
}
|
||||
|
||||
$result = $this->retrieveRange(
|
||||
$sql = 'SELECT e.*
|
||||
FROM email_log e' .
|
||||
($userId ? ' LEFT JOIN email_log_users u ON e.log_id = u.email_log_id' : '') .
|
||||
' WHERE e.assoc_type = ? AND
|
||||
e.assoc_id = ? AND
|
||||
e.event_type = ?' .
|
||||
($userId ? ' AND u.user_id = ?' : ''),
|
||||
$params,
|
||||
$rangeInfo
|
||||
);
|
||||
|
||||
return new DAOResultFactory($result, $this, 'build', [], $sql, $params, $rangeInfo); // Counted in submissionEmails.tpl
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve all log entries for an object matching the specified association.
|
||||
*
|
||||
* @param int $assocType
|
||||
* @param int $assocId
|
||||
* @param ?\PKP\db\DBResultRange $rangeInfo optional
|
||||
*
|
||||
* @return DAOResultFactory<EmailLogEntry> containing matching EmailLogEntry ordered by sequence
|
||||
*/
|
||||
public function getByAssoc($assocType = null, $assocId = null, $rangeInfo = null)
|
||||
{
|
||||
$result = $this->retrieveRange(
|
||||
'SELECT *
|
||||
FROM email_log
|
||||
WHERE assoc_type = ?
|
||||
AND assoc_id = ?
|
||||
ORDER BY log_id DESC',
|
||||
[(int) $assocType, (int) $assocId],
|
||||
$rangeInfo
|
||||
);
|
||||
|
||||
return new DAOResultFactory($result, $this, 'build');
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function to return an EmailLogEntry object from a row.
|
||||
*
|
||||
* @param array $row
|
||||
*
|
||||
* @return EmailLogEntry
|
||||
*/
|
||||
public function build($row)
|
||||
{
|
||||
$entry = $this->newDataObject();
|
||||
$entry->setId($row['log_id']);
|
||||
$entry->setAssocType($row['assoc_type']);
|
||||
$entry->setAssocId($row['assoc_id']);
|
||||
$entry->setSenderId($row['sender_id']);
|
||||
$entry->setDateSent($this->datetimeFromDB($row['date_sent']));
|
||||
$entry->setEventType($row['event_type']);
|
||||
$entry->setFrom($row['from_address']);
|
||||
$entry->setRecipients($row['recipients']);
|
||||
$entry->setCcs($row['cc_recipients']);
|
||||
$entry->setBccs($row['bcc_recipients']);
|
||||
$entry->setSubject($row['subject']);
|
||||
$entry->setBody($row['body']);
|
||||
|
||||
Hook::call('EmailLogDAO::build', [&$entry, &$row]);
|
||||
|
||||
return $entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a new log entry.
|
||||
*
|
||||
* @param EmailLogEntry $entry
|
||||
*/
|
||||
public function insertObject($entry)
|
||||
{
|
||||
$this->update(
|
||||
sprintf(
|
||||
'INSERT INTO email_log
|
||||
(sender_id, date_sent, event_type, assoc_type, assoc_id, from_address, recipients, cc_recipients, bcc_recipients, subject, body)
|
||||
VALUES
|
||||
(?, %s, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
$this->datetimeToDB($entry->getDateSent())
|
||||
),
|
||||
[
|
||||
$entry->getSenderId(),
|
||||
$entry->getEventType(),
|
||||
$entry->getAssocType(),
|
||||
$entry->getAssocId(),
|
||||
$entry->getFrom(),
|
||||
$entry->getRecipients(),
|
||||
$entry->getCcs(),
|
||||
$entry->getBccs(),
|
||||
$entry->getSubject(),
|
||||
$entry->getBody()
|
||||
]
|
||||
);
|
||||
|
||||
$entry->setId($this->getInsertId());
|
||||
$this->_insertLogUserIds($entry);
|
||||
|
||||
return $entry->getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a single log entry for an object.
|
||||
*
|
||||
* @param int $logId
|
||||
* @param int $assocType optional
|
||||
* @param int $assocId optional
|
||||
*/
|
||||
public function deleteObject($logId, $assocType = null, $assocId = null)
|
||||
{
|
||||
$params = [(int) $logId];
|
||||
if (isset($assocType)) {
|
||||
$params[] = (int) $assocType;
|
||||
$params[] = (int) $assocId;
|
||||
}
|
||||
return $this->update(
|
||||
'DELETE FROM email_log WHERE log_id = ?' .
|
||||
(isset($assocType) ? ' AND assoc_type = ? AND assoc_id = ?' : ''),
|
||||
$params
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all log entries for an object.
|
||||
*
|
||||
* @param int $assocType
|
||||
*
|
||||
* @praam $assocId int
|
||||
*/
|
||||
public function deleteByAssoc($assocType, $assocId)
|
||||
{
|
||||
return $this->update(
|
||||
'DELETE FROM email_log WHERE assoc_type = ? AND assoc_id = ?',
|
||||
[(int) $assocType, (int) $assocId]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer all log and log users entries to another user.
|
||||
*
|
||||
* @param int $oldUserId
|
||||
* @param int $newUserId
|
||||
*/
|
||||
public function changeUser($oldUserId, $newUserId)
|
||||
{
|
||||
return [
|
||||
$this->update(
|
||||
'UPDATE email_log SET sender_id = ? WHERE sender_id = ?',
|
||||
[(int) $newUserId, (int) $oldUserId]
|
||||
),
|
||||
$this->update(
|
||||
'UPDATE email_log_users
|
||||
SET user_id = ?
|
||||
WHERE user_id = ? AND email_log_id NOT IN (SELECT t1.email_log_id
|
||||
FROM (SELECT email_log_id FROM email_log_users WHERE user_id = ?) AS t1
|
||||
INNER JOIN
|
||||
(SELECT email_log_id FROM email_log_users WHERE user_id = ?) AS t2
|
||||
ON t1.email_log_id = t2.email_log_id);',
|
||||
[(int) $newUserId, (int) $oldUserId, (int) $newUserId, (int) $oldUserId]
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Private helper methods.
|
||||
//
|
||||
/**
|
||||
* Stores the correspondent user ids of the all recipient emails.
|
||||
*
|
||||
* @param EmailLogEntry $entry
|
||||
*/
|
||||
public function _insertLogUserIds($entry)
|
||||
{
|
||||
$recipients = $entry->getRecipients();
|
||||
|
||||
// We can use a simple regex to get emails, since we don't want to validate it.
|
||||
$pattern = '/(?<=\<)[^\>]*(?=\>)/';
|
||||
preg_match_all($pattern, $recipients, $matches);
|
||||
if (!isset($matches[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($matches[0] as $emailAddress) {
|
||||
$user = Repo::user()->getByEmail($emailAddress, true);
|
||||
if ($user instanceof \PKP\user\User) {
|
||||
// We use replace here to avoid inserting duplicated entries
|
||||
// in table (sometimes the recipients can have the same email twice).
|
||||
DB::table('email_log_users')->updateOrInsert(
|
||||
['email_log_id' => $entry->getId(), 'user_id' => $user->getId()]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new email log entry.
|
||||
*
|
||||
* @return EmailLogEntry
|
||||
*/
|
||||
public function newDataObject()
|
||||
{
|
||||
return new EmailLogEntry();
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\log\EmailLogDAO', '\EmailLogDAO');
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/log/EmailLogEntry.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 EmailLogEntry
|
||||
*
|
||||
* @ingroup log
|
||||
*
|
||||
* @see EmailLogDAO
|
||||
*
|
||||
* @brief Describes an entry in the email log.
|
||||
*/
|
||||
|
||||
namespace PKP\log;
|
||||
|
||||
use APP\facades\Repo;
|
||||
|
||||
class EmailLogEntry extends \PKP\core\DataObject
|
||||
{
|
||||
//
|
||||
// Get/set methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Get user ID of sender.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSenderId()
|
||||
{
|
||||
return $this->getData('senderId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user ID of sender.
|
||||
*
|
||||
* @param int $senderId
|
||||
*/
|
||||
public function setSenderId($senderId)
|
||||
{
|
||||
$this->setData('senderId', $senderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date email was sent.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDateSent()
|
||||
{
|
||||
return $this->getData('dateSent');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set date email was sent.
|
||||
*
|
||||
* @param string $dateSent
|
||||
*/
|
||||
public function setDateSent($dateSent)
|
||||
{
|
||||
$this->setData('dateSent', $dateSent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get event type.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEventType()
|
||||
{
|
||||
return $this->getData('eventType');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set event type.
|
||||
*
|
||||
* @param int $eventType
|
||||
*/
|
||||
public function setEventType($eventType)
|
||||
{
|
||||
$this->setData('eventType', $eventType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get associated type.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAssocType()
|
||||
{
|
||||
return $this->getData('assocType');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set associated type.
|
||||
*
|
||||
* @param int $assocType
|
||||
*/
|
||||
public function setAssocType($assocType)
|
||||
{
|
||||
$this->setData('assocType', $assocType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get associated ID.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAssocId()
|
||||
{
|
||||
return $this->getData('assocId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set associated ID.
|
||||
*
|
||||
* @param int $assocId
|
||||
*/
|
||||
public function setAssocId($assocId)
|
||||
{
|
||||
$this->setData('assocId', $assocId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full name of the sender (not necessarily the same as the from address).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSenderFullName()
|
||||
{
|
||||
$senderFullName = $this->getData('senderFullName');
|
||||
|
||||
if ($senderFullName) {
|
||||
return $senderFullName;
|
||||
}
|
||||
|
||||
$sender = $this->getSenderId()
|
||||
? Repo::user()->get($this->getSenderId(), true)
|
||||
: null;
|
||||
|
||||
return $sender ? $sender->getFullName() : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the email address of sender.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getSenderEmail()
|
||||
{
|
||||
$senderEmail = & $this->getData('senderEmail');
|
||||
|
||||
if (!isset($senderEmail)) {
|
||||
$senderEmail = Repo::user()->get($this->getSenderId(), true)->getEmail();
|
||||
}
|
||||
|
||||
return ($senderEmail ? $senderEmail : '');
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Email data
|
||||
//
|
||||
|
||||
public function getFrom()
|
||||
{
|
||||
return $this->getData('from');
|
||||
}
|
||||
|
||||
public function setFrom($from)
|
||||
{
|
||||
$this->setData('from', $from);
|
||||
}
|
||||
|
||||
public function getRecipients()
|
||||
{
|
||||
return $this->getData('recipients');
|
||||
}
|
||||
|
||||
public function setRecipients($recipients)
|
||||
{
|
||||
$this->setData('recipients', $recipients);
|
||||
}
|
||||
|
||||
public function getCcs()
|
||||
{
|
||||
return $this->getData('ccs');
|
||||
}
|
||||
|
||||
public function setCcs($ccs)
|
||||
{
|
||||
$this->setData('ccs', $ccs);
|
||||
}
|
||||
|
||||
public function getBccs()
|
||||
{
|
||||
return $this->getData('bccs');
|
||||
}
|
||||
|
||||
public function setBccs($bccs)
|
||||
{
|
||||
$this->setData('bccs', $bccs);
|
||||
}
|
||||
|
||||
public function getSubject()
|
||||
{
|
||||
return $this->getData('subject');
|
||||
}
|
||||
|
||||
public function setSubject($subject)
|
||||
{
|
||||
$this->setData('subject', $subject);
|
||||
}
|
||||
|
||||
public function getBody()
|
||||
{
|
||||
return $this->getData('body');
|
||||
}
|
||||
|
||||
public function setBody($body)
|
||||
{
|
||||
$this->setData('body', $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the subject of the message with a prefix explaining the event type
|
||||
*
|
||||
* @return string Prefixed subject
|
||||
*/
|
||||
public function getPrefixedSubject()
|
||||
{
|
||||
return __('submission.event.subjectPrefix') . ' ' . $this->getSubject();
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\log\EmailLogEntry', '\EmailLogEntry');
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/log/SubmissionEmailLogDAO.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 SubmissionEmailLogDAO
|
||||
*
|
||||
* @ingroup log
|
||||
*
|
||||
* @see EmailLogDAO
|
||||
*
|
||||
* @brief Extension to EmailLogDAO for submission-specific log entries.
|
||||
*/
|
||||
|
||||
namespace PKP\log;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\submission\Submission;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use PKP\core\Core;
|
||||
use PKP\db\DAOResultFactory;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\mail\Mailable;
|
||||
use PKP\user\User;
|
||||
|
||||
class SubmissionEmailLogDAO extends EmailLogDAO
|
||||
{
|
||||
/**
|
||||
* Instantiate and return a SubmissionEmailLogEntry
|
||||
*
|
||||
* @return SubmissionEmailLogEntry
|
||||
*/
|
||||
public function newDataObject()
|
||||
{
|
||||
$returner = new SubmissionEmailLogEntry();
|
||||
$returner->setAssocType(Application::ASSOC_TYPE_SUBMISSION);
|
||||
return $returner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get submission email log entries by submission ID and event type
|
||||
*
|
||||
* @param int $submissionId
|
||||
* @param int $userId optional Return only emails sent to this user.
|
||||
*
|
||||
* @return DAOResultFactory<SubmissionEmailLogEntry>
|
||||
*/
|
||||
public function getByEventType($submissionId, $eventType, $userId = null)
|
||||
{
|
||||
return parent::_getByEventType(Application::ASSOC_TYPE_SUBMISSION, $submissionId, $eventType, $userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get submission email log entries by submission ID
|
||||
*
|
||||
* @param int $submissionId
|
||||
*
|
||||
* @return DAOResultFactory<SubmissionEmailLogEntry>
|
||||
*/
|
||||
public function getBySubmissionId($submissionId)
|
||||
{
|
||||
return $this->getByAssoc(Application::ASSOC_TYPE_SUBMISSION, $submissionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a log entry from data in a Mailable class
|
||||
*
|
||||
* @param int $eventType One of the SubmissionEmailLogEntry::SUBMISSION_EMAIL_* constants
|
||||
*
|
||||
* @return int The new log entry id
|
||||
*/
|
||||
public function logMailable(int $eventType, Mailable $mailable, Submission $submission, ?User $sender = null): int
|
||||
{
|
||||
$entry = $this->newDataObject();
|
||||
$clonedMailable = clone $mailable;
|
||||
$clonedMailable->removeFooter();
|
||||
$entry->setEventType($eventType);
|
||||
$entry->setAssocId($submission->getId());
|
||||
$entry->setDateSent(Core::getCurrentDate());
|
||||
$entry->setSenderId($sender ? $sender->getId() : 0);
|
||||
$entry->setSubject(Mail::compileParams(
|
||||
$clonedMailable->subject,
|
||||
$clonedMailable->getData(Locale::getLocale())
|
||||
));
|
||||
$entry->setBody($clonedMailable->render());
|
||||
$entry->setFrom($this->getContactString($clonedMailable->from));
|
||||
$entry->setRecipients($this->getContactString($clonedMailable->to));
|
||||
$entry->setCcs($this->getContactString($clonedMailable->cc));
|
||||
$entry->setBccs($this->getContactString($clonedMailable->bcc));
|
||||
|
||||
return $this->insertObject($entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the from or to data as a string
|
||||
*
|
||||
* @param array $addressees Expects Mailable::$to or Mailable::$from
|
||||
*/
|
||||
protected function getContactString(array $addressees): string
|
||||
{
|
||||
$contactStrings = [];
|
||||
foreach ($addressees as $addressee) {
|
||||
$contactStrings[] = isset($addressee['name'])
|
||||
? '"' . $addressee['name'] . '" <' . $addressee['address'] . '>'
|
||||
: $addressee['address'];
|
||||
}
|
||||
return join(', ', $contactStrings);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\log\SubmissionEmailLogDAO', '\SubmissionEmailLogDAO');
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/log/SubmissionEmailLogEntry.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 SubmissionEmailLogEntry
|
||||
*
|
||||
* @ingroup log
|
||||
*
|
||||
* @see SubmissionEmailLogDAO
|
||||
*
|
||||
* @brief Base class for describing an entry in the submission email log.
|
||||
*/
|
||||
|
||||
namespace PKP\log;
|
||||
|
||||
class SubmissionEmailLogEntry extends EmailLogEntry
|
||||
{
|
||||
// Author events 0x20000000
|
||||
public const SUBMISSION_EMAIL_AUTHOR_NOTIFY_REVISED_VERSION = 0x20000001;
|
||||
public const SUBMISSION_EMAIL_AUTHOR_SUBMISSION_ACK = 0x20000002;
|
||||
|
||||
// Editor events 0x30000000
|
||||
public const SUBMISSION_EMAIL_EDITOR_NOTIFY_AUTHOR = 0x30000001;
|
||||
public const SUBMISSION_EMAIL_EDITOR_ASSIGN = 0x30000002;
|
||||
public const SUBMISSION_EMAIL_EDITOR_NOTIFY_AUTHOR_UNSUITABLE = 0x30000003;
|
||||
public const SUBMISSION_EMAIL_EDITOR_RECOMMEND_NOTIFY = 0x30000004;
|
||||
public const SUBMISSION_EMAIL_NEEDS_EDITOR = 0x30000005;
|
||||
|
||||
// Reviewer events 0x40000000
|
||||
public const SUBMISSION_EMAIL_REVIEW_NOTIFY_REVIEWER = 0x40000001;
|
||||
public const SUBMISSION_EMAIL_REVIEW_THANK_REVIEWER = 0x40000002;
|
||||
public const SUBMISSION_EMAIL_REVIEW_CANCEL = 0x40000003;
|
||||
public const SUBMISSION_EMAIL_REVIEW_REMIND = 0x40000004;
|
||||
public const SUBMISSION_EMAIL_REVIEW_CONFIRM = 0x40000005;
|
||||
public const SUBMISSION_EMAIL_REVIEW_DECLINE = 0x40000006;
|
||||
public const SUBMISSION_EMAIL_REVIEW_CONFIRM_ACK = 0x40000008;
|
||||
|
||||
// Copyeditor events 0x50000000
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_COPYEDITOR = 0x50000001;
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_AUTHOR = 0x50000002;
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_FINAL = 0x50000003;
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_COMPLETE = 0x50000004;
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_AUTHOR_COMPLETE = 0x50000005;
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_FINAL_COMPLETE = 0x50000006;
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_ACKNOWLEDGE = 0x50000007;
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_AUTHOR_ACKNOWLEDGE = 0x50000008;
|
||||
public const SUBMISSION_EMAIL_COPYEDIT_NOTIFY_FINAL_ACKNOWLEDGE = 0x50000009;
|
||||
|
||||
// Proofreader events 0x60000000
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_NOTIFY_AUTHOR = 0x60000001;
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_NOTIFY_AUTHOR_COMPLETE = 0x60000002;
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_THANK_AUTHOR = 0x60000003;
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_NOTIFY_PROOFREADER = 0x60000004;
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_NOTIFY_PROOFREADER_COMPLETE = 0x60000005;
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_THANK_PROOFREADER = 0x60000006;
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_NOTIFY_LAYOUTEDITOR = 0x60000007;
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_NOTIFY_LAYOUTEDITOR_COMPLETE = 0x60000008;
|
||||
public const SUBMISSION_EMAIL_PROOFREAD_THANK_LAYOUTEDITOR = 0x60000009;
|
||||
|
||||
// Layout events 0x70000000
|
||||
public const SUBMISSION_EMAIL_LAYOUT_NOTIFY_EDITOR = 0x70000001;
|
||||
public const SUBMISSION_EMAIL_LAYOUT_THANK_EDITOR = 0x70000002;
|
||||
public const SUBMISSION_EMAIL_LAYOUT_NOTIFY_COMPLETE = 0x70000003;
|
||||
|
||||
// Index events 0x80000000
|
||||
public const SUBMISSION_EMAIL_INDEX_NOTIFY_INDEXER = 0x80000001;
|
||||
public const SUBMISSION_EMAIL_INDEX_NOTIFY_COMPLETE = 0x80000002;
|
||||
|
||||
// Discussion
|
||||
public const SUBMISSION_EMAIL_DISCUSSION_NOTIFY = 0x90000001;
|
||||
|
||||
/**
|
||||
* Set the submission ID for the log entry.
|
||||
*
|
||||
* @param int $submissionId
|
||||
*/
|
||||
public function setSubmissionId($submissionId)
|
||||
{
|
||||
return $this->setAssocId($submissionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the submission ID for the log entry.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSubmissionId()
|
||||
{
|
||||
return $this->getAssocId();
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\log\SubmissionEmailLogEntry', '\SubmissionEmailLogEntry');
|
||||
foreach ([
|
||||
'SUBMISSION_EMAIL_AUTHOR_NOTIFY_REVISED_VERSION',
|
||||
'SUBMISSION_EMAIL_EDITOR_NOTIFY_AUTHOR',
|
||||
'SUBMISSION_EMAIL_EDITOR_ASSIGN',
|
||||
'SUBMISSION_EMAIL_EDITOR_NOTIFY_AUTHOR_UNSUITABLE',
|
||||
'SUBMISSION_EMAIL_EDITOR_RECOMMEND_NOTIFY',
|
||||
'SUBMISSION_EMAIL_REVIEW_NOTIFY_REVIEWER',
|
||||
'SUBMISSION_EMAIL_REVIEW_THANK_REVIEWER',
|
||||
'SUBMISSION_EMAIL_REVIEW_CANCEL',
|
||||
'SUBMISSION_EMAIL_REVIEW_REMIND',
|
||||
'SUBMISSION_EMAIL_REVIEW_CONFIRM',
|
||||
'SUBMISSION_EMAIL_REVIEW_DECLINE',
|
||||
'SUBMISSION_EMAIL_REVIEW_CONFIRM_ACK',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_COPYEDITOR',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_AUTHOR',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_FINAL',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_COMPLETE',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_AUTHOR_COMPLETE',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_FINAL_COMPLETE',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_ACKNOWLEDGE',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_AUTHOR_ACKNOWLEDGE',
|
||||
'SUBMISSION_EMAIL_COPYEDIT_NOTIFY_FINAL_ACKNOWLEDGE',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_NOTIFY_AUTHOR',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_NOTIFY_AUTHOR_COMPLETE',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_THANK_AUTHOR',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_NOTIFY_PROOFREADER',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_NOTIFY_PROOFREADER_COMPLETE',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_THANK_PROOFREADER',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_NOTIFY_LAYOUTEDITOR',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_NOTIFY_LAYOUTEDITOR_COMPLETE',
|
||||
'SUBMISSION_EMAIL_PROOFREAD_THANK_LAYOUTEDITOR',
|
||||
'SUBMISSION_EMAIL_LAYOUT_NOTIFY_EDITOR',
|
||||
'SUBMISSION_EMAIL_LAYOUT_THANK_EDITOR',
|
||||
'SUBMISSION_EMAIL_LAYOUT_NOTIFY_COMPLETE',
|
||||
] as $constantName) {
|
||||
define($constantName, constant('SubmissionEmailLogEntry::' . $constantName));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/log/event/Collector.php
|
||||
*
|
||||
* Copyright (c) 2014-2023 Simon Fraser University
|
||||
* Copyright (c) 2000-2023 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 log entries
|
||||
*/
|
||||
|
||||
namespace PKP\log\event;
|
||||
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
use PKP\core\interfaces\CollectorInterface;
|
||||
use PKP\plugins\Hook;
|
||||
|
||||
class Collector implements CollectorInterface
|
||||
{
|
||||
public DAO $dao;
|
||||
protected ?int $assocType = null;
|
||||
protected ?array $assocIds = null;
|
||||
protected ?array $userIds = null;
|
||||
public ?int $count = null;
|
||||
public ?int $offset = null;
|
||||
|
||||
public function __construct(DAO $dao)
|
||||
{
|
||||
$this->dao = $dao;
|
||||
}
|
||||
|
||||
public function getCount(): int
|
||||
{
|
||||
return $this->dao->getCount($this);
|
||||
}
|
||||
|
||||
public function getIds(): Collection
|
||||
{
|
||||
return $this->dao->getIds($this);
|
||||
}
|
||||
|
||||
public function getMany(): LazyCollection
|
||||
{
|
||||
return $this->dao->getMany($this);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param null|int $assocType One of the Application::ASSOC_TYPE_ constants
|
||||
* @param null|array $assocIds Match for the specified assoc type
|
||||
*/
|
||||
public function filterByAssoc(?int $assocType, ?array $assocIds = null): self
|
||||
{
|
||||
$this->assocType = $assocType;
|
||||
$this->assocIds = $assocIds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function filterByUserIds(?array $userIds): self
|
||||
{
|
||||
$this->userIds = $userIds;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function limit(?int $count): self
|
||||
{
|
||||
$this->count = $count;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function offset(?int $offset): self
|
||||
{
|
||||
$this->offset = $offset;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getQueryBuilder(): Builder
|
||||
{
|
||||
$q = DB::table($this->dao->table . ' as e')
|
||||
->select(['e.*'])
|
||||
->when(!is_null($this->assocType), function (Builder $q) {
|
||||
return $q->where('assoc_type', $this->assocType);
|
||||
})
|
||||
->when(!is_null($this->assocIds), function (Builder $q) {
|
||||
return $q->whereIn('assoc_id', $this->assocIds);
|
||||
})
|
||||
->when(!is_null($this->userIds), function (Builder $q) {
|
||||
return $q->whereIn('user_id', $this->userIds);
|
||||
})
|
||||
->orderBy('date_logged', 'desc')
|
||||
->when(!is_null($this->count), function (Builder $q) {
|
||||
return $q->limit($this->count);
|
||||
})
|
||||
->when(!is_null($this->count) && !is_null($this->offset), function (Builder $q) {
|
||||
return $q->offset($this->offset);
|
||||
});
|
||||
|
||||
Hook::call('EventLog::Collector::getQueryBuilder', [&$q, $this]);
|
||||
|
||||
return $q;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/log/event/DAO.php
|
||||
*
|
||||
* Copyright (c) 2014-2023 Simon Fraser University
|
||||
* Copyright (c) 2000-2023 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class DAO
|
||||
*
|
||||
* @brief Read and write event information to the database.
|
||||
*/
|
||||
|
||||
namespace PKP\log\event;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\LazyCollection;
|
||||
use PKP\core\EntityDAO;
|
||||
use PKP\services\PKPSchemaService;
|
||||
|
||||
class DAO extends EntityDAO
|
||||
{
|
||||
/** @copydoc EntityDAO::$schema */
|
||||
public $schema = PKPSchemaService::SCHEMA_EVENT_LOG;
|
||||
|
||||
/** @copydoc EntityDAO::$table */
|
||||
public $table = 'event_log';
|
||||
|
||||
/** @copydoc EntityDAO::$settingsTable */
|
||||
public $settingsTable = 'event_log_settings';
|
||||
|
||||
/** @copydoc EntityDAO::$primaryKeyColumn */
|
||||
public $primaryKeyColumn = 'log_id';
|
||||
|
||||
/** @copydoc EntityDAO::$primaryTableColumns */
|
||||
public $primaryTableColumns = [
|
||||
'id' => 'log_id',
|
||||
'assocType' => 'assoc_type',
|
||||
'assocId' => 'assoc_id',
|
||||
'userId' => 'user_id',
|
||||
'dateLogged' => 'date_logged',
|
||||
'eventType' => 'event_type',
|
||||
'message' => 'message',
|
||||
'isTranslated' => 'is_translated',
|
||||
];
|
||||
|
||||
/**
|
||||
* Instantiate a new DataObject
|
||||
*/
|
||||
public function newDataObject(): EventLogEntry
|
||||
{
|
||||
return app(EventLogEntry::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a log entry exists
|
||||
*/
|
||||
public function exists(int $id): bool
|
||||
{
|
||||
return DB::table($this->table)
|
||||
->where($this->primaryKeyColumn, '=', $id)
|
||||
->exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an event log entry
|
||||
*/
|
||||
public function get(int $id): ?EventLogEntry
|
||||
{
|
||||
$row = DB::table($this->table)
|
||||
->where($this->primaryKeyColumn, $id)
|
||||
->first();
|
||||
return $row ? $this->fromRow($row) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of log entries matching the configured query
|
||||
*/
|
||||
public function getCount(Collector $query): int
|
||||
{
|
||||
return $query
|
||||
->getQueryBuilder()
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of ids matching the configured query
|
||||
*/
|
||||
public function getIds(Collector $query): Collection
|
||||
{
|
||||
return $query
|
||||
->getQueryBuilder()
|
||||
->select('e.' . $this->primaryKeyColumn)
|
||||
->pluck('e.' . $this->primaryKeyColumn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a collection of log entries matching the configured query
|
||||
*/
|
||||
public function getMany(Collector $query): LazyCollection
|
||||
{
|
||||
$rows = $query
|
||||
->getQueryBuilder()
|
||||
->get();
|
||||
|
||||
return LazyCollection::make(function () use ($rows) {
|
||||
foreach ($rows as $row) {
|
||||
yield $row->log_id => $this->fromRow($row);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc EntityDAO::fromRow()
|
||||
*/
|
||||
public function fromRow(object $row): EventLogEntry
|
||||
{
|
||||
$logEntry = parent::fromRow($row);
|
||||
$schema = $this->schemaService->get($this->schema);
|
||||
|
||||
DB::table($this->settingsTable)
|
||||
->where($this->primaryKeyColumn, '=', $row->{$this->primaryKeyColumn})
|
||||
->get()
|
||||
->each(function ($row) use ($logEntry, $schema) {
|
||||
if (!empty($schema->properties->{$row->setting_name})) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Retrieve custom properties
|
||||
if (!empty($row->setting_type)) {
|
||||
$logEntry->setData(
|
||||
$row->setting_name,
|
||||
$this->convertFromDB(
|
||||
$row->setting_value,
|
||||
$row->setting_type
|
||||
),
|
||||
empty($row->locale) ? null : $row->locale
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return $logEntry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc EntityDAO::insert()
|
||||
*/
|
||||
public function insert(EventLogEntry $eventLog): int
|
||||
{
|
||||
return parent::_insert($eventLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* @copydoc EntityDAO::delete()
|
||||
*/
|
||||
public function delete(EventLogEntry $eventLog)
|
||||
{
|
||||
parent::_delete($eventLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer all log entries to another user.
|
||||
*/
|
||||
public function changeUser(int $oldUserId, int $newUserId)
|
||||
{
|
||||
DB::table($this->table)->where('user_id', $oldUserId)->update(['user_id' => $newUserId]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/log/event/EventLogEntry.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 EventLogEntry
|
||||
*
|
||||
* @ingroup log
|
||||
*
|
||||
* @brief Describes an entry in the event log.
|
||||
*/
|
||||
|
||||
namespace PKP\log\event;
|
||||
|
||||
use APP\core\Application;
|
||||
use APP\facades\Repo;
|
||||
use PKP\db\DAORegistry;
|
||||
use PKP\facades\Locale;
|
||||
use PKP\submission\reviewAssignment\ReviewAssignment;
|
||||
use PKP\submissionFile\SubmissionFile;
|
||||
|
||||
class EventLogEntry extends \PKP\core\DataObject
|
||||
{
|
||||
// Information Center events
|
||||
public const SUBMISSION_LOG_NOTE_POSTED = 0x01000000;
|
||||
public const SUBMISSION_LOG_MESSAGE_SENT = 0x01000001;
|
||||
|
||||
//
|
||||
// Get/set methods
|
||||
//
|
||||
|
||||
/**
|
||||
* Get user ID of user that initiated the event.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->getData('userId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set user ID of user that initiated the event.
|
||||
*
|
||||
* @param int $userId
|
||||
*/
|
||||
public function setUserId($userId)
|
||||
{
|
||||
$this->setData('userId', $userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date entry was logged.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDateLogged()
|
||||
{
|
||||
return $this->getData('dateLogged');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set date entry was logged.
|
||||
*
|
||||
* @param string $dateLogged
|
||||
*/
|
||||
public function setDateLogged($dateLogged)
|
||||
{
|
||||
$this->setData('dateLogged', $dateLogged);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get event type.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getEventType()
|
||||
{
|
||||
return $this->getData('eventType');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set event type.
|
||||
*
|
||||
* @param int $eventType
|
||||
*/
|
||||
public function setEventType($eventType)
|
||||
{
|
||||
$this->setData('eventType', $eventType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get associated type.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAssocType()
|
||||
{
|
||||
return $this->getData('assocType');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set associated type.
|
||||
*
|
||||
* @param int $assocType
|
||||
*/
|
||||
public function setAssocType($assocType)
|
||||
{
|
||||
$this->setData('assocType', $assocType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get associated ID.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAssocId()
|
||||
{
|
||||
return $this->getData('assocId');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set associated ID.
|
||||
*
|
||||
* @param int $assocId
|
||||
*/
|
||||
public function setAssocId($assocId)
|
||||
{
|
||||
$this->setData('assocId', $assocId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom log message (either locale key or literal string).
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage()
|
||||
{
|
||||
return $this->getData('message');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom log message (either locale key or literal string).
|
||||
*
|
||||
* @param string $message
|
||||
*/
|
||||
public function setMessage($message)
|
||||
{
|
||||
$this->setData('message', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get flag indicating whether or not message is translated.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getIsTranslated()
|
||||
{
|
||||
return $this->getData('isTranslated');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set flag indicating whether or not message is translated.
|
||||
*
|
||||
* @param int $isTranslated
|
||||
*/
|
||||
public function setIsTranslated($isTranslated)
|
||||
{
|
||||
$this->setData('isTranslated', $isTranslated);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get translated message, translating it if necessary.
|
||||
*
|
||||
* @param string $locale optional
|
||||
* @param bool $hideReviewerName optional Don't reveal reviewer names in
|
||||
* log descriptions.
|
||||
*/
|
||||
public function getTranslatedMessage($locale = null, $hideReviewerName = false)
|
||||
{
|
||||
$message = $this->getMessage();
|
||||
// If it's already translated, just return the message.
|
||||
if ($this->getData('isTranslated')) {
|
||||
return $message;
|
||||
}
|
||||
|
||||
// Otherwise, translate it and include parameters.
|
||||
if ($locale === null) {
|
||||
$locale = Locale::getLocale();
|
||||
}
|
||||
|
||||
$eventLog = clone $this;
|
||||
|
||||
if ($hideReviewerName) {
|
||||
$reviewAssignmentDao = DAORegistry::getDAO('ReviewAssignmentDAO'); /** @var \PKP\submission\reviewAssignment\ReviewAssignmentDAO $reviewAssignmentDao */
|
||||
// Reviewer activity log entries (assigning, accepting, declining)
|
||||
if ($eventLog->getData('reviewerName')) {
|
||||
$anonymousAuthor = true;
|
||||
if ($reviewAssignmentId = $eventLog->getData('reviewAssignmentId')) {
|
||||
$reviewAssignment = $reviewAssignmentDao->getById($reviewAssignmentId);
|
||||
if ($reviewAssignment && !in_array($reviewAssignment->getReviewMethod(), [ReviewAssignment::SUBMISSION_REVIEW_METHOD_ANONYMOUS, ReviewAssignment::SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS])) {
|
||||
$anonymousAuthor = false;
|
||||
}
|
||||
}
|
||||
if ($anonymousAuthor) {
|
||||
$eventLog->setData('reviewerName', __('editor.review.anonymousReviewer'));
|
||||
}
|
||||
}
|
||||
// Files submitted by reviewers
|
||||
$fileStage = $eventLog->getData('fileStage');
|
||||
if ($fileStage && $fileStage === SubmissionFile::SUBMISSION_FILE_REVIEW_ATTACHMENT) {
|
||||
$submissionFileId = $eventLog->getData('submissionFileId');
|
||||
assert($eventLog->getData('fileId') && $eventLog->getData('submissionId') && $submissionFileId);
|
||||
$anonymousAuthor = true;
|
||||
$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])) {
|
||||
$anonymousAuthor = false;
|
||||
}
|
||||
}
|
||||
if ($eventLog->getData('username') && $anonymousAuthor) {
|
||||
$eventLog->setData('username', __('editor.review.anonymousReviewer'));
|
||||
$filenames = $eventLog->getData('filename');
|
||||
$eventLog->setData('filename', array_map(function (string $value) {
|
||||
return '';
|
||||
}, $filenames));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$params = [];
|
||||
foreach ($eventLog->getAllData() as $key => $data) {
|
||||
if (!is_array($data)) {
|
||||
$params[$key] = $eventLog->getData($key);
|
||||
continue;
|
||||
}
|
||||
|
||||
$params[$key] = $eventLog->getData($key, $locale);
|
||||
}
|
||||
|
||||
return __($message, $params, $locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the full name of the user.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUserFullName()
|
||||
{
|
||||
$userFullName = & $this->getData('userFullName');
|
||||
if (!isset($userFullName) && $this->getUserId()) {
|
||||
$userFullName = Repo::user()->get($this->getUserId(), true)->getFullName();
|
||||
}
|
||||
|
||||
return $userFullName ?: '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the email address of the user.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getUserEmail()
|
||||
{
|
||||
$userEmail = $this->getData('userEmail');
|
||||
|
||||
if (!isset($userEmail)) {
|
||||
$userEmail = Repo::user()->get($this->getUserId(), true)->getEmail();
|
||||
}
|
||||
|
||||
return $userEmail ?: '';
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\log\event\EventLogEntry', '\EventLogEntry');
|
||||
define('SUBMISSION_LOG_NOTE_POSTED', EventLogEntry::SUBMISSION_LOG_NOTE_POSTED);
|
||||
define('SUBMISSION_LOG_MESSAGE_SENT', EventLogEntry::SUBMISSION_LOG_MESSAGE_SENT);
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/log/event/PKPSubmissionEventLogEntry.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 PKPSubmissionEventLogEntry
|
||||
*
|
||||
* @ingroup log
|
||||
*
|
||||
* @brief Describes an entry in the submission history log.
|
||||
*/
|
||||
|
||||
namespace PKP\log\event;
|
||||
|
||||
use APP\core\Application;
|
||||
|
||||
class PKPSubmissionEventLogEntry extends EventLogEntry
|
||||
{
|
||||
public const SUBMISSION_LOG_SUBMISSION_SUBMIT = 0x10000001;
|
||||
public const SUBMISSION_LOG_METADATA_UPDATE = 0x10000002;
|
||||
public const SUBMISSION_LOG_ADD_PARTICIPANT = 0x10000003;
|
||||
public const SUBMISSION_LOG_REMOVE_PARTICIPANT = 0x10000004;
|
||||
|
||||
public const SUBMISSION_LOG_METADATA_PUBLISH = 0x10000006;
|
||||
public const SUBMISSION_LOG_METADATA_UNPUBLISH = 0x10000007;
|
||||
|
||||
public const SUBMISSION_LOG_CREATE_VERSION = 0x10000008;
|
||||
|
||||
public const SUBMISSION_LOG_COPYRIGHT_AGREED = 0x10000009;
|
||||
|
||||
public const SUBMISSION_LOG_EDITOR_DECISION = 0x30000003;
|
||||
public const SUBMISSION_LOG_EDITOR_RECOMMENDATION = 0x30000004;
|
||||
public const SUBMISSION_LOG_DECISION_EMAIL_SENT = 0x30000007;
|
||||
|
||||
public const SUBMISSION_LOG_REVIEW_ASSIGN = 0x40000001;
|
||||
public const SUBMISSION_LOG_REVIEW_REINSTATED = 0x40000005;
|
||||
public const SUBMISSION_LOG_REVIEW_ACCEPT = 0x40000006;
|
||||
public const SUBMISSION_LOG_REVIEW_DECLINE = 0x40000007;
|
||||
public const SUBMISSION_LOG_REVIEW_UNCONSIDERED = 0x40000009;
|
||||
public const SUBMISSION_LOG_REVIEW_SET_DUE_DATE = 0x40000011;
|
||||
public const SUBMISSION_LOG_REVIEW_CLEAR = 0x40000014;
|
||||
public const SUBMISSION_LOG_REVIEW_READY = 0x40000018;
|
||||
public const SUBMISSION_LOG_REVIEW_CONFIRMED = 0x40000019;
|
||||
public const SUBMISSION_LOG_REVIEW_REMIND = 0x40000020;
|
||||
public const SUBMISSION_LOG_REVIEW_REMIND_AUTO = 0x40000021;
|
||||
|
||||
|
||||
//
|
||||
// Getters/setters
|
||||
//
|
||||
/**
|
||||
* Set the submission ID
|
||||
*/
|
||||
public function setSubmissionId($submissionId)
|
||||
{
|
||||
return $this->setAssocId($submissionId);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the submission ID
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getSubmissionId()
|
||||
{
|
||||
return $this->getAssocId();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the assoc ID
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAssocType()
|
||||
{
|
||||
return Application::ASSOC_TYPE_SUBMISSION;
|
||||
}
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\log\event\PKPSubmissionEventLogEntry', '\PKPSubmissionEventLogEntry');
|
||||
foreach ([
|
||||
'SUBMISSION_LOG_SUBMISSION_SUBMIT',
|
||||
'SUBMISSION_LOG_METADATA_UPDATE',
|
||||
'SUBMISSION_LOG_ADD_PARTICIPANT',
|
||||
'SUBMISSION_LOG_REMOVE_PARTICIPANT',
|
||||
'SUBMISSION_LOG_METADATA_PUBLISH',
|
||||
'SUBMISSION_LOG_METADATA_UNPUBLISH',
|
||||
'SUBMISSION_LOG_CREATE_VERSION',
|
||||
'SUBMISSION_LOG_EDITOR_DECISION',
|
||||
'SUBMISSION_LOG_EDITOR_RECOMMENDATION',
|
||||
'SUBMISSION_LOG_REVIEW_ASSIGN',
|
||||
'SUBMISSION_LOG_REVIEW_REINSTATED',
|
||||
'SUBMISSION_LOG_REVIEW_DECLINE',
|
||||
'SUBMISSION_LOG_REVIEW_UNCONSIDERED',
|
||||
'SUBMISSION_LOG_REVIEW_SET_DUE_DATE',
|
||||
'SUBMISSION_LOG_REVIEW_CLEAR',
|
||||
'SUBMISSION_LOG_REVIEW_READY',
|
||||
'SUBMISSION_LOG_REVIEW_CONFIRMED',
|
||||
] as $constantName) {
|
||||
define($constantName, constant('\PKPSubmissionEventLogEntry::' . $constantName));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/log/event/Repository.php
|
||||
*
|
||||
* Copyright (c) 2014-2023 Simon Fraser University
|
||||
* Copyright (c) 2000-2023 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 event log entries.
|
||||
*/
|
||||
|
||||
namespace PKP\log\event;
|
||||
|
||||
use APP\facades\Repo;
|
||||
use PKP\context\Context;
|
||||
use PKP\core\PKPApplication;
|
||||
use PKP\core\PKPRequest;
|
||||
use PKP\plugins\Hook;
|
||||
use PKP\services\PKPSchemaService;
|
||||
use PKP\validation\ValidatorFactory;
|
||||
|
||||
class Repository
|
||||
{
|
||||
public DAO $dao;
|
||||
|
||||
// The name of the class to map this entity to its schema
|
||||
public string $schemaMap = maps\Schema::class;
|
||||
|
||||
protected PKPRequest $request;
|
||||
|
||||
protected PKPSchemaService $schemaService;
|
||||
|
||||
public function __construct(DAO $dao, PKPRequest $request, PKPSchemaService $schemaService)
|
||||
{
|
||||
$this->dao = $dao;
|
||||
$this->request = $request;
|
||||
$this->schemaService = $schemaService;
|
||||
}
|
||||
|
||||
/** @copydoc DAO::newDataObject() */
|
||||
public function newDataObject(array $params = []): EventLogEntry
|
||||
{
|
||||
$object = $this->dao->newDataObject();
|
||||
if (!empty($params)) {
|
||||
$object->setAllData($params);
|
||||
}
|
||||
return $object;
|
||||
}
|
||||
|
||||
/** @copydoc DAO::getByKey() */
|
||||
public function get(int $key): ?EventLogEntry
|
||||
{
|
||||
return $this->dao->get($key);
|
||||
}
|
||||
|
||||
/** @copydoc DAO::getCollector() */
|
||||
public function getCollector(): Collector
|
||||
{
|
||||
return app(Collector::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an instance of the map class for mapping
|
||||
* log entries to their schema
|
||||
*/
|
||||
public function getSchemaMap(): maps\Schema
|
||||
{
|
||||
return app('maps')->withExtensions($this->schemaMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate properties for an event log entry
|
||||
*
|
||||
* Perform validation checks on data used to add or edit an event log entry.
|
||||
*
|
||||
* @param array $props A key/value array with the new data to validate
|
||||
* @param array $allowedLocales The context's supported locales
|
||||
* @param string $primaryLocale The context's primary locale
|
||||
*
|
||||
* @return array A key/value array with validation errors. Empty if no errors
|
||||
*/
|
||||
public function validate(?EventLogEntry $object, array $props, Context $context): array
|
||||
{
|
||||
$allowedLocales = $context->getSupportedSubmissionLocales();;
|
||||
$primaryLocale = $context->getPrimaryLocale();
|
||||
|
||||
$validator = ValidatorFactory::make(
|
||||
$props,
|
||||
$this->schemaService->getValidationRules($this->dao->schema, $allowedLocales)
|
||||
);
|
||||
|
||||
// Check required fields
|
||||
ValidatorFactory::required(
|
||||
$validator,
|
||||
$object,
|
||||
$this->schemaService->getRequiredProps($this->dao->schema),
|
||||
$this->schemaService->getMultilingualProps($this->dao->schema),
|
||||
$allowedLocales,
|
||||
$primaryLocale
|
||||
);
|
||||
|
||||
// Check for input from disallowed locales
|
||||
ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);
|
||||
|
||||
$errors = [];
|
||||
|
||||
if ($validator->fails()) {
|
||||
$errors = $this->schemaService->formatValidationErrors($validator->errors());
|
||||
}
|
||||
|
||||
Hook::call('EventLog::validate', [&$errors, $object, $props, $allowedLocales, $primaryLocale]);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/** @copydoc DAO::insert() */
|
||||
public function add(EventLogEntry $logEntry): int
|
||||
{
|
||||
$id = $this->dao->insert($logEntry);
|
||||
Hook::call('EventLog::add', [$logEntry]);
|
||||
|
||||
// Stamp the submission status modification date without triggering edit event
|
||||
if ($logEntry->getData('assocType') === PKPApplication::ASSOC_TYPE_SUBMISSION) {
|
||||
$submission = Repo::submission()->get($logEntry->getData('assocId'));
|
||||
$submission->stampLastActivity();
|
||||
Repo::submission()->dao->update($submission);
|
||||
}
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
||||
/** @copydoc DAO::delete() */
|
||||
public function delete(EventLogEntry $logEntry)
|
||||
{
|
||||
Hook::call('EventLog::delete::before', [$logEntry]);
|
||||
$this->dao->delete($logEntry);
|
||||
Hook::call('EventLog::delete', [$logEntry]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a collection of categories
|
||||
*/
|
||||
public function deleteMany(Collector $collector)
|
||||
{
|
||||
foreach ($collector->getMany() as $logEntry) {
|
||||
/** @var EventLogEntry $logEntry */
|
||||
$this->delete($logEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file classes/log/event/SubmissionFileEventLogEntry.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 SubmissionFileEventLogEntry
|
||||
*
|
||||
* @ingroup log
|
||||
*
|
||||
* @brief Describes an entry in the submission file history log.
|
||||
*/
|
||||
|
||||
namespace PKP\log\event;
|
||||
|
||||
class SubmissionFileEventLogEntry extends EventLogEntry
|
||||
{
|
||||
// File upload/delete event types.
|
||||
public const SUBMISSION_LOG_FILE_UPLOAD = 0x50000001;
|
||||
public const SUBMISSION_LOG_FILE_DELETE = 0x50000002;
|
||||
public const SUBMISSION_LOG_FILE_REVISION_UPLOAD = 0x50000008;
|
||||
public const SUBMISSION_LOG_FILE_EDIT = 0x50000010;
|
||||
|
||||
// Audit events
|
||||
public const SUBMISSION_LOG_FILE_AUDITOR_ASSIGN = 0x50000004;
|
||||
public const SUBMISSION_LOG_FILE_AUDITOR_CLEAR = 0x50000005;
|
||||
public const SUBMISSION_LOG_FILE_AUDIT_UPLOAD = 0x50000006;
|
||||
public const SUBMISSION_LOG_FILE_SIGNOFF_SIGNOFF = 0x50000007;
|
||||
|
||||
// Deprecated events. Preserve for historical logs
|
||||
public const SUBMISSION_LOG_FILE_REVISION_DELETE = 0x50000009; // uses submission.event.revisionDeleted
|
||||
}
|
||||
|
||||
if (!PKP_STRICT_MODE) {
|
||||
class_alias('\PKP\log\event\SubmissionFileEventLogEntry', '\SubmissionFileEventLogEntry');
|
||||
foreach ([
|
||||
'SUBMISSION_LOG_FILE_UPLOAD',
|
||||
'SUBMISSION_LOG_FILE_DELETE',
|
||||
'SUBMISSION_LOG_FILE_REVISION_UPLOAD',
|
||||
'SUBMISSION_LOG_FILE_EDIT',
|
||||
'SUBMISSION_LOG_FILE_AUDITOR_ASSIGN',
|
||||
'SUBMISSION_LOG_FILE_AUDITOR_CLEAR',
|
||||
'SUBMISSION_LOG_FILE_AUDIT_UPLOAD',
|
||||
'SUBMISSION_LOG_FILE_SIGNOFF_SIGNOFF',
|
||||
'SUBMISSION_LOG_FILE_REVISION_DELETE',
|
||||
] as $constantName) {
|
||||
define($constantName, constant('\SubmissionFileEventLogEntry::' . $constantName));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* @file classes/log/event/maps/Schema.php
|
||||
*
|
||||
* Copyright (c) 2014-2023 Simon Fraser University
|
||||
* Copyright (c) 2000-2023 John Willinsky
|
||||
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
||||
*
|
||||
* @class Schema
|
||||
*
|
||||
* @brief Map event log entries to the properties defined in the event log schema
|
||||
*/
|
||||
|
||||
namespace PKP\log\event\maps;
|
||||
|
||||
use Illuminate\Support\Enumerable;
|
||||
use PKP\log\event\EventLogEntry;
|
||||
use PKP\services\PKPSchemaService;
|
||||
|
||||
class Schema extends \PKP\core\maps\Schema
|
||||
{
|
||||
public Enumerable $collection;
|
||||
|
||||
public string $schema = PKPSchemaService::SCHEMA_EVENT_LOG;
|
||||
|
||||
/**
|
||||
* Map an event log
|
||||
*
|
||||
* Includes all properties in the event log entry schema.
|
||||
*/
|
||||
public function map(EventLogEntry $item): array
|
||||
{
|
||||
return $this->mapByProperties($this->getProps(), $item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Summarize an event log
|
||||
*
|
||||
* Includes properties with the apiSummary flag in the event log entry schema.
|
||||
*/
|
||||
public function summarize(EventLogEntry $entry): array
|
||||
{
|
||||
return $this->mapByProperties($this->getSummaryProps(), $entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a collection of event log entries
|
||||
*
|
||||
* @see self::map
|
||||
*/
|
||||
public function mapMany(Enumerable $collection): Enumerable
|
||||
{
|
||||
$this->collection = $collection;
|
||||
return $collection->map(function ($category) {
|
||||
return $this->map($category);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Summarize a collection of event log entries
|
||||
*
|
||||
* @see self::summarize
|
||||
*/
|
||||
public function summarizeMany(Enumerable $collection): Enumerable
|
||||
{
|
||||
$this->collection = $collection;
|
||||
return $collection->map(function ($category) {
|
||||
return $this->summarize($category);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Map schema properties of an event log entry to an assoc array
|
||||
*/
|
||||
protected function mapByProperties(array $props, EventLogEntry $entry): array
|
||||
{
|
||||
$output = [];
|
||||
|
||||
foreach ($props as $prop) {
|
||||
switch ($prop) {
|
||||
default:
|
||||
$output[$prop] = $entry->getData($prop);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user