Passed
Push — master ( ae9760...35700c )
by Andreas
17:19
created

midcom_services_cache_module::prepare_backend()   B

Complexity

Conditions 11
Paths 54

Size

Total Lines 42
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 22.5563

Importance

Changes 0
Metric Value
cc 11
eloc 35
c 0
b 0
f 0
nc 54
nop 2
dl 0
loc 42
ccs 19
cts 35
cp 0.5429
crap 22.5563
rs 7.3166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @package midcom.services
4
 * @author The Midgard Project, http://www.midgard-project.org
5
 * @copyright The Midgard Project, http://www.midgard-project.org
6
 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License
7
 */
8
9
use Doctrine\Common\Cache;
10
use Doctrine\Common\Cache\CacheProvider;
11
12
/**
13
 * This is the base class for the MidCOM cache modules. It provides a basic infrastructure
14
 * for building your own caching service, providing hooks for initialization.
15
 *
16
 * It provides convenience methods to start up the cache module, for example for the creation
17
 * of a cache backend instance. There is no specific initialization done during startup, to
18
 * allow the modules to do their own magic during startup (it is difficult to generalize such
19
 * stuff).
20
 *
21
 * @package midcom.services
22
 */
23
abstract class midcom_services_cache_module
24
{
25
    /**
26
     * A list of all backends created by _create_backend(). They will be automatically
27
     * shut down when the module shuts down. They are indexed by their name.
28
     *
29
     * @var Doctrine\Common\Cache\CacheProvider[]
30
     */
31
    protected $_backends = [];
32
33
    /**
34
     * The cache key prefix.
35
     *
36
     * @var string
37
     */
38
    protected $_prefix;
39
40
    /**
41
     * Initialize the module. This will initialize the class configuration
42
     * and call the corresponding event handler.
43
     */
44 1
    public function __construct()
45
    {
46 1
        $this->_prefix = get_class($this) . $_SERVER['SERVER_NAME'];
47 1
    }
48
49
    /**
50
     * Creates an instance of the handler described by the configuration passed to
51
     * the function.
52
     *
53
     * The configuration array must include the configuration parameters driver and
54
     * directory, as outlined in the midcom_services_cache_backend class documentation.
55
     *
56
     * All backends will be collected in the $_backends array, indexed by their name.
57
     *
58
     * Any duplicate instantiation will be intercepted, throwing a critical error.
59
     *
60
     * @param string $name The name of the backend, must be unique throughout the system.
61
     * @param array $config The configuration of the backend to create. It must contain
62
     *     the key 'driver', which indicates which backend to use.
63
     */
64 1
    protected function _create_backend($name, array $config) : CacheProvider
65
    {
66 1
        $name = $this->_prefix . $name;
67
68 1
        if (array_key_exists($name, $this->_backends)) {
69
            throw new midcom_error("Cannot create backend driver instance {$name}: A backend with this name does already exist.");
70
        }
71
72 1
        if (!array_key_exists('driver', $config)) {
73
            throw new midcom_error("Cannot create backend driver instance {$name}: The driver class is not specified in the configuration.");
74
        }
75
76 1
        if (is_string($config['driver'])) {
77 1
            $backend = $this->prepare_backend($config, $name);
78
        } else {
79
            $backend = $config['driver'];
80
        }
81 1
        $backend->setNamespace($name);
82
83 1
        $this->_backends[$name] = $backend;
84
85 1
        return $backend;
86
    }
87
88 1
    private function prepare_backend(array $config, string $name) : CacheProvider
89
    {
90 1
        $directory = midcom::get()->getCacheDir();
91 1
        if (!empty($config['directory'])) {
92 1
            $directory .= '/' . $config['directory'];
93
        }
94 1
        $memcache_operational = false;
95 1
        switch ($config['driver']) {
96 1
            case 'apc':
97
                $backend = new Cache\ApcuCache();
98
                break;
99 1
            case 'memcached':
100 1
                $host = !empty($config['host']) ? $config['host'] : 'localhost';
101 1
                $port = !empty($config['port']) ? $config['port'] : 11211;
102 1
                $memcached = new Memcached;
103 1
                if (@$memcached->addServer($host, $port)) {
104 1
                    $backend = new Cache\MemcachedCache();
105 1
                    $backend->setMemcached($memcached);
106 1
                    $memcache_operational = true;
107 1
                    break;
108
                }
109
                midcom::get()->debug->log_php_error(MIDCOM_LOG_ERROR);
110
                debug_add("memcache: Failed to connect to {$host}:{$port}. Falling back to filecache", MIDCOM_LOG_ERROR);
111
                // fall-through
112
            case 'dba':
113
            case 'flatfile':
114
                $backend = new Cache\FilesystemCache($directory . '/' . $name);
115
                break;
116
            case 'sqlite':
117
                $sqlite = new SQLite3("{$directory}/{$name}.db");
118
                $table = str_replace(['.', '-'], '_', $name);
119
                $backend = new Cache\SQLite3Cache($sqlite, $table);
120
                break;
121
            case 'null':
122
            default:
123
                $backend = new Cache\VoidCache();
124
                break;
125
        }
126
127 1
        $cache = new Cache\ChainCache([new Cache\ArrayCache, $backend]);
128 1
        $cache->memcache_operational = $memcache_operational;
0 ignored issues
show
Bug introduced by
The property memcache_operational does not seem to exist on Doctrine\Common\Cache\ChainCache.
Loading history...
129 1
        return $cache;
130
    }
131
132
    /**
133
     * Invalidate the cache completely, dropping all entries. The default implementation will
134
     * drop all entries from all registered cache backends using CacheProvider::flushAll().
135
     * Override this function if this behavior doesn't suit your needs.
136
     */
137
    public function invalidate_all()
138
    {
139
        foreach ($this->_backends as $name => $backend) {
140
            debug_add("Invalidating cache backend {$name}...", MIDCOM_LOG_INFO);
141
            $backend->flushAll();
142
        }
143
    }
144
145
    /**
146
     * Invalidate all cache objects related to the given GUID.
147
     *
148
     * @param string $guid The GUID that has to be invalidated.
149
     * @param object $object The object that has to be invalidated (if available).
150
     */
151
    abstract public function invalidate($guid, $object = null);
152
}
153