From a5e397d00529e2a591ebbc73df1abb89ac40ecb4 Mon Sep 17 00:00:00 2001 From: Ryan Cramer Date: Fri, 18 Mar 2022 13:49:01 -0400 Subject: [PATCH] Additional updates for processwire/processwire-issues#1467 --- wire/core/Database.php | 1 + wire/core/PagefilesManager.php | 5 +- wire/core/PagesTrash.php | 4 +- wire/core/Process.php | 4 +- wire/core/WireDateTime.php | 82 +++++++++++- wire/core/WireFileTools.php | 2 +- .../modules/Fieldtype/FieldtypeInteger.module | 2 +- .../FieldtypeOptions/SelectableOption.php | 2 +- .../SelectableOptionManager.php | 4 +- .../InputfieldRepeater.module | 2 +- .../Fieldtype/FieldtypeSelector.module | 2 +- .../types/InputfieldDatetimeSelect.php | 8 +- .../InputfieldPage/InputfieldPage.module | 122 ++++++++++++------ .../InputfieldPageTableAjax.php | 2 +- .../InputfieldSelector.module | 2 +- .../LanguageSupportPageNames.module | 6 +- .../MarkupAdminDataTable.module | 2 +- .../Process/ProcessField/ProcessField.module | 4 +- .../ProcessPageAdd/ProcessPageAdd.module | 2 +- .../ProcessPageSearch.module | 8 +- .../parsedown/Parsedown.php | 4 +- 21 files changed, 194 insertions(+), 76 deletions(-) diff --git a/wire/core/Database.php b/wire/core/Database.php index 6636d969..da451799 100644 --- a/wire/core/Database.php +++ b/wire/core/Database.php @@ -95,6 +95,7 @@ class Database extends \mysqli implements WireDatabase { * @throws WireDatabaseException * */ + #[\ReturnTypeWillChange] public function query($sql, $resultmode = MYSQLI_STORE_RESULT) { static $timerTotalQueryTime = 0; diff --git a/wire/core/PagefilesManager.php b/wire/core/PagefilesManager.php index 0dfa3b3d..9edf3d62 100644 --- a/wire/core/PagefilesManager.php +++ b/wire/core/PagefilesManager.php @@ -31,7 +31,7 @@ * * #pw-body * - * ProcessWire 3.x, Copyright 2016 by Ryan Cramer + * ProcessWire 3.x, Copyright 2022 by Ryan Cramer * https://processwire.com * * @method save() #pw-hooker @@ -301,7 +301,8 @@ class PagefilesManager extends Wire { * */ protected function _createPath($path) { - if(is_dir($path)) return true; + if(empty($path)) return false; + if(is_dir("$path")) return true; return $this->wire('files')->mkdir($path, true); } diff --git a/wire/core/PagesTrash.php b/wire/core/PagesTrash.php index d5e4fdc6..298a8f64 100644 --- a/wire/core/PagesTrash.php +++ b/wire/core/PagesTrash.php @@ -79,7 +79,7 @@ class PagesTrash extends Wire { if($languages && $languages->hasPageNames()) { foreach($languages as $language) { if($language->isDefault()) continue; - $langName = $page->get("name$language->id"); + $langName = (string) $page->get("name$language->id"); if(!strlen($langName)) continue; $page->set("name$language->id", $name . "_" . $langName); } @@ -227,7 +227,7 @@ class PagesTrash extends Wire { foreach($languages as $language) { /** @var Language $language */ if($language->isDefault()) continue; - $langName = $page->get("name$language->id"); + $langName = (string) $page->get("name$language->id"); if(!strlen($langName)) continue; if(strpos($langName, $trashPrefix) === 0) { list(,$langName) = explode('_', $langName); diff --git a/wire/core/Process.php b/wire/core/Process.php index 0952fd2c..ee8feed3 100644 --- a/wire/core/Process.php +++ b/wire/core/Process.php @@ -483,14 +483,14 @@ abstract class Process extends WireData implements Module { $id = $item->id; $name = $item->name; $label = (string) $item->{$options['itemLabel']}; - $icon = str_replace(array('icon-', 'fa-'),'', $item->{$options['iconKey']}); + $icon = str_replace(array('icon-', 'fa-'),'', (string) $item->{$options['iconKey']}); $class = $item->{$options['classKey']}; } else if(is_array($item)) { $id = isset($item['id']) ? $item['id'] : ''; $name = isset($item['name']) ? $item['name'] : ''; $label = isset($item[$options['itemLabel']]) ? $item[$options['itemLabel']] : ''; $class = isset($item[$options['classKey']]) ? $item[$options['classKey']] : ''; - if(isset($item[$options['iconKey']])) $icon = str_replace(array('icon-', 'fa-'),'', $item[$options['iconKey']]); + if(isset($item[$options['iconKey']])) $icon = str_replace(array('icon-', 'fa-'),'', (string) $item[$options['iconKey']]); } else { $this->error("Item must be object or array: $item"); continue; diff --git a/wire/core/WireDateTime.php b/wire/core/WireDateTime.php index 59725284..26e91977 100644 --- a/wire/core/WireDateTime.php +++ b/wire/core/WireDateTime.php @@ -286,7 +286,7 @@ class WireDateTime extends Wire { } else { $TRIM0 = false; } - $value = strftime($format, $value); + $value = $this->strftime($format, $value); if($TRIM0) $value = str_replace(array('TRIM00', 'TRIM0'), '', $value); } else { @@ -412,7 +412,7 @@ class WireDateTime extends Wire { else if($format == 'r') $value = $this->relativeTimeStr($ts, 1); else if($format == 'r-') $value = $this->relativeTimeStr($ts, 1, false); else if($format == 'ts') $value = $ts; - else if(strpos($format, '%') !== false) $value = strftime($format, $ts); + else if(strpos($format, '%') !== false && version_compare(PHP_VERSION, '8.1.0', '<')) $value = $this->strftime($format, $ts); else $value = date($format, $ts); return $value; } @@ -450,6 +450,84 @@ class WireDateTime extends Wire { return strtotime($str, $options['baseTimestamp']) ; } + /** + * strftime() replacement function that works in PHP 8.1+ (though not locale aware) + * + * @param string $format + * @param null|int|string $timestamp + * @return string|false + * @since 3.0.197 + * + */ + public function strftime($format, $timestamp = null) { + + $format = (string) $format; + + if(is_string($timestamp)) { + if(empty($timestamp)) { + $timestamp = null; + } else if(ctype_digit($timestamp)) { + $timestamp = (int) $timestamp; + } else { + $timestamp = $this->strtotime($timestamp); + } + } + + if($timestamp === null) $timestamp = time(); + + if(version_compare(PHP_VERSION, '8.1.0', '<')) { + return strftime($format, $timestamp); + } + + $format = $this->strftimeToDateFormat($format); + + return date($format, $timestamp); + } + + /** + * Convert strftime() format to date() format + * + * @param string $format + * @return string + * @since 3.0.197 + * + */ + protected function strftimeToDateFormat($format) { + + // replacements, in addition to those specified in self::$dateConversion + // strftime format => date format + $replacements = array( + '%e' => 'j', // Day of the month without leading zeros + '%j' => 'z', // Day of the year, 3 digits with leading zeros + '%U' => '_', // Week number of the given year, starting with the first Sunday as the first week (not implemented) + '%h' => 'M', // Abbreviated month name + '%C' => '_', // Two digit representation of the century (year divided by 100, truncated to an integer) (not implemented) + '%g' => 'y', // Two digit representation of the year going by ISO-8601:1988 standards (see %V) + '%G' => 'Y', // 4 digit year + '%k' => 'G', // Hour in 24-hour format + '%l' => 'g', // Hour in 12-hour format + '%r' => 'h:i:s A', // Example: 09:34:17 PM + '%R' => 'G:i', // Example: 00:35 for 12:35 AM + '%T' => 'G:i:s', // Example: 21:34:17 for 09:34:17 PM + '%X' => 'G:i:s', // Preferred time representation based on locale, without the date, Example: 03:59:16 or 15:59:16 + '%Z' => 'T', // The time zone abbreviation. Example: EST for Eastern Time + '%c' => 'Y-m-d H:i:s', // Preferred date and time stamp based on locale + '%D' => 'm/d/y', // Example: 02/05/09 for February 5, 2009 + '%F' => 'Y-m-d', // Example: 2009-02-05 for February 5, 2009 + '%n' => '\\n', // newline + '%t' => '\\t', // tab + '%%' => '%', // literal percent + ); + + foreach(self::$dateConversion as $dateFormat => $formats) { + $strftimeFormat = $formats[0]; + if(empty($strftimeFormat)) continue; + if(strpos($format, $strftimeFormat) !== false) $replacements[$strftimeFormat] = $dateFormat; + } + + return strtr($format, $replacements); + } + /** * Given a unix timestamp (or date string), returns a formatted string indicating the time relative to now diff --git a/wire/core/WireFileTools.php b/wire/core/WireFileTools.php index d0f1011d..48f6b0af 100644 --- a/wire/core/WireFileTools.php +++ b/wire/core/WireFileTools.php @@ -38,7 +38,7 @@ class WireFileTools extends Wire { * */ public function mkdir($path, $recursive = false, $chmod = null) { - if(!strlen($path)) return false; + if(!strlen("$path")) return false; if(is_string($recursive) && strlen($recursive) > 2) { // chmod argument specified as $recursive argument or arguments swapped diff --git a/wire/modules/Fieldtype/FieldtypeInteger.module b/wire/modules/Fieldtype/FieldtypeInteger.module index 626415f7..447ff71a 100644 --- a/wire/modules/Fieldtype/FieldtypeInteger.module +++ b/wire/modules/Fieldtype/FieldtypeInteger.module @@ -225,7 +225,7 @@ class FieldtypeInteger extends Fieldtype { $f->label = $this->_('Default value'); $f->description = $this->_('This value is assigned as the default for this field on pages with no value entered.'); $f->collapsed = Inputfield::collapsedBlank; - $f->attr('value', strlen($field->get('defaultValue')) ? (int) $field->get('defaultValue') : ''); + $f->attr('value', strlen((string) $field->get('defaultValue')) ? (int) $field->get('defaultValue') : ''); $inputfields->add($f); return $inputfields; diff --git a/wire/modules/Fieldtype/FieldtypeOptions/SelectableOption.php b/wire/modules/Fieldtype/FieldtypeOptions/SelectableOption.php index 668e2911..f6fabebe 100644 --- a/wire/modules/Fieldtype/FieldtypeOptions/SelectableOption.php +++ b/wire/modules/Fieldtype/FieldtypeOptions/SelectableOption.php @@ -111,7 +111,7 @@ class SelectableOption extends WireData { // implements LanguagesValueInterface } else { $value = parent::get("$property$language"); // fallback to default language title if no title present for language - if(!strlen($value)) $value = parent::get($property); + if(!strlen("$value")) $value = parent::get($property); } } else { $value = parent::get($property); diff --git a/wire/modules/Fieldtype/FieldtypeOptions/SelectableOptionManager.php b/wire/modules/Fieldtype/FieldtypeOptions/SelectableOptionManager.php index 51f29b79..894bda7e 100644 --- a/wire/modules/Fieldtype/FieldtypeOptions/SelectableOptionManager.php +++ b/wire/modules/Fieldtype/FieldtypeOptions/SelectableOptionManager.php @@ -371,8 +371,8 @@ class SelectableOptionManager extends Wire { $out = ''; foreach($options as $option) { - $title = trim($option->get("title$language")); - $value = trim($option->get("value$language")); + $title = trim((string) $option->get("title$language")); + $value = trim((string) $option->get("value$language")); $titleLength = strlen($title); $valueLength = strlen($value); if(!$titleLength && !$valueLength) continue; diff --git a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module index bad0f8ba..0d6fef84 100644 --- a/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module +++ b/wire/modules/Fieldtype/FieldtypeRepeater/InputfieldRepeater.module @@ -686,7 +686,7 @@ class InputfieldRepeater extends Inputfield implements InputfieldItemList { ); $readyPage->set('_repeater_clone', $clonePage->id); } else if(!$cloneItemID) { - $notIDs = $this->wire()->sanitizer->intArray(explode(',', trim($this->wire()->input->get('repeater_not'), ','))); + $notIDs = $this->wire()->sanitizer->intArray(explode(',', trim((string) $this->wire()->input->get('repeater_not'), ','))); $readyPage = $this->getNextReadyPage($notIDs); $readyPage->removeStatus(Page::statusHidden); } diff --git a/wire/modules/Fieldtype/FieldtypeSelector.module b/wire/modules/Fieldtype/FieldtypeSelector.module index bb787901..605b2c27 100644 --- a/wire/modules/Fieldtype/FieldtypeSelector.module +++ b/wire/modules/Fieldtype/FieldtypeSelector.module @@ -61,7 +61,7 @@ class FieldtypeSelector extends Fieldtype { public function ___wakeupValue(Page $page, Field $field, $value) { $value = parent::___wakeupValue($page, $field, $value); - $initValue = trim($field->get('initValue')); + $initValue = trim((string) $field->get('initValue')); if(strlen($initValue) && strpos($value, $initValue) === false) { $value = "$initValue, $value"; } diff --git a/wire/modules/Inputfield/InputfieldDatetime/types/InputfieldDatetimeSelect.php b/wire/modules/Inputfield/InputfieldDatetime/types/InputfieldDatetimeSelect.php index 217ee892..fa431e2d 100644 --- a/wire/modules/Inputfield/InputfieldDatetime/types/InputfieldDatetimeSelect.php +++ b/wire/modules/Inputfield/InputfieldDatetime/types/InputfieldDatetimeSelect.php @@ -75,7 +75,8 @@ class InputfieldDatetimeSelect extends InputfieldDatetimeType { $yearLock = $this->getSetting('yearLock'); $format = $this->getSetting('dateSelectFormat'); $select = $this->modules->get('InputfieldSelect'); /** @var InputfieldSelect $select */ - $sanitizer = $this->wire('sanitizer'); /** @var Sanitizer $sanitizer */ + $sanitizer = $this->wire()->sanitizer; + $datetime = $this->wire()->datetime; $monthLabel = $this->_('Month'); $yearLabel = $this->_('Year'); $dayLabel = $this->_('Day'); @@ -90,7 +91,7 @@ class InputfieldDatetimeSelect extends InputfieldDatetimeType { for($n = 1; $n <= 12; $n++) { $monthFormat = $abbreviate ? '%b' : '%B'; - $monthLabel = $sanitizer->entities(strftime($monthFormat, mktime(0, 0, 0, $n, 1))); + $monthLabel = $sanitizer->entities($datetime->strftime($monthFormat, mktime(0, 0, 0, $n, 1))); $months->addOption($n, $monthLabel); } @@ -211,7 +212,8 @@ class InputfieldDatetimeSelect extends InputfieldDatetimeType { public function getConfigInputfields(InputfieldWrapper $inputfields) { list($y, $d, $h, $hh, $i, $a) = explode(' ', date('Y d h H i A')); - list($m, $mm) = explode(' ', strftime('%b %B')); + // list($m, $mm) = explode(' ', strftime('%b %B')); // strftime deprecated + list($m, $mm) = explode(' ', date('M F')); $none = $this->_('None'); if($m === $mm && $m === 'May') list($m, $mm) = array('Apr', 'April'); diff --git a/wire/modules/Inputfield/InputfieldPage/InputfieldPage.module b/wire/modules/Inputfield/InputfieldPage/InputfieldPage.module index 2e525f8a..2c5dea7d 100644 --- a/wire/modules/Inputfield/InputfieldPage/InputfieldPage.module +++ b/wire/modules/Inputfield/InputfieldPage/InputfieldPage.module @@ -139,7 +139,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { foreach(self::$defaultConfig as $key => $value) { $this->set($key, $value); } - $this->attr('value', $this->wire('pages')->newPageArray()); + $this->attr('value', $this->wire()->pages->newPageArray()); parent::init(); } @@ -807,6 +807,8 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { * */ protected function ___renderAddable() { + + $pages = $this->wire()->pages; $parent_id = $this->getSetting('parent_id'); $template_id = $this->getSetting('template_id'); @@ -816,17 +818,18 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { if($labelFieldName && $labelFieldName != 'title') return ''; - $parent = $this->wire('pages')->get($parent_id); + $parent = $pages->get($parent_id); - $test = $this->wire('pages')->newPage($template_id); + $test = $pages->newPage($template_id); $test->parent = $parent; $test->id = -1; // prevents permissions check from failing if(!$parent->addable($test)) return ''; if(!$test->publishable()) return ''; - $inputfield = $this->wire('modules')->get($this->getInputfieldClass()); + $inputfield = $this->wire()->modules->get($this->getInputfieldClass()); if(!$inputfield) return ''; + $key = "_{$this->name}_add_items"; if($inputfield instanceof InputfieldHasArrayValue || $inputfield instanceof InputfieldSupportsArrayValue) { @@ -844,12 +847,12 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $out = "
" . - "

