/**
  * Přidává k metadatům entity rozšiřující vazby
  *
  * @param string
  * @param MetaData
  * @return MetaData
  */
 public function completeMetaData($targetEntityClass, MetaData $metaData)
 {
     // kompletujeme relace i pro všechny předky entity
     $classes = $this->getClasses($targetEntityClass);
     $relations = array();
     foreach ($classes as $class) {
         $relations = $relations + $this->getRelations($class);
     }
     $properties = $metaData->toArray();
     // 0 type
     // 1 property
     // 2 relationType
     // 3 repositoryClass
     // 4 opositProperty
     foreach ($relations as $data) {
         if (isset($properties[$data[1]])) {
             continue;
         }
         if ($data[2] === MetaData::OneToMany) {
             $metaData->addProperty($data[1], $data[0])->setOneToMany($data[3], $data[4]);
         } elseif ($data[2] === MetaData::ManyToMany) {
             $metaData->addProperty($data[1], $data[0])->setManyToMany($data[3], $data[4], RelationshipMetaDataToMany::MAPPED_THERE);
         } else {
             throw new InvalidArgumentException("Pouze relace '1:m' a 'm:m' může být přiřazdena entitě rozšiřijící entitou. Uvedenou relaci '{$data['2']}' nelze přidat.");
         }
     }
     return $metaData;
 }
Пример #2
0
 /** @param DibiMapper */
 public function __construct(DibiMapper $mapper)
 {
     $this->mapper = $mapper;
     $model = $mapper->getModel();
     $repository = $mapper->getRepository();
     foreach ((array) $repository->getEntityClassName() as $entityName) {
         foreach (MetaData::getEntityRules($entityName, $model) as $name => $rule) {
             if ($rule['relationship'] === MetaData::OneToMany) {
                 $loader = $rule['relationshipParam'];
                 if ($r = $loader->getRepository() and $p = $loader->getParam()) {
                     $this->relationships[$name] = array($r, array('id', false), array($p, false));
                 }
             } else {
                 if ($rule['relationship'] === MetaData::ManyToMany) {
                     $loader = $rule['relationshipParam'];
                     if ($r = $loader->getRepository()) {
                         $manyToManyMapper = $loader->getMapper($repository);
                         if ($manyToManyMapper instanceof DibiManyToManyMapper) {
                             $this->relationships[$name] = array($r, array($manyToManyMapper->childParam, true), array('id', false), array($manyToManyMapper->table, array('id', false), array($manyToManyMapper->parentParam, true)));
                         }
                     }
                 } else {
                     if ($rule['relationship'] === MetaData::ManyToOne or $rule['relationship'] === MetaData::OneToOne) {
                         $this->relationships[$name] = array($rule['relationshipParam'], array(NULL, false), array('id', false));
                     }
                 }
             }
         }
     }
 }
Пример #3
0
 /**
  * @return string|NULL null mean disable
  */
 protected function getOrderProperty()
 {
     // Default ordering by property order is deprecated and in future version will be removed.
     if ($this->defaltOrderPropertyBCValue === false) {
         foreach ($this->getMetaData()->getCanConnectWithEntities($this->getModel()) as $entityClass) {
             $meta = MetaData::getEntityRules($entityClass, $this->getModel());
             if (!isset($meta['order'])) {
                 $this->defaltOrderPropertyBCValue = NULL;
                 break;
             }
             $this->defaltOrderPropertyBCValue = 'order';
         }
     }
     return $this->defaltOrderPropertyBCValue;
 }
