Passed
Pull Request — master (#204)
by
unknown
23:41
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 initialize()
45
    {
46 1
        $this->_prefix = get_class($this) . $_SERVER['SERVER_NAME'];
47 1
        $this->_on_initialize();
48 1
    }
49
50
    /**
51
     * Creates an instance of the handler described by the configuration passed to
52
     * the function.
53
     *
54
     * The configuration array must include the configuration parameters driver and
55
     * directory, as outlined in the midcom_services_cache_backend class documentation.
56
     *
57
     * All backends will be collected in the $_backends array, indexed by their name.
58
     *
59
     * Any duplicate instantiation will be intercepted, throwing a critical error.
60
     *
61
     * @param string $name The name of the backend, must be unique throughout the system.
62
     * @param array $config The configuration of the backend to create. It must contain
63
     *     the key 'driver', which indicates which backend to use.
64
     */
65 1
    protected function _create_backend($name, array $config) : CacheProvider
66
    {
67 1
        $name = $this->_prefix . $name;
68
69 1
        if (array_key_exists($name, $this->_backends)) {
70
            throw new midcom_error("Cannot create backend driver instance {$name}: A backend with this name does already exist.");
71
        }
72
73 1
        if (!array_key_exists('driver', $config)) {
74
            throw new midcom_error("Cannot create backend driver instance {$name}: The driver class is not specified in the configuration.");
75
        }
76
77 1
        if (is_string($config['driver'])) {
78 1
            $backend = $this->prepare_backend($config, $name);
79
        } else {
80
            $backend = $config['driver'];
81
        }
82 1
        $backend->setNamespace($name);
83
84 1
        $this->_backends[$name] = $backend;
85
86 1
        return $backend;
87
    }
88
89 1
    private function prepare_backend(array $config, string $name) : CacheProvider
90
    {
91 1
        $directory = midcom::get()->config->get('cache_base_directory');
92 1
        if (!empty($config['directory'])) {
93 1
            $directory .= $config['directory'];
94
        }
95 1
        $memcache_operational = false;
96 1
        switch ($config['driver']) {
97 1
            case 'apc':
98
                $backend = new Cache\ApcuCache();
99
                break;
100 1
            case 'memcached':
101 1
                $host = !empty($config['host']) ? $config['host'] : 'localhost';
102 1
                $port = !empty($config['port']) ? $config['port'] : 11211;
103 1
                $memcached = new Memcached;
104 1
                if (@$memcached->addServer($host, $port)) {
105 1
                    $backend = new Cache\MemcachedCache();
106 1
                    $backend->setMemcached($memcached);
107 1
                    $memcache_operational = true;
108 1
                    break;
109
                }
110
                midcom::get()->debug->log_php_error(MIDCOM_LOG_ERROR);
111
                debug_add("memcache: Failed to connect to {$host}:{$port}. Falling back to filecache", MIDCOM_LOG_ERROR);
112
                // fall-through
113
            case 'dba':
114
            case 'flatfile':
115
                $backend = new Cache\FilesystemCache($directory . $name);
116
                break;
117
            case 'sqlite':
118
                $sqlite = new SQLite3("{$directory}/{$name}.db");
119
                $table = str_replace(['.', '-'], '_', $name);
120
                $backend = new Cache\SQLite3Cache($sqlite, $table);
121
                break;
122
            case 'null':
123
            default:
124
                $backend = new Cache\VoidCache();
125
                break;
126
        }
127
128 1
        $cache = new Cache\ChainCache([new Cache\ArrayCache, $backend]);
129 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...
130 1
        return $cache;
131
    }
132
133
    /**
134
     * Invalidate the cache completely, dropping all entries. The default implementation will
135
     * drop all entries from all registered cache backends using CacheProvider::flushAll().
136
     * Override this function if this behavior doesn't suit your needs.
137
     */
138
    public function invalidate_all()
139
    {
140
        foreach ($this->_backends as $name => $backend) {
141
            debug_add("Invalidating cache backend {$name}...", MIDCOM_LOG_INFO);
142
            $backend->flushAll();
143
        }
144
    }
145
146
    /**
147
     * Startup handler, called during service start up at the start of the request.
148
     */
149
    abstract public function _on_initialize();
150
151
    /**
152
     * Invalidate all cache objects related to the given GUID.
153
     *
154
     * @param string $guid The GUID that has to be invalidated.
155
     * @param object $object The object that has to be invalidated (if available).
156
     */
157
    abstract public function invalidate($guid, $object = null);
158
}
159