<?php /** * When deploying on systems that lack mixin support, fake it. * * @mixinFile polyfill.php * * This polyfill does some (persnickity) deduplication, but it doesn't allow upgrades or shipping replacements in core. * * Note: The polyfill.php is designed to be copied into extensions for interoperability. Consequently, this file is * not used 'live' by `civicrm-core`. However, the file does need a canonical home, and it's convenient to keep it * adjacent to the actual mixin files. * * @param string $longName * @param string $shortName * @param string $basePath */ return function ($longName, $shortName, $basePath) { // Construct imitations of the mixin services. These cannot work as well (e.g. with respect to // number of file-reads, deduping, upgrading)... but they should be OK for a few months while // the mixin services become available. // List of active mixins; deduped by version $mixinVers = []; foreach ((array) glob($basePath . '/mixin/*.mixin.php') as $f) { [$name, $ver] = explode('@', substr(basename($f), 0, -10)); if (!isset($mixinVers[$name]) || version_compare($ver, $mixinVers[$name], '>')) { $mixinVers[$name] = $ver; } } $mixins = []; foreach ($mixinVers as $name => $ver) { $mixins[] = "$name@$ver"; } // Imitate CRM_Extension_MixInfo. $mixInfo = new class() { /** * @var string */ public $longName; /** * @var string */ public $shortName; public $_basePath; public function getPath($file = NULL) { return $this->_basePath . ($file === NULL ? '' : (DIRECTORY_SEPARATOR . $file)); } public function isActive() { return \CRM_Extension_System::singleton()->getMapper()->isActiveModule($this->shortName); } }; $mixInfo->longName = $longName; $mixInfo->shortName = $shortName; $mixInfo->_basePath = $basePath; // Imitate CRM_Extension_BootCache. $bootCache = new class() { public function define($name, $callback) { $envId = \CRM_Core_Config_Runtime::getId(); $oldExtCachePath = \Civi::paths()->getPath("[civicrm.compile]/CachedExtLoader.{$envId}.php"); $stat = stat($oldExtCachePath); $file = Civi::paths()->getPath('[civicrm.compile]/CachedMixin.' . md5($name . ($stat['mtime'] ?? 0)) . '.php'); if (file_exists($file)) { return include $file; } else { $data = $callback(); file_put_contents($file, '<' . "?php\nreturn " . var_export($data, TRUE) . ';'); return $data; } } }; // Imitate CRM_Extension_MixinLoader::run() // Parse all live mixins before trying to scan any classes. global $_CIVIX_MIXIN_POLYFILL; foreach ($mixins as $mixin) { // If the exact same mixin is defined by multiple exts, just use the first one. if (!isset($_CIVIX_MIXIN_POLYFILL[$mixin])) { $_CIVIX_MIXIN_POLYFILL[$mixin] = include_once $basePath . '/mixin/' . $mixin . '.mixin.php'; } } foreach ($mixins as $mixin) { // If there's trickery about installs/uninstalls/resets, then we may need to register a second time. if (!isset(\Civi::$statics[$longName][$mixin])) { \Civi::$statics[$longName][$mixin] = 1; $func = $_CIVIX_MIXIN_POLYFILL[$mixin]; $func($mixInfo, $bootCache); } } };