[NFC] Release Notes 5.53 first pass
[civicrm-core.git] / mixin / polyfill.php
CommitLineData
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 */
18return 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};