UrlCacheManager.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. /**
  3. * This class will statically hold in memory url's indexed by a custom hash
  4. *
  5. * @licence MIT
  6. * @modified Mark Scherer
  7. * - now easier to integrate
  8. * - optimization for `pageFiles` (still stores urls with only controller/action keys in global file)
  9. * - can handle legacy `prefix` urls
  10. *
  11. */
  12. class UrlCacheManager {
  13. /**
  14. * Holds all generated urls so far by the application indexed by a custom hash
  15. *
  16. */
  17. public static $cache = array();
  18. /**
  19. * Holds all generated urls so far by the application indexed by a custom hash
  20. *
  21. */
  22. public static $cachePage = array();
  23. /**
  24. * Holds all generated urls so far by the application indexed by a custom hash
  25. *
  26. */
  27. public static $extras = array();
  28. /**
  29. * Type for the current set (triggered by last get)
  30. */
  31. public static $type = 'cache';
  32. /**
  33. * Key for current get/set
  34. */
  35. public static $key = null;
  36. /**
  37. * Cache key for pageFiles
  38. */
  39. public static $cacheKey = 'url_map';
  40. /**
  41. * Cache key for pageFiles
  42. */
  43. public static $cachePageKey = null;
  44. /**
  45. * Params that will always be present and will determine the global cache if pageFiles is used
  46. */
  47. public static $paramFields = array('controller', 'plugin', 'action', 'prefix');
  48. /**
  49. * Should be called in beforeRender()
  50. *
  51. */
  52. public static function init(View $View) {
  53. $params = $View->request->params;
  54. if (Configure::read('UrlCache.pageFiles')) {
  55. $cachePageKey = '_misc';
  56. if (is_object($View)) {
  57. $path = $View->request->here;
  58. if ($path === '/') {
  59. $path = 'uc_homepage';
  60. } else {
  61. $path = strtolower(Inflector::slug($path));
  62. }
  63. if (empty($path)) {
  64. $path = 'uc_error';
  65. }
  66. $cachePageKey = '_' . $path;
  67. }
  68. self::$cachePageKey = self::$cacheKey . $cachePageKey;
  69. self::$cachePage = Cache::read(self::$cachePageKey, '_cake_core_');
  70. }
  71. self::$cache = Cache::read(self::$cacheKey, '_cake_core_');
  72. # still old "prefix true/false" syntax?
  73. if (Configure::read('UrlCache.verbosePrefixes')) {
  74. unset(self::$paramFields[3]);
  75. self::$paramFields = array_merge(self::$paramFields, (array)Configure::read('Routing.prefixes'));
  76. }
  77. self::$extras = array_intersect_key($params, array_combine(self::$paramFields, self::$paramFields));
  78. $defaults = array();
  79. foreach (self::$paramFields as $field) {
  80. $defaults[$field] = '';
  81. }
  82. self::$extras = array_merge($defaults, self::$extras);
  83. }
  84. /**
  85. * Should be called in afterLayout()
  86. *
  87. */
  88. public static function finalize() {
  89. Cache::write(self::$cacheKey, self::$cache, '_cake_core_');
  90. if (Configure::read('UrlCache.pageFiles') && !empty(self::$cachePage)) {
  91. Cache::write(self::$cachePageKey, self::$cachePage, '_cake_core_');
  92. }
  93. }
  94. /**
  95. * Returns the stored url if it was already generated, false otherwise
  96. *
  97. * @param string $key
  98. * @return mixed
  99. */
  100. public static function get($url, $full) {
  101. $keyUrl = $url;
  102. if (is_array($keyUrl)) {
  103. $keyUrl += self::$extras;
  104. # prevent different hashs on different orders
  105. ksort($keyUrl, SORT_STRING);
  106. # prevent different hashs on different types (int/string/bool)
  107. foreach ($keyUrl as $key => $val) {
  108. $keyUrl[$key] = (string) $val;
  109. }
  110. }
  111. self::$key = md5(serialize($keyUrl) . $full);
  112. if (Configure::read('UrlCache.pageFiles')) {
  113. self::$type = 'cachePage';
  114. if (is_array($keyUrl)) {
  115. $res = array_diff_key($keyUrl, self::$extras);
  116. if (empty($res)) {
  117. self::$type = 'cache';
  118. }
  119. }
  120. if (self::$type === 'cachePage') {
  121. return isset(self::$cachePage[self::$key]) ? self::$cachePage[self::$key] : false;
  122. }
  123. }
  124. return isset(self::$cache[self::$key]) ? self::$cache[self::$key] : false;
  125. }
  126. /**
  127. * Stores a ney key in memory cache
  128. *
  129. * @param string $key
  130. * @param mixed data to be stored
  131. * @return void
  132. */
  133. public static function set($data) {
  134. if (Configure::read('UrlCache.pageFiles') && self::$type === 'cachePage') {
  135. self::$cachePage[self::$key] = $data;
  136. } else {
  137. self::$cache[self::$key] = $data;
  138. }
  139. }
  140. }