/** * Saves state information for all subcomponents to $this->globalState. * @return array */ private function getGlobalState($forClass = NULL) { $sinces =& $this->globalStateSinces; if ($this->globalState === NULL) { if ($this->phase >= self::PHASE_SHUTDOWN) { throw new InvalidStateException("Presenter is shutting down, cannot save state."); } $state = array(); foreach ($this->globalParams as $id => $params) { $prefix = $id . self::NAME_SEPARATOR; foreach ($params as $key => $val) { $state[$prefix . $key] = $val; } } $this->saveState($state, $forClass); if ($sinces === NULL) { $sinces = array(); foreach (PresenterHelpers::getPersistentParams(get_class($this)) as $nm => $meta) { $sinces[$nm] = $meta['since']; } } $components = PresenterHelpers::getPersistentComponents(get_class($this)); $iterator = $this->getComponents(TRUE, 'Nette\\Application\\IStatePersistent'); foreach ($iterator as $name => $component) { if ($iterator->getDepth() === 0) { // counts with RecursiveIteratorIterator::SELF_FIRST $since = isset($components[$name]['since']) ? $components[$name]['since'] : FALSE; // FALSE = nonpersistent } $prefix = $component->getUniqueId() . self::NAME_SEPARATOR; $params = array(); $component->saveState($params); foreach ($params as $key => $val) { $state[$prefix . $key] = $val; $sinces[$prefix . $key] = $since; } } } else { $state = $this->globalState; } if ($forClass !== NULL) { $since = NULL; foreach ($state as $key => $foo) { if (!isset($sinces[$key])) { $x = strpos($key, self::NAME_SEPARATOR); $x = $x === FALSE ? $key : substr($key, 0, $x); $sinces[$key] = isset($sinces[$x]) ? $sinces[$x] : FALSE; } if ($since !== $sinces[$key]) { $since = $sinces[$key]; $ok = $since && (is_subclass_of($forClass, $since) || $forClass === $since); } if (!$ok) { unset($state[$key]); } } } return $state; }
/** * Saves state informations for next request. * @param array * @param portion specified by class name (used by Presenter) * @return void */ public function saveState(array &$params, $forClass = NULL) { foreach (PresenterHelpers::getPersistentParams($forClass === NULL ? $this->getClass() : $forClass) as $nm => $meta) { if (isset($params[$nm])) { $val = $params[$nm]; // injected value } elseif (array_key_exists($nm, $params)) { // $params[$nm] === NULL continue; // means skip } elseif (!isset($meta['since']) || $this instanceof $meta['since']) { $val = $this->{$nm}; // object property value } else { continue; // ignored parameter } if (is_object($val)) { throw new InvalidStateException("Persistent parameter must be scalar or array, '{$this->class}::\${$nm}' is " . gettype($val)); } else { if (isset($meta['def'])) { settype($val, gettype($meta['def'])); if ($val === $meta['def']) { $val = NULL; } } else { if ((string) $val === '') { $val = NULL; } } $params[$nm] = $val; } } }