2015-02-13 05:35:39 +01:00
|
|
|
<?php
|
|
|
|
|
2016-08-19 00:51:35 +02:00
|
|
|
namespace SilverStripe\Forms;
|
|
|
|
|
|
|
|
use ArrayAccess;
|
|
|
|
|
2015-02-13 05:35:39 +01:00
|
|
|
/**
|
|
|
|
* Represents the base class for a single-select field
|
|
|
|
*/
|
2016-11-29 00:31:16 +01:00
|
|
|
abstract class SingleSelectField extends SelectField
|
|
|
|
{
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Show the first <option> element as empty (not having a value),
|
|
|
|
* with an optional label defined through {@link $emptyString}.
|
|
|
|
* By default, the <select> element will be rendered with the
|
|
|
|
* first option from {@link $source} selected.
|
|
|
|
*
|
|
|
|
* @var bool
|
|
|
|
*/
|
|
|
|
protected $hasEmptyDefault = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The title shown for an empty default selection,
|
|
|
|
* e.g. "Select...".
|
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
protected $emptyString = '';
|
|
|
|
|
|
|
|
protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_SINGLESELECT;
|
|
|
|
|
|
|
|
public function getSchemaStateDefaults()
|
|
|
|
{
|
|
|
|
$data = parent::getSchemaStateDefaults();
|
|
|
|
|
|
|
|
// Add options to 'data'
|
|
|
|
$data['data']['hasEmptyDefault'] = $this->getHasEmptyDefault();
|
|
|
|
$data['data']['emptyString'] = $this->getHasEmptyDefault() ? $this->getEmptyString() : null;
|
|
|
|
|
|
|
|
$data['value'] = $this->getDefaultValue();
|
|
|
|
|
|
|
|
return $data;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDefaultValue()
|
|
|
|
{
|
|
|
|
$value = $this->Value();
|
|
|
|
// assign value to field, such as first option available
|
|
|
|
if ($value === null) {
|
|
|
|
if ($this->getHasEmptyDefault()) {
|
|
|
|
$value = '';
|
|
|
|
} else {
|
|
|
|
$values = $this->getValidValues();
|
|
|
|
$value = array_shift($values);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param boolean $bool
|
|
|
|
* @return self Self reference
|
|
|
|
*/
|
|
|
|
public function setHasEmptyDefault($bool)
|
|
|
|
{
|
|
|
|
$this->hasEmptyDefault = $bool;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function getHasEmptyDefault()
|
|
|
|
{
|
|
|
|
return $this->hasEmptyDefault;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the default selection label, e.g. "select...".
|
|
|
|
* Defaults to an empty string. Automatically sets
|
|
|
|
* {@link $hasEmptyDefault} to true.
|
|
|
|
*
|
|
|
|
* @param string $string
|
|
|
|
* @return $this
|
|
|
|
*/
|
|
|
|
public function setEmptyString($string)
|
|
|
|
{
|
|
|
|
$this->setHasEmptyDefault(true);
|
|
|
|
$this->emptyString = $string;
|
|
|
|
return $this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getEmptyString()
|
|
|
|
{
|
|
|
|
return $this->emptyString;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the source array, including the empty string, if present
|
|
|
|
*
|
|
|
|
* @return array|ArrayAccess
|
|
|
|
*/
|
|
|
|
public function getSourceEmpty()
|
|
|
|
{
|
|
|
|
// Inject default option
|
|
|
|
if ($this->getHasEmptyDefault()) {
|
2020-04-20 19:58:09 +02:00
|
|
|
return ['' => $this->getEmptyString()] + $this->getSource();
|
2016-11-29 00:31:16 +01:00
|
|
|
} else {
|
|
|
|
return $this->getSource();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Validate this field
|
|
|
|
*
|
|
|
|
* @param Validator $validator
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function validate($validator)
|
|
|
|
{
|
|
|
|
// Check if valid value is given
|
|
|
|
$selected = $this->Value();
|
2018-10-06 00:53:17 +02:00
|
|
|
$validValues = $this->getValidValues();
|
|
|
|
|
2016-11-29 00:31:16 +01:00
|
|
|
if (strlen($selected)) {
|
|
|
|
// Use selection rules to check which are valid
|
2018-10-06 00:53:17 +02:00
|
|
|
foreach ($validValues as $formValue) {
|
2016-11-29 00:31:16 +01:00
|
|
|
if ($this->isSelectedValue($formValue, $selected)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2018-10-06 00:53:17 +02:00
|
|
|
if ($this->getHasEmptyDefault() || !$validValues || in_array('', $validValues)) {
|
2016-11-29 00:31:16 +01:00
|
|
|
// Check empty value
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
$selected = '(none)';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fail
|
|
|
|
$validator->validationError(
|
|
|
|
$this->name,
|
|
|
|
_t(
|
2017-04-20 03:15:24 +02:00
|
|
|
'SilverStripe\\Forms\\DropdownField.SOURCE_VALIDATION',
|
2016-11-29 00:31:16 +01:00
|
|
|
"Please select a value within the list provided. {value} is not a valid option",
|
2020-04-20 19:58:09 +02:00
|
|
|
['value' => $selected]
|
2016-11-29 00:31:16 +01:00
|
|
|
),
|
|
|
|
"validation"
|
|
|
|
);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function castedCopy($classOrCopy)
|
|
|
|
{
|
|
|
|
$field = parent::castedCopy($classOrCopy);
|
|
|
|
if ($field instanceof SingleSelectField && $this->getHasEmptyDefault()) {
|
|
|
|
$field->setEmptyString($this->getEmptyString());
|
|
|
|
}
|
|
|
|
return $field;
|
|
|
|
}
|
2018-04-20 00:29:45 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return SingleLookupField
|
|
|
|
*/
|
|
|
|
public function performReadonlyTransformation()
|
|
|
|
{
|
|
|
|
/** @var SingleLookupField $field */
|
|
|
|
$field = $this->castedCopy(SingleLookupField::class);
|
|
|
|
$field->setSource($this->getSource());
|
|
|
|
$field->setReadonly(true);
|
|
|
|
|
|
|
|
return $field;
|
|
|
|
}
|
2015-02-13 05:35:39 +01:00
|
|
|
}
|