예제 #1
0
 /**
  * Copy a singe object based on field annotations about how to copy the object
  *
  * @param Tx_Extbase_DomainObject_DomainObjectInterface $object The object to be copied
  * @return Tx_Extbase_DomainObject_DomainObjectInterface $copy
  * @api
  */
 public function copy($object)
 {
     $className = get_class($object);
     $this->recursionService->in();
     $this->recursionService->check($className);
     $copy = $this->objectManager->get($className);
     $properties = $this->reflectionService->getClassPropertyNames($className);
     foreach ($properties as $propertyName) {
         $tags = $this->reflectionService->getPropertyTagsValues($className, $propertyName);
         $getter = 'get' . ucfirst($propertyName);
         $setter = 'set' . ucfirst($propertyName);
         $copyMethod = $tags['copy'][0];
         $copiedValue = NULL;
         if ($copyMethod !== NULL && $copyMethod !== 'ignore') {
             $originalValue = $object->{$getter}();
             if ($copyMethod == 'reference') {
                 $copiedValue = $this->copyAsReference($originalValue);
             } elseif ($copyMethod == 'clone') {
                 $copiedValue = $this->copyAsClone($originalValue);
             }
             if ($copiedValue != NULL) {
                 $copy->{$setter}($copiedValue);
             }
         }
     }
     $this->recursionService->out();
     return $copy;
 }
예제 #2
0
 /**
  * Returns an array of property names and values by searching the $object
  * for annotations based on $annotation and $value. If $annotation is provided
  * but $value is not, All properties which simply have the annotation present.
  * Relational values which have the annotation are parsed through the same
  * function - sub-elements' properties are exported based on the same
  * annotation and value
  *
  * @param mixed $object The object or classname to read
  * @param string $annotation The annotation on which to base output
  * @param string|boolean $value The value to search for; multiple values may be used in the annotation; $value must be present among them. If TRUE, all properties which have the annotation are returned
  * @param boolean $addUid If TRUE, the UID of the DomainObject will be force-added to the output regardless of annotation
  * @return array
  * @api
  */
 public function getValuesByAnnotation($object, $annotation = 'json', $value = TRUE, $addUid = TRUE)
 {
     if (is_array($object)) {
         $array = array();
         foreach ($object as $k => $v) {
             $array[$k] = $this->getValuesByAnnotation($v, $annotation, $value, $addUid);
         }
         return $array;
     }
     if (is_object($object)) {
         $className = get_class($object);
     } else {
         $className = $object;
         $object = $this->objectManager->get($className);
     }
     $this->recursionService->in();
     $this->recursionService->check($className);
     $properties = $this->reflectionService->getClassPropertyNames($className);
     $return = array();
     if ($addUid === TRUE) {
         $return['uid'] = $object->getUid();
     }
     foreach ($properties as $propertyName) {
         $getter = 'get' . ucfirst($propertyName);
         if (method_exists($object, $getter) === FALSE) {
             continue;
         }
         if ($this->hasAnnotation($className, $propertyName, $annotation, $value)) {
             $returnValue = $object->{$getter}();
             if ($returnValue instanceof Tx_Extbase_Persistence_ObjectStorage) {
                 $array = $returnValue->toArray();
                 foreach ($array as $k => $v) {
                     $array[$k] = $this->getValuesByAnnotation($v, $annotation, $value, $addUid);
                 }
                 $returnValue = $array;
             } elseif ($returnValue instanceof Tx_Extbase_DomainObject_DomainObjectInterface) {
                 $returnValue = $this->getValuesByAnnotation($returnValue, $annotation, $value, $addUid);
             } elseif ($returnValue instanceof DateTime) {
                 $returnValue = $returnValue->format('r');
             }
             $return[$propertyName] = $returnValue;
         }
     }
     $this->recursionService->out();
     return $return;
 }
