Passed
Pull Request — master (#204)
by
unknown
23:41
created

_on_initialize()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 7
ccs 0
cts 6
cp 0
crap 6
rs 10
c 0
b 0
f 0
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
/**
10
 * The Memory caching system is geared to hold needed information available quickly.
11
 * There are a number of limitations you have to deal with, when working with the
12
 * Memory Cache.
13
 *
14
 * Number One, you cannot put arbitrary keys into the cache. Since the memcached
15
 * php extension does not support key listings, you are bound to use MidCOM object
16
 * GUIDs as cache keys, whatever you do. To allow for different subsystems of the
17
 * Framework to share the cache, I have introduce "Data groups", which are suffixes
18
 * for the actual cache information. Thus, all keys in the cache follow a
19
 * "{$datagroup}-{$guid}" naming scheme. These groups need to be registered in the
20
 * MidCOM configuration key <i>cache_module_memcache_data_groups</i>.
21
 *
22
 * Number Two, it is entirely possible (as it is the default), that the memcache
23
 * is actually not available, as no memcache daemon has been found.  This is
24
 * controlled by the <i>cache_module_memcache_backend</i> configuration option,
25
 * which tries to auto-detect a sensible default. If it is set to the name of a caching module
26
 * it will actually start caching. Otherwise it will silently ignore
27
 * put requests, and reports all keys as not existent.
28
 *
29
 * Number Three, as at least memcache's contains() check isn't working on some machines, key
30
 * values of false are forbidden, as they are used to check a keys existence
31
 * during the get cycle. You should also avoid null and 0 members, if possible,
32
 * they could naturally be error prone if you start forgetting about the typed
33
 * comparisons.
34
 *
35
 * <b>Special functionality</b>
36
 *
37
 * - Interface to the PARENT caching group, has a few simple shortcuts to the
38
 *   access the available information.
39
 *
40
 * @package midcom.services
41
 */
42
class midcom_services_cache_module_memcache extends midcom_services_cache_module
43
{
44
    /**
45
     * List of known data groups. See the class introduction for details.
46
     *
47
     * @var Array
48
     */
49
    private $_data_groups = [];
50
51
    /**
52
     * The cache backend instance to use.
53
     *
54
     * @var Doctrine\Common\Cache\CacheProvider
55
     */
56
    private $_cache;
57
58
    /**
59
     * Initialization event handler.
60
     *
61
     * It will load the cache backend.
62
     *
63
     * Initializes the backend configuration.
64
     */
65
    public function _on_initialize()
66
    {
67
        if ($driver = midcom::get()->config->get('cache_module_memcache_backend')) {
68
            $this->_data_groups = midcom::get()->config->get('cache_module_memcache_data_groups');
69
            $config = midcom::get()->config->get('cache_module_memcache_backend_config');
70
            $config['driver'] = $driver;
71
            $this->_cache = $this->_create_backend('module_memcache', $config);
0 ignored issues
show
Bug introduced by
It seems like $config can also be of type null; however, parameter $config of midcom_services_cache_module::_create_backend() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

71
            $this->_cache = $this->_create_backend('module_memcache', /** @scrutinizer ignore-type */ $config);
Loading history...
72
        }
73
    }
74
75 1
    public function is_operational() : bool
76
    {
77 1
        return !empty($this->_cache->memcache_operational);
78
    }
79
80
    /**
81
     * {@inheritDoc}
82
     */
83 285
    public function invalidate($guid, $object = null)
84
    {
85 285
        if ($this->_cache !== null) {
86 285
            foreach ($this->_data_groups as $group) {
87 285
                if ($group == 'ACL') {
88 285
                    $this->_cache->delete("{$group}-SELF::{$guid}");
89 285
                    $this->_cache->delete("{$group}-CONTENT::{$guid}");
90
                } else {
91 285
                    $this->_cache->delete("{$group}-{$guid}");
92
                }
93
            }
94
        }
95 285
    }
96
97
    /**
98
     * Looks up a value in the cache and returns it. Not existent
99
     * keys are caught in this call as well
100
     *
101
     * @param string $data_group The Data Group to look in.
102
     * @param string $key The key to look up.
103
     * @return mixed The cached value on success, false on failure.
104
     */
105 306
    public function get($data_group, $key)
106
    {
107 306
        if ($this->_cache === null) {
108
            return false;
109
        }
110
111 306
        return $this->_cache->fetch("{$data_group}-{$key}");
112
    }
113
114
    /**
115
     * Sets a given key in the cache. If the data group is unknown, a Warning-Level error
116
     * is logged and putting is denied.
117
     *
118
     * @param string $data_group The Data Group to look in.
119
     * @param string $key The key to look up.
120
     * @param mixed $data The data to store.
121
     * @param int $timeout how long the data should live in the cache.
122
     */
123 296
    public function put($data_group, $key, $data, $timeout = 0)
124
    {
125 296
        if ($this->_cache === null) {
126
            return;
127
        }
128
129 296
        if (!in_array($data_group, $this->_data_groups)) {
130
            debug_add("Tried to add data to the unknown data group {$data_group}, cannot do that.", MIDCOM_LOG_WARN);
131
            debug_print_r('Known data groups:', $this->_data_groups);
132
            debug_print_function_stack('We were called from here:');
133
            return;
134
        }
135
136 296
        $this->_cache->save("{$data_group}-{$key}", $data, $timeout);
137 296
    }
138
139
    /**
140
     * This is a little helper that tries to look up a GUID in the memory
141
     * cache's PARENT data group. If it is not found, false is returned.
142
     * If the object has no parent, the array value is null
143
     *
144
     * @param string $guid The guid of which a parent is searched.
145
     * @return array|false The classname => GUID pair or false when nothing is in cache
146
     */
147 281
    public function lookup_parent_data($guid)
148
    {
149 281
        return $this->get('PARENT', $guid);
150
    }
151
152
    /**
153
     * This is a little helper that saves a parent GUID and class in the memory
154
     * cache's PARENT data group.
155
     *
156
     * @param string $object_guid The guid of which a parent is saved.
157
     * @param array $parent_data The guid and classname of the parent which is saved.
158
     */
159 281
    public function update_parent_data($object_guid, array $parent_data)
160
    {
161 281
        $this->put('PARENT', $object_guid, $parent_data);
162 281
    }
163
}
164