예제 #1
0
 /**
  * Sets a variable in this session section.
  * @param  string  name
  * @param  mixed   value
  * @return void
  */
 public function __set($name, $value)
 {
     $this->start();
     $this->data[$name] = $value;
     if (is_object($value)) {
         $this->meta[$name]['V'] = XApp_Reflection_ClassType::from($value)->getAnnotation('serializationVersion');
     }
 }
예제 #2
0
 /**
  * Returns annotations.
  * @param  \ReflectionClass|\ReflectionMethod|\ReflectionProperty
  * @return array
  */
 public static function getAll(\Reflector $r)
 {
     if ($r instanceof ReflectionClass) {
         $type = $r->getName();
         $member = 'class';
     } elseif ($r instanceof ReflectionMethod) {
         $type = $r->getDeclaringClass()->getName();
         $member = $r->getName();
     } else {
         $type = $r->getDeclaringClass()->getName();
         $member = '$' . $r->getName();
     }
     if (!self::$useReflection) {
         // auto-expire cache
         $file = $r instanceof ReflectionClass ? $r->getFileName() : $r->getDeclaringClass()->getFileName();
         // will be used later
         if ($file && isset(self::$timestamps[$file]) && self::$timestamps[$file] !== filemtime($file)) {
             unset(self::$cache[$type]);
         }
         unset(self::$timestamps[$file]);
     }
     if (isset(self::$cache[$type][$member])) {
         // is value cached?
         return self::$cache[$type][$member];
     }
     if (self::$useReflection === NULL) {
         // detects whether is reflection available
         self::$useReflection = (bool) XApp_Reflection_ClassType::from(__CLASS__)->getDocComment();
     }
     if (self::$useReflection) {
         $annotations = self::parseComment($r->getDocComment());
     } else {
         if (!self::$cacheStorage) {
             // trigger_error('Set a cache storage for annotations parser via Nette\Reflection\AnnotationParser::setCacheStorage().', E_USER_WARNING);
             self::$cacheStorage = new Nette\Caching\Storages\DevNullStorage();
         }
         $outerCache = new Nette\Caching\Cache(self::$cacheStorage, 'Nette.Reflection.Annotations');
         if (self::$cache === NULL) {
             self::$cache = (array) $outerCache->load('list');
             self::$timestamps = isset(self::$cache['*']) ? self::$cache['*'] : array();
         }
         if (!isset(self::$cache[$type]) && $file) {
             self::$cache['*'][$file] = filemtime($file);
             foreach (self::parsePhp(file_get_contents($file)) as $class => $info) {
                 foreach ($info as $prop => $comment) {
                     if ($prop !== 'use') {
                         self::$cache[$class][$prop] = self::parseComment($comment);
                     }
                 }
             }
             $outerCache->save('list', self::$cache);
         }
         if (isset(self::$cache[$type][$member])) {
             $annotations = self::$cache[$type][$member];
         } else {
             $annotations = array();
         }
     }
     if ($r instanceof \ReflectionMethod && !$r->isPrivate() && (!$r->isConstructor() || !empty($annotations['inheritdoc'][0]))) {
         try {
             $inherited = self::getAll(new \ReflectionMethod(get_parent_class($type), $member));
         } catch (\ReflectionException $e) {
             try {
                 $inherited = self::getAll($r->getPrototype());
             } catch (\ReflectionException $e) {
                 $inherited = array();
             }
         }
         $annotations += array_intersect_key($inherited, array_flip(self::$inherited));
     }
     return self::$cache[$type][$member] = $annotations;
 }
예제 #3
0
 /**
  * Starts and initializes session data.
  * @throws XApp_InvalidStateException
  * @return void
  */
 public function start()
 {
     if (self::$started) {
         return;
     }
     $this->configure($this->options);
     $id =& $_COOKIE[session_name()];
     if (!is_string($id) || !preg_match('#^[0-9a-zA-Z,-]{22,128}\\z#i', $id)) {
         unset($_COOKIE[session_name()]);
     }
     set_error_handler(function ($severity, $message) use(&$error) {
         // session_start returns FALSE on failure only sometimes
         if (($severity & error_reporting()) === $severity) {
             $error = $message;
             restore_error_handler();
         }
     });
     session_start();
     if (!$error) {
         restore_error_handler();
     }
     $this->response->removeDuplicateCookies();
     if ($error) {
         @session_write_close();
         // this is needed
         throw new Exception("session_start(): {$error}");
     }
     self::$started = TRUE;
     /* structure:
     			__NF: BrowserKey, Data, Meta, Time
     				DATA: section->variable = data
     				META: section->variable = Timestamp, Browser, Version
     		*/
     $nf =& $_SESSION['__NF'];
     // regenerate empty session
     if (empty($nf['Time'])) {
         $nf['Time'] = time();
         $this->regenerated = TRUE;
     }
     // browser closing detection
     $browserKey = $this->request->getCookie('nette-browser');
     if (!$browserKey) {
         $browserKey = XApp_Utils_Strings::random();
     }
     $browserClosed = !isset($nf['B']) || $nf['B'] !== $browserKey;
     $nf['B'] = $browserKey;
     // resend cookie
     $this->sendCookie();
     // process meta metadata
     if (isset($nf['META'])) {
         $now = time();
         // expire section variables
         foreach ($nf['META'] as $section => $metadata) {
             if (is_array($metadata)) {
                 foreach ($metadata as $variable => $value) {
                     if (!empty($value['B']) && $browserClosed || !empty($value['T']) && $now > $value['T'] || isset($nf['DATA'][$section][$variable]) && is_object($nf['DATA'][$section][$variable]) && (isset($value['V']) ? $value['V'] : NULL) != XApp_Reflection_ClassType::from($nf['DATA'][$section][$variable])->getAnnotation('serializationVersion')) {
                         if ($variable === '') {
                             // expire whole section
                             unset($nf['META'][$section], $nf['DATA'][$section]);
                             continue 2;
                         }
                         unset($nf['META'][$section][$variable], $nf['DATA'][$section][$variable]);
                     }
                 }
             }
         }
     }
     if ($this->regenerated) {
         $this->regenerated = FALSE;
         $this->regenerateId();
     }
     register_shutdown_function(array($this, 'clean'));
 }