Пример #4
0
 /**
  * Vrati cizy klice pro tuto entitu.
  * @param string
  * @return array paramName => repositoryName
  */
 private final function getFkForEntity($entityName)
 {
     static $fks = array();
     if (!isset($fks[$entityName])) {
         $fk = array();
         foreach (MetaData::getEntityRules($entityName, $this->model) as $name => $rule) {
             if ($rule['relationship'] !== MetaData::ManyToOne and $rule['relationship'] !== MetaData::OneToOne) {
                 continue;
             }
             $fk[$name] = $rule['relationshipParam'];
         }
         $fks[$entityName] = $fk;
     }
     return $fks[$entityName];
 }
 /**
  * Vytazena z mapperu
  * @param IRepository
  * @param array
  */
 protected function onLoad(IRepository $repository, array $data)
 {
     parent::onLoad($repository, $data);
     $this->rules = MetaData::getEntityRules(get_class($this), $repository->getModel());
     $this->values = $data;
     $this->valid = [];
     $this->getValue('id');
     // throw error if any
 }
 /**
  * @param IRepositoryContainer
  * @param string MetaData::ManyToOne|MetaData::OneToOne|MetaData::ManyToMany|MetaData::OneToMany
  * @param bool
  * @param callback (RelationshipMetaData $parent, RelationshipMetaData $child)
  */
 protected function checkIntegrity(IRepositoryContainer $model, $expectedType, $requiredChildParam, $callback = NULL)
 {
     $lowerEntityName = strtolower($this->parentEntityName);
     $classes = array_values((array) $model->getRepository($this->childRepository)->getEntityClassName());
     $this->canConnectWith = array_combine(array_map('strtolower', $classes), $classes);
     if (!$this->childParam) {
         return;
     }
     foreach ($this->canConnectWith as $lowerEn => $en) {
         $meta = MetaData::getEntityRules($en, $model, $this->childParam);
         $e = NULL;
         if (isset($meta[$this->childParam])) {
             $meta = $meta[$this->childParam];
             try {
                 if ($meta['relationship'] !== $expectedType) {
                     throw new RelationshipLoaderException("{$this->parentEntityName}::\${$this->parentParam} {{$this->type}} na druhe strane asociace {$en}::\${$this->childParam} neni asociace ktera by ukazovala zpet");
                 }
                 $loader = $meta['relationshipParam'];
                 if ($requiredChildParam and !$loader->childParam) {
                     throw new RelationshipLoaderException("{$this->parentEntityName}::\${$this->parentParam} {{$this->type}} na druhe strane asociace {$en}::\${$this->childParam} neni vyplnen param ktery by ukazoval zpet");
                 }
                 if (!isset($loader->canConnectWith[$lowerEntityName])) {
                     do {
                         foreach ($loader->canConnectWith as $canConnectWithEntity) {
                             if (is_subclass_of($canConnectWithEntity, $lowerEntityName)) {
                                 break 2;
                                 // goto canConnect;
                             }
                         }
                         throw new RelationshipLoaderException("{$this->parentEntityName}::\${$this->parentParam} {{$this->type}} na druhe strane asociace {$en}::\${$this->childParam} neukazuje zpet; ukazuje na jiny repository ({$loader->repository})");
                     } while (false);
                     // canConnect:
                 }
                 if ($loader->childParam and $loader->childParam !== $this->parentParam) {
                     throw new RelationshipLoaderException("{$this->parentEntityName}::\${$this->parentParam} {{$this->type}} na druhe strane asociace {$en}::\${$this->childParam} neukazuje zpet; ukazuje na jiny parametr ({$loader->childParam})");
                 }
                 if ($callback) {
                     call_user_func($callback, $this, $loader);
                 }
                 continue;
             } catch (Exception $e) {
             }
         }
         unset($this->canConnectWith[$lowerEn]);
         if ($e) {
             throw $e;
         }
     }
     if (!$this->canConnectWith) {
         throw new RelationshipLoaderException("{$this->parentEntityName}::\${$this->parentParam} {{$this->type}} na druhe strane asociace {$this->repository}::\${$this->childParam} neni asociace ktera by ukazovala zpet");
     }
 }
Пример #7
0
 /**
  * @param MetaData
  * @param string
  * @param MetaData::READWRITE|MetaData::READ|MetaData::WRITE
  * @param string
  */
 private function addProperty(MetaData $metaData, $string, $mode, $class)
 {
     if ($mode === MetaData::READWRITE) {
         if (preg_match('#^(-read|-write)?\\s?(.*)$#si', $string, $match)) {
             $mode = $match[1];
             $mode = ((!$mode or $mode === '-read') ? MetaData::READ : 0) | ((!$mode or $mode === '-write') ? MetaData::WRITE : 0);
             $string = $match[2];
         }
     }
     if (preg_match('#^([a-z0-9_\\|\\\\]+)\\s+\\$([a-z0-9_]+)($|\\s(.*)$)#si', $string, $match)) {
         $property = $match[2];
         $type = $match[1];
         $string = $match[3];
     } else {
         if (preg_match('#^\\$([a-z0-9_]+)\\s+([a-z0-9_\\|\\\\]+)($|\\s(.*)$)#si', $string, $match)) {
             $property = $match[1];
             $type = $match[2];
             $string = $match[3];
         } else {
             if (preg_match('#^\\$([a-z0-9_]+)($|\\s(.*)$)#si', $string, $match)) {
                 $property = $match[1];
                 $type = 'mixed';
                 $string = $match[2];
             } else {
                 $tmp = $mode === MetaData::READ ? '-read' : '';
                 throw new AnnotationMetaDataException("Invalid annotation format '@property{$tmp} {$string}' in {$class}");
             }
         }
     }
     $propertyName = $property;
     $property = $metaData->addProperty($propertyName, $type, $mode, $class);
     $this->property = array($propertyName, $property);
     $string = preg_replace_callback('#\\{\\s*([^\\s\\}\\{]+)(?:\\s+([^\\}\\{]*))?\\s*\\}#si', array($this, 'callOnMacro'), $string);
     $this->property = NULL;
     if (preg_match('#\\{|\\}#', $string)) {
         $string = trim($string);
         throw new AnnotationMetaDataException("Invalid annotation format, extra curly bracket '{$string}' in {$class}::\${$propertyName}");
     }
 }