$label

" . - "

" . - "" . - "$input" . - "$notes" . - "

" . + "

$label

" . + "

" . + "" . + "$input" . + "$notes" . + "

" . "
"; return $out; @@ -880,7 +883,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $of = $p->of(); $p->of(true); $v = $labelFieldFormat ? $p->getText($labelFieldFormat, true, true) : $p->get($labelFieldName); - if(!strlen($v)) $v = $p->get('name'); + if(!strlen("$v")) $v = (string) $p->get('name'); $out .= "
  • $v
  • "; $p->of($of); } @@ -890,7 +893,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $of = $value->of(); $value->of(true); $out = $labelFieldFormat ? $value->getText($labelFieldFormat, true, true) : $value->get($labelFieldName); - if(!strlen($out)) $out = $value->get('name'); + if(!strlen("$out")) $out = (string) $value->get('name'); $value->of($of); } else { @@ -1013,9 +1016,13 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { */ protected function ___processInputAddPages($input) { - $this->pagesAdded = $this->wire('pages')->newPageArray(); + $pages = $this->wire()->pages; + $sanitizer = $this->wire()->sanitizer; + + $this->pagesAdded = $pages->newPageArray(); $parent_id = $this->getSetting('parent_id'); $template_id = $this->getSetting('template_id'); + $template = $this->wire()->templates->get((int) $template_id); if(!$this->getSetting('addable') || !$parent_id || !$template_id) return; @@ -1025,7 +1032,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { if(empty($value)) return; - $parent = $this->pages->get($parent_id); + $parent = $pages->get($parent_id); $sort = $parent->numChildren; $titles = explode("\n", $value); $n = 0; @@ -1033,8 +1040,9 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { foreach($titles as $title) { // check if there is an existing page using this title - $selector = "include=all, templates_id=$template_id, title=" . $this->wire('sanitizer')->selectorValue($title); + $selector = "include=all, templates_id=$template_id, title=" . $sanitizer->selectorValue($title); $existingPage = $parent->child($selector); + if($existingPage->id) { // use existing page $this->pagesAdded->add($existingPage); @@ -1048,8 +1056,8 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { } // create a new page - $page = $this->wire('pages')->newPage(array( - 'template' => $template_id, + $page = $pages->newPage(array( + 'template' => $template, 'parent' => $parent, 'title' => trim($title), 'sort' => $sort++, @@ -1114,9 +1122,12 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { * * @return InputfieldWrapper * @throws WireException + * @todo move to separate config.php file * */ public function ___getConfigInputfields() { + $modules = $this->wire()->modules; + // let the module know it's being used for configuration purposes $this->configMode = true; $exampleLabel = $this->_('Example:') . ' '; @@ -1124,8 +1135,9 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $inputfields = new InputfieldWrapper(); $this->wire($inputfields); - - $fieldset = $this->wire('modules')->get('InputfieldFieldset'); + + /** @var InputfieldFieldset $fieldset */ + $fieldset = $modules->get('InputfieldFieldset'); $fieldset->label = $this->_('Selectable pages'); $fieldset->attr('name', '_selectable_pages'); $fieldset->description = $this->_('Use at least one of the options below to determine which pages will be selectable with this field.'); @@ -1133,7 +1145,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $selectablePagesFieldset = $fieldset; /** @var InputfieldPageListSelect $field */ - $field = $this->modules->get('InputfieldPageListSelect'); + $field = $modules->get('InputfieldPageListSelect'); $field->setAttribute('name', 'parent_id'); $field->label = $this->_('Parent'); $field->attr('value', (int) $this->parent_id); @@ -1144,7 +1156,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $fieldset->append($field); /** @var InputfieldSelect $field */ - $field = $this->modules->get('InputfieldSelect'); + $field = $modules->get('InputfieldSelect'); $field->setAttribute('name', 'template_id'); $field->label = $this->_('Template'); $field->description = $this->_('Select the template of the pages that are selectable. May be used instead of, or in addition to, the parent above.'); // Description for Template of selectable pages @@ -1160,8 +1172,9 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $templateIDs = $this->getTemplateIDs(); $key = array_search($template_id, $templateIDs); if(is_int($key)) unset($templateIDs[$key]); + /** @var InputfieldAsmSelect $field */ - $field = $this->modules->get('InputfieldAsmSelect'); + $field = $modules->get('InputfieldAsmSelect'); $field->attr('name', 'template_ids'); $field->label = $this->_('Additional templates'); $field->description = $this->_('If you need additional templates for selectable pages, select them here.'); @@ -1181,7 +1194,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $extra = $this->_('While this overrides parent and template selections above, those selections (if present) are still used for validation.'); // Additional notes /** @var InputfieldSelector $field */ - $field = $this->modules->get('InputfieldSelector'); + $field = $modules->get('InputfieldSelector'); $field->description = $this->_('Add one or more fields below to create a query that finds the pages you want to make selectable.'); $field->description .= ' ' . $this->_('This creates a selector that finds pages at runtime. If you prefer to enter this manually, use the “Selector string” option below instead.'); $field->description .= ' ' . $extra; @@ -1199,7 +1212,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { /** @var InputfieldText $field */ - $field = $this->modules->get('InputfieldText'); + $field = $modules->get('InputfieldText'); $field->attr('name', 'findPagesSelector'); $field->label = $this->_('Selector string'); $field->attr('value', $this->findPagesSelector); @@ -1213,7 +1226,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { if($this->findPagesCode) { // allow only if already present, as this option is deprecated /** @var InputfieldTextarea $field */ - $field = $this->modules->get('InputfieldTextarea'); + $field = $modules->get('InputfieldTextarea'); $field->attr('name', 'findPagesCode'); $field->attr('value', $this->findPagesCode); $field->attr('rows', 4); @@ -1224,7 +1237,8 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $field->notes = $exampleLabel . $this->_('return $page->parent->parent->children("name=locations")->first()->children();'); // Example of Custom PHP code to find selectable pages $field->collapsed = Inputfield::collapsedBlank; } else { - $field = $this->modules->get('InputfieldMarkup'); + /** @var InputfieldMarkup $field */ + $field = $modules->get('InputfieldMarkup'); $field->attr('name', '_findPagesCode'); $field->collapsed = Inputfield::collapsedYes; $if = "\$event->object->" . @@ -1251,7 +1265,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $inputfields->append($fieldset); /** @var InputfieldSelect $field */ - $field = $this->modules->get('InputfieldSelect'); + $field = $modules->get('InputfieldSelect'); $field->attr('name', 'labelFieldName'); $field->label = $this->_('Label field'); $field->required = true; @@ -1261,7 +1275,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $field->addOption('.', $this->_('Custom format (multiple fields)' . ' ...')); $field->columnWidth = 50; - if($this->wire('fields')->get('title')) { + if($this->wire()->fields->get('title')) { $field->addOption('title', 'title' . $defaultLabel); $field->addOption('name', 'name'); $titleIsDefault = true; @@ -1271,7 +1285,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { } $field->addOption('path', 'path'); - foreach($this->wire('fields') as $f) { + foreach($this->wire()->fields as $f) { if(!$f->type instanceof FieldtypeText) continue; if($f->type instanceof FieldtypeTextarea) continue; if($titleIsDefault && $f->name == 'title') continue; @@ -1291,7 +1305,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $inputfields->append($field); /** @var InputfieldText $field */ - $field = $this->modules->get('InputfieldText'); + $field = $modules->get('InputfieldText'); $field->attr('name', 'labelFieldFormat'); $field->attr('value', $this->labelFieldFormat); $field->label = $this->_('Custom page label format'); @@ -1306,12 +1320,14 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { if(!$this->inputfield) $this->inputfield = 'InputfieldSelect'; /** @var InputfieldSelect $field */ - $field = $this->modules->get('InputfieldSelect'); + $field = $modules->get('InputfieldSelect'); $field->setAttribute('name', 'inputfield'); $field->setAttribute('value', $this->inputfield); $field->label = $this->_('Input field type'); $field->description = $this->_('The type of input field (Inputfield module) that will be used to select page(s) for this field.'); - $field->description .= ' ' . $this->_('Select one that is consistent with your “Value type” selection on the “Details” tab for single or multiple-page selection.'); + if($this->hasFieldtype !== false) { + $field->description .= ' ' . $this->_('Select one that is consistent with your “Value type” selection on the “Details” tab for single or multiple-page selection.'); + } $field->notes = $this->_('After selecting an input field type and saving changes, please note that additional configuration options specific to your selection may appear directly below this.'); $field->required = true; $field->icon = 'plug'; @@ -1326,9 +1342,9 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { if($this->hasFieldtype) $inputfieldClasses = array_merge(self::$defaultInputfieldClasses, $inputfieldClasses); foreach($inputfieldClasses as $class) { - $module = $this->modules->getModule($class, array('noInit' => true)); - $info = $this->modules->getModuleInfo($module); - $label = ucfirst($info['title']); + $module = $modules->getModule($class, array('noInit' => true)); + $info = $modules->getModuleInfo($module); + $label = ucfirst((string) $info['title']); if($module instanceof InputfieldPageListSelection) { $pageListTypes[] = $class; } @@ -1346,12 +1362,30 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $field->addOption($this->_('Single page selection'), $singles); $field->addOption($multiLabel, $multiples); $field->addOption($multiLabel . ' (' . $this->_('sortable') . ')', $sortables); - $inputfields->insertBefore($field, $selectablePagesFieldset); - - if($this->hasFieldtype !== false) { + $inputfields->insertBefore($field, $selectablePagesFieldset); + + if($this->hasFieldtype === false) { + /** @var InputfieldRadios $field */ + /* + $field = $modules->get('InputfieldRadios'); + $field->attr('name', 'derefAsPage'); + $field->label = $this->_('Value type'); + $field->addOption(FieldtypePage::derefAsPageArray, + $this->_('PageArray') . ' ' . + '[span.detail] ' . $this->_('(works for all cases but required for multiple selection)') . ' [/span]' + ); + $field->addOption(FieldtypePage::derefAsPageOrNullPage, + $this->_('Page') . ' ' . + '[span.detail] ' . $this->_('(optional for single page selection)') . ' [/span]' + ); + $field->attr('value', (int) $this->derefAsPage); + $inputfields->add($field); + */ + + } else { /** @var InputfieldMarkup $f */ - $f = $this->modules->get('InputfieldMarkup'); + $f = $modules->get('InputfieldMarkup'); $f->label = $this->_('Regarding “Page List” input types'); $f->icon = 'warning'; $f->showIf = 'inputfield=' . implode('|', $pageListTypes); @@ -1362,8 +1396,9 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $this->_('If you want to make everything selectable, then specify nothing.') . '

    '; $inputfields->insertAfter($f, $field); - - $field = $this->modules->get('InputfieldCheckbox'); + + /** @var InputfieldCheckbox $field */ + $field = $modules->get('InputfieldCheckbox'); $field->attr('name', 'addable'); $field->attr('value', 1); $field->icon = 'lightbulb-o'; @@ -1389,7 +1424,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $inputfield = $this->getInputfield(); if($inputfield) { // tell it it's under control of a parent, regardless of whether this one is hasFieldtype true or not. - $info = $this->modules->getModuleInfo($inputfield); + $info = $modules->getModuleInfo($inputfield); $inputfield->hasFieldtype = $this->hasFieldtype ? $this->hasFieldtype : true; $inputfield->hasInputfield = $this; if($inputfield instanceof InputfieldSupportsPageSelector) { @@ -1397,7 +1432,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { $inputfield->setPageSelector($exampleSelector); } /** @var InputfieldFieldset $fieldset */ - $fieldset = $this->modules->get('InputfieldFieldset'); + $fieldset = $modules->get('InputfieldFieldset'); $n = 0; foreach($inputfield->___getConfigInputfields() as $f) { if(in_array($f->name, array('required', 'requiredIf', 'showIf', 'collapsed', 'columnWidth'))) continue; @@ -1419,6 +1454,7 @@ class InputfieldPage extends Inputfield implements ConfigurableModule { } $this->configMode = false; // reverse what was set at the top of this function + return $inputfields; } diff --git a/wire/modules/Inputfield/InputfieldPageTable/InputfieldPageTableAjax.php b/wire/modules/Inputfield/InputfieldPageTable/InputfieldPageTableAjax.php index 5433ddfd..6c1a3cc3 100644 --- a/wire/modules/Inputfield/InputfieldPageTable/InputfieldPageTableAjax.php +++ b/wire/modules/Inputfield/InputfieldPageTable/InputfieldPageTableAjax.php @@ -62,7 +62,7 @@ class InputfieldPageTableAjax extends Wire { if($itemID) $this->addItem($page, $field, $this->wire('pages')->get($itemID)); $sort = $input->get('InputfieldPageTableSort'); - if(strlen($sort)) $this->sortItems($page, $field, $sort); + if(strlen("$sort")) $this->sortItems($page, $field, $sort); $this->renderAjax($page, $field); } diff --git a/wire/modules/Inputfield/InputfieldSelector/InputfieldSelector.module b/wire/modules/Inputfield/InputfieldSelector/InputfieldSelector.module index b4a11706..8a7c4240 100644 --- a/wire/modules/Inputfield/InputfieldSelector/InputfieldSelector.module +++ b/wire/modules/Inputfield/InputfieldSelector/InputfieldSelector.module @@ -1888,7 +1888,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule { // convert the value attribute to a Selectors object try { - $value = trim($this->attr('value')); + $value = trim((string) $this->attr('value')); $this->selectors = $this->wire(new Selectors()); if(!$this->parseVars) $this->selectors->setParseVars(false); $this->selectors->setSelectorString($value); diff --git a/wire/modules/LanguageSupport/LanguageSupportPageNames.module b/wire/modules/LanguageSupport/LanguageSupportPageNames.module index 79972789..adda0329 100644 --- a/wire/modules/LanguageSupport/LanguageSupportPageNames.module +++ b/wire/modules/LanguageSupport/LanguageSupportPageNames.module @@ -181,7 +181,7 @@ class LanguageSupportPageNames extends WireData implements Module, ConfigurableM $pages = $this->wire()->pages; $page = $this->wire()->page; $process = $page ? $page->process : null; - $pageNumUrlPrefix = $this->get("pageNumUrlPrefix$language"); + $pageNumUrlPrefix = (string) $this->get("pageNumUrlPrefix$language"); if($process && $page->template->name === 'admin' && in_array('WirePageEditor', wireClassImplements($process))) { // when in admin, add inputs for each language's page name @@ -526,10 +526,10 @@ class LanguageSupportPageNames extends WireData implements Module, ConfigurableM // avoid having default language name inherited at homepage level // if($isDefault && $name === $parent->get("name")) continue; } - if(strlen($name)) $path .= "/" . $name; + if(strlen("$name")) $path .= "/" . $name; } - $name = $page->get("name$language|name"); + $name = (string) $page->get("name$language|name"); $path = strlen($name) ? "$path/$name/" : "$path/"; if(!$template->slashUrls && $path != '/') $path = rtrim($path, '/'); diff --git a/wire/modules/Markup/MarkupAdminDataTable/MarkupAdminDataTable.module b/wire/modules/Markup/MarkupAdminDataTable/MarkupAdminDataTable.module index 43bca8b4..603960d0 100644 --- a/wire/modules/Markup/MarkupAdminDataTable/MarkupAdminDataTable.module +++ b/wire/modules/Markup/MarkupAdminDataTable/MarkupAdminDataTable.module @@ -300,7 +300,7 @@ class MarkupAdminDataTable extends ModuleJS { foreach($row as $td) { $class = ''; if(is_array($td)) list($td, $class) = $td; - if(strlen($td) == 0 || $td === ' ') $class .= ($class ? ' ' : '') . 'blank'; + if(strlen("$td") == 0 || $td === ' ') $class .= ($class ? ' ' : '') . 'blank'; if($class) $class = " class='$class'"; $out .= "\n\t\t\t$td"; } diff --git a/wire/modules/Process/ProcessField/ProcessField.module b/wire/modules/Process/ProcessField/ProcessField.module index 9db3969b..eae48c5a 100644 --- a/wire/modules/Process/ProcessField/ProcessField.module +++ b/wire/modules/Process/ProcessField/ProcessField.module @@ -2864,8 +2864,8 @@ class ProcessField extends Process implements ConfigurableModule { $valueStr = ((int) $value) ? $labels['on'] : $labels['off']; } - $originalValueStr = str_replace('|', ' ', $originalValueStr); - $valueStr = str_replace('|', ' ', $valueStr); + $originalValueStr = str_replace('|', ' ', (string) $originalValueStr); + $valueStr = str_replace('|', ' ', (string) $valueStr); $change = array( "name" => $name, "value" => $valueStr, diff --git a/wire/modules/Process/ProcessPageAdd/ProcessPageAdd.module b/wire/modules/Process/ProcessPageAdd/ProcessPageAdd.module index 345f66bc..f10010b5 100644 --- a/wire/modules/Process/ProcessPageAdd/ProcessPageAdd.module +++ b/wire/modules/Process/ProcessPageAdd/ProcessPageAdd.module @@ -1094,7 +1094,7 @@ class ProcessPageAdd extends Process implements ConfigurableModule, WirePageEdit $this->deleteOldTempPages(); // allow for nameFormat to come from a name_format GET variable - $nameFormat = $input->get('name_format'); + $nameFormat = (string) $input->get('name_format'); if(strlen($nameFormat)) { $nameFormat = $sanitizer->chars($sanitizer->text($nameFormat), '-_:./| [alpha][digit]', '-'); } else { diff --git a/wire/modules/Process/ProcessPageSearch/ProcessPageSearch.module b/wire/modules/Process/ProcessPageSearch/ProcessPageSearch.module index 3b5905fb..579ddda4 100644 --- a/wire/modules/Process/ProcessPageSearch/ProcessPageSearch.module +++ b/wire/modules/Process/ProcessPageSearch/ProcessPageSearch.module @@ -509,10 +509,10 @@ class ProcessPageSearch extends Process implements ConfigurableModule { */ protected function getDisplayFields() { - $display = $this->input->get('display'); + $display = (string) $this->input->get('display'); - if(!strlen($display)) $display = $this->input->get('get'); // as required by ProcessPageSearch API - if(!strlen($display)) $display = $this->displayField; + if(!strlen($display)) $display = (string) $this->input->get('get'); // as required by ProcessPageSearch API + if(!strlen($display)) $display = (string) $this->displayField; if(!strlen($display)) $display = 'title path'; $display = str_replace(',', ' ', $display); @@ -1354,7 +1354,7 @@ class ProcessPageSearch extends Process implements ConfigurableModule { */ public function renderSearchForm($placeholder = '') { - $q = substr($this->input->get('q'), 0, 128); + $q = substr((string) $this->input->get('q'), 0, 128); $q = $this->wire('sanitizer')->entities($q); $adminURL = $this->wire('config')->urls->admin; diff --git a/wire/modules/Textformatter/TextformatterMarkdownExtra/parsedown/Parsedown.php b/wire/modules/Textformatter/TextformatterMarkdownExtra/parsedown/Parsedown.php index ae0cbdec..512a444b 100755 --- a/wire/modules/Textformatter/TextformatterMarkdownExtra/parsedown/Parsedown.php +++ b/wire/modules/Textformatter/TextformatterMarkdownExtra/parsedown/Parsedown.php @@ -40,7 +40,7 @@ class Parsedown $this->DefinitionData = array(); # standardize line breaks - $text = str_replace(array("\r\n", "\r"), "\n", $text); + $text = str_replace(array("\r\n", "\r"), "\n", (string) $text); # remove surrounding line breaks $text = trim($text, "\n"); @@ -1135,7 +1135,7 @@ class Parsedown protected function lineElements($text, $nonNestables = array()) { # standardize line breaks - $text = str_replace(array("\r\n", "\r"), "\n", $text); + $text = str_replace(array("\r\n", "\r"), "\n", (string) $text); $Elements = array();