Commit | Line | Data |
---|---|---|
50bfb460 SB |
1 | <?php |
2 | /* | |
b812aefb | 3 | +--------------------------------------------------------------------+ |
bc77d7c0 | 4 | | Copyright CiviCRM LLC. All rights reserved. | |
b812aefb | 5 | | | |
bc77d7c0 TO |
6 | | This work is published under the GNU AGPLv3 license with some | |
7 | | permitted exceptions and without any warranty. For full license | | |
8 | | and copyright information, see https://civicrm.org/licensing | | |
b812aefb TO |
9 | +--------------------------------------------------------------------+ |
10 | */ | |
11 | ||
50bfb460 SB |
12 | /** |
13 | * | |
14 | * @package CRM | |
ca5cec67 | 15 | * @copyright CiviCRM LLC https://civicrm.org/licensing |
50bfb460 SB |
16 | */ |
17 | ||
b812aefb TO |
18 | /** |
19 | * Class CRM_Utils_AutoClean | |
20 | * | |
21 | * Automatically cleanup state when the object handle is released. | |
22 | * This is useful for unordered cleanup when a function has many | |
23 | * different exit scenarios (eg multiple returns, exceptions). | |
24 | */ | |
25 | class CRM_Utils_AutoClean { | |
26 | protected $callback; | |
27 | protected $args; | |
28 | ||
29 | /** | |
30 | * Call a cleanup function when the current context shuts down. | |
31 | * | |
0b882a86 | 32 | * ``` |
b812aefb TO |
33 | * function doStuff() { |
34 | * $ac = CRM_Utils_AutoClean::with(function(){ | |
35 | * MyCleanup::doIt(); | |
36 | * }); | |
37 | * ... | |
38 | * } | |
0b882a86 | 39 | * ``` |
b812aefb TO |
40 | * |
41 | * @param mixed $callback | |
42 | * @return CRM_Utils_AutoClean | |
43 | */ | |
44 | public static function with($callback) { | |
45 | $ac = new CRM_Utils_AutoClean(); | |
46 | $ac->args = func_get_args(); | |
47 | $ac->callback = array_shift($ac->args); | |
48 | return $ac; | |
49 | } | |
50 | ||
9c332a90 TO |
51 | /** |
52 | * Temporarily set the active locale. Cleanup locale when the autoclean handle disappears. | |
53 | * | |
54 | * @param string|null $newLocale | |
55 | * Ex: 'fr_CA' | |
56 | * @return \CRM_Utils_AutoClean|null | |
57 | */ | |
58 | public static function swapLocale(?string $newLocale) { | |
59 | $oldLocale = $GLOBALS['tsLocale'] ?? NULL; | |
60 | if ($oldLocale === $newLocale) { | |
61 | return NULL; | |
62 | } | |
63 | ||
64 | $i18n = \CRM_Core_I18n::singleton(); | |
65 | $i18n->setLocale($newLocale); | |
66 | return static::with(function() use ($i18n, $oldLocale) { | |
67 | $i18n->setLocale($oldLocale); | |
68 | }); | |
69 | } | |
70 | ||
b812aefb TO |
71 | /** |
72 | * Temporarily swap values using callback functions, and cleanup | |
73 | * when the current context shuts down. | |
74 | * | |
0b882a86 | 75 | * ``` |
b812aefb TO |
76 | * function doStuff() { |
77 | * $ac = CRM_Utils_AutoClean::swap('My::get', 'My::set', 'tmpValue'); | |
78 | * ... | |
79 | * } | |
0b882a86 | 80 | * ``` |
b812aefb TO |
81 | * |
82 | * @param mixed $getter | |
83 | * Function to lookup current value. | |
84 | * @param mixed $setter | |
85 | * Function to set new value. | |
86 | * @param mixed $tmpValue | |
87 | * The value to temporarily use. | |
88 | * @return CRM_Utils_AutoClean | |
89 | * @see \Civi\Core\Resolver | |
90 | */ | |
91 | public static function swap($getter, $setter, $tmpValue) { | |
92 | $resolver = \Civi\Core\Resolver::singleton(); | |
93 | ||
be2fb01f | 94 | $origValue = $resolver->call($getter, []); |
b812aefb TO |
95 | |
96 | $ac = new CRM_Utils_AutoClean(); | |
97 | $ac->callback = $setter; | |
be2fb01f | 98 | $ac->args = [$origValue]; |
b812aefb | 99 | |
be2fb01f | 100 | $resolver->call($setter, [$tmpValue]); |
b812aefb TO |
101 | |
102 | return $ac; | |
103 | } | |
104 | ||
105 | public function __destruct() { | |
106 | \Civi\Core\Resolver::singleton()->call($this->callback, $this->args); | |
107 | } | |
108 | ||
b56a4a96 TO |
109 | /** |
110 | * Prohibit (de)serialization of CRM_Utils_AutoClean. | |
111 | * | |
112 | * The generic nature of AutoClean makes it a potential target for escalating | |
113 | * serialization vulnerabilities, and there's no good reason for serializing it. | |
114 | */ | |
115 | public function __sleep() { | |
116 | throw new \RuntimeException("CRM_Utils_AutoClean is a runtime helper. It is not intended for serialization."); | |
117 | } | |
118 | ||
119 | /** | |
120 | * Prohibit (de)serialization of CRM_Utils_AutoClean. | |
121 | * | |
122 | * The generic nature of AutoClean makes it a potential target for escalating | |
123 | * serialization vulnerabilities, and there's no good reason for deserializing it. | |
124 | */ | |
125 | public function __wakeup() { | |
126 | throw new \RuntimeException("CRM_Utils_AutoClean is a runtime helper. It is not intended for deserialization."); | |
127 | } | |
128 | ||
b812aefb | 129 | } |