Files
CHIEFSOFT\ameye df3a033196 first commit
2024-06-08 17:09:23 -04:00

477 lines
15 KiB
PHP

<?php
/**
* @file controllers/grid/plugins/PluginGridHandler.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 PluginGridHandler
*
* @ingroup controllers_grid_plugins
*
* @brief Handle plugins grid requests.
*/
namespace PKP\controllers\grid\plugins;
use APP\notification\NotificationManager;
use Exception;
use PKP\controllers\grid\CategoryGridHandler;
use PKP\controllers\grid\GridColumn;
use PKP\controllers\grid\GridHandler;
use PKP\controllers\grid\plugins\form\UploadPluginForm;
use PKP\core\Core;
use PKP\core\JSONMessage;
use PKP\core\PKPApplication;
use PKP\core\PKPRequest;
use PKP\db\DAORegistry;
use PKP\file\FileManager;
use PKP\file\TemporaryFileManager;
use PKP\linkAction\LinkAction;
use PKP\linkAction\request\AjaxModal;
use PKP\notification\PKPNotification;
use PKP\plugins\Plugin;
use PKP\plugins\PluginHelper;
use PKP\plugins\PluginRegistry;
use PKP\security\Role;
use PKP\site\Version;
use PKP\site\VersionCheck;
use PKP\site\VersionDAO;
abstract class PluginGridHandler extends CategoryGridHandler
{
/**
* Constructor
*
* @param array $roles
*/
public function __construct($roles)
{
$this->addRoleAssignment(
$roles,
['enable', 'disable', 'manage', 'fetchGrid', 'fetchCategory', 'fetchRow']
);
$this->addRoleAssignment(
Role::ROLE_ID_SITE_ADMIN,
['uploadPlugin', 'upgradePlugin', 'deletePlugin', 'saveUploadPlugin', 'uploadPluginFile']
);
parent::__construct();
}
//
// Overridden template methods
//
/**
* @copydoc GridHandler::initialize()
*
* @param null|mixed $args
*/
public function initialize($request, $args = null)
{
parent::initialize($request, $args);
// Basic grid configuration
$this->setTitle('common.plugins');
// Set the no items row text
$this->setEmptyRowText('grid.noItems');
// Columns
$pluginCellProvider = new PluginGridCellProvider();
$this->addColumn(
new GridColumn(
'name',
'common.name',
null,
null,
$pluginCellProvider,
[
'showTotalItemsNumber' => true,
'collapseAllColumnsInCategories' => true
]
)
);
$descriptionColumn = new GridColumn(
'description',
'common.description',
null,
null,
$pluginCellProvider
);
$descriptionColumn->addFlag('html', true);
$this->addColumn($descriptionColumn);
$this->addColumn(
new GridColumn(
'enabled',
'common.enabled',
null,
'controllers/grid/common/cell/selectStatusCell.tpl',
$pluginCellProvider
)
);
$router = $request->getRouter();
// Grid level actions.
$userRoles = $this->getAuthorizedContextObject(PKPApplication::ASSOC_TYPE_USER_ROLES);
if (in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles)) {
// Install plugin.
$this->addAction(
new LinkAction(
'upload',
new AjaxModal(
$router->url($request, null, null, 'uploadPlugin'),
__('manager.plugins.upload'),
'modal_add_file'
),
__('manager.plugins.upload'),
'add'
)
);
}
}
/**
* @copydoc GridHandler::getFilterForm()
*/
protected function getFilterForm()
{
return 'controllers/grid/plugins/pluginGridFilter.tpl';
}
/**
* @copydoc GridHandler::getFilterSelectionData()
*/
public function getFilterSelectionData($request)
{
$category = $request->getUserVar('category');
$pluginName = $request->getUserVar('pluginName');
if (is_null($category)) {
$category = PluginGalleryGridHandler::PLUGIN_GALLERY_ALL_CATEGORY_SEARCH_VALUE;
}
return ['category' => $category, 'pluginName' => $pluginName];
}
/**
* @copydoc GridHandler::renderFilter()
*/
public function renderFilter($request, $filterData = [])
{
$categoriesSymbolic = $this->loadData($request, null);
$categories = [PluginGalleryGridHandler::PLUGIN_GALLERY_ALL_CATEGORY_SEARCH_VALUE => __('grid.plugin.allCategories')];
foreach ($categoriesSymbolic as $category) {
$categories[$category] = __("plugins.categories.{$category}");
}
$filterData['categories'] = $categories;
return parent::renderFilter($request, $filterData);
}
/**
* @copydoc CategoryGridHandler::getCategoryRowInstance()
*/
protected function getCategoryRowInstance()
{
return new PluginCategoryGridRow();
}
/**
* @copydoc CategoryGridHandler::loadCategoryData()
*
* @param null|mixed $filter
*/
public function loadCategoryData($request, &$categoryDataElement, $filter = null)
{
$plugins = PluginRegistry::loadCategory($categoryDataElement);
$versionDao = DAORegistry::getDAO('VersionDAO'); /** @var VersionDAO $versionDao */
$fileManager = new FileManager();
$notHiddenPlugins = [];
foreach ((array) $plugins as $plugin) {
if (!$plugin->getHideManagement()) {
$notHiddenPlugins[$plugin->getName()] = $plugin;
}
$version = $plugin->getCurrentVersion();
if ($version == null) { // this plugin is on the file system, but not installed.
$versionFile = $plugin->getPluginPath() . '/version.xml';
if ($fileManager->fileExists($versionFile)) {
$versionInfo = VersionCheck::parseVersionXML($versionFile);
$pluginVersion = $versionInfo['version'];
} else {
$pluginVersion = new Version(
1,
0,
0,
0, // Major, minor, revision, build
Core::getCurrentDate(), // Date installed
1, // Current
'plugins.' . $plugin->getCategory(), // Type
basename($plugin->getPluginPath()), // Product
'', // Class name
0, // Lazy load
$plugin->isSitePlugin() // Site wide
);
}
$versionDao->insertVersion($pluginVersion, true);
}
}
if (!is_null($filter) && isset($filter['pluginName']) && $filter['pluginName'] != '') {
// Find all plugins that have the filter name string in their display names.
$filteredPlugins = [];
foreach ($notHiddenPlugins as $plugin) { /** @var Plugin $plugin */
$pluginName = $plugin->getDisplayName();
if (stristr($pluginName, $filter['pluginName']) !== false) {
$filteredPlugins[$plugin->getName()] = $plugin;
}
}
ksort($filteredPlugins);
return $filteredPlugins;
}
ksort($notHiddenPlugins);
return $notHiddenPlugins;
}
/**
* @copydoc CategoryGridHandler::getCategoryRowIdParameterName()
*/
public function getCategoryRowIdParameterName()
{
return 'category';
}
/**
* @copydoc GridHandler::loadData()
*/
protected function loadData($request, $filter)
{
$categories = PluginRegistry::getCategories();
if (is_array($filter) && isset($filter['category']) && in_array($filter['category'], $categories)) {
return [$filter['category'] => $filter['category']];
} else {
return array_combine($categories, $categories);
}
}
//
// Public handler methods.
//
/**
* Manage a plugin.
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage JSON object
*/
public function manage($args, $request)
{
$plugin = $this->getAuthorizedContextObject(PKPApplication::ASSOC_TYPE_PLUGIN); /** @var Plugin $plugin */
return $plugin->manage($args, $request);
}
/**
* Enable a plugin.
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage JSON object
*/
public function enable($args, $request)
{
$plugin = $this->getAuthorizedContextObject(PKPApplication::ASSOC_TYPE_PLUGIN); /** @var Plugin $plugin */
if ($request->checkCSRF() && $plugin->getCanEnable()) {
$plugin->setEnabled(true);
if (empty($args['disableNotification'])) {
$user = $request->getUser();
$notificationManager = new NotificationManager();
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_PLUGIN_ENABLED, ['pluginName' => $plugin->getDisplayName()]);
}
return \PKP\db\DAO::getDataChangedEvent($request->getUserVar('plugin'), $request->getUserVar($this->getCategoryRowIdParameterName()));
}
return new JSONMessage(false);
}
/**
* Disable a plugin.
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage JSON object
*/
public function disable($args, $request)
{
$plugin = $this->getAuthorizedContextObject(PKPApplication::ASSOC_TYPE_PLUGIN); /** @var Plugin $plugin */
if ($request->checkCSRF() && $plugin->getCanDisable()) {
$plugin->setEnabled(false);
if (empty($args['disableNotification'])) {
$user = $request->getUser();
$notificationManager = new NotificationManager();
$notificationManager->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_PLUGIN_DISABLED, ['pluginName' => $plugin->getDisplayName()]);
}
return \PKP\db\DAO::getDataChangedEvent($request->getUserVar('plugin'), $request->getUserVar($this->getCategoryRowIdParameterName()));
}
return new JSONMessage(false);
}
/**
* Show upload plugin form to upload a new plugin.
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage
*/
public function uploadPlugin($args, $request)
{
return $this->_showUploadPluginForm(PluginHelper::PLUGIN_ACTION_UPLOAD, $request);
}
/**
* Show upload plugin form to update an existing plugin.
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage
*/
public function upgradePlugin($args, $request)
{
return $this->_showUploadPluginForm(PluginHelper::PLUGIN_ACTION_UPGRADE, $request);
}
/**
* Upload a plugin file.
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage JSON object
*/
public function uploadPluginFile($args, $request)
{
$temporaryFileManager = new TemporaryFileManager();
$user = $request->getUser();
// Return the temporary file id.
if ($temporaryFile = $temporaryFileManager->handleUpload('uploadedFile', $user->getId())) {
$json = new JSONMessage(true);
$json->setAdditionalAttributes([
'temporaryFileId' => $temporaryFile->getId()
]);
return $json;
} else {
return new JSONMessage(false, __('manager.plugins.uploadError'));
}
}
/**
* Save upload plugin file form.
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage JSON object
*/
public function saveUploadPlugin($args, $request)
{
if (!$request->checkCSRF()) {
throw new Exception('CSRF mismatch!');
}
$function = $request->getUserVar('function');
$uploadPluginForm = new UploadPluginForm($function);
$uploadPluginForm->readInputData();
if ($uploadPluginForm->validate()) {
if ($uploadPluginForm->execute()) {
return \PKP\db\DAO::getDataChangedEvent();
}
}
return new JSONMessage(false);
}
/**
* Delete plugin.
*
* @param array $args
* @param PKPRequest $request
*
* @return JSONMessage JSON object
*/
public function deletePlugin($args, $request)
{
if (!$request->checkCSRF()) {
return new JSONMessage(false);
}
$plugin = $this->getAuthorizedContextObject(PKPApplication::ASSOC_TYPE_PLUGIN);
$category = $plugin->getCategory();
$productName = basename($plugin->getPluginPath());
$versionDao = DAORegistry::getDAO('VersionDAO'); /** @var VersionDAO $versionDao */
$installedPlugin = $versionDao->getCurrentVersion('plugins.' . $category, $productName);
$notificationMgr = new NotificationManager();
$user = $request->getUser();
$pluginName = ['pluginName' => $plugin->getDisplayName()];
if ($installedPlugin) {
$pluginDest = Core::getBaseDir() . "/plugins/{$category}/{$productName}";
$pluginLibDest = Core::getBaseDir() . '/' . PKP_LIB_PATH . "/plugins/{$category}/{$productName}";
// make sure plugin type is valid and then delete the files
if (in_array($category, PluginRegistry::getCategories())) {
// Delete the plugin from the file system.
$fileManager = new FileManager();
$fileManager->rmtree($pluginDest);
$fileManager->rmtree($pluginLibDest);
}
if (is_dir($pluginDest) || is_dir($pluginLibDest)) {
$notificationMgr->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_ERROR, ['contents' => __('manager.plugins.deleteError', $pluginName)]);
} else {
$versionDao->disableVersion('plugins.' . $category, $productName);
$notificationMgr->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_SUCCESS, ['contents' => __('manager.plugins.deleteSuccess', $pluginName)]);
}
} else {
$notificationMgr->createTrivialNotification($user->getId(), PKPNotification::NOTIFICATION_TYPE_ERROR, ['contents' => __('manager.plugins.doesNotExist', $pluginName)]);
}
return \PKP\db\DAO::getDataChangedEvent($plugin->getName());
}
/**
* Fetch upload plugin form.
*
* @param string $function
* @param PKPRequest $request Request object
*
* @return JSONMessage JSON object
*/
public function _showUploadPluginForm($function, $request)
{
$uploadPluginForm = new UploadPluginForm($function);
$uploadPluginForm->initData();
return new JSONMessage(true, $uploadPluginForm->fetch($request));
}
}
if (!PKP_STRICT_MODE) {
class_alias('\PKP\controllers\grid\plugins\PluginGridHandler', '\PluginGridHandler');
}