/freemius/includes/managers/class-fs-key-value-storage.php

  1. <?php 
  2. /** 
  3. * @package Freemius 
  4. * @copyright Copyright (c) 2015, Freemius, Inc. 
  5. * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License 
  6. * @since 1.0.7 
  7. */ 
  8.  
  9. if ( ! defined( 'ABSPATH' ) ) { 
  10. exit; 
  11.  
  12. /** 
  13. * Class FS_Key_Value_Storage 
  14. * 
  15. * @property int $install_timestamp 
  16. * @property int $activation_timestamp 
  17. * @property int $sync_timestamp 
  18. * @property object $sync_cron 
  19. * @property int $install_sync_timestamp 
  20. * @property array $connectivity_test 
  21. * @property array $is_on 
  22. * @property object $trial_plan 
  23. * @property bool $has_trial_plan 
  24. * @property bool $trial_promotion_shown 
  25. * @property string $sdk_version 
  26. * @property string $sdk_last_version 
  27. * @property bool $sdk_upgrade_mode 
  28. * @property bool $sdk_downgrade_mode 
  29. * @property bool $plugin_upgrade_mode 
  30. * @property bool $plugin_downgrade_mode 
  31. * @property string $plugin_version 
  32. * @property string $plugin_last_version 
  33. * @property bool $is_plugin_new_install 
  34. * @property bool $was_plugin_loaded 
  35. * @property object $plugin_main_file 
  36. * @property bool $prev_is_premium 
  37. * @property array $is_anonymous 
  38. * @property bool $is_pending_activation 
  39. * @property bool $sticky_optin_added 
  40. * @property object $uninstall_reason 
  41. * @property object $subscription 
  42. */ 
  43. class FS_Key_Value_Storage implements ArrayAccess, Iterator, Countable { 
  44. /** 
  45. * @var string 
  46. */ 
  47. protected $_id; 
  48. /** 
  49. * @var string 
  50. */ 
  51. protected $_slug; 
  52. /** 
  53. * @var array 
  54. */ 
  55. protected $_data; 
  56.  
  57. /** 
  58. * @var FS_Plugin_Manager[] 
  59. */ 
  60. private static $_instances = array(); 
  61. /** 
  62. * @var FS_Logger 
  63. */ 
  64. protected $_logger; 
  65.  
  66. /** 
  67. * @param string $id 
  68. * @param string $slug 
  69. * 
  70. * @return FS_Key_Value_Storage 
  71. */ 
  72. static function instance( $id, $slug ) { 
  73. $key = $id . ':' . $slug; 
  74. if ( ! isset( self::$_instances[ $key ] ) ) { 
  75. self::$_instances[ $key ] = new FS_Key_Value_Storage( $id, $slug ); 
  76.  
  77. return self::$_instances[ $key ]; 
  78.  
  79. protected function __construct( $id, $slug ) { 
  80. $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $slug . '_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); 
  81.  
  82. $this->_slug = $slug; 
  83. $this->_id = $id; 
  84. $this->load(); 
  85.  
  86. protected function get_option_manager() { 
  87. return FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true ); 
  88.  
  89. protected function get_all_data() { 
  90. return $this->get_option_manager()->get_option( $this->_id, array() ); 
  91.  
  92. /** 
  93. * Load plugin data from local DB. 
  94. * 
  95. * @author Vova Feldman (@svovaf) 
  96. * @since 1.0.7 
  97. */ 
  98. function load() { 
  99. $all_plugins_data = $this->get_all_data(); 
  100. $this->_data = isset( $all_plugins_data[ $this->_slug ] ) ? 
  101. $all_plugins_data[ $this->_slug ] : 
  102. array(); 
  103.  
  104. /** 
  105. * @author Vova Feldman (@svovaf) 
  106. * @since 1.0.7 
  107. * 
  108. * @param string $key 
  109. * @param mixed $value 
  110. * @param bool $flush 
  111. */ 
  112. function store( $key, $value, $flush = true ) { 
  113. if ( $this->_logger->is_on() ) { 
  114. $this->_logger->entrance( $key . ' = ' . var_export( $value, true ) ); 
  115.  
  116. if ( array_key_exists( $key, $this->_data ) && $value === $this->_data[ $key ] ) { 
  117. // No need to store data if the value wasn't changed. 
  118. return; 
  119.  
  120. $all_data = $this->get_all_data(); 
  121.  
  122. $this->_data[ $key ] = $value; 
  123.  
  124. $all_data[ $this->_slug ] = $this->_data; 
  125.  
  126. $options_manager = $this->get_option_manager(); 
  127. $options_manager->set_option( $this->_id, $all_data, $flush ); 
  128.  
  129. /** 
  130. * @author Vova Feldman (@svovaf) 
  131. * @since 1.0.7 
  132. * 
  133. * @param bool $store 
  134. * @param string[] $exceptions Set of keys to keep and not clear. 
  135. */ 
  136. function clear_all( $store = true, $exceptions = array() ) { 
  137. $new_data = array(); 
  138. foreach ( $exceptions as $key ) { 
  139. if ( isset( $this->_data[ $key ] ) ) { 
  140. $new_data[ $key ] = $this->_data[ $key ]; 
  141.  
  142. $this->_data = $new_data; 
  143.  
  144. if ( $store ) { 
  145. $all_data = $this->get_all_data(); 
  146. $all_data[ $this->_slug ] = $this->_data; 
  147. $options_manager = $this->get_option_manager(); 
  148. $options_manager->set_option( $this->_id, $all_data, true ); 
  149.  
  150. /** 
  151. * Delete key-value storage. 
  152. * 
  153. * @author Vova Feldman (@svovaf) 
  154. * @since 1.0.9 
  155. */ 
  156. function delete() { 
  157. $this->_data = array(); 
  158.  
  159. $all_data = $this->get_all_data(); 
  160. unset( $all_data[ $this->_slug ] ); 
  161. $options_manager = $this->get_option_manager(); 
  162. $options_manager->set_option( $this->_id, $all_data, true ); 
  163.  
  164. /** 
  165. * @author Vova Feldman (@svovaf) 
  166. * @since 1.0.7 
  167. * 
  168. * @param string $key 
  169. * @param bool $store 
  170. */ 
  171. function remove( $key, $store = true ) { 
  172. if ( ! array_key_exists( $key, $this->_data ) ) { 
  173. return; 
  174.  
  175. unset( $this->_data[ $key ] ); 
  176.  
  177. if ( $store ) { 
  178. $all_data = $this->get_all_data(); 
  179. $all_data[ $this->_slug ] = $this->_data; 
  180. $options_manager = $this->get_option_manager(); 
  181. $options_manager->set_option( $this->_id, $all_data, true ); 
  182.  
  183. /** 
  184. * @author Vova Feldman (@svovaf) 
  185. * @since 1.0.7 
  186. * 
  187. * @param string $key 
  188. * @param mixed $default 
  189. * 
  190. * @return bool|\FS_Plugin 
  191. */ 
  192. function get( $key, $default = false ) { 
  193. return array_key_exists( $key, $this->_data ) ? 
  194. $this->_data[ $key ] : 
  195. $default; 
  196.  
  197.  
  198. /** ArrayAccess + Magic Access (better for refactoring) 
  199. -----------------------------------------------------------------------------------*/ 
  200. function __set( $k, $v ) { 
  201. $this->store( $k, $v ); 
  202.  
  203. function __isset( $k ) { 
  204. return array_key_exists( $k, $this->_data ); 
  205.  
  206. function __unset( $k ) { 
  207. $this->remove( $k ); 
  208.  
  209. function __get( $k ) { 
  210. return $this->get( $k, null ); 
  211.  
  212. function offsetSet( $k, $v ) { 
  213. if ( is_null( $k ) ) { 
  214. throw new Exception( 'Can\'t append value to request params.' ); 
  215. } else { 
  216. $this->{$k} = $v; 
  217.  
  218. function offsetExists( $k ) { 
  219. return array_key_exists( $k, $this->_data ); 
  220.  
  221. function offsetUnset( $k ) { 
  222. unset( $this->$k ); 
  223.  
  224. function offsetGet( $k ) { 
  225. return $this->get( $k, null ); 
  226.  
  227. /** 
  228. * (PHP 5 >= 5.0.0)<br/> 
  229. * Return the current element 
  230. * 
  231. * @link http://php.net/manual/en/iterator.current.php 
  232. * @return mixed Can return any type. 
  233. */ 
  234. public function current() { 
  235. return current( $this->_data ); 
  236.  
  237. /** 
  238. * (PHP 5 >= 5.0.0)<br/> 
  239. * Move forward to next element 
  240. * 
  241. * @link http://php.net/manual/en/iterator.next.php 
  242. * @return void Any returned value is ignored. 
  243. */ 
  244. public function next() { 
  245. next( $this->_data ); 
  246.  
  247. /** 
  248. * (PHP 5 >= 5.0.0)<br/> 
  249. * Return the key of the current element 
  250. * 
  251. * @link http://php.net/manual/en/iterator.key.php 
  252. * @return mixed scalar on success, or null on failure. 
  253. */ 
  254. public function key() { 
  255. return key( $this->_data ); 
  256.  
  257. /** 
  258. * (PHP 5 >= 5.0.0)<br/> 
  259. * Checks if current position is valid 
  260. * 
  261. * @link http://php.net/manual/en/iterator.valid.php 
  262. * @return boolean The return value will be casted to boolean and then evaluated. 
  263. * Returns true on success or false on failure. 
  264. */ 
  265. public function valid() { 
  266. $key = key( $this->_data ); 
  267.  
  268. return ( $key !== null && $key !== false ); 
  269.  
  270. /** 
  271. * (PHP 5 >= 5.0.0)<br/> 
  272. * Rewind the Iterator to the first element 
  273. * 
  274. * @link http://php.net/manual/en/iterator.rewind.php 
  275. * @return void Any returned value is ignored. 
  276. */ 
  277. public function rewind() { 
  278. reset( $this->_data ); 
  279.  
  280. /** 
  281. * (PHP 5 >= 5.1.0)<br/> 
  282. * Count elements of an object 
  283. * 
  284. * @link http://php.net/manual/en/countable.count.php 
  285. * @return int The custom count as an integer. 
  286. * </p> 
  287. * <p> 
  288. * The return value is cast to an integer. 
  289. */ 
  290. public function count() { 
  291. return count( $this->_data ); 
.