StateStore.php 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <?php
  2. namespace YahnisElsts\PluginUpdateChecker\v5p1;
  3. if ( !class_exists(StateStore::class, false) ):
  4. class StateStore {
  5. /**
  6. * @var int Last update check timestamp.
  7. */
  8. protected $lastCheck = 0;
  9. /**
  10. * @var string Version number.
  11. */
  12. protected $checkedVersion = '';
  13. /**
  14. * @var Update|null Cached update.
  15. */
  16. protected $update = null;
  17. /**
  18. * @var string Site option name.
  19. */
  20. private $optionName = '';
  21. /**
  22. * @var bool Whether we've already tried to load the state from the database.
  23. */
  24. private $isLoaded = false;
  25. public function __construct($optionName) {
  26. $this->optionName = $optionName;
  27. }
  28. /**
  29. * Get time elapsed since the last update check.
  30. *
  31. * If there are no recorded update checks, this method returns a large arbitrary number
  32. * (i.e. time since the Unix epoch).
  33. *
  34. * @return int Elapsed time in seconds.
  35. */
  36. public function timeSinceLastCheck() {
  37. $this->lazyLoad();
  38. return time() - $this->lastCheck;
  39. }
  40. /**
  41. * @return int
  42. */
  43. public function getLastCheck() {
  44. $this->lazyLoad();
  45. return $this->lastCheck;
  46. }
  47. /**
  48. * Set the time of the last update check to the current timestamp.
  49. *
  50. * @return $this
  51. */
  52. public function setLastCheckToNow() {
  53. $this->lazyLoad();
  54. $this->lastCheck = time();
  55. return $this;
  56. }
  57. /**
  58. * @return null|Update
  59. */
  60. public function getUpdate() {
  61. $this->lazyLoad();
  62. return $this->update;
  63. }
  64. /**
  65. * @param Update|null $update
  66. * @return $this
  67. */
  68. public function setUpdate(Update $update = null) {
  69. $this->lazyLoad();
  70. $this->update = $update;
  71. return $this;
  72. }
  73. /**
  74. * @return string
  75. */
  76. public function getCheckedVersion() {
  77. $this->lazyLoad();
  78. return $this->checkedVersion;
  79. }
  80. /**
  81. * @param string $version
  82. * @return $this
  83. */
  84. public function setCheckedVersion($version) {
  85. $this->lazyLoad();
  86. $this->checkedVersion = strval($version);
  87. return $this;
  88. }
  89. /**
  90. * Get translation updates.
  91. *
  92. * @return array
  93. */
  94. public function getTranslations() {
  95. $this->lazyLoad();
  96. if ( isset($this->update, $this->update->translations) ) {
  97. return $this->update->translations;
  98. }
  99. return array();
  100. }
  101. /**
  102. * Set translation updates.
  103. *
  104. * @param array $translationUpdates
  105. */
  106. public function setTranslations($translationUpdates) {
  107. $this->lazyLoad();
  108. if ( isset($this->update) ) {
  109. $this->update->translations = $translationUpdates;
  110. $this->save();
  111. }
  112. }
  113. public function save() {
  114. $state = new \stdClass();
  115. $state->lastCheck = $this->lastCheck;
  116. $state->checkedVersion = $this->checkedVersion;
  117. if ( isset($this->update)) {
  118. $state->update = $this->update->toStdClass();
  119. $updateClass = get_class($this->update);
  120. $state->updateClass = $updateClass;
  121. $prefix = $this->getLibPrefix();
  122. if ( Utils::startsWith($updateClass, $prefix) ) {
  123. $state->updateBaseClass = substr($updateClass, strlen($prefix));
  124. }
  125. }
  126. update_site_option($this->optionName, $state);
  127. $this->isLoaded = true;
  128. }
  129. /**
  130. * @return $this
  131. */
  132. public function lazyLoad() {
  133. if ( !$this->isLoaded ) {
  134. $this->load();
  135. }
  136. return $this;
  137. }
  138. protected function load() {
  139. $this->isLoaded = true;
  140. $state = get_site_option($this->optionName, null);
  141. if (
  142. !is_object($state)
  143. //Sanity check: If the Utils class is missing, the plugin is probably in the process
  144. //of being deleted (e.g. the old version gets deleted during an update).
  145. || !class_exists(Utils::class)
  146. ) {
  147. $this->lastCheck = 0;
  148. $this->checkedVersion = '';
  149. $this->update = null;
  150. return;
  151. }
  152. $this->lastCheck = intval(Utils::get($state, 'lastCheck', 0));
  153. $this->checkedVersion = Utils::get($state, 'checkedVersion', '');
  154. $this->update = null;
  155. if ( isset($state->update) ) {
  156. //This mess is due to the fact that the want the update class from this version
  157. //of the library, not the version that saved the update.
  158. $updateClass = null;
  159. if ( isset($state->updateBaseClass) ) {
  160. $updateClass = $this->getLibPrefix() . $state->updateBaseClass;
  161. } else if ( isset($state->updateClass) ) {
  162. $updateClass = $state->updateClass;
  163. }
  164. $factory = array($updateClass, 'fromObject');
  165. if ( ($updateClass !== null) && is_callable($factory) ) {
  166. $this->update = call_user_func($factory, $state->update);
  167. }
  168. }
  169. }
  170. public function delete() {
  171. delete_site_option($this->optionName);
  172. $this->lastCheck = 0;
  173. $this->checkedVersion = '';
  174. $this->update = null;
  175. }
  176. private function getLibPrefix() {
  177. //This assumes that the current class is at the top of the versioned namespace.
  178. return __NAMESPACE__ . '\\';
  179. }
  180. }
  181. endif;