Passed
Push — master ( 788146...671601 )
by Andreas
23:40
created

midcom_services_cache_module_memcache   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 116
Duplicated Lines 0 %

Test Coverage

Coverage 58.81%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 29
dl 0
loc 116
ccs 20
cts 34
cp 0.5881
rs 10
c 1
b 0
f 0
wmc 13

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 2
A lookup_parent_data() 0 3 1
A invalidate() 0 9 4
A update_parent_data() 0 3 1
A put() 0 14 3
A get() 0 7 2
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 __construct(midcom_config $config)
66
    {
67
        parent::__construct();
68
        if ($driver = $config->get('cache_module_memcache_backend')) {
69
            $this->_data_groups = $config->get('cache_module_memcache_data_groups');
70
            $backend_config = $config->get('cache_module_memcache_backend_config');
71
            $backend_config['driver'] = $driver;
72
            $this->_cache = $this->_create_backend('module_memcache', $backend_config);
0 ignored issues
show
Bug introduced by
It seems like $backend_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

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