Browse Source

Added cache fallback config option

Jeremy Harris 8 years ago
parent
commit
1d81bf05ee
3 changed files with 79 additions and 6 deletions
  1. 12 1
      src/Cache/Cache.php
  2. 6 5
      src/Cache/Engine/FileEngine.php
  3. 61 0
      tests/TestCase/Cache/CacheTest.php

+ 12 - 1
src/Cache/Cache.php

@@ -168,7 +168,18 @@ class Cache
         }
 
         $config = static::$_config[$name];
-        $registry->load($name, $config);
+
+        try {
+            $registry->load($name, $config);
+        } catch (RuntimeException $e) {
+            if (!array_key_exists('fallback', $config)) {
+                throw $e;
+            }
+            $fallbackEngine = static::engine($config['fallback']);
+            static::getRegistry()->set($name, $fallbackEngine);
+
+            return;
+        }
 
         if ($config['className'] instanceof CacheEngine) {
             $config = $config['className']->getConfig();

+ 6 - 5
src/Cache/Engine/FileEngine.php

@@ -420,21 +420,22 @@ class FileEngine extends CacheEngine
     {
         $dir = new SplFileInfo($this->_config['path']);
         $path = $dir->getPathname();
+        $success = true;
         if (!is_dir($path)) {
-            mkdir($path, 0775, true);
+            //@codingStandardsIgnoreStart
+            $success = @mkdir($path, 0775, true);
+            //@codingStandardsIgnoreEnd
         }
 
-        if ($this->_init && !($dir->isDir() && $dir->isWritable())) {
+        if ($success && $this->_init && !($dir->isDir() && $dir->isWritable())) {
             $this->_init = false;
             trigger_error(sprintf(
                 '%s is not writable',
                 $this->_config['path']
             ), E_USER_WARNING);
-
-            return false;
         }
 
-        return true;
+        return $success;
     }
 
     /**

+ 61 - 0
tests/TestCase/Cache/CacheTest.php

@@ -65,6 +65,67 @@ class CacheTest extends TestCase
     }
 
     /**
+     * tests Cache::engine() fallback
+     *
+     * @return void
+     */
+    public function testCacheEngineFallback()
+    {
+        Cache::setConfig('tests', [
+            'engine' => 'File',
+            'path' => DS . 'missing_dir',
+            'prefix' => 'test_',
+            'fallback' => 'tests_fallback'
+        ]);
+        Cache::setConfig('tests_fallback', [
+            'engine' => 'File',
+            'path' => TMP,
+            'prefix' => 'test_',
+        ]);
+
+        $engine = Cache::engine('tests');
+        $path = $engine->getConfig('path');
+        $this->assertSame(TMP, $path);
+
+        Cache::drop('tests');
+        Cache::drop('tests_fallback');
+    }
+
+    /**
+     * tests cache fallback
+     *
+     * @return void
+     */
+    public function testCacheFallbackIntegration()
+    {
+        Cache::setConfig('tests', [
+            'engine' => 'File',
+            'path' => DS . 'unwritable_dir',
+            'prefix' => 'test_',
+            'fallback' => 'tests_fallback',
+        ]);
+        Cache::setConfig('tests_fallback', [
+            'engine' => 'File',
+            'path' => DS . 'still_unwritable_dir',
+            'prefix' => 'test_',
+            'fallback' => 'tests_fallback_final',
+        ]);
+        Cache::setConfig('tests_fallback_final', [
+            'engine' => 'File',
+            'path' => TMP,
+            'prefix' => 'test_',
+        ]);
+
+        $this->assertTrue(Cache::write('fallback', 'worked', 'tests'));
+        $this->assertSame('worked', Cache::read('fallback', 'tests'));
+        $this->assertTrue(Cache::delete('fallback', 'tests'));
+
+        Cache::drop('tests');
+        Cache::drop('tests_fallback');
+        Cache::drop('tests_fallback_final');
+    }
+
+    /**
      * Check that no fatal errors are issued doing normal things when Cache.disable is true.
      *
      * @return void