Skip to content

Commit

Permalink
Merge pull request #12171 from Jurigag/3.0.x-model-cache-serialize
Browse files Browse the repository at this point in the history
  • Loading branch information
sergeyklay committed Aug 26, 2016
2 parents 48830f1 + 676fd2f commit 3422322
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# [3.0.2](https://github.com/phalcon/cphalcon/releases/tag/v3.0.2) (2016-XX-XX)
- Fixed saving snapshot data while caching model [#12170](https://github.com/phalcon/cphalcon/issues/12170), [#12000](https://github.com/phalcon/cphalcon/issues/12000)

# [3.0.1](https://github.com/phalcon/cphalcon/releases/tag/v3.0.1) (2016-08-24)
- Fixed `Phalcon\Cache\Backend\Redis::flush` in order to flush cache correctly
Expand Down
28 changes: 26 additions & 2 deletions phalcon/mvc/model.zep
Original file line number Diff line number Diff line change
Expand Up @@ -4303,15 +4303,30 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface
/**
* Use the standard serialize function to serialize the array data
*/
return serialize(this->toArray());
var attributes, snapshot, manager;

let attributes = this->toArray(),
manager = <ManagerInterface> this->getModelsManager();

if manager->isKeepingSnapshots(this) {
let snapshot = this->_snapshot;
/**
* If attributes is not the same as snapshot then save snapshot too
*/
if attributes != snapshot {
return serialize(["_attributes": attributes, "_snapshot": snapshot]);
}
}

return serialize(attributes);
}

/**
* Unserializes the object from a serialized string
*/
public function unserialize(string! data)
{
var attributes, dependencyInjector, manager, key, value;
var attributes, dependencyInjector, manager, key, value, snapshot;

let attributes = unserialize(data);
if typeof attributes == "array" {
Expand Down Expand Up @@ -4346,6 +4361,15 @@ abstract class Model implements EntityInterface, ModelInterface, ResultInterface
* Try to initialize the model
*/
manager->initialize(this);
if manager->isKeepingSnapshots(this) {
if fetch snapshot, attributes["_snapshot"] {
let this->_snapshot = snapshot;
let attributes = attributes["_attributes"];
}
else {
let this->_snapshot = attributes;
}
}

/**
* Update the objects attributes
Expand Down
1 change: 1 addition & 0 deletions tests/_data/models/Robots.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Robots extends Model
{
public function initialize()
{
$this->keepSnapshots(true);
$this->hasMany('id',RobotsParts::class, 'robots_id', ['foreignKey' => true, 'reusable' => false, 'alias' => 'parts']);
}
}
38 changes: 38 additions & 0 deletions tests/unit/Mvc/ModelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace Phalcon\Test\Unit\Mvc;

use Phalcon\Cache\Backend\Apc;
use Phalcon\Cache\Frontend\Data;
use Phalcon\Test\Models\Robots;
use Phalcon\Test\Models\Users;
use Phalcon\Test\Models\Customers;
use Phalcon\Test\Models\Packages;
Expand Down Expand Up @@ -187,4 +190,39 @@ function () {
}
);
}

/**
* Tests serializing model while using cache and keeping snapshots
*
* The snapshot should be saved while using cache
*
* @issue 12170, 12000
* @author Wojciech Ślawski <jurigag@gmail.com>
* @since 2016-08-26
*/
public function testSerializeSnapshotCache()
{
$this->specify(
'Snapshot data should be saved while saving model to cache',
function () {
$cache = new Apc(new Data(['lifetime' => 20]));
$robot = Robots::findFirst();
expect($robot)->isInstanceOf(Robots::class);
expect($robot->getSnapshotData())->notEmpty();
$cache->save('robot', $robot);
/** @var Robots $robot */
$robot = $cache->get('robot');
expect($robot)->isInstanceOf(Robots::class);
expect($robot->getSnapshotData())->notEmpty();
expect($robot->getSnapshotData())->equals($robot->toArray());
$robot->text = 'abc';
$cache->save('robot', $robot);
/** @var Robots $robot */
$robot = $cache->get('robot');
expect($robot)->isInstanceOf(Robots::class);
expect($robot->getSnapshotData())->notEmpty();
expect($robot->getSnapshotData())->notEquals($robot->toArray());
}
);
}
}

0 comments on commit 3422322

Please sign in to comment.