diff --git a/wire/config.php b/wire/config.php index 01cb5ef5..ee528f18 100644 --- a/wire/config.php +++ b/wire/config.php @@ -1481,8 +1481,9 @@ $config->lazyPageChunkSize = 250; * Uncomment and paste into /site/config.php if you want to use this * * $config->InputfieldWrapper = array( - * 'useDependencies' => true, - * 'requiredLabel' => 'Missing required value', + * 'useDependencies' => true, + * 'requiredLabel' => 'Missing required value', + * 'columnWidthSpacing' => 0, * ); * */ @@ -1680,6 +1681,8 @@ $config->versionName = ''; * column width spacing for inputfields: used by some admin themes to communicate to InputfieldWrapper * * Value is null, 0, or 1 or higher. This should be kept at null in this file. + * + * This can also be specified with $config->InputfieldWrapper('columnWidthSpacing', 0); (3.0.158+) * */ $config->inputfieldColumnWidthSpacing = null; diff --git a/wire/core/ProcessWire.php b/wire/core/ProcessWire.php index 9be6a6cb..3c0e08b6 100644 --- a/wire/core/ProcessWire.php +++ b/wire/core/ProcessWire.php @@ -733,12 +733,14 @@ class ProcessWire extends Wire { if($profiler) $profiler->maintenance(); if($config->templateCompile) { - $compiler = new FileCompiler($this->wire('config')->paths->templates); + $compiler = new FileCompiler($config->paths->templates); + $this->wire($compiler); $compiler->maintenance(); } if($config->moduleCompile) { - $compiler = new FileCompiler($this->wire('config')->paths->siteModules); + $compiler = new FileCompiler($config->paths->siteModules); + $this->wire($compiler); $compiler->maintenance(); } } @@ -795,7 +797,16 @@ class ProcessWire extends Wire { $this->fileSave = ''; return true; } - + + /** + * Call method + * + * @param string $method + * @param array $arguments + * @return mixed + * @throws WireException + * + */ public function __call($method, $arguments) { if(method_exists($this, "___$method")) return parent::__call($method, $arguments); $value = $this->__get($method); @@ -816,6 +827,35 @@ class ProcessWire extends Wire { if(empty($name)) return $this->fuel; return $this->fuel->$name; } + + /** + * Called if any Wire-derived object makes API calls before being wired + * + * This is for debugging purposes only and is not called unless `ProcessWire::objectNotWired` is hooked. + * It is called only once per non-wired object. Uncomment code within to use. + * + * #pw-internal + * + * @param Wire $obj Object that accessed API var without being assigned ProcessWire instance + * @param string|Wire The $name argument that was passed to $obj->wire($name, $value) + * @param mixed $value The $value argument passed to $object->wire($name, $value) + * @since 3.0.158 + * + */ + public function _objectNotWired(Wire $obj, $name, $value) { + // Uncomment code below to enable (use in admin) + /* + if(is_string($name) && $this->wire($name)) { + $msg = $obj->className() . " accessed API var \$$name before being wired"; + $this->warning("$msg\n" . Debug::backtrace(array( + 'limit' => 2, + 'getString' => true, + 'getCnt' => false, + 'getFile' => 'basename', + ))); + } + */ + } /*** MULTI-INSTANCE *************************************************************************************/ diff --git a/wire/core/Wire.php b/wire/core/Wire.php index 8f4b391e..6f0811e5 100644 --- a/wire/core/Wire.php +++ b/wire/core/Wire.php @@ -124,7 +124,11 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable { * */ private $_instanceNum = 0; - + + /** + * Construct + * + */ public function __construct() {} /** @@ -1586,7 +1590,7 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable { /** * ProcessWire instance * - * @var ProcessWire|null + * @var ProcessWire|bool|null * */ protected $_wire = null; @@ -1594,16 +1598,18 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable { /** * Set the current ProcessWire instance for this object (PW 3.0) * - * Specify no arguments to get, or specify a ProcessWire instance to set. - * * #pw-internal * * @param ProcessWire $wire * */ public function setWire(ProcessWire $wire) { + $wired = $this->_wire; + if($wired === $wire) return; $this->_wire = $wire; + if($wired) return; $this->getInstanceNum(); + $this->wired(); } /** @@ -1617,7 +1623,7 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable { * */ public function getWire() { - return $this->_wire; + return $this->_wire ? $this->_wire : null; } /** @@ -1695,18 +1701,18 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable { */ public function wire($name = '', $value = null, $lock = false) { - if($this->_wire === null) { + if($this->_wire) { + // this instance is wired + $wire = $this->_wire; + } else { // this object has not yet been wired! use last known current instance as fallback // note this condition is unsafe in multi-instance mode $wire = ProcessWire::getCurrentInstance(); if(!$wire) return null; - - // For live hunting objects that are using the fallback, uncomment the following: - // echo "
Non-wired object: '$name' in " . get_class($this) . ($value ? " (value=$value)" : "") . "
"; - // echo "" . print_r(debug_backtrace(), true) . ""; - } else { - // this instance is wired - $wire = $this->_wire; + if($name && $this->_wire === null) { + $this->_wire = false; // false prevents this from being called another time for this object + $wire->_objectNotWired($this, $name, $value); + } } if(is_object($name)) { @@ -1743,6 +1749,38 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable { return $value; } + /** + * Initialization called when object injected with ProcessWire instance (aka “wired”) + * + * - Can be used for any constructor-type initialization that depends on API vars. + * - Called automatically when object is “wired”, do not call it on your own. + * - Expects to be called only once per object instance. + * - Typically called after `__construct()` but before any other method calls. + * - Please note: If object is never “wired” then this method will not be called! + * + * ~~~~~ + * class Test extends Wire { + * function wired() { + * echo "Wired to ProcessWire instance: "; + * echo $this->wire()->getProcessWireInstanceID(); + * } + * } + * + * // objects in ProcessWire are “wired” like this: + * $o = new Test(); + * $this->wire($o); // outputs "ProcessWire instance: n" + * + * // or on one line, like this… + * $this->wire(new Test()); // outputs "ProcessWire instance: n" + * ~~~~~ + * + * #pw-internal + * + * @since 3.0.158 + * + */ + public function wired() { } + /** * Get an object property by direct reference or NULL if it doesn't exist *