Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /**
- * This file belongs to the HdM.Accounting project.
- * Created By: mathis
- * Creation date: 27.06.13
- * Creation time: 13:01
- */
- namespace HdM\Accounting\TypeConverter;
- use TYPO3\Flow\Configuration\ConfigurationManager;
- use TYPO3\Flow\Mvc\Exception\RequiredArgumentMissingException;
- use TYPO3\Flow\Property\Exception\InvalidTargetException;
- use TYPO3\Flow\Property\PropertyMappingConfigurationInterface;
- use TYPO3\Flow\Property\TypeConverter\ObjectConverter;
- use TYPO3\Flow\Annotations as Flow;
- use TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter;
- /**
- * Class AbstractPersistentInheritedObjectConverter
- * @package HdM\Accounting\TypeConverter
- * @todo Use object-configuration to configure target-type, type-identifier and concrete-sub-classes
- */
- abstract class AbstractPersistentInheritedObjectConverter extends PersistentObjectConverter {
- const DEFAULT_TYPE_IDENTIFIER = 'type';
- /**
- * override priority
- * @var integer
- */
- protected $priority = 100;
- /**
- * needs to be configured in concrete sub class
- * @var string
- */
- protected $targetType = 'object';
- /**
- * needs to be configured in concrete sub class
- * @var array
- */
- protected $concreteSubClasses;
- /**
- * can be overwritten in concrete sub classes
- * @var string
- */
- protected $typeIdentifier = AbstractPersistentInheritedObjectConverter::DEFAULT_TYPE_IDENTIFIER;
- /**
- * needs to be configured in concrete sub class
- * @var string
- */
- protected $abstractClass;
- /**
- * Returns all properties of the given class that have a setter method
- *
- * @param string $className
- * @return array
- */
- protected function getAccessibleProperties($className) {
- $result = array();
- $properties = $this->reflectionService->getClassPropertyNames($className);
- foreach ($properties as $property) {
- if ($this->reflectionService->hasMethod($className, 'set'.ucfirst($property)))
- $result[] = $property;
- }
- return $result;
- }
- /**
- * We can only convert if target is a persisted object and matches the configured type and is not persisted yet
- *
- * @param mixed $source
- * @param string $targetType
- * @return boolean
- */
- public function canConvertFrom($source, $targetType) {
- return (($targetType === $this->targetType));
- }
- /**
- * The type of a property is determined by the reflection service.
- *
- * @param string $targetType
- * @param string $propertyName
- * @param PropertyMappingConfigurationInterface $configuration
- * @return string
- * @throws \TYPO3\Flow\Property\Exception\InvalidTargetException
- */
- public function getTypeOfChildProperty($targetType, $propertyName, PropertyMappingConfigurationInterface $configuration) {
- // type idenfifier is always string
- if ($propertyName === $this->typeIdentifier)
- return 'string';
- // otherwise detect type
- $propertyType = null;
- foreach ($this->concreteSubClasses as $concreteSubClass) {
- try {
- $propertyType = parent::getTypeOfChildProperty($concreteSubClass, $propertyName, $configuration);
- }
- catch (InvalidTargetException $e) {
- }
- }
- if ($propertyType === null)
- throw new InvalidTargetException('The property '.$propertyName.' does not exist in any of the concrete implementations.');
- return $propertyType;
- }
- /**
- * Convert an object from $source to an entity or a value object.
- *
- * @param mixed $source
- * @param string $targetType
- * @param array $convertedChildProperties
- * @param PropertyMappingConfigurationInterface $configuration
- * @return object
- * @throws RequiredArgumentMissingException
- */
- public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = NULL) {
- // determine our target-type and invoke to parent
- if (isset($source[$this->typeIdentifier])) {
- if (isset($this->concreteSubClasses[$source[$this->typeIdentifier]])) {
- $targetType = $this->concreteSubClasses[$source[$this->typeIdentifier]];
- unset($source[$this->typeIdentifier]);
- unset($convertedChildProperties[$this->typeIdentifier]);
- }
- else
- $targetType = $this->abstractClass;
- }
- else
- $targetType = $this->abstractClass;
- /** remove property if it does not exist in targetType
- * @todo remove only if property exists in at least one of the concrete sub classes to provide a suitable exception otherwise
- */
- $allowedProperties = $this->getAccessibleProperties($targetType);
- foreach($source as $property => $value) {
- if (!in_array($property, $allowedProperties))
- unset ($source[$property]);
- }
- foreach($convertedChildProperties as $property => $value) {
- if (!in_array($property, $allowedProperties))
- unset ($convertedChildProperties[$property]);
- }
- return parent::convertFrom($source,$targetType,$convertedChildProperties,$configuration);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment