Extbase:
authorSebastian Kurfürst <sebastian@typo3.org>
Mon, 13 Jul 2009 21:34:36 +0000 (21:34 +0000)
committerSebastian Kurfürst <sebastian@typo3.org>
Mon, 13 Jul 2009 21:34:36 +0000 (21:34 +0000)
* Implemented cache clearing by TYPO3s clearCacheCmd. This is not particularily fine-grained, but works. references #3421
* Made AbstractEntity have a different compare method inside _isDirty() which compares objects in-depth, and not just their references.

typo3/sysext/extbase/Classes/Dispatcher.php
typo3/sysext/extbase/Classes/DomainObject/AbstractEntity.php
typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php
typo3/sysext/extbase/Classes/Utility/Plugin.php
typo3/sysext/extbase/Tests/Utility/Plugin_testcase.php

index 1a5e861..5309a59 100644 (file)
@@ -57,6 +57,11 @@ class Tx_Extbase_Dispatcher {
 
                $persistenceSession = t3lib_div::makeInstance('Tx_Extbase_Persistence_Session'); // singleton
                $storageBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Storage_Typo3DbBackend'); // singleton
+               if (isset($configuration['enableAutomaticCacheClearing']) && $configuration['enableAutomaticCacheClearing'] === '1') {
+                       $storageBackend->setAutomaticCacheClearing(TRUE);
+               } else {
+                       $storageBackend->setAutomaticCacheClearing(FALSE);
+               }
                $dataMapper = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMapper');
 
                $persistenceBackend = t3lib_div::makeInstance('Tx_Extbase_Persistence_Backend', $persistenceSession, $storageBackend); // singleton
@@ -177,4 +182,4 @@ class Tx_Extbase_Dispatcher {
        }
 
 }
-?>
+?>
\ No newline at end of file
index 688c2f7..ec3347f 100644 (file)
@@ -115,9 +115,17 @@ abstract class Tx_Extbase_DomainObject_AbstractEntity extends Tx_Extbase_DomainO
                        $result = $this->_cleanProperties[$propertyName] !== $this->$propertyName;
                } else {
                        foreach ($this->_cleanProperties as $propertyName => $propertyValue) {
-                               if ($this->$propertyName !== $propertyValue) {
-                                       $result = TRUE;
-                                       break;
+                               if (is_object($this->$propertyName)) {
+                                       // In case it is an object, we do a simple comparison (!=) as we want cloned objects to return the same values.
+                                       if ($this->$propertyName != $propertyValue) {
+                                               $result = TRUE;
+                                               break;
+                                       }
+                               } else {
+                                       if ($this->$propertyName !== $propertyValue) {
+                                               $result = TRUE;
+                                               break;
+                                       }
                                }
                        }
                }
index 8a12403..0204bae 100644 (file)
@@ -31,7 +31,6 @@
  * @package Extbase
  * @subpackage Persistence
  * @version $Id: $
- * @scope prototype
  */
 class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persistence_Storage_BackendInterface, t3lib_Singleton {
 
@@ -48,6 +47,13 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
         * @var t3lib_pageSelect
         */
        protected $pageSelectObject;
+       
+       /**
+        * TRUE if automatic cache clearing in TCEMAIN should be done on insert/update/delete, FALSE otherwise.
+        *  
+        * @var boolean
+        */
+       protected $automaticCacheClearing = FALSE;
 
        /**
         * Constructs this Storage Backend instance
@@ -55,6 +61,18 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
        public function __construct() {
                $this->databaseHandle = $GLOBALS['TYPO3_DB'];
        }
+       
+       /**
+        * Set the automatic cache clearing flag.
+        * If TRUE, then inserted/updated/deleted records trigger a TCEMAIN cache clearing.
+        * 
+        * @param $automaticCacheClearing boolean if TRUE, enables automatic cache clearing
+        * @return void
+        * @internal
+        */
+       public function setAutomaticCacheClearing($automaticCacheClearing) {
+               $this->automaticCacheClearing = (boolean)$automaticCacheClearing;
+       }
 
        /**
         * Adds a row to the storage
@@ -78,7 +96,9 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
                $this->replacePlaceholders($sqlString, $parameters);
 
                $this->databaseHandle->sql_query($sqlString);
-               return $this->databaseHandle->sql_insert_id();
+               $uid = $this->databaseHandle->sql_insert_id();
+               $this->clearPageCache($tableName, $uid);
+               return $uid;
        }
 
        /**
@@ -103,7 +123,9 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
                $sqlString = 'UPDATE ' . $tableName . ' SET ' . implode(', ', $fields) . ' WHERE uid=?';
                $this->replacePlaceholders($sqlString, $parameters);
 
-               return $this->databaseHandle->sql_query($sqlString);
+               $returnValue = $this->databaseHandle->sql_query($sqlString);
+               $this->clearPageCache($tableName, $uid);
+               return $returnValue;
        }
 
        /**
@@ -116,7 +138,9 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
        public function removeRow($tableName, $uid) {
                $sqlString = 'DELETE FROM ' . $tableName . ' WHERE uid=?';
                $this->replacePlaceholders($sqlString, array((int)$uid));
-               return $this->databaseHandle->sql_query($sqlString);
+               $this->clearPageCache($tableName, $uid);
+               $returnValue = $this->databaseHandle->sql_query($sqlString);
+               return $returnValue;
        }
 
        /**
@@ -468,6 +492,48 @@ class Tx_Extbase_Persistence_Storage_Typo3DbBackend implements Tx_Extbase_Persis
                return $row;
        }
 
+       /**
+        * Clear the TYPO3 page cache for the given record.
+        * Much of this functionality is taken from t3lib_tcemain::clear_cache() which unfortunately only works with logged-in BE user.
+        * 
+        * @param $tableName Table name of the record
+        * @param $uid UID of the record
+        * @return void
+        */
+       protected function clearPageCache($tableName, $uid) {
+               if ($this->automaticCacheClearing !== TRUE) return;
+
+               $pageCache = $GLOBALS['typo3CacheManager']->getCache('cache_pages');
+               $pageSectionCache = $GLOBALS['typo3CacheManager']->getCache('cache_pagesection');
+       
+               $result = $GLOBALS['TYPO3_DB']->exec_SELECTquery('pid', $tableName, 'uid='.intval($uid));
+       
+               $pageIdsToClear = array();
+               if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result))      {
+                       $storagePage = $row['pid'];
+                       $pageIdsToClear[] = $storagePage;
+               }
+               if (!$storagePage) {
+                       return;
+               }
+               
+               $pageTSConfig = t3lib_BEfunc::getPagesTSconfig($storagePage);
+               
+               if ($pageTSConfig['clearCacheCmd'])     {
+                       $clearCacheCommands = t3lib_div::trimExplode(',',strtolower($TSConfig['clearCacheCmd']),1);
+                               $clearCacheCommands = array_unique($clearCacheCommands);
+                               foreach ($clearCacheCommands as $clearCacheCommand)     {
+                                       if (t3lib_div::testInt($clearCacheCommand))     {
+                                               $pageIdsToClear[] = $clearCacheCommand;
+                                       }
+                               }
+                       }
+               
+               foreach ($pageIdsToClear as $pageIdToClear) {
+                       $pageCache->flushByTag('pageId_' . $pageIdToClear);
+                       $pageSectionCache->flushByTag('pageId_' . $pageIdToClear);
+               }
+       }
 }
 
 ?>
