/**
  * @param object $entity Entity
  *
  * @throws \Darvin\Utils\DefaultValue\DefaultValueException
  */
 protected function setDefaultValues($entity)
 {
     $entityClass = ClassUtils::getClass($entity);
     $meta = $this->extendedMetadataFactory->getExtendedMetadata($entityClass);
     if (!isset($meta['defaultValues']) || empty($meta['defaultValues'])) {
         return;
     }
     $defaultValuesMap = $meta['defaultValues'];
     $this->filterDefaultValuesMap($defaultValuesMap, $entity, $entityClass);
     if (empty($defaultValuesMap)) {
         return;
     }
     $sourcePropertyValues = $this->getSourcePropertyValues(array_unique(array_values($defaultValuesMap)), $entity, $entityClass);
     $recomputeChangeSet = false;
     foreach ($defaultValuesMap as $targetProperty => $sourcePropertyPath) {
         if (null === $sourcePropertyValues[$sourcePropertyPath]) {
             continue;
         }
         if (!$this->propertyAccessor->isWritable($entity, $targetProperty)) {
             throw new DefaultValueException(sprintf('Property "%s::$%s" is not writable.', $entityClass, $targetProperty));
         }
         $this->propertyAccessor->setValue($entity, $targetProperty, $sourcePropertyValues[$sourcePropertyPath]);
         $recomputeChangeSet = true;
     }
     if ($recomputeChangeSet) {
         $this->recomputeChangeSet($entity);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function apply(Request $request, ParamConverter $configuration) : bool
 {
     $class = $configuration->getClass();
     $constant = sprintf('%s::EMPTY_PROPERTIES', $class);
     $propertiesToBeSkipped = [];
     $instance = new $class();
     $declaredProperties = array_filter((new \ReflectionClass($class))->getProperties(), function (ReflectionProperty $property) use($class) {
         return $property->getDeclaringClass()->name === $class;
     });
     // fetch result properties that are optional and to be skipped as those must not be processed
     if (defined($constant)) {
         $propertiesToBeSkipped = constant($constant);
     }
     /** @var ReflectionProperty $property */
     foreach ($declaredProperties as $property) {
         $propertyName = $property->getName();
         if (in_array($propertyName, $propertiesToBeSkipped, true)) {
             continue;
         }
         // non-writable properties cause issues with the DTO creation
         if (!$this->propertyAccess->isWritable($instance, $propertyName)) {
             throw new \RuntimeException($this->getInvalidPropertyExceptionMessage($class, $propertyName));
         }
         $this->propertyAccess->setValue($instance, $propertyName, $this->findAttributeInRequest($request, $property, $this->propertyAccess->getValue($instance, $propertyName)));
     }
     $request->attributes->set($configuration->getName(), $instance);
     return true;
 }
 /**
  * {@inheritdoc}
  */
 public function apply(Request $request, ParamConverter $configuration)
 {
     $instance = $this->getDTOInstance($configuration->getClass());
     foreach ($this->getDTOParametersByClass($configuration->getClass()) as $property) {
         $propertyName = $property->getName();
         if (!$this->propertyAccess->isWritable($instance, $propertyName)) {
             throw new \RuntimeException($this->getInvalidPropertyExceptionMessage($configuration->getClass(), $propertyName));
         }
         $this->propertyAccess->setValue($instance, $propertyName, $this->findAttributeInRequest($request, $property));
     }
     $request->attributes->set($configuration->getName(), $instance);
     return true;
 }
 /**
  * @param object $entity       Entity
  * @param string $propertyPath Property path
  * @param mixed  $value        Value
  *
  * @throws \Darvin\Utils\CustomObject\CustomObjectException
  */
 private function setPropertyValue($entity, $propertyPath, $value)
 {
     if (!$this->propertyAccessor->isWritable($entity, $propertyPath)) {
         throw new CustomObjectException(sprintf('Property "%s::$%s" is not writable.', ClassUtils::getClass($entity), $propertyPath));
     }
     $this->propertyAccessor->setValue($entity, $propertyPath, $value);
 }
Exemple #5
0
 /**
  * @param object $object Object to clone
  *
  * @return object
  * @throws \Darvin\Utils\Cloner\ClonerException
  */
 private function cloneObject($object)
 {
     $objectHash = spl_object_hash($object);
     if (isset($this->clonedObjects[$objectHash])) {
         return $this->clonedObjects[$objectHash];
     }
     $class = ClassUtils::getClass($object);
     if (false === strpos($class, '\\')) {
         $clone = clone $object;
         $this->clonedObjects[$objectHash] = $clone;
         return $clone;
     }
     $meta = $this->extendedMetadataFactory->getExtendedMetadata($class);
     if (!isset($meta['clonable'])) {
         $message = sprintf('Class "%s" must be annotated with "%s" annotation in order to create clone of it\'s instance.', $class, Clonable::ANNOTATION);
         throw new ClonerException($message);
     }
     $clone = new $class();
     $this->clonedObjects[$objectHash] = $clone;
     foreach ($meta['clonable']['properties'] as $property) {
         if (!$this->propertyAccessor->isReadable($object, $property)) {
             throw new ClonerException(sprintf('Property "%s::$%s" is not readable.', $class, $property));
         }
         if (!$this->propertyAccessor->isWritable($clone, $property)) {
             throw new ClonerException(sprintf('Property "%s::$%s" is not writable.', $class, $property));
         }
         $value = $this->propertyAccessor->getValue($object, $property);
         $valueCopy = $this->copyValue($value);
         $this->propertyAccessor->setValue($clone, $property, $valueCopy);
     }
     $this->eventDispatcher->dispatch(Events::POST_CLONE, new CloneEvent($object, $clone));
     return $clone;
 }
 /**
  * {@inheritdoc}
  */
 public function getResult(ClassMetadata $classMetadata, array $options = [])
 {
     if (!isset($options['property'])) {
         throw new \InvalidArgumentException('The property option was not specified.');
     }
     $instance = $classMetadata->newInstance();
     if (!$this->propertyAccessor->isWritable($instance, $options['property']) || !$this->propertyAccessor->isReadable($instance, $options['property'])) {
         return false;
     }
     if (isset($options['create'])) {
         $create = $options['create'];
         unset($options['create']);
     } else {
         $create = true;
     }
     if ($annotation = $this->annotationQuery->getResult($classMetadata, array_merge($options, ['annotationClass' => 'Sentient\\Data\\Metadata\\Annotation\\LockedProperty']))) {
         if ($create ? $annotation->onCreate : $annotation->onUpdate) {
             return false;
         }
     }
     if ($annotation = $this->annotationQuery->getResult($classMetadata, array_merge($options, ['annotationClass' => 'Sentient\\Data\\Metadata\\Annotation\\CrudProperty']))) {
         if ($annotation->editable === CrudProperty::EDITABLE_ALWAYS) {
             return true;
         }
         if ($annotation->editable === CrudProperty::EDITABLE_NEVER) {
             return false;
         }
         if ($annotation->editable === CrudProperty::EDITABLE_ON_CREATE) {
             return $create;
         }
         if ($annotation->editable === CrudProperty::EDITABLE_ON_UPDATE) {
             return !$create;
         }
         throw new \RuntimeException('The editable property has an invalid value.');
     }
     foreach ($this->bannedAnnotations as $annotationClass) {
         if ($this->annotationQuery->getResult($classMetadata, array_merge($options, compact('annotationClass')))) {
             return false;
         }
     }
     return true;
 }
 /**
  * @param object $entity Entity
  *
  * @throws \Darvin\Utils\Transliteratable\TransliteratableException
  */
 protected function transliterate($entity)
 {
     $entityClass = ClassUtils::getClass($entity);
     $meta = $this->extendedMetadataFactory->getExtendedMetadata($entityClass);
     if (!isset($meta['transliteratable']) || empty($meta['transliteratable'])) {
         return;
     }
     $changeSet = $this->uow->getEntityChangeSet($entity);
     $recomputeChangeSet = false;
     foreach ($meta['transliteratable'] as $property => $params) {
         if (!isset($changeSet[$property])) {
             continue;
         }
         if (!$this->propertyAccessor->isWritable($entity, $property)) {
             throw new TransliteratableException(sprintf('Property "%s::$%s" is not writable.', $entityClass, $property));
         }
         $transliterated = $this->transliterator->transliterate($changeSet[$property][1], $params['sanitize'], $params['allowedSymbols'], $params['separator']);
         $this->propertyAccessor->setValue($entity, $property, $transliterated);
         $recomputeChangeSet = true;
     }
     if ($recomputeChangeSet) {
         $this->recomputeChangeSet($entity);
     }
 }
Exemple #8
0
 /**
  * @inheritdoc
  */
 public function isWritable($objectOrArray, $propertyPath)
 {
     return $objectOrArray instanceof \stdClass ? true : $this->decoratedPropertyAccessor->isWritable($objectOrArray, $propertyPath);
 }