예제 #3
0
 /**
  * Builds a base validator conjunction for the given data type.
  *
  * The base validation rules are those which were declared directly in a class (typically
  * a model) through some @validate annotations on properties.
  *
  * Additionally, if a custom validator was defined for the class in question, it will be added
  * to the end of the conjunction. A custom validator is found if it follows the naming convention
  * "Replace '\Model\' by '\Validator\' and append "Validator".
  *
  * Example: $dataType is F3\Foo\Domain\Model\Quux, then the Validator will be found if it has the
  * name F3\Foo\Domain\Validator\QuuxValidator
  *
  * @param string $dataType The data type to build the validation conjunction for. Needs to be the fully qualified object name.
  * @return Tx_Extbase_Validation_Validator_ConjunctionValidator The validator conjunction or NULL
  */
 protected function buildBaseValidatorConjunction($dataType)
 {
     $validatorConjunction = $this->objectManager->get('Tx_Extbase_Validation_Validator_ConjunctionValidator');
     // Model based validator
     if (strstr($dataType, '_') !== FALSE && class_exists($dataType)) {
         $validatorCount = 0;
         $objectValidator = $this->createValidator('GenericObject');
         foreach ($this->reflectionService->getClassPropertyNames($dataType) as $classPropertyName) {
             $classPropertyTagsValues = $this->reflectionService->getPropertyTagsValues($dataType, $classPropertyName);
             if (!isset($classPropertyTagsValues['validate'])) {
                 continue;
             }
             foreach ($classPropertyTagsValues['validate'] as $validateValue) {
                 $parsedAnnotation = $this->parseValidatorAnnotation($validateValue);
                 foreach ($parsedAnnotation['validators'] as $validatorConfiguration) {
                     $newValidator = $this->createValidator($validatorConfiguration['validatorName'], $validatorConfiguration['validatorOptions']);
                     if ($newValidator === NULL) {
                         throw new Tx_Extbase_Validation_Exception_NoSuchValidator('Invalid validate annotation in ' . $dataType . '::' . $classPropertyName . ': Could not resolve class name for  validator "' . $validatorConfiguration['validatorName'] . '".', 1241098027);
                     }
                     $objectValidator->addPropertyValidator($classPropertyName, $newValidator);
                     $validatorCount++;
                 }
             }
         }
         if ($validatorCount > 0) {
             $validatorConjunction->addValidator($objectValidator);
         }
     }
     // Custom validator for the class
     $possibleValidatorClassName = str_replace('_Model_', '_Validator_', $dataType) . 'Validator';
     $customValidator = $this->createValidator($possibleValidatorClassName);
     if ($customValidator !== NULL) {
         $validatorConjunction->addValidator($customValidator);
     }
     return $validatorConjunction;
 }
예제 #4
0
 /**
  * Does $propertyName on $instance contain a data type which supports deflation?
  *
  * @param object $instance Instance of an object, DomainObject included
  * @param string $propertyName String name of property on DomainObject instance which is up for assertion
  * @return boolean
  * @throws RuntimeException
  */
 protected function assertSupportsDeflation($instance, $propertyName)
 {
     $className = get_class($instance);
     $gettableProperties = $this->reflectionService->getClassPropertyNames($className);
     if (FALSE === in_array($propertyName, $gettableProperties)) {
         return FALSE;
     }
     try {
         $value = Tx_Extbase_Reflection_ObjectAccess::getProperty($instance, $propertyName, TRUE);
     } catch (RuneimeException $error) {
         $getter = 'get' . ucfirst($propertyName);
         if (FALSE === method_exists($instance, $getter)) {
             return FALSE;
         }
         t3lib_div::sysLog('MarshallService encountered an error while attempting to retrieve the value of ' . $className . '::$' . $propertyName . ' - assuming safe deflation is possible', 'site', t3lib_div::SYSLOG_SEVERITY_NOTICE);
         return TRUE;
     }
     return FALSE === $value instanceof Closure;
 }