spotorm / spot2

Spot v2.x DataMapper built on top of Doctrine's Database Abstraction Layer
http://phpdatamapper.com
BSD 3-Clause "New" or "Revised" License
601 stars 101 forks source link

Bug using set{FieldCamelCase} with DateTimeType #245

Closed sojimaxi closed 6 years ago

sojimaxi commented 6 years ago

A little bug should it self while developing my current app and its due to the autoloaded "set{FieldCamelCase}". I think there should be an option to toggle enable or disable on this feature similar to validate.

abstract class BaseModel extends \Spot\Entity
{
 public static function events(EventEmitter $eventEmitter)
    {
        $eventEmitter->on('beforeSave',function (EntityInterface $entity, MapperInterface $mapper){
            $entity->setCreatedAt();
        });
    }
    public function setCreatedAt() {
        $this->created_at = new DateTime;
     }
}

class ObjectModel extends BaseModel
{
    ...
    public static function fields()
    {
        return [
             ...
            'created_at' => ['type' => 'datetime']
        ];
    }
    ...
}

This make DBAL produce an error Call to undefined method App\\Object::format() since the value passed to Doctrine\\DBAL\\Types\\DateTimeType->convertToDatabaseValue was an object instead of string.

This bug goes away if I rename the setCreatedAt method to something else.

FlipEverything commented 6 years ago

The preferred way of initializing the DateTime field is this:

class ObjectModel extends BaseModel
{
    ...
    public static function fields()
    {
        return [
             ...
            'created_at' => ['type' => 'datetime', 'value' => new \DateTime()]
        ];
    }
    ...
}

To be honest your solution is pretty pointless and slow.

willemwollebrants commented 6 years ago

"It's not a bug, it's a feature™"

The set{FieldCamelCase} methods are indeed somewhat reserved for setters. Since your getCreatedAt-method returns nothing, I was expecting created_at to be null to be honest.

You have options:

What @FlipEverything suggested is probably the easiest, most elegant way.