src/web/app/mu-plugins/bedrock-autoloader.php
changeset 15 1921d064475c
parent 1 79bc439970cd
equal deleted inserted replaced
14:30f2ac9a7656 15:1921d064475c
    21  * @author Roots
    21  * @author Roots
    22  * @link https://roots.io/
    22  * @link https://roots.io/
    23  */
    23  */
    24 class Autoloader
    24 class Autoloader
    25 {
    25 {
       
    26     /** @var static Singleton instance */
       
    27     private static $instance;
       
    28 
    26     /** @var array Store Autoloader cache and site option */
    29     /** @var array Store Autoloader cache and site option */
    27     private static $cache;
    30     private $cache;
    28 
    31 
    29     /** @var array Autoloaded plugins */
    32     /** @var array Autoloaded plugins */
    30     private static $auto_plugins;
    33     private $autoPlugins;
    31 
    34 
    32     /** @var array Autoloaded mu-plugins */
    35     /** @var array Autoloaded mu-plugins */
    33     private static $mu_plugins;
    36     private $muPlugins;
    34 
    37 
    35     /** @var int Number of plugins */
    38     /** @var int Number of plugins */
    36     private static $count;
    39     private $count;
    37 
    40 
    38     /** @var array Newly activated plugins */
    41     /** @var array Newly activated plugins */
    39     private static $activated;
    42     private $activated;
    40 
    43 
    41     /** @var string Relative path to the mu-plugins dir */
    44     /** @var string Relative path to the mu-plugins dir */
    42     private static $relative_path;
    45     private $relativePath;
    43 
       
    44     /** @var static Singleton instance */
       
    45     private static $_single;
       
    46 
    46 
    47     /**
    47     /**
    48      * Create singleton, populate vars, and set WordPress hooks
    48      * Create singleton, populate vars, and set WordPress hooks
    49      */
    49      */
    50     public function __construct()
    50     public function __construct()
    51     {
    51     {
    52         if (isset(self::$_single)) {
    52         if (isset(self::$instance)) {
    53             return;
    53             return;
    54         }
    54         }
    55 
    55 
    56         self::$_single = $this;
    56         self::$instance = $this;
    57         self::$relative_path = '/../' . basename(__DIR__);
    57 
       
    58         $this->relativePath = '/../' . basename(__DIR__);
    58 
    59 
    59         if (is_admin()) {
    60         if (is_admin()) {
    60             add_filter('show_advanced_plugins', [$this, 'showInAdmin'], 0, 2);
    61             add_filter('show_advanced_plugins', [$this, 'showInAdmin'], 0, 2);
    61         }
    62         }
    62 
    63 
    72         $this->validatePlugins();
    73         $this->validatePlugins();
    73         $this->countPlugins();
    74         $this->countPlugins();
    74 
    75 
    75         array_map(static function () {
    76         array_map(static function () {
    76             include_once WPMU_PLUGIN_DIR . '/' . func_get_args()[0];
    77             include_once WPMU_PLUGIN_DIR . '/' . func_get_args()[0];
    77         }, array_keys(self::$cache['plugins']));
    78         }, array_keys($this->cache['plugins']));
    78 
    79 
    79         $this->pluginHooks();
    80         $this->pluginHooks();
    80     }
    81     }
    81 
    82 
    82     /**
    83     /**
    95             return $show;
    96             return $show;
    96         }
    97         }
    97 
    98 
    98         $this->updateCache();
    99         $this->updateCache();
    99 
   100 
   100         self::$auto_plugins = array_map(function ($auto_plugin) {
   101         $this->autoPlugins = array_map(function ($auto_plugin) {
   101             $auto_plugin['Name'] .= ' *';
   102             $auto_plugin['Name'] .= ' *';
   102             return $auto_plugin;
   103             return $auto_plugin;
   103         }, self::$auto_plugins);
   104         }, $this->autoPlugins);
   104 
   105 
   105         $GLOBALS['plugins']['mustuse'] = array_unique(array_merge(self::$auto_plugins, self::$mu_plugins), SORT_REGULAR);
   106         $GLOBALS['plugins']['mustuse'] = array_unique(array_merge($this->autoPlugins, $this->muPlugins), SORT_REGULAR);
   106 
   107 
   107         return false;
   108         return false;
   108     }
   109     }
   109 
   110 
   110     /**
   111     /**
   112      */
   113      */
   113     private function checkCache()
   114     private function checkCache()
   114     {
   115     {
   115         $cache = get_site_option('bedrock_autoloader');
   116         $cache = get_site_option('bedrock_autoloader');
   116 
   117 
   117         if ($cache === false) {
   118         if ($cache === false || (isset($cache['plugins'], $cache['count']) && count($cache['plugins']) !== $cache['count'])) {
   118             $this->updateCache();
   119             $this->updateCache();
   119             return;
   120             return;
   120         }
   121         }
   121 
   122 
   122         self::$cache = $cache;
   123         $this->cache = $cache;
   123     }
   124     }
   124 
   125 
   125     /**
   126     /**
   126      * Get the plugins and mu-plugins from the mu-plugin path and remove duplicates.
   127      * Get the plugins and mu-plugins from the mu-plugin path and remove duplicates.
   127      * Check cache against current plugins for newly activated plugins.
   128      * Check cache against current plugins for newly activated plugins.
   129      */
   130      */
   130     private function updateCache()
   131     private function updateCache()
   131     {
   132     {
   132         require_once ABSPATH . 'wp-admin/includes/plugin.php';
   133         require_once ABSPATH . 'wp-admin/includes/plugin.php';
   133 
   134 
   134         self::$auto_plugins = get_plugins(self::$relative_path);
   135         $this->autoPlugins = get_plugins($this->relativePath);
   135         self::$mu_plugins   = get_mu_plugins();
   136         $this->muPlugins   = get_mu_plugins();
   136         $plugins            = array_diff_key(self::$auto_plugins, self::$mu_plugins);
   137         $plugins           = array_diff_key($this->autoPlugins, $this->muPlugins);
   137         $rebuild            = !is_array(self::$cache['plugins']);
   138         $rebuild           = !is_array($this->cache['plugins']);
   138         self::$activated    = $rebuild ? $plugins : array_diff_key($plugins, self::$cache['plugins']);
   139         $this->activated   = $rebuild ? $plugins : array_diff_key($plugins, $this->cache['plugins']);
   139         self::$cache        = ['plugins' => $plugins, 'count' => $this->countPlugins()];
   140         $this->cache       = ['plugins' => $plugins, 'count' => $this->countPlugins()];
   140 
   141 
   141         update_site_option('bedrock_autoloader', self::$cache);
   142         update_site_option('bedrock_autoloader', $this->cache);
   142     }
   143     }
   143 
   144 
   144     /**
   145     /**
   145      * This accounts for the plugin hooks that would run if the plugins were
   146      * This accounts for the plugin hooks that would run if the plugins were
   146      * loaded as usual. Plugins are removed by deletion, so there's no way
   147      * loaded as usual. Plugins are removed by deletion, so there's no way
   147      * to deactivate or uninstall.
   148      * to deactivate or uninstall.
   148      */
   149      */
   149     private function pluginHooks()
   150     private function pluginHooks()
   150     {
   151     {
   151         if (!is_array(self::$activated)) {
   152         if (!is_array($this->activated)) {
   152             return;
   153             return;
   153         }
   154         }
   154 
   155 
   155         foreach (self::$activated as $plugin_file => $plugin_info) {
   156         foreach ($this->activated as $plugin_file => $plugin_info) {
   156             do_action('activate_' . $plugin_file);
   157             do_action('activate_' . $plugin_file);
   157         }
   158         }
   158     }
   159     }
   159 
   160 
   160     /**
   161     /**
   161      * Check that the plugin file exists, if it doesn't update the cache.
   162      * Check that the plugin file exists, if it doesn't update the cache.
   162      */
   163      */
   163     private function validatePlugins()
   164     private function validatePlugins()
   164     {
   165     {
   165         foreach (self::$cache['plugins'] as $plugin_file => $plugin_info) {
   166         foreach ($this->cache['plugins'] as $plugin_file => $plugin_info) {
   166             if (!file_exists(WPMU_PLUGIN_DIR . '/' . $plugin_file)) {
   167             if (!file_exists(WPMU_PLUGIN_DIR . '/' . $plugin_file)) {
   167                 $this->updateCache();
   168                 $this->updateCache();
   168                 break;
   169                 break;
   169             }
   170             }
   170         }
   171         }
   178      *
   179      *
   179      * @return int Number of autoloaded plugins.
   180      * @return int Number of autoloaded plugins.
   180      */
   181      */
   181     private function countPlugins()
   182     private function countPlugins()
   182     {
   183     {
   183         if (isset(self::$count)) {
   184         if (isset($this->count)) {
   184             return self::$count;
   185             return $this->count;
   185         }
   186         }
   186 
   187 
   187         $count = count(glob(WPMU_PLUGIN_DIR . '/*/', GLOB_ONLYDIR | GLOB_NOSORT));
   188         $count = count(glob(WPMU_PLUGIN_DIR . '/*/', GLOB_ONLYDIR | GLOB_NOSORT));
   188 
   189 
   189         if (!isset(self::$cache['count']) || $count !== self::$cache['count']) {
   190         if (!isset($this->cache['count']) || $count !== $this->cache['count']) {
   190             self::$count = $count;
   191             $this->count = $count;
   191             $this->updateCache();
   192             $this->updateCache();
   192         }
   193         }
   193 
   194 
   194         return self::$count;
   195         return $this->count;
   195     }
   196     }
   196 }
   197 }
   197 
   198 
   198 new Autoloader();
   199 new Autoloader();