[ Mini Kiebo ]
Server: Windows NT AKFAR_SERVER 10.0 build 26200 (Windows 10) AMD64
Path:
D:
/
Jurnal PSCP
/
lib
/
pkp
/
classes
/
components
/
forms
/
[
Home
]
File: FormComponent.inc.php
<?php /** * @file classes/components/form/FormComponent.inc.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; define('FIELD_POSITION_BEFORE', 'before'); define('FIELD_POSITION_AFTER', 'after'); class FormComponent { /** @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 pages in this form. */ public $pages = []; /** @var array List of error messages */ public $errors = []; /** * Initialize the form with config parameters * * @param $id string * @param $method string * @param $action string * @param $locales array */ 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 $position array [ * @option string One of FIELD_POSITION_BEFORE or FIELD_POSITION_AFTER * @option string The field to position it before or after * ] * @return FormComponent */ public function addField($field, $position = []) { 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 $fieldName string * @return FormComponent */ public function removeField($fieldName) { $this->fields = array_values(array_filter($this->fields, function($field) use ($fieldName) { return $field->name !== $fieldName; })); return $this; } /** * Get a form field * * @param $fieldName string * @return Field */ public function getField($fieldName) { foreach ($this->fields as $field) { if ($field->name === $fieldName) { return $field; } } return null; } /** * Add a form group * * @param $args array [ * @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 $position array [ * @option string One of FIELD_POSITION_BEFORE or FIELD_POSITION_AFTER * @option string The group to position it before or after * ] * @return FormComponent */ public function addGroup($args, $position = []) { if (empty($args['id'])) { fatalError('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 $groupId string * @return FormComponent */ public function removeGroup($groupId) { $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 $args array [ * @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 $position array [ * @option string One of FIELD_POSITION_BEFORE or FIELD_POSITION_AFTER * @option string The page to position it before or after * ] * @return FormComponent */ public function addPage($args, $position = []) { 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 $pageId string * @return FormComponent */ public function removePage($pageId) { $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 $id string The id of the item to position before or after * @param $list array The list of fields, groups or pages * @param $item array The item to insert * @param $position string 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 ((is_a($val, 'PKP\components\forms\Field') && $id === $val->name) || (!is_a($val, '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) ); } /** * 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->method) || empty($this->action)) { throw new Exception('FormComponent::getConfig() was called but one or more required property is missing: id, method, action.'); } \HookRegistry::call('Form::config::before', $this); // Add a default page/group if none exist if (!$this->groups) { $this->addGroup(array('id' => 'default')); $this->fields = array_map(function($field) { $field->groupId = 'default'; return $field; }, $this->fields); } if (!$this->pages) { $this->addPage(array('id' => 'default', 'submitButton' => array('label' => __('common.save')))); $this->groups = array_map(function($group) { $group['pageId'] = 'default'; return $group; }, $this->groups); } $fieldsConfig = array_map([$this, 'getFieldConfig'], $this->fields); $visibleLocales = [\AppLocale::getLocale()]; if (\AppLocale::getLocale() !== \AppLocale::getPrimaryLocale()) { array_unshift($visibleLocales, \AppLocale::getPrimaryLocale()); } $config = array( 'id' => $this->id, 'method' => $this->method, 'action' => $this->action, 'fields' => $fieldsConfig, 'groups' => $this->groups, 'pages' => $this->pages, 'primaryLocale' => \AppLocale::getPrimaryLocale(), 'visibleLocales' => $visibleLocales, 'supportedFormLocales' => array_values($this->locales), // See #5690 'errors' => (object) [], ); \HookRegistry::call('Form::config::after', array(&$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 ? array() : $field->getEmptyValue(); } if ($field->isMultilingual) { foreach ($this->locales as $locale) { if (!array_key_exists($locale['key'], $config['value'])) { $config['value'][$locale['key']] = $field->getEmptyValue(); } } } return $config; } }