danielebarchiesi@0
|
1 <?php
|
danielebarchiesi@0
|
2
|
danielebarchiesi@0
|
3 /**
|
danielebarchiesi@0
|
4 * @file
|
danielebarchiesi@0
|
5 * The non-volatile object cache is used to store an object while it is
|
danielebarchiesi@0
|
6 * being edited, so that we don't have to save until we're completely
|
danielebarchiesi@0
|
7 * done. The cache should be 'cleaned' on a regular basis, meaning to
|
danielebarchiesi@0
|
8 * remove old objects from the cache, but otherwise the data in this
|
danielebarchiesi@0
|
9 * cache must remain stable, as it includes unsaved changes.
|
danielebarchiesi@0
|
10 */
|
danielebarchiesi@0
|
11
|
danielebarchiesi@0
|
12 /**
|
danielebarchiesi@0
|
13 * Get an object from the non-volatile ctools cache.
|
danielebarchiesi@0
|
14 *
|
danielebarchiesi@0
|
15 * This function caches in memory as well, so that multiple calls to this
|
danielebarchiesi@0
|
16 * will not result in multiple database reads.
|
danielebarchiesi@0
|
17 *
|
danielebarchiesi@0
|
18 * @param $obj
|
danielebarchiesi@0
|
19 * A 128 character or less string to define what kind of object is being
|
danielebarchiesi@0
|
20 * stored; primarily this is used to prevent collisions.
|
danielebarchiesi@0
|
21 * @param $name
|
danielebarchiesi@0
|
22 * The name of the object being stored.
|
danielebarchiesi@0
|
23 * @param $skip_cache
|
danielebarchiesi@0
|
24 * Skip the memory cache, meaning this must be read from the db again.
|
danielebarchiesi@0
|
25 * @param $sid
|
danielebarchiesi@0
|
26 * The session id, allowing someone to use Session API or their own solution;
|
danielebarchiesi@0
|
27 * defaults to session_id().
|
danielebarchiesi@0
|
28 *
|
danielebarchiesi@0
|
29 * @deprecated $skip_cache is deprecated in favor of drupal_static*
|
danielebarchiesi@0
|
30 * @return
|
danielebarchiesi@0
|
31 * The data that was cached.
|
danielebarchiesi@0
|
32 */
|
danielebarchiesi@0
|
33 function ctools_object_cache_get($obj, $name, $skip_cache = FALSE, $sid = NULL) {
|
danielebarchiesi@0
|
34 $cache = &drupal_static(__FUNCTION__, array());
|
danielebarchiesi@0
|
35 $key = "$obj:$name";
|
danielebarchiesi@0
|
36 if ($skip_cache) {
|
danielebarchiesi@0
|
37 unset($cache[$key]);
|
danielebarchiesi@0
|
38 }
|
danielebarchiesi@0
|
39
|
danielebarchiesi@0
|
40 if (!$sid) {
|
danielebarchiesi@0
|
41 $sid = session_id();
|
danielebarchiesi@0
|
42 }
|
danielebarchiesi@0
|
43
|
danielebarchiesi@0
|
44 if (!array_key_exists($key, $cache)) {
|
danielebarchiesi@0
|
45 $data = db_query('SELECT * FROM {ctools_object_cache} WHERE sid = :session_id AND obj = :object AND name = :name', array(':session_id' => $sid, ':object' => $obj, ':name' => $name))
|
danielebarchiesi@0
|
46 ->fetchObject();
|
danielebarchiesi@0
|
47 if ($data) {
|
danielebarchiesi@0
|
48 $cache[$key] = unserialize($data->data);
|
danielebarchiesi@0
|
49 }
|
danielebarchiesi@0
|
50 }
|
danielebarchiesi@0
|
51 return isset($cache[$key]) ? $cache[$key] : NULL;
|
danielebarchiesi@0
|
52 }
|
danielebarchiesi@0
|
53
|
danielebarchiesi@0
|
54 /**
|
danielebarchiesi@0
|
55 * Store an object in the non-volatile ctools cache.
|
danielebarchiesi@0
|
56 *
|
danielebarchiesi@0
|
57 * @param $obj
|
danielebarchiesi@0
|
58 * A 128 character or less string to define what kind of object is being
|
danielebarchiesi@0
|
59 * stored; primarily this is used to prevent collisions.
|
danielebarchiesi@0
|
60 * @param $name
|
danielebarchiesi@0
|
61 * The name of the object being stored.
|
danielebarchiesi@0
|
62 * @param $cache
|
danielebarchiesi@0
|
63 * The object to be cached. This will be serialized prior to writing.
|
danielebarchiesi@0
|
64 * @param $sid
|
danielebarchiesi@0
|
65 * The session id, allowing someone to use Session API or their own solution;
|
danielebarchiesi@0
|
66 * defaults to session_id().
|
danielebarchiesi@0
|
67 */
|
danielebarchiesi@0
|
68 function ctools_object_cache_set($obj, $name, $cache, $sid = NULL) {
|
danielebarchiesi@0
|
69 // Store the CTools session id in the user session to force a
|
danielebarchiesi@0
|
70 // session for anonymous users in Drupal 7 and Drupal 6 Pressflow.
|
danielebarchiesi@0
|
71 // see http://drupal.org/node/562374, http://drupal.org/node/861778
|
danielebarchiesi@0
|
72 if (empty($GLOBALS['user']->uid) && empty($_SESSION['ctools_session_id'])) {
|
danielebarchiesi@0
|
73 $_SESSION['ctools_hold_session'] = TRUE;
|
danielebarchiesi@0
|
74 }
|
danielebarchiesi@0
|
75
|
danielebarchiesi@0
|
76 ctools_object_cache_clear($obj, $name, $sid);
|
danielebarchiesi@0
|
77
|
danielebarchiesi@0
|
78 if (!$sid) {
|
danielebarchiesi@0
|
79 $sid = session_id();
|
danielebarchiesi@0
|
80 }
|
danielebarchiesi@0
|
81
|
danielebarchiesi@0
|
82 db_insert('ctools_object_cache')
|
danielebarchiesi@0
|
83 ->fields(array(
|
danielebarchiesi@0
|
84 'sid' => $sid,
|
danielebarchiesi@0
|
85 'obj' => $obj,
|
danielebarchiesi@0
|
86 'name' => $name,
|
danielebarchiesi@0
|
87 'data' => serialize($cache),
|
danielebarchiesi@0
|
88 'updated' => REQUEST_TIME,
|
danielebarchiesi@0
|
89 ))
|
danielebarchiesi@0
|
90 ->execute();
|
danielebarchiesi@0
|
91 }
|
danielebarchiesi@0
|
92
|
danielebarchiesi@0
|
93 /**
|
danielebarchiesi@0
|
94 * Remove an object from the non-volatile ctools cache
|
danielebarchiesi@0
|
95 *
|
danielebarchiesi@0
|
96 * @param $obj
|
danielebarchiesi@0
|
97 * A 128 character or less string to define what kind of object is being
|
danielebarchiesi@0
|
98 * stored; primarily this is used to prevent collisions.
|
danielebarchiesi@0
|
99 * @param $name
|
danielebarchiesi@0
|
100 * The name of the object being removed.
|
danielebarchiesi@0
|
101 * @param $sid
|
danielebarchiesi@0
|
102 * The session id, allowing someone to use Session API or their own solution;
|
danielebarchiesi@0
|
103 * defaults to session_id().
|
danielebarchiesi@0
|
104 */
|
danielebarchiesi@0
|
105 function ctools_object_cache_clear($obj, $name, $sid = NULL) {
|
danielebarchiesi@0
|
106
|
danielebarchiesi@0
|
107 if (!$sid) {
|
danielebarchiesi@0
|
108 $sid = session_id();
|
danielebarchiesi@0
|
109 }
|
danielebarchiesi@0
|
110
|
danielebarchiesi@0
|
111 db_delete('ctools_object_cache')
|
danielebarchiesi@0
|
112 ->condition('sid', $sid)
|
danielebarchiesi@0
|
113 ->condition('obj', $obj)
|
danielebarchiesi@0
|
114 ->condition('name', $name)
|
danielebarchiesi@0
|
115 ->execute();
|
danielebarchiesi@0
|
116 // Ensure the static cache is emptied of this obj:name set.
|
danielebarchiesi@0
|
117 drupal_static_reset('ctools_object_cache_get');
|
danielebarchiesi@0
|
118 }
|
danielebarchiesi@0
|
119
|
danielebarchiesi@0
|
120
|
danielebarchiesi@0
|
121 /**
|
danielebarchiesi@0
|
122 * Determine if another user has a given object cached.
|
danielebarchiesi@0
|
123 *
|
danielebarchiesi@0
|
124 * This is very useful for 'locking' objects so that only one user can
|
danielebarchiesi@0
|
125 * modify them.
|
danielebarchiesi@0
|
126 *
|
danielebarchiesi@0
|
127 * @param $obj
|
danielebarchiesi@0
|
128 * A 128 character or less string to define what kind of object is being
|
danielebarchiesi@0
|
129 * stored; primarily this is used to prevent collisions.
|
danielebarchiesi@0
|
130 * @param $name
|
danielebarchiesi@0
|
131 * The name of the object being removed.
|
danielebarchiesi@0
|
132 * @param $sid
|
danielebarchiesi@0
|
133 * The session id, allowing someone to use Session API or their own solution;
|
danielebarchiesi@0
|
134 * defaults to session_id().
|
danielebarchiesi@0
|
135 *
|
danielebarchiesi@0
|
136 * @return
|
danielebarchiesi@0
|
137 * An object containing the UID and updated date if found; NULL if not.
|
danielebarchiesi@0
|
138 */
|
danielebarchiesi@0
|
139 function ctools_object_cache_test($obj, $name, $sid = NULL) {
|
danielebarchiesi@0
|
140
|
danielebarchiesi@0
|
141 if (!$sid) {
|
danielebarchiesi@0
|
142 $sid = session_id();
|
danielebarchiesi@0
|
143 }
|
danielebarchiesi@0
|
144
|
danielebarchiesi@0
|
145 return db_query('SELECT s.uid, c.updated FROM {ctools_object_cache} c INNER JOIN {sessions} s ON c.sid = s.sid WHERE s.sid <> :session_id AND c.obj = :obj AND c.name = :name ORDER BY c.updated ASC', array(':session_id' => $sid, ':obj' => $obj, ':name' => $name))
|
danielebarchiesi@0
|
146 ->fetchObject();
|
danielebarchiesi@0
|
147 }
|
danielebarchiesi@0
|
148
|
danielebarchiesi@0
|
149 /**
|
danielebarchiesi@0
|
150 * Get the cache status of a group of objects.
|
danielebarchiesi@0
|
151 *
|
danielebarchiesi@0
|
152 * This is useful for displaying lock status when listing a number of objects
|
danielebarchiesi@0
|
153 * an an administration UI.
|
danielebarchiesi@0
|
154 *
|
danielebarchiesi@0
|
155 * @param $obj
|
danielebarchiesi@0
|
156 * A 128 character or less string to define what kind of object is being
|
danielebarchiesi@0
|
157 * stored; primarily this is used to prevent collisions.
|
danielebarchiesi@0
|
158 * @param $names
|
danielebarchiesi@0
|
159 * An array of names of objects
|
danielebarchiesi@0
|
160 *
|
danielebarchiesi@0
|
161 * @return
|
danielebarchiesi@0
|
162 * An array of objects containing the UID and updated date for each name found.
|
danielebarchiesi@0
|
163 */
|
danielebarchiesi@0
|
164 function ctools_object_cache_test_objects($obj, $names) {
|
danielebarchiesi@0
|
165 return db_query("SELECT c.name, s.uid, c.updated FROM {ctools_object_cache} c INNER JOIN {sessions} s ON c.sid = s.sid WHERE c.obj = :obj AND c.name IN (:names) ORDER BY c.updated ASC", array(':obj' => $obj, ':names' => $names))
|
danielebarchiesi@0
|
166 ->fetchAllAssoc('name');
|
danielebarchiesi@0
|
167 }
|
danielebarchiesi@0
|
168
|
danielebarchiesi@0
|
169 /**
|
danielebarchiesi@0
|
170 * Remove an object from the non-volatile ctools cache for all session IDs.
|
danielebarchiesi@0
|
171 *
|
danielebarchiesi@0
|
172 * This is useful for clearing a lock.
|
danielebarchiesi@0
|
173 *
|
danielebarchiesi@0
|
174 * @param $obj
|
danielebarchiesi@0
|
175 * A 128 character or less string to define what kind of object is being
|
danielebarchiesi@0
|
176 * stored; primarily this is used to prevent collisions.
|
danielebarchiesi@0
|
177 * @param $name
|
danielebarchiesi@0
|
178 * The name of the object being removed.
|
danielebarchiesi@0
|
179 */
|
danielebarchiesi@0
|
180 function ctools_object_cache_clear_all($obj, $name) {
|
danielebarchiesi@0
|
181 db_delete('ctools_object_cache')
|
danielebarchiesi@0
|
182 ->condition('obj', $obj)
|
danielebarchiesi@0
|
183 ->condition('name', $name)
|
danielebarchiesi@0
|
184 ->execute();
|
danielebarchiesi@0
|
185 // Ensure the static cache is emptied of this obj:name set.
|
danielebarchiesi@0
|
186 $cache = &drupal_static('ctools_object_cache_get', array());
|
danielebarchiesi@0
|
187 unset($cache["$obj:$name"]);
|
danielebarchiesi@0
|
188 }
|
danielebarchiesi@0
|
189
|
danielebarchiesi@0
|
190 /**
|
danielebarchiesi@0
|
191 * Remove all objects in the object cache that are older than the
|
danielebarchiesi@0
|
192 * specified age.
|
danielebarchiesi@0
|
193 *
|
danielebarchiesi@0
|
194 * @param $age
|
danielebarchiesi@0
|
195 * The minimum age of objects to remove, in seconds. For example, 86400 is
|
danielebarchiesi@0
|
196 * one day. Defaults to 7 days.
|
danielebarchiesi@0
|
197 */
|
danielebarchiesi@0
|
198 function ctools_object_cache_clean($age = NULL) {
|
danielebarchiesi@0
|
199 if (empty($age)) {
|
danielebarchiesi@0
|
200 $age = 86400 * 7; // 7 days
|
danielebarchiesi@0
|
201 }
|
danielebarchiesi@0
|
202 db_delete('ctools_object_cache')
|
danielebarchiesi@0
|
203 ->condition('updated', REQUEST_TIME - $age, '<')
|
danielebarchiesi@0
|
204 ->execute();
|
danielebarchiesi@0
|
205 }
|