Returns repository by repository class.
public getRepository ( string $className ) : Nextras\Orm\Repository\IRepository | ||
$className | string | |
return | Nextras\Orm\Repository\IRepository |
protected function random(PropertyMetadata $property) { if (in_array($property->relationshipType, [PropertyMetadata::RELATIONSHIP_MANY_HAS_ONE, PropertyMetadata::RELATIONSHIP_ONE_HAS_ONE, PropertyMetadata::RELATIONSHIP_ONE_HAS_ONE_DIRECTED])) { $entityClass = $this->model->getRepository($property->relationshipRepository)->getEntityClassNames()[0]; return $this->create($entityClass); } $possibilities = []; if ($property->enum) { $possibilities = $property->enum; } else { foreach (array_keys($property->types) as $type) { switch ($type) { case 'datetime': $possibilities[] = new DateTime($this->randomInt(2010, 2020) . '-' . $this->randomInt(1, 12) . '-' . $this->randomInt(1, 31)); break; case 'string': $possibilities[] = $this->randomWords(20, 50); break; case 'int': $possibilities[] = $this->randomInt(0, 100); break; case 'float': $possibilities[] = $this->randomInt(0, 100) + $this->randomInt(0, 100) / 100; break; case 'bool': $possibilities[] = (bool) $this->randomInt(0, 1); break; } } } if (!$possibilities) { return NULL; } return $possibilities[array_rand($possibilities)]; }
private function parseCondition(array $levels, IMapper $mapper) { /** @var IDbStorageReflection $reflection */ $reflection = $mapper->getStorageReflection(); $expression = ''; $column = array_pop($levels); $entityMD = $this->metadataStorage->get($mapper->getRepository()->getEntityClassNames()[0]); foreach ($levels as $level) { if (!$entityMD->hasProperty($level)) { throw new InvalidArgumentException("Undefined property {$entityMD->className}::\${$level}."); } $propertyMD = $entityMD->getProperty($level); if (!$propertyMD->relationshipRepository) { throw new InvalidArgumentException("Entity {$entityMD->className}::\${$level} does not contain a relationship."); } $targetMapper = $this->model->getRepository($propertyMD->relationshipRepository)->getMapper(); $targetReflection = $targetMapper->getStorageReflection(); if ($propertyMD->relationshipType === PropertyMetadata::RELATIONSHIP_ONE_HAS_MANY) { $table = $targetReflection->getStorageName(); $joinColumn = $targetReflection->convertEntityToStorageKey($propertyMD->relationshipProperty); $expression .= ":{$table}({$joinColumn})"; } elseif ($propertyMD->relationshipType === PropertyMetadata::RELATIONSHIP_MANY_HAS_MANY) { if ($propertyMD->relationshipIsMain) { $expression .= ':' . $reflection->getManyHasManyStorageName($targetMapper); $expression .= '.' . $reflection->getManyHasManyStoragePrimaryKeys($targetMapper)[1]; } else { $expression .= ':' . $targetReflection->getManyHasManyStorageName($mapper); $expression .= '.' . $targetReflection->getManyHasManyStoragePrimaryKeys($mapper)[0]; } } else { $expression .= '.' . $reflection->convertEntityToStorageKey($level); } $mapper = $targetMapper; $reflection = $targetReflection; $entityMD = $this->metadataStorage->get($mapper->getRepository()->getEntityClassNames()[0]); } // check if property exists $entityMD->getProperty($column); $column = $reflection->convertEntityToStorageKey($column); return "{$expression}.{$column}"; }
/** @inheritdoc */ public function remove($entity, $recursive = FALSE) { $entity = $entity instanceof IEntity ? $entity : $this->getById($entity); $this->identityMap->check($entity); if (isset($this->isProcessing[spl_object_hash($entity)])) { return $entity; } $this->isProcessing[spl_object_hash($entity)] = TRUE; $this->fireEvent($entity, 'onBeforeRemove'); foreach ($entity->getMetadata()->getProperties() as $property) { if ($property->relationship !== NULL) { if (in_array($property->relationship->type, [PropertyRelationshipMetadata::MANY_HAS_ONE, PropertyRelationshipMetadata::ONE_HAS_ONE, PropertyRelationshipMetadata::ONE_HAS_ONE_DIRECTED])) { $entity->getProperty($property->name)->set(NULL, TRUE); } elseif ($property->relationship->type === PropertyRelationshipMetadata::MANY_HAS_MANY) { $entity->getValue($property->name)->set([]); } else { $reverseRepository = $this->model->getRepository($property->relationship->repository); $reverseProperty = $reverseRepository->getEntityMetadata()->getProperty($property->relationship->property); if ($reverseProperty->isNullable || !$recursive) { $entity->getValue($property->name)->set([]); } else { foreach ($entity->getValue($property->name) as $reverseEntity) { $reverseRepository->remove($reverseEntity, $recursive); } } } } } if ($entity->isPersisted()) { $this->mapper->remove($entity); $this->identityMap->remove($entity->getPersistedId()); $this->entitiesToFlush[1][] = $entity; } $this->detach($entity); $this->fireEvent($entity, 'onAfterRemove'); unset($this->isProcessing[spl_object_hash($entity)]); return $entity; }
protected function createComponentOneHasMany(Nextras\Orm\Entity\Reflection\PropertyMetadata $metadata, int $forceDefault = 0) : Kdyby\Replicator\Container { $repository = $this->model->getRepository($metadata->relationship->repository); $collection = $this->entity->getValue($metadata->name)->get()->fetchPairs(current($repository->getEntityMetadata()->getPrimaryKey())); $replicator = new Kdyby\Replicator\Container(function (Nette\Forms\Container $container) use($metadata, $repository, $collection) { $replicator = $container->parent; $name = $container->getName(); unset($container->parent[$name]); if (!($entity = $collection[$name] ?? NULL)) { $entityClassName = $repository->getEntityMetadata()->getClassName(); $entity = new $entityClassName(); } $replicator->addComponent($container = $this->form->createComponent($entity), $name); if ($container instanceof Nette\Forms\Container) { call_user_func([$container->addSubmit('delete', $this->formatPropertyAction($metadata, 'delete')), 'addRemoveOnClick'], function (Kdyby\Replicator\Container $replicator, self $container) { $container->removeEntity(TRUE); }); } }); $add = $replicator->addSubmit('add', $this->formatPropertyAction($metadata, 'add')); call_user_func([$add, 'addCreateOnClick']); $add->setValidationScope([$replicator]); $replicator->setCurrentGroup($this->getForm()->addGroup($this->prefixPropertyGroup($metadata), FALSE)->add($add)); $this[$metadata->name] = $replicator; if ($createDefault = max(count($collection), $forceDefault)) { if (!$this->getForm()->isSubmitted()) { $count = 0; while ($count++ < $createDefault) { $replicator->createOne(key($collection)); next($collection); } } elseif ($forceDefault) { while (iterator_count($replicator->getContainers()) < $createDefault) { $replicator->createOne(); } } } if ($add->isSubmittedBy()) { $isValid = TRUE; if ($scope = $add->getValidationScope()) { $isValid = !array_filter($scope, function (Nette\Forms\Container $container) { return !$container->isValid(); }); } if ($isValid) { $add->setValidationScope(FALSE); } $add->click(); $add->onClick = []; } $containers = []; foreach ($replicator->getContainers() as $container) { $delete = $container['delete'] ?? NULL; if ($delete instanceof Nette\Forms\Controls\SubmitButton && !$delete->isSubmittedBy()) { $containers[$container->name] = $container; } } if (count($containers) <= $forceDefault) { array_map(function (self $container) { unset($container['delete']); }, $containers); } else { $persistedContainers = array_filter($containers, function (self $container) { return $container->getEntity()->isPersisted(); }); if (count($persistedContainers) <= $forceDefault) { array_map(function (self $container) { unset($container['delete']); }, $persistedContainers); } } foreach ($containers as $key => $container) { if ($container instanceof Nette\ComponentModel\IContainer) { foreach ($container->getComponents(FALSE, Nette\Forms\Controls\BaseControl::class) as $control) { if ($control instanceof Nette\Forms\Controls\BaseControl && ($unique = $control->getOption('unique'))) { foreach (array_diff_key($containers, [$key => $container]) as $sibling) { $condition = $control->addCondition(Nette\Forms\Form::FILLED); if (is_string($unique) && isset($sibling[$unique]) && ($uniqueControl = $container[$unique] ?? NULL)) { if ($uniqueControl instanceof Nette\Forms\IControl) { $condition = $condition->addConditionOn($uniqueControl, Nette\Forms\Form::EQUAL, $sibling[$unique]); } } $condition->addRule(Nette\Forms\Form::NOT_EQUAL, NULL, $sibling[$control->name]); } } } } } return $replicator; }
private function normalizeAndAddJoins(array $levels, $sourceEntity, QueryBuilder $builder, &$distinctNeeded = false, &$value = null, &$modifier = '%any') { $column = array_pop($levels); $sourceMapper = $this->mapper; $sourceAlias = $builder->getFromAlias(); $sourceReflection = $sourceMapper->getStorageReflection(); $sourceEntityMeta = $this->metadataStorage->get($sourceEntity ?: $sourceMapper->getRepository()->getEntityClassNames()[0]); foreach ($levels as $levelIndex => $level) { $property = $sourceEntityMeta->getProperty($level); if ($property->relationship === null) { throw new InvalidArgumentException("Entity {$sourceEntityMeta->className}::\${$level} does not contain a relationship."); } $targetMapper = $this->model->getRepository($property->relationship->repository)->getMapper(); $targetReflection = $targetMapper->getStorageReflection(); $targetEntityMetadata = $this->metadataStorage->get($property->relationship->entity); $relType = $property->relationship->type; if ($relType === Relationship::ONE_HAS_MANY || $relType === Relationship::ONE_HAS_ONE && !$property->relationship->isMain) { $targetColumn = $targetReflection->convertEntityToStorageKey($property->relationship->property); $sourceColumn = $sourceReflection->getStoragePrimaryKey()[0]; $distinctNeeded = $relType === Relationship::ONE_HAS_MANY; } elseif ($relType === Relationship::MANY_HAS_MANY) { if ($property->relationship->isMain) { list($joinTable, list($inColumn, $outColumn)) = $sourceMapper->getManyHasManyParameters($property, $targetMapper); } else { $sourceProperty = $targetEntityMetadata->getProperty($property->relationship->property); list($joinTable, list($outColumn, $inColumn)) = $targetMapper->getManyHasManyParameters($sourceProperty, $sourceMapper); } $sourceColumn = $sourceReflection->getStoragePrimaryKey()[0]; $builder->leftJoin($sourceAlias, $joinTable, self::getAlias($joinTable), "[{$sourceAlias}.{$sourceColumn}] = [{$joinTable}.{$inColumn}]"); $sourceAlias = $joinTable; $sourceColumn = $outColumn; $targetColumn = $targetReflection->getStoragePrimaryKey()[0]; $distinctNeeded = true; } else { $targetColumn = $targetReflection->getStoragePrimaryKey()[0]; $sourceColumn = $sourceReflection->convertEntityToStorageKey($level); } $targetTable = $targetMapper->getTableName(); $targetAlias = $level . str_repeat('_', $levelIndex); $builder->leftJoin($sourceAlias, $targetTable, $targetAlias, "[{$sourceAlias}.{$sourceColumn}] = [{$targetAlias}.{$targetColumn}]"); $sourceAlias = $targetAlias; $sourceMapper = $targetMapper; $sourceReflection = $targetReflection; $sourceEntityMeta = $targetEntityMetadata; } $targetProperty = $sourceEntityMeta->getProperty($column); if ($targetProperty->isPrimary && $targetProperty->isVirtual) { // primary-proxy $primaryKey = $sourceEntityMeta->getPrimaryKey(); if (count($primaryKey) > 1) { // composite primary key $modifier = '%any'; list($expression, $value) = $this->processMultiColumn($sourceReflection, $primaryKey, $value, $sourceAlias); return $expression; } else { $column = reset($primaryKey); } } list($expression, $modifier, $value) = $this->processColumn($sourceReflection, $column, $value, $sourceAlias); return $expression; }
private function normalizeAndAddJoins(array $levels, $sourceEntity, QueryBuilder $builder, &$distinctNeeded = FALSE, &$value = NULL) { $column = array_pop($levels); $sourceMapper = $this->mapper; $sourceAlias = $builder->getFromAlias(); $sourceReflection = $sourceMapper->getStorageReflection(); $sourceEntityMeta = $this->metadataStorage->get($sourceEntity ?: $sourceMapper->getRepository()->getEntityClassNames()[0]); foreach ($levels as $levelIndex => $level) { $property = $sourceEntityMeta->getProperty($level); if ($property->relationship === NULL) { throw new InvalidArgumentException("Entity {$sourceEntityMeta->className}::\${$level} does not contain a relationship."); } $targetMapper = $this->model->getRepository($property->relationship->repository)->getMapper(); $targetReflection = $targetMapper->getStorageReflection(); $targetEntityMetadata = $this->metadataStorage->get($property->relationship->entity); $relType = $property->relationship->type; if ($relType === Relationship::ONE_HAS_MANY || $relType === Relationship::ONE_HAS_ONE_DIRECTED && !$property->relationship->isMain) { $targetColumn = $targetReflection->convertEntityToStorageKey($property->relationship->property); $sourceColumn = $sourceReflection->getStoragePrimaryKey()[0]; $distinctNeeded = TRUE; } elseif ($relType === Relationship::MANY_HAS_MANY) { if ($property->relationship->isMain) { list($joinTable, list($inColumn, $outColumn)) = $sourceMapper->getManyHasManyParameters($property, $targetMapper); } else { $sourceProperty = $targetEntityMetadata->getProperty($property->relationship->property); list($joinTable, list($outColumn, $inColumn)) = $targetMapper->getManyHasManyParameters($sourceProperty, $sourceMapper); } $sourceColumn = $sourceReflection->getStoragePrimaryKey()[0]; $builder->leftJoin($sourceAlias, $joinTable, self::getAlias($joinTable), "[{$sourceAlias}.{$sourceColumn}] = [{$joinTable}.{$inColumn}]"); $sourceAlias = $joinTable; $sourceColumn = $outColumn; $targetColumn = $targetReflection->getStoragePrimaryKey()[0]; $distinctNeeded = TRUE; } else { $targetColumn = $targetReflection->getStoragePrimaryKey()[0]; $sourceColumn = $sourceReflection->convertEntityToStorageKey($level); } $targetTable = $targetMapper->getTableName(); $targetAlias = $level . str_repeat('_', $levelIndex); $builder->leftJoin($sourceAlias, $targetTable, $targetAlias, "[{$sourceAlias}.{$sourceColumn}] = [{$targetAlias}.{$targetColumn}]"); $sourceAlias = $targetAlias; $sourceMapper = $targetMapper; $sourceReflection = $targetReflection; $sourceEntityMeta = $targetEntityMetadata; } $sourceEntityMeta->getProperty($column); // check if property exists if ($column === 'id' && count($sourceEntityMeta->getPrimaryKey()) > 1) { $pair = []; foreach ($sourceEntityMeta->getPrimaryKey() as $column) { $column = $sourceReflection->convertEntityToStorageKey($column); $pair[] = "{$sourceAlias}.{$column}"; } if (!isset($value[0][0])) { $value = [$value]; } return '(' . implode(', ', $pair) . ')'; } else { $column = $sourceReflection->convertEntityToStorageKey($column); return "{$sourceAlias}.{$column}"; } }
/** * @param IEntity $entity * @param PropertyMetadata[] $metadata * @parma IModel $model * @param array $pre */ private static function setNulls($entity, array $metadata, IModel $model, array &$pre) { foreach ($metadata as $propertyMeta) { $type = $propertyMeta->relationship->type; $name = $propertyMeta->name; $reverseRepository = $model->getRepository($propertyMeta->relationship->repository); $reverseProperty = $propertyMeta->relationship->property ? $reverseRepository->getEntityMetadata()->getProperty($propertyMeta->relationship->property) : null; if ($type === Relationship::MANY_HAS_MANY) { /** @var ManyHasMany $property */ $property = $entity->getProperty($name); $pre[] = $property; if ($reverseProperty !== null) { foreach ($property as $reverseEntity) { $pre[] = $reverseEntity->getProperty($reverseProperty->name); } } $entity->setValue($name, []); } elseif ($type === Relationship::MANY_HAS_ONE || $type === Relationship::ONE_HAS_ONE && $propertyMeta->relationship->isMain) { /** @var ManyHasOne|OneHasOne $property */ $property = $entity->getProperty($name); if ($reverseProperty !== null && $entity->hasValue($name)) { $pre[] = $entity->getValue($name)->getProperty($reverseProperty->name); } $property->set(null, true); } else { // $type === Relationship::ONE_HAS_MANY or // $type === Relationship::ONE_HAS_ONE && !$isMain if (!$entity->hasValue($name) || $reverseProperty === null) { continue; } if ($reverseProperty->isNullable) { if ($type === Relationship::ONE_HAS_MANY) { foreach ($entity->getValue($name) as $subValue) { $pre[] = $subValue; } $entity->setValue($name, []); } else { $pre[] = $entity->getValue($name); $entity->getProperty($name)->set(null, true); } } else { if ($type === Relationship::ONE_HAS_MANY && $entity->getValue($name)->count() === 0) { continue; } $entityClass = get_class($entity); $reverseEntityClass = $propertyMeta->relationship->entity; $primaryValue = $entity->getValue('id'); $primaryValue = is_array($primaryValue) ? '[' . implode(', ', $primaryValue) . ']' : $primaryValue; throw new InvalidStateException("Cannot remove {$entityClass}::\$id={$primaryValue} because {$reverseEntityClass}::\${$reverseProperty->name} cannot be a null."); } } } }
/** * @param IEntity $entity * @param PropertyMetadata[] $metadata * @parma IModel $model * @param array $pre */ private static function setNulls($entity, array $metadata, IModel $model, array &$pre) { foreach ($metadata as $propertyMeta) { $type = $propertyMeta->relationship->type; $name = $propertyMeta->name; if ($type === Relationship::MANY_HAS_MANY) { $entity->setValue($name, []); } elseif ($type === Relationship::MANY_HAS_ONE || $type === Relationship::ONE_HAS_ONE && $propertyMeta->relationship->isMain) { $entity->getProperty($name)->set(NULL, TRUE); } else { // $type === Relationship::ONE_HAS_MANY or // $type === Relationship::ONE_HAS_ONE && !$isPrimary $reverseRepository = $model->getRepository($propertyMeta->relationship->repository); $reverseProperty = $reverseRepository->getEntityMetadata()->getProperty($propertyMeta->relationship->property); if ($reverseProperty->isNullable) { if ($entity->hasValue($name)) { if ($type === Relationship::ONE_HAS_MANY) { foreach ($entity->getValue($name) as $subValue) { $pre[] = $subValue; } $entity->getValue($name)->set([]); } else { $pre[] = $entity->getValue($name); $entity->setValue($name, NULL); } } } else { $entityClass = get_class($entity); $reverseEntityClass = $propertyMeta->relationship->entity; $primaryValue = $entity->getValue('id'); $primaryValue = is_array($primaryValue) ? '[' . implode(', ', $primaryValue) . ']' : $primaryValue; throw new InvalidStateException("Cannot remove {$entityClass}::\$id={$primaryValue} because {$reverseEntityClass}::\${$reverseProperty->name} cannot be a null."); } } } }