You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

255 lines
6.3 KiB
PHTML

<?php
namespace Artmark\Forms;
/**
* Description of AbstractChoiceField
*
* @author Andrey Pokidov <pokidov@e-traffic.ru>
*/
abstract class AbstractChoiceField extends AbstractVisibleField
{
/**
* Список опций
* @var AbstractChoiceOption[]
*/
private $options = [];
/**
* Список выбранных опций
* @var AbstractChoiceOption[]
*/
private $selectedOptions = [];
private $multiselect = false;
/**
* Возвращает, можно ли делать множественный выбор
* @return boolean
*/
public function isMultiSelect()
{
return $this->multiselect;
}
/**
* Переключает поле в режим множественного выбора
* @return $this
*/
public function setMultiSelect()
{
$this->multiselect = true;
return $this;
}
/**
* Переключает поле в режим единственного выбора
* @return $this
*/
public function setSingleSelect()
{
$this->multiselect = false;
if (count($this->selectedOptions) > 0) {
$this->selectedOptions = [$this->selectedOptions[0]];
}
return $this;
}
/**
* Возвращает значение выделенной опции
* @return mixed
*/
public function value()
{
if (empty($this->selectedOptions)) {
return null;
}
if (!$this->multiselect) {
return $this->selectedOptions[0]->value();
}
$values = [];
foreach ($this->selectedOptions as $option) {
$values[] = $option->value();
}
return $values;
}
/**
* Задаёт новое значение для select поля
* @param mixed $newValue
* @return $this
*/
public function setValue($newValue)
{
if (is_array($newValue)) {
$values = self::getUniqueValues($newValue);
}
else {
$values = [$newValue];
}
$this->selectedOptions = [];
foreach ($values as $value) {
foreach ($this->options as $option) {
if ($option->value() == $value && !in_array($option, $this->selectedOptions)) {
$this->selectedOptions[] = $option;
continue 2;
}
}
}
return $this;
}
private static function getUniqueValues(array $values)
{
$unquie = [];
foreach ($values as $value) {
if (!in_array($value, $unquie)) {
$unquie[] = $value;
}
}
return $unquie;
}
/**
* Метод возвращает список всех опций
* @return AbstractChoiceOption[]
*/
public function options()
{
return $this->options;
}
/**
* Метод возвращает список выбранных опций
* @return AbstractChoiceOption[]
*/
public function selection()
{
return $this->selectedOptions;
}
/**
* Устанавливает новый набор опций для поля
* @param array $options
* @return $this
*/
public function setOptions(array $options)
{
$this->options = [];
$this->selectedOptions = [];
foreach ($options as $key => $data) {
$this->registerOption($key, $data);
}
return $this;
}
private function registerOption($key, $data)
{
if (is_string($data) || is_numeric($data)) {
$this->addOption($key, $data);
return;
}
if (!is_array($data)) {
return;
}
$value = array_key_exists('value', $data) ? $data['value'] : $key;
$text = array_key_exists('text', $data) ? $data['text'] : '';
$option = $this->addOption($value, $text);
if ((array_key_exists('disabled', $data) && !empty($data['disabled']))
|| (array_key_exists('disable', $data) && !empty($data['disable']))) {
$option->disable();
}
if ((array_key_exists('selected', $data) && !empty($data['selected']))
|| (array_key_exists('select', $data) && !empty($data['select']))) {
$this->select($option);
}
}
/**
* Метод добавляет опцию со значением $value и текстом $text
* @param string|int|float $value
* @param string $text
* @param array $parameters
* @return AbstractChoiceOption
*/
public function addOption($value, $text)
{
$option = $this->createOption($value, $text);
$this->options[] = $option;
return $option;
}
/**
* Проверяет, выбрана ли данная опция
* @param AbstractChoiceOption $option
* @return boolean
*/
public function isSelected(AbstractChoiceOption $option)
{
return in_array($option, $this->selectedOptions);
}
/**
*
* @param AbstractChoiceOption $option
* @return boolean
*/
public function select(AbstractChoiceOption $option)
{
if (!in_array($option, $this->options)) {
return false;
}
if (!$this->multiselect) {
$this->selectedOptions = [$option];
return true;
}
if (!in_array($option, $this->selectedOptions)) {
$this->selectedOptions[] = $option;
}
return true;
}
public function getAssociativeAttributes()
{
$attributes = parent::getAssociativeAttributes();
$this->appendVisibleAttributes($attributes);
$this->appendSizeAttribute($attributes);
return $attributes;
}
/**
* Создаёт новый экземпляр опции
* @return AbstractChoiceOption
*/
protected abstract function createOption($value, $text);
public abstract function appendAttributesToOption(AbstractChoiceOption $option, array & $attributes);
}