1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-11 17:24:46 +02:00

Minor code updates in FieldtypeOptions and supporting classes

This commit is contained in:
Ryan Cramer
2022-09-30 12:04:03 -04:00
parent cce5073969
commit c1e1cecf93
4 changed files with 71 additions and 39 deletions

View File

@@ -3,7 +3,7 @@
/**
* ProcessWire Select Options Fieldtype
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property SelectableOptionManager $manager
@@ -66,6 +66,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
*
*/
public function getBlankValue(Page $page, Field $field) {
/** @var SelectableOptionArray $a */
$a = $this->wire(new SelectableOptionArray());
$a->setPage($page);
$a->setField($field);
@@ -99,8 +100,9 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
$inputfieldClass = $field->get('inputfieldClass');
if(!$inputfieldClass) $inputfieldClass = 'InputfieldSelect';
$inputfield = $this->wire('modules')->get($inputfieldClass);
if(!$inputfield) $inputfield = $this->wire('modules')->get('InputfieldSelect');
/** @var InputfieldSelect $inputfield */
$inputfield = $this->wire()->modules->get($inputfieldClass);
if(!$inputfield) $inputfield = $this->wire()->modules->get('InputfieldSelect');
foreach($this->manager->getOptions($field) as $option) {
$inputfield->addOption((int) $option->id, $option->getTitle());
@@ -112,7 +114,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
if(empty($value) || !wireCount($value)) {
$page->set($field->name, $field->get('initValue'));
}
} else if($this->wire('process') != 'ProcessField' && !wireCount($value)) {
} else if($this->wire()->process != 'ProcessField' && !wireCount($value)) {
$this->warning(
$field->getLabel() . " ($field->name): " .
$this->_('Configured pre-selection not populated since value is not always required. Please correct this field configuration.')
@@ -133,7 +135,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
*/
public function ___getCompatibleFieldtypes(Field $field) {
$fieldtypes = $this->wire(new Fieldtypes());
foreach($this->wire('fieldtypes') as $fieldtype) {
foreach($this->wire()->fieldtypes as $fieldtype) {
if($fieldtype instanceof FieldtypeOptions) $fieldtypes->add($fieldtype);
}
return $fieldtypes;
@@ -259,9 +261,13 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
}
return $sleepValue;
}
if(!$value instanceof SelectableOptionArray) throw new WireException("sleepValue requires SelectableOptionArray");
if(!$value instanceof SelectableOptionArray) {
throw new WireException("sleepValue requires SelectableOptionArray");
}
foreach($value as $option) {
/** @var SelectableOption $option */
$sleepValue[] = (int) $option->id;
}
return $sleepValue;
@@ -361,6 +367,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
$subfield = 'data';
if(count($options) < 2) {
/** @var SelectableOption $option */
$option = $options->first();
$value = $option ? $option->id : '';
} else {
@@ -373,7 +380,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
if($operator == '!=') {
// force a != for one value to prevent matching, even if more than one value
$database = $this->wire('database');
$database = $this->wire()->database;
$t = $database->escapeTable($query->field->getTable());
$s = $database->escapeCol($subfield);
@@ -402,14 +409,15 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
* @param string $table
* @param string $subfield
* @param bool $desc
* @return bool|string
* @return bool
* @since 3.0.167
*
*/
public function getMatchQuerySort(Field $field, $query, $table, $subfield, $desc) {
// FieldtypeOptions uses an separate table for option values/labels
$subfield = $this->wire()->sanitizer->fieldName($subfield);
if(empty($subfield)) return false;
$table2 = "_sort_options_$field->name" . ($subfield ? "_$subfield" : '');
$table2 = "_sort_options_{$field->name}_$subfield";
$bindKey = $query->bindValueGetKey($field->id, \PDO::PARAM_INT);
$query->leftjoin("fieldtype_options AS $table2 ON $table2.fields_id=$bindKey AND $table.data=$table2.option_id");
$query->orderby("$table2.$subfield " . ($desc ? 'DESC' : ''), true);
@@ -494,7 +502,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
$data['export_options'] = array('default' => $data['_options']);
unset($data['_options']);
}
if($this->manager->useLanguages()) foreach($this->wire('languages') as $language) {
if($this->manager->useLanguages()) foreach($this->wire()->languages as $language) {
if($language->isDefault()) continue;
$key = "_options__$language";
if(isset($data[$key])) {
@@ -529,7 +537,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
*
*/
public function ___cloneField(Field $field) {
$this->wire('fields')->addHookAfter('cloned', $this, 'hookCloned');
$this->wire()->fields->addHookAfter('cloned', $this, 'hookCloned');
return parent::___cloneField($field);
}
@@ -584,6 +592,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
public function ___getConfigInputfields(Field $field) {
$inputfields = parent::___getConfigInputfields($field);
include_once(dirname(__FILE__) . '/SelectableOptionConfig.php');
/** @var SelectableOptionConfig $cfg */
$cfg = $this->wire(new SelectableOptionConfig($field, $inputfields));
$inputfields = $cfg->getConfigInputfields();
return $inputfields;
@@ -599,7 +608,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
protected function _getField($field) {
if(!$field instanceof Field) {
$_field = $field;
$field = $this->wire('fields')->get($field);
$field = $this->wire()->fields->get($field);
if(!$field) throw new WireException("Unknown field: $_field");
}
if(!$field->type instanceof FieldtypeOptions) {
@@ -634,7 +643,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
*
*/
public function getOptions($field) {
return $this->manager->getOptions($field = $this->_getField($field));
return $this->manager->getOptions($this->_getField($field));
}
/**
@@ -647,7 +656,7 @@ class FieldtypeOptions extends FieldtypeMulti implements Module {
*
*/
public function setOptions($field, SelectableOptionArray $options) {
return $this->manager->setOptions($field = $this->_getField($field), $options, true);
return $this->manager->setOptions($this->_getField($field), $options, true);
}
/**

View File

@@ -3,7 +3,7 @@
/**
* ProcessWire Selectable Option class, for FieldtypeOptions
*
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property int $id
@@ -31,6 +31,7 @@ class SelectableOption extends WireData { // implements LanguagesValueInterface
protected $of = false;
public function __construct() {
parent::__construct();
foreach(self::$defaults as $property => $value) {
$this->set($property, $value);
}

View File

@@ -3,8 +3,12 @@
/**
* ProcessWire Selectable Option Array, for FieldtypeOptions
*
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
* @property string $title
* @property string $value
* @property int $id
*
*/
@@ -51,7 +55,7 @@ class SelectableOptionArray extends WireArray {
*
*/
public function getPage() {
return $this->page ? $this->page : $this->wire('pages')->newNullPage();
return $this->page ? $this->page : $this->wire()->pages->newNullPage();
}
/**
@@ -85,7 +89,10 @@ class SelectableOptionArray extends WireArray {
$_of = $this->of;
if(is_null($of)) return $_of;
$this->of = $of ? true : false;
foreach($this as $option) $option->of($this->of);
foreach($this as $option) {
/** @var SelectableOption $option */
$option->of($this->of);
}
return $_of; // whatever previous value was
}
@@ -143,8 +150,9 @@ class SelectableOptionArray extends WireArray {
public function setProperty($property, $value) {
if(SelectableOption::isProperty($property)) {
if($this->count()) {
/** @var SelectableOption|null $option */
$option = $this->first();
return $option->set($property, $value);
if($option) return $option->set($property, $value);
}
}
// note: there is no parent method for this one
@@ -159,8 +167,11 @@ class SelectableOptionArray extends WireArray {
public function __set($key, $value) {
// we must have both this and set() per behavior of WireArray::__set()
// which throws exceptions if attempting to set a property
if(SelectableOption::isProperty($key)) return $this->setProperty($key, $value);
return parent::__set($key, $value);
if(SelectableOption::isProperty($key)) {
$this->setProperty($key, $value);
} else {
parent::__set($key, $value);
}
}
public function isValidItem($item) {
@@ -172,6 +183,7 @@ class SelectableOptionArray extends WireArray {
}
public function getItemKey($item) {
/** @var SelectableOption $item */
return $item->id ? $item->id : null;
}
@@ -189,6 +201,7 @@ class SelectableOptionArray extends WireArray {
*/
public function isIdentical(WireArray $items, $strict = true) {
$isIdentical = parent::isIdentical($items, false); // force non-strict
/** @var SelectableOptionArray $items */
if($isIdentical && $strict) {
if($this->of() != $items->of()) $isIdentical = false;
if($isIdentical && ((string) $this->getPage()) !== ((string) $items->getPage())) $isIdentical = false;
@@ -208,6 +221,7 @@ class SelectableOptionArray extends WireArray {
protected function getOptionByProperty($property, $value) {
$match = false;
foreach($this as $option) {
/** @var SelectableOption $option */
$v = $option->getProperty($property);
if($v !== $value) continue;
$match = $option;

View File

@@ -6,7 +6,7 @@
* Handles management of the fieldtype_options table and related field_[name] table
* to assist FieldtypeOptions module.
*
* ProcessWire 3.x, Copyright 2021 by Ryan Cramer
* ProcessWire 3.x, Copyright 2022 by Ryan Cramer
* https://processwire.com
*
*/
@@ -46,7 +46,7 @@ class SelectableOptionManager extends Wire {
protected $removedOptionIDs = array();
public function wired() {
if($this->wire('modules')->isInstalled('LanguageSupportFields')) {
if($this->wire()->modules->isInstalled('LanguageSupportFields')) {
$this->useLanguages = true;
$this->addHookAfter('Languages::updated', $this, 'updateLanguages');
}
@@ -81,11 +81,13 @@ class SelectableOptionManager extends Wire {
*
* @param Field $field
* @param array $ids
* @return SelectableOptionArray
* @return SelectableOptionArray|SelectableOption[]
*
*/
public function getOptionsByID(Field $field, array $ids) {
return $this->getOptions($field, array('id' => $ids));
/** @var SelectableOptionArray|SelectableOption[] $value */
$value = $this->getOptions($field, array('id' => $ids));
return $value;
}
/**
@@ -96,12 +98,13 @@ class SelectableOptionManager extends Wire {
*
* @param Field $field
* @param array $filters Any of array(property => array) where property is 'id', 'title' or 'value'.
* @return SelectableOptionArray
* @return SelectableOptionArray|SelectableOption[]
* @throws WireException
*
*/
public function getOptions(Field $field, array $filters = array()) {
$database = $this->wire()->database;
$hasFilters = count($filters) > 0;
if(isset($this->optionsCache[$field->id]) && !$hasFilters) {
@@ -141,7 +144,7 @@ class SelectableOptionManager extends Wire {
if(!count($filters[$property])) continue;
$s = "`$property` IN(";
foreach($filters[$property] as $val) {
$s .= $this->wire('database')->quote($val) . ',';
$s .= $database->quote($val) . ',';
$sorted[$val] = ''; // placeholder
}
$s = rtrim($s, ',') . ')';
@@ -159,7 +162,7 @@ class SelectableOptionManager extends Wire {
if($sortKey === true) $sql .= 'ORDER BY sort ASC';
$query = $this->wire('database')->prepare($sql);
$query = $database->prepare($sql);
$query->bindValue(':fields_id', $field->id);
$query->execute();
@@ -183,6 +186,7 @@ class SelectableOptionManager extends Wire {
$query->closeCursor();
/** @var SelectableOptionArray $options */
$options = $this->wire(new SelectableOptionArray());
$options->setField($field);
foreach($sorted as $option) {
@@ -200,7 +204,8 @@ class SelectableOptionManager extends Wire {
* Perform a partial match on title of options
*
* @param Field $field
* @param string $property Either 'title' or 'value'. May also be blank (to imply 'either') if operator is '=' or '!='
* @param string $property Either 'title' or 'value'. May also be blank (to imply 'either') if operator is '=' or
* '!='
* @param string $operator
* @param string $value Value to find
* @return SelectableOptionArray
@@ -253,7 +258,7 @@ class SelectableOptionManager extends Wire {
if(isset($a['title'])) $option->set('title', $a['title']);
if(isset($a['value'])) $option->set('value', $a['value']);
if(isset($a['sort'])) $option->set('sort', (int) $a['sort']);
if($this->useLanguages) foreach($this->wire('languages') as $language) {
if($this->useLanguages) foreach($this->wire()->languages as $language) {
if($language->isDefault()) continue;
if(isset($a["title$language"])) $option->set("title$language", $a["title$language"]);
if(isset($a["value$language"])) $option->set("value$language", $a["value$language"]);
@@ -360,7 +365,7 @@ class SelectableOptionManager extends Wire {
if($language && $this->useLanguages()) {
if(is_string($language) || is_int($language)) {
$language = $this->wire('languages')->get($language);
$language = $this->wire()->languages->get($language);
if(!$language->id) throw new WireException("Unknown language: $language");
}
if(is_object($language) && $language->isDefault()) $language = '';
@@ -371,6 +376,7 @@ class SelectableOptionManager extends Wire {
$out = '';
foreach($options as $option) {
/** @var SelectableOption $option */
$title = trim((string) $option->get("title$language"));
$value = trim((string) $option->get("value$language"));
$titleLength = strlen($title);
@@ -427,8 +433,9 @@ class SelectableOptionManager extends Wire {
if(!$this->useLanguages) throw new WireException("Language support not active");
$arrays = array();
$default = array();
$languages = $this->wire()->languages;
foreach($values as $languageID => $value) {
$language = $this->wire('languages')->get($languageID);
$language = $languages->get($languageID);
if(!$language || !$language->id) {
$this->error("Unknown language: $language");
continue;
@@ -443,6 +450,7 @@ class SelectableOptionManager extends Wire {
$options = $this->optionsArrayToObjects($default);
$options->setField($field);
foreach($options as $option) {
/** @var SelectableOption $option */
foreach($arrays as $languageID => $a) {
$key = "id$option->id";
if(!isset($a[$key])) continue;
@@ -484,6 +492,7 @@ class SelectableOptionManager extends Wire {
$sort = 0;
foreach($options as $option) {
/** @var SelectableOption $option */
$option->set('sort', $sort);
@@ -563,11 +572,11 @@ class SelectableOptionManager extends Wire {
unset($this->optionsCache[$field->id]);
$database = $this->wire('database');
$database = $this->wire()->database;
$sql = "UPDATE " . self::optionsTable . " SET sort=:sort, title=:title, `value`=:value ";
$bindCols = array();
if($this->useLanguages) foreach($this->wire('languages') as $language) {
if($this->useLanguages) foreach($this->wire()->languages as $language) {
if($language->isDefault()) continue;
foreach(array('title', 'value') as $name) {
$name .= (int) $language->id;
@@ -637,11 +646,11 @@ class SelectableOptionManager extends Wire {
public function deleteOptionsByID(Field $field, array $ids) {
unset($this->optionsCache[$field->id]);
$database = $this->wire('database');
$database = $this->wire()->database;
$table = $database->escapeTable($field->getTable());
$cleanIDs = array();
foreach($ids as $key => $id) {
foreach($ids as $id) {
$cleanIDs[] = (int) $id;
}
@@ -699,8 +708,7 @@ class SelectableOptionManager extends Wire {
*/
public function addOptions(Field $field, $options) {
/** @var WireDatabasePDO $database */
$database = $this->wire('database');
$database = $this->wire()->database;
// options that have pre-assigned IDs
$optionsByID = array();