mirror of
https://github.com/processwire/processwire.git
synced 2025-08-08 15:57:01 +02:00
Various updates including optimizations to WireHooks, support for a hookable renderReadyHook method in Inputfield, cache prevention measures for Pages::findMany() per @apeisa, and some work in progress on InputfieldSelector support for improved "custom (field=value)" searches.
This commit is contained in:
@@ -43,17 +43,23 @@ class HookEvent extends WireData {
|
||||
|
||||
/**
|
||||
* Construct the HookEvent and establish default values
|
||||
*
|
||||
* @param array $eventData Optional event data to start with
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->set('object', null);
|
||||
$this->set('method', '');
|
||||
$this->set('arguments', array());
|
||||
$this->set('return', null);
|
||||
$this->set('replace', false);
|
||||
$this->set('options', array());
|
||||
$this->set('id', '');
|
||||
$this->set('cancelHooks', false);
|
||||
public function __construct(array $eventData = array()) {
|
||||
$data = array(
|
||||
'object' => null,
|
||||
'method' => '',
|
||||
'arguments' => array(),
|
||||
'return' => null,
|
||||
'replace' => false,
|
||||
'options' => array(),
|
||||
'id' => '',
|
||||
'cancelHooks' => false
|
||||
);
|
||||
if(!empty($eventData)) $data = array_merge($data, $eventData);
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,7 +208,7 @@ class HookEvent extends WireData {
|
||||
* ~~~~~
|
||||
*
|
||||
* @param string|null $hookId
|
||||
* @return $this
|
||||
* @return HookEvent|WireData $this
|
||||
*
|
||||
*/
|
||||
public function removeHook($hookId) {
|
||||
@@ -227,6 +233,5 @@ class HookEvent extends WireData {
|
||||
return $s;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
@@ -69,7 +69,7 @@
|
||||
* @property InputfieldWrapper|null $parent The parent InputfieldWrapper for this Inputfield or null if not set. #pw-internal
|
||||
* @property null|bool|Fieldtype $hasFieldtype The Fieldtype using this Inputfield, or boolean false when known not to have a Fieldtype, or null when not known. #pw-group-other
|
||||
* @property bool|null $useLanguages When multi-language support active, can be set to true to make it provide inputs for each language, where supported (default=false). #pw-group-behavior
|
||||
* @property null|bool|int $entityEncodeLabel Set to boolean false to specifically disable entity encoding of field header/label, or set to a Inputfield::textFormat constant. (default=true). #pw-group-output
|
||||
* @property null|bool|int $entityEncodeLabel Set to boolean false to specifically disable entity encoding of field header/label (default=true). #pw-group-output
|
||||
* @property null|bool $entityEncodeText Set to boolean false to specifically disable entity encoding for other text: description, notes, etc. (default=true). #pw-group-output
|
||||
* @property int $renderValueFlags Options that can be applied to renderValue mode, see "renderValue" constants (default=0). #pw-group-output
|
||||
* @property string $wrapClass Optional class name (CSS) to apply to the HTML element wrapping the Inputfield. #pw-group-other
|
||||
@@ -80,6 +80,7 @@
|
||||
* ================
|
||||
* @method string render()
|
||||
* @method string renderValue()
|
||||
* @method void renderReadyHook(Inputfield $parent, $renderValueMode)
|
||||
* @method Inputfield processInput(WireInputData $input)
|
||||
* @method InputfieldWrapper getConfigInputfields()
|
||||
* @method array getConfigArray()
|
||||
@@ -385,7 +386,7 @@ abstract class Inputfield extends WireData implements Module {
|
||||
*
|
||||
* @param string $key Name of property to set
|
||||
* @param mixed $value Value of property
|
||||
* @return $this
|
||||
* @return Inputfield|WireData
|
||||
*
|
||||
*/
|
||||
public function set($key, $value) {
|
||||
@@ -642,7 +643,7 @@ abstract class Inputfield extends WireData implements Module {
|
||||
* - String with attributes split by "+" or "|" to set them all to have the same value.
|
||||
* - Specify boolean true to get all attributes in an associative array.
|
||||
* @param string|int|null $value Value to set (if setting), omit otherwise.
|
||||
* @return mixed|$this If setting an attribute, it returns this instance. If getting an attribute, the attribute is returned.
|
||||
* @return Inputfield|array|string|int|object|float If setting an attribute, it returns this instance. If getting an attribute, the attribute is returned.
|
||||
* @see Inputfield::removeAttr(), Inputfield::addClass(), Inputfield::removeClass()
|
||||
*
|
||||
*/
|
||||
@@ -702,7 +703,7 @@ abstract class Inputfield extends WireData implements Module {
|
||||
* - Omit if getting an attribute.
|
||||
* - Value to set for $key of setting.
|
||||
* - Boolean false to remove the attribute specified for $key.
|
||||
* @return string|array|$this Returns one of the following:
|
||||
* @return Inputfield|string|array|null Returns one of the following:
|
||||
* - If getting, returns attribute value of NULL if not present.
|
||||
* - If setting, returns $this.
|
||||
* @see Inputfield::attr(), Inputfield::addClass()
|
||||
@@ -1030,9 +1031,24 @@ abstract class Inputfield extends WireData implements Module {
|
||||
public function renderReady(Inputfield $parent = null, $renderValueMode = false) {
|
||||
if($parent) {}
|
||||
if($renderValueMode) {}
|
||||
return $this->wire('modules')->loadModuleFileAssets($this) > 0;
|
||||
$result = $this->wire('modules')->loadModuleFileAssets($this) > 0;
|
||||
if($this->wire('hooks')->isMethodHooked($this, 'renderReadyHook')) {
|
||||
$this->renderReadyHook($parent, $renderValueMode);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hookable version of renderReady(), not called unless 'renderReadyHook' is hooked
|
||||
*
|
||||
* Hook this method instead if you want to hook renderReady().
|
||||
*
|
||||
* @param Inputfield $parent
|
||||
* @param bool $renderValueMode
|
||||
*
|
||||
*/
|
||||
public function ___renderReadyHook(Inputfield $parent = null, $renderValueMode) { }
|
||||
|
||||
/**
|
||||
* This hook was replaced by renderReady
|
||||
*
|
||||
@@ -1502,7 +1518,7 @@ abstract class Inputfield extends WireData implements Module {
|
||||
* @param string $what Name of property that changed
|
||||
* @param mixed $old Previous value before change
|
||||
* @param mixed $new New value
|
||||
* @return $this
|
||||
* @return Inputfield|WireData $this
|
||||
*
|
||||
*/
|
||||
public function trackChange($what, $old = null, $new = null) {
|
||||
|
@@ -123,6 +123,12 @@ class PageFinder extends Wire {
|
||||
*
|
||||
*/
|
||||
'reverseSort' => false,
|
||||
|
||||
/**
|
||||
* Allow use of _custom="another selector" in Selectors?
|
||||
*
|
||||
*/
|
||||
'allowCustom' => false,
|
||||
|
||||
);
|
||||
|
||||
@@ -293,7 +299,6 @@ class PageFinder extends Wire {
|
||||
$sort = $parent->template->sortfield;
|
||||
if(!$sort) $sort = $parent->sortfield;
|
||||
if($sort) $selectors->add(new SelectorEqual('sort', $sort));
|
||||
$hasSort = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,23 +317,31 @@ class PageFinder extends Wire {
|
||||
* @param array $options
|
||||
* - `findOne` (bool): Specify that you only want to find 1 page and don't need info for pagination (default=false).
|
||||
* - `findHidden` (bool): Specify that it's okay for hidden pages to be included in the results (default=false).
|
||||
* - `findUnpublished` (bool): Specify that it's okay for hidden AND unpublished pages to be included in the results (default=false).
|
||||
* - `findTrash` (bool): Specify that it's okay for hidden AND unpublished AND trashed pages to be included in the results (default=false).
|
||||
* - `findAll` (bool): Specify that no page should be excluded - results can include unpublished, trash, system, no-access pages, etc. (default=false)
|
||||
* - `getTotal` (bool|null): Whether the total quantity of matches should be determined and accessible from getTotal() method call.
|
||||
* - `findUnpublished` (bool): Specify that it's okay for hidden AND unpublished pages to be included in the
|
||||
* results (default=false).
|
||||
* - `findTrash` (bool): Specify that it's okay for hidden AND unpublished AND trashed pages to be included in the
|
||||
* results (default=false).
|
||||
* - `findAll` (bool): Specify that no page should be excluded - results can include unpublished, trash, system,
|
||||
* no-access pages, etc. (default=false)
|
||||
* - `getTotal` (bool|null): Whether the total quantity of matches should be determined and accessible from
|
||||
* getTotal() method call.
|
||||
* - null: determine automatically (default is disabled when limit=1, enabled in all other cases).
|
||||
* - true: always calculate total.
|
||||
* - false: never calculate total.
|
||||
* - `getTotalType` (string): Method to use to get total, specify 'count' or 'calc' (default='calc').
|
||||
* - `returnQuery` (bool): When true, only the DatabaseQuery object is returned by find(), for internal use. (default=false)
|
||||
* - `loadPages` (bool): This is an optimization used by the Pages::find() method, but we observe it here as we may be able to apply
|
||||
* some additional optimizations in certain cases. For instance, if loadPages=false, then we can skip retrieval of IDs and omit
|
||||
* sort fields. (default=true)
|
||||
* - `stopBeforeID` (int): Stop loading pages once a page matching this ID is found. Page having this ID will be excluded as well (default=0).
|
||||
* - `startAfterID` (int): Start loading pages once a page matching this ID is found. Page having this ID will be excluded as well (default=0).
|
||||
* - `loadPages` (bool): This is an optimization used by the Pages::find() method, but we observe it here as we
|
||||
* may be able to apply some additional optimizations in certain cases. For instance, if loadPages=false, then
|
||||
* we can skip retrieval of IDs and omit sort fields. (default=true)
|
||||
* - `stopBeforeID` (int): Stop loading pages once a page matching this ID is found. Page having this ID will be
|
||||
* excluded as well (default=0).
|
||||
* - `startAfterID` (int): Start loading pages once a page matching this ID is found. Page having this ID will be
|
||||
* excluded as well (default=0).
|
||||
* - `reverseSort` (bool): Reverse whatever sort is specified.
|
||||
* - `returnVerbose` (bool): When true, this function returns array of arrays containing page ID, parent ID, template ID and score.
|
||||
* When false, returns only an array of page IDs. True is required by most usage from Pages class. False is only for specific cases.
|
||||
* - `returnVerbose` (bool): When true, this function returns array of arrays containing page ID, parent ID,
|
||||
* template ID and score. When false, returns only an array of page IDs. True is required by most usage from
|
||||
* Pages class. False is only for specific cases.
|
||||
* - `allowCustom` (bool): Whether or not to allow _custom='selector string' type values (default=false).
|
||||
* @return array|DatabaseQuerySelect
|
||||
* @throws PageFinderException
|
||||
*
|
||||
@@ -468,7 +481,28 @@ class PageFinder extends Wire {
|
||||
$options['returnVerbose'] = false;
|
||||
return $this->find($selectors, $options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pre-process given Selectors object
|
||||
*
|
||||
* @param Selectors $selectors
|
||||
* @param array $options
|
||||
*
|
||||
*/
|
||||
protected function preProcessSelectors(Selectors $selectors, $options = array()) {
|
||||
if(!empty($options['allowCustom'])) {
|
||||
foreach($selectors as $selector) {
|
||||
$field = $selector->field;
|
||||
if(!is_string($field) || $field !== '_custom') continue;
|
||||
$selectors->remove($selector);
|
||||
$_selectors = $this->wire(new Selectors($selector->value()));
|
||||
/** @var Selectors $_selectors */
|
||||
foreach($_selectors as $s) $selectors->add($s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Pre-process the given selector to perform any necessary replacements
|
||||
*
|
||||
@@ -742,6 +776,7 @@ class PageFinder extends Wire {
|
||||
// $this->extraJoins = array();
|
||||
$startLimit = false; // true when the start/limit part of the query generation is done
|
||||
$database = $this->wire('database');
|
||||
$this->preProcessSelectors($selectors, $options);
|
||||
|
||||
/** @var DatabaseQuerySelect $query */
|
||||
$query = $this->wire(new DatabaseQuerySelect());
|
||||
@@ -1070,7 +1105,7 @@ class PageFinder extends Wire {
|
||||
static $tableCnt = 0;
|
||||
$table = $database->escapeTable($field->table);
|
||||
$tableAlias = $table . "__blank" . (++$tableCnt);
|
||||
$blankValue = $field->type->getBlankValue(new NullPage(), $field, $value);
|
||||
$blankValue = $field->type->getBlankValue(new NullPage(), $field);
|
||||
$blankIsObject = is_object($blankValue);
|
||||
if($blankIsObject) $blankValue = '';
|
||||
$blankValue = $database->escapeStr($blankValue);
|
||||
|
@@ -199,20 +199,22 @@ class Pages extends Wire {
|
||||
*
|
||||
* @param string|int|array|Selectors $selector Specify selector (standard usage), but can also accept page ID or array of page IDs.
|
||||
* @param array|string $options One or more options that can modify certain behaviors. May be associative array or "key=value" selector string.
|
||||
* - `findOne` (boolean): Apply optimizations for finding a single page.
|
||||
* - `findAll` (boolean): Find all pages with no exculsions (same as include=all option).
|
||||
* - `getTotal` (boolean): Whether to set returning PageArray's "total" property (default: true except when findOne=true).
|
||||
* - `loadPages` (boolean): Whether to populate the returned PageArray with found pages (default: true).
|
||||
* - `findOne` (boolean): Apply optimizations for finding a single page (default=false).
|
||||
* - `findAll` (boolean): Find all pages with no exclusions, same as "include=all" option (default=false).
|
||||
* - `getTotal` (boolean): Whether to set returning PageArray's "total" property (default=true, except when findOne=true).
|
||||
* - `loadPages` (boolean): Whether to populate the returned PageArray with found pages (default=true).
|
||||
* The only reason why you'd want to change this to false would be if you only needed the count details from
|
||||
* the PageArray: getTotal(), getStart(), getLimit, etc. This is intended as an optimization for $pages->count().
|
||||
* Does not apply if $selector argument is an array.
|
||||
* - `caller` (string): Optional name of calling function, for debugging purposes, i.e. pages.count
|
||||
* - `include` (string): Optional inclusion mode of 'hidden', 'unpublished' or 'all'. Default=none. Typically you would specify this
|
||||
* - `cache` (boolean): Allow caching of selectors and loaded pages? (default=true). Also sets loadOptions[cache].
|
||||
* - `allowCustom` (boolean): Allow use of _custom="another selector" in given $selector? For specific uses. (default=false)
|
||||
* - `caller` (string): Optional name of calling function, for debugging purposes, i.e. "pages.count" (default=blank).
|
||||
* - `include` (string): Optional inclusion mode of 'hidden', 'unpublished' or 'all'. (default=none). Typically you would specify this
|
||||
* directly in the selector string, so the option is mainly useful if your first argument is not a string.
|
||||
* - `stopBeforeID` (int): Stop loading pages once page matching this ID is found (default=0).
|
||||
* - `startAfterID` (int): Start loading pages once page matching this ID is found (default=0).
|
||||
* - `lazy` (bool): Specify true to force lazy loading. This is the same as using the Pages::findMany() method (default=false).
|
||||
* - `loadOptions` (array): Optional assoc array of options to pass to getById() load options.
|
||||
* - `loadOptions` (array): Optional associative array of options to pass to getById() load options.
|
||||
* @return PageArray Pages that matched the given selector.
|
||||
*
|
||||
* Non-visible pages are excluded unless an "include=x" mode is specified in the selector
|
||||
@@ -289,6 +291,7 @@ class Pages extends Wire {
|
||||
$debug = $this->debug;
|
||||
if($debug) $this->debug(false);
|
||||
$options['lazy'] = true;
|
||||
if(!isset($options['cache'])) $options['cache'] = false;
|
||||
$matches = $this->loader->find($selector, $options);
|
||||
if($debug) $this->debug($debug);
|
||||
return $matches;
|
||||
|
@@ -154,6 +154,8 @@ class PagesLoader extends Wire {
|
||||
* - findOne: boolean - apply optimizations for finding a single page
|
||||
* - findAll: boolean - find all pages with no exculsions (same as include=all option)
|
||||
* - getTotal: boolean - whether to set returning PageArray's "total" property (default: true except when findOne=true)
|
||||
* - cache: boolean - Allow caching of selectors and pages loaded (default=true). Also sets loadOptions[cache].
|
||||
* - allowCustom: boolean - Whether to allow use of "_custom=new selector" in selectors (default=false).
|
||||
* - lazy: boolean - makes find() return Page objects that don't have any data populated to them (other than id and template).
|
||||
* - loadPages: boolean - whether to populate the returned PageArray with found pages (default: true).
|
||||
* The only reason why you'd want to change this to false would be if you only needed the count details from
|
||||
@@ -177,6 +179,8 @@ class PagesLoader extends Wire {
|
||||
$caller = isset($options['caller']) ? $options['caller'] : 'pages.find';
|
||||
$lazy = empty($options['lazy']) ? false : true;
|
||||
$debug = $this->debug && !$lazy;
|
||||
$cachePages = isset($options['cache']) ? (bool) $options['cache'] : true;
|
||||
if(!$cachePages && !isset($loadOptions['cache'])) $loadOptions['cache'] = false;
|
||||
$pages = $this->findShortcut($selector, $options, $loadOptions);
|
||||
|
||||
if($pages) return $pages;
|
||||
@@ -293,7 +297,9 @@ class PagesLoader extends Wire {
|
||||
$pages->setSelectors($selectors);
|
||||
$pages->setTrackChanges(true);
|
||||
|
||||
if($loadPages) $this->pages->cacher()->selectorCache($selectorString, $options, $pages);
|
||||
if($loadPages && $cachePages) {
|
||||
$this->pages->cacher()->selectorCache($selectorString, $options, $pages);
|
||||
}
|
||||
|
||||
if($debug) {
|
||||
$this->pages->debugLog('find', $selectorString, $pages);
|
||||
|
@@ -29,6 +29,7 @@ require_once(PROCESSWIRE_CORE_PATH . "Selector.php");
|
||||
* #pw-body
|
||||
*
|
||||
* @link https://processwire.com/api/selectors/ Official Selectors Documentation
|
||||
* @method Selector[] getIterator()
|
||||
*
|
||||
* ProcessWire 3.x, Copyright 2016 by Ryan Cramer
|
||||
* https://processwire.com
|
||||
@@ -365,10 +366,9 @@ class Selectors extends WireArray {
|
||||
|
||||
|
||||
/**
|
||||
* Given a selector string, return an array of (field, value, operator) for each selector in the strong.
|
||||
* Given a selector string, populate to Selector objects in this Selectors instance
|
||||
*
|
||||
* @param string $str The string containing a selector (or multiple selectors, separated by commas)
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
protected function extractString($str) {
|
||||
@@ -741,6 +741,47 @@ class Selectors extends WireArray {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of all field names referenced in all of the Selector objects here
|
||||
*
|
||||
* @param bool $subfields Default is to allow "field.subfield" fields, or specify false to convert them to just "field".
|
||||
* @return array Returned array has both keys and values as field names (same)
|
||||
*
|
||||
*/
|
||||
public function getAllFields($subfields = true) {
|
||||
$fields = array();
|
||||
foreach($this as $selector) {
|
||||
$field = $selector->field;
|
||||
if(!is_array($field)) $field = array($field);
|
||||
foreach($field as $f) {
|
||||
if(!$subfields && strpos($f, '.')) {
|
||||
list($f, $subfield) = explode('.', $f, 2);
|
||||
if($subfield) {} // ignore
|
||||
}
|
||||
$fields[$f] = $f;
|
||||
}
|
||||
}
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of all values referenced in all Selector objects here
|
||||
*
|
||||
* @return array Returned array has both keys and values as field values (same)
|
||||
*
|
||||
*/
|
||||
public function getAllValues() {
|
||||
$values = array();
|
||||
foreach($this as $selector) {
|
||||
$value = $selector->value;
|
||||
if(!is_array($value)) $value = array($value);
|
||||
foreach($value as $v) {
|
||||
$values[$v] = $v;
|
||||
}
|
||||
}
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the given Wire match these Selectors?
|
||||
*
|
||||
|
@@ -50,7 +50,7 @@
|
||||
* @property WireMailTools $mail #pw-internal
|
||||
* @property WireFileTools $files #pw-internal
|
||||
*
|
||||
* @method changed(string $what) See Wire::___changed()
|
||||
* @method changed(string $what, $old = null, $new = null) See Wire::___changed()
|
||||
* @method log($str = '', array $options = array()) See Wire::___log()
|
||||
* @method callUnknown($method, $arguments) See Wire::___callUnknown()
|
||||
* @method Wire trackException(\Exception $e, $severe = true, $text = null)
|
||||
@@ -367,11 +367,14 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
||||
* @param $method
|
||||
* @param $arguments
|
||||
* @return mixed
|
||||
* @internal
|
||||
*
|
||||
*/
|
||||
public function _callMethod($method, $arguments) {
|
||||
return call_user_func_array(array($this, $method), $arguments);
|
||||
if(empty($arguments)) {
|
||||
return $this->$method();
|
||||
} else {
|
||||
return call_user_func_array(array($this, $method), $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -953,7 +956,13 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
||||
}
|
||||
|
||||
if(is_null($old) || is_null($new) || $lastValue !== $new) {
|
||||
$this->changed($what, $old, $new); // triggers ___changed hook
|
||||
/** @var WireHooks $hooks */
|
||||
$hooks = $this->wire('hooks');
|
||||
if(($hooks && $hooks->isHooked('changed')) || !$hooks) {
|
||||
$this->changed($what, $old, $new); // triggers ___changed hook
|
||||
} else {
|
||||
$this->___changed($what, $old, $new);
|
||||
}
|
||||
}
|
||||
|
||||
if($this->trackChanges & self::trackChangesValues) {
|
||||
@@ -1490,8 +1499,6 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
||||
/**
|
||||
* ProcessWire instance
|
||||
*
|
||||
* This will replace static fuel in PW 3.0
|
||||
*
|
||||
* @var ProcessWire|null
|
||||
*
|
||||
*/
|
||||
@@ -1505,7 +1512,6 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
||||
* #pw-internal
|
||||
*
|
||||
* @param ProcessWire $wire
|
||||
* @return $this
|
||||
*
|
||||
*/
|
||||
public function setWire(ProcessWire $wire) {
|
||||
|
@@ -71,23 +71,38 @@ class WireHooks {
|
||||
protected $staticHooks = array();
|
||||
|
||||
/**
|
||||
* A static cache of all hook method/property names for an optimization.
|
||||
* A cache of all hook method/property names for an optimization.
|
||||
*
|
||||
* Hooked methods end with '()' while hooked properties don't.
|
||||
*
|
||||
* This does not distinguish which instance it was added to or whether it was removed.
|
||||
* But will use keys in the form 'fromClass::method' (with value 'method') in cases where a fromClass was specified.
|
||||
* This cache exists primarily to gain some speed in our __get and __call methods.
|
||||
*
|
||||
*/
|
||||
protected $hookMethodCache = array();
|
||||
|
||||
/**
|
||||
* Same as hook method cache but for "Class::method"
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
*/
|
||||
protected $hookClassMethodCache = array();
|
||||
|
||||
/**
|
||||
* Cache of all local hooks combined, for debugging purposes
|
||||
*
|
||||
*/
|
||||
protected $allLocalHooks = array();
|
||||
|
||||
/**
|
||||
* Cached parent classes and interfaces
|
||||
*
|
||||
* @var array of class|interface => [ 'parentClass', 'parentClass', 'interface', 'interface', 'etc.' ]
|
||||
*
|
||||
*/
|
||||
protected $parentClasses = array();
|
||||
|
||||
/**
|
||||
* @var Config
|
||||
*
|
||||
@@ -135,6 +150,9 @@ class WireHooks {
|
||||
|
||||
$hooks = array();
|
||||
|
||||
// see if we can do a quick exit
|
||||
if($method && $method !== '*' && !$this->isHookedOrParents($object, $method)) return $hooks;
|
||||
|
||||
// first determine which local hooks when should include
|
||||
if($type !== self::getHooksStatic) {
|
||||
$localHooks = $object->getLocalHooks();
|
||||
@@ -205,7 +223,7 @@ class WireHooks {
|
||||
if($needSort && count($hooks) > 1) {
|
||||
defined("SORT_NATURAL") ? ksort($hooks, SORT_NATURAL) : uksort($hooks, "strnatcmp");
|
||||
}
|
||||
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
|
||||
@@ -217,8 +235,11 @@ class WireHooks {
|
||||
* As a result, a true return value indicates something "might" be hooked, as opposed to be
|
||||
* being definitely hooked.
|
||||
*
|
||||
* If checking for a hooked method, it should be in the form "Class::method()" or "method()".
|
||||
* If checking for a hooked property, it should be in the form "Class::property" or "property".
|
||||
* If checking for a hooked method, it should be in the form `Class::method()` or `method()` (with parenthesis).
|
||||
* If checking for a hooked property, it should be in the form `Class::property` or `property`.
|
||||
*
|
||||
* If you need to check if a method/property is hooked, including any of its parent classes, use
|
||||
* the `WireHooks::isMethodHooked()`, `WireHooks::isPropertyHooked()`, or `WireHooks::hasHook()` methods instead.
|
||||
*
|
||||
* @param string $method Method or property name in one of the following formats:
|
||||
* Class::method()
|
||||
@@ -228,23 +249,114 @@ class WireHooks {
|
||||
* @param Wire|null $instance Optional instance to check against (see hasHook method for details)
|
||||
* Note that if specifying an $instance, you may not use the Class::method() or Class::property options for $method argument.
|
||||
* @return bool
|
||||
* @see WireHooks::isMethodHooked(), WireHooks::isPropertyHooked(), WireHooks::hasHook()
|
||||
*
|
||||
*/
|
||||
public function isHooked($method, Wire $instance = null) {
|
||||
if($instance) return $this->hasHook($instance, $method);
|
||||
$hooked = false;
|
||||
if(strpos($method, ':') !== false) {
|
||||
if(array_key_exists($method, $this->hookMethodCache)) $hooked = true; // fromClass::method() or fromClass::property
|
||||
$hooked = isset($this->hookClassMethodCache[$method]); // fromClass::method() or fromClass::property
|
||||
} else {
|
||||
if(in_array($method, $this->hookMethodCache)) $hooked = true; // method() or property
|
||||
$hooked = isset($this->hookMethodCache[$method]); // method() or property
|
||||
}
|
||||
return $hooked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to isHooked() method but also checks parent classes for the hooked method as well
|
||||
*
|
||||
* This method is designed for fast determinations of whether something is hooked
|
||||
*
|
||||
* @param string|Wire $class
|
||||
* @param string $method Name of method or property
|
||||
* @param string $type May be either 'method', 'property' or 'either'
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
protected function isHookedOrParents($class, $method, $type = 'either') {
|
||||
|
||||
$property = '';
|
||||
$className = is_object($class) ? wireClassName($class) : $class;
|
||||
|
||||
if($type == 'method' || $type == 'either') {
|
||||
if(strpos($method, '(') === false) $method .= '()';
|
||||
if($type == 'either') $property = rtrim($method, '()');
|
||||
}
|
||||
|
||||
if($type == 'method') {
|
||||
if(!isset($this->hookMethodCache[$method])) return false; // not hooked for any class
|
||||
$hooked = isset($this->hookClassMethodCache["$className::$method"]);
|
||||
} else if($type == 'property') {
|
||||
if(!isset($this->hookMethodCache[$property])) return false; // not hooked for any class
|
||||
$hooked = isset($this->hookClassMethodCache["$className::$property"]);
|
||||
} else {
|
||||
if(!isset($this->hookMethodCache[$method])
|
||||
&& !isset($this->hookMethodCache[$property])) return false;
|
||||
$hooked = isset($this->hookClassMethodCache["$className::$property"]) ||
|
||||
isset($this->hookClassMethodCache["$className::$method"]);
|
||||
}
|
||||
|
||||
if(!$hooked) {
|
||||
foreach($this->getClassParents($class) as $parentClass) {
|
||||
if($type == 'method') {
|
||||
if(isset($this->hookClassMethodCache["$parentClass::$method"])) {
|
||||
$hooked = true;
|
||||
$this->hookClassMethodCache["$class::$method"] = true;
|
||||
}
|
||||
} else if($type == 'property') {
|
||||
if(isset($this->hookClassMethodCache["$parentClass::$property"])) {
|
||||
$hooked = true;
|
||||
$this->hookClassMethodCache["$class::$property"] = true;
|
||||
}
|
||||
} else {
|
||||
if(isset($this->hookClassMethodCache["$parentClass::$method"])) {
|
||||
$hooked = true;
|
||||
$this->hookClassMethodCache["$class::$method"] = true;
|
||||
}
|
||||
if(!$hooked && isset($this->hookClassMethodCache["$parentClass::$property"])) {
|
||||
$hooked = true;
|
||||
$this->hookClassMethodCache["$class::$property"] = true;
|
||||
}
|
||||
}
|
||||
if($hooked) break;
|
||||
}
|
||||
}
|
||||
|
||||
return $hooked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to isHooked() method but also checks parent classes for the hooked method as well
|
||||
*
|
||||
* This method is designed for fast determinations of whether something is hooked
|
||||
*
|
||||
* @param string|Wire $class
|
||||
* @param string $method Name of method
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function isMethodHooked($class, $method) {
|
||||
return $this->isHookedOrParents($class, $method, 'method');
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to isHooked() method but also checks parent classes for the hooked property as well
|
||||
*
|
||||
* This method is designed for fast determinations of whether something is hooked
|
||||
*
|
||||
* @param string|Wire $class
|
||||
* @param string $property Name of property
|
||||
* @return bool
|
||||
*
|
||||
*/
|
||||
public function isPropertyHooked($class, $property) {
|
||||
return $this->isHookedOrParents($class, $property, 'property');
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to isHooked(), returns true if the method or property hooked, false if it isn't.
|
||||
*
|
||||
* Accomplishes the same thing as the isHooked() method, but this is more accruate,
|
||||
* Accomplishes the same thing as the isHooked() method, but this is more accurate,
|
||||
* and potentially slower than isHooked(). Less for optimization use, more for accuracy use.
|
||||
*
|
||||
* It checks for both static hooks and local hooks, but only accepts a method() or property
|
||||
@@ -270,9 +382,7 @@ class WireHooks {
|
||||
}
|
||||
|
||||
// quick exit when possible
|
||||
if(!in_array($method, $this->hookMethodCache)) {
|
||||
return false;
|
||||
}
|
||||
if(!isset($this->hookMethodCache[$method])) return false;
|
||||
|
||||
$_method = rtrim($method, '()');
|
||||
$localHooks = $object->getLocalHooks();
|
||||
@@ -285,12 +395,10 @@ class WireHooks {
|
||||
$hooked = true;
|
||||
} else {
|
||||
// check parent classes and interfaces
|
||||
$classes = wireClassParents($object, false);
|
||||
$interfaces = wireClassImplements($object);
|
||||
if(is_array($interfaces)) $classes = array_merge($interfaces, $classes);
|
||||
foreach($classes as $class) {
|
||||
foreach($this->getClassParents($object) as $class) {
|
||||
if(!empty($this->staticHooks[$class][$_method])) {
|
||||
$hooked = true;
|
||||
$this->hookClassMethodCache["$class::$method"] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -299,6 +407,31 @@ class WireHooks {
|
||||
return $hooked;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of parent classes and interfaces for the given object
|
||||
*
|
||||
* @param Wire|string $object Maybe either object instance or class name
|
||||
* @param bool $cache Allow use of cache for getting or storing? (default=true)
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function getClassParents($object, $cache = true) {
|
||||
if(is_string($object)) {
|
||||
$className = $object;
|
||||
} else {
|
||||
$className = $object->className();
|
||||
}
|
||||
if($cache && isset($this->parentClasses[$className])) {
|
||||
$classes = $this->parentClasses[$className];
|
||||
} else {
|
||||
$classes = wireClassParents($object, false);
|
||||
$interfaces = wireClassImplements($object);
|
||||
if(is_array($interfaces)) $classes = array_merge($interfaces, $classes);
|
||||
if($cache) $this->parentClasses[$className] = $classes;
|
||||
}
|
||||
return $classes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hook a function/method to a hookable method call in this object
|
||||
@@ -364,7 +497,7 @@ class WireHooks {
|
||||
}
|
||||
unset($ref);
|
||||
}
|
||||
|
||||
|
||||
if(strpos($method, '::')) {
|
||||
list($fromClass, $method) = explode('::', $method, 2);
|
||||
if(strpos($fromClass, '(') !== false) {
|
||||
@@ -380,7 +513,6 @@ class WireHooks {
|
||||
}
|
||||
$options['fromClass'] = $fromClass;
|
||||
}
|
||||
|
||||
|
||||
$argOpen = strpos($method, '(');
|
||||
if($argOpen && strpos($method, ')') > $argOpen+1) {
|
||||
@@ -453,7 +585,7 @@ class WireHooks {
|
||||
$priority = "$options[priority].$n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Note hookClass is always blank when this is a local hook
|
||||
$id = "$hookClass:$priority:$method";
|
||||
$options['priority'] = $priority;
|
||||
@@ -468,10 +600,10 @@ class WireHooks {
|
||||
);
|
||||
$hooks[$method][$priority] = $hook;
|
||||
|
||||
// cacheValue is just the method() or property, cacheKey includes optional fromClass::
|
||||
// cache record known hooks so they can be detected quickly
|
||||
$cacheValue = $options['type'] == 'method' ? "$method()" : "$method";
|
||||
$cacheKey = ($options['fromClass'] ? $options['fromClass'] . '::' : '') . $cacheValue;
|
||||
$this->hookMethodCache[$cacheKey] = $cacheValue;
|
||||
if($options['fromClass']) $this->hookClassMethodCache["$options[fromClass]::$cacheValue"] = true;
|
||||
$this->hookMethodCache[$cacheValue] = true;
|
||||
|
||||
// keep track of all local hooks combined when debug mode is on
|
||||
if($local && $this->config->debug) {
|
||||
@@ -534,14 +666,15 @@ class WireHooks {
|
||||
|
||||
$realMethod = "___$method";
|
||||
if($type == 'method') $result['methodExists'] = method_exists($object, $realMethod);
|
||||
if(!$result['methodExists'] && !$this->hasHook($object, $method . ($type == 'method' ? '()' : ''))) {
|
||||
// if(!$result['methodExists'] && !$this->hasHook($object, $method . ($type == 'method' ? '()' : ''))) {
|
||||
if(!$result['methodExists'] && !$this->isHookedOrParents($object, $method, $type)) {
|
||||
return $result; // exit quickly when we can
|
||||
}
|
||||
|
||||
$hooks = $this->getHooks($object, $method);
|
||||
$cancelHooks = false;
|
||||
$profiler = $this->wire->wire('profiler');
|
||||
|
||||
|
||||
foreach(array('before', 'after') as $when) {
|
||||
|
||||
if($type === 'method' && $when === 'after' && $result['replace'] !== true) {
|
||||
@@ -557,6 +690,7 @@ class WireHooks {
|
||||
if(!$hook['options'][$when]) continue;
|
||||
|
||||
if(!empty($hook['options']['objMatch'])) {
|
||||
/** @var Selectors $objMatch */
|
||||
$objMatch = $hook['options']['objMatch'];
|
||||
// object match comparison to determine at runtime whether to execute the hook
|
||||
if(is_object($objMatch)) {
|
||||
@@ -571,6 +705,7 @@ class WireHooks {
|
||||
$argMatches = $hook['options']['argMatch'];
|
||||
$matches = true;
|
||||
foreach($argMatches as $argKey => $argMatch) {
|
||||
/** @var Selectors $argMatch */
|
||||
$argVal = isset($arguments[$argKey]) ? $arguments[$argKey] : null;
|
||||
if(is_object($argMatch)) {
|
||||
// Selectors object
|
||||
@@ -594,15 +729,16 @@ class WireHooks {
|
||||
if(!$matches) continue; // don't run hook
|
||||
}
|
||||
|
||||
$event = new HookEvent();
|
||||
$event = new HookEvent(array(
|
||||
'object' => $object,
|
||||
'method' => $method,
|
||||
'arguments' => $arguments,
|
||||
'when' => $when,
|
||||
'return' => $result['return'],
|
||||
'id' => $hook['id'],
|
||||
'options' => $hook['options']
|
||||
));
|
||||
$this->wire->wire($event);
|
||||
$event->object = $object;
|
||||
$event->method = $method;
|
||||
$event->arguments = $arguments;
|
||||
$event->when = $when;
|
||||
$event->return = $result['return'];
|
||||
$event->id = $hook['id'];
|
||||
$event->options = $hook['options'];
|
||||
|
||||
$toObject = $hook['toObject'];
|
||||
$toMethod = $hook['toMethod'];
|
||||
@@ -624,6 +760,7 @@ class WireHooks {
|
||||
}
|
||||
$toMethod($event);
|
||||
} else {
|
||||
/** @var Wire $toObject */
|
||||
if($hook['toPublic']) {
|
||||
// public
|
||||
$returnValue = $toObject->$toMethod($event);
|
||||
@@ -632,6 +769,7 @@ class WireHooks {
|
||||
$returnValue = $toObject->_callMethod($toMethod, array($event));
|
||||
}
|
||||
// @todo allow for use of $returnValue as alternative to $event->return
|
||||
if($returnValue) {}
|
||||
}
|
||||
|
||||
if($profilerEvent) $profiler->stop($profilerEvent);
|
||||
@@ -660,9 +798,9 @@ class WireHooks {
|
||||
/**
|
||||
* Start timing a hook and return the timer name
|
||||
*
|
||||
* @param $object
|
||||
* @param $method
|
||||
* @param $arguments
|
||||
* @param Wire $object
|
||||
* @param String $method
|
||||
* @param array $arguments
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
@@ -694,8 +832,8 @@ class WireHooks {
|
||||
* }
|
||||
*
|
||||
* @param Wire $object
|
||||
* @param string|null $hookId
|
||||
* @return $this
|
||||
* @param string|null $hookID
|
||||
* @return Wire
|
||||
*
|
||||
*/
|
||||
public function removeHook(Wire $object, $hookID) {
|
||||
@@ -707,6 +845,9 @@ class WireHooks {
|
||||
$object->setLocalHooks($localHooks);
|
||||
} else {
|
||||
unset($this->staticHooks[$hookClass][$method][$priority]);
|
||||
if(empty($this->staticHooks[$hookClass][$method])) {
|
||||
unset($this->hookClassMethodCache["$hookClass::$method"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $object;
|
||||
|
@@ -390,7 +390,7 @@ class FieldtypePageTable extends FieldtypeMulti implements Module {
|
||||
|
||||
if(!is_array($value) || !count($value) || empty($field->template_id)) return $this->getBlankValue($page, $field);
|
||||
|
||||
$template_id = $field->template_id;
|
||||
$template_id = $field->get('template_id');
|
||||
|
||||
if(!is_array($template_id)) {
|
||||
$template_id = $template_id ? array($template_id) : array();
|
||||
@@ -402,16 +402,26 @@ class FieldtypePageTable extends FieldtypeMulti implements Module {
|
||||
$template = null;
|
||||
}
|
||||
|
||||
if($field->sortfields) {
|
||||
$loadOptions = array('cache' => false);
|
||||
if($template) $loadOptions['template'] = $template;
|
||||
|
||||
$sortfields = $field->get('sortfields');
|
||||
|
||||
if($sortfields) {
|
||||
$selector = $template ? "template=$template, " : "";
|
||||
$selector .= "include=unpublished, id=" . implode('|', $value);
|
||||
foreach(explode(',', $field->sortfields) as $sortfield) {
|
||||
foreach(explode(',', $sortfields) as $sortfield) {
|
||||
$selector .= ", sort=" . $this->wire('sanitizer')->name(trim($sortfield));
|
||||
}
|
||||
$items = $this->wire('pages')->find($selector);
|
||||
$options = array(
|
||||
'cache' => false,
|
||||
'caller' => $this->className() . '::wakeupValue',
|
||||
'loadOptions' => $loadOptions
|
||||
);
|
||||
$items = $this->wire('pages')->find($selector, $options);
|
||||
|
||||
} else {
|
||||
$items = $this->wire('pages')->getById($value, $template);
|
||||
$items = $this->wire('pages')->getById($value, $loadOptions);
|
||||
}
|
||||
|
||||
return $items;
|
||||
|
@@ -640,7 +640,17 @@ class FieldtypeRepeater extends Fieldtype implements ConfigurableModule {
|
||||
*/
|
||||
|
||||
// load the repeater pages
|
||||
$a = $this->wire('pages')->find($selector);
|
||||
$options = array(
|
||||
'cache' => false,
|
||||
'caller' => $this->className() . '::wakeupValue',
|
||||
'loadOptions' => array(
|
||||
'cache' => false,
|
||||
'parent_id' => $parent_id,
|
||||
'template' => $this->wire('templates')->get($template_id)
|
||||
)
|
||||
);
|
||||
|
||||
$a = $this->wire('pages')->find($selector, $options);
|
||||
$class = $this->getPageArrayClass();
|
||||
$pageArray = $this->wire(new $class($page, $field));
|
||||
$pageArray->import($a);
|
||||
|
@@ -588,9 +588,10 @@ var InputfieldSelector = {
|
||||
if(s.field == '_custom') {
|
||||
if(s.isOrGroup) {
|
||||
s.value = s.value.replace('(', '').replace(')', '');
|
||||
selector += s.field + '=' + '(' + s.value + ')';
|
||||
selector += s.field + '=' + '(' + $.trim(s.value) + ')';
|
||||
} else {
|
||||
selector += s.value;
|
||||
//selector += s.value;
|
||||
selector += s.field + '="' + $.trim(s.value) + '"';
|
||||
}
|
||||
} else {
|
||||
selector += s.field + s.operator + $.trim(s.value);
|
||||
|
File diff suppressed because one or more lines are too long
@@ -273,7 +273,10 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
|
||||
} else if($action == 'subfield' && ($fieldName = $input->get->field)) {
|
||||
$fieldName = $sanitizer->name($fieldName);
|
||||
if(strpos($fieldName, '.')) list($fieldName, $subfieldName) = explode('.', $fieldName);
|
||||
if(strpos($fieldName, '.')) {
|
||||
list($fieldName, $subfieldName) = explode('.', $fieldName);
|
||||
if($subfieldName) {} // ignore
|
||||
}
|
||||
$out = $this->renderSelectSubfield($fieldName);
|
||||
|
||||
} else if($action == 'opval' && ($fieldName = $input->get->field)) {
|
||||
@@ -617,6 +620,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
// consider multi-language
|
||||
if(strpos($name, 'data') === 0 && $this->wire('languages')) {
|
||||
list($unused, $languageID) = explode('data', "x$name");
|
||||
if($unused) {}
|
||||
if(ctype_digit($languageID)) {
|
||||
$language = $this->wire('languages')->get((int) $languageID);
|
||||
if($language && $language->id) {
|
||||
@@ -630,7 +634,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
} else if(!empty($subfield['label'])) {
|
||||
$label = $subfield['label'];
|
||||
} else if(strpos($name, 'data') === 0 && ctype_digit(substr($name, 4)) && $this->wire('languages')) {
|
||||
|
||||
$label = $this->wire('languages')->get((int) substr($name, 4))->get('title|name');
|
||||
} else {
|
||||
$f = $this->wire('fields')->get($name);
|
||||
$label = $f ? $f->getLabel() : $name;
|
||||
@@ -646,6 +650,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
$_subfields = array();
|
||||
foreach($subfields as $key => $subfield) {
|
||||
list($label, $name) = explode("\t", $key);
|
||||
if($label) {}
|
||||
$_subfields[$name] = $subfield;
|
||||
}
|
||||
$subfields = $_subfields;
|
||||
@@ -839,6 +844,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
if($settings['showFieldLabels']) {
|
||||
$customFields = array();
|
||||
foreach($settings['customFields'] as $field) {
|
||||
/** @var Field $field */
|
||||
$label = $field->getLabel();
|
||||
while(isset($customFields[$label])) $label .= ' ';
|
||||
$customFields[$label] = $field;
|
||||
@@ -1183,8 +1189,18 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
&& ($field->get('findPagesCode') || $field->get('findPagesSelector'))) {
|
||||
// see if we can locate options purely with the parent or template
|
||||
$findSelector = array("include=unpublished, limit=500, sort=title, sort=name, ");
|
||||
if($field->get('parent_id')) $findSelector[] = "parent_id=" . (int) $field->get('parent_id');
|
||||
if($field->get('template_id')) $findSelector[] = "templates_id=" . (int) $field->get('template_id');
|
||||
$parent_ids = $field->get('parent_ids');
|
||||
$template_ids = $field->get('template_ids');
|
||||
if($parent_ids && count($parent_ids)) {
|
||||
$findSelector[] = "parent_id=" . implode('|', $parent_ids);
|
||||
} else if($field->get('parent_id')) {
|
||||
$findSelector[] = "parent_id=" . (int) $field->get('parent_id');
|
||||
}
|
||||
if($template_ids && count($template_ids)) {
|
||||
$findSelector[] = "templates_id=" . implode('|', $template_ids);
|
||||
} else if($field->get('template_id')) {
|
||||
$findSelector[] = "templates_id=" . (int) $field->get('template_id');
|
||||
}
|
||||
foreach($this->wire('pages')->find(implode(', ', $findSelector)) as $item) {
|
||||
$options[$item->id] = $inputfield->getPageLabel($item); // $item->get('title|name');
|
||||
}
|
||||
@@ -1386,6 +1402,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
if(strpos($limitField, '.') === false) continue;
|
||||
if(strpos($limitField, $fieldName) !== 0) continue;
|
||||
list($limitField, $limitSubfield) = explode('.', $limitField);
|
||||
if($limitField) {} // ignore
|
||||
if($limitSubfield) $limitSubfields[$limitSubfield] = $limitSubfield;
|
||||
}
|
||||
// render all the subfield options
|
||||
@@ -1625,7 +1642,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param int|string $value
|
||||
* @return $this
|
||||
* @return InputfieldSelector|WireData
|
||||
*
|
||||
*/
|
||||
public function setAttribute($key, $value) {
|
||||
@@ -1913,6 +1930,7 @@ class InputfieldSelector extends Inputfield implements ConfigurableModule {
|
||||
*
|
||||
*/
|
||||
public function getModuleConfigInputfields(array $data) {
|
||||
if($data) {} // ignore
|
||||
$form = $this->wire(new InputfieldWrapper());
|
||||
$f = $this->wire('modules')->get('InputfieldSelector');
|
||||
$f->name = 'test';
|
||||
|
@@ -1504,7 +1504,8 @@ class ProcessPageLister extends Process implements ConfigurableModule {
|
||||
$this->finalSelector = $selector;
|
||||
|
||||
try {
|
||||
$results = $selector ? $this->wire('pages')->find($selector) : $this->wire('pages')->newPageArray();
|
||||
$options = array('allowCustom' => true);
|
||||
$results = $selector ? $this->wire('pages')->find($selector, $options) : $this->wire('pages')->newPageArray();
|
||||
|
||||
} catch(\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
|
Reference in New Issue
Block a user