mirror of
https://github.com/processwire/processwire.git
synced 2025-08-24 15:23:11 +02:00
Update to support module autoload order per request from @adrianbj
This commit is contained in:
@@ -199,7 +199,7 @@
|
|||||||
* something like an Inputfield module would not be singular. When not specified, modules that extend an
|
* something like an Inputfield module would not be singular. When not specified, modules that extend an
|
||||||
* existing base type typically inherit the singular setting from the module they extend.
|
* existing base type typically inherit the singular setting from the module they extend.
|
||||||
*
|
*
|
||||||
* - `autoload` (boolean|string|callable): Should this module load automatically at boot? (default=false).
|
* - `autoload` (boolean|string|callable|int): Should this module load automatically at boot? (default=false).
|
||||||
* This is good for modules that attach hooks or that need to otherwise load on every single
|
* This is good for modules that attach hooks or that need to otherwise load on every single
|
||||||
* request. Autoload is typically specified as a boolean true or false. Below are the different ways
|
* request. Autoload is typically specified as a boolean true or false. Below are the different ways
|
||||||
* autoload can be specified:
|
* autoload can be specified:
|
||||||
@@ -214,6 +214,9 @@
|
|||||||
* - **Callable function:** The module will automatically load only if the given callable function
|
* - **Callable function:** The module will automatically load only if the given callable function
|
||||||
* returns true.
|
* returns true.
|
||||||
*
|
*
|
||||||
|
* - **Integer:** If given integer 2 or higher, it will autoload the module before other autoload
|
||||||
|
* modules (in /site/modules/). Higher numbers autoload before lower numbers.
|
||||||
|
*
|
||||||
* - `searchable` (string): When present, indicates that module implements a search() method
|
* - `searchable` (string): When present, indicates that module implements a search() method
|
||||||
* consistent with the SearchableModule interface. The value of the 'searchable' property should
|
* consistent with the SearchableModule interface. The value of the 'searchable' property should
|
||||||
* be the name that the search results are referred to, using ascii characters of a-z, 0-9, and
|
* be the name that the search results are referred to, using ascii characters of a-z, 0-9, and
|
||||||
|
@@ -250,6 +250,14 @@ class Modules extends WireArray {
|
|||||||
*/
|
*/
|
||||||
protected $coreModulesDir = '';
|
protected $coreModulesDir = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of moduleName => order to indicate autoload order when necessary
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected $autoloadOrders = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties that only appear in 'verbose' moduleInfo
|
* Properties that only appear in 'verbose' moduleInfo
|
||||||
*
|
*
|
||||||
@@ -751,6 +759,7 @@ class Modules extends WireArray {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function loadModulesTable() {
|
protected function loadModulesTable() {
|
||||||
|
$this->autoloadOrders = array();
|
||||||
$database = $this->wire('database');
|
$database = $this->wire('database');
|
||||||
// we use SELECT * so that this select won't be broken by future DB schema additions
|
// we use SELECT * so that this select won't be broken by future DB schema additions
|
||||||
// Currently: id, class, flags, data, with created added at sysupdate 7
|
// Currently: id, class, flags, data, with created added at sysupdate 7
|
||||||
@@ -765,7 +774,8 @@ class Modules extends WireArray {
|
|||||||
$class = $row['class'];
|
$class = $row['class'];
|
||||||
$this->moduleIDs[$class] = $moduleID;
|
$this->moduleIDs[$class] = $moduleID;
|
||||||
$this->moduleFlags[$moduleID] = $flags;
|
$this->moduleFlags[$moduleID] = $flags;
|
||||||
$loadSettings = ($flags & self::flagsAutoload) || ($flags & self::flagsDuplicate) || ($class == 'SystemUpdater');
|
$autoload = $flags & self::flagsAutoload;
|
||||||
|
$loadSettings = $autoload || ($flags & self::flagsDuplicate) || ($class == 'SystemUpdater');
|
||||||
|
|
||||||
if($loadSettings) {
|
if($loadSettings) {
|
||||||
// preload config data for autoload modules since we'll need it again very soon
|
// preload config data for autoload modules since we'll need it again very soon
|
||||||
@@ -783,6 +793,14 @@ class Modules extends WireArray {
|
|||||||
$this->createdDates[$moduleID] = $row['created'];
|
$this->createdDates[$moduleID] = $row['created'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($autoload && !empty($this->moduleInfoCache[$moduleID]['autoload'])) {
|
||||||
|
$autoload = $this->moduleInfoCache[$moduleID]['autoload'];
|
||||||
|
if(is_int($autoload) && $autoload > 1) {
|
||||||
|
// autoload specifies an order > 1, indicating it should load before others
|
||||||
|
$this->autoloadOrders[$class] = $autoload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unset($row['data']); // info we don't want stored in modulesTableCache
|
unset($row['data']); // info we don't want stored in modulesTableCache
|
||||||
$this->modulesTableCache[$class] = $row;
|
$this->modulesTableCache[$class] = $row;
|
||||||
}
|
}
|
||||||
@@ -798,12 +816,13 @@ class Modules extends WireArray {
|
|||||||
*/
|
*/
|
||||||
protected function load($path) {
|
protected function load($path) {
|
||||||
|
|
||||||
|
$config = $this->wire('config');
|
||||||
$debugKey = $this->debug ? $this->debugTimerStart("load($path)") : null;
|
$debugKey = $this->debug ? $this->debugTimerStart("load($path)") : null;
|
||||||
$installed =& $this->modulesTableCache;
|
$installed =& $this->modulesTableCache;
|
||||||
$modulesLoaded = array();
|
$modulesLoaded = array();
|
||||||
$modulesDelayed = array();
|
$modulesDelayed = array();
|
||||||
$modulesRequired = array();
|
$modulesRequired = array();
|
||||||
$rootPath = $this->wire('config')->paths->root;
|
$rootPath = $config->paths->root;
|
||||||
$basePath = substr($path, strlen($rootPath));
|
$basePath = substr($path, strlen($rootPath));
|
||||||
|
|
||||||
foreach($this->findModuleFiles($path, true) as $pathname) {
|
foreach($this->findModuleFiles($path, true) as $pathname) {
|
||||||
@@ -819,7 +838,7 @@ class Modules extends WireArray {
|
|||||||
$requires = array();
|
$requires = array();
|
||||||
$name = $moduleName;
|
$name = $moduleName;
|
||||||
$moduleName = $this->loadModule($path, $pathname, $requires, $installed);
|
$moduleName = $this->loadModule($path, $pathname, $requires, $installed);
|
||||||
if(!$this->wire('config')->paths->get($name)) $this->setConfigPaths($name, dirname($basePath . $pathname));
|
if(!$config->paths->get($name)) $this->setConfigPaths($name, dirname($basePath . $pathname));
|
||||||
if(!$moduleName) continue;
|
if(!$moduleName) continue;
|
||||||
|
|
||||||
if(count($requires)) {
|
if(count($requires)) {
|
||||||
@@ -1030,6 +1049,7 @@ class Modules extends WireArray {
|
|||||||
|
|
||||||
static $startPath;
|
static $startPath;
|
||||||
static $callNum = 0;
|
static $callNum = 0;
|
||||||
|
static $prependFiles = array();
|
||||||
|
|
||||||
$callNum++;
|
$callNum++;
|
||||||
$config = $this->wire('config');
|
$config = $this->wire('config');
|
||||||
@@ -1053,6 +1073,11 @@ class Modules extends WireArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$files = array();
|
$files = array();
|
||||||
|
$autoloadOrders = null;
|
||||||
|
|
||||||
|
if(count($this->autoloadOrders) && $path !== $config->paths->modules) {
|
||||||
|
$autoloadOrders = &$this->autoloadOrders;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$dir = new \DirectoryIterator($path);
|
$dir = new \DirectoryIterator($path);
|
||||||
@@ -1070,7 +1095,6 @@ class Modules extends WireArray {
|
|||||||
|
|
||||||
if(DIRECTORY_SEPARATOR != '/') {
|
if(DIRECTORY_SEPARATOR != '/') {
|
||||||
$pathname = str_replace(DIRECTORY_SEPARATOR, '/', $pathname);
|
$pathname = str_replace(DIRECTORY_SEPARATOR, '/', $pathname);
|
||||||
$filename = str_replace(DIRECTORY_SEPARATOR, '/', $filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strpos($pathname, '/.') !== false) {
|
if(strpos($pathname, '/.') !== false) {
|
||||||
@@ -1084,16 +1108,30 @@ class Modules extends WireArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if the filename doesn't end with .module or .module.php, then stop and move onto the next
|
// if the filename doesn't end with .module or .module.php, then stop and move onto the next
|
||||||
if(!strpos($filename, '.module')) continue;
|
$extension = $file->getExtension();
|
||||||
if(substr($filename, -7) !== '.module' && substr($filename, -11) !== '.module.php') {
|
if($extension !== 'module' && $extension !== 'php') continue;
|
||||||
continue;
|
list($moduleName, $extension) = explode('.', $filename, 2);
|
||||||
}
|
if($extension !== 'module' && $extension !== 'module.php') continue;
|
||||||
|
|
||||||
$files[] = str_replace($startPath, '', $pathname);
|
$pathname = str_replace($startPath, '', $pathname);
|
||||||
|
|
||||||
|
if($autoloadOrders !== null && isset($autoloadOrders[$moduleName])) {
|
||||||
|
$prependFiles[$pathname] = $autoloadOrders[$moduleName];
|
||||||
|
} else {
|
||||||
|
$files[] = $pathname;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($level == 0 && $dir !== null) {
|
if($level == 0 && $dir !== null) {
|
||||||
if($cache && $cacheName) $cache->save($cacheName, implode("\n", $files), WireCache::expireNever);
|
if(!empty($prependFiles)) {
|
||||||
|
// one or more non-core modules must be loaded first in a specific order
|
||||||
|
arsort($prependFiles);
|
||||||
|
$files = array_merge(array_keys($prependFiles), $files);
|
||||||
|
$prependFiles = array();
|
||||||
|
}
|
||||||
|
if($cache && $cacheName) {
|
||||||
|
$cache->save($cacheName, implode("\n", $files), WireCache::expireNever);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $files;
|
return $files;
|
||||||
@@ -4106,6 +4144,7 @@ class Modules extends WireArray {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->clearModuleInfoCache();
|
$this->clearModuleInfoCache();
|
||||||
|
$this->loadModulesTable();
|
||||||
foreach($this->paths as $path) $this->findModuleFiles($path, false);
|
foreach($this->paths as $path) $this->findModuleFiles($path, false);
|
||||||
foreach($this->paths as $path) $this->load($path);
|
foreach($this->paths as $path) $this->load($path);
|
||||||
if($this->duplicates()->numNewDuplicates() > 0) $this->duplicates()->updateDuplicates(); // PR#1020
|
if($this->duplicates()->numNewDuplicates() > 0) $this->duplicates()->updateDuplicates(); // PR#1020
|
||||||
|
Reference in New Issue
Block a user