|
|
<?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);
|
|
|
}
|