745 lines
25 KiB
PHP
745 lines
25 KiB
PHP
<?php
|
|
/**
|
|
* @defgroup controllers_grid_issues Issues Grid
|
|
* The Issues Grid implements the management interface allowing editors to
|
|
* manage future and archived issues.
|
|
*/
|
|
|
|
/**
|
|
* @file controllers/grid/issues/IssueGridHandler.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 IssueGridHandler
|
|
*
|
|
* @ingroup controllers_grid_issues
|
|
*
|
|
* @brief Handle issues grid requests.
|
|
*/
|
|
|
|
namespace APP\controllers\grid\issues;
|
|
|
|
use APP\controllers\grid\issues\form\IssueAccessForm;
|
|
use APP\controllers\grid\issues\form\IssueForm;
|
|
use APP\controllers\grid\pubIds\form\AssignPublicIdentifiersForm;
|
|
use APP\controllers\tab\pubIds\form\PublicIdentifiersForm;
|
|
use APP\core\Application;
|
|
use APP\core\Request;
|
|
use APP\facades\Repo;
|
|
use APP\file\PublicFileManager;
|
|
use APP\issue\Collector;
|
|
use APP\jobs\notifications\IssuePublishedNotifyUsers;
|
|
use APP\notification\Notification;
|
|
use APP\notification\NotificationManager;
|
|
use APP\publication\Publication;
|
|
use APP\security\authorization\OjsIssueRequiredPolicy;
|
|
use APP\submission\Submission;
|
|
use APP\template\TemplateManager;
|
|
use Illuminate\Support\Facades\Bus;
|
|
use PKP\controllers\grid\GridColumn;
|
|
use PKP\controllers\grid\GridHandler;
|
|
use PKP\core\Core;
|
|
use PKP\core\JSONMessage;
|
|
use PKP\core\PKPApplication;
|
|
use PKP\db\DAO;
|
|
use PKP\db\DAORegistry;
|
|
use PKP\facades\Locale;
|
|
use PKP\file\TemporaryFileManager;
|
|
use PKP\mail\Mailer;
|
|
use PKP\notification\NotificationSubscriptionSettingsDAO;
|
|
use PKP\notification\PKPNotification;
|
|
use PKP\plugins\Hook;
|
|
use PKP\plugins\PluginRegistry;
|
|
use PKP\security\authorization\ContextAccessPolicy;
|
|
use PKP\security\Role;
|
|
|
|
class IssueGridHandler extends GridHandler
|
|
{
|
|
/**
|
|
* Constructor
|
|
*/
|
|
public function __construct()
|
|
{
|
|
parent::__construct();
|
|
$this->addRoleAssignment(
|
|
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
|
|
[
|
|
'fetchGrid', 'fetchRow',
|
|
'addIssue', 'editIssue', 'editIssueData', 'updateIssue',
|
|
'uploadFile', 'deleteCoverImage',
|
|
'issueToc',
|
|
'issueGalleys',
|
|
'deleteIssue', 'publishIssue', 'unpublishIssue', 'setCurrentIssue',
|
|
'identifiers', 'updateIdentifiers', 'clearPubId', 'clearIssueObjectsPubIds',
|
|
'access', 'updateAccess',
|
|
]
|
|
);
|
|
}
|
|
|
|
|
|
//
|
|
// Implement template methods from PKPHandler
|
|
//
|
|
/**
|
|
* @copydoc PKPHandler::authorize()
|
|
*/
|
|
public function authorize($request, &$args, $roleAssignments)
|
|
{
|
|
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
|
|
|
|
// If a signoff ID was specified, authorize it.
|
|
if ($request->getUserVar('issueId')) {
|
|
$this->addPolicy(new OjsIssueRequiredPolicy($request, $args));
|
|
}
|
|
|
|
return parent::authorize($request, $args, $roleAssignments);
|
|
}
|
|
|
|
/**
|
|
* @copydoc GridHandler::initialize()
|
|
*
|
|
* @param null|mixed $args
|
|
*/
|
|
public function initialize($request, $args = null)
|
|
{
|
|
parent::initialize($request, $args);
|
|
|
|
// Grid columns.
|
|
$issueGridCellProvider = new IssueGridCellProvider();
|
|
|
|
// Issue identification
|
|
$this->addColumn(
|
|
new GridColumn(
|
|
'identification',
|
|
'issue.issue',
|
|
null,
|
|
null,
|
|
$issueGridCellProvider
|
|
)
|
|
);
|
|
|
|
$this->_addCenterColumns($issueGridCellProvider);
|
|
|
|
// Number of articles
|
|
$this->addColumn(
|
|
new GridColumn(
|
|
'numArticles',
|
|
'editor.issues.numArticles',
|
|
null,
|
|
null,
|
|
$issueGridCellProvider
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Private function to add central columns to the grid.
|
|
* May be overridden by subclasses.
|
|
*
|
|
* @param IssueGridCellProvider $issueGridCellProvider
|
|
*/
|
|
protected function _addCenterColumns($issueGridCellProvider)
|
|
{
|
|
// Default implementation does nothing.
|
|
}
|
|
|
|
/**
|
|
* Get the row handler - override the default row handler
|
|
*
|
|
* @return IssueGridRow
|
|
*/
|
|
protected function getRowInstance()
|
|
{
|
|
return new IssueGridRow();
|
|
}
|
|
|
|
//
|
|
// Public operations
|
|
//
|
|
/**
|
|
* An action to add a new issue
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*/
|
|
public function addIssue($args, $request)
|
|
{
|
|
// Calling editIssueData with an empty ID will add
|
|
// a new issue.
|
|
return $this->editIssueData($args, $request);
|
|
}
|
|
|
|
/**
|
|
* An action to edit an issue
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function editIssue($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$templateMgr = TemplateManager::getManager($request);
|
|
if ($issue) {
|
|
$templateMgr->assign('issueId', $issue->getId());
|
|
}
|
|
$publisherIdEnabled = in_array('issue', (array) $request->getContext()->getData('enablePublisherId'));
|
|
$pubIdPlugins = PluginRegistry::getPlugins('pubIds');
|
|
if ($publisherIdEnabled || count($pubIdPlugins)) {
|
|
$templateMgr->assign('enableIdentifiers', true);
|
|
}
|
|
return new JSONMessage(true, $templateMgr->fetch('controllers/grid/issues/issue.tpl'));
|
|
}
|
|
|
|
/**
|
|
* An action to edit an issue's identifying data
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function editIssueData($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
|
|
$issueForm = new IssueForm($issue);
|
|
$issueForm->initData();
|
|
return new JSONMessage(true, $issueForm->fetch($request));
|
|
}
|
|
|
|
/**
|
|
* An action to upload an issue file. Used for issue cover images.
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function uploadFile($args, $request)
|
|
{
|
|
$user = $request->getUser();
|
|
|
|
$temporaryFileManager = new TemporaryFileManager();
|
|
$temporaryFile = $temporaryFileManager->handleUpload('uploadedFile', $user->getId());
|
|
if ($temporaryFile) {
|
|
$json = new JSONMessage(true);
|
|
$json->setAdditionalAttributes([
|
|
'temporaryFileId' => $temporaryFile->getId()
|
|
]);
|
|
return $json;
|
|
} else {
|
|
return new JSONMessage(false, __('common.uploadFailed'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete an uploaded cover image.
|
|
*
|
|
* @param array $args
|
|
* `coverImage` string Filename of the cover image to be deleted.
|
|
* `issueId` int Id of the issue this cover image is attached to
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function deleteCoverImage($args, $request)
|
|
{
|
|
assert(!empty($args['coverImage']) && !empty($args['issueId']));
|
|
|
|
// Check if the passed filename matches the filename for this issue's
|
|
// cover page.
|
|
$issue = Repo::issue()->get((int) $args['issueId']);
|
|
$context = $request->getContext();
|
|
if ($issue->getJournalId() != $context->getId()) {
|
|
return new JSONMessage(false, __('editor.issues.removeCoverImageOnDifferentContextNowAllowed'));
|
|
}
|
|
|
|
$locale = Locale::getLocale();
|
|
if ($args['coverImage'] != $issue->getCoverImage($locale)) {
|
|
return new JSONMessage(false, __('editor.issues.removeCoverImageFileNameMismatch'));
|
|
}
|
|
|
|
$file = $args['coverImage'];
|
|
|
|
// Remove cover image and alt text from issue settings
|
|
$issue->setCoverImage('', $locale);
|
|
$issue->setCoverImageAltText('', $locale);
|
|
Repo::issue()->edit($issue, []);
|
|
// Remove the file
|
|
$publicFileManager = new PublicFileManager();
|
|
if ($publicFileManager->removeContextFile($issue->getJournalId(), $file)) {
|
|
$json = new JSONMessage(true);
|
|
$json->setEvent('fileDeleted');
|
|
return $json;
|
|
} else {
|
|
return new JSONMessage(false, __('editor.issues.removeCoverImageFileNotFound'));
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Update an issue
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function updateIssue($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
|
|
$issueForm = new IssueForm($issue);
|
|
$issueForm->readInputData();
|
|
|
|
if ($issueForm->validate()) {
|
|
$issueForm->execute();
|
|
$notificationManager = new NotificationManager();
|
|
$notificationManager->createTrivialNotification($request->getUser()->getId());
|
|
return DAO::getDataChangedEvent();
|
|
} else {
|
|
return new JSONMessage(true, $issueForm->fetch($request));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* An action to edit an issue's access settings
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function access($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
|
|
$issueAccessForm = new IssueAccessForm($issue);
|
|
$issueAccessForm->initData();
|
|
return new JSONMessage(true, $issueAccessForm->fetch($request));
|
|
}
|
|
|
|
/**
|
|
* Update an issue's access settings
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function updateAccess($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
|
|
$issueAccessForm = new IssueAccessForm($issue);
|
|
$issueAccessForm->readInputData();
|
|
|
|
if ($issueAccessForm->validate()) {
|
|
$issueAccessForm->execute();
|
|
$notificationManager = new NotificationManager();
|
|
$notificationManager->createTrivialNotification($request->getUser()->getId());
|
|
return DAO::getDataChangedEvent();
|
|
} else {
|
|
return new JSONMessage(true, $issueAccessForm->fetch($request));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes an issue
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*/
|
|
public function deleteIssue($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
if (!$issue || !$request->checkCSRF()) {
|
|
return new JSONMessage(false);
|
|
}
|
|
|
|
$journal = $request->getJournal();
|
|
|
|
if ($issue->getJournalId() != $journal->getId()) {
|
|
return new JSONMessage(false);
|
|
}
|
|
|
|
// remove all published submissions and return original articles to editing queue
|
|
$submissions = Repo::submission()
|
|
->getCollector()
|
|
->filterByContextIds([$issue->getData('journalId')])
|
|
->filterByIssueIds([$issue->getId()])
|
|
->getMany();
|
|
|
|
foreach ($submissions as $submission) {
|
|
$publications = $submission->getData('publications');
|
|
foreach ($publications as $publication) {
|
|
if ($publication->getData('issueId') === (int) $issue->getId()) {
|
|
Repo::publication()->edit($publication, ['issueId' => '', 'status' => Submission::STATUS_QUEUED]);
|
|
}
|
|
}
|
|
$newSubmission = Repo::submission()->get($submission->getId());
|
|
Repo::submission()->updateStatus($newSubmission);
|
|
}
|
|
|
|
Repo::issue()->delete($issue);
|
|
$currentIssue = Repo::issue()->getCurrent($issue->getJournalId());
|
|
if ($currentIssue != null && $issue->getId() == $currentIssue->getId()) {
|
|
$issues = Repo::issue()->getCollector()
|
|
->filterByContextIds([$journal->getId()])
|
|
->filterByPublished(true)
|
|
->orderBy(Collector::ORDERBY_PUBLISHED_ISSUES)
|
|
->getMany();
|
|
if ($issue = $issues->first()) {
|
|
Repo::issue()->updateCurrent($journal->getId(), $issue);
|
|
}
|
|
}
|
|
|
|
return DAO::getDataChangedEvent($issue->getId());
|
|
}
|
|
|
|
/**
|
|
* An action to edit issue pub ids
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function identifiers($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$form = new PublicIdentifiersForm($issue);
|
|
$form->initData();
|
|
return new JSONMessage(true, $form->fetch($request));
|
|
}
|
|
|
|
/**
|
|
* Update issue pub ids
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function updateIdentifiers($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$form = new PublicIdentifiersForm($issue);
|
|
$form->readInputData();
|
|
if ($form->validate()) {
|
|
$form->execute();
|
|
return DAO::getDataChangedEvent($issue->getId());
|
|
} else {
|
|
return new JSONMessage(true, $form->fetch($request));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Clear issue pub id
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function clearPubId($args, $request)
|
|
{
|
|
if (!$request->checkCSRF()) {
|
|
return new JSONMessage(false);
|
|
}
|
|
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$form = new PublicIdentifiersForm($issue);
|
|
$form->clearPubId($request->getUserVar('pubIdPlugIn'));
|
|
$json = new JSONMessage(true);
|
|
$json->setEvent('reloadTab', [['tabsSelector' => '#editIssueTabs', 'tabSelector' => '#identifiersTab']]);
|
|
return $json;
|
|
}
|
|
|
|
/**
|
|
* Clear issue objects pub ids
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function clearIssueObjectsPubIds($args, $request)
|
|
{
|
|
if (!$request->checkCSRF()) {
|
|
return new JSONMessage(false);
|
|
}
|
|
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$form = new PublicIdentifiersForm($issue);
|
|
$form->clearIssueObjectsPubIds($request->getUserVar('pubIdPlugIn'));
|
|
return new JSONMessage(true);
|
|
}
|
|
|
|
/**
|
|
* Display the table of contents
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function issueToc($args, $request)
|
|
{
|
|
$templateMgr = TemplateManager::getManager($request);
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$templateMgr->assign('issue', $issue);
|
|
return new JSONMessage(true, $templateMgr->fetch('controllers/grid/issues/issueToc.tpl'));
|
|
}
|
|
|
|
/**
|
|
* Displays the issue galleys page.
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*
|
|
* @return JSONMessage JSON object
|
|
*/
|
|
public function issueGalleys($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$templateMgr = TemplateManager::getManager($request);
|
|
$dispatcher = $request->getDispatcher();
|
|
return $templateMgr->fetchAjax(
|
|
'issueGalleysGridContainer',
|
|
$dispatcher->url(
|
|
$request,
|
|
PKPApplication::ROUTE_COMPONENT,
|
|
null,
|
|
'grid.issueGalleys.IssueGalleyGridHandler',
|
|
'fetchGrid',
|
|
null,
|
|
['issueId' => $issue->getId()]
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Publish issue
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*/
|
|
public function publishIssue($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$context = $request->getContext();
|
|
$contextId = $context->getId();
|
|
$wasPublished = $issue->getPublished();
|
|
|
|
if (!$wasPublished) {
|
|
$confirmationText = __('editor.issues.confirmPublish');
|
|
$formTemplate = $this->getAssignPublicIdentifiersFormTemplate();
|
|
$assignPublicIdentifiersForm = new AssignPublicIdentifiersForm($formTemplate, $issue, true, $confirmationText);
|
|
if (!$request->getUserVar('confirmed')) {
|
|
// Display assign pub ids modal
|
|
$assignPublicIdentifiersForm->initData();
|
|
return new JSONMessage(true, $assignPublicIdentifiersForm->fetch($request));
|
|
}
|
|
// Assign pub ids
|
|
$assignPublicIdentifiersForm->readInputData();
|
|
if (!$assignPublicIdentifiersForm->validate()) {
|
|
return new JSONMessage(true, $assignPublicIdentifiersForm->fetch($request));
|
|
}
|
|
$assignPublicIdentifiersForm->execute();
|
|
Repo::issue()->createDoi($issue);
|
|
}
|
|
|
|
if (!$request->checkCSRF()) {
|
|
return new JSONMessage(false);
|
|
}
|
|
|
|
$issue->setPublished(1);
|
|
$issue->setDatePublished(Core::getCurrentDate());
|
|
|
|
// If subscriptions with delayed open access are enabled then
|
|
// update open access date according to open access delay policy
|
|
if ($context->getData('publishingMode') == \APP\journal\Journal::PUBLISHING_MODE_SUBSCRIPTION && ($delayDuration = $context->getData('delayedOpenAccessDuration'))) {
|
|
$delayYears = (int)floor($delayDuration / 12);
|
|
$delayMonths = (int)fmod($delayDuration, 12);
|
|
|
|
$curYear = date('Y');
|
|
$curMonth = date('n');
|
|
$curDay = date('j');
|
|
|
|
$delayOpenAccessYear = $curYear + $delayYears + (int)floor(($curMonth + $delayMonths) / 12);
|
|
$delayOpenAccessMonth = (int)fmod($curMonth + $delayMonths, 12);
|
|
|
|
$issue->setAccessStatus(\APP\issue\Issue::ISSUE_ACCESS_SUBSCRIPTION);
|
|
$issue->setOpenAccessDate(date('Y-m-d H:i:s', mktime(0, 0, 0, $delayOpenAccessMonth, $curDay, $delayOpenAccessYear)));
|
|
}
|
|
|
|
Hook::call('IssueGridHandler::publishIssue', [&$issue]);
|
|
|
|
Repo::issue()->updateCurrent($contextId, $issue);
|
|
|
|
if (!$wasPublished) {
|
|
Repo::doi()->issueUpdated($issue);
|
|
|
|
// Publish all related publications
|
|
// Include published submissions in order to support cases where two
|
|
// versions of the same submission are published in distinct issues. In
|
|
// such cases, the submission will be STATUS_PUBLISHED but the
|
|
// publication will be STATUS_SCHEDULED.
|
|
$submissions = Repo::submission()->getCollector()
|
|
->filterByContextIds([$issue->getJournalId()])
|
|
->filterByIssueIds([$issue->getId()])
|
|
->filterByStatus([Submission::STATUS_SCHEDULED, Submission::STATUS_PUBLISHED])
|
|
->getMany();
|
|
|
|
foreach ($submissions as $submission) { /** @var Submission $submission */
|
|
$publications = $submission->getData('publications');
|
|
|
|
foreach ($publications as $publication) { /** @var Publication $publication */
|
|
if ($publication->getData('status') === Submission::STATUS_SCHEDULED && $publication->getData('issueId') === (int) $issue->getId()) {
|
|
Repo::publication()->publish($publication);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Send a notification to associated users if selected and context is publishing content online with OJS
|
|
if ($request->getUserVar('sendIssueNotification') && $context->getData('publishingMode') != \APP\journal\Journal::PUBLISHING_MODE_NONE) {
|
|
// Notify users
|
|
/** @var NotificationSubscriptionSettingsDAO $notificationSubscriptionSettingsDao */
|
|
$notificationSubscriptionSettingsDao = DAORegistry::getDAO('NotificationSubscriptionSettingsDAO');
|
|
|
|
$userIdsToNotify = $notificationSubscriptionSettingsDao->getSubscribedUserIds(
|
|
[NotificationSubscriptionSettingsDAO::BLOCKED_NOTIFICATION_KEY],
|
|
[Notification::NOTIFICATION_TYPE_PUBLISHED_ISSUE],
|
|
[$contextId]
|
|
);
|
|
|
|
$userIdsToMail = $notificationSubscriptionSettingsDao->getSubscribedUserIds(
|
|
[
|
|
NotificationSubscriptionSettingsDAO::BLOCKED_NOTIFICATION_KEY,
|
|
NotificationSubscriptionSettingsDAO::BLOCKED_EMAIL_NOTIFICATION_KEY
|
|
],
|
|
[Notification::NOTIFICATION_TYPE_PUBLISHED_ISSUE],
|
|
[$contextId]
|
|
);
|
|
|
|
$userIdsToNotifyAndMail = $userIdsToNotify->intersect($userIdsToMail);
|
|
$userIdsToNotify = $userIdsToNotify->diff($userIdsToMail);
|
|
|
|
$jobs = [];
|
|
foreach ($userIdsToNotify->chunk(PKPNotification::NOTIFICATION_CHUNK_SIZE_LIMIT) as $notifyUserIds) {
|
|
$jobs[] = new IssuePublishedNotifyUsers(
|
|
$notifyUserIds,
|
|
$contextId,
|
|
$issue,
|
|
Locale::getLocale(),
|
|
);
|
|
}
|
|
|
|
foreach ($userIdsToNotifyAndMail->chunk(Mailer::BULK_EMAIL_SIZE_LIMIT) as $mailUserIds) {
|
|
$jobs[] = new IssuePublishedNotifyUsers(
|
|
$mailUserIds,
|
|
$contextId,
|
|
$issue,
|
|
Locale::getLocale(),
|
|
$request->getUser()
|
|
);
|
|
}
|
|
Bus::batch($jobs)->dispatch();
|
|
}
|
|
|
|
$json = DAO::getDataChangedEvent();
|
|
$json->setGlobalEvent('issuePublished', ['id' => $issue->getId()]);
|
|
return $json;
|
|
}
|
|
|
|
/**
|
|
* Unpublish a previously-published issue
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*/
|
|
public function unpublishIssue($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$journal = $request->getJournal();
|
|
|
|
if (!$request->checkCSRF()) {
|
|
return new JSONMessage(false);
|
|
}
|
|
|
|
// NB: Data set via params because setData('datePublished', null)
|
|
// removes the entry into _data rather than updating 'datePublished' to null.
|
|
$updateParams = [
|
|
'published' => 0,
|
|
'datePublished' => null
|
|
];
|
|
|
|
Hook::call('IssueGridHandler::unpublishIssue', [&$issue]);
|
|
|
|
Repo::issue()->edit($issue, $updateParams);
|
|
Repo::issue()->updateCurrent($request->getContext()->getId());
|
|
|
|
Repo::doi()->issueUpdated($issue);
|
|
|
|
// insert article tombstones for all articles
|
|
$submissions = Repo::submission()->getCollector()
|
|
->filterByContextIds([$issue->getJournalId()])
|
|
->filterByIssueIds([$issue->getId()])
|
|
->getMany();
|
|
|
|
foreach ($submissions as $submission) { /** @var Submission $submission */
|
|
$publications = $submission->getData('publications');
|
|
foreach ($publications as $publication) { /** @var Publication $publication */
|
|
if ($publication->getData('status') === Submission::STATUS_PUBLISHED && $publication->getData('issueId') === (int) $issue->getId()) {
|
|
// Republish the publication in the issue, now that it's status has changed,
|
|
// to ensure the publication's status is restored to Submission::STATUS_SCHEDULED
|
|
// rather than Submission::STATUS_QUEUED
|
|
Repo::publication()->unpublish($publication);
|
|
Repo::publication()->publish($publication);
|
|
}
|
|
}
|
|
}
|
|
|
|
$json = DAO::getDataChangedEvent($issue->getId());
|
|
$json->setGlobalEvent('issueUnpublished', ['id' => $issue->getId()]);
|
|
return $json;
|
|
}
|
|
|
|
/**
|
|
* Set Issue as current
|
|
*
|
|
* @param array $args
|
|
* @param Request $request
|
|
*/
|
|
public function setCurrentIssue($args, $request)
|
|
{
|
|
$issue = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_ISSUE);
|
|
$journal = $request->getJournal();
|
|
|
|
if (!$request->checkCSRF()) {
|
|
return new JSONMessage(false);
|
|
}
|
|
|
|
Repo::issue()->updateCurrent($journal->getId(), $issue);
|
|
|
|
$dispatcher = $request->getDispatcher();
|
|
return DAO::getDataChangedEvent();
|
|
}
|
|
|
|
/**
|
|
* Get the template for the assign public identifiers form.
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getAssignPublicIdentifiersFormTemplate()
|
|
{
|
|
return 'controllers/grid/pubIds/form/assignPublicIdentifiersForm.tpl';
|
|
}
|
|
}
|