More support for Model/Datasource date formatters #679

Closed
wants to merge 2 commits into from

3 participants

@milesj

This allows date formatter functions to be called during the deconstruct() process and not just the save() process. This is helpful for systems that need custom date objects/strings, like MongoDB.

Example when setting the formatter to 'MongoDbDateFormatter' within the datasource.

function MongoDbDateFormatter($format, $time = null) {
    if (is_string($time)) {
        $time = strtotime($time);
    } else if (!$time) {
        $time = time();
    }

    return new MongoDate($time);
}

This is primarily to support non-created/modified datetime fields.

@milesj milesj Add more advanced support for Model/Datasource date formatters
This allows date formatter functions to be called during the
deconstruct() process and not just the save() process. This is helpful
for systems that need custom date objects/strings, like MongoDB.
d35689f
@markstory markstory and 1 other commented on an outdated diff May 30, 2012
lib/Cake/Test/Case/Model/ModelIntegrationTest.php
@@ -2424,3 +2460,18 @@ public function testSchemaNoDB() {
$this->assertEmpty($model->schema());
}
}
+
+/**
+ * Global function used for datetime formatting during Model::deconstruct() and defined in the Datasource.
+ *
+ * @param string $format
+ * @param int $time
+ * @return int
+ */
+function dateFormatter($format, $time) {
@markstory
CakePHP member

Why not make this a method on the test case? Seems like this will eventually cause a problem as a global function.

@milesj
milesj added a note May 30, 2012

Yeah can do that. Was unsure where to place it as I also saw CakeTestSuiteDispatcher::date().

@markstory
CakePHP member

I would just make it a public method on the ModelIntegrationTest class.

@milesj
milesj added a note May 31, 2012

Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@markstory markstory commented on the diff May 31, 2012
lib/Cake/Model/Model.php
foreach (array('m', 'd', 'H', 'i', 's') as $index) {
if (isset($date[$index])) {
$date[$index] = sprintf('%02d', $date[$index]);
}
}
- return str_replace(array_keys($date), array_values($date), $format);
+
+ $result = str_replace(array_keys($date), array_values($date), $format);
+
+ // Don't trigger on date()
+ if (!empty($columnTypes['formatter']) && $columnTypes['formatter'] !== 'date') {
@markstory
CakePHP member

So you can custom format any column type except date?

@milesj
milesj added a note May 31, 2012

The formatter function cannot be date(). There was a reason for this but totally can't remember at this time. I will test tomorrow and see if I can remember why.

@milesj
milesj added a note May 31, 2012

So I remember why I disallowed date(). Basically date() would blow up if the 2nd argument passed was a string, it requires an integer unix timestamp. The only solution I can think of is casting $result with strtotime(), but that doesn't seem necessary since the "format" option can be used in the datasource.

@markstory
CakePHP member

Wouldn't things be more consistent if the input type was always a timestamp instead of a formatted date string? There are probably some tricks in dealing with timezones, as currently the datetime string has no timezone information. It seems like a workaround to skip the date() formatter. Perhaps the existing deconstruct() logic needs to be reworked though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@milesj milesj referenced this pull request Nov 22, 2012
Closed

Add URL to exception logs #970

@zoghal

If it is possible to implement this feature is so excellent be able to use other calendars. (Arabic and Jalali calendar).
My suggestion is to define an event for this Actions. ("Model. DbDateFormatter").

@markstory markstory closed this Feb 2, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment