Guest User

AbstractPersistentInheritedObjectConverter.php

a guest
Jul 24th, 2013
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.85 KB | None | 0 0
  1. <?php
  2. /**
  3.  * This file belongs to the HdM.Accounting project.
  4.  * Created By: mathis
  5.  * Creation date: 27.06.13
  6.  * Creation time: 13:01
  7.  */
  8.  
  9. namespace HdM\Accounting\TypeConverter;
  10.  
  11.  
  12. use TYPO3\Flow\Configuration\ConfigurationManager;
  13. use TYPO3\Flow\Mvc\Exception\RequiredArgumentMissingException;
  14. use TYPO3\Flow\Property\Exception\InvalidTargetException;
  15. use TYPO3\Flow\Property\PropertyMappingConfigurationInterface;
  16. use TYPO3\Flow\Property\TypeConverter\ObjectConverter;
  17. use TYPO3\Flow\Annotations as Flow;
  18. use TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter;
  19.  
  20. /**
  21.  * Class AbstractPersistentInheritedObjectConverter
  22.  * @package HdM\Accounting\TypeConverter
  23.  * @todo Use object-configuration to configure target-type, type-identifier and concrete-sub-classes
  24.  */
  25. abstract class AbstractPersistentInheritedObjectConverter extends PersistentObjectConverter {
  26.  
  27.     const DEFAULT_TYPE_IDENTIFIER = 'type';
  28.  
  29.     /**
  30.      * override priority
  31.      * @var integer
  32.      */
  33.     protected $priority = 100;
  34.  
  35.     /**
  36.      * needs to be configured in concrete sub class
  37.      * @var string
  38.      */
  39.     protected $targetType = 'object';
  40.  
  41.     /**
  42.      * needs to be configured in concrete sub class
  43.      * @var array
  44.      */
  45.     protected $concreteSubClasses;
  46.  
  47.     /**
  48.      * can be overwritten in concrete sub classes
  49.      * @var string
  50.      */
  51.     protected $typeIdentifier = AbstractPersistentInheritedObjectConverter::DEFAULT_TYPE_IDENTIFIER;
  52.  
  53.     /**
  54.      * needs to be configured in concrete sub class
  55.      * @var string
  56.      */
  57.     protected  $abstractClass;
  58.  
  59.     /**
  60.      * Returns all properties of the given class that have a setter method
  61.      *
  62.      * @param string $className
  63.      * @return array
  64.      */
  65.     protected function getAccessibleProperties($className) {
  66.         $result = array();
  67.         $properties = $this->reflectionService->getClassPropertyNames($className);
  68.         foreach ($properties as $property) {
  69.             if ($this->reflectionService->hasMethod($className, 'set'.ucfirst($property)))
  70.                 $result[] = $property;
  71.         }
  72.         return $result;
  73.     }
  74.  
  75.     /**
  76.      * We can only convert if target is a persisted object and matches the configured type and is not persisted yet
  77.      *
  78.      * @param mixed $source
  79.      * @param string $targetType
  80.      * @return boolean
  81.      */
  82.     public function canConvertFrom($source, $targetType) {
  83.         return (($targetType === $this->targetType));
  84.     }
  85.  
  86.     /**
  87.      * The type of a property is determined by the reflection service.
  88.      *
  89.      * @param string $targetType
  90.      * @param string $propertyName
  91.      * @param PropertyMappingConfigurationInterface $configuration
  92.      * @return string
  93.      * @throws \TYPO3\Flow\Property\Exception\InvalidTargetException
  94.      */
  95.     public function getTypeOfChildProperty($targetType, $propertyName, PropertyMappingConfigurationInterface $configuration) {
  96.  
  97.         // type idenfifier is always string
  98.         if ($propertyName === $this->typeIdentifier)
  99.             return 'string';
  100.  
  101.         // otherwise detect type
  102.         $propertyType = null;
  103.         foreach ($this->concreteSubClasses as $concreteSubClass) {
  104.             try {
  105.                 $propertyType = parent::getTypeOfChildProperty($concreteSubClass, $propertyName, $configuration);
  106.             }
  107.             catch (InvalidTargetException $e) {
  108.             }
  109.         }
  110.         if ($propertyType === null)
  111.             throw new InvalidTargetException('The property '.$propertyName.' does not exist in any of the concrete implementations.');
  112.         return $propertyType;
  113.     }
  114.  
  115.     /**
  116.      * Convert an object from $source to an entity or a value object.
  117.      *
  118.      * @param mixed $source
  119.      * @param string $targetType
  120.      * @param array $convertedChildProperties
  121.      * @param PropertyMappingConfigurationInterface $configuration
  122.      * @return object
  123.      * @throws RequiredArgumentMissingException
  124.      */
  125.     public function convertFrom($source, $targetType, array $convertedChildProperties = array(), PropertyMappingConfigurationInterface $configuration = NULL) {
  126.         // determine our target-type and invoke to parent
  127.         if (isset($source[$this->typeIdentifier])) {
  128.             if (isset($this->concreteSubClasses[$source[$this->typeIdentifier]])) {
  129.                 $targetType = $this->concreteSubClasses[$source[$this->typeIdentifier]];
  130.                 unset($source[$this->typeIdentifier]);
  131.                 unset($convertedChildProperties[$this->typeIdentifier]);
  132.             }
  133.             else
  134.                 $targetType = $this->abstractClass;
  135.         }
  136.         else
  137.             $targetType = $this->abstractClass;
  138.  
  139.         /** remove property if it does not exist in targetType
  140.          * @todo remove only if property exists in at least one of the concrete sub classes to provide a suitable exception otherwise
  141.          */
  142.         $allowedProperties = $this->getAccessibleProperties($targetType);
  143.         foreach($source as $property => $value) {
  144.             if (!in_array($property, $allowedProperties))
  145.                 unset ($source[$property]);
  146.         }
  147.         foreach($convertedChildProperties as $property => $value) {
  148.             if (!in_array($property, $allowedProperties))
  149.                 unset ($convertedChildProperties[$property]);
  150.         }
  151.  
  152.         return parent::convertFrom($source,$targetType,$convertedChildProperties,$configuration);
  153.     }
  154.  
  155. }
Advertisement
Add Comment
Please, Sign In to add comment