Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge branch 'master' of https://github.com/marc-mabe/zf2 into hotfix…
Browse files Browse the repository at this point in the history
…/cache-output
  • Loading branch information
weierophinney committed Apr 3, 2012
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 106 deletions.
68 changes: 19 additions & 49 deletions src/Pattern/OutputCache.php
Expand Up @@ -58,39 +58,24 @@ public function setOptions(PatternOptions $options)
}

/**
* Start output cache
* if there is a cached item with the given key display it's data and return true
* else start buffering output until end() is called or the script ends.
*
* Options:
* output boolean If true the (default) cached output will be displayed
* else the cached output will be returned instead of true
* + storage read options
*
* @param string $key Key
* @param array $options Output start options (ttl | validate | output)
* @return boolean|string True if the cache is hit or if output disabled the cached data, false else
* @param string $key Key
* @param array $storageOptions Options passing to Zend\Cache\Storage\Adapter::getItem
* @return boolean
* @throws Exception
*/
public function start($key, array $options = array())
public function start($key, array $storageOptions = array())
{
if (($key = (string) $key) === '') {
throw new Exception\MissingKeyException('Missing key to read/write output from storage');
}

$classOptions = $this->getOptions();

$optOutput = true;
if (isset($options['output'])) {
$optOutput = (bool) $options['output'];
unset($options['output']); // don't forword this option to storage
throw new Exception\MissingKeyException('Missing key to read/write output from cache');
}

$data = $classOptions->getStorage()->getItem($key, $options);
$data = $this->getOptions()->getStorage()->getItem($key, $storageOptions);
if ($data !== false) {
if ($optOutput) {
echo $data;
return true;
}
return (string) $data;
echo $data;
return true;
}

ob_start();
Expand All @@ -100,40 +85,25 @@ public function start($key, array $options = array())
}

/**
* Stop output cache
*
* Options:
* output boolean If true (default) the catched output will be displayed
* else teh catched output will only be written to cache
* + storage write options
* Stops bufferung output, write buffered data to cache using the given key on start()
* and displays the buffer.
*
* @param array $options
* @return boolean
* @param array $storageOptions Options passed to Zend\Cache\Storage\Adapter::setItem
* @return boolean TRUE on success, FALSE on failure writing to cache
* @throws Exception
*/
public function end(array $options = array())
public function end(array $storageOptions = array())
{
$key = array_pop($this->keyStack);
if ($key === null) {
throw new Exception\RuntimeException('use of end() without a start()');
}

$optOutput = true;
if (isset($options['output'])) {
$optOutput = (bool) $options['output'];
unset($options['output']); // don't forword this option to storage
}

if ($optOutput) {
$data = ob_get_flush();
} else {
$data = ob_get_clean();
throw new Exception\RuntimeException('Output cache not started');
}

if ($data === false) {
$output = ob_end_flush();
if ($output === false) {
throw new Exception\RuntimeException('Output buffering not active');
}

return $this->getOptions()->getStorage()->setItem($key, $data, $options);
return $this->getOptions()->getStorage()->setItem($key, $output, $storageOptions);
}
}
91 changes: 34 additions & 57 deletions test/Pattern/OutputCacheTest.php
Expand Up @@ -39,6 +39,13 @@ class OutputCacheTest extends CommonPatternTest
*/
protected $_storage;

/**
* Nesting level of output buffering used to restore on tearDown()
*
* @var null|int
*/
protected $_obLevel;

public function setUp()
{
$this->_storage = new Cache\Storage\Adapter\Memory();
Expand All @@ -48,91 +55,61 @@ public function setUp()
$this->_pattern = new Cache\Pattern\OutputCache();
$this->_pattern->setOptions($this->_options);

// used to reset the level on tearDown
$this->_obLevel = ob_get_level();

parent::setUp();
}

public function tearDown()
{
parent::tearDown();
}

public function testStartEndOutput()
{
$output = 'foobar';
$key = 'testStartEndOutput';

ob_start();
if (!($this->_pattern->start($key))) {
echo $output;
$this->_pattern->end();
if ($this->_obLevel > ob_get_Level()) {
for ($i = ob_get_level(); $i < $this->_obLevel; $i++) {
ob_start();
}
$this->fail("Nesting level of output buffering to often ended");
} elseif ($this->_obLevel < ob_get_level()) {
for ($i = ob_get_level(); $i > $this->_obLevel; $i--) {
ob_end_clean();
}
$this->fail("Nesting level of output buffering not well restored");
}
$data = ob_get_clean();
$this->assertEquals($output, $data);
}

public function testStartEndReturnOutput()
{
$output = 'foobar';
$key = 'testStartEndReturnOutput';
$data = '';
if (!($this->_pattern->start($key))) {
echo $output;
$data = $this->_pattern->end(array('output' => false));
}
$this->assertEquals($output, $data);
parent::tearDown();
}

public function testStartEndCachedOutput()
public function testStartEndCacheMiss()
{
$output = 'foobar';
$key = 'testStartEndCachedOutput';
$key = 'testStartEndCacheMiss';

// first run to write to cache
ob_start();
if (!($this->_pattern->start($key))) {
echo $output;
$this->_pattern->end();
}
$this->assertFalse($this->_pattern->start($key));
echo $output;
$this->assertTrue($this->_pattern->end());
$data = ob_get_clean();
$this->assertEquals($output, $data);

// second run to check if cached
// first run to write to cache
ob_start();
if (!($this->_pattern->start($key))) {
ob_end_clean();
$this->fail('Second run has to be cached');
}
$data = ob_get_clean();
$this->assertEquals($output, $data);
}

public function testStartEndReturnCachedOutput()
public function testStartEndCacheHit()
{
$output = 'foobar';
$key = 'testStartEndReturnCachedOutput';
$key = 'testStartEndCacheHit';

// fill cache
$this->_pattern->getOptions()->getStorage()->setItem($key, $output);

// first run to write to cache
ob_start();
if (!($this->_pattern->start($key))) {
echo $output;
$this->_pattern->end();
}
$this->assertTrue($this->_pattern->start($key));
$data = ob_get_clean();
ob_implicit_flush(true);
$this->assertEquals($output, $data);

// second run to check if cached
// first run to write to cache
if ( ($data = $this->_pattern->start($key, array('output' => false))) === false ) {
$this->fail('Second run has to be cached');
}
$this->assertEquals($output, $data);
$this->assertSame($output, $data);
}

public function testThrowMissingKeyException()
{
$this->setExpectedException('Zend\\Cache\\Exception\\MissingKeyException');
$this->setExpectedException('Zend\Cache\Exception\MissingKeyException');
$this->_pattern->start(''); // empty key
}

Expand Down

0 comments on commit 6d7cf99

Please sign in to comment.