cache.inc 5.8 KB

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