danielebarchiesi@0
|
1 <?php
|
danielebarchiesi@0
|
2
|
danielebarchiesi@0
|
3 /**
|
danielebarchiesi@0
|
4 * @file
|
danielebarchiesi@0
|
5 *
|
danielebarchiesi@0
|
6 * Plugins to handle cache-indirection.
|
danielebarchiesi@0
|
7 *
|
danielebarchiesi@0
|
8 * Simple plugin management to allow clients to more tightly control where
|
danielebarchiesi@0
|
9 * object caches are stored.
|
danielebarchiesi@0
|
10 *
|
danielebarchiesi@0
|
11 * CTools provides an object cache mechanism, and it also provides a number
|
danielebarchiesi@0
|
12 * of subsystems that are designed to plug into larger systems. When doing
|
danielebarchiesi@0
|
13 * caching on multi-step forms (in particular during AJAX operations) these
|
danielebarchiesi@0
|
14 * subsystems often need to operate their own cache. In reality, its best
|
danielebarchiesi@0
|
15 * for everyone if they are able to piggyback off of the larger cache.
|
danielebarchiesi@0
|
16 *
|
danielebarchiesi@0
|
17 * This system allows this by registering plugins to control where caches
|
danielebarchiesi@0
|
18 * are actually stored. For the most part, the subsystems could care less
|
danielebarchiesi@0
|
19 * where the data is fetched from and stored to. All it needs to know is
|
danielebarchiesi@0
|
20 * that it can 'get', 'set' and 'clear' caches. Additionally, some caches
|
danielebarchiesi@0
|
21 * might need extra operations such as 'lock' and 'finalize', and other
|
danielebarchiesi@0
|
22 * operations may be needed based upon the specific uses for the cache
|
danielebarchiesi@0
|
23 * plugins.
|
danielebarchiesi@0
|
24 *
|
danielebarchiesi@0
|
25 * To utilize cache plugins, there are two pieces of data. First, there is
|
danielebarchiesi@0
|
26 * the mechanism, which is simply the name of the plugin to use. CTools
|
danielebarchiesi@0
|
27 * provides a 'simple' mechanism which goes straight through to the object
|
danielebarchiesi@0
|
28 * cache. The second piece of data is the 'key' which is a unique identifier
|
danielebarchiesi@0
|
29 * that can be used to find the data needed. Keys can be generated any number
|
danielebarchiesi@0
|
30 * of ways, and the plugin must be agnostic about the key itself.
|
danielebarchiesi@0
|
31 *
|
danielebarchiesi@0
|
32 * That said, the 'mechanism' can be specified as pluginame::data and that
|
danielebarchiesi@0
|
33 * data can be used to derive additional data. For example, it is often
|
danielebarchiesi@0
|
34 * desirable to NOT store any cached data until original data (i.e, user
|
danielebarchiesi@0
|
35 * input) has been received. The data can be used to derive this original
|
danielebarchiesi@0
|
36 * data so that when a 'get' is called, if the cache is missed it can create
|
danielebarchiesi@0
|
37 * the data needed. This can help prevent unwanted cache entries from
|
danielebarchiesi@0
|
38 * building up just by visiting edit UIs without actually modifying anything.
|
danielebarchiesi@0
|
39 *
|
danielebarchiesi@0
|
40 * Modules wishing to implement cache indirection mechanisms need to implement
|
danielebarchiesi@0
|
41 * a plugin of type 'cache' for the module 'ctools' and provide the .inc file.
|
danielebarchiesi@0
|
42 * It should provide callbacks for 'cache set', 'cache get', and 'cache clear'.
|
danielebarchiesi@0
|
43 * It can provide callbacks for 'break' and 'finalize' if these are relevant
|
danielebarchiesi@0
|
44 * to the caching mechanism (i.e, for use with locking caches such as the page
|
danielebarchiesi@0
|
45 * manager cache). Other operations may be utilized but at this time are not part
|
danielebarchiesi@0
|
46 * of CTools.
|
danielebarchiesi@0
|
47 */
|
danielebarchiesi@0
|
48
|
danielebarchiesi@0
|
49 /**
|
danielebarchiesi@0
|
50 * Fetch data from an indirect cache.
|
danielebarchiesi@0
|
51 *
|
danielebarchiesi@0
|
52 * @param string $mechanism
|
danielebarchiesi@0
|
53 * A string containing the plugin name, and an optional data element to
|
danielebarchiesi@0
|
54 * send to the plugin separated by two colons.
|
danielebarchiesi@0
|
55 *
|
danielebarchiesi@0
|
56 * @param string $key
|
danielebarchiesi@0
|
57 * The key used to identify the cache.
|
danielebarchiesi@0
|
58 *
|
danielebarchiesi@0
|
59 * @return mixed
|
danielebarchiesi@0
|
60 * The cached data. This can be any format as the plugin does not necessarily
|
danielebarchiesi@0
|
61 * have knowledge of what is being cached.
|
danielebarchiesi@0
|
62 */
|
danielebarchiesi@0
|
63 function ctools_cache_get($mechanism, $key) {
|
danielebarchiesi@0
|
64 return ctools_cache_operation($mechanism, $key, 'get');
|
danielebarchiesi@0
|
65 }
|
danielebarchiesi@0
|
66
|
danielebarchiesi@0
|
67 /**
|
danielebarchiesi@0
|
68 * Store data in an indirect cache.
|
danielebarchiesi@0
|
69 *
|
danielebarchiesi@0
|
70 * @param string $mechanism
|
danielebarchiesi@0
|
71 * A string containing the plugin name, and an optional data element to
|
danielebarchiesi@0
|
72 * send to the plugin separated by two colons.
|
danielebarchiesi@0
|
73 *
|
danielebarchiesi@0
|
74 * @param string $key
|
danielebarchiesi@0
|
75 * The key used to identify the cache.
|
danielebarchiesi@0
|
76 *
|
danielebarchiesi@0
|
77 * @param mixed $object
|
danielebarchiesi@0
|
78 * The data to cache. This can be any format as the plugin does not
|
danielebarchiesi@0
|
79 * necessarily have knowledge of what is being cached.
|
danielebarchiesi@0
|
80 */
|
danielebarchiesi@0
|
81 function ctools_cache_set($mechanism, $key, $object) {
|
danielebarchiesi@0
|
82 return ctools_cache_operation($mechanism, $key, 'set', $object);
|
danielebarchiesi@0
|
83 }
|
danielebarchiesi@0
|
84
|
danielebarchiesi@0
|
85 /**
|
danielebarchiesi@0
|
86 * Clear data from an indirect cache.
|
danielebarchiesi@0
|
87 *
|
danielebarchiesi@0
|
88 * @param string $mechanism
|
danielebarchiesi@0
|
89 * A string containing the plugin name, and an optional data element to
|
danielebarchiesi@0
|
90 * send to the plugin separated by two colons.
|
danielebarchiesi@0
|
91 *
|
danielebarchiesi@0
|
92 * @param string $key
|
danielebarchiesi@0
|
93 * The key used to identify the cache.
|
danielebarchiesi@0
|
94 */
|
danielebarchiesi@0
|
95 function ctools_cache_clear($mechanism, $key) {
|
danielebarchiesi@0
|
96 return ctools_cache_operation($mechanism, $key, 'clear');
|
danielebarchiesi@0
|
97
|
danielebarchiesi@0
|
98 }
|
danielebarchiesi@0
|
99
|
danielebarchiesi@0
|
100 /**
|
danielebarchiesi@0
|
101 * Perform a secondary operation on an indirect cache.
|
danielebarchiesi@0
|
102 *
|
danielebarchiesi@0
|
103 * Additional operations, beyond get, set and clear may be items
|
danielebarchiesi@0
|
104 * such as 'break' and 'finalize', which are needed to support cache
|
danielebarchiesi@0
|
105 * locking. Other operations may be added by users of the indirect
|
danielebarchiesi@0
|
106 * caching functions as needed.
|
danielebarchiesi@0
|
107 *
|
danielebarchiesi@0
|
108 * @param string $mechanism
|
danielebarchiesi@0
|
109 * A string containing the plugin name, and an optional data element to
|
danielebarchiesi@0
|
110 * send to the plugin separated by two colons.
|
danielebarchiesi@0
|
111 *
|
danielebarchiesi@0
|
112 * @param string $key
|
danielebarchiesi@0
|
113 * The key used to identify the cache.
|
danielebarchiesi@0
|
114 *
|
danielebarchiesi@0
|
115 * @param string $op
|
danielebarchiesi@0
|
116 * The operation to call, such as 'break' or 'finalize'.
|
danielebarchiesi@0
|
117 *
|
danielebarchiesi@0
|
118 * @param mixed $object
|
danielebarchiesi@0
|
119 * The cache data being operated on, in case it is necessary. This is
|
danielebarchiesi@0
|
120 * optional so no references should be used.
|
danielebarchiesi@0
|
121 *
|
danielebarchiesi@0
|
122 * @return mixed
|
danielebarchiesi@0
|
123 * The operation may or may not return a value.
|
danielebarchiesi@0
|
124 */
|
danielebarchiesi@0
|
125 function ctools_cache_operation($mechanism, $key, $op, $object = NULL) {
|
danielebarchiesi@0
|
126 list($plugin, $data) = ctools_cache_find_plugin($mechanism);
|
danielebarchiesi@0
|
127 if (empty($plugin)) {
|
danielebarchiesi@0
|
128 return;
|
danielebarchiesi@0
|
129 }
|
danielebarchiesi@0
|
130
|
danielebarchiesi@0
|
131 $function = ctools_plugin_get_function($plugin, "cache $op");
|
danielebarchiesi@0
|
132 if (empty($function)) {
|
danielebarchiesi@0
|
133 return;
|
danielebarchiesi@0
|
134 }
|
danielebarchiesi@0
|
135
|
danielebarchiesi@0
|
136 return $function($data, $key, $object, $op);
|
danielebarchiesi@0
|
137 }
|
danielebarchiesi@0
|
138
|
danielebarchiesi@0
|
139 /**
|
danielebarchiesi@0
|
140 * Take a mechanism and return a plugin and data.
|
danielebarchiesi@0
|
141 *
|
danielebarchiesi@0
|
142 * @param string $mechanism
|
danielebarchiesi@0
|
143 * A string containing the plugin name, and an optional data element to
|
danielebarchiesi@0
|
144 * send to the plugin separated by two colons.
|
danielebarchiesi@0
|
145 *
|
danielebarchiesi@0
|
146 * @return array
|
danielebarchiesi@0
|
147 * An array, the first element will be the plugin and the second element
|
danielebarchiesi@0
|
148 * will be the data. If the plugin could not be found, the $plugin will
|
danielebarchiesi@0
|
149 * be NULL.
|
danielebarchiesi@0
|
150 */
|
danielebarchiesi@0
|
151 function ctools_cache_find_plugin($mechanism) {
|
danielebarchiesi@0
|
152 if (strpos($mechanism, '::') !== FALSE) {
|
danielebarchiesi@0
|
153 // use explode(2) to ensure that the data can contain double
|
danielebarchiesi@0
|
154 // colons, just in case.
|
danielebarchiesi@0
|
155 list($name, $data) = explode('::', $mechanism, 2);
|
danielebarchiesi@0
|
156 }
|
danielebarchiesi@0
|
157 else {
|
danielebarchiesi@0
|
158 $name = $mechanism;
|
danielebarchiesi@0
|
159 $data = '';
|
danielebarchiesi@0
|
160 }
|
danielebarchiesi@0
|
161
|
danielebarchiesi@0
|
162 if (empty($name)) {
|
danielebarchiesi@0
|
163 return array(NULL, $data);
|
danielebarchiesi@0
|
164 }
|
danielebarchiesi@0
|
165
|
danielebarchiesi@0
|
166 ctools_include('plugins');
|
danielebarchiesi@0
|
167 $plugin = ctools_get_plugins('ctools', 'cache', $name);
|
danielebarchiesi@0
|
168 return array($plugin, $data);
|
danielebarchiesi@0
|
169 }
|