709 lines
26 KiB
PHP
709 lines
26 KiB
PHP
<?php
|
|
/**
|
|
* @file api/v1/contexts/PKPContextHandler.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 PKPContextHandler
|
|
*
|
|
* @ingroup api_v1_context
|
|
*
|
|
* @brief Base class to handle API requests for contexts (journals/presses).
|
|
*/
|
|
|
|
namespace PKP\API\v1\contexts;
|
|
|
|
use APP\core\Application;
|
|
use APP\core\Services;
|
|
use APP\plugins\IDoiRegistrationAgency;
|
|
use APP\services\ContextService;
|
|
use APP\template\TemplateManager;
|
|
use PKP\context\Context;
|
|
use PKP\core\APIResponse;
|
|
use PKP\db\DAORegistry;
|
|
use PKP\handler\APIHandler;
|
|
use PKP\plugins\Hook;
|
|
use PKP\plugins\Plugin;
|
|
use PKP\plugins\PluginRegistry;
|
|
use PKP\plugins\ThemePlugin;
|
|
use PKP\security\authorization\PolicySet;
|
|
use PKP\security\authorization\RoleBasedHandlerOperationPolicy;
|
|
use PKP\security\authorization\UserRolesRequiredPolicy;
|
|
use PKP\security\Role;
|
|
use PKP\security\RoleDAO;
|
|
use PKP\services\interfaces\EntityWriteInterface;
|
|
use PKP\services\PKPSchemaService;
|
|
use Slim\Http\Request as SlimRequest;
|
|
use Slim\Http\Response as SlimResponse;
|
|
|
|
class PKPContextHandler extends APIHandler
|
|
{
|
|
/** @var string One of the SCHEMA_... constants */
|
|
public $schemaName = PKPSchemaService::SCHEMA_CONTEXT;
|
|
|
|
/**
|
|
* @copydoc APIHandler::__construct()
|
|
*/
|
|
public function __construct()
|
|
{
|
|
$this->_handlerPath = 'contexts';
|
|
$roles = [Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_MANAGER];
|
|
$this->_endpoints = [
|
|
'GET' => [
|
|
[
|
|
'pattern' => $this->getEndpointPattern(),
|
|
'handler' => [$this, 'getMany'],
|
|
'roles' => $roles,
|
|
],
|
|
[
|
|
'pattern' => $this->getEndpointPattern() . '/{contextId:\d+}',
|
|
'handler' => [$this, 'get'],
|
|
'roles' => $roles,
|
|
],
|
|
[
|
|
'pattern' => $this->getEndpointPattern() . '/{contextId:\d+}/theme',
|
|
'handler' => [$this, 'getTheme'],
|
|
'roles' => $roles,
|
|
],
|
|
],
|
|
'POST' => [
|
|
[
|
|
'pattern' => $this->getEndpointPattern(),
|
|
'handler' => [$this, 'add'],
|
|
'roles' => [Role::ROLE_ID_SITE_ADMIN],
|
|
],
|
|
],
|
|
'PUT' => [
|
|
[
|
|
'pattern' => $this->getEndpointPattern() . '/{contextId:\d+}',
|
|
'handler' => [$this, 'edit'],
|
|
'roles' => $roles,
|
|
],
|
|
[
|
|
'pattern' => $this->getEndpointPattern() . '/{contextId:\d+}/theme',
|
|
'handler' => [$this, 'editTheme'],
|
|
'roles' => $roles,
|
|
],
|
|
[
|
|
'pattern' => $this->getEndpointPattern() . '/{contextId:\d+}/registrationAgency',
|
|
'handler' => [$this, 'editDoiRegistrationAgencyPlugin'],
|
|
'roles' => $roles,
|
|
]
|
|
],
|
|
'DELETE' => [
|
|
[
|
|
'pattern' => $this->getEndpointPattern() . '/{contextId:\d+}',
|
|
'handler' => [$this, 'delete'],
|
|
'roles' => [Role::ROLE_ID_SITE_ADMIN],
|
|
],
|
|
],
|
|
];
|
|
parent::__construct();
|
|
}
|
|
|
|
/**
|
|
* @copydoc PKPHandler::authorize
|
|
*/
|
|
public function authorize($request, &$args, $roleAssignments)
|
|
{
|
|
$this->addPolicy(new UserRolesRequiredPolicy($request), true);
|
|
|
|
$rolePolicy = new PolicySet(PolicySet::COMBINING_PERMIT_OVERRIDES);
|
|
|
|
foreach ($roleAssignments as $role => $operations) {
|
|
$rolePolicy->addPolicy(new RoleBasedHandlerOperationPolicy($request, $role, $operations));
|
|
}
|
|
$this->addPolicy($rolePolicy);
|
|
|
|
return parent::authorize($request, $args, $roleAssignments);
|
|
}
|
|
|
|
/**
|
|
* Get a collection of contexts
|
|
*
|
|
* @param SlimRequest $slimRequest Slim request object
|
|
* @param APIResponse $response object
|
|
* @param array $args arguments
|
|
*
|
|
* @return APIResponse
|
|
*/
|
|
public function getMany($slimRequest, $response, $args)
|
|
{
|
|
$request = $this->getRequest();
|
|
|
|
$defaultParams = [
|
|
'count' => 20,
|
|
'offset' => 0,
|
|
];
|
|
|
|
$requestParams = array_merge($defaultParams, $slimRequest->getQueryParams());
|
|
|
|
$allowedParams = [];
|
|
|
|
// Process query params to format incoming data as needed
|
|
foreach ($requestParams as $param => $val) {
|
|
switch ($param) {
|
|
case 'isEnabled':
|
|
$allowedParams[$param] = (bool) $val;
|
|
break;
|
|
|
|
case 'searchPhrase':
|
|
$allowedParams[$param] = trim($val);
|
|
break;
|
|
|
|
case 'count':
|
|
$allowedParams[$param] = min(100, (int) $val);
|
|
break;
|
|
|
|
case 'offset':
|
|
$allowedParams[$param] = (int) $val;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Hook::call('API::contexts::params', [&$allowedParams, $slimRequest]);
|
|
|
|
// Anyone not a site admin should not be able to access contexts that are
|
|
// not enabled
|
|
if (empty($allowedParams['isEnabled'])) {
|
|
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
|
$canAccessDisabledContexts = !empty(array_intersect([Role::ROLE_ID_SITE_ADMIN], $userRoles));
|
|
if (!$canAccessDisabledContexts) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.requestedDisabledContexts');
|
|
}
|
|
}
|
|
|
|
$items = [];
|
|
$contextsIterator = Services::get('context')->getMany($allowedParams);
|
|
$propertyArgs = [
|
|
'request' => $request,
|
|
'slimRequest' => $slimRequest,
|
|
];
|
|
foreach ($contextsIterator as $context) {
|
|
$items[] = Services::get('context')->getSummaryProperties($context, $propertyArgs);
|
|
}
|
|
|
|
$data = [
|
|
'itemsMax' => Services::get('context')->getMax($allowedParams),
|
|
'items' => $items,
|
|
];
|
|
|
|
return $response->withJson($data, 200);
|
|
}
|
|
|
|
/**
|
|
* Get a single context
|
|
*
|
|
* @param SlimRequest $slimRequest Slim request object
|
|
* @param APIResponse $response object
|
|
* @param array $args arguments
|
|
*
|
|
* @return APIResponse
|
|
*/
|
|
public function get($slimRequest, $response, $args)
|
|
{
|
|
$request = $this->getRequest();
|
|
$user = $request->getUser();
|
|
|
|
$contextService = Services::get('context');
|
|
$context = $contextService->get((int) $args['contextId']);
|
|
|
|
if (!$context) {
|
|
return $response->withStatus(404)->withJsonError('api.contexts.404.contextNotFound');
|
|
}
|
|
|
|
// Don't allow to get one context from a different context's endpoint
|
|
if ($request->getContext() && $request->getContext()->getId() !== $context->getId()) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.contextsDidNotMatch');
|
|
}
|
|
|
|
// A disabled journal can only be access by site admins and users with a
|
|
// manager role in that journal
|
|
if (!$context->getEnabled()) {
|
|
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
|
if (!in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles)) {
|
|
$roleDao = DAORegistry::getDao('RoleDAO'); /** @var RoleDAO $roleDao */
|
|
if (!$roleDao->userHasRole($context->getId(), $user->getId(), Role::ROLE_ID_MANAGER)) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.notAllowed');
|
|
}
|
|
}
|
|
}
|
|
|
|
$data = $contextService->getFullProperties($context, [
|
|
'request' => $request,
|
|
'slimRequest' => $slimRequest
|
|
]);
|
|
|
|
return $response->withJson($data, 200);
|
|
}
|
|
|
|
/**
|
|
* Get the theme and any theme options for a context
|
|
*
|
|
* @param SlimRequest $slimRequest Slim request object
|
|
* @param APIResponse $response object
|
|
* @param array $args arguments
|
|
*
|
|
* @return APIResponse
|
|
*/
|
|
public function getTheme($slimRequest, $response, $args)
|
|
{
|
|
$request = $this->getRequest();
|
|
$user = $request->getUser();
|
|
|
|
$contextService = Services::get('context');
|
|
$context = $contextService->get((int) $args['contextId']);
|
|
|
|
if (!$context) {
|
|
return $response->withStatus(404)->withJsonError('api.contexts.404.contextNotFound');
|
|
}
|
|
|
|
// Don't allow to get one context from a different context's endpoint
|
|
if ($request->getContext() && $request->getContext()->getId() !== $context->getId()) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.contextsDidNotMatch');
|
|
}
|
|
|
|
// A disabled journal can only be access by site admins and users with a
|
|
// manager role in that journal
|
|
if (!$context->getEnabled()) {
|
|
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
|
if (!in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles)) {
|
|
$roleDao = DAORegistry::getDao('RoleDAO'); /** @var RoleDAO $roleDao */
|
|
if (!$roleDao->userHasRole($context->getId(), $user->getId(), Role::ROLE_ID_MANAGER)) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.notAllowed');
|
|
}
|
|
}
|
|
}
|
|
|
|
$allThemes = PluginRegistry::loadCategory('themes', true);
|
|
$activeTheme = null;
|
|
foreach ($allThemes as $theme) {
|
|
if ($context->getData('themePluginPath') === $theme->getDirName()) {
|
|
$activeTheme = $theme;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!$activeTheme) {
|
|
return $response->withStatus(404)->withJsonError('api.themes.404.themeUnavailable');
|
|
}
|
|
|
|
$data = array_merge(
|
|
$activeTheme->getOptionValues($context->getId()),
|
|
['themePluginPath' => $theme->getDirName()]
|
|
);
|
|
|
|
ksort($data);
|
|
|
|
return $response->withJson($data, 200);
|
|
}
|
|
|
|
/**
|
|
* Add a context
|
|
*
|
|
* @param SlimRequest $slimRequest Slim request object
|
|
* @param APIResponse $response object
|
|
* @param array $args arguments
|
|
*
|
|
* @return APIResponse
|
|
*/
|
|
public function add($slimRequest, $response, $args)
|
|
{
|
|
$request = $this->getRequest();
|
|
|
|
// This endpoint is only available at the site-wide level
|
|
if ($request->getContext()) {
|
|
return $response->withStatus(404)->withJsonError('api.submissions.404.siteWideEndpoint');
|
|
}
|
|
|
|
$site = $request->getSite();
|
|
$params = $this->convertStringsToSchema(PKPSchemaService::SCHEMA_CONTEXT, $slimRequest->getParsedBody());
|
|
|
|
$primaryLocale = $site->getPrimaryLocale();
|
|
$allowedLocales = $site->getSupportedLocales();
|
|
|
|
// If the site only supports a single locale, set the context's locales
|
|
if (count($allowedLocales) === 1) {
|
|
if (!isset($params['primaryLocale'])) {
|
|
$params['primaryLocale'] = $primaryLocale;
|
|
}
|
|
if (!isset($params['supportedLocales'])) {
|
|
$params['supportedLocales'] = $allowedLocales;
|
|
}
|
|
}
|
|
|
|
$contextService = Services::get('context'); /** @var ContextService $contextService */
|
|
$errors = $contextService->validate(EntityWriteInterface::VALIDATE_ACTION_ADD, $params, $allowedLocales, $primaryLocale);
|
|
|
|
if (!empty($errors)) {
|
|
return $response->withStatus(400)->withJson($errors);
|
|
}
|
|
|
|
$context = Application::getContextDAO()->newDataObject();
|
|
$context->setAllData($params);
|
|
$context = $contextService->add($context, $request);
|
|
$contextProps = $contextService->getFullProperties($context, [
|
|
'request' => $request,
|
|
'slimRequest' => $slimRequest
|
|
]);
|
|
|
|
return $response->withJson($contextProps, 200);
|
|
}
|
|
|
|
/**
|
|
* Edit a context
|
|
*
|
|
* @param SlimRequest $slimRequest Slim request object
|
|
* @param APIResponse $response object
|
|
* @param array $args arguments
|
|
*
|
|
* @return APIResponse
|
|
*/
|
|
public function edit($slimRequest, $response, $args)
|
|
{
|
|
$request = $this->getRequest();
|
|
$requestContext = $request->getContext();
|
|
|
|
$contextId = (int) $args['contextId'];
|
|
|
|
// Don't allow to get one context from a different context's endpoint
|
|
if ($request->getContext() && $request->getContext()->getId() !== $contextId) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.contextsDidNotMatch');
|
|
}
|
|
|
|
// Don't allow to edit the context from the site-wide API, because the
|
|
// context's plugins will not be enabled
|
|
if (!$request->getContext()) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.requiresContext');
|
|
}
|
|
|
|
$contextService = Services::get('context');
|
|
$context = $contextService->get($contextId);
|
|
|
|
if (!$context) {
|
|
return $response->withStatus(404)->withJsonError('api.contexts.404.contextNotFound');
|
|
}
|
|
|
|
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
|
if (!$requestContext && !in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles)) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.notAllowedEdit');
|
|
}
|
|
|
|
$params = $this->convertStringsToSchema(PKPSchemaService::SCHEMA_CONTEXT, $slimRequest->getParsedBody());
|
|
$params['id'] = $contextId;
|
|
|
|
$site = $request->getSite();
|
|
$primaryLocale = $context->getPrimaryLocale();
|
|
$allowedLocales = $context->getSupportedFormLocales();
|
|
|
|
$errors = $contextService->validate(EntityWriteInterface::VALIDATE_ACTION_EDIT, $params, $allowedLocales, $primaryLocale);
|
|
|
|
if (!empty($errors)) {
|
|
return $response->withStatus(400)->withJson($errors);
|
|
}
|
|
$context = $contextService->edit($context, $params, $request);
|
|
|
|
$contextProps = $contextService->getFullProperties($context, [
|
|
'request' => $request,
|
|
'slimRequest' => $slimRequest
|
|
]);
|
|
|
|
return $response->withJson($contextProps, 200);
|
|
}
|
|
|
|
/**
|
|
* Edit a context's theme and theme options
|
|
*
|
|
* @param SlimRequest $slimRequest Slim request object
|
|
* @param APIResponse $response object
|
|
* @param array $args arguments
|
|
*
|
|
* @return APIResponse
|
|
*/
|
|
public function editTheme($slimRequest, $response, $args)
|
|
{
|
|
$request = $this->getRequest();
|
|
$requestContext = $request->getContext();
|
|
|
|
$contextId = (int) $args['contextId'];
|
|
|
|
// Don't allow to get one context from a different context's endpoint
|
|
if ($request->getContext() && $request->getContext()->getId() !== $contextId) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.contextsDidNotMatch');
|
|
}
|
|
|
|
// Don't allow to edit the context from the site-wide API, because the
|
|
// context's plugins will not be enabled
|
|
if (!$requestContext) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.requiresContext');
|
|
}
|
|
|
|
$contextService = Services::get('context');
|
|
$context = $contextService->get($contextId);
|
|
|
|
if (!$context) {
|
|
return $response->withStatus(404)->withJsonError('api.contexts.404.contextNotFound');
|
|
}
|
|
|
|
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
|
$allowedRoles = [Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_MANAGER];
|
|
|
|
if (!array_intersect($allowedRoles, $userRoles)) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.notAllowedEdit');
|
|
}
|
|
|
|
$params = $slimRequest->getParsedBody();
|
|
|
|
// Validate the themePluginPath and allow themes to perform their own validation
|
|
$themePluginPath = empty($params['themePluginPath']) ? null : $params['themePluginPath'];
|
|
if ($themePluginPath !== $context->getData('themePluginPath')) {
|
|
$errors = $contextService->validate(
|
|
EntityWriteInterface::VALIDATE_ACTION_EDIT,
|
|
['themePluginPath' => $themePluginPath],
|
|
$context->getSupportedFormLocales(),
|
|
$context->getPrimaryLocale()
|
|
);
|
|
if (!empty($errors)) {
|
|
return $response->withJson($errors, 400);
|
|
}
|
|
$newContext = $contextService->edit($context, ['themePluginPath' => $themePluginPath], $request);
|
|
}
|
|
|
|
// Get the appropriate theme plugin
|
|
/** @var iterable<ThemePlugin> */
|
|
$allThemes = PluginRegistry::loadCategory('themes', true);
|
|
/** @var ?ThemePlugin */
|
|
$selectedTheme = null;
|
|
foreach ($allThemes as $theme) {
|
|
if ($themePluginPath === $theme->getDirName()) {
|
|
$selectedTheme = $theme;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Run the theme's init() method if a new theme has been selected
|
|
if (isset($newContext)) {
|
|
$selectedTheme->init();
|
|
}
|
|
|
|
$errors = $selectedTheme->validateOptions($params, $themePluginPath, $context->getId(), $request);
|
|
if (!empty($errors)) {
|
|
return $response->withJson($errors, 400);
|
|
}
|
|
|
|
// Only accept params that are defined in the theme options
|
|
$options = $selectedTheme->getOptionsConfig();
|
|
foreach ($options as $optionName => $optionConfig) {
|
|
if (!array_key_exists($optionName, $params)) {
|
|
continue;
|
|
}
|
|
$selectedTheme->saveOption($optionName, $params[$optionName], $context->getId());
|
|
}
|
|
|
|
// Clear the template cache so that new settings can take effect
|
|
$templateMgr = TemplateManager::getManager(Application::get()->getRequest());
|
|
$templateMgr->clearTemplateCache();
|
|
$templateMgr->clearCssCache();
|
|
|
|
$data = array_merge(
|
|
$selectedTheme->getOptionValues($context->getId()),
|
|
['themePluginPath' => $themePluginPath]
|
|
);
|
|
|
|
ksort($data);
|
|
|
|
return $response->withJson($data, 200);
|
|
}
|
|
|
|
/** @param APIResponse $response */
|
|
public function editDoiRegistrationAgencyPlugin(SlimRequest $slimRequest, SlimResponse $response, array $args): SlimResponse
|
|
{
|
|
$request = $this->getRequest();
|
|
$requestContext = $request->getContext();
|
|
|
|
$contextId = (int) $args['contextId'];
|
|
|
|
// Don't allow to get one context from a different context's endpoint
|
|
if ($request->getContext() && $request->getContext()->getId() !== $contextId) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.contextsDidNotMatch');
|
|
}
|
|
|
|
// Don't allow to edit the context from the site-wide API, because the
|
|
// context's plugins will not be enabled
|
|
if (!$requestContext) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.requiresContext');
|
|
}
|
|
|
|
/** @var ContextService $contextService */
|
|
$contextService = Services::get('context');
|
|
$context = $contextService->get($contextId);
|
|
|
|
if (!$context) {
|
|
return $response->withStatus(404)->withJsonError('api.contexts.404.contextNotFound');
|
|
}
|
|
|
|
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
|
if (!array_intersect([Role::ROLE_ID_SITE_ADMIN, Role::ROLE_ID_MANAGER], $userRoles)) {
|
|
return $response->withStatus(403)->withJsonError('api.contexts.403.notAllowedEdit');
|
|
}
|
|
|
|
/** @var PKPSchemaService $schemaService */
|
|
$schemaService = Services::get('schema');
|
|
|
|
$params = $this->convertStringsToSchema(PKPSchemaService::SCHEMA_CONTEXT, $slimRequest->getParsedBody());
|
|
$contextFullProps = array_flip($schemaService->getFullProps(PKPSchemaService::SCHEMA_CONTEXT));
|
|
$contextParams = array_intersect_key(
|
|
$params,
|
|
$contextFullProps,
|
|
);
|
|
|
|
// Validate the registrationAgency and automatic deposit fields
|
|
// and allow agencies to perform their own validation.
|
|
if (!empty($contextParams)) {
|
|
$errors = $contextService->validate(
|
|
ContextService::VALIDATE_ACTION_EDIT,
|
|
$contextParams,
|
|
$context->getSupportedFormLocales(),
|
|
$context->getPrimaryLocale(),
|
|
);
|
|
|
|
if (!empty($errors)) {
|
|
return $response->withJson($errors, 400);
|
|
}
|
|
$contextService->edit(
|
|
$context,
|
|
$contextParams,
|
|
$request
|
|
);
|
|
}
|
|
|
|
// Return if no registration agency enabled;
|
|
if ($contextParams[Context::SETTING_CONFIGURED_REGISTRATION_AGENCY] === null) {
|
|
return $response->withJson($contextParams, 200);
|
|
}
|
|
|
|
// Get the appropriate agency plugin
|
|
$plugins = PluginRegistry::loadCategory('generic', true);
|
|
$selectedPlugin = null;
|
|
foreach ($plugins as $plugin) {
|
|
if (
|
|
$contextParams[Context::SETTING_CONFIGURED_REGISTRATION_AGENCY] === $plugin->getName()
|
|
) {
|
|
$selectedPlugin = $plugin;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Check if it's a registration agency plugin
|
|
if (!$selectedPlugin instanceof IDoiRegistrationAgency) {
|
|
return $response->withStatus(400)->withJsonError('api.dois.400.invalidPluginType');
|
|
}
|
|
|
|
// If it's a new/different registration agency plugin, update the enabled DOI types based on
|
|
// allowed types per the registration agency plugin
|
|
if (
|
|
$context->getData(Context::SETTING_CONFIGURED_REGISTRATION_AGENCY) !== $contextParams[Context::SETTING_CONFIGURED_REGISTRATION_AGENCY] &&
|
|
$contextParams[Context::SETTING_CONFIGURED_REGISTRATION_AGENCY] !== null
|
|
) {
|
|
/** @var Context $newContext */
|
|
$newContext = $contextService->get($contextId);
|
|
$enabledPubObjectTypes = $newContext->getEnabledDoiTypes();
|
|
$allowedPubObjectTypes = $selectedPlugin->getAllowedDoiTypes();
|
|
$filteredPubObjectTypes = array_intersect($enabledPubObjectTypes, $allowedPubObjectTypes);
|
|
|
|
if ($filteredPubObjectTypes != $enabledPubObjectTypes) {
|
|
$contextService->edit(
|
|
$newContext,
|
|
[Context::SETTING_ENABLED_DOI_TYPES => $filteredPubObjectTypes],
|
|
$request
|
|
);
|
|
}
|
|
}
|
|
|
|
$settingsObject = $selectedPlugin->getSettingsObject();
|
|
$params = $this->convertStringsToSchema($settingsObject::class, $slimRequest->getParsedBody());
|
|
$pluginParams = array_intersect_key(
|
|
$params,
|
|
(array) $settingsObject->getSchema()->properties,
|
|
);
|
|
|
|
// Validate plugin settings
|
|
$errors = $settingsObject->validate($pluginParams);
|
|
if (!empty($errors)) {
|
|
return $response->withStatus(400)->withJson($errors);
|
|
}
|
|
|
|
$this->updateRegistrationAgencyPluginSettings(
|
|
$contextId,
|
|
$selectedPlugin,
|
|
$settingsObject::class,
|
|
$pluginParams,
|
|
);
|
|
|
|
return $response->withJson(
|
|
array_merge($contextParams, $pluginParams),
|
|
200,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Delete a context
|
|
*
|
|
* @param SlimRequest $slimRequest Slim request object
|
|
* @param APIResponse $response object
|
|
* @param array $args arguments
|
|
*
|
|
* @return APIResponse
|
|
*/
|
|
public function delete($slimRequest, $response, $args)
|
|
{
|
|
// This endpoint is only available at the site-wide level
|
|
if ($this->getRequest()->getContext()) {
|
|
return $response->withStatus(404)->withJsonError('api.submissions.404.siteWideEndpoint');
|
|
}
|
|
|
|
$userRoles = $this->getAuthorizedContextObject(Application::ASSOC_TYPE_USER_ROLES);
|
|
if (!in_array(Role::ROLE_ID_SITE_ADMIN, $userRoles)) {
|
|
$response->withStatus(403)->withJsonError('api.contexts.403.notAllowedDelete');
|
|
}
|
|
|
|
$contextId = (int) $args['contextId'];
|
|
|
|
$contextService = Services::get('context');
|
|
$context = $contextService->get($contextId);
|
|
|
|
if (!$context) {
|
|
return $response->withStatus(404)->withJsonError('api.contexts.404.contextNotFound');
|
|
}
|
|
|
|
$contextProps = $contextService->getSummaryProperties($context, [
|
|
'request' => $this->getRequest(),
|
|
'slimRequest' => $slimRequest
|
|
]);
|
|
|
|
$contextService->delete($context);
|
|
|
|
return $response->withJson($contextProps, 200);
|
|
}
|
|
|
|
/**
|
|
* Updates a settings plugin according to a given schema. Used in lieu of a generic plugin settings management workflow.
|
|
*
|
|
* @param Plugin $plugin Currently configured registration agency plugin. Should also implement IDoiRegistrationAgency
|
|
* @param string $schemaName Name of RegistrationAgencySettings child class used as schema name
|
|
* @param array $props Plugin properties to update
|
|
*/
|
|
protected function updateRegistrationAgencyPluginSettings(int $contextId, Plugin $plugin, string $schemaName, array $props): void
|
|
{
|
|
/** @var PKPSchemaService $schemaService */
|
|
$schemaService = Services::get('schema');
|
|
$sanitizedProps = $schemaService->sanitize($schemaName, $props);
|
|
|
|
foreach ($sanitizedProps as $fieldName => $value) {
|
|
$plugin->updateSetting($contextId, $fieldName, $value);
|
|
}
|
|
}
|
|
}
|