args = func_get_args(); $ac->callback = array_shift($ac->args); return $ac; } /** * Temporarily swap values using callback functions, and cleanup * when the current context shuts down. * * ``` * function doStuff() { * $ac = CRM_Utils_AutoClean::swap('My::get', 'My::set', 'tmpValue'); * ... * } * ``` * * @param mixed $getter * Function to lookup current value. * @param mixed $setter * Function to set new value. * @param mixed $tmpValue * The value to temporarily use. * @return CRM_Utils_AutoClean * @see \Civi\Core\Resolver */ public static function swap($getter, $setter, $tmpValue) { $resolver = \Civi\Core\Resolver::singleton(); $origValue = $resolver->call($getter, []); $ac = new CRM_Utils_AutoClean(); $ac->callback = $setter; $ac->args = [$origValue]; $resolver->call($setter, [$tmpValue]); return $ac; } public function __destruct() { \Civi\Core\Resolver::singleton()->call($this->callback, $this->args); } /** * Prohibit (de)serialization of CRM_Utils_AutoClean. * * The generic nature of AutoClean makes it a potential target for escalating * serialization vulnerabilities, and there's no good reason for serializing it. */ public function __sleep() { throw new \RuntimeException("CRM_Utils_AutoClean is a runtime helper. It is not intended for serialization."); } /** * Prohibit (de)serialization of CRM_Utils_AutoClean. * * The generic nature of AutoClean makes it a potential target for escalating * serialization vulnerabilities, and there's no good reason for deserializing it. */ public function __wakeup() { throw new \RuntimeException("CRM_Utils_AutoClean is a runtime helper. It is not intended for deserialization."); } }