Skip to content

Commit

Permalink
[#10183] Fix cache entry removal on xPDOObject::remove()
Browse files Browse the repository at this point in the history
  • Loading branch information
opengeek committed Sep 6, 2013
1 parent 2bc9e86 commit 2526075
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 5 deletions.
163 changes: 163 additions & 0 deletions test/xPDO/xPDOCache/xPDOCacheDb.php
@@ -0,0 +1,163 @@
<?php
/**
* Copyright 2010-2013 by MODX, LLC.
*
* This file is part of xPDO.
*
* xPDO is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* xPDO is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* xPDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
* Suite 330, Boston, MA 02111-1307 USA
*
* @package xpdo-test
*/
/**
* Tests related to basic xPDOObject methods
*
* @package xpdo-test
* @subpackage xpdo
*/
class xPDOCacheDbTest extends xPDOTestCase {
/**
* Setup dummy data for each test.
*/
public function setUp() {
parent::setUp();
try {
/* ensure we have clear data and identity sequences */
$this->xpdo->getManager();

$this->xpdo->manager->createObjectContainer('Phone');
$this->xpdo->manager->createObjectContainer('Person');
$this->xpdo->manager->createObjectContainer('PersonPhone');
$this->xpdo->manager->createObjectContainer('BloodType');

$bloodTypes = array('A+','A-','B+','B-','AB+','AB-','O+','O-');
foreach ($bloodTypes as $bloodType) {
$bt = $this->xpdo->newObject('BloodType');
$bt->set('type',$bloodType);
$bt->set('description','');
if (!$bt->save()) {
$this->xpdo->log(xPDO::LOG_LEVEL_FATAL,'Could not add blood type: '.$bloodType);
}
}

$bloodTypeABPlus = $this->xpdo->getObject('BloodType','AB+');
if (empty($bloodTypeABPlus)) $this->xpdo->log(xPDO::LOG_LEVEL_FATAL,'Could not load blood type.');

/* add some people */
$person= $this->xpdo->newObject('Person');
$person->set('first_name', 'Johnathon');
$person->set('last_name', 'Doe');
$person->set('middle_name', 'Harry');
$person->set('dob', '1950-03-14');
$person->set('gender', 'M');
$person->set('password', 'ohb0ybuddy');
$person->set('username', 'john.doe@gmail.com');
$person->set('security_level', 3);
$person->set('blood_type',$bloodTypeABPlus->get('type'));
$person->save();

$phone = $this->xpdo->newObject('Phone');
$phone->fromArray(array(
'type' => 'work',
'number' => '555-111-1111',
));
$phone->save();

$personPhone = $this->xpdo->newObject('PersonPhone');
$personPhone->fromArray(array(
'person' => 1,
'phone' => 1,
'is_primary' => true,
),'',true,true);
$personPhone->save();

$person= $this->xpdo->newObject('Person');
$person->set('first_name', 'Jane');
$person->set('last_name', 'Heartstead');
$person->set('middle_name', 'Cecilia');
$person->set('dob', '1978-10-23');
$person->set('gender', 'F');
$person->set('password', 'n0w4yimdoingthat');
$person->set('username', 'jane.heartstead@yahoo.com');
$person->set('security_level',1);
$person->set('blood_type',$bloodTypeABPlus->get('type'));
$person->save();

$phone = $this->xpdo->newObject('Phone');
$phone->fromArray(array(
'type' => 'work',
'number' => '555-222-2222',
));
$phone->save();

$personPhone = $this->xpdo->newObject('PersonPhone');
$personPhone->fromArray(array(
'person' => 2,
'phone' => 2,
'is_primary' => true,
),'',true,true);
$personPhone->save();

$phone = $this->xpdo->newObject('Phone');
$phone->fromArray(array(
'type' => 'home',
'number' => '555-555-5555',
));
$phone->save();

$personPhone = $this->xpdo->newObject('PersonPhone');
$personPhone->fromArray(array(
'person' => 2,
'phone' => 3,
'is_primary' => false,
),'',true,true);
$personPhone->save();
} catch (Exception $e) {
$this->xpdo->log(xPDO::LOG_LEVEL_ERROR, $e->getMessage(), '', __METHOD__, __FILE__, __LINE__);
}
}

/**
* Remove dummy data prior to each test.
*/
public function tearDown() {
try {
$this->xpdo->manager->removeObjectContainer('Phone');
$this->xpdo->manager->removeObjectContainer('Person');
$this->xpdo->manager->removeObjectContainer('PersonPhone');
$this->xpdo->manager->removeObjectContainer('BloodType');
} catch (Exception $e) {
$this->xpdo->log(xPDO::LOG_LEVEL_ERROR, $e->getMessage(), '', __METHOD__, __FILE__, __LINE__);
}
parent::tearDown();
}

/**
* Ensure cache entries for class do not remain when removing an object.
*/
public function testRemoveObject() {
$this->xpdo->setOption(xPDO::OPT_CACHE_DB, true);

$people= $this->xpdo->getCollection('Person');

/** @var Person $person */
$person= $this->xpdo->getObject('Person', 1);
$person->remove();

$people= $this->xpdo->getCollection('Person');
$count= count($people);

$this->assertEquals(0, $this->xpdo->getCount('Person', 1), "Object still exists after remove");
$this->assertEquals(1, $count, "Object still exists in cache after removal");
}
}
4 changes: 3 additions & 1 deletion test/xPDO/xPDOCache/xPDOCache_AllTests.php
Expand Up @@ -20,6 +20,7 @@
* @package xpdo-test
*/
require_once 'xPDOCacheManager.php';
require_once 'xPDOCacheDb.php';
/**
* Suite handling all xPDOCache related tests.
*
Expand All @@ -30,6 +31,7 @@ class xPDOCache_AllTests extends PHPUnit_Framework_TestSuite {
public static function suite() {
$suite = new xPDOCache_AllTests('xPDOCacheTest');
$suite->addTestSuite('xPDOCacheManagerTest');
$suite->addTestSuite('xPDOCacheDbTest');
return $suite;
}
}
}
2 changes: 2 additions & 0 deletions xpdo/changelog.txt
@@ -1,5 +1,7 @@
This file shows the changes in this release of xPDO.

- [#10183] Fix cache entry removal on xPDOObject::remove()

xPDO 2.2.8-pl (August 26, 2013)
====================================
- [#9864] Identify compound PK's properly in xPDOQuery::parseConditions()
Expand Down
18 changes: 15 additions & 3 deletions xpdo/om/xpdoobject.class.php
Expand Up @@ -1642,9 +1642,21 @@ public function remove(array $ancestors= array ()) {
if ($callback && is_callable($callback)) {
call_user_func($callback, array('className' => $this->_class, 'criteria' => $delete, 'object' => $this));
}
if ($this->xpdo->_cacheEnabled) {
$cacheKey= is_array($pk) ? implode('_', $pk) : $pk;
$this->xpdo->toCache($this->xpdo->getTableClass($this->_class) . '_' . $cacheKey, null, 0, array('modified' => true));
if ($this->xpdo->_cacheEnabled && $this->xpdo->getOption('cache_db', null, false)) {
/** @var xPDOCache $dbCache */
$dbCache = $this->xpdo->getCacheManager()->getCacheProvider(
$this->getOption('cache_db_key', null, 'db'),
array(
xPDO::OPT_CACHE_KEY => $this->getOption('cache_db_key', null, 'db'),
xPDO::OPT_CACHE_HANDLER => $this->getOption(xPDO::OPT_CACHE_DB_HANDLER, null, $this->getOption(xPDO::OPT_CACHE_HANDLER, null, 'cache.xPDOFileCache')),
xPDO::OPT_CACHE_FORMAT => (integer) $this->getOption('cache_db_format', null, $this->getOption(xPDO::OPT_CACHE_FORMAT, null, xPDOCacheManager::CACHE_PHP)),
xPDO::OPT_CACHE_EXPIRES => (integer) $this->getOption(xPDO::OPT_CACHE_DB_EXPIRES, null, $this->getOption(xPDO::OPT_CACHE_EXPIRES, null, 0)),
xPDO::OPT_CACHE_PREFIX => $this->getOption('cache_db_prefix', null, xPDOCacheManager::CACHE_DIR)
)
);
if (!$dbCache->delete($this->_class, array('multiple_object_delete' => true))) {
$this->xpdo->log(xPDO::LOG_LEVEL_WARN, "Could not remove cache entries for {$this->_class}", '', __METHOD__, __FILE__, __LINE__);
}
}
$this->xpdo->log(xPDO::LOG_LEVEL_INFO, "Removed {$this->_class} instance with primary key " . print_r($pk, true));
}
Expand Down
4 changes: 3 additions & 1 deletion xpdo/xpdo.class.php
Expand Up @@ -2303,6 +2303,7 @@ public function toCache($signature, $object, $lifetime= 0, $options = array()) {
xPDO::OPT_CACHE_KEY => $this->getOption('cache_db_key', $options, 'db'),
xPDO::OPT_CACHE_HANDLER => $this->getOption(xPDO::OPT_CACHE_DB_HANDLER, $options, $this->getOption(xPDO::OPT_CACHE_HANDLER, $options, 'cache.xPDOFileCache')),
xPDO::OPT_CACHE_FORMAT => (integer) $this->getOption('cache_db_format', $options, $this->getOption(xPDO::OPT_CACHE_FORMAT, $options, xPDOCacheManager::CACHE_PHP)),
xPDO::OPT_CACHE_EXPIRES => (integer) $this->getOption(xPDO::OPT_CACHE_DB_EXPIRES, null, $this->getOption(xPDO::OPT_CACHE_EXPIRES, null, 0)),
xPDO::OPT_CACHE_PREFIX => $this->getOption('cache_db_prefix', $options, xPDOCacheManager::CACHE_DIR),
'multiple_object_delete' => true
)));
Expand All @@ -2316,7 +2317,8 @@ public function toCache($signature, $object, $lifetime= 0, $options = array()) {
xPDO::OPT_CACHE_KEY => $this->getOption('cache_db_key', $options, 'db'),
xPDO::OPT_CACHE_HANDLER => $this->getOption(xPDO::OPT_CACHE_DB_HANDLER, $options, $this->getOption(xPDO::OPT_CACHE_HANDLER, $options, 'cache.xPDOFileCache')),
xPDO::OPT_CACHE_FORMAT => (integer) $this->getOption('cache_db_format', $options, $this->getOption(xPDO::OPT_CACHE_FORMAT, $options, xPDOCacheManager::CACHE_PHP)),
'cache_prefix' => $this->getOption('cache_db_prefix', $options, xPDOCacheManager::CACHE_DIR)
xPDO::OPT_CACHE_EXPIRES => (integer) $this->getOption(xPDO::OPT_CACHE_DB_EXPIRES, null, $this->getOption(xPDO::OPT_CACHE_EXPIRES, null, 0)),
xPDO::OPT_CACHE_PREFIX => $this->getOption('cache_db_prefix', $options, xPDOCacheManager::CACHE_DIR)
));
$result= $this->cacheManager->set($sig, $object, $lifetime, $cacheOptions);
if ($result && $object instanceof xPDOObject) {
Expand Down

0 comments on commit 2526075

Please sign in to comment.