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,93 @@
<?php
/**
* @file components/PKPStatsComponent.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 PKPStatsComponent
*
* @ingroup classes_components_stats
*
* @brief A class to prepare the data object for a statistics UI component
*/
namespace PKP\components;
use PKP\statistics\PKPStatisticsHelper;
class PKPStatsComponent
{
/** @var string The URL to the /stats API endpoint */
public $apiUrl = '';
/** @var array Configuration for the columns to display in the table */
public $tableColumns = [];
/** @var string Retrieve stats after this date */
public $dateStart = '';
/** @var string Retrieve stats before this date */
public $dateEnd = '';
/** @var array Quick options to provide for configuring the date range */
public $dateRangeOptions = [];
/** @var array|null Configuration assoc array for available filters */
public $filters = null;
/**
* Constructor
*
* @param string $apiUrl The URL to fetch stats from
* @param array $args Optional arguments
*/
public function __construct($apiUrl, $args = [])
{
$this->apiUrl = $apiUrl;
$this->init($args);
}
/**
* Initialize the handler with config parameters
*
* @param array $args Configuration params
*/
public function init($args = [])
{
foreach ($args as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
}
/**
* Retrieve the configuration data to be used when initializing this
* handler on the frontend
*
* @return array Configuration data
*/
public function getConfig()
{
$config = [
'apiUrl' => $this->apiUrl,
'tableColumns' => $this->tableColumns,
'dateStart' => $this->dateStart,
'dateStartMin' => PKPStatisticsHelper::STATISTICS_EARLIEST_DATE,
'dateEnd' => $this->dateEnd,
'dateEndMax' => date('Y-m-d', strtotime('yesterday')),
'dateRangeOptions' => $this->dateRangeOptions,
'activeFilters' => [],
'isLoadingItems' => false,
'isSidebarVisible' => false,
];
if ($this->filters) {
$config['filters'] = $this->filters;
}
return $config;
}
}
@@ -0,0 +1,60 @@
<?php
/**
* @file components/PKPStatsContextPage.php
*
* Copyright (c) 2022 Simon Fraser University
* Copyright (c) 2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPStatsContextPage
*
* @ingroup classes_controllers_stats
*
* @brief A class to prepare the data object for the context statistics
* UI component
*/
namespace PKP\components;
use PKP\statistics\PKPStatisticsHelper;
class PKPStatsContextPage extends PKPStatsComponent
{
/** @var array A timeline of stats (eg - monthly) for a graph */
public $timeline = [];
/** @var string Which time segment (eg - month) is displayed in the graph */
public $timelineInterval = PKPStatisticsHelper::STATISTICS_DIMENSION_MONTH;
/**
* Retrieve the configuration data to be used when initializing this
* handler on the frontend
*
* @return array Configuration data
*/
public function getConfig()
{
$config = parent::getConfig();
$config = array_merge(
$config,
[
'timeline' => $this->timeline,
'timelineInterval' => $this->timelineInterval,
'dateRangeLabel' => __('stats.dateRange'),
'betweenDatesLabel' => __('stats.downloadReport.betweenDates'),
'allDatesLabel' => __('stats.dateRange.allDates'),
'contextLabel' => __('context.context'),
'timelineTypeLabel' => __('stats.timelineType'),
'timelineIntervalLabel' => __('stats.timelineInterval'),
'viewsLabel' => __('submission.views'),
'dayLabel' => __('common.day'),
'monthLabel' => __('common.month'),
'timelineDescriptionLabel' => __('stats.timeline.downloadReport.description'),
'isLoadingTimeline' => false,
]
);
return $config;
}
}
@@ -0,0 +1,55 @@
<?php
/**
* @file components/PKPStatsEditorialPage.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 PKPStatsEditorialPage
*
* @ingroup classes_controllers_stats
*
* @brief A class to prepare the data object for the editorial statistics
* UI component
*/
namespace PKP\components;
class PKPStatsEditorialPage extends PKPStatsComponent
{
/** @var array A key/value array of active submissions by stage */
public $activeByStage = [];
/** @var string The URL to get the averages from the API */
public $averagesApiUrl = [];
/** @var array List of stats that should be converted to percentages */
public $percentageStats = [];
/** @var array List of stats details to display in the table */
public $tableRows = [];
/**
* Retrieve the configuration data to be used when initializing this
* handler on the frontend
*
* @return array Configuration data
*/
public function getConfig()
{
$config = parent::getConfig();
$config = array_merge(
$config,
[
'activeByStage' => $this->activeByStage,
'averagesApiUrl' => $this->averagesApiUrl,
'percentageStats' => $this->percentageStats,
'tableRows' => $this->tableRows,
]
);
return $config;
}
}
@@ -0,0 +1,93 @@
<?php
/**
* @file components/PKPStatsPublicationPage.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 PKPStatsPublicationPage
*
* @ingroup classes_controllers_stats
*
* @brief A class to prepare the data object for the publication statistics
* UI component
*/
namespace PKP\components;
use PKP\statistics\PKPStatisticsHelper;
class PKPStatsPublicationPage extends PKPStatsComponent
{
/** @var array A timeline of stats (eg - monthly) for a graph */
public $timeline = [];
/** @var string Which time segment (eg - month) is displayed in the graph */
public $timelineInterval = PKPStatisticsHelper::STATISTICS_DIMENSION_MONTH;
/** @var string Which views to show in the graph. Supports `abstract` or `galley`. */
public $timelineType = '';
/** @var array List of items to display stats for */
public $items = [];
/** @var int The maximum number of items that stats can be shown for */
public $itemsMax = 0;
/** @var int How many items to show per page */
public $count = 30;
/** @var string Order items by this property */
public $orderBy = '';
/** @var string Order items in this direction: ASC or DESC*/
public $orderDirection = 'DESC';
/** @var string A search phrase to filter the list of items */
public $searchPhrase = null;
/**
* Retrieve the configuration data to be used when initializing this
* handler on the frontend
*
* @return array Configuration data
*/
public function getConfig()
{
$config = parent::getConfig();
$config = array_merge(
$config,
[
'timeline' => $this->timeline,
'timelineInterval' => $this->timelineInterval,
'timelineType' => $this->timelineType,
'items' => $this->items,
'dateRangeLabel' => __('stats.dateRange'),
'searchPhraseLabel' => __('common.searchPhrase'),
'itemsOfTotalLabel' => __('stats.publications.countOfTotal'),
'betweenDatesLabel' => __('stats.downloadReport.betweenDates'),
'allDatesLabel' => __('stats.dateRange.allDates'),
'allFiltersLabel' => __('stats.downloadReport.allFilters'),
'commonSubmissionsLabel' => __('common.publications'),
'timelineTypeLabel' => __('stats.timelineType'),
'timelineIntervalLabel' => __('stats.timelineInterval'),
'viewsLabel' => __('submission.views'),
'downloadsLabel' => __('submission.downloads'),
'dayLabel' => __('common.day'),
'monthLabel' => __('common.month'),
'timelineDescriptionLabel' => __('stats.timeline.downloadReport.description'),
'itemsMax' => $this->itemsMax,
'count' => $this->count,
'offset' => 0,
'searchPhrase' => null,
'orderBy' => $this->orderBy,
'orderDirection' => $this->orderDirection,
'isLoadingTimeline' => false,
]
);
return $config;
}
}
@@ -0,0 +1,51 @@
<?php
/**
* @file classes/components/fileAttachers/Base.php
*
* Copyright (c) 2014-2022 Simon Fraser University
* Copyright (c) 2000-2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Base
*
* @ingroup classes_controllers_form
*
* @brief A base class for FileAttacher components.
*/
namespace PKP\components\fileAttachers;
abstract class BaseAttacher
{
public string $component;
public string $label;
public string $description;
public string $button;
/**
* Initialize the file attacher
*
* @param string $label The label to display for this file attacher
* @param string $description A description of this file attacher
* @param string $button The label for the button to activate this file attacher
*/
public function __construct(string $label, string $description, string $button)
{
$this->label = $label;
$this->description = $description;
$this->button = $button;
}
/**
* Compile the initial state for this file attacher
*/
public function getState(): array
{
return [
'component' => $this->component,
'label' => $this->label,
'description' => $this->description,
'button' => $this->button,
];
}
}
@@ -0,0 +1,82 @@
<?php
/**
* @file classes/components/fileAttachers/FileStage.php
*
* Copyright (c) 2014-2022 Simon Fraser University
* Copyright (c) 2000-2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class FileStage
*
* @ingroup classes_controllers_form
*
* @brief A class to compile initial state for a FileAttacherFileStage component.
*/
namespace PKP\components\fileAttachers;
use APP\core\Application;
use APP\submission\Submission;
use PKP\context\Context;
use PKP\submission\reviewRound\ReviewRound;
class FileStage extends BaseAttacher
{
public string $component = 'FileAttacherFileStage';
public Context $context;
public Submission $submission;
public array $fileStages = [];
/**
* Initialize a file stage attacher
*
* @param string $label The label to display for this file attacher
* @param string $description A description of this file attacher
* @param string $button The label for the button to activate this file attacher
*/
public function __construct(Context $context, Submission $submission, string $label, string $description, string $button)
{
parent::__construct($label, $description, $button);
$this->context = $context;
$this->submission = $submission;
}
/**
* Add a submission file stage that can be used for attachments
*/
public function withFileStage(int $fileStage, string $label, ?ReviewRound $reviewRound = null): self
{
$queryParams = ['fileStages' => [$fileStage]];
if ($reviewRound) {
$queryParams['reviewRoundIds'] = [$reviewRound->getId()];
}
$this->fileStages[] = [
'label' => $label,
'queryParams' => $queryParams,
];
return $this;
}
/**
* Compile the props for this file attacher
*/
public function getState(): array
{
$props = parent::getState();
$request = Application::get()->getRequest();
$props['submissionFilesApiUrl'] = $request->getDispatcher()->url(
$request,
Application::ROUTE_API,
$this->context->getData('urlPath'),
'submissions/' . $this->submission->getId() . '/files'
);
$props['fileStages'] = $this->fileStages;
$props['attachSelectedLabel'] = __('common.attachSelected');
$props['downloadLabel'] = __('common.download');
$props['backLabel'] = __('common.back');
return $props;
}
}
@@ -0,0 +1,66 @@
<?php
/**
* @file classes/components/fileAttachers/Library.php
*
* Copyright (c) 2014-2022 Simon Fraser University
* Copyright (c) 2000-2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Library
*
* @ingroup classes_controllers_form
*
* @brief A class to compile initial state for a FileAttacherLibrary component.
*/
namespace PKP\components\fileAttachers;
use APP\core\Application;
use APP\submission\Submission;
use PKP\context\Context;
class Library extends BaseAttacher
{
public string $component = 'FileAttacherLibrary';
public Context $context;
public Submission $submission;
/**
* Initialize this file attacher
*
*/
public function __construct(Context $context, ?Submission $submission = null)
{
parent::__construct(
__('email.addAttachment.libraryFiles'),
__('email.addAttachment.libraryFiles.description'),
__('email.addAttachment.libraryFiles.attach')
);
$this->context = $context;
$this->submission = $submission;
}
/**
* Compile the props for this file attacher
*/
public function getState(): array
{
$props = parent::getState();
$request = Application::get()->getRequest();
$props['libraryApiUrl'] = $request->getDispatcher()->url(
$request,
Application::ROUTE_API,
$this->context->getData('urlPath'),
'_library'
);
if ($this->submission) {
$props['includeSubmissionId'] = $this->submission->getId();
}
$props['attachSelectedLabel'] = __('common.attachSelected');
$props['backLabel'] = __('common.back');
$props['downloadLabel'] = __('common.download');
return $props;
}
}
@@ -0,0 +1,99 @@
<?php
/**
* @file classes/components/fileAttachers/ReviewFiles.php
*
* Copyright (c) 2014-2022 Simon Fraser University
* Copyright (c) 2000-2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class ReviewFiles
*
* @ingroup classes_controllers_form
*
* @brief A class to compile initial state for a FileAttacherReviewFiles component.
*/
namespace PKP\components\fileAttachers;
use APP\core\Application;
use APP\core\Services;
use APP\facades\Repo;
use Exception;
use PKP\context\Context;
use PKP\submission\reviewAssignment\ReviewAssignment;
use PKP\submissionFile\SubmissionFile;
class ReviewFiles extends BaseAttacher
{
public string $component = 'FileAttacherReviewFiles';
public Context $context;
/** @var iterable<SubmissionFile> $files */
public iterable $files;
/** @var array<ReviewAssignment> $reviewAssignments */
public array $reviewAssignments;
/**
* Initialize this file attacher
*
* @param string $label The label to display for this file attacher
* @param string $description A description of this file attacher
* @param string $button The label for the button to activate this file attacher
*/
public function __construct(string $label, string $description, string $button, iterable $files, array $reviewAssignments, Context $context)
{
parent::__construct($label, $description, $button);
$this->files = $files;
$this->reviewAssignments = $reviewAssignments;
$this->context = $context;
}
/**
* Compile the props for this file attacher
*/
public function getState(): array
{
$props = parent::getState();
$props['attachSelectedLabel'] = __('common.attachSelected');
$props['backLabel'] = __('common.back');
$props['downloadLabel'] = __('common.download');
$props['files'] = $this->getFilesState();
return $props;
}
protected function getFilesState(): array
{
$request = Application::get()->getRequest();
$files = [];
/** @var SubmissionFile $file */
foreach ($this->files as $file) {
if (!isset($this->reviewAssignments[$file->getData('assocId')])) {
throw new Exception('Tried to add review file attachment from unknown review assignment.');
}
$files[] = [
'id' => $file->getId(),
'name' => $file->getData('name'),
'documentType' => Services::get('file')->getDocumentType($file->getData('documentType')),
'reviewerName' => $this->reviewAssignments[$file->getData('assocId')]->getReviewerFullName(),
'url' => $request->getDispatcher()->url(
$request,
Application::ROUTE_COMPONENT,
$this->context->getData('urlPath'),
'api.file.FileApiHandler',
'downloadFile',
null,
[
'submissionFileId' => $file->getId(),
'submissionId' => $file->getData('submissionId'),
'stageId' => Repo::submissionFile()->getWorkflowStageId($file),
]
),
];
}
return $files;
}
}
@@ -0,0 +1,77 @@
<?php
/**
* @file classes/components/fileAttachers/Upload.php
*
* Copyright (c) 2014-2022 Simon Fraser University
* Copyright (c) 2000-2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class Upload
*
* @ingroup classes_controllers_form
*
* @brief A class to compile initial state for a FileAttacherUpload component.
*/
namespace PKP\components\fileAttachers;
use APP\core\Application;
use PKP\context\Context;
class Upload extends BaseAttacher
{
public string $component = 'FileAttacherUpload';
public Context $context;
/**
* Initialize this file attacher
*
* @param string $label The label to display for this file attacher
* @param string $description A description of this file attacher
* @param string $button The label for the button to activate this file attacher
*/
public function __construct(Context $context, string $label, string $description, string $button)
{
parent::__construct($label, $description, $button);
$this->context = $context;
}
/**
* Compile the props for this file attacher
*/
public function getState(): array
{
$props = parent::getState();
$request = Application::get()->getRequest();
$props['temporaryFilesApiUrl'] = $request->getDispatcher()->url(
$request,
Application::ROUTE_API,
$this->context->getData('urlPath'),
'temporaryFiles'
);
$props['dropzoneOptions'] = [
'maxFilesize' => Application::getIntMaxFileMBs(),
'timeout' => ini_get('max_execution_time') ? ini_get('max_execution_time') * 1000 : 0,
'dropzoneDictDefaultMessage' => __('form.dropzone.dictDefaultMessage'),
'dropzoneDictFallbackMessage' => __('form.dropzone.dictFallbackMessage'),
'dropzoneDictFallbackText' => __('form.dropzone.dictFallbackText'),
'dropzoneDictFileTooBig' => __('form.dropzone.dictFileTooBig'),
'dropzoneDictInvalidFileType' => __('form.dropzone.dictInvalidFileType'),
'dropzoneDictResponseError' => __('form.dropzone.dictResponseError'),
'dropzoneDictCancelUpload' => __('form.dropzone.dictCancelUpload'),
'dropzoneDictUploadCanceled' => __('form.dropzone.dictUploadCanceled'),
'dropzoneDictCancelUploadConfirmation' => __('form.dropzone.dictCancelUploadConfirmation'),
'dropzoneDictRemoveFile' => __('form.dropzone.dictRemoveFile'),
'dropzoneDictMaxFilesExceeded' => __('form.dropzone.dictMaxFilesExceeded'),
];
$props['addFilesLabel'] = __('common.addFiles');
$props['attachFilesLabel'] = __('common.attachFiles');
$props['dragAndDropMessage'] = __('common.dragAndDropHere');
$props['dragAndDropOrUploadMessage'] = __('common.orUploadFile');
$props['backLabel'] = __('common.back');
$props['removeItemLabel'] = __('common.removeItem');
return $props;
}
}
+169
View File
@@ -0,0 +1,169 @@
<?php
/**
* @file classes/components/form/Field.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 Field
*
* @ingroup classes_controllers_form
*
* @brief A base class representing a single field in a form.
*/
namespace PKP\components\forms;
abstract class Field
{
/** @var string Which UI Library component this field represents */
public $component;
/** @var string The form input name for this field */
public $name;
/** @var string|object Field label or multilingual object matching locales to labels, eg ['en' => 'Label', 'fr_CA' => 'Étiquette'] */
public $label = '';
/** @var string Field description */
public $description;
/** @var string Field tooltip */
public $tooltip;
/** @var string Field help topic. Refers to the /dev/docs file name without .md */
public $helpTopic;
/** @var string Field help section. An optional anchor link to open to when loading the helpTopic. */
public $helpSection;
/** @var string Which group should this field be placed in? */
public $groupId;
/** @var bool Is this field required? */
public $isRequired = false;
/** @var bool Is this field multilingual? */
public $isMultilingual = false;
/** @var mixed The value of this field. If multilingual, expects a key/value array: ['en', => 'English value', 'fr_CA' => 'French value'] */
public $value;
/** @var mixed A default for this field when no value is specified. */
public $default;
/**
* Only show this field when the field named here is not empty. Match an exact
* value by passing an array:
*
* $this->showWhen = ['fieldName', 'expectedValue'];
*
* @var string|array
*/
public $showWhen;
/** @var array List of required properties for this field. */
private $_requiredProperties = ['name', 'component'];
/**
* Initialize the form field
*
* @param string $name
* @param array $args [
*
* @option label string|object
* @option groupId string
* @option isRequired boolean
* @option isMultilingual boolean
* ]
*/
public function __construct($name, $args = [])
{
$this->name = $name;
foreach ($args as $key => $value) {
if (property_exists($this, $key)) {
$this->{$key} = $value;
}
}
}
/**
* Get a configuration object representing this field to be passed to the UI
* Library
*
* @return array
*/
public function getConfig()
{
if (!$this->validate()) {
throw new \Exception('Form field configuration did not pass validation: ' . print_r($this, true));
}
$config = [
'name' => $this->name,
'component' => $this->component,
'label' => $this->label,
];
if (isset($this->description)) {
$config['description'] = $this->description;
}
if (isset($this->tooltip)) {
$config['tooltip'] = $this->tooltip;
}
if (isset($this->helpTopic)) {
$config['helpTopic'] = $this->helpTopic;
if ($this->helpSection) {
$config['helpSection'] = $this->helpSection;
}
}
if (isset($this->groupId)) {
$config['groupId'] = $this->groupId;
}
if (isset($this->isRequired)) {
$config['isRequired'] = $this->isRequired;
}
if (isset($this->isMultilingual)) {
$config['isMultilingual'] = $this->isMultilingual;
}
if (isset($this->showWhen)) {
$config['showWhen'] = $this->showWhen;
}
$config['value'] = $this->value ?? $this->default ?? null;
return $config;
}
/**
* Validate the field configuration
*
* Check that no required fields are missing
*
* @return bool
*/
public function validate()
{
foreach ($this->_requiredProperties as $property) {
if (!isset($this->{$property})) {
return false;
}
}
return true;
}
/**
* Get a default empty value for this field type
*
* The UI Library expects to receive a value property for each field. If it's
* a multilingual field, it expects the value property to contain keys for
* each locale in the form.
*
* This function will provide a default empty value so that a form can fill
* in the empty values automatically.
*
*/
public function getEmptyValue()
{
return '';
}
}
@@ -0,0 +1,81 @@
<?php
/**
* @file classes/components/form/FieldControlledVocab.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 FieldAutosuggestPreset
*
* @ingroup classes_controllers_form
*
* @brief A type of autosuggest field that preloads all of its options.
*/
namespace PKP\components\forms;
class FieldAutosuggestPreset extends FieldBaseAutosuggest
{
/** @copydoc Field::$component */
public $component = 'field-autosuggest-preset';
/** @var array Key/value list of suggestions for this field */
public $options = [];
/** @var array Key/value list of languages this field should support. Key = locale code. Value = locale name */
public $locales = [];
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['options'] = $this->options;
$config['selected'] = $this->getSelected();
return $config;
}
/**
* @copydoc Field::getConfig()
*/
protected function getSelected(): array
{
if ($this->isMultilingual) {
$selected = [];
foreach ($this->locales as $locale) {
if (array_key_exists($locale['key'], $this->value)) {
$config['selected'][$locale['key']] = array_map([$this, 'mapSelected'], (array) $this->value[$locale['key']]);
} else {
$config['selected'][$locale['key']] = [];
}
}
return $selected;
}
return array_map([$this, 'mapSelected'], $this->value);
}
/**
* Map the selected values to the format expected by an
* autosuggest field
*
* @param string $value
*
* @return array
*/
protected function mapSelected($value)
{
foreach ($this->options as $option) {
if ($option['value'] === $value) {
return $option;
}
}
return [
'value' => $value,
'label' => $value,
];
}
}
@@ -0,0 +1,49 @@
<?php
/**
* @file classes/components/form/FieldBaseAutosuggest.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 FieldBaseAutosuggest
*
* @ingroup classes_controllers_form
*
* @brief A base class for text fields that provide suggested values while typing.
*/
namespace PKP\components\forms;
define('AUTOSUGGEST_POSITION_INLINE', 'inline');
define('AUTOSUGGEST_POSITION_BELOW', 'below');
abstract class FieldBaseAutosuggest extends Field
{
/** @copydoc Field::$component */
public $component = 'field-base-autosuggest';
/** @var string A URL to retrieve suggestions. */
public $apiUrl;
/** @var array Query params when getting suggestions. */
public $getParams = [];
/** @var array List of selected items. */
public $selected = [];
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['apiUrl'] = $this->apiUrl;
$config['deselectLabel'] = __('common.removeItem');
$config['getParams'] = empty($this->getParams) ? new \stdClass() : $this->getParams;
$config['selectedLabel'] = __('common.selectedPrefix');
$config['selected'] = $this->selected;
return $config;
}
}
@@ -0,0 +1,22 @@
<?php
/**
* @file classes/components/form/FieldColor.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 FieldColor
*
* @ingroup classes_controllers_form
*
* @brief A color picker field in a form.
*/
namespace PKP\components\forms;
class FieldColor extends Field
{
/** @copydoc Field::$component */
public $component = 'field-color';
}
@@ -0,0 +1,64 @@
<?php
/**
* @file classes/components/form/FieldControlledVocab.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 FieldControlledVocab
*
* @ingroup classes_controllers_form
*
* @brief A type of autosuggest field for controlled vocabulary like keywords.
*/
namespace PKP\components\forms;
class FieldControlledVocab extends FieldBaseAutosuggest
{
/** @copydoc Field::$component */
public $component = 'field-controlled-vocab';
/** @var array Key/value list of languages this field should support. Key = locale code. Value = locale name */
public $locales = [];
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
if ($this->isMultilingual) {
$config['selected'] = [];
foreach ($this->locales as $locale) {
if (array_key_exists($locale['key'], $this->value)) {
$config['selected'][$locale['key']] = array_map([$this, 'mapSelected'], (array) $this->value[$locale['key']]);
} else {
$config['selected'][$locale['key']] = [];
}
}
} else {
$config['selected'] = array_map([$this, 'mapSelected'], $this->value);
}
return $config;
}
/**
* Map the selected values to the format expected by an
* autosuggest field
*
* @param string $value
*
* @return array
*/
public function mapSelected($value)
{
return [
'value' => $value,
'label' => $value,
];
}
}
@@ -0,0 +1,23 @@
<?php
/**
* @file classes/components/form/FieldHTML.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 FieldHTML
*
* @ingroup classes_controllers_form
*
* @brief A component for inserting HTML into a form, when you don't need any
* input fields or values stored.
*/
namespace PKP\components\forms;
class FieldHTML extends Field
{
/** @copydoc Field::$component */
public $component = 'field-html';
}
@@ -0,0 +1,50 @@
<?php
/**
* @file classes/components/form/FieldMetadataSetting.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 FieldMetadataSetting
*
* @ingroup classes_controllers_form
*
* @brief A field to enable a type of metadata and determine when it should be
* requested or required.
*/
namespace PKP\components\forms;
use PKP\context\Context;
class FieldMetadataSetting extends FieldOptions
{
/** @copydoc Field::$component */
public $component = 'field-metadata-setting';
/** @var int What is the value that represents metadata that is disabled */
public $disabledValue = Context::METADATA_DISABLE;
/**
* @var int What is the value that represents metadata that is enabled,
* but which is not requested or required during submission?
*/
public $enabledOnlyValue = Context::METADATA_ENABLE;
/** @var array The options for what to request/require from the author during submission */
public $submissionOptions = [];
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['disabledValue'] = $this->disabledValue;
$config['enabledOnlyValue'] = $this->enabledOnlyValue;
$config['submissionOptions'] = $this->submissionOptions;
return $config;
}
}
@@ -0,0 +1,44 @@
<?php
/**
* @file classes/components/form/FieldOptions.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 FieldOptions
*
* @ingroup classes_controllers_form
*
* @brief A field to select from a set of checkbox or radio options.
*/
namespace PKP\components\forms;
class FieldOptions extends Field
{
/** @copydoc Field::$component */
public $component = 'field-options';
/** @var string Use a checkbox or radio button input type */
public $type = 'checkbox';
/** @var bool Should the user be able to re-order the options? */
public $isOrderable = false;
/** @var array The options which can be selected */
public $options = [];
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['type'] = $this->type;
$config['isOrderable'] = $this->isOrderable;
$config['options'] = $this->options;
return $config;
}
}
@@ -0,0 +1,40 @@
<?php
/**
* @file classes/components/form/FieldPreparedContent.php
*
* Copyright (c) 2014-2022 Simon Fraser University
* Copyright (c) 2000-2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class FieldPreparedContent
*
* @ingroup classes_controllers_form
*
* @brief A rich text editor that can insert prepared content snippets
*/
namespace PKP\components\forms;
class FieldPreparedContent extends FieldRichTextarea
{
public $component = 'field-prepared-content';
/**
* A list of content that can be inserted from a TinyMCE button.
*
* @see FieldPreparedContent in the UI Library for details on the expected format
*/
public array $preparedContent = [];
public function getConfig()
{
$config = parent::getConfig();
$config['preparedContentLabel'] = __('common.content');
$config['insertLabel'] = __('common.insert');
$config['insertModalLabel'] = __('common.insertContent');
$config['searchLabel'] = __('common.insertContentSearch');
$config['preparedContent'] = $this->preparedContent;
return $config;
}
}
@@ -0,0 +1,112 @@
<?php
/**
* @file classes/components/form/FieldPubId.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 FieldPubId
*
* @ingroup classes_controllers_form
*
* @brief A field for generating a pub id, like a DOI.
*/
namespace PKP\components\forms;
class FieldPubId extends Field
{
/** @copydoc Field::$component */
public $component = 'field-pub-id';
/** @var string A localized label for the button to assign the pubid */
public $assignIdLabel;
/** @var string A localized label for the button to clear the pubid */
public $clearIdLabel;
/** @var string The journal/press initials to use when generating a pub id */
public $contextInitials;
/** @var bool If a %p in the pattern should stand for press (OMP). Otherwise it means pages (OJS). */
public $isPForPress = false;
/** @var string The issue number to use when generating a pub id */
public $issueNumber;
/** @var string The issue volume to use when generating a pub id */
public $issueVolume;
/** @var string A localized message when the pub id can not be generated due to missing information */
public $missingPartsLabel;
/** @var string The page numbers use when generating a pub id */
public $pages;
/** @var string The pattern to use when generating a pub id */
public $pattern;
/** @var string The pub id prefix for this context */
public $prefix;
/** @var string The publisher id to use when generating a pub id */
public $publisherId;
/** @var string Optional separator to add between prefix and suffix when generating pub id */
public $separator = '';
/** @var string The submission ID to use when generating a pub id */
public $submissionId;
/** @var string The publication ID to use when generating a pub id */
public $publicationId;
/** @var string The year of publication to use when generating a pub id */
public $year;
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['assignIdLabel'] = $this->assignIdLabel;
$config['clearIdLabel'] = $this->clearIdLabel;
$config['missingPartsLabel'] = $this->missingPartsLabel;
if (isset($this->contextInitials)) {
$config['contextInitials'] = $this->contextInitials;
}
if (isset($this->issueNumber)) {
$config['issueNumber'] = $this->issueNumber;
}
if (isset($this->issueVolume)) {
$config['issueVolume'] = $this->issueVolume;
}
if (isset($this->pages)) {
$config['pages'] = $this->pages;
}
if (isset($this->pattern)) {
$config['pattern'] = $this->pattern;
}
if (isset($this->prefix)) {
$config['prefix'] = $this->prefix;
}
if (isset($this->publisherId)) {
$config['publisherId'] = $this->publisherId;
}
if (isset($this->submissionId)) {
$config['submissionId'] = $this->submissionId;
}
if (isset($this->publicationId)) {
$config['publicationId'] = $this->publicationId;
}
if (isset($this->year)) {
$config['year'] = $this->year;
}
$config['isPForPress'] = $this->isPForPress;
$config['separator'] = $this->separator;
return $config;
}
}
@@ -0,0 +1,37 @@
<?php
/**
* @file classes/components/form/FieldRadioInput.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 FieldRadioInput
*
* @ingroup classes_controllers_form
*
* @brief A field to select one of a set of options, and one option is a text
* field for entering a custom value.
*/
namespace PKP\components\forms;
class FieldRadioInput extends Field
{
/** @copydoc Field::$component */
public $component = 'field-radio-input';
/** @var array The options which can be selected */
public $options = [];
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['options'] = $this->options;
return $config;
}
}
@@ -0,0 +1,54 @@
<?php
/**
* @file classes/components/form/FieldRichText.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 FieldRichText
*
* @ingroup classes_controllers_form
*
* @brief A rich single line text editor field in a form.
*/
namespace PKP\components\forms;
class FieldRichText extends Field
{
/** @copydoc Field::$component */
public $component = 'field-rich-text';
/** @var array Optional. An assoc array of init properties to pass to TinyMCE */
public $init;
/** @var string Optional. A preset size option. */
public $size = 'oneline';
/** @var string Optional. A preset toolbar configuration. */
public $toolbar = 'formatgroup';
/** @var array Optional. A list of required plugins. */
public $plugins = 'paste';
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['i18nFormattingLabel'] = __('common.formatting');
$config['toolbar'] = $this->toolbar;
$config['plugins'] = $this->plugins;
$config['size'] = $this->size;
if (!empty($this->init)) {
$config['init'] = $this->init;
}
return $config;
}
}
@@ -0,0 +1,65 @@
<?php
/**
* @file classes/components/form/FieldRichTextarea.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 FieldRichTextarea
*
* @ingroup classes_controllers_form
*
* @brief A rich text editor field in a form.
*/
namespace PKP\components\forms;
class FieldRichTextarea extends Field
{
/** @copydoc Field::$component */
public $component = 'field-rich-textarea';
/** @var array Optional. An assoc array of init properties to pass to TinyMCE */
public $init;
/** @var array Optional. A list of required plugins. */
public $plugins = 'paste,link,noneditable';
/** @var string Optional. A preset size option. */
public $size;
/** @var string Optional. A preset toolbar configuration. */
public $toolbar = 'bold italic superscript subscript | link';
/** @var string Optional. The API endpoint to upload images to. Only include if image uploads are supported here. */
public $uploadUrl;
/** @var int Optional. When a word limit is specified a word counter will be shown */
public $wordLimit = 0;
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
if (!empty($this->init)) {
$config['init'] = $this->init;
}
$config['plugins'] = $this->plugins;
if (!empty($this->size)) {
$config['size'] = $this->size;
}
$config['toolbar'] = $this->toolbar;
if (!empty($this->uploadUrl)) {
$config['uploadUrl'] = $this->uploadUrl;
}
if ($this->wordLimit) {
$config['wordLimit'] = $this->wordLimit;
$config['wordCountLabel'] = __('publication.wordCount');
}
return $config;
}
}
@@ -0,0 +1,36 @@
<?php
/**
* @file classes/components/form/FieldSelect.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 FieldSelect
*
* @ingroup classes_controllers_form
*
* @brief A select field in a form.
*/
namespace PKP\components\forms;
class FieldSelect extends Field
{
/** @copydoc Field::$component */
public $component = 'field-select';
/** @var array The options which can be selected */
public $options = [];
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['options'] = $this->options;
return $config;
}
}
@@ -0,0 +1,22 @@
<?php
/**
* @file classes/components/form/FieldSelectSubmissions.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 FieldSelectSubmissions
*
* @ingroup classes_controllers_form
*
* @brief A text field to search for and select submissions.
*/
namespace PKP\components\forms;
class FieldSelectSubmissions extends FieldBaseAutosuggest
{
/** @copydoc Field::$component */
public $component = 'field-select-submissions';
}
@@ -0,0 +1,22 @@
<?php
/**
* @file classes/components/form/FieldSelectUsers.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 FieldSelectUsers
*
* @ingroup classes_controllers_form
*
* @brief A text field to search for and select users.
*/
namespace PKP\components\forms;
class FieldSelectUsers extends FieldBaseAutosuggest
{
/** @copydoc Field::$component */
public $component = 'field-select-users';
}
@@ -0,0 +1,39 @@
<?php
/**
* @file classes/components/form/FieldShowEnsuringLink.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 FieldShowEnsuringLink
*
* @ingroup classes_controllers_form
*
* @brief An extension of the FieldOptions for the configuration setting which
* determines whether or not to show a link to reviewers about keeping reviews
* anonymous.
*/
namespace PKP\components\forms;
class FieldShowEnsuringLink extends FieldOptions
{
/** @copydoc Field::$component */
public $component = 'field-show-ensuring-link';
/** @var string The message to show in a modal when the link is clicked. */
public $message = '';
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['message'] = __('review.anonymousPeerReview');
$config['modalTitle'] = __('review.anonymousPeerReview.title');
return $config;
}
}
@@ -0,0 +1,52 @@
<?php
/**
* @file classes/components/form/FieldText.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 FieldText
*
* @ingroup classes_controllers_form
*
* @brief A basic text field in a form.
*/
namespace PKP\components\forms;
class FieldText extends Field
{
/** @copydoc Field::$component */
public $component = 'field-text';
/** @var string What should the <input type=""> be? */
public $inputType = 'text';
/** @var bool Whether the user should have to click a button to edit the field */
public $optIntoEdit = false;
/** @var string The label of the button added by self::$optIntoEdit */
public $optIntoEditLabel = '';
/** @var string Accepts: `small`, `normal` or `large` */
public $size = 'normal';
/** @var string A prefix to display before the input value */
public $prefix = '';
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['inputType'] = $this->inputType;
$config['optIntoEdit'] = $this->optIntoEdit;
$config['optIntoEditLabel'] = $this->optIntoEditLabel;
$config['size'] = $this->size;
$config['prefix'] = $this->prefix;
return $config;
}
}
@@ -0,0 +1,38 @@
<?php
/**
* @file classes/components/form/FieldTextarea.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 FieldTextarea
*
* @ingroup classes_controllers_form
*
* @brief A multiline textarea field in a form.
*/
namespace PKP\components\forms;
class FieldTextarea extends Field
{
/** @copydoc Field::$component */
public $component = 'field-textarea';
/** @var string Optional. A preset size option. */
public $size;
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
if (isset($this->size)) {
$config['size'] = $this->size;
}
return $config;
}
}
@@ -0,0 +1,86 @@
<?php
/**
* @file classes/components/form/FieldUpload.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 FieldUpload
*
* @ingroup classes_controllers_form
*
* @brief A field for uploading a file.
*/
namespace PKP\components\forms;
use APP\core\Application;
class FieldUpload extends Field
{
/** @copydoc Field::$component */
public $component = 'field-upload';
/**
* @var array Options to pass to the dropzone.js instance.
*
* A `url` key must be included with the value of the API endpoint where files
* can be uploaded to: <api-path>/temporaryFiles.
*/
public $options = [];
/**
* @copydoc Field::__construct()
*/
public function __construct($name, $args = [])
{
parent::__construct($name, $args);
$this->options['maxFilesize'] = Application::getIntMaxFileMBs();
$this->options['timeout'] = ini_get('max_execution_time')
? ini_get('max_execution_time') * 1000
: 0;
$this->options = array_merge(
[
'dropzoneDictDefaultMessage' => __('form.dropzone.dictDefaultMessage'),
'dropzoneDictFallbackMessage' => __('form.dropzone.dictFallbackMessage'),
'dropzoneDictFallbackText' => __('form.dropzone.dictFallbackText'),
'dropzoneDictFileTooBig' => __('form.dropzone.dictFileTooBig'),
'dropzoneDictInvalidFileType' => __('form.dropzone.dictInvalidFileType'),
'dropzoneDictResponseError' => __('form.dropzone.dictResponseError'),
'dropzoneDictCancelUpload' => __('form.dropzone.dictCancelUpload'),
'dropzoneDictUploadCanceled' => __('form.dropzone.dictUploadCanceled'),
'dropzoneDictCancelUploadConfirmation' => __('form.dropzone.dictCancelUploadConfirmation'),
'dropzoneDictRemoveFile' => __('form.dropzone.dictRemoveFile'),
'dropzoneDictMaxFilesExceeded' => __('form.dropzone.dictMaxFilesExceeded'),
],
$this->options
);
}
/**
* @copydoc Field::validate()
*/
public function validate()
{
if (empty($this->options['url'])) {
return false;
}
return parent::validate();
}
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['options'] = $this->options;
$config['uploadFileLabel'] = __('common.upload.addFile');
$config['restoreLabel'] = __('common.upload.restore');
return $config;
}
}
@@ -0,0 +1,60 @@
<?php
/**
* @file classes/components/form/FieldUploadImage.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 FieldUploadImage
*
* @ingroup classes_controllers_form
*
* @brief A field for uploading a file.
*/
namespace PKP\components\forms;
class FieldUploadImage extends FieldUpload
{
/** @copydoc Field::$component */
public $component = 'field-upload-image';
/** @var string Base url for displaying the image */
public $baseUrl = '';
/** @var string Label for the alt text field */
public $altTextLabel = '';
/** @var string Description for the alt text field */
public $altTextDescription = '';
/** @var string Description for the image thumbnail */
public $thumbnailDescription = '';
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
if (!array_key_exists('acceptedFiles', $this->options)) {
$this->options['acceptedFiles'] = 'image/*';
}
$config = parent::getConfig();
$config['baseUrl'] = $this->baseUrl;
$config['thumbnailDescription'] = __('common.upload.thumbnailPreview');
$config['altTextLabel'] = __('common.altText');
$config['altTextDescription'] = __('common.altTextInstructions');
return $config;
}
/**
* @copydoc Field::getEmptyValue()
*/
public function getEmptyValue()
{
return null;
}
}
@@ -0,0 +1,347 @@
<?php
/**
* @file classes/components/form/FormComponent.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 FormComponent
*
* @ingroup classes_controllers_form
*
* @brief A base class for building forms to be passed to the Form component
* in the UI Library.
*/
namespace PKP\components\forms;
use Exception;
use PKP\facades\Locale;
use PKP\plugins\Hook;
define('FIELD_POSITION_BEFORE', 'before');
define('FIELD_POSITION_AFTER', 'after');
class FormComponent
{
/**
* @var string An $action value that will emit an event
* when the form is submitted, instead of sending a
* HTTP request
*/
public const ACTION_EMIT = 'emit';
/** @var string A unique ID for this form */
public $id = '';
/** @var string Form method: POST or PUT */
public $method = '';
/** @var string Where the form should be submitted. */
public $action = '';
/** @var array Key/value list of languages this form should support. Key = locale code. Value = locale name */
public $locales = [];
/** @var array List of fields in this form. */
public $fields = [];
/** @var array List of groups in this form. */
public $groups = [];
/** @var array List of hidden fields in this form. */
public $hiddenFields = [];
/** @var array List of pages in this form. */
public $pages = [];
/** @var array List of error messages */
public $errors = [];
/**
* Initialize the form with config parameters
*
* @param string $id
* @param string $method
* @param string $action
* @param array $locales
*/
public function __construct($id, $method, $action, $locales)
{
$this->id = $id;
$this->action = $action;
$this->method = $method;
$this->locales = $locales;
}
/**
* Add a form field
*
* @param Field $field
* @param array $position [
*
* @option string One of FIELD_POSITION_BEFORE or FIELD_POSITION_AFTER
* @option string The field to position it before or after
* ]
*/
public function addField($field, $position = []): static
{
if (empty($position)) {
$this->fields[] = $field;
} else {
$this->fields = $this->addToPosition($position[1], $this->fields, $field, $position[0]);
}
return $this;
}
/**
* Remove a form field
*
* @param string $fieldName
*/
public function removeField($fieldName): static
{
$this->fields = array_values(array_filter($this->fields, function ($field) use ($fieldName) {
return $field->name !== $fieldName;
}));
return $this;
}
/**
* Get a form field
*
* @param string $fieldName
*
* @return ?Field
*/
public function getField($fieldName)
{
foreach ($this->fields as $field) {
if ($field->name === $fieldName) {
return $field;
}
}
return null;
}
/**
* Add a form group
*
* @param array $args [
*
* @option id string Required A unique ID for this form group
* @option label string A label to identify this group of fields. Will become the fieldset's <legend>
* @option description string A description of this group of fields.
* ]
*
* @param array $position [
*
* @option string One of FIELD_POSITION_BEFORE or FIELD_POSITION_AFTER
* @option string The group to position it before or after
* ]
*/
public function addGroup($args, $position = []): static
{
if (empty($args['id'])) {
throw new Exception('Tried to add a form group without an id.');
}
if (empty($position)) {
$this->groups[] = $args;
} else {
$this->groups = $this->addToPosition($position[1], $this->groups, $args, $position[0]);
}
return $this;
}
/**
* Remove a form group
*
* @param string $groupId
*/
public function removeGroup($groupId): static
{
$this->groups = array_filter($this->groups, function ($group) use ($groupId) {
return $group['id'] !== $groupId;
});
$this->fields = array_filter($this->fields, function ($field) use ($groupId) {
return $field['groupId'] !== $groupId;
});
return $this;
}
/**
* Add a form page
*
* @param array $args [
*
* @option id string Required A unique ID for this form page
* @option label string The name of the page to identify it in the page list
* @option submitButton array Required Assoc array defining submission/next button params. Supports any param of the Button component in the UI Library.
* @option previousButton array Assoc array defining button params to go back to the previous page. Supports any param of the Button component in the UI Library.
* ]
*
* @param array $position [
*
* @option string One of FIELD_POSITION_BEFORE or FIELD_POSITION_AFTER
* @option string The page to position it before or after
* ]
*/
public function addPage($args, $position = []): static
{
if (empty($args['id'])) {
fatalError('Tried to add a form page without an id.');
}
if (empty($position)) {
$this->pages[] = $args;
} else {
$this->pages = $this->addToPosition($position[1], $this->pages, $args, $position[0]);
}
return $this;
}
/**
* Remove a form page
*
* @param string $pageId
*/
public function removePage($pageId): static
{
$this->pages = array_filter($this->pages, function ($page) use ($pageId) {
return $page['id'] !== $pageId;
});
foreach ($this->groups as $group) {
if ($group['pageId'] === $pageId) {
$this->removeGroup($group['id']);
}
}
return $this;
}
/**
* Add an field, group or page to a specific position in its array
*
* @param string $id The id of the item to position before or after
* @param array $list The list of fields, groups or pages
* @param mixed $item The item to insert
* @param string $position FIELD_POSITION_BEFORE or FIELD_POSITION_AFTER
*
* @return array
*/
public function addToPosition($id, $list, $item, $position)
{
$index = count($list);
foreach ($list as $key => $val) {
if (($val instanceof \PKP\components\forms\Field && $id === $val->name) || (!$val instanceof \PKP\components\forms\Field && $id === $val['id'])) {
$index = $key;
break;
}
}
if (!$index && $position === FIELD_POSITION_BEFORE) {
array_unshift($list, $item);
return $list;
}
$slice = $position === FIELD_POSITION_BEFORE ? $index : $index + 1;
return array_merge(
array_slice($list, 0, $slice),
[$item],
array_slice($list, $slice)
);
}
/**
* Add a hidden field to this form
*/
public function addHiddenField(string $name, $value)
{
$this->hiddenFields[$name] = $value;
}
/**
* Retrieve the configuration data to be used when initializing this
* handler on the frontend
*
* @return array Configuration data
*/
public function getConfig()
{
if (empty($this->id) || empty($this->action) || ($this->action !== self::ACTION_EMIT && empty($this->method))) {
throw new Exception('FormComponent::getConfig() was called but one or more required property is missing: id, method, action.');
}
Hook::run('Form::config::before', [$this]);
// Add a default page/group if none exist
if (!$this->groups) {
$this->addGroup(['id' => 'default']);
$this->fields = array_map(function ($field) {
$field->groupId = 'default';
return $field;
}, $this->fields);
}
if (!$this->pages) {
$this->addPage(['id' => 'default', 'submitButton' => ['label' => __('common.save')]]);
$this->groups = array_map(function ($group) {
$group['pageId'] = 'default';
return $group;
}, $this->groups);
}
$fieldsConfig = array_map([$this, 'getFieldConfig'], $this->fields);
$visibleLocales = [Locale::getLocale()];
if (Locale::getLocale() !== Locale::getPrimaryLocale()) {
array_unshift($visibleLocales, Locale::getPrimaryLocale());
}
$config = [
'id' => $this->id,
'method' => $this->method,
'action' => $this->action,
'fields' => $fieldsConfig,
'groups' => $this->groups,
'hiddenFields' => (object) $this->hiddenFields,
'pages' => $this->pages,
'primaryLocale' => Locale::getPrimaryLocale(),
'visibleLocales' => $visibleLocales,
'supportedFormLocales' => array_values($this->locales), // See #5690
'errors' => (object) [],
];
Hook::call('Form::config::after', [&$config, $this]);
return $config;
}
/**
* Compile a configuration array for a single field
*
* @param Field $field
*
* @return array
*/
public function getFieldConfig($field)
{
$config = $field->getConfig();
// Add a value property if the field does not include one
if (!array_key_exists('value', $config)) {
$config['value'] = $field->isMultilingual ? [] : $field->getEmptyValue();
}
if ($field->isMultilingual) {
if (is_null($config['value'])) {
$config['value'] = [];
}
foreach ($this->locales as $locale) {
if (!array_key_exists($locale['key'], $config['value'])) {
$config['value'][$locale['key']] = $field->getEmptyValue();
}
}
}
return $config;
}
}
@@ -0,0 +1,123 @@
<?php
/**
* @file classes/components/form/announcement/PKPAnnouncementForm.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 PKPAnnouncementForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for creating a new announcement
*/
namespace PKP\components\forms\announcement;
use APP\core\Application;
use PKP\announcement\AnnouncementTypeDAO;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldText;
use PKP\components\forms\FieldUploadImage;
use PKP\components\forms\FormComponent;
use PKP\config\Config;
use PKP\context\Context;
use PKP\db\DAORegistry;
define('FORM_ANNOUNCEMENT', 'announcement');
class PKPAnnouncementForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_ANNOUNCEMENT;
/** @copydoc FormComponent::$method */
public $method = 'POST';
public ?Context $context;
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
*/
public function __construct($action, $locales, string $baseUrl, string $temporaryFileApiUrl, ?Context $context = null)
{
$this->action = $action;
$this->locales = $locales;
$this->context = $context;
$announcementTypeOptions = $this->getAnnouncementTypeOptions();
$this->addField(new FieldText('title', [
'label' => __('common.title'),
'size' => 'large',
'isMultilingual' => true,
]))
->addField(new FieldRichTextarea('descriptionShort', [
'label' => __('manager.announcements.form.descriptionShort'),
'description' => __('manager.announcements.form.descriptionShortInstructions'),
'isMultilingual' => true,
]))
->addField(new FieldRichTextarea('description', [
'label' => __('manager.announcements.form.description'),
'description' => __('manager.announcements.form.descriptionInstructions'),
'isMultilingual' => true,
'size' => 'large',
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]));
if (Config::getVar('features', 'announcement_images')) {
$this->addField(new FieldUploadImage('image', [
'label' => __('manager.image'),
'baseUrl' => $baseUrl,
'options' => [
'url' => $temporaryFileApiUrl,
],
]));
}
$this->addField(new FieldText('dateExpire', [
'label' => __('manager.announcements.form.dateExpire'),
'description' => __('manager.announcements.form.dateExpireInstructions'),
'size' => 'small',
]));
if (!empty($announcementTypeOptions)) {
$this->addField(new FieldOptions('typeId', [
'label' => __('manager.announcementTypes.typeName'),
'type' => 'radio',
'options' => $announcementTypeOptions,
]));
}
$this->addField(new FieldOptions('sendEmail', [
'label' => __('common.sendEmail'),
'options' => [
[
'value' => true,
'label' => __('notification.sendNotificationConfirmation')
]
]
]));
}
protected function getAnnouncementTypeOptions(): array
{
/** @var AnnouncementTypeDAO */
$announcementTypeDao = DAORegistry::getDAO('AnnouncementTypeDAO');
$announcementTypes = $announcementTypeDao->getByContextId($this->context?->getId());
$announcementTypeOptions = [];
foreach ($announcementTypes as $announcementType) {
$announcementTypeOptions[] = [
'value' => (int) $announcementType->getId(),
'label' => $announcementType->getLocalizedTypeName(),
];
}
return $announcementTypeOptions;
}
}
@@ -0,0 +1,69 @@
<?php
/**
* @file classes/components/form/context/PKPAnnouncementSettingsForm.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 PKPAnnouncementSettingsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for enabling and configuring announcements.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
use PKP\site\Site;
define('FORM_ANNOUNCEMENT_SETTINGS', 'announcementSettings');
class PKPAnnouncementSettingsForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_ANNOUNCEMENT_SETTINGS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
*/
public function __construct($action, $locales, Context|Site $context)
{
$this->action = $action;
$this->locales = $locales;
$this->addField(new FieldOptions('enableAnnouncements', [
'label' => __('manager.setup.announcements'),
'description' => __('manager.setup.enableAnnouncements.description'),
'options' => [
['value' => true, 'label' => __('manager.setup.enableAnnouncements.enable')]
],
'value' => (bool) $context->getData('enableAnnouncements'),
]))
->addField(new FieldRichTextarea('announcementsIntroduction', [
'label' => __('manager.setup.announcementsIntroduction'),
'tooltip' => __('manager.setup.announcementsIntroduction.description'),
'isMultilingual' => true,
'value' => $context->getData('announcementsIntroduction'),
'showWhen' => 'enableAnnouncements',
]))
->addField(new FieldText('numAnnouncementsHomepage', [
'label' => __('manager.setup.numAnnouncementsHomepage'),
'description' => __('manager.setup.numAnnouncementsHomepage.description'),
'size' => 'small',
'value' => $context->getData('numAnnouncementsHomepage'),
'showWhen' => 'enableAnnouncements',
]));
}
}
@@ -0,0 +1,76 @@
<?php
/**
* @file classes/components/form/context/PKPAppearanceAdvancedForm.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 PKPAppearanceAdvancedForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for advanced settings under the website appearance tab.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldUpload;
use PKP\components\forms\FieldUploadImage;
use PKP\components\forms\FormComponent;
define('FORM_APPEARANCE_ADVANCED', 'appearanceAdvanced');
class PKPAppearanceAdvancedForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_APPEARANCE_ADVANCED;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
* @param string $baseUrl Site's base URL. Used for image previews.
* @param string $temporaryFileApiUrl URL to upload files to
* @param string $imageUploadUrl The API endpoint for images uploaded through the rich text field
*/
public function __construct($action, $locales, $context, $baseUrl, $temporaryFileApiUrl, $imageUploadUrl)
{
$this->action = $action;
$this->locales = $locales;
$this->addField(new FieldUpload('styleSheet', [
'label' => __('manager.setup.useStyleSheet'),
'value' => $context->getData('styleSheet'),
'options' => [
'url' => $temporaryFileApiUrl,
'acceptedFiles' => '.css',
],
]))
->addField(new FieldUploadImage('favicon', [
'label' => __('manager.setup.favicon'),
'value' => $context->getData('favicon'),
'isMultilingual' => true,
'baseUrl' => $baseUrl,
'options' => [
'url' => $temporaryFileApiUrl,
'acceptedFiles' => 'image/x-icon,image/png,image/gif',
],
]))
->addField(new FieldRichTextarea('additionalHomeContent', [
'label' => __('manager.setup.additionalContent'),
'description' => __('manager.setup.additionalContent.description'),
'isMultilingual' => true,
'value' => $context->getData('additionalHomeContent'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist | image | code',
'plugins' => 'paste,link,lists,image,code',
'uploadUrl' => $imageUploadUrl,
]));
}
}
@@ -0,0 +1,112 @@
<?php
/**
* @file classes/components/form/context/PKPAppearanceSetupForm.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 PKPAppearanceSetupForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for general website appearance setup, such as uploading
* a logo.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldUploadImage;
use PKP\components\forms\FormComponent;
use PKP\plugins\PluginRegistry;
define('FORM_APPEARANCE_SETUP', 'appearanceSetup');
class PKPAppearanceSetupForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_APPEARANCE_SETUP;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
* @param string $baseUrl Site's base URL. Used for image previews.
* @param string $temporaryFileApiUrl URL to upload files to
* @param string $imageUploadUrl The API endpoint for images uploaded through the rich text field
*/
public function __construct($action, $locales, $context, $baseUrl, $temporaryFileApiUrl, $imageUploadUrl)
{
$this->action = $action;
$this->locales = $locales;
$sidebarOptions = [];
$enabledOptions = [];
$disabledOptions = [];
$currentBlocks = (array) $context->getData('sidebar');
$plugins = PluginRegistry::loadCategory('blocks', true);
foreach ($currentBlocks as $plugin) {
if (isset($plugins[$plugin])) {
$enabledOptions[] = [
'value' => $plugin,
'label' => htmlspecialchars($plugins[$plugin]->getDisplayName()),
];
}
}
foreach ($plugins as $pluginName => $plugin) {
if (!in_array($pluginName, $currentBlocks)) {
$disabledOptions[] = [
'value' => $pluginName,
'label' => htmlspecialchars($plugin->getDisplayName()),
];
}
}
$sidebarOptions = array_merge($enabledOptions, $disabledOptions);
$this->addField(new FieldUploadImage('pageHeaderLogoImage', [
'label' => __('manager.setup.logo'),
'value' => $context->getData('pageHeaderLogoImage'),
'isMultilingual' => true,
'baseUrl' => $baseUrl,
'options' => [
'url' => $temporaryFileApiUrl,
],
]))
->addField(new FieldUploadImage('homepageImage', [
'label' => __('manager.setup.homepageImage'),
'tooltip' => __('manager.setup.homepageImage.description'),
'value' => $context->getData('homepageImage'),
'isMultilingual' => true,
'baseUrl' => $baseUrl,
'options' => [
'url' => $temporaryFileApiUrl,
],
]))
->addField(new FieldRichTextarea('pageFooter', [
'label' => __('manager.setup.pageFooter'),
'tooltip' => __('manager.setup.pageFooter.description'),
'isMultilingual' => true,
'value' => $context->getData('pageFooter'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist | image | code',
'plugins' => 'paste,link,lists,image,code',
'uploadUrl' => $imageUploadUrl,
]))
->addField(new FieldOptions('sidebar', [
'label' => __('manager.setup.layout.sidebar'),
'isOrderable' => true,
'value' => $currentBlocks,
'options' => $sidebarOptions,
]));
}
}
@@ -0,0 +1,102 @@
<?php
/**
* @file classes/components/form/context/PKPContactForm.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 PKPContactForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring a context's contact details.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldText;
use PKP\components\forms\FieldTextarea;
use PKP\components\forms\FormComponent;
define('FORM_CONTACT', 'contact');
class PKPContactForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_CONTACT;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $context)
{
$this->action = $action;
$this->locales = $locales;
$this->addGroup([
'id' => 'principal',
'label' => __('manager.setup.principalContact'),
'description' => __('manager.setup.principalContactDescription'),
])
->addField(new FieldText('contactName', [
'label' => __('common.name'),
'isRequired' => true,
'groupId' => 'principal',
'value' => $context->getData('contactName'),
]))
->addField(new FieldText('contactEmail', [
'label' => __('user.email'),
'isRequired' => true,
'groupId' => 'principal',
'value' => $context->getData('contactEmail'),
]))
->addField(new FieldText('contactPhone', [
'label' => __('user.phone'),
'groupId' => 'principal',
'value' => $context->getData('contactPhone'),
]))
->addField(new FieldText('contactAffiliation', [
'label' => __('user.affiliation'),
'isMultilingual' => true,
'groupId' => 'principal',
'value' => $context->getData('contactAffiliation'),
]))
->addField(new FieldTextarea('mailingAddress', [
'label' => __('common.mailingAddress'),
'isRequired' => false,
'size' => 'small',
'groupId' => 'principal',
'value' => $context->getData('mailingAddress'),
]))
->addGroup([
'id' => 'technical',
'label' => __('manager.setup.technicalSupportContact'),
'description' => __('manager.setup.technicalSupportContactDescription'),
])
->addField(new FieldText('supportName', [
'label' => __('common.name'),
'isRequired' => true,
'groupId' => 'technical',
'value' => $context->getData('supportName'),
]))
->addField(new FieldText('supportEmail', [
'label' => __('user.email'),
'isRequired' => true,
'groupId' => 'technical',
'value' => $context->getData('supportEmail'),
]))
->addField(new FieldText('supportPhone', [
'label' => __('user.phone'),
'groupId' => 'technical',
'value' => $context->getData('supportPhone'),
]));
}
}
@@ -0,0 +1,128 @@
<?php
/**
* @file classes/components/form/context/PKPContextForm.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 PKPContextForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for adding and editing a context from the admin area.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldSelect;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\facades\Locale;
define('FORM_CONTEXT', 'context');
class PKPContextForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_CONTEXT;
/** @copydoc FormComponent::$method */
public $method = 'POST';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param string $baseUrl Base URL for the site
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $baseUrl, $context)
{
$this->action = $action;
$this->locales = $locales;
$this->method = $context ? 'PUT' : 'POST';
$countries = [];
foreach (Locale::getCountries() as $country) {
$countries[] = [
'value' => $country->getAlpha2(),
'label' => $country->getLocalName()
];
}
usort($countries, function ($a, $b) {
return strcmp($a['label'], $b['label']);
});
$this
->addField(new FieldText('name', [
'label' => __('manager.setup.contextTitle'),
'isRequired' => true,
'isMultilingual' => true,
'value' => $context ? $context->getData('name') : null,
]))
->addField(new FieldText('acronym', [
'label' => __('manager.setup.contextInitials'),
'size' => 'small',
'isRequired' => true,
'isMultilingual' => true,
'groupId' => 'identity',
'value' => $context ? $context->getData('acronym') : null,
]))
->addField(new FieldText('contactName', [
'label' => __('manager.setup.principalContact') . ' ' . __('common.name'),
'isRequired' => true,
'value' => $context ? $context->getData('contactName') : null,
]))
->addField(new FieldText('contactEmail', [
'label' => __('manager.setup.principalContact') . ' ' . __('user.email'),
'isRequired' => true,
'value' => $context ? $context->getData('contactEmail') : null,
]))
->addField(new FieldSelect('country', [
'label' => __('common.country'),
'description' => __('manager.setup.selectCountry'),
'options' => $countries,
'value' => $context ? $context->getData('country') : null,
]))
->addField(new FieldRichTextarea('description', [
'label' => __('admin.contexts.contextDescription'),
'isMultilingual' => true,
'value' => $context ? $context->getData('description') : null,
]))
->addField(new FieldText('urlPath', [
'label' => __('context.path'),
'isRequired' => true,
'value' => $context ? $context->getData('urlPath') : null,
'prefix' => $baseUrl . '/',
'size' => 'large',
]));
if (!$context && count($locales) > 1) {
$localeOptions = [];
foreach ($locales as $locale) {
$localeOptions[] = [
'value' => $locale['key'],
'label' => $locale['label'],
];
}
$this->addField(new FieldOptions('supportedLocales', [
'label' => __('common.languages'),
'isRequired' => true,
'value' => [],
'options' => $localeOptions,
]))
->addField(new FieldOptions('primaryLocale', [
'label' => __('locale.primary'),
'type' => 'radio',
'isRequired' => true,
'value' => null,
'options' => $localeOptions,
]));
}
}
}
@@ -0,0 +1,103 @@
<?php
/**
* @file classes/components/forms/context/PKPContextStatisticsForm.php
*
* Copyright (c) 2022 Simon Fraser University
* Copyright (c) 2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPContextStatisticsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for the context specific statistics settings.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
use PKP\site\Site;
use PKP\statistics\PKPStatisticsHelper;
define('FORM_CONTEXT_STATISTICS', 'contextStatistics');
class PKPContextStatisticsForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_CONTEXT_STATISTICS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
*/
public function __construct(string $action, array $locales, Site $site, Context $context)
{
$this->action = $action;
$this->locales = $locales;
$possibleGeoOptions = [
'disabled' => __('manager.settings.statistics.geoUsageStats.disabled'),
PKPStatisticsHelper::STATISTICS_SETTING_COUNTRY => __('manager.settings.statistics.geoUsageStats.countryLevel'),
PKPStatisticsHelper::STATISTICS_SETTING_REGION => __('manager.settings.statistics.geoUsageStats.regionLevel'),
PKPStatisticsHelper::STATISTICS_SETTING_CITY => __('manager.settings.statistics.geoUsageStats.cityLevel'),
];
$geoOptions = [];
foreach ($possibleGeoOptions as $value => $label) {
$geoOptions[] = [
'value' => $value,
'label' => $label,
];
if ($site->getData('enableGeoUsageStats') === $value) {
break;
}
}
$selectedGeoOption = $site->getData('enableGeoUsageStats');
if ($context->getData('enableGeoUsageStats') != null &&
str_starts_with($selectedGeoOption, $context->getData('enableGeoUsageStats'))) {
$selectedGeoOption = $context->getData('enableGeoUsageStats');
}
if ($site->getData('enableGeoUsageStats') && $site->getData('enableGeoUsageStats') !== 'disabled') {
$this->addField(new FieldOptions('enableGeoUsageStats', [
'label' => __('manager.settings.statistics.geoUsageStats'),
'description' => __('manager.settings.statistics.geoUsageStats.description'),
'type' => 'radio',
'options' => $geoOptions,
'value' => $selectedGeoOption,
]));
}
if ($site->getData('enableInstitutionUsageStats')) {
$this->addField(new FieldOptions('enableInstitutionUsageStats', [
'label' => __('manager.settings.statistics.institutionUsageStats'),
'description' => __('manager.settings.statistics.institutionUsageStats.description'),
'options' => [
[
'value' => true,
'label' => __('manager.settings.statistics.institutionUsageStats.enable'),
],
],
'value' => $context->getData('enableInstitutionUsageStats') !== null ? $context->getData('enableInstitutionUsageStats') : $site->getData('enableInstitutionUsageStats'),
]));
}
if ($site->getData('isSushiApiPublic') !== null && $site->getData('isSushiApiPublic')) {
$this->addField(new FieldOptions('isSushiApiPublic', [
'label' => __('manager.settings.statistics.publicSushiApi'),
'description' => __('manager.settings.statistics.publicSushiApi.description'),
'options' => [
[
'value' => true,
'label' => __('manager.settings.statistics.publicSushiApi.public'),
],
],
'value' => $context->getData('isSushiApiPublic') !== null ? $context->getData('isSushiApiPublic') : $site->getData('isSushiApiPublic'),
]));
}
}
}
@@ -0,0 +1,159 @@
<?php
/**
* @file classes/components/form/context/PKPDateTimeForm.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 PKPDateTimeForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for presenting date and time on the frontend
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldRadioInput;
use PKP\components\forms\FormComponent;
define('FORM_DATE_TIME', 'dateTime');
class PKPDateTimeForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_DATE_TIME;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $context)
{
$this->action = $action;
$this->locales = $locales;
$localizedOptions = []; // template for localized options to be used for date and time format
foreach ($this->locales as $key => $localeValue) {
$localizedOptions[$localeValue['key']] = $key;
}
$this->addGroup([
'id' => 'descriptions',
'label' => __('manager.setup.dateTime.descriptionTitle'),
'description' => __('manager.setup.dateTime.description'),
])
//The default date format to use in the editorial and reader interfaces.
->addField(new FieldRadioInput('dateFormatLong', [
'label' => __('manager.setup.dateTime.longDate'),
'isMultilingual' => true,
'options' => $this->_setDateOptions([
'%B %e, %Y',
'%B %e %Y',
'%e %B %Y',
'%Y %B %e',
]),
'value' => $context->getDateTimeFormats('dateFormatLong'),
'groupId' => 'descriptions',
]))
// A brief date format that is used when there is less space for the full date.
->addField(new FieldRadioInput('dateFormatShort', [
'label' => __('manager.setup.dateTime.shortDate'),
'isMultilingual' => true,
'options' => $this->_setDateOptions([
'%Y-%m-%d',
'%d-%m-%Y',
'%m/%d/%Y',
'%d.%m.%Y',
]),
'value' => $context->getDateTimeFormats('dateFormatShort'),
'groupId' => 'descriptions',
]))
->addField(new FieldRadioInput('timeFormat', [
'label' => __('manager.setup.dateTime.time'),
'isMultilingual' => true,
'options' => $this->_setDateOptions([
'%H:%M',
'%I:%M %p',
'%l:%M%P',
]),
'value' => $context->getDateTimeFormats('timeFormat'),
'groupId' => 'descriptions',
]))
->addField(new FieldRadioInput('datetimeFormatLong', [
'label' => __('manager.setup.dateTime.longDateTime'),
'isMultilingual' => true,
'options' => array_map(function ($value) use ($context, $localizedOptions) {
$locale = array_search($value, $localizedOptions);
$optionValue = $context->getLocalizedDateFormatLong($locale) . ' - ' . $context->getLocalizedTimeFormat($locale);
return [
[
'value' => $optionValue,
'label' => $optionValue,
],
[
'isInput' => true,
'label' => __('manager.setup.dateTime.custom'),
]
];
}, $localizedOptions),
'value' => $context->getDateTimeFormats('datetimeFormatLong'),
'groupId' => 'descriptions',
]))
->addField(new FieldRadioInput('datetimeFormatShort', [
'label' => __('manager.setup.dateTime.shortDateTime'),
'isMultilingual' => true,
'options' => array_map(function ($value) use ($context, $localizedOptions) {
$locale = array_search($value, $localizedOptions);
$optionValue = $context->getLocalizedDateFormatShort($locale) . ' ' . $context->getLocalizedTimeFormat($locale);
return [
[
'value' => $optionValue,
'label' => $optionValue,
],
[
'isInput' => true,
'label' => __('manager.setup.dateTime.custom'),
]
];
}, $localizedOptions),
'value' => $context->getDateTimeFormats('datetimeFormatShort'),
'groupId' => 'descriptions',
]));
}
/**
* Set localized options for date/time fields
*
* @param array $optionValues options to pass to the field
*
* @return array
*/
private function _setDateOptions($optionValues)
{
$options = [];
foreach ($this->locales as $localeValue) {
$locale = $localeValue['key'];
foreach ($optionValues as $optionValue) {
$options[$locale][] = [
'value' => $optionValue,
'label' => $optionValue
];
}
$options[$locale][] = [
'isInput' => true,
'label' => __('manager.setup.dateTime.custom'),
];
}
return $options;
}
}
@@ -0,0 +1,69 @@
<?php
/**
* @file classes/components/form/context/PKPDisableSubmissionsForm.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 PKPDisableSubmissionsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for disabling new submissions.
*/
namespace PKP\components\forms\context;
use APP\core\Application;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
define('FORM_DISABLE_SUBMISSIONS', 'disableSubmissions');
class PKPDisableSubmissionsForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_DISABLE_SUBMISSIONS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $context)
{
$this->action = $action;
$this->locales = $locales;
$url = Application::get()->getRequest()->getDispatcher()->url(
Application::get()->getRequest(),
Application::ROUTE_PAGE,
null,
'management',
'settings',
'context',
null,
'sections'
);
$description = __('manager.setup.disableSubmissions.description', ['url' => $url]);
$this->addField(new FieldOptions('disableSubmissions', [
'label' => __('manager.setup.disableSubmissions'),
'description' => $description,
'options' => [
[
'value' => true,
'label' => __('manager.setup.disableSubmissions'),
],
],
'value' => (bool) $context->getData('disableSubmissions'),
]));
}
}
@@ -0,0 +1,140 @@
<?php
/**
* @file classes/components/form/context/PKPDoiRegistrationSettingsForm.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 PKPDoiRegistrationSettingsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for enabling and configuring DOI settings for a given context
*/
namespace PKP\components\forms\context;
use APP\plugins\IDoiRegistrationAgency;
use PKP\components\forms\Field;
use PKP\components\forms\FieldHTML;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldSelect;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
use PKP\plugins\Hook;
use PKP\plugins\Plugin;
class PKPDoiRegistrationSettingsForm extends FormComponent
{
public const FORM_DOI_REGISTRATION_SETTINGS = 'doiRegistrationSettings';
/** @copydoc FormComponent::$id */
public $id = self::FORM_DOI_REGISTRATION_SETTINGS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
protected const GENERAL_SETTINGS = 'generalSettings';
protected const AGENCY_SPECIFIC_SETTINGS = 'agencySpecificSettings';
/** @var Field[] Registration agency plugin-specific settings, grouped by plugin */
protected array $agencyFields;
/**
* Constructor
*
*/
public function __construct(string $action, array $locales, Context $context)
{
$this->action = $action;
$this->locales = $locales;
$registrationAgencies = collect();
Hook::call('DoiSettingsForm::setEnabledRegistrationAgencies', [&$registrationAgencies]);
// Add registration agency options for each registration agency plugin
$options = [
[
'value' => Context::SETTING_NO_REGISTRATION_AGENCY,
'label' => __('doi.manager.settings.registrationAgency.none'),
],
];
$this->agencyFields = [];
$registrationAgencies->each(function (IDoiRegistrationAgency|Plugin $agency) use (&$options, $context) {
$options[] = [
'value' => $agency->getName(),
'label' => $agency->getRegistrationAgencyName(),
];
$this->agencyFields[$agency->getName()] = array_map(function ($field) {
$field->groupId = self::AGENCY_SPECIFIC_SETTINGS;
return $field;
}, $agency->getSettingsObject()->getFields($context));
});
$this->addGroup([
'id' => self::GENERAL_SETTINGS,
]);
$this->addGroup([
'id' => self::AGENCY_SPECIFIC_SETTINGS,
'showWhen' => Context::SETTING_CONFIGURED_REGISTRATION_AGENCY,
]);
if (count($options) > 1) {
$this->addField(new FieldSelect(Context::SETTING_CONFIGURED_REGISTRATION_AGENCY, [
'label' => __('doi.manager.settings.registrationAgency'),
'description' => __('doi.manager.settings.registrationAgency.description'),
'options' => $options,
'value' => $context->getData(Context::SETTING_CONFIGURED_REGISTRATION_AGENCY) === '' ?
null :
$context->getData(Context::SETTING_CONFIGURED_REGISTRATION_AGENCY),
'groupId' => self::GENERAL_SETTINGS,
]))
->addField(new FieldOptions(Context::SETTING_DOI_AUTOMATIC_DEPOSIT, [
'label' => __('doi.manager.setup.automaticDeposit'),
'description' => __('doi.manager.setup.automaticDeposit.description'),
'options' => [
['value' => true, 'label' => __('doi.manager.setup.automaticDeposit.enable')]
],
'value' => (bool) $context->getData(Context::SETTING_DOI_AUTOMATIC_DEPOSIT),
'groupId' => self::GENERAL_SETTINGS,
'showWhen' => Context::SETTING_CONFIGURED_REGISTRATION_AGENCY,
]));
} else {
$this->addField(new FieldHTML('noPluginsEnabled', [
'label' => __('doi.manager.settings.registrationAgency.noPluginsEnabled.label'),
'description' => __('doi.manager.settings.registrationAgency.noPluginsEnabled.description'),
'groupId' => self::GENERAL_SETTINGS,
]));
}
}
public function getConfig()
{
$activeAgencyField = array_filter($this->fields, function ($field) {
return $field->name === Context::SETTING_CONFIGURED_REGISTRATION_AGENCY;
});
$activeAgency = empty($activeAgencyField) ? '' : $activeAgencyField[0]->value;
if (!empty($this->agencyFields[$activeAgency])) {
$this->fields = array_merge($this->fields, $this->agencyFields[$activeAgency]);
}
$config = parent::getConfig();
// Set up field config for non-active fields
$config['agencyFields'] = array_map(function ($agencyFields) {
return array_map(function ($agencyField) {
$field = $this->getFieldConfig($agencyField);
$field['groupId'] = self::AGENCY_SPECIFIC_SETTINGS;
return $field;
}, $agencyFields);
}, $this->agencyFields);
return $config;
}
}
@@ -0,0 +1,160 @@
<?php
/**
* @file classes/components/form/context/PKPDoiSetupSettingsForm.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 PKPDoiSetupSettingsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for enabling and configuring DOI settings for a given context
*/
namespace PKP\components\forms\context;
use APP\core\Application;
use APP\facades\Repo;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldSelect;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
abstract class PKPDoiSetupSettingsForm extends FormComponent
{
public const FORM_DOI_SETUP_SETTINGS = 'doiSetupSettings';
/** @copydoc FormComponent::$id */
public $id = self::FORM_DOI_SETUP_SETTINGS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/** @var ?string Name of registration agency for checking allowed pub object types for DOI registration */
public ?string $enabledRegistrationAgency = null;
/** @var array Default list of all possible pubObject types for DOI registration */
public array $objectTypeOptions = [];
protected const DOI_SETTINGS_GROUP = 'doiSettingsGroup';
protected const DOI_DEFAULT_GROUP = 'doiDefaultGroup';
protected const DOI_CUSTOM_SUFFIX_GROUP = 'doiCustomSuffixGroup';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param Context $context Journal or Press to change settings for
*/
public function __construct(string $action, array $locales, Context $context)
{
$this->action = $action;
$this->locales = $locales;
$this->enabledRegistrationAgency = $context->getConfiguredDoiAgency()?->getName();
$doiManagementUrl = Application::get()->getDispatcher()->url(
Application::get()->getRequest(),
Application::ROUTE_PAGE,
$context->getPath(),
'dois'
);
$this->addGroup(
[
'id' => self::DOI_DEFAULT_GROUP,
]
)
->addGroup(
[
'id' => self::DOI_SETTINGS_GROUP,
'showWhen' => Context::SETTING_ENABLE_DOIS,
]
)
->addGroup(
[
'id' => self::DOI_CUSTOM_SUFFIX_GROUP,
'label' => __('doi.manager.settings.doiSuffix.custom'),
'description' => __('doi.manager.settings.doiSuffixPattern'),
'showWhen' => [Context::SETTING_DOI_SUFFIX_TYPE, Repo::doi()::SUFFIX_CUSTOM_PATTERN],
]
)
->addField(new FieldOptions(Context::SETTING_ENABLE_DOIS, [
'label' => __('manager.setup.dois'),
'groupId' => self::DOI_DEFAULT_GROUP,
'options' => [
['value' => true, 'label' => __('manager.setup.enableDois.description')]
],
'value' => (bool) $context->getData(Context::SETTING_ENABLE_DOIS),
]))
->addField(new FieldText(Context::SETTING_DOI_PREFIX, [
'label' => __('doi.manager.settings.doiPrefix'),
'description' => __('doi.manager.settings.doiPrefix.description'),
'groupId' => self::DOI_SETTINGS_GROUP,
'value' => $context->getData(Context::SETTING_DOI_PREFIX),
'size' => 'small',
]))
->addField(new FieldSelect(Context::SETTING_DOI_CREATION_TIME, [
'label' => __('doi.manager.settings.doiCreationTime.label'),
'description' => __('doi.manager.settings.doiCreationTime.description'),
'groupId' => self::DOI_SETTINGS_GROUP,
'options' => [
[
'value' => Repo::doi()::CREATION_TIME_COPYEDIT,
'label' => __('doi.manager.settings.doiCreationTime.copyedit')
],
[
'value' => Repo::doi()::CREATION_TIME_PUBLICATION,
'label' => __('doi.manager.settings.doiCreationTime.publication')
],
[
'value' => Repo::doi()::CREATION_TIME_NEVER,
'label' => __('doi.manager.settings.doiCreationTime.never')
]
],
'value' => $context->getData(Context::SETTING_DOI_CREATION_TIME) ? $context->getData(Context::SETTING_DOI_CREATION_TIME) : Repo::doi()::CREATION_TIME_COPYEDIT,
]))
->addField(new FieldOptions(Context::SETTING_DOI_SUFFIX_TYPE, [
'label' => __('doi.manager.settings.doiSuffix'),
'description' => __('doi.manager.settings.doiSuffix.description'),
'groupId' => self::DOI_SETTINGS_GROUP,
'options' => [
[
'value' => Repo::doi()::SUFFIX_DEFAULT,
'label' => __('doi.manager.settings.doiSuffixDefault')
],
[
'value' => Repo::doi()::SUFFIX_MANUAL,
'label' => __('doi.manager.settings.doiSuffixManual', ['doiManagementUrl' => $doiManagementUrl])
],
[
'value' => Repo::doi()::SUFFIX_CUSTOM_PATTERN,
'label' => __('doi.manager.settings.doiSuffixUserDefined')
],
],
'value' => $context->getData(Context::SETTING_DOI_SUFFIX_TYPE) ? $context->getData(Context::SETTING_DOI_SUFFIX_TYPE) : Repo::doi()::SUFFIX_DEFAULT,
'type' => 'radio',
]))
->addField(new FieldText(Repo::doi()::CUSTOM_PUBLICATION_PATTERN, [
'label' => __('manager.language.submissions'),
'groupId' => self::DOI_CUSTOM_SUFFIX_GROUP,
'value' => $context->getData(Repo::doi()::CUSTOM_PUBLICATION_PATTERN),
]))
->addField(new FieldText(Repo::doi()::CUSTOM_REPRESENTATION_PATTERN, [
'label' => __('doi.manager.settings.enableRepresentationDoi'),
'groupId' => self::DOI_CUSTOM_SUFFIX_GROUP,
'value' => $context->getData(Repo::doi()::CUSTOM_REPRESENTATION_PATTERN),
]));
}
public function getConfig()
{
$config = parent::getConfig();
$config['enabledRegistrationAgency'] = $this->enabledRegistrationAgency;
$config['objectTypeOptions'] = $this->objectTypeOptions;
return $config;
}
}
@@ -0,0 +1,248 @@
<?php
/**
* @file classes/components/form/context/PKPEmailSetupForm.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 PKPEmailSetupForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring a context's email settings.
*/
namespace PKP\components\forms\context;
use APP\core\Application;
use APP\mail\variables\ContextEmailVariable;
use Illuminate\Support\Arr;
use PKP\components\forms\FieldHTML;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldPreparedContent;
use PKP\components\forms\FieldRadioInput;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\config\Config;
use PKP\context\Context;
class PKPEmailSetupForm extends FormComponent
{
public const GROUP_EMAIL_TEMPLATES = 'emailTemplates';
public const GROUP_NEW_SUBMISSION = 'newSubmission';
public const GROUP_EDITORIAL_DECISIONS = 'decisions';
public const GROUP_EDITORS = 'editors';
public const GROUP_ADVANCED = 'advanced';
public const FIELD_SUBMISSION_ACK = 'submissionAcknowledgement';
public $id = 'emailSetup';
public $method = 'PUT';
public Context $context;
public function __construct(string $action, array $locales, Context $context)
{
$this->action = $action;
$this->locales = $locales;
$this->context = $context;
$this->addGroup([
'id' => self::GROUP_EMAIL_TEMPLATES,
'label' => __('manager.manageEmails'),
'description' => __('manager.manageEmails.description'),
])
->addEmailTemplatesField()
->addSignatureField()
->addGroup([
'id' => self::GROUP_NEW_SUBMISSION,
'label' => __('manager.newSubmission'),
'description' => __('manager.newSubmission.description'),
])
->addSubmissionAcknowledgementField()
->addCopySubmissionAckPrimaryContactField()
->addCopySubmissionAckAddress()
->addGroup([
'id' => self::GROUP_EDITORIAL_DECISIONS,
'label' => __('manager.editorialDecisions'),
'description' => __('manager.editorialDecisions.description'),
])
->addNotifyAllAuthorsField()
->addGroup([
'id' => self::GROUP_EDITORS,
'label' => __('manager.forEditors'),
'description' => __('manager.forEditors.description')
])
->addStatisticsReportField()
->addGroup([
'id' => self::GROUP_ADVANCED,
'label' => __('manager.setup.advanced'),
])
->addEnveloperSenderField();
}
protected function addEmailTemplatesField(): self
{
$manageEmailsUrl = Application::get()->getRequest()->getDispatcher()->url(
Application::get()->getRequest(),
Application::ROUTE_PAGE,
$this->context->getPath(),
'management',
'settings',
'manageEmails'
);
return $this->addField(new FieldHTML('emailTemplates', [
'label' => __('manager.emails.emailTemplates'),
'description' => __('manager.manageEmailTemplates.description', ['url' => $manageEmailsUrl]),
'groupId' => self::GROUP_EMAIL_TEMPLATES,
]));
}
protected function addSignatureField(): self
{
return $this->addField(new FieldPreparedContent('emailSignature', [
'label' => __('manager.setup.emailSignature'),
'description' => __('manager.setup.emailSignature.description'),
'value' => $this->context->getData('emailSignature'),
'preparedContent' => array_values(
Arr::sort(
Arr::map(
Arr::except(ContextEmailVariable::descriptions(), ContextEmailVariable::CONTEXT_SIGNATURE),
function ($description, $key) {
return [
'key' => $key,
'description' => $description,
'value' => '{$' . $key . '}'
];
}
)
)
),
'groupId' => self::GROUP_EMAIL_TEMPLATES,
]));
}
/**
* Add the submission ack field
*/
protected function addSubmissionAcknowledgementField(): self
{
return $this->addField(new FieldOptions(self::FIELD_SUBMISSION_ACK, [
'label' => __('mailable.submissionAck.name'),
'description' => __('manager.submissionAck.description'),
'type' => 'radio',
'options' => [
['value' => Context::SUBMISSION_ACKNOWLEDGEMENT_ALL_AUTHORS, 'label' => __('manager.submissionAck.allAuthors')],
['value' => Context::SUBMISSION_ACKNOWLEDGEMENT_SUBMITTING_AUTHOR, 'label' => __('manager.submissionAck.submittingAuthor')],
['value' => Context::SUBMISSION_ACKNOWLEDGEMENT_OFF, 'label' => __('manager.submissionAck.off')],
],
'value' => $this->context->getData(self::FIELD_SUBMISSION_ACK),
'groupId' => self::GROUP_NEW_SUBMISSION,
]));
}
/**
* Add the copy submission ack primary contact field
*/
protected function addCopySubmissionAckPrimaryContactField(): self
{
$contactEmail = $this->context->getData('contactEmail');
if (!empty($contactEmail)) {
return $this->addField(new FieldRadioInput('copySubmissionAckPrimaryContact', [
'label' => __('manager.setup.notifications.copySubmissionAckPrimaryContact'),
'description' => __('manager.setup.notifications.copySubmissionAckPrimaryContact.description'),
'options' => [
['value' => true, 'label' => __('manager.setup.notifications.copySubmissionAckPrimaryContact.enabled', ['email' => $contactEmail])],
['value' => false, 'label' => __('manager.setup.notifications.copySubmissionAckPrimaryContact.disabled')],
],
'value' => $this->context->getData('copySubmissionAckPrimaryContact'),
'groupId' => self::GROUP_NEW_SUBMISSION,
'showWhen' => self::FIELD_SUBMISSION_ACK,
]));
}
$request = Application::get()->getRequest();
$pageUrl = $request->getDispatcher()
->url($request, Application::ROUTE_PAGE, null, 'management', 'settings', 'context', null, 'contact');
return $this->addField(new FieldHTML('copySubmissionAckPrimaryContact', [
'label' => __('manager.setup.notifications.copySubmissionAckPrimaryContact'),
'description' => __('manager.setup.notifications.copySubmissionAckPrimaryContact.disabled.description', ['url' => $pageUrl]),
'groupId' => self::GROUP_NEW_SUBMISSION,
'showWhen' => self::FIELD_SUBMISSION_ACK,
]));
}
/**
* Add the field to copy any email address on the submission acknowledgement
*/
protected function addCopySubmissionAckAddress(): self
{
return $this->addField(new FieldText('copySubmissionAckAddress', [
'label' => __('manager.setup.notifications.copySubmissionAckAddress'),
'description' => __('manager.setup.notifications.copySubmissionAckAddress.description'),
'size' => 'large',
'value' => $this->context->getData('copySubmissionAckAddress'),
'groupId' => self::GROUP_NEW_SUBMISSION,
'showWhen' => self::FIELD_SUBMISSION_ACK,
]));
}
/**
* Add the field to notify all authors when an editorial decision is recorded
*/
protected function addNotifyAllAuthorsField(): self
{
return $this->addField(new FieldOptions('notifyAllAuthors', [
'label' => __('manager.setup.notifyAllAuthors'),
'description' => __('manager.setup.notifyAllAuthors.description'),
'type' => 'radio',
'options' => [
['value' => true, 'label' => __('manager.setup.notifyAllAuthors.allAuthors')],
['value' => false, 'label' => __('manager.setup.notifyAllAuthors.assignedAuthors')],
],
'value' => $this->context->getData('notifyAllAuthors'),
'groupId' => self::GROUP_EDITORIAL_DECISIONS,
]));
}
/**
* Add the field to enable/disable the editorial statistics report email
*/
protected function addStatisticsReportField(): self
{
return $this->addField(new FieldOptions('editorialStatsEmail', [
'label' => __('manager.editorialStatistics'),
'description' => __('manager.editorialStatistics.description'),
'type' => 'radio',
'options' => [
['value' => true, 'label' => __('manager.editorialStatistics.on')],
['value' => false, 'label' => __('manager.editorialStatistics.off')],
],
'value' => $this->context->getData('editorialStatsEmail'),
'groupId' => self::GROUP_EDITORS,
]));
}
protected function addEnveloperSenderField(): self
{
$canEnvelopeSender = Config::getVar('email', 'allow_envelope_sender');
if ($canEnvelopeSender) {
return $this->addField(new FieldText('envelopeSender', [
'label' => __('manager.setup.emailBounceAddress'),
'tooltip' => __('manager.setup.emailBounceAddress.description'),
'value' => $this->context->getData('envelopeSender'),
'groupId' => self::GROUP_ADVANCED,
]));
}
return $this->addField(new FieldHTML('envelopeSender', [
'label' => __('manager.setup.emailBounceAddress'),
'description' => __('manager.setup.emailBounceAddress.disabled'),
'groupId' => self::GROUP_ADVANCED,
]));
}
}
@@ -0,0 +1,78 @@
<?php
/**
* @file classes/components/form/context/PKPInformationForm.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 PKPInformationForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring the information fields for a
* context (eg - info for readers, authors and librarians).
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FormComponent;
define('FORM_INFORMATION', 'information');
class PKPInformationForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_INFORMATION;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
* @param string $imageUploadUrl The API endpoint for images uploaded through the rich text field
*/
public function __construct($action, $locales, $context, $imageUploadUrl)
{
$this->action = $action;
$this->locales = $locales;
$this->addGroup([
'id' => 'descriptions',
'label' => __('manager.setup.information.descriptionTitle'),
'description' => __('manager.setup.information.description'),
])
->addField(new FieldRichTextarea('readerInformation', [
'label' => __('manager.setup.information.forReaders'),
'isMultilingual' => true,
'groupId' => 'descriptions',
'value' => $context->getData('readerInformation'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist | image | code',
'plugins' => 'paste,link,lists,image,code',
'uploadUrl' => $imageUploadUrl,
]))
->addField(new FieldRichTextarea('authorInformation', [
'label' => __('manager.setup.information.forAuthors'),
'isMultilingual' => true,
'groupId' => 'descriptions',
'value' => $context->getData('authorInformation'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist | image | code',
'plugins' => 'paste,link,lists,image,code',
'uploadUrl' => $imageUploadUrl,
]))
->addField(new FieldRichTextarea('librarianInformation', [
'label' => __('manager.setup.information.forLibrarians'),
'isMultilingual' => true,
'groupId' => 'descriptions',
'value' => $context->getData('librarianInformation'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist | image | code',
'plugins' => 'paste,link,lists,image,code',
'uploadUrl' => $imageUploadUrl,
]));
}
}
@@ -0,0 +1,92 @@
<?php
/**
* @file classes/components/form/context/PKPLicenseForm.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 PKPLicenseForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring a context's default licensing details.
*/
namespace PKP\components\forms\context;
use APP\core\Application;
use PKP\components\forms\FieldRadioInput;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
define('FORM_LICENSE', 'license');
class PKPLicenseForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_LICENSE;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $context)
{
$this->action = $action;
$this->locales = $locales;
$licenseOptions = Application::getCCLicenseOptions();
$licenseUrlOptions = [];
foreach ($licenseOptions as $url => $label) {
$licenseUrlOptions[] = [
'value' => $url,
'label' => __($label),
];
}
$licenseUrlOptions[] = [
'value' => 'other',
'label' => __('manager.distribution.license.other'),
'isInput' => true,
];
$this->addField(new FieldRadioInput('copyrightHolderType', [
'label' => __('submission.copyrightHolder'),
'type' => 'radio',
'options' => [
['value' => 'author', 'label' => __('user.role.author')],
['value' => 'context', 'label' => __('context.context')],
['value' => 'other', 'label' => __('submission.copyrightHolder.other')],
],
'value' => $context->getData('copyrightHolderType'),
]))
->addField(new FieldText('copyrightHolderOther', [
'label' => __('submission.copyrightOther'),
'description' => __('submission.copyrightOther.description'),
'isMultilingual' => true,
'showWhen' => ['copyrightHolderType', 'other'],
'value' => $context->getData('copyrightHolderOther'),
]))
->addField(new FieldRadioInput('licenseUrl', [
'label' => __('manager.distribution.license'),
'type' => 'radio',
'options' => $licenseUrlOptions,
'value' => $context->getData('licenseUrl'),
]))
->addField(new FieldRichTextarea('licenseTerms', [
'label' => __('manager.distribution.licenseTerms'),
'tooltip' => __('manager.distribution.licenseTerms.description'),
'isMultilingual' => true,
'value' => $context->getData('licenseTerms'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]));
}
}
@@ -0,0 +1,59 @@
<?php
/**
* @file classes/components/form/context/PKPListsForm.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 PKPListsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring how a context handles lists of
* items in the UI.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
define('FORM_LISTS', 'lists');
class PKPListsForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_LISTS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $context)
{
$this->action = $action;
$this->locales = $locales;
$this->addField(new FieldText('itemsPerPage', [
'label' => __('common.itemsPerPage'),
'description' => __('manager.setup.itemsPerPage.description'),
'isRequired' => true,
'value' => $context->getData('itemsPerPage'),
'size' => 'small',
]))
->addField(new FieldText('numPageLinks', [
'label' => __('manager.setup.numPageLinks'),
'description' => __('manager.setup.numPageLinks.description'),
'isRequired' => true,
'value' => $context->getData('numPageLinks'),
'size' => 'small',
]));
}
}
@@ -0,0 +1,127 @@
<?php
/**
* @file classes/components/form/context/PKPMastheadForm.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 PKPMastheadForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring a context's masthead details.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldSelect;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\facades\Locale;
define('FORM_MASTHEAD', 'masthead');
class PKPMastheadForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_MASTHEAD;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
* @param string $imageUploadUrl The API endpoint for images uploaded through the rich text field
*/
public function __construct($action, $locales, $context, $imageUploadUrl)
{
$this->action = $action;
$this->locales = $locales;
$countries = [];
foreach (Locale::getCountries() as $country) {
$countries[] = [
'value' => $country->getAlpha2(),
'label' => $country->getLocalName()
];
}
usort($countries, function ($a, $b) {
return strcmp($a['label'], $b['label']);
});
$this->addGroup([
'id' => 'identity',
'label' => __('manager.setup.identity'),
])
->addField(new FieldText('name', [
'label' => __('manager.setup.contextTitle'),
'size' => 'large',
'isRequired' => true,
'isMultilingual' => true,
'groupId' => 'identity',
'value' => $context->getData('name'),
]))
->addField(new FieldText('acronym', [
'label' => __('manager.setup.contextInitials'),
'size' => 'small',
'isRequired' => true,
'isMultilingual' => true,
'groupId' => 'identity',
'value' => $context->getData('acronym'),
]))
->addGroup([
'id' => 'publishing',
'label' => __('manager.setup.publishing'),
'description' => __('manager.setup.publishingDescription'),
])
->addField(new FieldSelect('country', [
'groupId' => 'publishing',
'label' => __('common.country'),
'description' => __('manager.setup.selectCountry'),
'options' => $countries,
'isRequired' => true,
'value' => $context ? $context->getData('country') : null,
]))
->addGroup([
'id' => 'keyInfo',
'label' => __('manager.setup.keyInfo'),
'description' => __('manager.setup.keyInfo.description'),
])
->addField(new FieldRichTextarea('description', [
'label' => __('manager.setup.contextSummary'),
'isMultilingual' => true,
'groupId' => 'keyInfo',
'value' => $context->getData('description'),
]))
->addField(new FieldRichTextarea('editorialTeam', [
'label' => __('manager.setup.editorialTeam'),
'isMultilingual' => true,
'groupId' => 'keyInfo',
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist | image | code',
'plugins' => 'paste,link,lists,image,code',
'uploadUrl' => $imageUploadUrl,
'value' => $context->getData('editorialTeam'),
]))
->addGroup([
'id' => 'about',
'label' => __('common.description'),
'description' => __('manager.setup.contextAbout.description'),
])
->addField(new FieldRichTextarea('about', [
'label' => __('manager.setup.contextAbout'),
'isMultilingual' => true,
'size' => 'large',
'groupId' => 'about',
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist | image | code',
'plugins' => 'paste,link,lists,image,code',
'uploadUrl' => $imageUploadUrl,
'value' => $context->getData('about'),
]));
}
}
@@ -0,0 +1,210 @@
<?php
/**
* @file classes/components/form/context/PKPMetadataSettingsForm.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 PKPMetadataSettingsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for enabling and configuring types of metadata to
* attach to submissions.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldMetadataSetting;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
define('FORM_METADATA_SETTINGS', 'metadataSettings');
class PKPMetadataSettingsForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_METADATA_SETTINGS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param Context $context Journal or Press to change settings for
*/
public function __construct($action, $context)
{
$this->action = $action;
$this
->addField(new FieldMetadataSetting('keywords', [
'label' => __('common.keywords'),
'description' => __('manager.setup.metadata.keywords.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.keywords.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.keywords.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.keywords.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.keywords.require')],
],
'value' => $context->getData('keywords') ? $context->getData('keywords') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('subjects', [
'label' => __('common.subjects'),
'description' => __('manager.setup.metadata.subjects.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.subjects.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.subjects.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.subjects.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.subjects.require')],
],
'value' => $context->getData('subjects') ? $context->getData('subjects') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('disciplines', [
'label' => __('search.discipline'),
'description' => __('manager.setup.metadata.disciplines.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.disciplines.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.disciplines.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.disciplines.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.disciplines.require')],
],
'value' => $context->getData('disciplines') ? $context->getData('disciplines') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('languages', [
'label' => __('common.languages'),
'description' => __('manager.setup.metadata.languages.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.languages.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.languages.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.languages.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.languages.require')],
],
'value' => $context->getData('languages') ? $context->getData('languages') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('agencies', [
'label' => __('submission.supportingAgencies'),
'description' => __('manager.setup.metadata.agencies.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.agencies.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.agencies.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.agencies.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.agencies.require')],
],
'value' => $context->getData('agencies') ? $context->getData('agencies') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('coverage', [
'label' => __('manager.setup.metadata.coverage'),
'description' => __('manager.setup.metadata.coverage.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.coverage.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.coverage.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.coverage.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.coverage.require')],
],
'value' => $context->getData('coverage') ? $context->getData('coverage') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('rights', [
'label' => __('submission.rights'),
'description' => __('manager.setup.metadata.rights.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.rights.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.rights.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.rights.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.rights.require')],
],
'value' => $context->getData('rights') ? $context->getData('rights') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('source', [
'label' => __('submission.source'),
'description' => __('manager.setup.metadata.source.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.source.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.source.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.source.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.source.require')],
],
'value' => $context->getData('source') ? $context->getData('source') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('type', [
'label' => __('common.type'),
'description' => __('manager.setup.metadata.type.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.type.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.type.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.type.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.type.require')],
],
'value' => $context->getData('type') ? $context->getData('type') : Context::METADATA_DISABLE,
]))
->addField(new FieldOptions('requireAuthorCompetingInterests', [
'label' => __('manager.setup.competingInterests'),
'options' => [
[
'value' => 'true',
'label' => __('manager.setup.competingInterests.requireAuthors'),
],
],
'value' => (bool) $context->getData('requireAuthorCompetingInterests'),
]))
->addField(new FieldMetadataSetting('citations', [
'label' => __('submission.citations'),
'description' => __('manager.setup.metadata.citations.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.citations.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.citations.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.citations.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.citations.require')],
],
'value' => $context->getData('citations') ? $context->getData('citations') : Context::METADATA_DISABLE,
]))
->addField(new FieldMetadataSetting('dataAvailability', [
'label' => __('submission.dataAvailability'),
'description' => __('manager.setup.metadata.dataAvailability.description'),
'options' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.dataAvailability.enable')]
],
'submissionOptions' => [
['value' => Context::METADATA_ENABLE, 'label' => __('manager.setup.metadata.dataAvailability.noRequest')],
['value' => Context::METADATA_REQUEST, 'label' => __('manager.setup.metadata.dataAvailability.request')],
['value' => Context::METADATA_REQUIRE, 'label' => __('manager.setup.metadata.dataAvailability.require')],
],
'value' => $context->getData('dataAvailability') ? $context->getData('dataAvailability') : Context::METADATA_DISABLE,
]))
->addField(new FieldOptions('submitWithCategories', [
'label' => __('category.category'),
'description' => __('manager.submitWithCategories.description'),
'type' => 'radio',
'options' => [
['value' => true, 'label' => __('manager.submitWithCategories.yes')],
['value' => false, 'label' => __('manager.submitWithCategories.no')],
],
'value' => (bool) $context->getData('submitWithCategories')
]));
}
}
@@ -0,0 +1,112 @@
<?php
/**
* @file classes/components/form/context/PKPNotifyUsersForm.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 PKPNotifyUsersForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for sending an email notification to users.
*/
namespace PKP\components\forms\context;
use APP\core\Application;
use APP\facades\Repo;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
define('FORM_NOTIFY_USERS', 'notifyUsers');
class PKPNotifyUsersForm extends FormComponent
{
public const FORM_NOTIFY_USERS = 'notifyUsers';
/** @copydoc FormComponent::$id */
public $id = self::FORM_NOTIFY_USERS;
/** @copydoc FormComponent::$method */
public $method = 'POST';
/** @var array count of users in each group */
public $userGroupCounts = [];
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param \PKP\context\Context $context Journal, press or preprint server
*/
public function __construct($action, $context)
{
$this->action = $action;
$userGroups = Repo::userGroup()->getCollector()
->filterByContextIds([$context->getId()])
->getMany();
$userCountByGroupId = Repo::userGroup()->getUserCountByContextId($context->getId());
$userGroupOptions = [];
foreach ($userGroups as $userGroup) {
if (in_array($userGroup->getId(), (array) $context->getData('disableBulkEmailUserGroups'))) {
continue;
}
$userGroupOptions[] = [
'value' => $userGroup->getId(),
'label' => $userGroup->getLocalizedData('name'),
];
$this->userGroupCounts[$userGroup->getId()] = $userCountByGroupId->get($userGroup->getId(), 0);
}
$currentUser = Application::get()->getRequest()->getUser();
$this->addField(new FieldOptions('userGroupIds', [
'label' => __('user.roles'),
'description' => __('manager.setup.notifyUsers.description'),
'value' => [],
'options' => $userGroupOptions,
'required' => true,
]))
->addField(new FieldText('subject', [
'label' => __('email.subject'),
'value' => '',
'required' => true,
]))
->addField(new FieldRichTextarea('body', [
'label' => __('email.email'),
'size' => 'large',
'value' => '',
'required' => true,
]))
->addField(new FieldOptions('copy', [
'label' => __('common.copy'),
'value' => 0,
'options' => [
[
'value' => 1,
'label' => __('manager.setup.notifyUsers.copyDetails', ['email' => $currentUser->getEmail()]),
],
]
]));
}
/**
* @copydoc FormComponent::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['confirmLabel'] = __('manager.setup.notifyUsers.confirm');
$config['sendLabel'] = __('manager.setup.notifyUsers.send');
$config['userGroupCounts'] = $this->userGroupCounts;
return $config;
}
}
@@ -0,0 +1,91 @@
<?php
/**
* @file classes/components/form/context/PKPPaymentSettingsForm.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 PKPPaymentSettingsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring the general payment settings.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldSelect;
use PKP\components\forms\FormComponent;
use PKP\facades\Locale;
use PKP\plugins\PluginRegistry;
define('FORM_PAYMENT_SETTINGS', 'paymentSettings');
class PKPPaymentSettingsForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_PAYMENT_SETTINGS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $context)
{
$this->action = $action;
$this->locales = $locales;
$currencies = [];
foreach (Locale::getCurrencies() as $currency) {
$currencies[] = [
'value' => $currency->getLetterCode(),
'label' => htmlspecialchars($currency->getLocalName()),
];
}
// Ensure payment method plugins can hook in
$paymentPlugins = PluginRegistry::loadCategory('paymethod', true);
$pluginList = [];
foreach ($paymentPlugins as $plugin) {
$pluginList[] = [
'value' => $plugin->getName(),
'label' => htmlspecialchars($plugin->getDisplayName()),
];
}
$this->addGroup([
'id' => 'setup',
'label' => __('navigation.setup'),
])
->addField(new FieldOptions('paymentsEnabled', [
'label' => __('common.enable'),
'options' => [
['value' => true, 'label' => __('manager.payment.options.enablePayments')]
],
'value' => (bool) $context->getData('paymentsEnabled'),
'groupId' => 'setup',
]))
->addField(new FieldSelect('currency', [
'label' => __('manager.paymentMethod.currency'),
'options' => $currencies,
'showWhen' => 'paymentsEnabled',
'value' => $context->getData('currency'),
'groupId' => 'setup',
]))
->addField(new FieldSelect('paymentPluginName', [
'label' => __('plugins.categories.paymethod'),
'options' => $pluginList,
'showWhen' => 'paymentsEnabled',
'value' => $context->getData('paymentPluginName'),
'groupId' => 'setup',
]));
}
}
@@ -0,0 +1,54 @@
<?php
/**
* @file classes/components/form/context/PKPPrivacyForm.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 PKPPrivacyForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring a context's privacy statement.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FormComponent;
define('FORM_PRIVACY', 'privacy');
class PKPPrivacyForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_PRIVACY;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
* @param string $imageUploadUrl The API endpoint for images uploaded through the rich text field
*/
public function __construct($action, $locales, $context, $imageUploadUrl)
{
$this->action = $action;
$this->locales = $locales;
$this->addField(new FieldRichTextArea('privacyStatement', [
'label' => __('manager.setup.privacyStatement'),
'description' => __('manager.setup.privacyStatement.description'),
'isMultilingual' => true,
'value' => $context->getData('privacyStatement'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist | image | code',
'plugins' => 'paste,link,lists,image,code',
'uploadUrl' => $imageUploadUrl,
]));
}
}
@@ -0,0 +1,60 @@
<?php
/**
* @file classes/components/form/site/PKPRestrictBulkEmailsForm.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 PKPRestrictBulkEmailsForm
*
* @ingroup classes_controllers_form
*
* @brief A form for setting restrictions on the sending of bulk emails in a context.
*/
namespace PKP\components\forms\context;
use APP\core\Application;
use Illuminate\Support\LazyCollection;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
define('FORM_RESTRICT_BULK_EMAILS', 'restrictBulkEmails');
class PKPRestrictBulkEmailsForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_RESTRICT_BULK_EMAILS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
*/
public function __construct($action, $context, LazyCollection $userGroups)
{
$this->action = $action;
$userGroupOptions = [];
foreach ($userGroups as $userGroup) {
$userGroupOptions[] = [
'value' => $userGroup->getId(),
'label' => htmlspecialchars($userGroup->getLocalizedData('name')),
];
}
$request = Application::get()->getRequest();
$siteSettingsUrl = $request->getDispatcher()->url($request, Application::ROUTE_PAGE, null, 'admin', 'settings', null, null, 'setup/bulkEmails');
$this->addField(new FieldOptions('disableBulkEmailUserGroups', [
'label' => __('admin.settings.disableBulkEmailRoles.label'),
'description' => __('admin.settings.disableBulkEmailRoles.description', ['siteSettingsUrl' => $siteSettingsUrl]),
'value' => (array) $context->getData('disableBulkEmailUserGroups'),
'options' => $userGroupOptions,
]));
}
}
@@ -0,0 +1,65 @@
<?php
/**
* @file classes/components/form/context/PKPReviewGuidanceForm.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 PKPReviewGuidanceForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring the guidance a reviewer should receive.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldShowEnsuringLink;
use PKP\components\forms\FormComponent;
define('FORM_REVIEW_GUIDANCE', 'reviewerGuidance');
class PKPReviewGuidanceForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_REVIEW_GUIDANCE;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $context)
{
$this->action = $action;
$this->locales = $locales;
$this->addField(new FieldRichTextarea('reviewGuidelines', [
'label' => __('manager.setup.reviewGuidelines'),
'isMultilingual' => true,
'value' => $context->getData('reviewGuidelines'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('competingInterests', [
'label' => __('manager.setup.competingInterests'),
'isMultilingual' => true,
'value' => $context->getData('competingInterests'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldShowEnsuringLink('showEnsuringLink', [
'options' => [
['value' => true, 'label' => __('manager.setup.reviewOptions.showAnonymousReviewLink')],
],
'value' => $context->getData('showEnsuringLink'),
]));
}
}
@@ -0,0 +1,108 @@
<?php
/**
* @file classes/components/form/context/PKPReviewSetupForm.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 PKPReviewSetupForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring review options, such as the default
* review type and deadlines.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldHTML;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\config\Config;
use PKP\submission\reviewAssignment\ReviewAssignment;
define('FORM_REVIEW_SETUP', 'reviewSetup');
class PKPReviewSetupForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_REVIEW_SETUP;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $locales, $context)
{
$this->action = $action;
$this->locales = $locales;
$this->addField(new FieldOptions('defaultReviewMode', [
'label' => __('manager.setup.reviewOptions.reviewMode'),
'type' => 'radio',
'value' => $context->getData('defaultReviewMode'),
'options' => [
['value' => ReviewAssignment::SUBMISSION_REVIEW_METHOD_DOUBLEANONYMOUS, 'label' => __('editor.submissionReview.doubleAnonymous')],
['value' => ReviewAssignment::SUBMISSION_REVIEW_METHOD_ANONYMOUS, 'label' => __('editor.submissionReview.anonymous')],
['value' => ReviewAssignment::SUBMISSION_REVIEW_METHOD_OPEN, 'label' => __('editor.submissionReview.open')],
],
]))
->addField(new FieldOptions('restrictReviewerFileAccess', [
'label' => __('manager.setup.reviewOptions.restrictReviewerFileAccess'),
'type' => 'checkbox',
'value' => $context->getData('restrictReviewerFileAccess'),
'options' => [
['value' => true, 'label' => __('manager.setup.reviewOptions.restrictReviewerFileAccess.description')],
]
]))
->addField(new FieldOptions('reviewerAccessKeysEnabled', [
'label' => __('manager.setup.reviewOptions.reviewerAccessKeysEnabled'),
'description' => __('manager.setup.reviewOptions.reviewerAccessKeysEnabled.description'),
'type' => 'checkbox',
'value' => $context->getData('reviewerAccessKeysEnabled'),
'options' => [
['value' => true, 'label' => __('manager.setup.reviewOptions.reviewerAccessKeysEnabled.label')],
]
]))
->addField(new FieldText('numWeeksPerResponse', [
'label' => __('manager.setup.reviewOptions.defaultReviewResponseTime'),
'description' => __('manager.setup.reviewOptions.numWeeksPerResponse'),
'value' => $context->getData('numWeeksPerResponse'),
'size' => 'small',
]))
->addField(new FieldText('numWeeksPerReview', [
'label' => __('manager.setup.reviewOptions.defaultReviewCompletionTime'),
'description' => __('manager.setup.reviewOptions.numWeeksPerReview'),
'value' => $context->getData('numWeeksPerReview'),
'size' => 'small',
]));
if (Config::getVar('general', 'scheduled_tasks')) {
$this->addField(new FieldText('numDaysBeforeInviteReminder', [
'label' => __('manager.setup.reviewOptions.reminders.response'),
'description' => __('manager.setup.reviewOptions.reminders.response.description'),
'value' => $context->getData('numDaysBeforeInviteReminder'),
'size' => 'small',
]))
->addField(new FieldText('numDaysBeforeSubmitReminder', [
'label' => __('manager.setup.reviewOptions.reminders.submit'),
'description' => __('manager.setup.reviewOptions.reminders.submit.description'),
'value' => $context->getData('numDaysBeforeSubmitReminder'),
'size' => 'small',
]));
} else {
$this->addField(new FieldHTML('reviewRemindersDisabled', [
'label' => __('manager.setup.reviewOptions.automatedReminders'),
'description' => __('manager.setup.reviewOptions.automatedRemindersDisabled'),
]));
}
}
}
@@ -0,0 +1,66 @@
<?php
/**
* @file classes/components/form/context/PKPSearchIndexingForm.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 PKPSearchIndexingForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring a context's search indexing settings.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldText;
use PKP\components\forms\FieldTextarea;
use PKP\components\forms\FormComponent;
define('FORM_SEARCH_INDEXING', 'searchIndexing');
class PKPSearchIndexingForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_SEARCH_INDEXING;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context $context Journal or Press to change settings for
* @param string $sitemapUrl A URL to the context's sitemap for use in the
* search engine indexing group description
*/
public function __construct($action, $locales, $context, $sitemapUrl)
{
$this->action = $action;
$this->locales = $locales;
$this->addGroup([
'id' => 'search',
'label' => __('manager.setup.searchEngineIndexing'),
'description' => __('manager.setup.searchEngineIndexing.description', ['sitemapUrl' => $sitemapUrl]),
])
->addField(new FieldText('searchDescription', [
'label' => __('common.description'),
'tooltip' => __('manager.setup.searchDescription.description'),
'isMultilingual' => true,
'value' => $context->getData('searchDescription'),
'groupId' => 'search',
]))
->addField(new FieldTextArea('customHeaders', [
'label' => __('manager.distribution.customHeaders'),
'tooltip' => __('manager.distribution.customHeaders.description'),
'isMultilingual' => true,
'value' => $context->getData('customHeaders'),
'groupId' => 'search',
]));
}
}
@@ -0,0 +1,164 @@
<?php
/**
* @file classes/components/form/context/PKPThemeForm.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 PKPThemeForm
*
* @ingroup classes_controllers_form
*
* @brief A form for selecting a theme and theme options. Expects to be attached
* to a <theme-form> element in the UI.
*
* This form works similarly to other form components, except that it keeps a
* separate store of fields for each theme's options. Only the active theme's
* fields are loaded into $this->fields. The <theme-form> UI component chooses
* which fields to display as the theme selection is changed.
*/
namespace PKP\components\forms\context;
use APP\core\Application;
use PKP\components\forms\FieldSelect;
use PKP\components\forms\FormComponent;
use PKP\plugins\PluginRegistry;
use PKP\plugins\ThemePlugin;
define('FORM_THEME', 'theme');
class PKPThemeForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_THEME;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/** @var array A key/value store of theme option fields, keyed by theme name */
public $themeFields = [];
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\context\Context|null $context Journal/Press to change settings for, or null
* to change settings for the Site
*/
public function __construct($action, $locales, $context = null)
{
$this->action = $action;
$this->locales = $locales;
if (!empty($context)) {
$activeTheme = $context->getData('themePluginPath');
$contextId = $context->getId();
} else {
$activeTheme = Application::get()->getRequest()->getSite()->getData('themePluginPath');
$contextId = \PKP\core\PKPApplication::CONTEXT_ID_NONE;
}
$themes = $themeOptions = [];
/** @var ThemePlugin[] */
$plugins = PluginRegistry::loadCategory('themes', true);
foreach ($plugins as $plugin) {
$themes[] = [
'value' => $plugin->getDirName(),
'label' => htmlspecialchars($plugin->getDisplayName()),
];
}
$this->addField(new FieldSelect('themePluginPath', [
'label' => __('manager.setup.theme'),
'description' => __('manager.setup.theme.description'),
'options' => $themes,
'value' => $activeTheme,
]));
// Add theme options for each theme
foreach ($plugins as $plugin) {
// Re-run the init functions for each theme so that any theme options
// are set up. Because this is run after PluginRegistry::loadCategory(),
// the scripts and styles won't actually be registered against the
// template manager. However, if PluginRegistry::loadCategory() is called
// again for the themes category, it can cause scripts and styles to be
// overwritten by inactive themes.
$plugin->init();
$themeOptions = $plugin->getOptionsConfig();
if (empty($themeOptions)) {
continue;
}
$themeOptionValues = $plugin->getOptionValues($contextId);
foreach ($themeOptions as $optionName => $optionField) {
$optionField->value = $themeOptionValues[$optionName] ?? null;
$this->addThemeField($plugin->getDirName(), $optionField);
}
}
}
/**
* Add a form field that should only appear when a particular theme is
* selected
*
* @param string $theme The theme's base plugin path
* @param \PKP\components\forms\Field $field
* @param array $position [
*
* @option string One of `before` or `after`
* @option string The field to position it before or after
* ]
*
* @return FormComponent
*/
public function addThemeField($theme, $field, $position = [])
{
if (empty($position)) {
if (!isset($this->themeFields[$theme])) {
$this->themeFields[$theme] = [];
}
$this->themeFields[$theme][] = $field;
} else {
$this->themeFields[$theme] = $this->addToPosition($position[1], $this->themeFields[$theme], $field, $position[0]);
}
return $this;
}
/**
* @copydoc FormComponent::getConfig()
*/
public function getConfig()
{
// Add the active theme's option fields to the fields array
$activeThemeField = array_filter($this->fields, function ($field) {
return $field->name === 'themePluginPath';
});
$activeTheme = $activeThemeField[0]->value;
if (!empty($this->themeFields[$activeTheme])) {
$this->fields = array_merge($this->fields, $this->themeFields[$activeTheme]);
}
$config = parent::getConfig();
// Set up field config for non-active fields
if (!$this->groups) {
$this->addGroup(['id' => 'default']);
$this->fields = array_map(function ($field) {
$field->groupId = 'default';
return $field;
}, $this->fields);
}
$defaultGroupId = $this->groups[0]['id'];
$config['themeFields'] = array_map(function ($themeOptions) use ($defaultGroupId) {
return array_map(function ($themeOption) use ($defaultGroupId) {
$field = $this->getFieldConfig($themeOption);
$field['groupId'] = $defaultGroupId;
return $field;
}, $themeOptions);
}, $this->themeFields);
return $config;
}
}
@@ -0,0 +1,59 @@
<?php
/**
* @file classes/components/form/context/PKPUserAccessForm.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 PKPUserAccessForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring the user access settings on the Users
* and Roles page of a context.
*/
namespace PKP\components\forms\context;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
define('FORM_USER_ACCESS', 'userAccess');
class PKPUserAccessForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_USER_ACCESS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param \PKP\context\Context $context Journal or Press to change settings for
*/
public function __construct($action, $context)
{
$this->action = $action;
$this->addField(new FieldOptions('restrictSiteAccess', [
'label' => __('manager.setup.siteAccess.view'),
'value' => (bool) $context->getData('restrictSiteAccess'),
'options' => [
['value' => true, 'label' => __('manager.setup.restrictSiteAccess')],
],
]))
->addField(new FieldOptions('disableUserReg', [
'type' => 'radio',
'label' => __('manager.setup.userRegistration'),
'value' => (bool) $context->getData('disableUserReg'),
'options' => [
['value' => false, 'label' => __('manager.setup.enableUserRegistration')],
['value' => true, 'label' => __('manager.setup.disableUserRegistration')],
],
]));
}
}
@@ -0,0 +1,66 @@
<?php
/**
* @file classes/components/form/counter/PKPCounterReportForm.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPCounterReportForm
*
* @ingroup classes_controllers_form
*
* @brief A form for setting a COUNTER R5 report
*/
namespace PKP\components\forms\counter;
use PKP\components\forms\FormComponent;
define('FORM_COUNTER', 'counter');
abstract class PKPCounterReportForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_COUNTER;
/** @copydoc FormComponent::$method */
public $method = 'GET';
/** Form fields for each COUNTER R5 report */
public $reportFields = [];
/** Set reportFields, that will contain form fields for each COUNTER R5 report */
abstract public function setReportFields(): void;
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
*/
public function __construct(string $action, array $locales)
{
$this->action = $action;
$this->locales = $locales;
$this->addPage(['id' => 'default', 'submitButton' => ['label' => __('common.download')]]);
$this->addGroup(['id' => 'default', 'pageId' => 'default']);
$this->setReportFields();
}
public function getConfig()
{
$config = parent::getConfig();
$config['reportFields'] = array_map(function ($reportFields) {
return array_map(function ($reportField) {
$field = $this->getFieldConfig($reportField);
$field['groupId'] = 'default';
return $field;
}, $reportFields);
}, $this->reportFields);
return $config;
}
}
@@ -0,0 +1,62 @@
<?php
/**
* @file classes/components/form/decision/SelectRevisionDecisionForm.php
*
* Copyright (c) 2014-2022 Simon Fraser University
* Copyright (c) 2000-2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class SelectRevisionDecisionForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for selecting between revisions or resubmit for review.
*/
namespace PKP\components\forms\decision;
use APP\decision\Decision;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
define('FORM_SELECT_REVISION_DECISION', 'selectRevisionDecision');
class SelectRevisionDecisionForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_SELECT_REVISION_DECISION;
/** @copydoc FormComponent::$action */
public $action = FormComponent::ACTION_EMIT;
/**
* Constructor
*/
public function __construct()
{
$this->addField(new FieldOptions('decision', [
'label' => __('editor.review.newReviewRound'),
'type' => 'radio',
'options' => [
[
'value' => Decision::PENDING_REVISIONS,
'label' => __('editor.review.NotifyAuthorRevisions'),
],
[
'value' => Decision::RESUBMIT,
'label' => __('editor.review.NotifyAuthorResubmit'),
],
],
'value' => Decision::PENDING_REVISIONS,
'groupId' => 'default',
]))
->addGroup([
'id' => 'default',
'pageId' => 'default',
])
->addPage([
'id' => 'default',
'submitButton' => ['label' => __('help.next')]
]);
}
}
@@ -0,0 +1,62 @@
<?php
/**
* @file classes/components/form/decision/SelectRevisionRecommendationForm.php
*
* Copyright (c) 2014-2022 Simon Fraser University
* Copyright (c) 2000-2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class SelectRevisionRecommendationForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for selecting between revisions or resubmit for review.
*/
namespace PKP\components\forms\decision;
use APP\decision\Decision;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
define('FORM_SELECT_REVISION_RECOMMENDATION', 'selectRevisionRecommendation');
class SelectRevisionRecommendationForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_SELECT_REVISION_RECOMMENDATION;
/** @copydoc FormComponent::$action */
public $action = FormComponent::ACTION_EMIT;
/**
* Constructor
*/
public function __construct()
{
$this->addField(new FieldOptions('decision', [
'label' => __('editor.review.newReviewRound'),
'type' => 'radio',
'options' => [
[
'value' => Decision::RECOMMEND_PENDING_REVISIONS,
'label' => __('editor.review.NotifyAuthorRevisions.recommendation'),
],
[
'value' => Decision::RECOMMEND_RESUBMIT,
'label' => __('editor.review.NotifyAuthorResubmit.recommendation'),
],
],
'value' => Decision::RECOMMEND_PENDING_REVISIONS,
'groupId' => 'default',
]))
->addGroup([
'id' => 'default',
'pageId' => 'default',
])
->addPage([
'id' => 'default',
'submitButton' => ['label' => __('help.next')]
]);
}
}
@@ -0,0 +1,52 @@
<?php
/**
* @file classes/components/form/context/PKPEmailTemplateForm.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 EmailTemplateForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for adding and editing email templates.
*/
namespace PKP\components\forms\emailTemplate;
use PKP\components\forms\FieldPreparedContent;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
define('FORM_EMAIL_TEMPLATE', 'editEmailTemplate');
class EmailTemplateForm extends FormComponent
{
public $id = FORM_EMAIL_TEMPLATE;
public function __construct(string $action, array $locales)
{
$this->action = $action;
$this->method = 'POST';
$this->locales = $locales;
$this->addField(new FieldText('name', [
'label' => __('common.name'),
'description' => __('manager.emailTemplate.name.description'),
'isMultilingual' => true,
]))
->addField(new FieldText('subject', [
'label' => __('email.subject'),
'isMultilingual' => true,
'size' => 'large',
]))
->addField(new FieldPreparedContent('body', [
'label' => __('email.body'),
'size' => 'large',
'isMultilingual' => true,
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]));
}
}
@@ -0,0 +1,82 @@
<?php
/**
* @file classes/components/form/highlight/HighlightForm.php
*
* Copyright (c) 2023 Simon Fraser University
* Copyright (c) 2023 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class HighlightForm
*
* @ingroup classes_controllers_form
*
* @brief A form for adding or editing a highlight
*/
namespace PKP\components\forms\highlight;
use APP\core\Application;
use PKP\components\forms\FieldRichText;
use PKP\components\forms\FieldText;
use PKP\components\forms\FieldUploadImage;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
define('FORM_HIGHLIGHT', 'highlight');
class HighlightForm extends FormComponent
{
public $id = FORM_HIGHLIGHT;
public $method = 'POST';
public ?Context $context;
/**
* Constructor
*
* @param string $action URL to submit the form to
*/
public function __construct(string $action, string $baseUrl, string $temporaryFileApiUrl, ?Context $context = null)
{
$this->action = $action;
$this->context = $context;
$this->locales = $this->getLocales($context);
$this->addField(new FieldRichText('title', [
'label' => __('common.title'),
'isMultilingual' => true,
]))
->addField(new FieldRichText('description', [
'label' => __('common.description'),
'isMultilingual' => true,
]))
->addField(new FieldText('url', [
'label' => __('common.url'),
'description' => __('manager.highlights.url.description'),
'size' => 'large',
]))
->addField(new FieldText('urlText', [
'label' => __('manager.highlights.urlText'),
'description' => __('manager.highlights.urlText.description'),
'size' => 'small',
'isMultilingual' => true,
]))
->addField(new FieldUploadImage('image', [
'label' => __('manager.highlights.image'),
'baseUrl' => $baseUrl,
'options' => [
'url' => $temporaryFileApiUrl,
],
]));
}
/**
* Get the locales formatted for display in the form
*/
protected function getLocales(?Context $context = null): array
{
$localeNames = $this?->context?->getSupportedFormLocaleNames()
?? Application::get()->getRequest()->getSite()->getSupportedLocaleNames();
return array_map(fn (string $locale, string $name) => ['key' => $locale, 'label' => $name], array_keys($localeNames), $localeNames);
}
}
@@ -0,0 +1,57 @@
<?php
/**
* @file classes/components/form/institution/PKPInstitutionForm.php
*
* Copyright (c) 2022 Simon Fraser University
* Copyright (c) 2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPInstitutionForm
*
* @ingroup classes_controllers_form
*
* @brief A form for creating a new institution
*/
namespace PKP\components\forms\institution;
use PKP\components\forms\FieldText;
use PKP\components\forms\FieldTextarea;
use PKP\components\forms\FormComponent;
define('FORM_INSTITUTION', 'institution');
class PKPInstitutionForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_INSTITUTION;
/** @copydoc FormComponent::$method */
public $method = 'POST';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
*/
public function __construct(string $action, array $locales)
{
$this->action = $action;
$this->locales = $locales;
$this->addField(new FieldText('name', [
'label' => __('common.name'),
'size' => 'large',
'isMultilingual' => true,
]))
->addField(new FieldTextarea('ipRanges', [
'label' => __('manager.institutions.form.ipRanges'),
'description' => __('manager.institutions.form.ipRangesInstructions'),
]))
->addField(new FieldText('ror', [
'label' => __('manager.institutions.form.ror'),
'description' => __('manager.institutions.form.ror.description'),
]));
}
}
@@ -0,0 +1,135 @@
<?php
/**
* @file classes/components/form/publication/ContributorForm.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 ContributorForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for adding and editing a contributor for a publication.
*/
namespace PKP\components\forms\publication;
use APP\facades\Repo;
use APP\submission\Submission;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldSelect;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
use PKP\security\Role;
use PKP\userGroup\UserGroup;
use Sokil\IsoCodes\IsoCodesFactory;
define('FORM_CONTRIBUTOR', 'contributor');
class ContributorForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_CONTRIBUTOR;
/** @copydoc FormComponent::$method */
public $method = 'POST';
public Submission $submission;
public Context $context;
public function __construct(string $action, array $locales, Submission $submission, Context $context)
{
$this->action = $action;
$this->locales = $locales;
$this->submission = $submission;
$this->context = $context;
$authorUserGroupsOptions = Repo::userGroup()
->getCollector()
->filterByRoleIds([Role::ROLE_ID_AUTHOR])
->filterByContextIds([$context->getId()])
->getMany()
->map(fn (UserGroup $authorUserGroup) => [
'value' => (int) $authorUserGroup->getId(),
'label' => $authorUserGroup->getLocalizedName(),
]);
$isoCodes = app(IsoCodesFactory::class);
$countries = [];
foreach ($isoCodes->getCountries() as $country) {
$countries[] = [
'value' => $country->getAlpha2(),
'label' => $country->getLocalName()
];
}
usort($countries, function ($a, $b) {
return strcmp($a['label'], $b['label']);
});
$this->addField(new FieldText('givenName', [
'label' => __('user.givenName'),
'isMultilingual' => true,
'isRequired' => true
]))
->addField(new FieldText('familyName', [
'label' => __('user.familyName'),
'isMultilingual' => true,
]))
->addField(new FieldText('preferredPublicName', [
'label' => __('user.preferredPublicName'),
'description' => __('user.preferredPublicName.description'),
'isMultilingual' => true,
]))
->addField(new FieldText('email', [
'label' => __('user.email'),
'isRequired' => true,
]))
->addField(new FieldSelect('country', [
'label' => __('common.country'),
'options' => $countries,
'isRequired' => true,
]))
->addField(new FieldText('url', [
'label' => __('user.url'),
]))
->addField(new FieldText('orcid', [
'label' => __('user.orcid'),
]));
if ($context->getSetting('requireAuthorCompetingInterests')) $this->addField(new FieldRichTextarea('competingInterests', [
'label' => __('author.competingInterests'),
'description' => __('author.competingInterests.description'),
'isMultilingual' => true,
]));
$this->addField(new FieldRichTextarea('biography', [
'label' => __('user.biography'),
'isMultilingual' => true,
]))
->addField(new FieldText('affiliation', [
'label' => __('user.affiliation'),
'isMultilingual' => true,
]));
if ($authorUserGroupsOptions->count() > 1) {
$this->addField(new FieldOptions('userGroupId', [
'label' => __('submission.submit.contributorRole'),
'type' => 'radio',
'value' => $authorUserGroupsOptions->first()['value'],
'options' => $authorUserGroupsOptions->values(),
]));
} else {
$this->addHiddenField('userGroupId', $authorUserGroupsOptions->first()['value']);
}
$this->addField(new FieldOptions('includeInBrowse', [
'label' => __('submission.submit.includeInBrowse.title'),
'type' => 'checkbox',
'value' => true,
'options' => [
['value' => true, 'label' => __('submission.submit.includeInBrowse')],
]
]));
}
}
@@ -0,0 +1,56 @@
<?php
/**
* @file classes/components/form/publication/Details.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 Details
*
* @ingroup classes_controllers_form
*
* @brief The Details form in the submission wizard.
*/
namespace PKP\components\forms\publication;
use APP\publication\Publication;
use PKP\components\forms\FieldControlledVocab;
use PKP\context\Context;
use PKP\submission\SubmissionKeywordDAO;
class Details extends TitleAbstractForm
{
/**
* Constructor
*
* @param string $suggestionUrlBase The base URL to get suggestions for controlled vocab.
*/
public function __construct(
string $action,
array $locales,
Publication $publication,
public Context $context,
public string $suggestionUrlBase,
int $abstractWordLimit = 0,
bool $isAbstractRequired = false
) {
parent::__construct($action, $locales, $publication, $abstractWordLimit, $isAbstractRequired);
$this->removeField('prefix');
$this->removeField('subtitle');
if (in_array($context->getData('keywords'), [Context::METADATA_REQUEST, Context::METADATA_REQUIRE])) {
$this->addField(new FieldControlledVocab('keywords', [
'label' => __('common.keywords'),
'description' => __('manager.setup.metadata.keywords.description'),
'isMultilingual' => true,
'apiUrl' => str_replace('__vocab__', SubmissionKeywordDAO::CONTROLLED_VOCAB_SUBMISSION_KEYWORD, $suggestionUrlBase),
'locales' => $this->locales,
'value' => (array) $publication->getData('keywords'),
'isRequired' => $context->getData('keywords') === Context::METADATA_REQUIRE ? true : false,
]), [FIELD_POSITION_AFTER, 'title']);
}
}
}
@@ -0,0 +1,47 @@
<?php
/**
* @file classes/components/form/publication/PKPCitationsForm.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 PKPCitationsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for setting a publication's citations
*/
namespace PKP\components\forms\publication;
use APP\publication\Publication;
use PKP\components\forms\FieldTextarea;
use PKP\components\forms\FormComponent;
define('FORM_CITATIONS', 'citations');
class PKPCitationsForm extends FormComponent
{
public $id = FORM_CITATIONS;
public $method = 'PUT';
public bool $isRequired;
/**
* Constructor
*
* @param string $action URL to submit the form to
*/
public function __construct(string $action, Publication $publication, bool $isRequired = false)
{
$this->action = $action;
$this->isRequired = $isRequired;
$this->addField(new FieldTextarea('citationsRaw', [
'label' => __('submission.citations'),
'description' => __('submission.citations.description'),
'value' => $publication->getData('citationsRaw'),
'isRequired' => $isRequired
]));
}
}
@@ -0,0 +1,174 @@
<?php
/**
* @file classes/components/form/publication/PKPMetadataForm.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 PKPMetadataForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for setting a publication's metadata fields
*/
namespace PKP\components\forms\publication;
use APP\publication\Publication;
use PKP\components\forms\FieldControlledVocab;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
use PKP\submission\SubmissionAgencyDAO;
use PKP\submission\SubmissionDisciplineDAO;
use PKP\submission\SubmissionKeywordDAO;
use PKP\submission\SubmissionLanguageDAO;
use PKP\submission\SubmissionSubjectDAO;
define('FORM_METADATA', 'metadata');
class PKPMetadataForm extends FormComponent
{
public $id = FORM_METADATA;
public $method = 'PUT';
public Context $context;
public Publication $publication;
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param Publication $publication The publication to change settings for
* @param Context $context The journal or press of the submission.
* @param string $suggestionUrlBase The base URL to get suggestions for controlled vocab.
*/
public function __construct(string $action, array $locales, Publication $publication, Context $context, string $suggestionUrlBase)
{
$this->action = $action;
$this->locales = $locales;
$this->context = $context;
$this->publication = $publication;
if ($this->enabled('keywords')) {
$this->addField(new FieldControlledVocab('keywords', [
'label' => __('common.keywords'),
'tooltip' => __('manager.setup.metadata.keywords.description'),
'isMultilingual' => true,
'apiUrl' => str_replace('__vocab__', SubmissionKeywordDAO::CONTROLLED_VOCAB_SUBMISSION_KEYWORD, $suggestionUrlBase),
'locales' => $this->locales,
'value' => (array) $publication->getData('keywords'),
]));
}
if ($this->enabled('subjects')) {
$this->addField(new FieldControlledVocab('subjects', [
'label' => __('common.subjects'),
'tooltip' => __('manager.setup.metadata.subjects.description'),
'isMultilingual' => true,
'apiUrl' => str_replace('__vocab__', SubmissionSubjectDAO::CONTROLLED_VOCAB_SUBMISSION_SUBJECT, $suggestionUrlBase),
'locales' => $this->locales,
'value' => (array) $publication->getData('subjects'),
]));
}
if ($this->enabled('disciplines')) {
$this->addField(new FieldControlledVocab('disciplines', [
'label' => __('search.discipline'),
'tooltip' => __('manager.setup.metadata.disciplines.description'),
'isMultilingual' => true,
'apiUrl' => str_replace('__vocab__', SubmissionDisciplineDAO::CONTROLLED_VOCAB_SUBMISSION_DISCIPLINE, $suggestionUrlBase),
'locales' => $this->locales,
'value' => (array) $publication->getData('disciplines'),
]));
}
if ($this->enabled('languages')) {
$this->addField(new FieldControlledVocab('languages', [
'label' => __('common.languages'),
'tooltip' => __('manager.setup.metadata.languages.description'),
'isMultilingual' => true,
'apiUrl' => str_replace('__vocab__', SubmissionLanguageDAO::CONTROLLED_VOCAB_SUBMISSION_LANGUAGE, $suggestionUrlBase),
'locales' => $this->locales,
'value' => (array) $publication->getData('languages'),
]));
}
if ($this->enabled('agencies')) {
$this->addField(new FieldControlledVocab('supportingAgencies', [
'label' => __('submission.supportingAgencies'),
'tooltip' => __('manager.setup.metadata.agencies.description'),
'isMultilingual' => true,
'apiUrl' => str_replace('__vocab__', SubmissionAgencyDAO::CONTROLLED_VOCAB_SUBMISSION_AGENCY, $suggestionUrlBase),
'locales' => $this->locales,
'value' => (array) $publication->getData('supportingAgencies'),
]));
}
if ($this->enabled('coverage')) {
$this->addField(new FieldText('coverage', [
'label' => __('manager.setup.metadata.coverage'),
'tooltip' => __('manager.setup.metadata.coverage.description'),
'isMultilingual' => true,
'value' => $publication->getData('coverage'),
]));
}
if ($this->enabled('rights')) {
$this->addField(new FieldText('rights', [
'label' => __('submission.rights'),
'tooltip' => __('manager.setup.metadata.rights.description'),
'isMultilingual' => true,
'value' => $publication->getData('rights'),
]));
}
if ($this->enabled('source')) {
$this->addField(new FieldText('source', [
'label' => __('common.source'),
'tooltip' => __('manager.setup.metadata.source.description'),
'isMultilingual' => true,
'value' => $publication->getData('source'),
]));
}
if ($this->enabled('type')) {
$this->addField(new FieldText('type', [
'label' => __('common.type'),
'tooltip' => __('manager.setup.metadata.type.description'),
'isMultilingual' => true,
'value' => $publication->getData('type'),
]));
}
if ($this->enabled('dataAvailability')) {
$this->addField(new FieldRichTextarea('dataAvailability', [
'label' => __('submission.dataAvailability'),
'tooltip' => __('manager.setup.metadata.dataAvailability.description'),
'isMultilingual' => true,
'value' => $publication->getData('dataAvailability'),
]));
}
if ($this->enabled('pub-id::publisher-id')) {
$this->addField(new FieldText('pub-id::publisher-id', [
'label' => __('submission.publisherId'),
'tooltip' => __('submission.publisherId.description'),
'value' => $publication->getData('pub-id::publisher-id'),
]));
}
}
/**
* Whether or not a metadata field is enabled in this form
*/
protected function enabled(string $setting): bool
{
if ($setting === 'pub-id::publisher-id') {
return in_array('publication', (array) $this->context->getData('enablePublisherId'));
}
return (bool) $this->context->getData($setting);
}
}
@@ -0,0 +1,52 @@
<?php
/**
* @file classes/components/form/publication/PKPPublicationIdentifiersForm.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 PKPPublicationIdentifiersForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for setting a publication's public identifiers (DOI, etc)
*/
namespace PKP\components\forms\publication;
use APP\publication\Publication;
use PKP\components\forms\FormComponent;
define('FORM_PUBLICATION_IDENTIFIERS', 'publicationIdentifiers');
class PKPPublicationIdentifiersForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_PUBLICATION_IDENTIFIERS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/** @var Publication The publication this form is for */
public $publication;
/** @var \PKP\context\Context The journal/press this publication exists in */
public $submissionContext;
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param Publication $publication The publication to change settings for
* @param \PKP\context\Context $submissionContext The journal/press this publication exists in
*/
public function __construct($action, $locales, $publication, $submissionContext)
{
$this->action = $action;
$this->locales = $locales;
$this->publication = $publication;
$this->submissionContext = $submissionContext;
}
}
@@ -0,0 +1,97 @@
<?php
/**
* @file classes/components/form/publication/PKPPublicationLicenseForm.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 PKPPublicationLicenseForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for setting a publication's license and copyright info
*/
namespace PKP\components\forms\publication;
use APP\core\Application;
use APP\publication\Publication;
use Illuminate\Support\LazyCollection;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
define('FORM_PUBLICATION_LICENSE', 'publicationLicense');
class PKPPublicationLicenseForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_PUBLICATION_LICENSE;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param Publication $publication The publication to change settings for
* @param \PKP\context\Context $context The publication's context
* @param LazyCollection<int,\PKP\userGroup\UserGroup> $userGroups User groups in this context
*/
public function __construct($action, $locales, $publication, $context, LazyCollection $userGroups)
{
$this->action = $action;
$this->locales = $locales;
// Get the copyright that will be set on publication based on context settings
if ($context->getData('copyrightHolderType') === 'author') {
$copyright = $publication->getAuthorString($userGroups);
} elseif ($context->getData('copyrightHolderType') === 'other') {
$copyright = $context->getLocalizedData('copyrightHolderOther');
} else {
$copyright = $context->getLocalizedData('name');
}
// Get the name of the context's license setting
$licenseUrlDescription = '';
if ($context->getData('licenseUrl')) {
$licenseOptions = Application::getCCLicenseOptions();
if (array_key_exists($context->getData('licenseUrl'), $licenseOptions)) {
$licenseName = __($licenseOptions[$context->getData('licenseUrl')]);
} else {
$licenseName = $context->getData('licenseUrl');
}
$licenseUrlDescription = __('submission.license.description', [
'licenseUrl' => $context->getData('licenseUrl'),
'licenseName' => $licenseName,
]);
}
$this->addField(new FieldText('copyrightHolder', [
'label' => __('submission.copyrightHolder'),
'description' => __('submission.copyrightHolder.description', ['copyright' => htmlspecialchars($copyright)]),
'isMultilingual' => true,
'optIntoEdit' => !$publication->getData('copyrightHolder'),
'optIntoEditLabel' => __('common.override'),
'value' => $publication->getData('copyrightHolder'),
]))
->addField(new FieldText('copyrightYear', [
'label' => __('submission.copyrightYear'),
'description' => $context->getData('copyrightYearBasis') === 'issue'
? __('publication.copyrightYearBasis.issueDescription')
: __('publication.copyrightYearBasis.submissionDescription'),
'optIntoEdit' => !$publication->getData('copyrightYear'),
'optIntoEditLabel' => __('common.override'),
'value' => $publication->getData('copyrightYear'),
]))
->addField(new FieldText('licenseUrl', [
'label' => __('submission.licenseURL'),
'description' => $licenseUrlDescription,
'optIntoEdit' => $context->getData('licenseUrl') && !$publication->getData('licenseUrl'),
'optIntoEditLabel' => __('common.override'),
'value' => $publication->getData('licenseUrl'),
]));
}
}
@@ -0,0 +1,80 @@
<?php
/**
* @file classes/components/form/publication/TitleAbstractForm.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 TitleAbstractForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for setting a publication's title and abstract
*/
namespace PKP\components\forms\publication;
use APP\publication\Publication;
use PKP\components\forms\FieldRichText;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
define('FORM_TITLE_ABSTRACT', 'titleAbstract');
class TitleAbstractForm extends FormComponent
{
public $id = FORM_TITLE_ABSTRACT;
public $method = 'PUT';
public $publication;
public int $abstractWordLimit;
public bool $isAbstractRequired;
/**
* Constructor
*
* @param int $abstractWordLimit The abstract word limit for this submission or 0 for no limit
* @param bool $isAbstractRequired Is the abstract required?
*/
public function __construct(
string $action,
array $locales,
Publication $publication,
int $abstractWordLimit = 0,
bool $isAbstractRequired = false
) {
$this->action = $action;
$this->locales = $locales;
$this->publication = $publication;
$this->abstractWordLimit = $abstractWordLimit;
$this->isAbstractRequired = $isAbstractRequired;
$this->addField(new FieldText('prefix', [
'label' => __('common.prefix'),
'description' => __('common.prefixAndTitle.tip'),
'size' => 'small',
'isMultilingual' => true,
'value' => $publication->getData('prefix'),
]))
->addField(new FieldRichText('title', [
'label' => __('common.title'),
'isMultilingual' => true,
'isRequired' => true,
'value' => $publication->getData('title'),
]))
->addField(new FieldRichText('subtitle', [
'label' => __('common.subtitle'),
'isMultilingual' => true,
'value' => $publication->getData('subtitle'),
]))
->addField(new FieldRichTextarea('abstract', [
'label' => __('common.abstract'),
'isMultilingual' => true,
'isRequired' => $this->isAbstractRequired,
'size' => 'large',
'wordLimit' => $this->abstractWordLimit,
'value' => $publication->getData('abstract'),
]));
}
}
@@ -0,0 +1,88 @@
<?php
/**
* @file classes/components/form/site/PKPSiteAppearanceForm.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 PKPSiteAppearanceForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for the site appearance settings.
*/
namespace PKP\components\forms\site;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldUpload;
use PKP\components\forms\FieldUploadImage;
use PKP\components\forms\FormComponent;
use PKP\plugins\PluginRegistry;
define('FORM_SITE_APPEARANCE', 'siteAppearance');
class PKPSiteAppearanceForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_SITE_APPEARANCE;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\site\Site $site
* @param string $baseUrl Site's base URL. Used for image previews.
* @param string $temporaryFileApiUrl URL to upload files to
*/
public function __construct($action, $locales, $site, $baseUrl, $temporaryFileApiUrl)
{
$this->action = $action;
$this->locales = $locales;
$sidebarOptions = [];
$plugins = PluginRegistry::loadCategory('blocks', true);
foreach ($plugins as $pluginName => $plugin) {
$sidebarOptions[] = [
'value' => $pluginName,
'label' => htmlspecialchars($plugin->getDisplayName()),
];
}
$this->addField(new FieldUploadImage('pageHeaderTitleImage', [
'label' => __('manager.setup.logo'),
'value' => $site->getData('pageHeaderTitleImage'),
'isMultilingual' => true,
'baseUrl' => $baseUrl,
'options' => [
'url' => $temporaryFileApiUrl,
],
]))
->addField(new FieldRichTextarea('pageFooter', [
'label' => __('manager.setup.pageFooter'),
'description' => __('manager.setup.pageFooter.description'),
'isMultilingual' => true,
'value' => $site->getData('pageFooter'),
]))
->addField(new FieldOptions('sidebar', [
'label' => __('manager.setup.layout.sidebar'),
'isOrderable' => true,
'value' => (array) $site->getData('sidebar'),
'options' => $sidebarOptions,
]))
->addField(new FieldUpload('styleSheet', [
'label' => __('admin.settings.siteStyleSheet'),
'value' => $site->getData('styleSheet'),
'options' => [
'url' => $temporaryFileApiUrl,
'acceptedFiles' => '.css',
],
]));
}
}
@@ -0,0 +1,61 @@
<?php
/**
* @file classes/components/form/site/PKPSiteBulkEmailsForm.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 PKPSiteBulkEmailsForm
*
* @ingroup classes_controllers_form
*
* @brief A form for enabling the bulk email features.
*/
namespace PKP\components\forms\site;
use APP\core\Application;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
define('FORM_SITE_BULK_EMAILS', 'bulkEmails');
class PKPSiteBulkEmailsForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_SITE_BULK_EMAILS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param \PKP\site\Site $site
* @param array $contexts List of context summary objects. See PKPContextQueryBuilder::getManySummary()
*/
public function __construct($action, $site, $contexts)
{
$this->action = $action;
$request = Application::get()->getRequest();
$hostedContextsUrl = $request->getDispatcher()->url($request, Application::ROUTE_PAGE, null, 'admin', 'contexts');
$options = [];
foreach ($contexts as $context) {
$options[] = [
'value' => $context->id,
'label' => htmlspecialchars($context->name),
];
}
$this->addField(new FieldOptions('enableBulkEmails', [
'label' => __('admin.settings.enableBulkEmails.label'),
'description' => __('admin.settings.enableBulkEmails.description', ['hostedContextsUrl' => $hostedContextsUrl]),
'value' => (array) $site->getData('enableBulkEmails'),
'options' => $options,
]));
}
}
@@ -0,0 +1,87 @@
<?php
/**
* @file classes/components/form/site/PKPSiteConfigForm.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 PKPSiteConfigForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for the site config settings.
*/
namespace PKP\components\forms\site;
use APP\core\Services;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldSelect;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
define('FORM_SITE_CONFIG', 'siteConfig');
class PKPSiteConfigForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_SITE_CONFIG;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\site\Site $site
*/
public function __construct($action, $locales, $site)
{
$this->action = $action;
$this->locales = $locales;
$contextsIterator = Services::get('context')->getMany(['isEnabled' => true]);
$this->addField(new FieldText('title', [
'label' => __('admin.settings.siteTitle'),
'isRequired' => true,
'isMultilingual' => true,
'value' => $site->getData('title'),
]));
$options = [['value' => '', 'label' => '']];
foreach ($contextsIterator as $context) {
$options[] = [
'value' => $context->getId(),
'label' => htmlspecialchars($context->getLocalizedData('name')),
];
}
if (count($options) > 1) {
$this->addField(new FieldSelect('redirect', [
'label' => __('admin.settings.redirect'),
'description' => __('admin.settings.redirectInstructions'),
'options' => $options,
'value' => $site->getData('redirect'),
]));
}
$this->addField(new FieldText('minPasswordLength', [
'label' => __('admin.settings.minPasswordLength'),
'isRequired' => true,
'size' => 'small',
'value' => $site->getData('minPasswordLength'),
]));
$this->addField(new FieldOptions('disableSharedReviewerStatistics', [
'label' => __('admin.settings.sharedReviewerStatistics'),
'description' => __('admin.settings.sharedReviewerStatistics.description'),
'options' => [
['value' => true, 'label' => __('admin.settings.sharedReviewerStatistics.disable')]
],
'value' => (bool) $site->getData('disableSharedReviewerStatistics'),
]));
}
}
@@ -0,0 +1,68 @@
<?php
/**
* @file classes/components/form/site/PKPSiteInformationForm.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 PKPSiteInformationForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for the site information settings.
*/
namespace PKP\components\forms\site;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
define('FORM_SITE_INFO', 'siteInfo');
class PKPSiteInformationForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_SITE_INFO;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
* @param \PKP\site\Site $site
*/
public function __construct($action, $locales, $site)
{
$this->action = $action;
$this->locales = $locales;
$this->addField(new FieldRichTextarea('about', [
'label' => __('admin.settings.about'),
'isMultilingual' => true,
'value' => $site->getData('about'),
]))
->addField(new FieldText('contactName', [
'label' => __('admin.settings.contactName'),
'isRequired' => true,
'isMultilingual' => true,
'value' => $site->getData('contactName'),
]))
->addField(new FieldText('contactEmail', [
'label' => __('admin.settings.contactEmail'),
'isRequired' => true,
'isMultilingual' => true,
'value' => $site->getData('contactEmail'),
]))
->addField(new FieldRichTextarea('privacyStatement', [
'label' => __('manager.setup.privacyStatement'),
'description' => __('manager.setup.privacyStatement.description'),
'isMultilingual' => true,
'value' => $site->getData('privacyStatement'),
]));
}
}
@@ -0,0 +1,175 @@
<?php
/**
* @file classes/components/forms/site/PKPSiteStatisticsForm.php
*
* Copyright (c) 2022 Simon Fraser University
* Copyright (c) 2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPSiteStatisticsForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for the site statistics settings.
*/
namespace PKP\components\forms\site;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
use PKP\site\Site;
use PKP\statistics\PKPStatisticsHelper;
use PKP\task\FileLoader;
define('FORM_SITE_STATISTICS', 'siteStatistics');
class PKPSiteStatisticsForm extends FormComponent
{
public const COLLECTION_GROUP = 'collection';
public const STORAGE_GROUP = 'storage';
public const SUSHI_GROUP = 'sushi';
/** @copydoc FormComponent::$id */
public $id = FORM_SITE_STATISTICS;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $locales Supported locales
*/
public function __construct(string $action, array $locales, Site $site)
{
$this->action = $action;
$this->locales = $locales;
$usageStatsFileDir = PKPStatisticsHelper::getUsageStatsDirPath() . '/' . FileLoader::FILE_LOADER_PATH_ARCHIVE;
$this->addGroup([
'id' => self::COLLECTION_GROUP,
'label' => __('admin.settings.statistics.collection'),
'description' => __('admin.settings.statistics.collection.description'),
])
->addField(new FieldOptions('enableGeoUsageStats', [
'label' => __('manager.settings.statistics.geoUsageStats'),
'description' => __('admin.settings.statistics.geo.description'),
'type' => 'radio',
'options' => [
[
'value' => 'disabled',
'label' => __('manager.settings.statistics.geoUsageStats.disabled'),
],
[
'value' => PKPStatisticsHelper::STATISTICS_SETTING_COUNTRY,
'label' => __('manager.settings.statistics.geoUsageStats.countryLevel'),
],
[
'value' => PKPStatisticsHelper::STATISTICS_SETTING_REGION,
'label' => __('manager.settings.statistics.geoUsageStats.regionLevel'),
],
[
'value' => PKPStatisticsHelper::STATISTICS_SETTING_CITY,
'label' => __('manager.settings.statistics.geoUsageStats.cityLevel'),
],
],
'value' => $site->getData('enableGeoUsageStats') ? $site->getData('enableGeoUsageStats') : 'disabled',
'groupId' => self::COLLECTION_GROUP,
]))
->addField(new FieldOptions('enableInstitutionUsageStats', [
'label' => __('manager.settings.statistics.institutionUsageStats'),
'description' => __('admin.settings.statistics.institutions.description'),
'options' => [
[
'value' => true,
'label' => __('manager.settings.statistics.institutionUsageStats.enable'),
],
],
'value' => $site->getData('enableInstitutionUsageStats'),
'groupId' => self::COLLECTION_GROUP,
]))
->addGroup([
'id' => self::STORAGE_GROUP,
'label' => __('admin.settings.statistics.storage'),
'description' => __('admin.settings.statistics.storage.description'),
])
->addField(new FieldOptions('keepDailyUsageStats', [
'label' => __('admin.settings.statistics.keepDaily'),
'description' => __('admin.settings.statistics.keepDaily.description'),
'type' => 'radio',
'options' => [
[
'value' => false,
'label' => __('admin.settings.statistics.keepDaily.discard'),
],
[
'value' => true,
'label' => __('admin.settings.statistics.keepDaily.keep'),
],
],
'value' => $site->getData('keepDailyUsageStats'),
'groupId' => self::STORAGE_GROUP,
]))
->addField(new FieldOptions('compressStatsLogs', [
'label' => __('admin.settings.statistics.compressStatsLogs.label'),
'description' => __('admin.settings.statistics.compressStatsLogs.description', ['path' => $usageStatsFileDir]),
'type' => 'radio',
'options' => [
[
'value' => false,
'label' => __('admin.settings.statistics.compressStatsLogs.default'),
],
[
'value' => true,
'label' => __('admin.settings.statistics.compressStatsLogs.compress'),
],
],
'value' => $site->getData('compressStatsLogs') ? $site->getData('compressStatsLogs') : false,
'groupId' => self::STORAGE_GROUP,
]))
->addGroup([
'id' => self::SUSHI_GROUP,
'label' => __('admin.settings.statistics.sushi'),
'description' => __('admin.settings.statistics.sushi.description'),
])
->addField(new FieldOptions('isSushiApiPublic', [
'label' => __('manager.settings.statistics.publicSushiApi'),
'description' => __('admin.settings.statistics.sushi.public.description'),
'type' => 'radio',
'options' => [
[
'value' => true,
'label' => __('manager.settings.statistics.publicSushiApi.public'),
],
[
'value' => false,
'label' => __('admin.settings.statistics.publicSushiApi.private'),
],
],
'value' => $site->getData('isSushiApiPublic') ? $site->getData('isSushiApiPublic') : true,
'groupId' => self::SUSHI_GROUP,
]))
->addField(new FieldOptions('isSiteSushiPlatform', [
'label' => __('admin.settings.statistics.sushiPlatform'),
'description' => __('admin.settings.statistics.sushiPlatform.description'),
'options' => [
[
'value' => true,
'label' => __('admin.settings.statistics.sushiPlatform.isSiteSushiPlatform'),
],
],
'value' => $site->getData('isSiteSushiPlatform'),
'groupId' => self::SUSHI_GROUP,
]))
->addField(new FieldText('sushiPlatformID', [
'label' => __('admin.settings.statistics.sushiPlatform.sushiPlatformID'),
'description' => __('admin.settings.statistics.sushiPlatform.sushiPlatformID.description'),
'value' => $site->getData('sushiPlatformID'),
'showWhen' => 'isSiteSushiPlatform',
'groupId' => self::SUSHI_GROUP,
]));
}
}
@@ -0,0 +1,58 @@
<?php
/**
* @file classes/components/form/statistics/users/ReportForm.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 ReportForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring the users report.
*/
namespace PKP\components\forms\statistics\users;
use APP\facades\Repo;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
use PKP\userGroup\UserGroup;
class ReportForm extends FormComponent
{
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param \Context $context The context
*/
public function __construct(string $action, Context $context)
{
$this->action = $action;
$this->id = 'reportForm';
$this->method = 'POST';
$this->addPage(['id' => 'default', 'submitButton' => ['label' => __('common.export')]]);
$this->addGroup(['id' => 'default', 'pageId' => 'default']);
$userGroups = Repo::userGroup()->getCollector()
->filterByContextIds([$context->getId()])
->getMany();
$this->addField(new FieldOptions('userGroupIds', [
'groupId' => 'default',
'label' => __('user.group'),
'description' => __('manager.export.usersToCsv.description'),
'options' => $userGroups->values()->map(function (UserGroup $userGroup) {
return [
'value' => $userGroup->getId(),
'label' => htmlspecialchars($userGroup->getLocalizedName())
];
}),
'default' => $userGroups->keys(),
]));
}
}
@@ -0,0 +1,39 @@
<?php
/**
* @file classes/components/form/submission/CommentsForTheEditors.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 CommentsForTheEditors
*
* @ingroup classes_controllers_form
*
* @brief A form during the For the Editors step in the submission wizard
*/
namespace PKP\components\forms\submission;
use APP\submission\Submission;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FormComponent;
class CommentsForTheEditors extends FormComponent
{
public $id = 'commentsForTheEditors';
public $method = 'PUT';
public Submission $submission;
public function __construct(string $action, Submission $submission)
{
$this->action = $action;
$this->submission = $submission;
$this->addField(new FieldRichTextarea('commentsForTheEditors', [
'label' => __('submission.submit.coverNote'),
'description' => __('submission.wizard.commentsForTheEditor.description'),
'value' => $this->submission->getData('commentsForTheEditors'),
]));
}
}
@@ -0,0 +1,58 @@
<?php
/**
* @file classes/components/form/submission/ConfirmSubmission.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 ConfirmSubmission
*
* @ingroup classes_controllers_form
*
* @brief A preset form for the confirm step in the submission wizard
*/
namespace PKP\components\forms\submission;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
define('FORM_CONFIRM_SUBMISSION', 'confirmSubmission');
class ConfirmSubmission extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_CONFIRM_SUBMISSION;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
public function __construct(string $action, Context $context)
{
$this->action = $action;
if ($context->getLocalizedData('copyrightNotice')) {
$this->addField(new FieldOptions('confirmCopyright', [
'label' => __('submission.copyright'),
'description' => $this->getCopyrightDescription($context),
'options' => [
[
'value' => true,
'label' => __('submission.copyright.agree'),
],
],
'value' => false,
]));
}
}
protected function getCopyrightDescription(Context $context)
{
return __('submission.copyright.description')
. '<blockquote>'
. $context->getLocalizedData('copyrightNotice')
. '</blockquote>';
}
}
@@ -0,0 +1,128 @@
<?php
/**
* @file classes/components/form/publication/ForTheEditors.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 ForTheEditors
*
* @ingroup classes_controllers_form
*
* @brief A form during the For the Editors step in the submission wizard
*/
namespace PKP\components\forms\submission;
use APP\facades\Repo;
use APP\publication\Publication;
use APP\submission\Submission;
use Illuminate\Support\LazyCollection;
use PKP\components\forms\FieldAutosuggestPreset;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\publication\PKPMetadataForm;
use PKP\context\Context;
class ForTheEditors extends PKPMetadataForm
{
/**
* How many categories can be present before the options field
* should become an autosuggest field
*/
public const MAX_CATEGORY_LIST_SIZE = 10;
public $id = 'forTheEditors';
public $method = 'PUT';
public Context $context;
public Publication $publication;
public Submission $submission;
public function __construct(string $action, array $locales, Publication $publication, Submission $submission, Context $context, string $suggestionUrlBase, LazyCollection $categories)
{
parent::__construct($action, $locales, $publication, $context, $suggestionUrlBase);
$this->submission = $submission;
$this->removeField('keywords');
$this->changeTooltipsToDescriptions();
$this->setRequiredMetadata();
$this->addCategoryField($context, $categories);
}
/**
* Whether or not a metadata field is enabled in this form
*/
protected function enabled(string $setting): bool
{
return in_array(
$this->context->getData($setting),
[
Context::METADATA_REQUEST,
Context::METADATA_REQUIRE
]
);
}
/**
* Changes the tooltips for the metadata fields to
* descriptions.
*
* Because authors are more likely to be encountering the metadata
* for the first time.
*/
protected function changeTooltipsToDescriptions(): void
{
foreach ($this->fields as $field) {
$field->description = $field->tooltip;
$field->tooltip = null;
}
}
/**
* Change the metadata fields to required when the
* author must provide them before submitting
*/
protected function setRequiredMetadata(): void
{
foreach ($this->fields as $field) {
$field->isRequired = $this->context->getData($field->name) === Context::METADATA_REQUIRE;
}
}
protected function addCategoryField(Context $context, LazyCollection $categories): void
{
if (!$context->getData('submitWithCategories') || !$categories->count()) {
return;
}
$categoryOptions = [];
$categoryOptions = Repo::category()
->getBreadcrumbs($categories)
->map(fn ($breadcrumb, $id) => [
'value' => $id,
'label' => $breadcrumb
])
->values()
->all();
$categoryValues = (array) $this->publication->getData('categoryIds');
if (count($categoryOptions) > self::MAX_CATEGORY_LIST_SIZE) {
$this->addField(new FieldAutosuggestPreset('categoryIds', [
'label' => __('submission.submit.placement.categories'),
'description' => __('submission.wizard.categories.description'),
'value' => $categoryValues,
'options' => $categoryOptions
]));
} else {
$this->addField(new FieldOptions('categoryIds', [
'label' => __('submission.submit.placement.categories'),
'description' => __('submission.wizard.categories.description'),
'value' => $categoryValues,
'options' => $categoryOptions,
]));
}
}
}
@@ -0,0 +1,54 @@
<?php
/**
* @file classes/components/form/context/PKPSubmissionFileForm.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 PKPSubmissionFileForm
*
* @ingroup classes_controllers_form
*
* @brief A preset form for editing a submission file
*/
namespace PKP\components\forms\submission;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
define('FORM_SUBMISSION_FILE', 'submissionFile');
class PKPSubmissionFileForm extends FormComponent
{
/** @copydoc FormComponent::$id */
public $id = FORM_SUBMISSION_FILE;
/** @copydoc FormComponent::$method */
public $method = 'PUT';
/**
* Constructor
*
* @param string $action URL to submit the form to
* @param array $genres List of genres to use as options
*/
public function __construct($action, $genres)
{
$this->action = $action;
$this->addField(new FieldOptions('genreId', [
'label' => __('submission.submit.genre.label'),
'description' => __('submission.submit.genre.description'),
'type' => 'radio',
'options' => array_map(function ($genre) {
return [
'value' => (int) $genre->getId(),
'label' => htmlspecialchars($genre->getLocalizedName()),
];
}, $genres),
'value' => 0,
]));
}
}
@@ -0,0 +1,64 @@
<?php
/**
* @file classes/components/form/submission/ReconfigureSubmission.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 ReconfigureSubmission
*
* @ingroup classes_controllers_form
*
* @brief A preset form for configuring the submission wizard, such as the
* submission's section or language, after the submission was started.
*/
namespace PKP\components\forms\submission;
use APP\publication\Publication;
use APP\submission\Submission;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
abstract class ReconfigureSubmission extends FormComponent
{
public $id = 'reconfigureSubmission';
public $method = 'PUT';
public Submission $submission;
public Publication $publication;
public Context $context;
public function __construct(string $action, Submission $submission, Publication $publication, Context $context)
{
$this->action = $action;
$this->context = $context;
$this->publication = $publication;
$this->submission = $submission;
$locales = $context->getSupportedSubmissionLocaleNames();
if (count($locales) > 1) {
$this->addLocaleField($locales);
}
}
protected function addLocaleField(array $locales): void
{
$options = [];
foreach ($locales as $locale => $name) {
$options[] = [
'value' => $locale,
'label' => $name,
];
}
$this->addField(new FieldOptions('locale', [
'label' => __('submission.submit.submissionLocale'),
'description' => __('submission.submit.submissionLocaleDescription'),
'type' => 'radio',
'options' => $options,
'isRequired' => true,
'value' => $this->submission->getData('locale'),
]));
}
}
@@ -0,0 +1,221 @@
<?php
/**
* @file classes/components/form/submission/StartSubmission.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 StartSubmission
*
* @ingroup classes_controllers_form
*
* @brief The form to begin the submission wizard
*/
namespace PKP\components\forms\submission;
use APP\core\Application;
use Illuminate\Support\Enumerable;
use PKP\components\forms\FieldHTML;
use PKP\components\forms\FieldOptions;
use PKP\components\forms\FieldRichText;
use PKP\components\forms\FormComponent;
use PKP\config\Config;
use PKP\context\Context;
use PKP\security\Role;
use PKP\userGroup\UserGroup;
class StartSubmission extends FormComponent
{
/** @var string id for the form's group and page configuration */
public const GROUP = 'default';
public $id = 'startSubmission';
public $method = 'POST';
public Context $context;
public Enumerable $userGroups;
/**
* @param Enumerable<UserGroup> $userGroups The user groups this user can submit as in this context
*/
public function __construct(string $action, Context $context, Enumerable $userGroups)
{
$this->action = $action;
$this->context = $context;
$this->userGroups = $userGroups;
$this->addIntroduction($context);
$this->addLanguage($context);
$this->addTitle();
$this->addSubmissionChecklist($context);
$this->addUserGroups($userGroups);
$this->addPrivacyConsent($context);
}
/**
* Add a custom button to the form and modify all
* fields as required
*/
public function getConfig()
{
$this->addPage([
'id' => self::GROUP,
'submitButton' => [
'label' => __('submission.wizard.start'),
'isPrimary' => true,
]
])
->addGroup([
'id' => self::GROUP,
'pageId' => self::GROUP,
]);
foreach ($this->fields as $field) {
$field->groupId = self::GROUP;
}
return parent::getConfig();
}
protected function addTitle(): void
{
$this->addField(new FieldRichText('title', [
'label' => __('common.title'),
'size' => 'oneline',
'isRequired' => true,
'value' => '',
]));
}
protected function addIntroduction(Context $context): void
{
if (!$context->getLocalizedData('beginSubmissionHelp')) {
return;
}
$this->addField(new FieldHTML('introduction', [
'label' => __('submission.wizard.beforeStart'),
'description' => $context->getLocalizedData('beginSubmissionHelp'),
]));
}
protected function addLanguage(Context $context): void
{
$languages = $context->getSupportedSubmissionLocaleNames();
if (count($languages) < 2) {
return;
}
$options = [];
foreach ($languages as $locale => $name) {
$options[] = [
'value' => $locale,
'label' => $name,
];
}
$this->addField(new FieldOptions('locale', [
'label' => __('submission.submit.submissionLocale'),
'description' => __('submission.submit.submissionLocaleDescription'),
'type' => 'radio',
'options' => $options,
'value' => '',
'isRequired' => true,
]));
}
protected function addSubmissionChecklist(Context $context): void
{
if (!$context->getLocalizedData('submissionChecklist')) {
return;
}
$this->addField(new FieldOptions('submissionRequirements', [
'label' => __('submission.submit.submissionChecklist'),
'description' => $context->getLocalizedData('submissionChecklist'),
'options' => [
[
'value' => true,
'label' => __('submission.submit.submissionChecklistConfirm'),
],
],
'value' => false,
'isRequired' => true,
]));
}
/**
* Allow the user to select which user group to submit as
*
* This field is only shown when the user can submit in more
* than one group.
*/
protected function addUserGroups(Enumerable $userGroups): void
{
if ($userGroups->count() < 2) {
return;
}
$options = $userGroups->map(fn (UserGroup $userGroup) => [
'value' => $userGroup->getId(),
'label' => $userGroup->getLocalizedName(),
]);
$hasEditorialRole = $userGroups->contains(
fn (UserGroup $userGroup) => in_array($userGroup->getRoleId(), [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SITE_ADMIN])
);
$description = __('submission.submit.availableUserGroupsDescription');
if ($hasEditorialRole) {
$description .= ' ' . __('submission.submit.managerUserGroupsDescription');
}
$this->addField(new FieldOptions('userGroupId', [
'label' => __('submission.submit.availableUserGroups'),
'description' => $description,
'type' => 'radio',
'options' => $options->values()->toArray(),
'value' => $options->first()['value'],
'isRequired' => true,
]));
}
protected function addPrivacyConsent(Context $context): void
{
$privacyStatement = Config::getVar('general', 'sitewide_privacy_statement')
? Application::get()
->getRequest()
->getSite()
->getData('privacyStatement')
: $context->getData('privacyStatement');
if (!$privacyStatement) {
return;
}
$privacyUrl = Application::get()
->getRequest()
->getDispatcher()
->url(
Application::get()->getRequest(),
Application::ROUTE_PAGE,
null,
'about',
'privacy'
);
$this->addField(new FieldOptions('privacyConsent', [
'label' => __('submission.wizard.privacyConsent'),
'options' => [
[
'value' => true,
'label' => __('user.register.form.privacyConsent', [
'privacyUrl' => $privacyUrl,
]),
],
],
'value' => false,
'isRequired' => true,
]));
}
}
@@ -0,0 +1,118 @@
<?php
/**
* @file classes/components/form/submission/SubmissionGuidanceSettings.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 SubmissionGuidanceSettings
*
* @ingroup classes_controllers_form
*
* @brief A form for the submission wizard instruction settings.
*/
namespace PKP\components\forms\submission;
use APP\core\Application;
use PKP\components\forms\FieldRichTextarea;
use PKP\components\forms\FormComponent;
use PKP\context\Context;
define('FORM_METADATA', 'metadata');
class SubmissionGuidanceSettings extends FormComponent
{
public $id = 'submissionGuidanceSettings';
public $method = 'PUT';
public Context $context;
public function __construct(string $action, array $locales, Context $context)
{
$this->action = $action;
$this->locales = $locales;
$this->context = $context;
$submissionUrl = Application::get()->getRequest()->getDispatcher()->url(
Application::get()->getRequest(),
Application::ROUTE_PAGE,
$context->getPath(),
'about',
'submissions'
);
$this->addField(new FieldRichTextarea('authorGuidelines', [
'label' => __('manager.setup.authorGuidelines'),
'description' => __('manager.setup.authorGuidelines.description', ['url' => $submissionUrl]),
'isMultilingual' => true,
'value' => $context->getData('authorGuidelines'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('beginSubmissionHelp', [
'label' => __('submission.wizard.beforeStart'),
'description' => __('manager.setup.workflow.beginSubmissionHelp.description'),
'isMultilingual' => true,
'value' => $context->getData('beginSubmissionHelp'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('submissionChecklist', [
'label' => __('manager.setup.submissionPreparationChecklist'),
'description' => __('manager.setup.submissionPreparationChecklistDescription'),
'isMultilingual' => true,
'value' => $context->getData('submissionChecklist'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('uploadFilesHelp', [
'label' => __('submission.upload.uploadFiles'),
'description' => __('manager.setup.workflow.uploadFilesHelp.description'),
'isMultilingual' => true,
'value' => $context->getData('uploadFilesHelp'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('contributorsHelp', [
'label' => __('publication.contributors'),
'description' => __('manager.setup.workflow.contributorsHelp.description'),
'isMultilingual' => true,
'value' => $context->getData('contributorsHelp'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('detailsHelp', [
'label' => __('common.details'),
'description' => __('manager.setup.workflow.detailsHelp.description'),
'isMultilingual' => true,
'value' => $context->getData('detailsHelp'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('forTheEditorsHelp', [
'label' => __('submission.forTheEditors'),
'description' => __('manager.setup.workflow.forTheEditorsHelp.description'),
'isMultilingual' => true,
'value' => $context->getData('forTheEditorsHelp'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('reviewHelp', [
'label' => __('submission.reviewAndSubmit'),
'description' => __('manager.setup.workflow.reviewHelp.description'),
'isMultilingual' => true,
'value' => $context->getData('reviewHelp'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))
->addField(new FieldRichTextarea('copyrightNotice', [
'label' => __('manager.setup.copyrightNotice'),
'description' => __('manager.setup.copyrightNotice.description', ['url' => $submissionUrl]),
'isMultilingual' => true,
'value' => $context->getData('copyrightNotice'),
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]));
}
}
@@ -0,0 +1,140 @@
<?php
/**
* @file classes/components/listPanels/ContributorsListPanel.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 ContributorsListPanel
*
* @ingroup classes_components_list
*
* @brief A ListPanel component for viewing and editing contributors
*/
namespace PKP\components\listPanels;
use APP\core\Application;
use APP\submission\Submission;
use PKP\components\forms\publication\ContributorForm;
use PKP\context\Context;
class ContributorsListPanel extends ListPanel
{
public Submission $submission;
public Context $context;
public array $locales;
/** Whether the user can edit the current publication */
public bool $canEditPublication;
public function __construct(
string $id,
string $title,
Submission $submission,
Context $context,
array $locales,
array $items = [],
bool $canEditPublication = false
) {
parent::__construct($id, $title);
$this->submission = $submission;
$this->context = $context;
$this->locales = $locales;
$this->items = $items;
$this->canEditPublication = $canEditPublication;
}
/**
* @copydoc ListPanel::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
// Remove some props not used in this list panel
unset($config['description']);
unset($config['expanded']);
unset($config['headingLevel']);
$config = array_merge(
$config,
[
'canEditPublication' => $this->canEditPublication,
'publicationApiUrlFormat' => $this->getPublicationUrlFormat(),
'form' => $this->getLocalizedForm(),
'items' => $this->items,
'i18nAddContributor' => __('grid.action.addContributor'),
'i18nConfirmDelete' => __('grid.action.deleteContributor.confirmationMessage'),
'i18nDeleteContributor' => __('grid.action.deleteContributor'),
'i18nEditContributor' => __('grid.action.edit'),
'i18nSetPrimaryContact' => __('author.users.contributor.setPrincipalContact'),
'i18nPrimaryContact' => __('author.users.contributor.principalContact'),
'i18nContributors' => __('submission.contributors'),
'i18nSaveOrder' => __('grid.action.saveOrdering'),
'i18nPreview' => __('contributor.listPanel.preview'),
'i18nPreviewDescription' => __('contributor.listPanel.preview.description'),
'i18nDisplay' => __('contributor.listPanel.preview.display'),
'i18nFormat' => __('contributor.listPanel.preview.format'),
'i18nAbbreviated' => __('contributor.listPanel.preview.abbreviated'),
'i18nPublicationLists' => __('contributor.listPanel.preview.publicationLists'),
'i18nFull' => __('contributor.listPanel.preview.full'),
]
);
return $config;
}
/**
* Get an example of the url to a publication's API endpoint,
* with a placeholder instead of the publication id, eg:
*
* http://example.org/api/v1/submissions/1/publications/__publicationId__
*/
protected function getPublicationUrlFormat(): string
{
return Application::get()->getRequest()->getDispatcher()->url(
Application::get()->getRequest(),
Application::ROUTE_API,
$this->context->getPath(),
'submissions/' . $this->submission->getId() . '/publications/__publicationId__'
);
}
/**
* Get the form data localized to the submission's locale
*/
protected function getLocalizedForm(): array
{
uksort($this->locales, fn ($a, $b) => $a === $this->submission->getData('locale') ? -1 : 1);
$apiUrl = Application::get()->getRequest()->getDispatcher()->url(
Application::get()->getRequest(),
Application::ROUTE_API,
$this->context->getPath(),
'submissions/' . $this->submission->getId() . '/publications/__publicationId__/contributors'
);
$form = $this->getForm($apiUrl);
$data = $form->getConfig();
$data['primaryLocale'] = $this->submission->getData('locale');
$data['visibleLocales'] = [$this->submission->getData('locale')];
return $data;
}
/**
* Get the contributor form
*/
protected function getForm(string $url): ContributorForm
{
return new ContributorForm(
$url,
$this->locales,
$this->submission,
$this->context
);
}
}
@@ -0,0 +1,53 @@
<?php
/**
* @file classes/components/listPanels/HighlightsListPanel.php
*
* Copyright (c) 2023 Simon Fraser University
* Copyright (c) 2023 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class HighlightsListPanel
*
* @ingroup classes_components_list
*
* @brief A ListPanel component for viewing and editing institutions
*/
namespace PKP\components\listPanels;
use PKP\components\forms\highlight\HighlightForm;
class HighlightsListPanel extends ListPanel
{
/** URL to the API endpoint where items can be retrieved */
public string $apiUrl = '';
/** Form for adding or editing a highlight */
public ?HighlightForm $form = null;
/** Query parameters to pass if this list executes GET requests */
public array $getParams = [];
/** Max number of items available to display in this list panel */
public int $itemsMax = 0;
public function getConfig(): array
{
$config = parent::getConfig();
$config = array_merge(
$config,
[
'apiUrl' => $this->apiUrl,
'form' => $this->form?->getConfig(),
'getParams' => $this->getParams,
'i18nAdd' => __('manager.highlights.add'),
'i18nConfirmDelete' => __('manager.highlights.confirmDelete'),
'i18nDelete' => __('manager.highlights.delete'),
'i18nEdit' => __('manager.highlights.edit'),
'i18nSaveOrder' => __('grid.action.saveOrdering'),
'itemsMax' => $this->itemsMax
]
);
return $config;
}
}
@@ -0,0 +1,103 @@
<?php
/**
* @file components/listPanels/ListPanel.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 ListPanel
*
* @ingroup classes_components_list
*
* @brief A base class for ListPanel components.
*/
namespace PKP\components\listPanels;
class ListPanel
{
/** @var string An optional description to add beneath the title */
public $description = '';
/** @var string An optional message to display when no items are in the list */
public $emptyLabel = '';
/** @var array Array of item ids that should be expanded on initial load */
public $expanded = [];
/** @var string The appropriate heading level for this component */
public $headingLevel = 'h2';
/** @var bool Should the sidebar be visible on initial load? */
public $isSidebarVisible = false;
/** @var string An ID for this component */
public $id = '';
/** @var array Items to display in the list */
public $items = [];
/** @var string Title (expects a translation key) */
public $title = '';
/**
* Initialize the form with config parameters
*
* @param string $id
* @param string $title
* @param array $args Configuration params
*/
public function __construct($id, $title, $args = [])
{
$this->id = $id;
$this->title = $title;
$this->set($args);
}
/**
* Set configuration data for the component
*
* @param array $args Configuration params
*
*/
public function set($args)
{
foreach ($args as $prop => $value) {
if (property_exists($this, $prop)) {
$this->{$prop} = $value;
}
}
return $this;
}
/**
* Convert the object into an assoc array ready to be json_encoded
* and passed to the UI component
*
* @return array Configuration data
*/
public function getConfig()
{
$config = [
'description' => $this->description,
'expanded' => $this->expanded,
'headingLevel' => $this->headingLevel,
'id' => $this->id,
'isSidebarVisible' => $this->isSidebarVisible,
'items' => $this->items,
'title' => $this->title,
];
if (strlen($this->emptyLabel)) {
$config['emptyLabel'] = $this->emptyLabel;
}
if (!empty($this->getParams)) {
$config['getParams'] = $this->getParams;
}
return $config;
}
}
@@ -0,0 +1,51 @@
<?php
/**
* @file classes/components/listPanels/PKPAnnouncementsListPanel.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 PKPAnnouncementsListPanel
*
* @ingroup classes_components_list
*
* @brief A ListPanel component for viewing and editing email templates
*/
namespace PKP\components\listPanels;
class PKPAnnouncementsListPanel extends ListPanel
{
/** @var string URL to the API endpoint where items can be retrieved */
public $apiUrl = '';
/** @var int How many items to display on one page in this list */
public $count = 30;
/** @param \PKP\components\forms\announcement\PKPAnnouncementForm Form for adding or editing an email template */
public $form = null;
/** @var array Query parameters to pass if this list executes GET requests */
public $getParams = [];
/** @var int Max number of items available to display in this list panel */
public $itemsMax = 0;
/**
* @copydoc ListPanel::getConfig()
*/
public function getConfig()
{
return parent::getConfig() + [
'addAnnouncementLabel' => __('grid.action.addAnnouncement'),
'apiUrl' => $this->apiUrl,
'confirmDeleteMessage' => __('manager.announcements.confirmDelete'),
'count' => $this->count,
'deleteAnnouncementLabel' => __('manager.announcements.deleteAnnouncement'),
'editAnnouncementLabel' => __('manager.announcements.edit'),
'form' => $this->form->getConfig(),
'itemsMax' => $this->itemsMax,
];
}
}
@@ -0,0 +1,53 @@
<?php
/**
* @file classes/components/listPanels/PKPCounterReportsListPanel.php
*
* Copyright (c) 2024 Simon Fraser University
* Copyright (c) 2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPCounterReportsListPanel
*
* @ingroup classes_components_list
*
* @brief A ListPanel component for viewing, editing and downloading COUNTER R5 reports
*/
namespace PKP\components\listPanels;
use APP\components\forms\counter\CounterReportForm;
use PKP\sushi\CounterR5Report;
class PKPCounterReportsListPanel extends ListPanel
{
/** URL to the API endpoint where items can be retrieved */
public string $apiUrl = '';
/** Form for setting up and downloading a report*/
public ?CounterReportForm $form = null;
/** Query parameters to pass if this list executes GET requests */
public array $getParams = [];
/**
* @copydoc ListPanel::getConfig()
*/
public function getConfig(): array
{
$config = parent::getConfig();
$earliestDate = CounterR5Report::getEarliestDate();
$lastDate = CounterR5Report::getLastDate();
$config = array_merge(
$config,
[
'apiUrl' => $this->apiUrl,
'editCounterReportLabel' => __('manager.statistics.counterR5Report.settings'),
'form' => $this->form->getConfig(),
'usagePossible' => $lastDate > $earliestDate,
]
);
return $config;
}
}
@@ -0,0 +1,225 @@
<?php
/**
* @file classes/components/listPanels/PKPDoiListPanel.php
*
* Copyright (c) 2014-2020 Simon Fraser University
* Copyright (c) 2000-2020 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPDoiListPanel
*
* @ingroup classes_components_list
*
* @brief A ListPanel component for viewing and editing DOIs
*/
namespace PKP\components\listPanels;
use APP\core\Application;
use APP\template\TemplateManager;
use PKP\doi\Doi;
use PKP\plugins\Hook;
use PKP\submission\PKPSubmission;
abstract class PKPDoiListPanel extends ListPanel
{
/** @var string URL to the API endpoint where items can be retrieved */
public $apiUrl = '';
/** @var int How many items to display on one page in this list */
public $count = 30;
/** @var array Query parameters to pass if this list executes GET requests */
public $getParams = [];
/** @var int Max number of items available to display in this list panel */
public $itemsMax = 0;
/** @var boolean Should items be loaded after the component is mounted? */
public $lazyLoad = false;
/** @var string DOI prefix set in DOI settings */
public $doiPrefix = '';
public ?\stdClass $registrationAgencyInfo = null;
/** @var array Which publishing objects have DOIs enabled */
public array $enabledDoiTypes = [];
/** @var bool Whether to include a DOI per publication version */
public bool $versionDois = false;
/** @var string DOI API url for handling DOI operations */
public $doiApiUrl = '';
/** @var string PubObject type, e.g. 'submission' */
public string $itemType = '';
/**
* Convert the object into an assoc array ready to be json_encoded
* and passed to the UI component
*
* @return array Configuration data
*/
public function getConfig()
{
$config = parent::getConfig();
$config['apiUrl'] = $this->apiUrl;
$config['doiApiUrl'] = $this->doiApiUrl;
$config['count'] = $this->count;
$config['lazyLoad'] = $this->lazyLoad;
$config['itemsMax'] = $this->itemsMax;
$config['itemType'] = $this->itemType;
$config['enabledDoiTypes'] = $this->enabledDoiTypes;
$config['versionDois'] = $this->versionDois;
$config['registrationAgencyInfo'] = $this->registrationAgencyInfo;
$config['doiPrefix'] = $this->doiPrefix;
$config['filters'][] = [
'heading' => __('common.status'),
'filters' => [
[
'title' => __('manager.dois.status.needsDoi'),
'param' => 'hasDois',
'value' => '0'
],
[
'title' => __('manager.dois.filters.doiAssigned'),
'param' => 'hasDois',
'value' => '1',
],
],
];
$config['filters'][] = [
'heading' => __('manager.setup.dois.registration'),
'filters' => [
[
'title' => __('manager.dois.status.unregistered'),
'param' => 'unregistered',
'value' => 'true'
],
[
'title' => __('manager.dois.status.submitted'),
'param' => 'doiStatus',
'value' => Doi::STATUS_SUBMITTED
],
[
'title' => __('manager.dois.status.registered'),
'param' => 'doiStatus',
'value' => Doi::STATUS_REGISTERED
],
[
'title' => __('manager.dois.status.error.filterTitle'),
'param' => 'doiStatus',
'value' => Doi::STATUS_ERROR
],
[
'title' => __('manager.dois.status.stale'),
'param' => 'doiStatus',
'value' => Doi::STATUS_STALE
],
],
];
$config['publishedStatuses'] = [
'name' => 'status',
'published' => [PKPSubmission::STATUS_PUBLISHED],
'unpublished' => [PKPSubmission::STATUS_QUEUED, PKPSubmission::STATUS_SCHEDULED],
];
// Provide required locale keys
$request = Application::get()->getRequest();
$templateMgr = TemplateManager::getManager($request);
$templateMgr->setConstants([
'DOI_STATUS_SUBMITTED' => Doi::STATUS_SUBMITTED,
'DOI_STATUS_UNREGISTERED' => Doi::STATUS_UNREGISTERED,
'DOI_STATUS_REGISTERED' => Doi::STATUS_REGISTERED,
'DOI_STATUS_ERROR' => Doi::STATUS_ERROR,
'DOI_STATUS_STALE' => Doi::STATUS_STALE,
]);
$templateMgr->setLocaleKeys([
'publication.status.unpublished',
'publication.status.published',
'manager.dois.actions.deposit.label',
'manager.dois.actions.deposit.prompt',
'manager.dois.actions.markRegistered.label',
'manager.dois.actions.markRegistered.prompt',
'manager.dois.actions.markUnregistered.label',
'manager.dois.actions.markUnregistered.prompt',
'manager.dois.actions.markStale.label',
'manager.dois.actions.markStale.prompt',
'manager.dois.actions.export.label',
'manager.dois.actions.export.prompt',
'manager.dois.actions.assign.label',
'manager.dois.actions.assign.prompt',
'manager.dois.notification.exportSuccess',
'manager.dois.notification.markRegisteredSuccess',
'manager.dois.notification.markUnregisteredSuccess',
'manager.dois.notification.markStaleSuccess',
'manager.dois.registration.submittedDescription',
'manager.dois.registration.notSubmittedDescription',
'manager.dois.registration.viewError',
'manager.dois.registration.viewError.title',
'manager.dois.registration.viewRecord',
'manager.dois.registration.viewRecord.title',
'manager.dois.publicationStatus',
'manager.dois.registration.depositDois',
'manager.dois.status.needsDoi',
'manager.dois.status.unregistered',
'manager.dois.status.submitted',
'manager.dois.status.registered',
'manager.dois.status.error',
'manager.dois.status.stale',
'manager.dois.notification.assignDoisSuccess',
'manager.dois.notification.depositQueuedSuccess',
'manager.dois.actions.depositAll.label',
'manager.dois.actions.depositAll.prompt',
'manager.dois.registration.notPublishedDescription',
'manager.dois.update.partialFailure',
'manager.dois.actions.deposit.all',
'manager.dois.update.success',
'common.selectAll',
'common.selectNone',
'common.edit',
'common.save',
'common.type',
'common.status',
'common.description',
'list.expandAll',
'list.collapseAll',
'manager.dois.update.failedCreation',
'plugins.importexport.common.action.export',
'manager.dois.actions.description',
'manager.dois.title',
'manager.dois.actions.bulkActions',
'publication.version',
'doi.manager.versions.countStatement',
'doi.manager.versions.view',
'doi.manager.versions.modalTitle',
'manager.dois.help.statuses.title',
'manager.dois.status.needsDoi.description',
'manager.dois.status.unregistered.description',
'manager.dois.status.submitted.description',
'manager.dois.status.registered.description',
'manager.dois.status.error.description',
'manager.dois.status.stale.description',
'manager.dois.registration.manuallyMarkedRegistered',
'manager.dois.filters.doiAssigned',
'manager.dois.filters.doiAssigned.description',
'manager.dois.status.error.filterTitle',
]);
$this->setAppConfig($config);
Hook::call('DoiListPanel::setConfig', [&$config]);
// Check added here in case hook adds additional getParams
$config['getParams'] = empty($config['getParams']) ? new \stdClass() : $config['getParams'];
return $config;
}
/**
* Add any application-specific config to the list panel setup
*/
abstract protected function setAppConfig(array &$config): void;
}
@@ -0,0 +1,58 @@
<?php
/**
* @file classes/components/listPanels/PKPInstitutionsListPanel.php
*
* Copyright (c) 2022 Simon Fraser University
* Copyright (c) 2022 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class PKPInstitutionsListPanel
*
* @ingroup classes_components_list
*
* @brief A ListPanel component for viewing and editing institutions
*/
namespace PKP\components\listPanels;
use PKP\components\forms\institution\PKPInstitutionForm;
class PKPInstitutionsListPanel extends ListPanel
{
/** URL to the API endpoint where items can be retrieved */
public string $apiUrl = '';
/** How many items to display on one page in this list */
public int $count = 30;
/** Form for adding or editing an institution */
public ?PKPInstitutionForm $form = null;
/**Query parameters to pass if this list executes GET requests */
public array $getParams = [];
/** Max number of items available to display in this list panel */
public int $itemsMax = 0;
/**
* @copydoc ListPanel::getConfig()
*/
public function getConfig(): array
{
$config = parent::getConfig();
$config = array_merge(
$config,
[
'addInstitutionLabel' => __('grid.action.addInstitution'),
'apiUrl' => $this->apiUrl,
'confirmDeleteMessage' => __('manager.institutions.confirmDelete'),
'count' => $this->count,
'deleteInstitutionLabel' => __('manager.institutions.deleteInstitution'),
'editInstitutionLabel' => __('manager.institutions.edit'),
'form' => $this->form->getConfig(),
'itemsMax' => $this->itemsMax
]
);
return $config;
}
}
@@ -0,0 +1,201 @@
<?php
/**
* @file components/listPanels/PKPSelectReviewerListPanel.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 PKPSelectReviewerListPanel
*
* @ingroup classes_controllers_list
*
* @brief A class for loading a panel to select a reviewer.
*/
namespace PKP\components\listPanels;
use APP\facades\Repo;
use Illuminate\Support\Enumerable;
use PKP\user\Collector;
class PKPSelectReviewerListPanel extends ListPanel
{
/** @var string URL to the API endpoint where items can be retrieved */
public $apiUrl = '';
/** @var int Number of items to show at one time */
public $count = 30;
/** @var array List of user IDs already assigned as a reviewer to this review round */
public $currentlyAssigned = [];
/** @var array Query parameters to pass if this list executes GET requests */
public $getParams = [];
/** @var int Count of total items available for list */
public $itemsMax = 0;
/** @var string Name of the input field*/
public $selectorName = '';
/** @var array List of user IDs which may not be suitable for anonymous review because of existing access to author details */
public $warnOnAssignment = [];
/** @var Enumerable List of users who completed a review in the last round */
public Enumerable $lastRoundReviewers;
/**
* @copydoc ListPanel::set()
*/
public function set($args)
{
parent::set($args);
$this->currentlyAssigned = !empty($args['currentlyAssigned']) ? $args['currentlyAssigned'] : $this->currentlyAssigned;
$this->warnOnAssignment = !empty($args['warnOnAssignment']) ? $args['warnOnAssignment'] : $this->warnOnAssignment;
}
/**
* @copydoc ListPanel::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['apiUrl'] = $this->apiUrl;
$config['count'] = $this->count;
$config['currentlyAssigned'] = $this->currentlyAssigned;
$config['selectorName'] = $this->selectorName;
$config['warnOnAssignment'] = $this->warnOnAssignment;
$config['filters'] = [
[
'param' => 'reviewerRating',
'title' => __('reviewer.list.filterRating'),
'value' => 3,
'min' => 1,
'max' => 5,
'useStars' => true,
'valueLabel' => '{$value/5}',
],
[
'param' => 'reviewsCompleted',
'title' => __('reviewer.list.completedReviews'),
'value' => 10,
'min' => 0,
'max' => 20,
'valueLabel' => __('common.moreThan'),
],
[
'param' => 'daysSinceLastAssignment',
'title' => __('reviewer.list.daysSinceLastAssignmentDescription'),
'value' => [0, 365],
'min' => 0,
'max' => 365,
'filterType' => 'filter-slider-multirange',
'valueLabel' => __('common.range'),
'moreThanLabel' => __('common.moreThanOnly'),
'lessThanLabel' => __('common.lessThanOnly'),
],
[
'param' => 'reviewsActive',
'title' => __('reviewer.list.activeReviewsDescription'),
'value' => [0, 20],
'min' => 0,
'max' => 20,
'filterType' => 'filter-slider-multirange',
'valueLabel' => __('common.range'),
'moreThanLabel' => __('common.moreThanOnly'),
'lessThanLabel' => __('common.lessThanOnly'),
],
[
'param' => 'averageCompletion',
'title' => __('reviewer.list.averageCompletion'),
'value' => 75,
'min' => 0,
'max' => 75,
'valueLabel' => __('common.lessThan'),
],
];
if (!empty($this->lastRoundReviewers)) {
$config['lastRoundReviewers'] = Repo::user()
->getSchemaMap()
->summarizeManyReviewers($this->lastRoundReviewers)
->values()
->toArray();
}
if (!empty($this->getParams)) {
$config['getParams'] = $this->getParams;
}
$config['itemsMax'] = $this->itemsMax;
$config['activeReviewsCountLabel'] = __('reviewer.list.activeReviews');
$config['activeReviewsLabel'] = __('reviewer.list.activeReviewsDescription');
$config['assignedToLastRoundLabel'] = __('reviewer.list.assignedToLastRound');
$config['averageCompletionLabel'] = __('reviewer.list.averageCompletion');
$config['biographyLabel'] = __('reviewer.list.biography');
$config['cancelledReviewsLabel'] = __('reviewer.list.cancelledReviews');
$config['completedReviewsLabel'] = __('reviewer.list.completedReviews');
$config['currentlyAssignedLabel'] = __('reviewer.list.currentlyAssigned');
$config['daySinceLastAssignmentLabel'] = __('reviewer.list.daySinceLastAssignment');
$config['daysSinceLastAssignmentLabel'] = __('reviewer.list.daysSinceLastAssignment');
$config['daysSinceLastAssignmentDescriptionLabel'] = __('reviewer.list.daysSinceLastAssignmentDescription');
$config['declinedReviewsLabel'] = __('reviewer.list.declinedReviews');
$config['emptyLabel'] = __('reviewer.list.empty');
$config['gossipLabel'] = __('user.gossip');
$config['neverAssignedLabel'] = __('reviewer.list.neverAssigned');
$config['reassignLabel'] = __('reviewer.list.reassign');
$config['reassignWithNameLabel'] = __('reviewer.list.reassign.withName');
$config['reviewerRatingLabel'] = __('reviewer.list.reviewerRating');
$config['reviewInterestsLabel'] = __('reviewer.list.reviewInterests');
$config['selectReviewerLabel'] = __('editor.submission.selectReviewer');
$config['warnOnAssignmentLabel'] = __('reviewer.list.warnOnAssign');
$config['warnOnAssignmentUnlockLabel'] = __('reviewer.list.warnOnAssignUnlock');
return $config;
}
/**
* Helper method to get the items property according to the self::$getParams
*
* @param \APP\core\Request $request
*
* @return array
*/
public function getItems($request)
{
$reviewers = $this->_getCollector()->getMany();
$items = [];
$map = Repo::user()->getSchemaMap();
foreach ($reviewers as $reviewer) {
$items[] = $map->summarizeReviewer($reviewer);
}
return $items;
}
/**
* Helper method to get the itemsMax property according to self::$getParams
*
* @return int
*/
public function getItemsMax()
{
return $this->_getCollector()->offset(null)->limit(null)->getCount();
}
/**
* Helper method to compile initial params to get items
*/
protected function _getCollector(): Collector
{
return Repo::user()->getCollector()
->filterByContextIds([$this->getParams['contextId']])
->filterByWorkflowStageIds([$this->getParams['reviewStage']])
->filterByRoleIds([\PKP\security\Role::ROLE_ID_REVIEWER])
->includeReviewerData()
->offset(null)
->limit($this->count);
}
}
@@ -0,0 +1,288 @@
<?php
/**
* @file components/listPanels/PKPSubmissionsListPanel.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 PKPSubmissionsListPanel
*
* @ingroup classes_components_list
*
* @brief A ListPanel component for displaying submissions in the dashboard
*/
namespace PKP\components\listPanels;
use APP\core\Application;
use APP\facades\Repo;
use APP\template\TemplateManager;
use PKP\components\forms\FieldAutosuggestPreset;
use PKP\components\forms\FieldSelectUsers;
use PKP\security\Role;
use PKP\submission\PKPSubmission;
use PKP\submission\reviewAssignment\ReviewAssignment;
use PKP\submission\reviewRound\ReviewRound;
abstract class PKPSubmissionsListPanel extends ListPanel
{
/** @var string URL to the API endpoint where items can be retrieved */
public $apiUrl = '';
/** @var int Number of items to show at one time */
public $count = 30;
/** @var array Query parameters to pass if this list executes GET requests */
public $getParams = [];
/** @var bool Should items be loaded after the component is mounted? */
public $lazyLoad = false;
/** @var int Count of total items available for list */
public $itemsMax = 0;
/** @var bool Whether to show assigned to editors filter */
public $includeAssignedEditorsFilter = false;
/** @var bool Whether to show categories filter */
public $includeCategoriesFilter = false;
/** @var array List of all available categories */
public $categories = [];
/**
* @copydoc ListPanel::getConfig()
*/
public function getConfig()
{
$request = Application::get()->getRequest();
$context = $request->getContext();
$config = parent::getConfig();
$config['apiUrl'] = $this->apiUrl;
$config['count'] = $this->count;
$config['getParams'] = $this->getParams;
$config['lazyLoad'] = $this->lazyLoad;
$config['itemsMax'] = $this->itemsMax;
// URL to add a new submission
if ($context->getData('disableSubmissions')) {
$config['allowSubmissions'] = false;
}
$config['addUrl'] = $request->getDispatcher()->url(
$request,
Application::ROUTE_PAGE,
null,
'submission'
);
// URL to view info center for a submission
$config['infoUrl'] = $request->getDispatcher()->url(
$request,
Application::ROUTE_COMPONENT,
null,
'informationCenter.SubmissionInformationCenterHandler',
'viewInformationCenter',
null,
['submissionId' => '__id__']
);
// URL to assign a participant
$config['assignParticipantUrl'] = $request->getDispatcher()->url(
$request,
Application::ROUTE_COMPONENT,
null,
'grid.users.stageParticipant.StageParticipantGridHandler',
'addParticipant',
null,
['submissionId' => '__id__', 'stageId' => '__stageId__']
);
$config['filters'] = [
[
'filters' => [
[
'param' => 'isOverdue',
'value' => true,
'title' => __('common.overdue'),
],
[
'param' => 'isIncomplete',
'value' => true,
'title' => __('submissions.incomplete'),
],
],
],
[
'heading' => __('settings.roles.stages'),
'filters' => $this->getWorkflowStages(),
],
[
'heading' => __('submission.list.activity'),
'filters' => [
[
'title' => __('submission.list.daysSinceLastActivity'),
'param' => 'daysInactive',
'value' => 30,
'min' => 1,
'max' => 180,
'filterType' => 'pkp-filter-slider',
]
]
]
];
if ($this->includeCategoriesFilter) {
$categoryFilter = [];
$categoryFilter = $this->getCategoryFilters($this->categories);
if ($categoryFilter) {
$config['filters'][] = $categoryFilter;
}
}
if ($this->includeAssignedEditorsFilter) {
$assignedEditorsField = new FieldSelectUsers('assignedTo', [
'label' => __('editor.submissions.assignedTo'),
'value' => [],
'apiUrl' => $request->getDispatcher()->url(
$request,
Application::ROUTE_API,
$context->getPath(),
'users',
null,
null,
['roleIds' => [Role::ROLE_ID_MANAGER, Role::ROLE_ID_SUB_EDITOR]]
),
]);
$config['filters'][] = [
'filters' => [
[
'title' => __('editor.submissions.assignedTo'),
'param' => 'assignedTo',
'value' => [],
'filterType' => 'pkp-filter-autosuggest',
'component' => $assignedEditorsField->component,
'autosuggestProps' => $assignedEditorsField->getConfig(),
]
]
];
}
// Provide required constants
$templateMgr = TemplateManager::getManager($request);
$templateMgr->setConstants([
'STATUS_QUEUED' => PKPSubmission::STATUS_QUEUED,
'STATUS_PUBLISHED' => PKPSubmission::STATUS_PUBLISHED,
'STATUS_DECLINED' => PKPSubmission::STATUS_DECLINED,
'STATUS_SCHEDULED' => PKPSubmission::STATUS_SCHEDULED,
'WORKFLOW_STAGE_ID_SUBMISSION' => WORKFLOW_STAGE_ID_SUBMISSION,
'WORKFLOW_STAGE_ID_INTERNAL_REVIEW' => WORKFLOW_STAGE_ID_INTERNAL_REVIEW,
'WORKFLOW_STAGE_ID_EXTERNAL_REVIEW' => WORKFLOW_STAGE_ID_EXTERNAL_REVIEW,
'WORKFLOW_STAGE_ID_EDITING' => WORKFLOW_STAGE_ID_EDITING,
'WORKFLOW_STAGE_ID_PRODUCTION' => WORKFLOW_STAGE_ID_PRODUCTION,
'STAGE_STATUS_SUBMISSION_UNASSIGNED' => Repo::submission()::STAGE_STATUS_SUBMISSION_UNASSIGNED,
'REVIEW_ROUND_STATUS_PENDING_REVIEWERS' => ReviewRound::REVIEW_ROUND_STATUS_PENDING_REVIEWERS,
'REVIEW_ROUND_STATUS_REVIEWS_READY' => ReviewRound::REVIEW_ROUND_STATUS_REVIEWS_READY,
'REVIEW_ROUND_STATUS_REVIEWS_COMPLETED' => ReviewRound::REVIEW_ROUND_STATUS_REVIEWS_COMPLETED,
'REVIEW_ROUND_STATUS_REVIEWS_OVERDUE' => ReviewRound::REVIEW_ROUND_STATUS_REVIEWS_OVERDUE,
'REVIEW_ROUND_STATUS_REVISIONS_REQUESTED' => ReviewRound::REVIEW_ROUND_STATUS_REVISIONS_REQUESTED,
'REVIEW_ROUND_STATUS_REVISIONS_SUBMITTED' => ReviewRound::REVIEW_ROUND_STATUS_REVISIONS_SUBMITTED,
'REVIEW_ROUND_STATUS_RESUBMIT_FOR_REVIEW' => ReviewRound::REVIEW_ROUND_STATUS_RESUBMIT_FOR_REVIEW,
'REVIEW_ROUND_STATUS_RESUBMIT_FOR_REVIEW_SUBMITTED' => ReviewRound::REVIEW_ROUND_STATUS_RESUBMIT_FOR_REVIEW_SUBMITTED,
'REVIEW_ASSIGNMENT_STATUS_AWAITING_RESPONSE' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_AWAITING_RESPONSE,
'REVIEW_ASSIGNMENT_STATUS_RESPONSE_OVERDUE' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_RESPONSE_OVERDUE,
'REVIEW_ASSIGNMENT_STATUS_REVIEW_OVERDUE' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_REVIEW_OVERDUE,
'REVIEW_ASSIGNMENT_STATUS_ACCEPTED' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_ACCEPTED,
'REVIEW_ASSIGNMENT_STATUS_RECEIVED' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_RECEIVED,
'REVIEW_ASSIGNMENT_STATUS_COMPLETE' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_COMPLETE,
'REVIEW_ASSIGNMENT_STATUS_THANKED' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_THANKED,
'REVIEW_ASSIGNMENT_STATUS_CANCELLED' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_CANCELLED,
'REVIEW_ASSIGNMENT_STATUS_REQUEST_RESEND' => ReviewAssignment::REVIEW_ASSIGNMENT_STATUS_REQUEST_RESEND,
'REVIEW_ROUND_STATUS_RECOMMENDATIONS_READY' => ReviewRound::REVIEW_ROUND_STATUS_RECOMMENDATIONS_READY,
'REVIEW_ROUND_STATUS_RECOMMENDATIONS_COMPLETED' => ReviewRound::REVIEW_ROUND_STATUS_RECOMMENDATIONS_COMPLETED,
]);
$templateMgr->setLocaleKeys([
'common.lastActivity',
'editor.submissionArchive.confirmDelete',
'submission.list.empty',
'submission.submit.newSubmissionSingle',
'submission.review',
'submissions.incomplete',
'submission.list.assignEditor',
'submission.list.copyeditsSubmitted',
'submission.list.currentStage',
'submission.list.discussions',
'submission.list.dualWorkflowLinks',
'submission.list.galleysCreated',
'submission.list.infoCenter',
'submission.list.reviewAssignment',
'submission.list.responseDue',
'submission.list.reviewCancelled',
'submission.list.reviewComplete',
'submission.list.reviewDue',
'submission.list.reviewerWorkflowLink',
'submission.list.reviewsCompleted',
'submission.list.revisionsSubmitted',
'submission.list.viewSubmission',
]);
return $config;
}
/**
* Compile the categories for passing as filters
*
* @param array $categories
*
* @return array
*/
public function getCategoryFilters($categories = [])
{
$request = Application::get()->getRequest();
if ($categories) {
// Use an autosuggest field if the list of categories is too long
if (count($categories) > 5) {
$autosuggestField = new FieldAutosuggestPreset('categoryIds', [
'label' => __('category.category'),
'value' => [],
'options' => array_map(function ($category) {
return [
'value' => (int) $category['id'],
'label' => $category['title'],
];
}, $categories),
]);
return [
'filters' => [
[
'title' => __('category.category'),
'param' => 'categoryIds',
'filterType' => 'pkp-filter-autosuggest',
'component' => 'field-autosuggest-preset',
'value' => [],
'autosuggestProps' => $autosuggestField->getConfig(),
]
],
];
}
return [
'heading' => __('category.category'),
'filters' => array_map(function ($category) {
return [
'param' => 'categoryIds',
'value' => (int) $category['id'],
'title' => $category['title'],
];
}, $categories),
];
}
return [];
}
}