Tharos / LeanMapper

Lean Mapper is a tiny ORM based on powerful Dibi database abstraction library for PHP.
MIT License
87 stars 35 forks source link

Fixes problem with passthru setter #117

Closed dakujem closed 6 years ago

dakujem commented 6 years ago

So in 3.1 you changed passthru getter so that you can specify the type in the callable, but you forgot that the passthru setter must do the same...

Let me demonstrate on a very common use case where one uses JSON as string in the DB and wants an array in the Entity.

Simplest Entity:

/**
 * @property int $id
 * @property array|NULL $attrs m:passThru(jsonDecodeData|jsonEncodeData)
 */
class Foo extends LeanMapper\Entity
{

    protected function jsonEncodeData($data)
    {
        return !empty($data) ? Json::encode($data) : NULL;
    }

    protected function jsonDecodeData($data)
    {
        return !empty($data) ? Json::decode($data, Json::FORCE_ARRAY) : [];
    }

}

You set array, and you expect to get arrays as well:

$entity->attrs = ['foo' => 'bar',];
var_dump($entity->attrs);

Whoa! Warning: json_decode() expects parameter 1 to be string, array given. Why? because after the setting calls to Entity::getModifiedRowData return:

attrs => array (1)
0 => "{"foo":"bar"}" (13)

instead of expected:

attrs => "{"foo":"bar"}" (13)

It is caused by calling settype with the returned string and "array" as the type.

This also obviously leads to invalid SQL like

UPDATE `products` 
SET `attrs`={'foo':'bar'}
WHERE ...

while it should be

UPDATE `products` 
SET `attrs`="{'foo':'bar'}"
WHERE ...

(it is not escaped properly).

castamir commented 6 years ago

thanks, give me some time to check it out please

janpecha commented 6 years ago

Thanks for PR!

dakujem commented 6 years ago

You're welcome.