public function remove(IEntity $parent, array $remove) { $id = $parent->getValue('id'); $data =& $this->mapper->getRelationshipDataStorage($this->metadata->name); foreach ($remove as $removeId) { unset($data[$id][$removeId]); } }
protected function updateRelationshipRemove(IEntity $entity) { if (!$this->metadata->relationship->property) { return; } $this->updatingReverseRelationship = true; $entity->getProperty($this->metadata->relationship->property)->setInjectedValue(null); $this->updatingReverseRelationship = false; }
protected function attached($control) { parent::attached($control); $this->addComponent($this->createComponent($this->entity), 'this'); $this->addGroup('orm.form.action.group'); $action = $this->addContainer('action'); $action->addSubmit('add', 'orm.form.action.add.label')->setDisabled($this->entity->isPersisted()); $action->addSubmit('edit', 'orm.form.action.edit.label')->setDisabled(!$this->entity->isPersisted()); $action->addSubmit('delete', 'orm.form.action.delete.label')->setValidationScope(FALSE)->setDisabled(!$this->entity->isPersisted()); }
protected function updateRelationshipRemove(IEntity $entity) { if (!$this->metadata->relationship->property) { return; } $otherSide = $entity->getProperty($this->metadata->relationship->property); $otherSide->collection = null; $otherSide->toRemove[spl_object_hash($this->parent)] = $this->parent; $otherSide->modify(); }
protected function createComponentPagination() : Nette\Application\UI\Multiplier { return new Nette\Application\UI\Multiplier(function ($key) : Ytnuk\Orm\Pagination\Control { $control = new Ytnuk\Orm\Pagination\Control($this->entity->getValue($key), is_array(static::$itemsPerPage) ? static::$itemsPerPage[$key] ?? self::$itemsPerPage : static::$itemsPerPage); if ($this->storage) { $control->setCacheStorage($this->storage); } return $control; }); }
protected function execute(DbalCollection $collection, IEntity $parent) { $builder = $collection->getQueryBuilder(); $preloadIterator = $parent->getPreloadContainer(); $cacheKey = $this->calculateCacheKey($builder, $preloadIterator, $parent); $data =& $this->cacheEntityContainers[$cacheKey]; if ($data) { return $data; } $values = $preloadIterator ? $preloadIterator->getPreloadValues($this->metadata->name) : [$parent->getRawValue($this->metadata->name)]; $data = $this->fetch(clone $builder, stripos($cacheKey, 'JOIN') !== FALSE, $values, $preloadIterator); return $data; }
/** * @return IRepository */ protected function getTargetRepository() { if (!$this->targetRepository) { $this->targetRepository = $this->parent->getModel()->getRepository($this->metadata->relationship->repository); } return $this->targetRepository; }
protected function execute(ICollection $collection, IEntity $parent) { $collectionMapper = $collection->getCollectionMapper(); if (!$collectionMapper instanceof CollectionMapper) { throw new LogicException(); } $builder = $collectionMapper->getSqlBuilder(); $preloadIterator = $parent->getPreloadContainer(); $values = $preloadIterator ? $preloadIterator->getPreloadValues($this->metadata->name) : [$parent->getRawValue($this->metadata->name)]; $cacheKey = md5($builder->buildSelectQuery() . json_encode($values)); $data =& $this->cacheEntityContainers[$cacheKey]; if ($data) { return $data; } $data = $this->fetch(clone $builder, stripos($cacheKey, 'JOIN') !== FALSE, $values); return $data; }
/** * Converts IEntity to array * @param IEntity $entity * @param int $type * @param int $recursionLevel * @return array|null */ public static function toArray(IEntity $entity, $type = IEntity::TO_ARRAY_RELATIONSHIP_AS_IS, $recursionLevel = 0) { if ($recursionLevel >= static::$maxRecursionLevel) { return NULL; } $return = []; $metadata = $entity->getMetadata(); foreach ($metadata->getStorageProperties() as $name) { if ($name === 'id' && !$entity->isPersisted()) { $value = NULL; } elseif ($type !== IEntity::TO_ARRAY_LOADED_RELATIONSHIP_AS_IS) { $value = $entity->getValue($name); } else { $property = $entity->getProperty($name); if ($property instanceof IRelationshipContainer) { if (!$property->isLoaded()) { $value = $property->getPrimaryValue(); } else { $value = $entity->getValue($name); } } elseif ($property instanceof IRelationshipCollection) { if (!$property->isLoaded()) { continue; } else { $value = $entity->getValue($name); } } else { $value = $entity->getValue($name); } } if ($value instanceof IEntity) { if ($type === IEntity::TO_ARRAY_RELATIONSHIP_AS_ID) { $value = $value->id; } elseif ($type === IEntity::TO_ARRAY_RELATIONSHIP_AS_ARRAY) { $value = static::toArray($value, $type, $recursionLevel + 1); } } elseif ($value instanceof IRelationshipCollection) { if ($type === IEntity::TO_ARRAY_RELATIONSHIP_AS_ID) { $collection = []; foreach ($value as $collectionEntity) { $collection[] = $collectionEntity->id; } $value = $collection; } elseif ($type === IEntity::TO_ARRAY_RELATIONSHIP_AS_ARRAY) { $collection = []; foreach ($value as $collectionEntity) { $collection[] = static::toArray($collectionEntity, $type, $recursionLevel + 1); } $value = $collection; } } $return[$name] = $value; } return $return; }
protected function fill(IEntity $entity, array $params) { foreach ($entity->getMetadata()->getProperties() as $property) { if ($property->isReadonly) { continue; } $key = $property->name; if (array_key_exists($key, $params)) { $value = $params[$key]; unset($params[$key]); } elseif ($property->isNullable || $entity->hasValue($key)) { continue; } else { $value = $this->random($property); } $entity->{$key} = $value; } }
protected function createComponentForm() : Ytnuk\Orm\Form { $form = $this->form->create($this->entity); $form->onSuccess[] = function (Ytnuk\Orm\Form $form) { $presenter = $this->getPresenter(); switch ($form->isSubmitted()) { case $form['action']['add']: $presenter->redirect('Presenter:edit', $this->entity->getPersistedId()); break; case $form['action']['edit']: $presenter->redirect('this#' . $this->getSnippetId()); break; case $form['action']['delete']: $presenter->redirect('Presenter:list'); break; } }; return $form; }
protected function createComponentTranslates(Nextras\Orm\Entity\Reflection\PropertyMetadata $metadata) : Nette\Forms\Container { $translates = $this->addContainer($metadata->name); $localeRepository = $this->model->getRepositoryForEntity(Ytnuk\Translation\Locale\Entity::class); self::$locales ?: (self::$locales = $localeRepository->findAll()->fetchPairs(current($localeRepository->getEntityMetadata()->getPrimaryKey()))); $collection = array_combine(array_map(function (Ytnuk\Translation\Translate\Entity $entity) { return $entity->getRawValue('locale'); }, $collection = iterator_to_array($this->entity->getValue($metadata->name))), $collection); array_walk(self::$locales, function (Ytnuk\Translation\Locale\Entity $locale) use($translates, $collection) { $translate = $collection[$locale->id] ?? new Ytnuk\Translation\Translate\Entity(); $translates->addComponent($component = $this->form->createComponent($translate), $locale->id); if ($component instanceof Nette\Forms\Container) { $component->setCurrentGroup($translates->getCurrentGroup()); $value = $component['value']; if ($value instanceof Nette\Forms\Controls\BaseControl) { $value->caption = NULL; $value->setRequired(FALSE); } unset($component['locale']); $component->addHidden('locale', $locale->id)->setOption('entity', $locale); } }); $parent = $this->lookup(parent::class, FALSE); if ($parent instanceof parent) { $translates->getCurrentGroup()->setOption('label', $parent->formatPropertyLabel($parent->getMetadata()->getProperty($this->getName()))); if (!$parent->getMetadata()->getProperty($this->name)->isNullable && ($containers = iterator_to_array($translates->getComponents(FALSE, Nette\Forms\Container::class)))) { foreach ($containers as $key => $container) { $value = $container['value'] ?? NULL; if ($value instanceof Nette\Forms\Controls\BaseControl) { foreach (array_diff_key($containers, array_flip([$key])) as $sibling) { $value = $value->addConditionOn($sibling['value'], ~Nette\Forms\Form::FILLED); } $value->setRequired(); } } } } return $translates; }
/** * Converts IEntity to array * @param IEntity $entity * @param int $type * @param int $recursionLevel * @return array|null */ public static function toArray(IEntity $entity, $type = IEntity::TO_ARRAY_RELATIONSHIP_AS_IS, $recursionLevel = 0) { if ($recursionLevel >= static::$maxRecursionLevel) { return null; } $return = []; $metadata = $entity->getMetadata(); foreach ($metadata->getProperties() as $name => $metadataProperty) { if (!$entity->hasValue($name)) { $value = null; } else { $value = $entity->getValue($name); } if ($value instanceof IEntity) { if ($type === IEntity::TO_ARRAY_RELATIONSHIP_AS_ID) { $value = $value->getValue('id'); } elseif ($type === IEntity::TO_ARRAY_RELATIONSHIP_AS_ARRAY) { $value = static::toArray($value, $type, $recursionLevel + 1); } } elseif ($value instanceof IRelationshipCollection) { if ($type === IEntity::TO_ARRAY_RELATIONSHIP_AS_ID) { $collection = []; foreach ($value as $collectionEntity) { $collection[] = $collectionEntity->getValue('id'); } $value = $collection; } elseif ($type === IEntity::TO_ARRAY_RELATIONSHIP_AS_ARRAY) { $collection = []; foreach ($value as $collectionEntity) { $collection[] = static::toArray($collectionEntity, $type, $recursionLevel + 1); } $value = $collection; } } $return[$name] = $value; } return $return; }
public function persist(IEntity $entity) { $this->initializeData(); if ($entity->isPersisted()) { $id = $entity->id; } else { $this->lock(); try { $data = $this->readData(); $id = $data ? max(array_keys($data)) + 1 : 1; $data[$id] = NULL; $this->saveData($data); } catch (\Exception $e) { // finally workaround } $this->unlock(); if (isset($e)) { throw $e; } } $this->data[$id] = $entity; return $id; }
protected function createEntity($value, $allowNull) { if ($value instanceof IEntity) { if ($model = $this->parent->getModel(false)) { $repo = $model->getRepository($this->metadata->relationship->repository); $repo->attach($value); } elseif ($model = $value->getModel(false)) { $repository = $model->getRepositoryForEntity($this->parent); $repository->attach($this->parent); } } elseif ($value === null) { if (!$this->metadata->isNullable && !$allowNull) { throw new NullValueException($this->parent, $this->metadata); } } elseif (is_scalar($value)) { $value = $this->getTargetRepository()->getById($value); } else { throw new InvalidArgumentException('Value is not a valid entity representation.'); } return $value; }
protected function createEntity($value, $forceNULL) { if ($value instanceof IEntity) { if ($model = $this->parent->getModel(FALSE)) { $repo = $model->getRepository($this->propertyMeta->relationshipRepository); $repo->attach($value); } elseif ($model = $value->getModel(FALSE)) { $repository = $model->getRepositoryForEntity($this->parent); $repository->attach($this->parent); } } elseif ($value === NULL) { if (!$this->propertyMeta->isNullable && !$forceNULL) { $class = get_class($this->parent); throw new InvalidArgumentException("Property {$class}::\${$this->propertyMeta->name} is not nullable."); } } elseif (is_scalar($value)) { $value = $this->getTargetRepository()->getById($value); } else { throw new InvalidArgumentException('Value is not a valid entity representation.'); } return $value; }
/** * Returns entity relationships as array, 0 => prePersist, 1 => postPersist * @param IEntity $entity * @return array */ public static function getLoadedRelationships(IEntity $entity) { $isPersisted = $entity->isPersisted(); $return = [[], []]; foreach ($entity->getMetadata()->getProperties() as $propertyMeta) { if ($propertyMeta->relationship === NULL) { continue; } $name = $propertyMeta->name; $rawValue = $entity->getRawProperty($name); if (!is_object($rawValue) && ($propertyMeta->isNullable || $isPersisted)) { continue; } $property = $entity->getProperty($name); if ($property instanceof IRelationshipContainer) { if (!$property->isLoaded() && $isPersisted) { continue; } $value = $entity->getValue($name); if ($value) { if ($propertyMeta->relationship->type === PropertyRelationshipMetadata::ONE_HAS_ONE_DIRECTED && !$propertyMeta->relationship->isMain) { $return[1][$name] = $value; } else { $return[0][$name] = $value; } } } elseif ($property instanceof IRelationshipCollection) { if (!$property->isLoaded() && $isPersisted) { continue; } $value = $entity->getValue($name); if ($value) { $return[1][$name] = $value; } } } return $return; }
protected function updateRelationshipRemove(IEntity $entity) { $otherSide = $entity->getProperty($this->metadata->relationship->property); $otherSide->collection = NULL; $otherSide->toRemove[spl_object_hash($this->parent)] = $this->parent; }
public function getIterator(IEntity $parent, ICollection $collection) { $key = $parent->getRawValue($this->metadata->name); return [$key ? $collection->getBy(['id' => $key]) : NULL]; }
public function add(IEntity $entity) { $this->entities[implode(',', (array) $entity->getPersistedId())] = $entity; }
protected function updateRelationshipRemove(IEntity $entity) { $this->updatingReverseRelationship = TRUE; $entity->getProperty($this->metadata->relationship->property)->setInjectedValue(NULL); $this->updatingReverseRelationship = FALSE; }
protected function entityToArray(IEntity $entity) { $return = []; $metadata = $entity->getMetadata(); foreach ($metadata->getProperties() as $name => $metadataProperty) { if ($metadataProperty->isVirtual) { continue; } elseif ($metadataProperty->isPrimary && ($entity->isPersisted() || !$entity->hasValue($name))) { continue; } elseif ($entity->isPersisted() && !$entity->isModified($name)) { continue; } if ($metadataProperty->relationship !== null) { $rel = $metadataProperty->relationship; $canSkip = $rel->type === Relationship::ONE_HAS_MANY || $rel->type === Relationship::MANY_HAS_MANY || $rel->type === Relationship::ONE_HAS_ONE && !$rel->isMain; if ($canSkip) { continue; } } $property = $entity->getProperty($name); if ($property instanceof IProperty) { $value = $property->getRawValue(); } else { $value = $entity->getValue($name); } $return[$name] = $value; } return $return; }
public function getIterator(IEntity $parent, ICollection $collection) { $data = $collection->findBy(["this->{$this->joinStorageKey}->id" => $parent->getValue('id')])->fetchAll(); return new EntityIterator($data); }
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; }
protected function updateRelationshipRemove(IEntity $entity) { $this->updatingReverseRelationship = TRUE; $entity->setValue($this->metadata->relationshipProperty, NULL); $this->updatingReverseRelationship = FALSE; }
protected function buildList(IEntity $parent, array $entries) { if (!$this->metadata->relationship->isMain) { throw new LogicException('ManyHasMany relationship has to be persited in the primary mapper.'); } $list = []; $primaryId = $parent->getValue('id'); foreach ($entries as $id) { $list[] = [$this->primaryKeyFrom => $primaryId, $this->primaryKeyTo => $id]; } return $list; }
protected function entityToArray(IEntity $entity) { $return = []; $metadata = $entity->getMetadata(); foreach ($metadata->getProperties() as $name => $metadataProperty) { if ($metadataProperty->isVirtual) { continue; } elseif ($metadataProperty->isPrimary && !$entity->hasValue($name)) { continue; } $property = $entity->getProperty($name); if ($property instanceof IRelationshipCollection) { continue; } if ($property instanceof IProperty) { $value = $property->getRawValue(); } else { $value = $entity->getValue($name); } $return[$name] = $value; } return $return; }
protected function calculateCacheKey(QueryBuilder $builder, IEntityPreloadContainer $preloadIterator = NULL, IEntity $parent) { return md5($builder->getQuerySQL() . json_encode($builder->getQueryParameters()) . ($preloadIterator ? $preloadIterator->getIdentification() : json_encode($parent->getValue('id')))); }
protected function fireEvent(IEntity $entity, $event) { if (!property_exists($this, $event)) { throw new InvalidArgumentException("Event '{$event}' is not defined."); } $entity->fireEvent($event); ObjectMixin::call($this, $event, [$entity]); }
protected function executeCounts(ICollection $collection, IEntity $parent) { $collectionMapper = $collection->getCollectionMapper(); if (!$collectionMapper instanceof CollectionMapper) { throw new LogicException(); } $builder = $collectionMapper->getSqlBuilder(); $preloadIterator = $parent->getPreloadContainer(); $values = $preloadIterator ? $preloadIterator->getPreloadValues('id') : [$parent->id]; $cacheKey = $this->calculateCacheKey($builder, $values); $data =& $this->cacheCounts[$cacheKey]; if ($data !== NULL) { return $data; } $data = $this->fetchCounts($builder, $values); return $data; }