push(array( * '_GET' => array( * 'q' => 'some-value * ), * )); * ...do stuff... * $globals->pop(); * @endcode * * Note: for purposes of this class, we'll refer to the array passed into * push() as a frame. */ class CRM_Utils_GlobalStack { /** * We don't have a container or dependency-injection, so use singleton instead * * @var object */ private static $_singleton = NULL; private $backups = array(); /** * Get or set the single instance of CRM_Utils_GlobalStack. * * @return CRM_Utils_GlobalStack */ static public function singleton() { if (self::$_singleton === NULL) { self::$_singleton = new CRM_Utils_GlobalStack(); } return self::$_singleton; } /** * @param $newFrame */ public function push($newFrame) { $this->backups[] = $this->createBackup($newFrame); $this->applyFrame($newFrame); } public function pop() { $this->applyFrame(array_pop($this->backups)); } /** * @param array $new * The new, incoming frame. * @return array * frame */ public function createBackup($new) { $frame = array(); foreach ($new as $globalKey => $values) { if (is_array($values)) { foreach ($values as $key => $value) { $frame[$globalKey][$key] = CRM_Utils_Array::value($key, $GLOBALS[$globalKey]); } } else { $frame[$globalKey] = CRM_Utils_Array::value($globalKey, $GLOBALS); } } return $frame; } /** * @param $newFrame */ public function applyFrame($newFrame) { foreach ($newFrame as $globalKey => $values) { if (is_array($values)) { foreach ($values as $key => $value) { $GLOBALS[$globalKey][$key] = $value; } } else { $GLOBALS[$globalKey] = $values; } } } }