Commit | Line | Data |
---|---|---|
d322c495 TO |
1 | <?php |
2 | ||
3 | /** | |
4 | * When deploying on systems that lack mixin support, fake it. | |
5 | * | |
6 | * @mixinFile polyfill.php | |
7 | * | |
8 | * This polyfill does some (persnickity) deduplication, but it doesn't allow upgrades or shipping replacements in core. | |
9 | * | |
10 | * Note: The polyfill.php is designed to be copied into extensions for interoperability. Consequently, this file is | |
11 | * not used 'live' by `civicrm-core`. However, the file does need a canonical home, and it's convenient to keep it | |
12 | * adjacent to the actual mixin files. | |
13 | * | |
14 | * @param string $longName | |
15 | * @param string $shortName | |
16 | * @param string $basePath | |
17 | */ | |
18 | return function ($longName, $shortName, $basePath) { | |
19 | // Construct imitations of the mixin services. These cannot work as well (e.g. with respect to | |
20 | // number of file-reads, deduping, upgrading)... but they should be OK for a few months while | |
21 | // the mixin services become available. | |
22 | ||
23 | // List of active mixins; deduped by version | |
24 | $mixinVers = []; | |
25 | foreach ((array) glob($basePath . '/mixin/*.mixin.php') as $f) { | |
26 | [$name, $ver] = explode('@', substr(basename($f), 0, -10)); | |
27 | if (!isset($mixinVers[$name]) || version_compare($ver, $mixinVers[$name], '>')) { | |
28 | $mixinVers[$name] = $ver; | |
29 | } | |
30 | } | |
31 | $mixins = []; | |
32 | foreach ($mixinVers as $name => $ver) { | |
33 | $mixins[] = "$name@$ver"; | |
34 | } | |
35 | ||
36 | // Imitate CRM_Extension_MixInfo. | |
37 | $mixInfo = new class() { | |
38 | ||
39 | /** | |
40 | * @var string | |
41 | */ | |
42 | public $longName; | |
43 | ||
44 | /** | |
45 | * @var string | |
46 | */ | |
47 | public $shortName; | |
48 | ||
49 | public $_basePath; | |
50 | ||
51 | public function getPath($file = NULL) { | |
52 | return $this->_basePath . ($file === NULL ? '' : (DIRECTORY_SEPARATOR . $file)); | |
53 | } | |
54 | ||
55 | public function isActive() { | |
56 | return \CRM_Extension_System::singleton()->getMapper()->isActiveModule($this->shortName); | |
57 | } | |
58 | ||
59 | }; | |
60 | $mixInfo->longName = $longName; | |
61 | $mixInfo->shortName = $shortName; | |
62 | $mixInfo->_basePath = $basePath; | |
63 | ||
64 | // Imitate CRM_Extension_BootCache. | |
65 | $bootCache = new class() { | |
66 | ||
67 | public function define($name, $callback) { | |
68 | $envId = \CRM_Core_Config_Runtime::getId(); | |
69 | $oldExtCachePath = \Civi::paths()->getPath("[civicrm.compile]/CachedExtLoader.{$envId}.php"); | |
70 | $stat = stat($oldExtCachePath); | |
71 | $file = Civi::paths()->getPath('[civicrm.compile]/CachedMixin.' . md5($name . ($stat['mtime'] ?? 0)) . '.php'); | |
72 | if (file_exists($file)) { | |
73 | return include $file; | |
74 | } | |
75 | else { | |
76 | $data = $callback(); | |
77 | file_put_contents($file, '<' . "?php\nreturn " . var_export($data, 1) . ';'); | |
78 | return $data; | |
79 | } | |
80 | } | |
81 | ||
82 | }; | |
83 | ||
84 | // Imitate CRM_Extension_MixinLoader::run() | |
85 | // Parse all live mixins before trying to scan any classes. | |
86 | global $_CIVIX_MIXIN_POLYFILL; | |
87 | foreach ($mixins as $mixin) { | |
88 | // If the exact same mixin is defined by multiple exts, just use the first one. | |
89 | if (!isset($_CIVIX_MIXIN_POLYFILL[$mixin])) { | |
90 | $_CIVIX_MIXIN_POLYFILL[$mixin] = include_once $basePath . '/mixin/' . $mixin . '.mixin.php'; | |
91 | } | |
92 | } | |
93 | foreach ($mixins as $mixin) { | |
94 | // If there's trickery about installs/uninstalls/resets, then we may need to register a second time. | |
95 | if (!isset(\Civi::$statics[__FUNCTION__][$mixin])) { | |
96 | \Civi::$statics[__FUNCTION__][$mixin] = 1; | |
97 | $func = $_CIVIX_MIXIN_POLYFILL[$mixin]; | |
98 | $func($mixInfo, $bootCache); | |
99 | } | |
100 | } | |
101 | }; |