Пример #8
0
 /**
  * Jestli je parametr ke cteni nebo jen pro zapis
  * @param int MetaData::READ|MetaData::READWRITE
  * @param MetaData
  * @return MetaDataProperty $this
  */
 protected function setAccess($access, MetaData $meta)
 {
     if ($access === NULL) {
         $access = MetaData::READWRITE;
     }
     if ($access === MetaData::WRITE) {
         throw new MetaDataException("Neni mozne vytvaret write-only polozky: {$this->class}::\${$this->name}");
     }
     if (!in_array($access, array(MetaData::READ, MetaData::READWRITE), true)) {
         throw new MetaDataException(__CLASS__ . ' access is Orm\\MetaData::READ or Orm\\MetaData::READWRITE allowed');
     }
     $methods = $meta->getMethods($this->name);
     if ($methods['is'] and $this->data['types'] === array('bool' => 'bool')) {
         $methods['get'] = $methods['is'];
     }
     $this->data['get'] = $access & MetaData::READ ? array('method' => $methods['get']) : NULL;
     $this->data['set'] = $access & MetaData::WRITE ? array('method' => $methods['set']) : NULL;
     return $this;
 }
 /**
  * @param MetaData $metaData
  * @param string $string
  * @param string $mode ::READWRITE|MetaData::READ|MetaData::WRITE
  * @param string $class
  * @param ReflectionClass $r
  */
 private function addProperty(MetaData $metaData, $string, $mode, $class, ReflectionClass $r)
 {
     if ($mode === MetaData::READWRITE) {
         if (preg_match('#^(-read|-write)?\\s?(.*)$#si', $string, $match)) {
             $mode = $match[1];
             $mode = ((!$mode or $mode === '-read') ? MetaData::READ : 0) | ((!$mode or $mode === '-write') ? MetaData::WRITE : 0);
             $string = $match[2];
         }
     }
     if (preg_match('#^([a-z0-9_\\[\\]\\|\\\\]+)\\s+\\$([a-z0-9_]+)($|\\s(.*)$)#si', $string, $match)) {
         $property = $match[2];
         $type = $match[1];
         $string = $match[3];
     } else {
         if (preg_match('#^\\$([a-z0-9_]+)\\s+([a-z0-9_\\|\\\\]+)($|\\s(.*)$)#si', $string, $match)) {
             $property = $match[1];
             $type = $match[2];
             $string = $match[3];
         } else {
             if (preg_match('#^\\$([a-z0-9_]+)($|\\s(.*)$)#si', $string, $match)) {
                 $property = $match[1];
                 $type = 'mixed';
                 $string = $match[2];
             } else {
                 $tmp = $mode === MetaData::READ ? '-read' : '';
                 throw new AnnotationMetaDataException("Invalid annotation format '@property{$tmp} {$string}' in {$class}");
             }
         }
     }
     if (strpos(strToLower($string), '{ignore}') !== FALSE) {
         return;
     }
     $propertyName = $property;
     // Support for simplified FQN '@property Foo' instead of '@property \App\Foo'
     $parts = explode('|', $type);
     foreach ($parts as &$part) {
         $fqn = NetteAnnotationsParser::expandClassName($part, $r);
         if (class_exists($fqn)) {
             $part = $fqn;
         }
         if ($part === Orm\OneToMany::class) {
             // Support for '@property OtM|Foo[]' instead of '@property Orm\OneToMany'
             $parts = [Orm\OneToMany::class];
             break;
         } else {
             if ($part === Orm\ManyToMany::class) {
                 // Support for '@property MtM|Foo[]' instead of '@property Orm\ManyToMany'
                 $parts = [Orm\ManyToMany::class];
                 break;
             } else {
                 if (substr($part, -2) === '[]') {
                     $part = 'array';
                 }
             }
         }
     }
     $type = implode('|', $parts);
     $property = $metaData->addProperty($propertyName, $type, $mode, $class);
     $this->property = [$propertyName, $property];
     $string = preg_replace_callback('#\\{\\s*([^\\s\\}\\{]+)(?:\\s+([^\\}\\{]*))?\\s*\\}#si', [$this, 'callOnMacro'], $string);
     $this->property = NULL;
     if (preg_match('#\\{|\\}#', $string)) {
         $string = trim($string);
         throw new AnnotationMetaDataException("Invalid annotation format, extra curly bracket '{$string}' in {$class}::\${$propertyName}");
     }
 }