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,106 @@
<?php
/**
* @file controllers/grid/settings/plugins/SettingsPluginGridHandler.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 SettingsPluginGridHandler
*
* @ingroup controllers_grid_settings_plugins
*
* @brief Handle plugin grid requests.
*/
namespace APP\controllers\grid\settings\plugins;
use APP\core\Application;
use PKP\controllers\grid\plugins\PluginGridHandler;
use PKP\controllers\grid\plugins\PluginGridRow;
use PKP\security\authorization\ContextAccessPolicy;
use PKP\security\authorization\PluginAccessPolicy;
use PKP\security\Role;
class SettingsPluginGridHandler extends PluginGridHandler
{
/**
* Constructor
*/
public function __construct()
{
$roles = [Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_MANAGER];
$this->addRoleAssignment($roles, ['manage']);
parent::__construct($roles);
}
//
// Extended methods from PluginGridHandler
//
/**
* @copydoc PluginGridHandler::loadCategoryData()
*
* @param null|mixed $filter
*/
public function loadCategoryData($request, &$categoryDataElement, $filter = null)
{
$plugins = parent::loadCategoryData($request, $categoryDataElement, $filter);
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
$showSitePlugins = false;
if (in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles)) {
$showSitePlugins = true;
}
if ($showSitePlugins) {
return $plugins;
} else {
$contextLevelPlugins = [];
foreach ($plugins as $plugin) {
if (!$plugin->isSitePlugin()) {
$contextLevelPlugins[$plugin->getName()] = $plugin;
}
unset($plugin);
}
return $contextLevelPlugins;
}
}
//
// Overridden template methods.
//
/**
* @copydoc CategoryGridHandler::getCategoryRowInstance()
*/
protected function getRowInstance()
{
return new PluginGridRow($this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES));
}
/**
* @copydoc GridHandler::authorize()
*/
public function authorize($request, &$args, $roleAssignments)
{
$categoryName = $request->getUserVar('category');
$pluginName = $request->getUserVar('plugin');
if ($categoryName && $pluginName) {
switch ($request->getRequestedOp()) {
case 'enable':
case 'disable':
case 'manage':
$accessMode = PluginAccessPolicy::ACCESS_MODE_MANAGE;
break;
default:
$accessMode = PluginAccessPolicy::ACCESS_MODE_ADMIN;
break;
}
$this->addPolicy(new PluginAccessPolicy($request, $args, $roleAssignments, $accessMode));
} else {
$this->addPolicy(new ContextAccessPolicy($request, $roleAssignments));
}
return parent::authorize($request, $args, $roleAssignments);
}
}
@@ -0,0 +1,95 @@
<?php
/**
* @file controllers/grid/settings/sections/SectionGridCellProvider.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 SectionGridCellProvider
*
* @ingroup controllers_grid_settings_sections
*
* @brief Grid cell provider for section grid
*/
namespace APP\controllers\grid\settings\sections;
use PKP\controllers\grid\GridCellProvider;
use PKP\controllers\grid\GridColumn;
use PKP\controllers\grid\GridHandler;
use PKP\linkAction\LinkAction;
use PKP\linkAction\request\RemoteActionConfirmationModal;
class SectionGridCellProvider extends 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();
switch ($columnId) {
case 'inactive':
return ['selected' => $element['inactive']];
}
return parent::getTemplateVarsFromRowColumn($row, $column);
}
/**
* @see GridCellProvider::getCellActions()
*/
public function getCellActions($request, $row, $column, $position = GridHandler::GRID_ACTION_POSITION_DEFAULT)
{
switch ($column->getId()) {
case 'inactive':
$element = $row->getData(); /** @var array $element */
$router = $request->getRouter();
if ($element['inactive']) {
return [new LinkAction(
'activateSection',
new RemoteActionConfirmationModal(
$request->getSession(),
__('manager.sections.confirmActivateSection'),
null,
$router->url(
$request,
null,
'grid.settings.sections.SectionGridHandler',
'activateSection',
null,
['sectionKey' => $row->getId()]
)
)
)];
} else {
return [new LinkAction(
'deactivateSection',
new RemoteActionConfirmationModal(
$request->getSession(),
__('manager.sections.confirmDeactivateSection'),
null,
$router->url(
$request,
null,
'grid.settings.sections.SectionGridHandler',
'deactivateSection',
null,
['sectionKey' => $row->getId()]
)
)
)];
}
}
return parent::getCellActions($request, $row, $column, $position);
}
}
@@ -0,0 +1,355 @@
<?php
/**
* @file controllers/grid/settings/sections/SectionGridHandler.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 SectionGridHandler
*
* @ingroup controllers_grid_settings_section
*
* @brief Handle section grid requests.
*/
namespace APP\controllers\grid\settings\sections;
use APP\controllers\grid\settings\sections\form\SectionForm;
use APP\core\Application;
use APP\core\Request;
use APP\facades\Repo;
use APP\notification\NotificationManager;
use PKP\context\SubEditorsDAO;
use PKP\controllers\grid\feature\OrderGridItemsFeature;
use PKP\controllers\grid\GridColumn;
use PKP\controllers\grid\settings\SetupGridHandler;
use PKP\core\JSONMessage;
use PKP\db\DAO;
use PKP\db\DAORegistry;
use PKP\linkAction\LinkAction;
use PKP\linkAction\request\AjaxModal;
use PKP\notification\PKPNotification;
use PKP\security\Role;
class SectionGridHandler extends SetupGridHandler
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->addRoleAssignment(
[Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN],
['fetchGrid', 'fetchRow', 'addSection', 'editSection', 'updateSection', 'deleteSection', 'saveSequence', 'deactivateSection','activateSection']
);
}
//
// Overridden template methods
//
/**
* @copydoc SetupGridHandler::initialize()
*
* @param null|mixed $args
*/
public function initialize($request, $args = null)
{
parent::initialize($request, $args);
$journal = $request->getJournal();
// Set the grid title.
$this->setTitle('section.sections');
// Elements to be displayed in the grid
$subEditorsDao = DAORegistry::getDAO('SubEditorsDAO'); /** @var SubEditorsDAO $subEditorsDao */
$sections = Repo::section()->getCollector()->filterByContextIds([$journal->getId()])->getMany();
$gridData = [];
foreach ($sections as $section) {
// Get the section editors data for the row
$users = $subEditorsDao->getBySubmissionGroupIds([$section->getId()], Application::ASSOC_TYPE_SECTION, $journal->getId());
if ($users->isEmpty()) {
$editorsString = __('common.none');
} else {
$editorsString = Repo::user()
->getCollector()
->filterByUserIds($users->map(fn ($user) => $user->userId)->toArray())
->getMany()
->map(fn ($user) => $user->getFullName())
->join(__('common.commaListSeparator'));
}
$sectionId = $section->getId();
$gridData[$sectionId] = [
'title' => $section->getLocalizedTitle(),
'editors' => $editorsString,
'inactive' => $section->getIsInactive(),
'seq' => $section->getSequence()
];
}
uasort($gridData, function ($a, $b) {
return $a['seq'] - $b['seq'];
});
$this->setGridDataElements($gridData);
// Add grid-level actions
$router = $request->getRouter();
$this->addAction(
new LinkAction(
'addSection',
new AjaxModal(
$router->url($request, null, null, 'addSection', null, ['gridId' => $this->getId()]),
__('manager.sections.create'),
'modal_manage'
),
__('manager.sections.create'),
'add_section'
)
);
//
// Grid columns.
//
$sectionGridCellProvider = new SectionGridCellProvider();
// Section name
$this->addColumn(
new GridColumn(
'title',
'common.title'
)
);
// Section 'editors'
$this->addColumn(new GridColumn('editors', 'user.role.editors'));
//Section 'inactive'
$this->addColumn(
new GridColumn(
'inactive',
'common.inactive',
null,
'controllers/grid/common/cell/selectStatusCell.tpl',
$sectionGridCellProvider,
['alignment' => GridColumn::COLUMN_ALIGNMENT_CENTER,
'width' => 20]
)
);
}
//
// Overridden methods from GridHandler
//
/**
* @copydoc GridHandler::initFeatures()
*/
public function initFeatures($request, $args)
{
return [new OrderGridItemsFeature()];
}
/**
* Get the row handler - override the default row handler
*
* @return SectionGridRow
*/
protected function getRowInstance()
{
return new SectionGridRow();
}
/**
* @copydoc GridHandler::getDataElementSequence()
*/
public function getDataElementSequence($row)
{
return $row['seq'];
}
/**
* @copydoc GridHandler::setDataElementSequence()
*/
public function setDataElementSequence($request, $rowId, $gridDataElement, $newSequence)
{
$journal = $request->getJournal();
$section = Repo::section()->get($rowId, $journal->getId());
$section->setSequence($newSequence);
Repo::section()->edit($section, []);
}
//
// Public Section Grid Actions
//
/**
* An action to add a new section
*
* @param array $args
* @param Request $request
*/
public function addSection($args, $request)
{
// Calling editSection with an empty ID will add
// a new section.
return $this->editSection($args, $request);
}
/**
* An action to edit a section
*
* @param array $args
* @param Request $request
*
* @return string Serialized JSON object
* @return JSONMessage JSON object
*/
public function editSection($args, $request)
{
$sectionId = $args['sectionId'] ?? null;
$this->setupTemplate($request);
$sectionForm = new SectionForm($request, $sectionId);
$sectionForm->initData();
return new JSONMessage(true, $sectionForm->fetch($request));
}
/**
* Update a section
*
* @param array $args
* @param Request $request
*
* @return JSONMessage JSON object
*/
public function updateSection($args, $request)
{
$sectionId = $request->getUserVar('sectionId');
$sectionForm = new SectionForm($request, $sectionId);
$sectionForm->readInputData();
if ($sectionForm->validate()) {
$sectionForm->execute();
$notificationManager = new NotificationManager();
$notificationManager->createTrivialNotification($request->getUser()->getId());
return DAO::getDataChangedEvent($sectionForm->getSectionId());
}
return new JSONMessage(false);
}
/**
* Delete a section
*
* @param array $args
* @param Request $request
*
* @return JSONMessage JSON object
*/
public function deleteSection($args, $request)
{
if (!$request->checkCSRF()) {
return new JSONMessage(false, __('form.csrfInvalid'));
}
$journal = $request->getJournal();
$section = Repo::section()->get($request->getUserVar('sectionId'), $journal->getId());
if (!$section) {
return new JSONMessage(false, __('manager.setup.errorDeletingItem'));
}
// Validate if it can be deleted
$sectionEmpty = Repo::section()->isEmpty($section->getId(), $journal->getId());
if (!$sectionEmpty) {
return new JSONMessage(false, __('manager.sections.alertDelete'));
}
$activeSectionsCount = Repo::section()->getCollector()->filterByContextIds([$journal->getId()])->excludeInactive()->getCount();
$activeSectionsCount = (!$section->getIsInactive()) ? $activeSectionsCount - 1 : $activeSectionsCount;
if ($activeSectionsCount < 1) {
return new JSONMessage(false, __('manager.sections.confirmDeactivateSection.error'));
}
Repo::section()->delete($section);
return DAO::getDataChangedEvent($section->getId());
}
/**
* Deactivate a section.
*
* @param array $args
* @param Request $request
*
* @return JSONMessage JSON object
*/
public function deactivateSection($args, $request)
{
// Identify the current section
$sectionId = (int) $request->getUserVar('sectionKey');
// Identify the context id.
$context = $request->getContext();
// Validate if it can be inactive
$activeSectionsCount = Repo::section()->getCollector()->filterByContextIds([$context->getId()])->excludeInactive()->getCount();
if ($activeSectionsCount > 1) {
$section = Repo::section()->get($sectionId, $context->getId());
if ($request->checkCSRF() && isset($section) && !$section->getIsInactive()) {
$section->setIsInactive(1);
Repo::section()->edit($section, []);
// Create the notification.
$notificationMgr = new NotificationManager();
$user = $request->getUser();
$notificationMgr->createTrivialNotification($user->getId());
return DAO::getDataChangedEvent($sectionId);
}
} else {
// Create the notification.
$notificationMgr = new NotificationManager();
$user = $request->getUser();
$notificationMgr->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_ERROR, ['contents' => __('manager.sections.confirmDeactivateSection.error')]);
return DAO::getDataChangedEvent($sectionId);
}
return new JSONMessage(false);
}
/**
* Activate a section.
*
* @param array $args
* @param Request $request
*
* @return JSONMessage JSON object
*/
public function activateSection($args, $request)
{
// Identify the current section
$sectionId = (int) $request->getUserVar('sectionKey');
// Identify the context id.
$context = $request->getContext();
// Get section object
$section = Repo::section()->get($sectionId, $context->getId());
if ($request->checkCSRF() && isset($section) && $section->getIsInactive()) {
$section->setIsInactive(0);
Repo::section()->edit($section, []);
// Create the notification.
$notificationMgr = new NotificationManager();
$user = $request->getUser();
$notificationMgr->createTrivialNotification($user->getId());
return DAO::getDataChangedEvent($sectionId);
}
return new JSONMessage(false);
}
}
@@ -0,0 +1,73 @@
<?php
/**
* @file controllers/grid/settings/sections/SectionGridRow.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 SectionGridRow
*
* @ingroup controllers_grid_settings_section
*
* @brief Handle section grid row requests.
*/
namespace APP\controllers\grid\settings\sections;
use PKP\controllers\grid\GridRow;
use PKP\linkAction\LinkAction;
use PKP\linkAction\request\AjaxModal;
use PKP\linkAction\request\RemoteActionConfirmationModal;
class SectionGridRow extends GridRow
{
//
// Overridden template methods
//
/**
* @copydoc GridRow::initialize()
*
* @param null|mixed $template
*/
public function initialize($request, $template = null)
{
parent::initialize($request, $template);
// Is this a new row or an existing row?
$sectionId = $this->getId();
if (!empty($sectionId) && is_numeric($sectionId)) {
$router = $request->getRouter();
$this->addAction(
new LinkAction(
'editSection',
new AjaxModal(
$router->url($request, null, null, 'editSection', null, ['sectionId' => $sectionId]),
__('grid.action.edit'),
'modal_edit',
true
),
__('grid.action.edit'),
'edit'
)
);
$this->addAction(
new LinkAction(
'deleteSection',
new RemoteActionConfirmationModal(
$request->getSession(),
__('manager.sections.confirmDelete'),
__('grid.action.delete'),
$router->url($request, null, null, 'deleteSection', null, ['sectionId' => $sectionId]),
'modal_delete'
),
__('grid.action.delete'),
'delete'
)
);
}
}
}
@@ -0,0 +1,198 @@
<?php
/**
* @file controllers/grid/settings/sections/form/SectionForm.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 SectionForm
*
* @ingroup controllers_grid_settings_section_form
*
* @brief Form for adding/editing a section
*/
namespace APP\controllers\grid\settings\sections\form;
use APP\core\Application;
use APP\core\Request;
use APP\facades\Repo;
use APP\template\TemplateManager;
use PKP\controllers\grid\settings\sections\form\PKPSectionForm;
use PKP\db\DAORegistry;
use PKP\reviewForm\ReviewFormDAO;
class SectionForm extends PKPSectionForm
{
/**
* Constructor.
*
* @param Request $request
* @param int $sectionId optional
*/
public function __construct($request, $sectionId = null)
{
parent::__construct(
$request,
'controllers/grid/settings/sections/form/sectionForm.tpl',
$sectionId
);
// Validation checks for this form
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'title', 'required', 'manager.setup.form.section.nameRequired'));
$this->addCheck(new \PKP\form\validation\FormValidatorLocale($this, 'abbrev', 'required', 'manager.sections.form.abbrevRequired'));
$journal = $request->getJournal();
$this->addCheck(new \PKP\form\validation\FormValidatorCustom($this, 'reviewFormId', 'optional', 'manager.sections.form.reviewFormId', [DAORegistry::getDAO('ReviewFormDAO'), 'reviewFormExists'], [Application::ASSOC_TYPE_JOURNAL, $journal->getId()]));
}
/**
* Initialize form data from current settings.
*/
public function initData()
{
$request = Application::get()->getRequest();
$journal = $request->getJournal();
$sectionId = $this->getSectionId();
if ($sectionId) {
$this->section = Repo::section()->get($sectionId, $journal->getId());
}
if (isset($this->section)) {
$this->setData([
'title' => $this->section->getTitle(null), // Localized
'abbrev' => $this->section->getAbbrev(null), // Localized
'reviewFormId' => $this->section->getReviewFormId(),
'isInactive' => $this->section->getIsInactive(),
'metaIndexed' => !$this->section->getMetaIndexed(), // #2066: Inverted
'metaReviewed' => !$this->section->getMetaReviewed(), // #2066: Inverted
'abstractsNotRequired' => $this->section->getAbstractsNotRequired(),
'identifyType' => $this->section->getIdentifyType(null), // Localized
'editorRestricted' => $this->section->getEditorRestricted(),
'hideTitle' => $this->section->getHideTitle(),
'hideAuthor' => $this->section->getHideAuthor(),
'policy' => $this->section->getPolicy(null), // Localized
'wordCount' => $this->section->getAbstractWordCount(),
]);
}
parent::initData();
}
/**
* @see Form::validate()
*/
public function validate($callHooks = true)
{
// Validate if it can be inactive
if ($this->getData('isInactive')) {
$request = Application::get()->getRequest();
$context = $request->getContext();
$sectionId = $this->getSectionId();
$activeSections = Repo::section()->getCollector()->filterByContextIds([$context->getId()])->excludeInactive()->getMany();
$otherActiveSections = $activeSections->filter(function ($activeSection) use ($sectionId) {
return $activeSection->getId() != $sectionId;
});
if ($otherActiveSections->count() < 1) {
$this->addError('isInactive', __('manager.sections.confirmDeactivateSection.error'));
}
}
return parent::validate($callHooks);
}
/**
* @copydoc Form::fetch()
*
* @param null|mixed $template
*/
public function fetch($request, $template = null, $display = false)
{
$templateMgr = TemplateManager::getManager($request);
$templateMgr->assign('sectionId', $this->getSectionId());
$journal = $request->getContext();
$reviewFormDao = DAORegistry::getDAO('ReviewFormDAO'); /** @var ReviewFormDAO $reviewFormDao */
$reviewForms = $reviewFormDao->getActiveByAssocId(Application::ASSOC_TYPE_JOURNAL, $journal->getId());
$reviewFormOptions = [];
while ($reviewForm = $reviewForms->next()) {
$reviewFormOptions[$reviewForm->getId()] = $reviewForm->getLocalizedTitle();
}
$templateMgr->assign('reviewFormOptions', $reviewFormOptions);
return parent::fetch($request, $template, $display);
}
/**
* @copydoc Form::readInputData()
*/
public function readInputData()
{
parent::readInputData();
$this->readUserVars(['abbrev', 'policy', 'reviewFormId', 'identifyType', 'isInactive', 'metaIndexed', 'metaReviewed', 'abstractsNotRequired', 'editorRestricted', 'hideTitle', 'hideAuthor', 'wordCount']);
}
/**
* Get the names of fields for which localized data is allowed.
*
* @return array
*/
public function getLocaleFieldNames()
{
return ['title', 'policy', 'abbrev', 'identifyType'];
}
/**
* Save section.
*/
public function execute(...$functionArgs)
{
$request = Application::get()->getRequest();
$journal = $request->getJournal();
// Get or create the section object
if ($this->getSectionId()) {
$section = Repo::section()->get($this->getSectionId(), $journal->getId());
} else {
$section = Repo::section()->newDataObject();
$section->setContextId($journal->getId());
}
// Populate/update the section object from the form
$section->setTitle($this->getData('title'), null); // Localized
$section->setAbbrev($this->getData('abbrev'), null); // Localized
$reviewFormId = $this->getData('reviewFormId');
if (!$reviewFormId) {
$reviewFormId = null;
}
$section->setReviewFormId($reviewFormId);
$section->setIsInactive($this->getData('isInactive') ? 1 : 0);
$section->setMetaIndexed($this->getData('metaIndexed') ? 0 : 1); // #2066: Inverted
$section->setMetaReviewed($this->getData('metaReviewed') ? 0 : 1); // #2066: Inverted
$section->setAbstractsNotRequired($this->getData('abstractsNotRequired') ? 1 : 0);
$section->setIdentifyType($this->getData('identifyType'), null); // Localized
$section->setEditorRestricted($this->getData('editorRestricted') ? 1 : 0);
$section->setHideTitle($this->getData('hideTitle') ? 1 : 0);
$section->setHideAuthor($this->getData('hideAuthor') ? 1 : 0);
$section->setPolicy($this->getData('policy'), null); // Localized
$section->setAbstractWordCount((int) $this->getData('wordCount'));
// Insert or update the section in the DB
if ($this->getSectionId()) {
Repo::section()->edit($section, []);
} else {
$section->setSequence(REALLY_BIG_NUMBER);
$sectionId = Repo::section()->add($section);
$this->setSectionId($sectionId);
Repo::section()->resequence($journal->getId());
}
return parent::execute(...$functionArgs);
}
}