From 38d66af6f1709256b05bd1212b721c2b37540811 Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Tue, 3 Sep 2019 11:48:48 -0400 Subject: [PATCH] Various minor updates --- wire/core/PageFinder.php | 8 ++-- .../Fieldtype/FieldtypeCheckbox.module | 37 +++++++++++++++++++ .../FieldtypeComments.module | 20 +++++----- .../InputfieldRadios/InputfieldRadios.module | 29 +++++++++++---- .../InputfieldSelector.module | 10 ++++- .../Process/ProcessField/ProcessField.module | 12 +++--- 6 files changed, 88 insertions(+), 28 deletions(-) diff --git a/wire/core/PageFinder.php b/wire/core/PageFinder.php index 34d9c5a7..f391644f 100644 --- a/wire/core/PageFinder.php +++ b/wire/core/PageFinder.php @@ -1275,15 +1275,17 @@ class PageFinder extends Wire { $valueArray = $selector->values(true); $fieldtype = $field->type; $operator = $selector->operator; + if($operator === '<>') $operator = '!='; foreach($valueArray as $value) { // shortcut for blank value condition: this ensures that NULL/non-existence is considered blank // without this section the query would still work, but a blank value must actually be present in the field - $useEmpty = empty($value) || ($value && $operator[0] == '<') || ($value < 0 && $operator[0] == '>'); + $isEmptyValue = $fieldtype->isEmptyValue($field, $value); + $useEmpty = $isEmptyValue || $operator[0] === '<' || ((int) $value < 0 && $operator[0] === '>'); if($subfield == 'data' && $useEmpty && $fieldtype) { // && !$fieldtype instanceof FieldtypeMulti) { - if(empty($value)) $numEmptyValues++; - if(in_array($operator, array('=', '!=', '<>', '<', '<=', '>', '>='))) { + if($isEmptyValue) $numEmptyValues++; + if(in_array($operator, array('=', '!=', '<', '<=', '>', '>='))) { // we only accommodate this optimization for single-value selectors... if($this->whereEmptyValuePossible($field, $selector, $query, $value, $whereFields)) { if(count($valueArray) > 1 && $operator == '=') $whereFieldsType = 'OR'; diff --git a/wire/modules/Fieldtype/FieldtypeCheckbox.module b/wire/modules/Fieldtype/FieldtypeCheckbox.module index b7bc2e54..7fe1f9b4 100644 --- a/wire/modules/Fieldtype/FieldtypeCheckbox.module +++ b/wire/modules/Fieldtype/FieldtypeCheckbox.module @@ -58,6 +58,17 @@ class FieldtypeCheckbox extends Fieldtype { return $schema; } + /** + * @param DatabaseQuerySelect $query + * @param string $table + * @param string $subfield + * @param string $operator + * @param mixed $value + * + * @return DatabaseQuery|DatabaseQuerySelect + * @throws WireException + * + */ public function getMatchQuery($query, $table, $subfield, $operator, $value) { if(!empty($value) && ($operator == '!=' || $operator == '<>')) { // allow for matching test_checkbox!=1 since non-checked rows don't appear in database @@ -84,6 +95,32 @@ class FieldtypeCheckbox extends Fieldtype { $info['input'] = 'checkbox'; return $info; } + + /** + * Get an array of Fieldtypes that are compatible with this one + * + * This represents the list of Fieldtype modules that the user is allowed to change to from this one. + * + * @param Field $field + * @return Fieldtypes|null + * + */ + public function ___getCompatibleFieldtypes(Field $field) { + if($field) {} + $fieldtypes = $this->wire(new Fieldtypes()); + $toggleClass = 'FieldtypeToggle'; + $allowToggle = $this->wire('modules')->isInstalled($toggleClass); + + foreach($this->wire('fieldtypes') as $fieldtype) { + if($fieldtype instanceof FieldtypeCheckbox) { + $fieldtypes->add($fieldtype); + } else if($allowToggle && wireInstanceOf($fieldtype, $toggleClass)) { + $fieldtypes->add($fieldtype); + } + } + + return $fieldtypes; + } } diff --git a/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module b/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module index 0fc8e678..ef8ee1c3 100644 --- a/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module +++ b/wire/modules/Fieldtype/FieldtypeComments/FieldtypeComments.module @@ -596,12 +596,6 @@ class FieldtypeComments extends FieldtypeMulti { foreach($itemsRemoved as $item) { if(!$item->id) continue; $this->deleteComment($page, $field, $item, 'deleted from savePageField()'); - /* - $query = $database->prepare("DELETE FROM `$table` WHERE id=:item_id AND pages_id=:pages_id"); - $query->bindValue(":item_id", $item->id, \PDO::PARAM_INT); - $query->bindValue(":pages_id", $page->id, \PDO::PARAM_INT); - $query->execute(); - */ } } @@ -652,21 +646,27 @@ class FieldtypeComments extends FieldtypeMulti { $sql .= "sort=:sort"; $binds['sort'] = ++$maxSort; } - $query = $database->prepare($sql); - foreach($binds as $k => $v) $query->bindValue(":$k", $v); try { + $query = $database->prepare($sql); + foreach($binds as $k => $v) { + $query->bindValue(":$k", $v); + } $result = $query->execute(); - if(!$value['id']) { + if($result && !$value['id']) { // populate newly added comment ID to Comment object $value['id'] = $database->lastInsertId(); foreach($allItems as $item) { if(!$item->id && $item->code === $value['code']) $item->id = $value['id']; } } + $error = ''; } catch(\Exception $e) { $result = false; + $error = $e->getMessage(); + } + if(!$result) { + $this->error("Error saving comment id $value[id]: $error", Notice::log); } - if(!$result) $this->error("Error saving item $value[id] in savePageField", Notice::log); } return true; diff --git a/wire/modules/Inputfield/InputfieldRadios/InputfieldRadios.module b/wire/modules/Inputfield/InputfieldRadios/InputfieldRadios.module index 273d8c3b..1f3398b3 100644 --- a/wire/modules/Inputfield/InputfieldRadios/InputfieldRadios.module +++ b/wire/modules/Inputfield/InputfieldRadios/InputfieldRadios.module @@ -27,6 +27,9 @@ class InputfieldRadios extends InputfieldSelect { } public function ___render() { + + /** @var Sanitizer $sanitizer */ + $sanitizer = $this->wire('sanitizer'); $defaults = array( 'wbr' => true, @@ -58,31 +61,41 @@ class InputfieldRadios extends InputfieldSelect { } foreach($options as $key => $value) { + $checked = ''; - - $id = $this->id . "_" . $this->wire('sanitizer')->name($key); - + $id = $this->id . "_" . $sanitizer->name($key); $attrs = $this->getOptionAttributes($key); + + $inputClass = trim($this->attr('class')); + if(isset($attrs['input.class'])) $inputClass .= ' ' . $attrs['input.class']; + if($this->isOptionSelected($key)) $checked = " checked='checked'"; $disabled = empty($attrs['disabled']) ? "" : " disabled='disabled'"; - unset($attrs['selected'], $attrs['checked'], $attrs['disabled']); + + unset($attrs['selected'], $attrs['checked'], $attrs['disabled'], $attrs['input.class']); + $textClass = $settings['noSelectLabels'] ? 'pw-no-select' : ''; if($disabled) $textClass .= ' ui-state-disabled'; + $attrs = $this->getOptionAttributesString($attrs); if($attrs) $attrs = ' ' . $attrs; + $label = $settings['wbr'] ? str_replace(' ', ' !wbr!', $value) : $value; $label = $this->entityEncode($label, Inputfield::textFormatBasic); if($settings['wbr']) $label = str_replace('!wbr!', '', $label); - $class = trim($this->wire('sanitizer')->entities($this->attr('class'))); + + $inputName = $sanitizer->entities($this->attr('name')); + $inputValue = $sanitizer->entities($key); + $inputClass = trim($sanitizer->entities($inputClass)); $out .= "" . "" . + "class='$inputClass' " . + "value='$inputValue' />" . "$label" . ""; } diff --git a/wire/modules/Inputfield/InputfieldSelector/InputfieldSelector.module b/wire/modules/Inputfield/InputfieldSelector/InputfieldSelector.module index 5eaf090d..143efdd6 100644 --- a/wire/modules/Inputfield/InputfieldSelector/InputfieldSelector.module +++ b/wire/modules/Inputfield/InputfieldSelector/InputfieldSelector.module @@ -1351,15 +1351,21 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule { if($type != 'checkbox' && !isset($this->systemFields[$fieldName]) && !isset($this->modifierFields[$fieldName])) { // allow for a "None" option to find pages that have no selections for the field $none = '0'; + $hasNone = false; foreach($options as $value => $label) { // if select is using "0" as a literal selectable value, don't consider it as "None" if($value === 0 || $value === '0') { $none = '""'; + } else if($value === '""' || $value === "''") { + // if it already literal quoted blank string then we should not show a none value at all + $hasNone = true; break; } } - $selected = $selectedValue == $none || $selectedValue == '""' ? ' selected' : ''; - $out .= "" . $this->_('None') . ""; + if(!$hasNone) { + $selected = $selectedValue == $none || $selectedValue == '""' ? ' selected' : ''; + $out .= "" . $this->_('None') . ""; + } } // render each option diff --git a/wire/modules/Process/ProcessField/ProcessField.module b/wire/modules/Process/ProcessField/ProcessField.module index d4d71329..54c8d77d 100644 --- a/wire/modules/Process/ProcessField/ProcessField.module +++ b/wire/modules/Process/ProcessField/ProcessField.module @@ -1379,6 +1379,9 @@ class ProcessField extends Process implements ConfigurableModule { * */ protected function ___buildEditFormBasics() { + + /** @var Fields $fields */ + $fields = $this->wire('fields'); /** @var InputfieldWrapper $form */ $form = $this->wire(new InputfieldWrapper()); @@ -1406,10 +1409,9 @@ class ProcessField extends Process implements ConfigurableModule { if(!$this->field->id) $field->description = $this->_("After selecting your field type and saving, you may be presented with additional configuration options specific to the field type you selected."); // Note that appears when adding new field - if($this->field->type) $fieldtypes = $this->field->type->getCompatibleFieldtypes($this->field); - else $fieldtypes = $this->fieldtypes; + $fieldtypes = $fields->getCompatibleFieldtypes($this->field); - if($fieldtypes && count($fieldtypes)) { + if(count($fieldtypes)) { $fieldtypeLabels = array(); foreach($fieldtypes as $fieldtype) { /** @var Fieldtype $fieldtype */ @@ -1418,7 +1420,7 @@ class ProcessField extends Process implements ConfigurableModule { $fieldtypeLabels[$label] = $fieldtype; } ksort($fieldtypeLabels); - $advanced = $this->config->advanced; + $advanced = $this->wire('config')->advanced; foreach($fieldtypeLabels as $label => $fieldtype) { if(!$advanced && $fieldtype->isAdvanced() && $this->field->name != 'title' && $field->value != $fieldtype->className()) continue; @@ -1430,7 +1432,7 @@ class ProcessField extends Process implements ConfigurableModule { if(!$this->field->id) { $names = array(); - foreach($this->wire('fields') as $f) { + foreach($fields as $f) { if(($f->flags & Field::flagSystem) && !$this->wire('config')->advanced) continue; if(strpos($f->name, '_END')) continue; $names['_' . $f->name] = $f->name;