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
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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