[TYPO3-mvc] Approach to solve problems with non mandatory DateTime properties

Kevin Ulrich Moschallski km at 3digit.de
Thu Feb 23 10:08:56 CET 2012


Hi list,

i yesterday got a problem with one of my models which has two 
DateTimeProperties which are booth not mandatory. As you may know you 
can't set a DateTime object to an undefined time, as it's constructed 
whether with the given time (+format) or without this option with the 
current local time.

This problem was already discussed in this thread:

http://lists.typo3.org/pipermail/typo3-project-typo3v4mvc/2011-April/009207.html 


The result of this thread was the suggestion to set the properties to 
string and not DateTime and use a custom validator.

The whole problem seems more to be PHP related than an extbase problem. 
One solution maybe would be to extend the DateTime class with a custom 
class which allows to set an undefined time which then results in NULL 
when any method is called on the object. But this would be a huge 
affort and maybe a breaking change.

So i looked at the reflection objectaccess and wrote a solution which i 
hope you will have a look on it. The concept is to use the property 
refelection to see if the param of the setter method on the object is 
of type DateTime. If so the value to be set is validated for DateTime. 
If the value is an instance of DateTime it will be set otherwise it 
will be obmitted. Before doing this i changed the DateTime converter to 
not throw an exception if the value couldn't be converted to DateTime 
it will now return NULL.

Enough of introduction, i think the code is quite clear for you all:

diff --git a/Classes/Property/TypeConverter/DateTimeConverter.php 
b/Classes/Property/TypeConverter/DateTimeConverter.php
index d0cba49..aba375e 100644
--- a/Classes/Property/TypeConverter/DateTimeConverter.php
+++ b/Classes/Property/TypeConverter/DateTimeConverter.php
@@ -122,7 +122,8 @@ class 
Tx_Extbase_Property_TypeConverter_DateTimeConverter extends 
Tx_Extbase_Pro
                }
                $date = DateTime::createFromFormat($dateFormat, $dateAsString);
                if ($date === FALSE || $dateAsString === '') {
-                       throw new 
Tx_Extbase_Property_Exception_TypeConverterException('The string"' . 
$dateAsString . '" could not be
+//                     throw new 
Tx_Extbase_Property_Exception_TypeConverterException('The string"' . 
$dateAsString . '" could not be
+                       return NULL;
                }
                if (is_array($source)) {
                        $this->overrideTimeIfSpecified($date, $source);
diff --git a/Classes/Reflection/ObjectAccess.php 
b/Classes/Reflection/ObjectAccess.php
index 6f380b9..4af7097 100644
--- a/Classes/Reflection/ObjectAccess.php
+++ b/Classes/Reflection/ObjectAccess.php
@@ -181,13 +181,26 @@ class Tx_Extbase_Reflection_ObjectAccess {
                if ($forceDirectAccess === TRUE) {
                        if (property_exists(get_class($subject), 
$propertyName)) {
                                $propertyReflection = new 
Tx_Extbase_Reflection_PropertyReflection(get_class($subject), 
$propertyName);
-                               $propertyReflection->setAccessible(TRUE);
-                               $propertyReflection->setValue($subject, 
$propertyValue);
+                               $propertyTags = 
$propertyReflection->getTagsValues();
+                               if(in_array('DateTime', 
$propertyTags['var']) && !($propertyValue instanceof  DateTime)) {
+                                       return TRUE;
+                               }
+                               else {
+                                       
$propertyReflection->setAccessible(TRUE);
+                                       
$propertyReflection->setValue($subject, $propertyValue);
+                               }
                        } else {
                                $subject->$propertyName = $propertyValue;
                        }
                } elseif (is_callable(array($subject, $setterMethodName 
= self::buildSetterMethodName($propertyName)))) {
-                       $subject->$setterMethodName($propertyValue);
+                       $propertyReflection = new 
Tx_Extbase_Reflection_PropertyReflection(get_class($subject), 
$propertyName);
+                       $propertyTags = $propertyReflection->getTagsValues();
+                       if(in_array('DateTime', $propertyTags['var']) 
&& !($propertyValue instanceof  DateTime)) {
+                               return TRUE;
+                       }
+                       else {
+                               $subject->$setterMethodName($propertyValue);
+                       }
                } elseif ($subject instanceof ArrayAccess) {
                        $subject[$propertyName] = $propertyValue;
                } elseif (array_key_exists($propertyName, 
get_object_vars($subject))) {

I will open an issue for that if you tell me that i'm not absolutly 
wrong with my approach.

Regards,
Kevin



More information about the TYPO3-project-typo3v4mvc mailing list