Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: 1.2.3
-
Fix Version/s: None
-
Component/s: Timestampable
-
Labels:None
Description
The Timestampable Listener only sets the timestamp if the timestamp field has not been modified:
if ( ! isset($modified[$createdName])) { $event->getInvoker()->$createdName = $this->getTimestamp('created', $event->getInvoker()->getTable()->getConnection()); }
When saving a copy of a Doctrine_Record that doesn't already have the timestamp fields set fails to be updated, leading to integrity constraint violation ("created_at cannot be NULL"). The reason is that all unset fields in the copy are set to an instance of Doctrine_Null, which is considered to be modifed according to the condition tested for above. To fix the issue, I modified the code above to read:
if ( ! isset($modified[$createdName]) || $modified[$createdName] instanceof Doctrine_Null) { $event->getInvoker()->$createdName = $this->getTimestamp('created', $event->getInvoker()->getTable()->getConnection()); }
Activity
blopblop
made changes -
| Field | Original Value | New Value |
|---|---|---|
| Attachment | Timestampable.php [ 11318 ] |
This list may be incomplete, as errors occurred whilst retrieving source from linked applications:
- Request to http://www.doctrine-project.org/fisheye/ failed: Error in remote call to 'FishEye 0 (http://www.doctrine-project.org/fisheye/)' (http://www.doctrine-project.org/fisheye) [AbstractRestCommand{path='/rest-service-fe/search-v1/crossRepositoryQuery', params={query=DC-1051, expand=changesets[-21:-1].revisions[0:29],reviews}, methodType=GET}] : Received status code 503 (Service Temporarily Unavailable)
Your fix works great, I have also added the fix for the preupdate function and in one more place in the preinsert function.
Lines affected: 65, 73, 91.
Attached the file with the fixes:
( C:\php5\PEAR\symfony\plugins\sfDoctrinePlugin\lib\vendor\doctrine\Doctrine\Template\Listener\Timestampable.php )
[code]
/**
*
*/
public function preInsert(Doctrine_Event $event)
{
if ( ! $this->_options['created']['disabled'])
if ( ! $this->_options['updated']['disabled'] && $this->_options['updated']['onInsert']) {
{ $event->getInvoker()->$updatedName = $this->getTimestamp('updated', $event->getInvoker()->getTable()->getConnection()); }$updatedName = $event->getInvoker()
>getTable()>getFieldName($this->_options['updated']['name']);$modified = $event->getInvoker()->getModified();
if ( ! isset($modified[$updatedName]) || $modified[$updatedName] instanceof Doctrine_Null)
}
}
/**
* Set updated Timestampable column when a record is updated
*
* @param Doctrine_Event $evet
* @return void
*/
public function preUpdate(Doctrine_Event $event)
{
if ( ! $this->_options['updated']['disabled']) {
$updatedName = $event->getInvoker()
>getTable()>getFieldName($this->_options['updated']['name']);//echo "updatedName: "; var_dump(updatedName);
$modified = $event->getInvoker()->getModified();
if ( ! isset($modified[$updatedName]) || $modified[$updatedName] instanceof Doctrine_Null) { $event->getInvoker()->$updatedName = $this->getTimestamp('updated', $event->getInvoker()->getTable()->getConnection()); }
}
}
[/code]
------------------
Also there is another problem too. If you dont disable the widgets of the fields updated_at and created_at, sometimes they are sending the date time information in the $form, and the function preUpdate doesnt update the update_at because the date time has been sent. The best option is to disable the widgets and form validation in global scope, here:
<?php
/**
*
*/
abstract class BaseFormDoctrine extends sfFormDoctrine
{
public function setup()
{
//Following code will remove Required validators from these fields.
if (isset($this->validatorSchema))
{
if (isset($this->validatorSchema['created_at'])) { unset($this->validatorSchema['created_at']); }
if (isset($this->validatorSchema['updated_at']))
{ unset($this->validatorSchema['updated_at']); }}
if (isset($this->widgetSchema))
{ unset($this->widgetSchema['created_at']); }{
//following code will remove fields from form
if (isset($this->widgetSchema['created_at']))
if (isset($this->widgetSchema['updated_at']))
{ unset($this->widgetSchema['updated_at']); }}
}
}