Пример #1
0
 private function cachedGet($classname, $all)
 {
     $loops = $this->getLoops();
     if (is_object($classname)) {
         $classname = get_class($classname);
     }
     $key = "Loops-Service-Annotations-{$classname}-" . ($all ? "all" : "strict");
     static $cache;
     if (!$cache) {
         $cache = new ChainCache([new ArrayCache(), $loops->getService("cache")]);
     }
     if ($cache->contains($key)) {
         return $cache->fetch($key);
     }
     $result = new __Class_Annotations($classname, $this->getLoops()->getService("doctrine_annotation_reader"), $all);
     $cache->save($key, $result);
     return $result;
 }
Пример #2
0
 /**
  * Build ReadOnly/ReadWrite/Expose/Sleep data from annotations
  */
 private static function initPropertyCache($class)
 {
     $loops = $class instanceof Object ? $class->getLoops() : Loops::getCurrentLoops();
     $classname = get_class($class);
     $key = "Loops-Misc-AccessTrait-{$classname}";
     static $cache;
     if (!$cache) {
         $cache = new ChainCache([new ArrayCache(), $loops->getService("cache")]);
     }
     if ($cache->contains($key)) {
         return $cache->fetch($key);
     }
     $annotations = $loops->getService("annotations");
     // build
     $result["getter"] = [];
     $result["setter"] = [];
     $result["exposed"] = [];
     $result["protected"] = [];
     $result["sleep"] = [];
     $ro = $annotations->get($classname)->properties->findFirst("Access\\ReadOnly");
     $rw = $annotations->get($classname)->properties->findFirst("Access\\ReadWrite");
     //make getter
     foreach (array_merge($ro, $rw) as $name => $annotation) {
         if ($annotation->getter && !method_exists($class, $annotation->getter)) {
             throw new Exception("Passed getter '{$annotation->getter}' is not a method of class '{$classname}'.");
         }
         $result["getter"][$name] = $annotation->getter ? [$annotation->getter, $annotation->arguments] : $name;
     }
     //make setter
     foreach ($rw as $name => $annotation) {
         if ($annotation->setter && !method_exists($class, $annotation->setter)) {
             throw new Exception("Passed getter '{$annotation->setter}' is not a method of class '{$classname}'.");
         }
         $result["setter"][$name] = $annotation->setter ? [$annotation->setter] : $name;
     }
     //expose public properties
     foreach ((new ReflectionClass($classname))->getProperties() as $property) {
         if ($property->isStatic()) {
             continue;
         }
         if ($property->isPublic()) {
             $name = $property->getName();
             $result["getter"][$name] = $name;
             $result["setter"][$name] = $name;
             $result["exposed"][$name] = $name;
         }
         if ($property->isProtected()) {
             $name = $property->getName();
             $result["protected"][$name] = $name;
         }
     }
     //expose properties that have the Exposed annotation - prefer getter of property if exists
     foreach ($annotations->get($classname)->properties->findLast("Access\\Expose") as $name => $annotation) {
         $result["exposed"][$annotation->name ?: $name] = array_key_exists($name, $result["getter"]) ? $result["getter"][$name] : $name;
     }
     //expose methods that have the Exposed annotation
     foreach ($annotations->get($classname)->methods->findLast("Access\\Expose") as $name => $annotation) {
         $result["exposed"][$annotation->name ?: $name] = [$name, $annotation->arguments];
     }
     //check, which keys must be imported when sleeping
     $current = $classname;
     do {
         $set = $annotations->getStrict($current);
         $properties = array_keys(iterator_to_array($set->properties));
         $properties = array_filter($properties, function ($name) use($current) {
             $property = new ReflectionProperty($current, $name);
             if ($property->isStatic()) {
                 return FALSE;
             }
             if ($property->isPrivate()) {
                 return FALSE;
             }
             return TRUE;
         });
         foreach ($set->find("Access\\Sleep") as $sleep) {
             if ($sleep->forbid) {
                 $result["sleep"] = FALSE;
                 break 2;
             }
             if ($sleep->include) {
                 $properties = array_intersect($properties, $sleep->include);
             }
             if ($sleep->exclude) {
                 $properties = array_diff($properties, $sleep->exclude);
             }
         }
         $result["sleep"] = array_merge($result["sleep"], $properties);
     } while ($current = get_parent_class($current));
     $cache->save($key, $result);
     return $result;
 }