\ No newline at end of file
index c53ca06..b1438bf 100644 (file)
@@ -122,7 +122,8 @@ tt_content.list.20.' . $pluginSignature . ' = ' . $contentObjectType . '
 tt_content.list.20.' . $pluginSignature . ' {
        userFunc = tx_extbase_dispatcher->dispatch
        pluginName = ' . $pluginName . '
-       extensionName = ' . $extensionName .
+       extensionName = ' . $extensionName . '
+       enableAutomaticCacheClearing = 1' . 
        $controller .
        $action . 
        $switchableControllerActions . '
index 33caf18..3666e77 100644 (file)
@@ -70,6 +70,27 @@ class Tx_Extbase_Utility_Plugin_testcase extends tx_phpunit_testcase {
        $this->assertNotContains('USER_INT', $staticTypoScript);
        }
 
+       
+       /**
+        * @test
+        * @see Tx_Extbase_Utility_Plugin::registerPlugin
+        */
+       public function addingTsAddsEnablesCacheClearingByDefault() {
+               global $TYPO3_CONF_VARS;
+               $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.'] = array();
+               Tx_Extbase_Utility_Plugin::registerPlugin(
+                       'MyExtension',
+                       'Pi1',
+                       'My Plugin Title',
+                       array('Blog' => 'index')
+               );
+               $staticTypoScript = $TYPO3_CONF_VARS['FE']['defaultTypoScript_setup.']['43'];
+
+               $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
+               $this->assertContains('
+       enableAutomaticCacheClearing = 1', $staticTypoScript);
+       }
+       
        /**
         * @test
         * @see Tx_Extbase_Utility_Plugin::registerPlugin
@@ -90,7 +111,8 @@ class Tx_Extbase_Utility_Plugin_testcase extends tx_phpunit_testcase {
                $this->assertContains('tt_content.list.20.myextension_pi1 = USER', $staticTypoScript);
                $this->assertContains('
        pluginName = Pi1
-       extensionName = MyExtension
+       extensionName = MyExtension', $staticTypoScript);
+               $this->assertContains('
        controller = FirstController
        action = index', $staticTypoScript);
                $this->assertNotContains('USER_INT', $staticTypoScript);