CachingSiteStore.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. /**
  3. * Represents the site configuration of a wiki.
  4. * Holds a list of sites (ie SiteList), with a caching layer.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. * http://www.gnu.org/copyleft/gpl.html
  20. *
  21. * @since 1.25
  22. *
  23. * @file
  24. * @ingroup Site
  25. *
  26. * @license GPL-2.0-or-later
  27. * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  28. * @author Katie Filbert < aude.wiki@gmail.com >
  29. */
  30. class CachingSiteStore implements SiteStore {
  31. /**
  32. * @var SiteList|null
  33. */
  34. private $sites = null;
  35. /**
  36. * @var string|null
  37. */
  38. private $cacheKey;
  39. /**
  40. * @var int
  41. */
  42. private $cacheTimeout;
  43. /**
  44. * @var BagOStuff
  45. */
  46. private $cache;
  47. /**
  48. * @var SiteStore
  49. */
  50. private $siteStore;
  51. /**
  52. * @param SiteStore $siteStore
  53. * @param BagOStuff $cache
  54. * @param string|null $cacheKey
  55. * @param int $cacheTimeout
  56. */
  57. public function __construct(
  58. SiteStore $siteStore,
  59. BagOStuff $cache,
  60. $cacheKey = null,
  61. $cacheTimeout = 3600
  62. ) {
  63. $this->siteStore = $siteStore;
  64. $this->cache = $cache;
  65. $this->cacheKey = $cacheKey;
  66. $this->cacheTimeout = $cacheTimeout;
  67. }
  68. /**
  69. * Constructs a cache key to use for caching the list of sites.
  70. *
  71. * This includes the concrete class name of the site list as well as a version identifier
  72. * for the list's serialization, to avoid problems when unserializing site lists serialized
  73. * by an older version, e.g. when reading from a cache.
  74. *
  75. * The cache key also includes information about where the sites were loaded from, e.g.
  76. * the name of a database table.
  77. *
  78. * @see SiteList::getSerialVersionId
  79. *
  80. * @return string The cache key.
  81. */
  82. private function getCacheKey() {
  83. if ( $this->cacheKey === null ) {
  84. $type = 'SiteList#' . SiteList::getSerialVersionId();
  85. $this->cacheKey = $this->cache->makeKey( "sites/$type" );
  86. }
  87. return $this->cacheKey;
  88. }
  89. /**
  90. * @see SiteStore::getSites
  91. *
  92. * @since 1.25
  93. *
  94. * @return SiteList
  95. */
  96. public function getSites() {
  97. if ( $this->sites === null ) {
  98. $this->sites = $this->cache->get( $this->getCacheKey() );
  99. if ( !is_object( $this->sites ) ) {
  100. $this->sites = $this->siteStore->getSites();
  101. $this->cache->set( $this->getCacheKey(), $this->sites, $this->cacheTimeout );
  102. }
  103. }
  104. return $this->sites;
  105. }
  106. /**
  107. * @see SiteStore::getSite
  108. *
  109. * @since 1.25
  110. *
  111. * @param string $globalId
  112. *
  113. * @return Site|null
  114. */
  115. public function getSite( $globalId ) {
  116. $sites = $this->getSites();
  117. return $sites->hasSite( $globalId ) ? $sites->getSite( $globalId ) : null;
  118. }
  119. /**
  120. * @see SiteStore::saveSite
  121. *
  122. * @since 1.25
  123. *
  124. * @param Site $site
  125. *
  126. * @return bool Success indicator
  127. */
  128. public function saveSite( Site $site ) {
  129. return $this->saveSites( [ $site ] );
  130. }
  131. /**
  132. * @see SiteStore::saveSites
  133. *
  134. * @since 1.25
  135. *
  136. * @param Site[] $sites
  137. *
  138. * @return bool Success indicator
  139. */
  140. public function saveSites( array $sites ) {
  141. if ( empty( $sites ) ) {
  142. return true;
  143. }
  144. $success = $this->siteStore->saveSites( $sites );
  145. // purge cache
  146. $this->reset();
  147. return $success;
  148. }
  149. /**
  150. * Purges the internal and external cache of the site list, forcing the list.
  151. * of sites to be reloaded.
  152. *
  153. * Only use this for testing, as APC is typically used and is per-server
  154. *
  155. * @since 1.25
  156. */
  157. public function reset() {
  158. // purge cache
  159. $this->cache->delete( $this->getCacheKey() );
  160. $this->sites = null;
  161. }
  162. /**
  163. * Clears the list of sites stored.
  164. *
  165. * Only use this for testing, as APC is typically used and is per-server.
  166. *
  167. * @see SiteStore::clear()
  168. *
  169. * @return bool Success
  170. */
  171. public function clear() {
  172. $this->reset();
  173. return $this->siteStore->clear();
  174. }
  175. }