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 | ||
51 | /** | |
52 | * Temporarily swap values using callback functions, and cleanup | |
53 | * when the current context shuts down. | |
54 | * | |
0b882a86 | 55 | * ``` |
b812aefb TO |
56 | * function doStuff() { |
57 | * $ac = CRM_Utils_AutoClean::swap('My::get', 'My::set', 'tmpValue'); | |
58 | * ... | |
59 | * } | |
0b882a86 | 60 | * ``` |
b812aefb TO |
61 | * |
62 | * @param mixed $getter | |
63 | * Function to lookup current value. | |
64 | * @param mixed $setter | |
65 | * Function to set new value. | |
66 | * @param mixed $tmpValue | |
67 | * The value to temporarily use. | |
68 | * @return CRM_Utils_AutoClean | |
69 | * @see \Civi\Core\Resolver | |
70 | */ | |
71 | public static function swap($getter, $setter, $tmpValue) { | |
72 | $resolver = \Civi\Core\Resolver::singleton(); | |
73 | ||
be2fb01f | 74 | $origValue = $resolver->call($getter, []); |
b812aefb TO |
75 | |
76 | $ac = new CRM_Utils_AutoClean(); | |
77 | $ac->callback = $setter; | |
be2fb01f | 78 | $ac->args = [$origValue]; |
b812aefb | 79 | |
be2fb01f | 80 | $resolver->call($setter, [$tmpValue]); |
b812aefb TO |
81 | |
82 | return $ac; | |
83 | } | |
84 | ||
85 | public function __destruct() { | |
86 | \Civi\Core\Resolver::singleton()->call($this->callback, $this->args); | |
87 | } | |
88 | ||
b56a4a96 TO |
89 | /** |
90 | * Prohibit (de)serialization of CRM_Utils_AutoClean. | |
91 | * | |
92 | * The generic nature of AutoClean makes it a potential target for escalating | |
93 | * serialization vulnerabilities, and there's no good reason for serializing it. | |
94 | */ | |
95 | public function __sleep() { | |
96 | throw new \RuntimeException("CRM_Utils_AutoClean is a runtime helper. It is not intended for serialization."); | |
97 | } | |
98 | ||
99 | /** | |
100 | * Prohibit (de)serialization of CRM_Utils_AutoClean. | |
101 | * | |
102 | * The generic nature of AutoClean makes it a potential target for escalating | |
103 | * serialization vulnerabilities, and there's no good reason for deserializing it. | |
104 | */ | |
105 | public function __wakeup() { | |
106 | throw new \RuntimeException("CRM_Utils_AutoClean is a runtime helper. It is not intended for deserialization."); | |
107 | } | |
108 | ||
b812aefb | 109 | } |