diff --git a/wire/modules/Inputfield/InputfieldSelect.module b/wire/modules/Inputfield/InputfieldSelect.module index 8c2d6c8a..904c4bd4 100644 --- a/wire/modules/Inputfield/InputfieldSelect.module +++ b/wire/modules/Inputfield/InputfieldSelect.module @@ -9,6 +9,8 @@ * Subclasses that select multiple values should implement the InputfieldHasArrayValue interface. * * @property string|int $defaultValue + * @property array|string $options Get or set options, array of [value => label], or use options string. + * @property array $optionAttributes * */ class InputfieldSelect extends Inputfield { @@ -25,6 +27,14 @@ class InputfieldSelect extends Inputfield { */ protected $optionAttributes = array(); + /** + * Alternate language labels for options, array of [ languageID => [ optionValue => optionLabel ] ] + * + * @var array + * + */ + protected $optionLanguageLabels = array(); + /** * Return information about this module * @@ -38,6 +48,10 @@ class InputfieldSelect extends Inputfield { ); } + /** + * Construct + * + */ public function __construct() { parent::__construct(); $this->set('defaultValue', ''); @@ -84,6 +98,59 @@ class InputfieldSelect extends Inputfield { return $this; } + /** + * Set/replace all options + * + * @param array $options Array of options to add. It is assumed that array keys are the option value, and array + * values are the option labels, unless overridden by the $assoc argument. + * @param bool $assoc Is $options an associative array? (default=true). Specify false if $options is intended to be + * a regular PHP array, where the array keys/indexes should be ignored, and option value will also be the label. + * @return $this + * + */ + public function setOptions(array $options, $assoc = true) { + $this->options = array(); + return $this->addOptions($options, $assoc); + } + + /** + * Get or set alternative language label(s) + * + * @param Language|int|string $language Language object, id or name (required). + * @param string|null|bool $key Option key/value to get/set label for, + * OR omit to return all currently set option language labels for language, + * OR boolean false to remove all language labels for this option value/key. + * OR array of [ optionValue => optionLabel ] to add multiple option values for language. + * @param $label|string|bool Translated label text to set, + * OR omit to GET language label. + * OR boolean false to remove. + * @return string|array|Inputfield Return value depends on given arguments + * + */ + public function optionLanguageLabel($language, $key = null, $label = null) { + if(is_string($language) && !ctype_digit("$language")) { + $language = $this->wire('languages')->get($language); + } + $languageID = (int) "$language"; // converts Page or string to id + if(!isset($this->optionLanguageLabels[$languageID])) { + $this->optionLanguageLabels[$languageID] = array(); + } + if($key === null) { + return $this->optionLanguageLabels[$languageID]; + } else if($key === false) { + unset($this->optionLanguageLabels[$languageID]); + } else if(is_array($key)) { + foreach($key as $k => $v) $this->optionLanguageLabels[$languageID][$k] = $v; + } else if($label === null) { + return isset($this->optionLanguageLabels[$languageID][$key]) ? $this->optionLanguageLabels[$languageID][$key] : ''; + } else if($label === false) { + unset($this->optionLanguageLabels[$languageID][$key]); + } else { + $this->optionLanguageLabels[$languageID][$key] = $label; + } + return $this; + } + /** * Given a multi-line string, convert it to options, one per line * @@ -163,6 +230,26 @@ class InputfieldSelect extends Inputfield { return $this; } + /** + * Add/modify existing option labels from a line separated key=value string, primarily for multi-language support + * + * @param string $str String of optionValue=optionLabel with each on its own line + * @param int $languageID Language ID to set for, or omit for default language + * + */ + protected function addOptionLabelsString($str, $languageID = 0) { + foreach(explode("\n", $str) as $line) { + $line = trim($line); + if(!strpos($line, '=')) continue; // 0 or false OK + list($key, $label) = explode('=', $line, 2); + if($languageID) { + $this->optionLanguageLabel($languageID, $key, $label); + } else { + $this->addOption($key, $label); + } + } + } + /** * Remove the option with the given value * @@ -261,6 +348,75 @@ class InputfieldSelect extends Inputfield { } return $disabled; } + + /** + * Get an attributes array intended for an item (or for all items) + * + * @param string|int|null $key Option value, or omit to return ALL option attributes indexed by option value + * @return array Array of attributes + * + */ + public function getOptionAttributes($key = null) { + if($key === null) return $this->optionAttributes; + if(!isset($this->optionAttributes[$key])) return array(); + return $this->optionAttributes[$key]; + } + + /** + * Set/replace entire attributes array for an item + * + * @param string|int|array $key Option value, or specify associative array (indexed by option value) to set ALL option attributes + * @param array $attrs Array of attributes to set, or omit if you specified array for first argument. + * @return $this + * + */ + public function setOptionAttributes($key, array $attrs = array()) { + if(is_array($key)) { + $this->optionAttributes = $key; + } else { + $this->optionAttributes[$key] = $attrs; + } + return $this; + } + + /** + * Add attributes for an item (without removing existing attributes), or for multiple items + * + * @param string|int|array $key Option value, or array of option attributes indexed by option value. + * @param array $attrs Array of attributes to set, or omit if you specified array for first argument. + * @return $this + * + */ + public function addOptionAttributes($key, array $attrs = array()) { + if(is_array($key)) { + foreach($key as $k => $v) { + $this->addOptionAttributes($k, $v); + } + } else { + $value = isset($this->optionAttributes[$key]) ? $this->optionAttributes[$key] : array(); + $this->optionAttributes[$key] = array_merge($value, $attrs); + } + return $this; + } + + /** + * Get an attributes string intended for the