Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixing issues with duplicate content/empty tags with CacheHelper.

Added internal tag munging proposed by 'FelipePtChO'.
Uncommented a test that was failing.
Fixes #1857
  • Loading branch information...
commit 095c15d557b0cdc13dd2e9eaced191465a0bf32b 1 parent eccfd1d
@markstory markstory authored markstory committed
View
39 cake/libs/view/helpers/cache.php
@@ -55,6 +55,13 @@ class CacheHelper extends AppHelper {
*/
var $cacheAction;
/**
+ * Counter used for counting nocache section tags.
+ *
+ * @var integer
+ */
+ var $_counter = 0;
+
+/**
* Main method used to cache a view
*
* @param string $file File to cache
@@ -134,10 +141,13 @@ function cache($file, $out, $cache = false) {
}
if ($cacheTime != '' && $cacheTime > 0) {
+ $out = preg_replace_callback('/<cake\:nocache>/', array($this, '_replaceSection'), $out);
+
$this->__parseFile($file, $out);
if ($cache === true) {
$cached = $this->__parseOutput($out);
$this->__writeFile($cached, $cacheTime, $useCallbacks);
+ $out = $this->_stripTags($out);
}
return $out;
} else {
@@ -157,7 +167,8 @@ function __parseFile($file, $cache) {
} elseif ($file = fileExistsInPath($file)) {
$file = file_get_contents($file);
}
- preg_match_all('/(<cake:nocache>(?<=<cake:nocache>)[\\s\\S]*?(?=<\/cake:nocache>)<\/cake:nocache>)/i', $cache, $outputResult, PREG_PATTERN_ORDER);
+
+ preg_match_all('/(<cake:nocache:\d{3}>(?<=<cake:nocache:\d{3}>)[\\s\\S]*?(?=<\/cake:nocache>)<\/cake:nocache>)/i', $cache, $outputResult, PREG_PATTERN_ORDER);
preg_match_all('/(?<=<cake:nocache>)([\\s\\S]*?)(?=<\/cake:nocache>)/i', $file, $fileResult, PREG_PATTERN_ORDER);
$fileResult = $fileResult[0];
$outputResult = $outputResult[0];
@@ -184,6 +195,30 @@ function __parseFile($file, $cache) {
}
}
/**
+ * Munges the output from a view with cache tags, and numbers the sections.
+ * This helps solve issues with empty/duplicate content.
+ *
+ * @param string $content The content to munge.
+ * @return string The content with cake:nocache tags replaced.
+ */
+ function _replaceSection($matches) {
+ $this->_counter += 1;
+ return sprintf('<cake:nocache:%03d>', $this->_counter);
+ }
+
+/**
+ * Strip cake:nocache tags from a string. Since View::render()
+ * only removes un-numbered nocache tags, remove all the numbered ones.
+ * This is the complement to _replaceSection.
+ *
+ * @param string $content String to remove tags from.
+ * @return string String with tags removed.
+ */
+ function _stripTags($content) {
+ return preg_replace('#<\/?cake\:nocache(\:\d{3})?>#', '', $content);
+ }
+
+/**
* Parse the output and replace cache tags
*
* @param sting $cache
@@ -290,4 +325,4 @@ function __writeFile($content, $timestamp, $useCallbacks = false) {
return cache('views' . DS . $cache, $file, $timestamp);
}
}
-?>
+?>
View
2  cake/libs/view/view.php
@@ -687,7 +687,7 @@ function _render($___viewFn, $___dataForView, $loadHelpers = true, $cached = fal
$cache->controllerName = $this->name;
$cache->layout = $this->layout;
$cache->cacheAction = $this->cacheAction;
- $cache->cache($___viewFn, $out, $cached);
+ $out = $cache->cache($___viewFn, $out, $cached);
}
}
return $out;
View
27 cake/tests/cases/libs/view/helpers/cache.test.php
@@ -352,11 +352,17 @@ function testCacheBaseNameControllerName() {
* This test must be uncommented/fixed in next release (1.2+)
*
* @return void
- * @access public
- *
- function testCacheEmptySections () {
+ */
+ function testCacheEmptySections() {
$this->Controller->cache_parsing();
- $this->Controller->cacheAction = array('cacheTest' => 21600);
+ $this->Controller->params = array(
+ 'controller' => 'cacheTest',
+ 'action' => 'cache_empty_sections',
+ 'url' => array(),
+ 'pass' => array(),
+ 'named' => array()
+ );
+ $this->Controller->cacheAction = array('cache_empty_sections' => 21600);
$this->Controller->here = '/cacheTest/cache_empty_sections';
$this->Controller->action = 'cache_empty_sections';
$this->Controller->layout = 'cache_empty_sections';
@@ -379,17 +385,16 @@ function testCacheEmptySections () {
$this->assertNoPattern('/cake:nocache/', $contents);
$this->assertPattern(
'@<head>\s*<title>Posts</title>\s*' .
- "<\?php \$x = 1; \?>\s*" .
+ '<\?php \$x \= 1; \?>\s*' .
'</head>\s*' .
'<body>\s*' .
- "<\?php \$x\+\+; \?>\s*" .
- "<\?php \$x\+\+; \?>\s*" .
+ '<\?php \$x\+\+; \?>\s*' .
+ '<\?php \$x\+\+; \?>\s*' .
'View Content\s*' .
- "<\?php \$y = 1; \?>\s*" .
- "<\?php echo 'cached count is:' . \$x; \?>\s*" .
+ '<\?php \$y = 1; \?>\s*' .
+ '<\?php echo \'cached count is: \' . \$x; \?>\s*' .
'@', $contents);
@unlink($filename);
}
-*/
}
-?>
+?>
Please sign in to comment.
Something went wrong with that request. Please try again.