2014-11-12 07:33:58 +11:00
|
|
|
<?php namespace Backend\Classes;
|
|
|
|
|
|
|
|
use IteratorAggregate;
|
|
|
|
use ArrayIterator;
|
|
|
|
use ArrayAccess;
|
2022-02-13 11:32:03 -06:00
|
|
|
use Traversable;
|
2014-11-12 07:33:58 +11:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Form Tabs definition
|
|
|
|
* A translation of the form field tab configuration
|
|
|
|
*
|
2021-03-10 15:02:53 -06:00
|
|
|
* @package winter\wn-backend-module
|
2014-11-12 07:33:58 +11:00
|
|
|
* @author Alexey Bobkov, Samuel Georges
|
|
|
|
*/
|
|
|
|
class FormTabs implements IteratorAggregate, ArrayAccess
|
|
|
|
{
|
|
|
|
const SECTION_OUTSIDE = 'outside';
|
|
|
|
const SECTION_PRIMARY = 'primary';
|
|
|
|
const SECTION_SECONDARY = 'secondary';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string Specifies the form section these tabs belong to.
|
|
|
|
*/
|
|
|
|
public $section = 'outside';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array Collection of panes fields to these tabs.
|
|
|
|
*/
|
|
|
|
public $fields = [];
|
|
|
|
|
2019-12-09 10:45:26 +01:00
|
|
|
/**
|
|
|
|
* @var array Names of tabs to lazy load.
|
|
|
|
*/
|
|
|
|
public $lazy = [];
|
|
|
|
|
2015-03-14 17:06:03 +11:00
|
|
|
/**
|
|
|
|
* @var string Default tab label to use when none is specified.
|
|
|
|
*/
|
|
|
|
public $defaultTab = 'backend::lang.form.undefined_tab';
|
2019-07-18 22:50:37 +08:00
|
|
|
|
2018-10-30 20:06:33 -06:00
|
|
|
/**
|
|
|
|
* @var array List of icons for their corresponding tabs.
|
|
|
|
*/
|
|
|
|
public $icons = [];
|
2019-07-18 22:50:37 +08:00
|
|
|
|
2014-11-12 07:33:58 +11:00
|
|
|
/**
|
|
|
|
* @var bool Should these tabs stretch to the bottom of the page layout.
|
|
|
|
*/
|
2018-08-15 18:33:24 +02:00
|
|
|
public $stretch;
|
2014-11-12 07:33:58 +11:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var boolean If set to TRUE, fields will not be displayed in tabs.
|
|
|
|
*/
|
|
|
|
public $suppressTabs = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string Specifies a CSS class to attach to the tab container.
|
|
|
|
*/
|
|
|
|
public $cssClass;
|
|
|
|
|
2017-06-05 17:37:13 +10:00
|
|
|
/**
|
|
|
|
* @var array Specifies a CSS class to an individual tab pane.
|
|
|
|
*/
|
|
|
|
public $paneCssClass;
|
|
|
|
|
2020-04-05 05:56:48 +02:00
|
|
|
/**
|
|
|
|
* @var bool Each tab gets url fragment to be linkable.
|
|
|
|
*/
|
|
|
|
public $linkable = true;
|
|
|
|
|
2014-11-12 07:33:58 +11:00
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
* Specifies a tabs rendering section. Supported sections are:
|
|
|
|
* - outside - stores a section of "tabless" fields.
|
|
|
|
* - primary - tabs section for primary fields.
|
|
|
|
* - secondary - tabs section for secondary fields.
|
|
|
|
* @param string $section Specifies a section as described above.
|
|
|
|
* @param array $config A list of render mode specific config.
|
|
|
|
*/
|
|
|
|
public function __construct($section, $config = [])
|
|
|
|
{
|
|
|
|
$this->section = strtolower($section) ?: $this->section;
|
|
|
|
$this->config = $this->evalConfig($config);
|
|
|
|
|
|
|
|
if ($this->section == self::SECTION_OUTSIDE) {
|
|
|
|
$this->suppressTabs = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Process options and apply them to this object.
|
|
|
|
* @param array $config
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
protected function evalConfig($config)
|
|
|
|
{
|
2015-03-14 17:06:03 +11:00
|
|
|
if (array_key_exists('defaultTab', $config)) {
|
|
|
|
$this->defaultTab = $config['defaultTab'];
|
|
|
|
}
|
2019-07-18 22:50:37 +08:00
|
|
|
|
2018-10-30 20:06:33 -06:00
|
|
|
if (array_key_exists('icons', $config)) {
|
|
|
|
$this->icons = $config['icons'];
|
|
|
|
}
|
2019-07-18 22:50:37 +08:00
|
|
|
|
2014-11-12 07:33:58 +11:00
|
|
|
if (array_key_exists('stretch', $config)) {
|
|
|
|
$this->stretch = $config['stretch'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (array_key_exists('suppressTabs', $config)) {
|
|
|
|
$this->suppressTabs = $config['suppressTabs'];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (array_key_exists('cssClass', $config)) {
|
|
|
|
$this->cssClass = $config['cssClass'];
|
|
|
|
}
|
2017-06-05 17:37:13 +10:00
|
|
|
|
|
|
|
if (array_key_exists('paneCssClass', $config)) {
|
|
|
|
$this->paneCssClass = $config['paneCssClass'];
|
|
|
|
}
|
2019-12-09 10:45:26 +01:00
|
|
|
|
2020-04-05 05:56:48 +02:00
|
|
|
if (array_key_exists('linkable', $config)) {
|
|
|
|
$this->linkable = (bool) $config['linkable'];
|
|
|
|
}
|
|
|
|
|
2019-12-09 10:45:26 +01:00
|
|
|
if (array_key_exists('lazy', $config)) {
|
|
|
|
$this->lazy = $config['lazy'];
|
|
|
|
}
|
2014-11-12 07:33:58 +11:00
|
|
|
}
|
|
|
|
|
2015-02-12 08:37:24 +11:00
|
|
|
/**
|
|
|
|
* Add a field to the collection of tabs.
|
|
|
|
* @param string $name
|
|
|
|
* @param FormField $field
|
|
|
|
* @param string $tab
|
|
|
|
*/
|
|
|
|
public function addField($name, FormField $field, $tab = null)
|
|
|
|
{
|
|
|
|
if (!$tab) {
|
2018-10-30 20:06:33 -06:00
|
|
|
$tab = $this->defaultTab;
|
2015-02-12 08:37:24 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
$this->fields[$tab][$name] = $field;
|
|
|
|
}
|
|
|
|
|
2015-02-07 19:52:34 +10:00
|
|
|
/**
|
|
|
|
* Remove a field from all tabs by name.
|
|
|
|
* @param string $name
|
2015-02-12 08:37:24 +11:00
|
|
|
* @return boolean
|
2015-02-07 19:52:34 +10:00
|
|
|
*/
|
|
|
|
public function removeField($name)
|
|
|
|
{
|
|
|
|
foreach ($this->fields as $tab => $fields) {
|
|
|
|
foreach ($fields as $fieldName => $field) {
|
|
|
|
if ($fieldName == $name) {
|
|
|
|
unset($this->fields[$tab][$fieldName]);
|
|
|
|
|
2015-06-18 18:46:03 +10:00
|
|
|
/*
|
|
|
|
* Remove empty tabs from collection
|
|
|
|
*/
|
|
|
|
if (!count($this->fields[$tab])) {
|
2015-06-18 14:44:43 +10:00
|
|
|
unset($this->fields[$tab]);
|
|
|
|
}
|
|
|
|
|
2015-02-07 19:52:34 +10:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-11-12 07:39:42 +11:00
|
|
|
/**
|
|
|
|
* Returns true if any fields have been registered for these tabs
|
|
|
|
* @return boolean
|
|
|
|
*/
|
2014-11-12 07:33:58 +11:00
|
|
|
public function hasFields()
|
|
|
|
{
|
|
|
|
return count($this->fields) > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2014-11-12 07:39:42 +11:00
|
|
|
* Returns an array of the registered fields, including tabs.
|
2014-11-12 07:33:58 +11:00
|
|
|
* @return array
|
|
|
|
*/
|
2016-04-23 05:13:08 +10:00
|
|
|
public function getFields()
|
2014-11-12 07:33:58 +11:00
|
|
|
{
|
|
|
|
return $this->fields;
|
|
|
|
}
|
|
|
|
|
2016-04-23 05:13:08 +10:00
|
|
|
/**
|
|
|
|
* Returns an array of the registered fields, without tabs.
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getAllFields()
|
|
|
|
{
|
|
|
|
$tablessFields = [];
|
|
|
|
|
|
|
|
foreach ($this->getFields() as $tab) {
|
|
|
|
$tablessFields += $tab;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $tablessFields;
|
|
|
|
}
|
2019-07-18 22:50:37 +08:00
|
|
|
|
2018-10-30 20:06:33 -06:00
|
|
|
/**
|
|
|
|
* Returns an icon for the tab based on the tab's name.
|
|
|
|
* @param string $name
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getIcon($name)
|
|
|
|
{
|
|
|
|
if (!empty($this->icons[$name])) {
|
|
|
|
return $this->icons[$name];
|
|
|
|
}
|
|
|
|
}
|
2019-07-18 22:50:37 +08:00
|
|
|
|
2017-06-05 17:37:13 +10:00
|
|
|
/**
|
|
|
|
* Returns a tab pane CSS class.
|
|
|
|
* @param string $index
|
|
|
|
* @param string $label
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getPaneCssClass($index = null, $label = null)
|
|
|
|
{
|
2018-09-16 19:51:00 +03:00
|
|
|
if (is_string($this->paneCssClass)) {
|
|
|
|
return $this->paneCssClass;
|
|
|
|
}
|
|
|
|
|
2017-06-05 17:37:13 +10:00
|
|
|
if ($index !== null && isset($this->paneCssClass[$index])) {
|
|
|
|
return $this->paneCssClass[$index];
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($label !== null && isset($this->paneCssClass[$label])) {
|
|
|
|
return $this->paneCssClass[$label];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-12 07:33:58 +11:00
|
|
|
/**
|
|
|
|
* Get an iterator for the items.
|
|
|
|
*/
|
2022-02-13 11:32:03 -06:00
|
|
|
public function getIterator(): Traversable
|
2014-11-12 07:33:58 +11:00
|
|
|
{
|
2019-07-18 22:50:37 +08:00
|
|
|
return new ArrayIterator(
|
|
|
|
$this->suppressTabs
|
|
|
|
? $this->getAllFields()
|
|
|
|
: $this->getFields()
|
2014-11-12 07:33:58 +11:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ArrayAccess implementation
|
|
|
|
*/
|
2022-02-13 11:32:03 -06:00
|
|
|
public function offsetSet($offset, $value): void
|
2014-11-12 07:33:58 +11:00
|
|
|
{
|
|
|
|
$this->fields[$offset] = $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ArrayAccess implementation
|
|
|
|
*/
|
2022-02-13 11:32:03 -06:00
|
|
|
public function offsetExists($offset): bool
|
2014-11-12 07:33:58 +11:00
|
|
|
{
|
|
|
|
return isset($this->fields[$offset]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ArrayAccess implementation
|
|
|
|
*/
|
2022-02-13 11:32:03 -06:00
|
|
|
public function offsetUnset($offset): void
|
2014-11-12 07:33:58 +11:00
|
|
|
{
|
|
|
|
unset($this->fields[$offset]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ArrayAccess implementation
|
|
|
|
*/
|
2022-02-13 11:32:03 -06:00
|
|
|
public function offsetGet($offset): mixed
|
2014-11-12 07:33:58 +11:00
|
|
|
{
|
2018-08-15 19:15:13 +02:00
|
|
|
return $this->fields[$offset] ?? null;
|
2014-11-12 07:33:58 +11:00
|
|
|
}
|
2015-01-03 12:41:23 +01:00
|
|
|
}
|