PluginProbe ʕ •ᴥ•ʔ
Gallery : FooGallery / 3.3.3
Gallery : FooGallery v3.3.3
3.3.2 3.3.3 3.3.0 3.1.31 3.1.32 3.1.34 3.1.36 3.2.0 3.2.6 trunk 1.10.3 2.0.24 2.1.34 2.2.44 2.3.3 2.4.32 3.0.6 3.1.11 3.1.12 3.1.13 3.1.20 3.1.25 3.1.26 3.1.26.1 3.1.26.2
foogallery / freemius / includes / managers / class-fs-key-value-storage.php
foogallery / freemius / includes / managers Last commit date
class-fs-admin-menu-manager.php 3 days ago class-fs-admin-notice-manager.php 3 days ago class-fs-cache-manager.php 3 days ago class-fs-checkout-manager.php 3 days ago class-fs-clone-manager.php 3 days ago class-fs-contact-form-manager.php 3 days ago class-fs-debug-manager.php 3 days ago class-fs-gdpr-manager.php 3 days ago class-fs-key-value-storage.php 3 days ago class-fs-license-manager.php 3 days ago class-fs-option-manager.php 3 days ago class-fs-permission-manager.php 3 days ago class-fs-plan-manager.php 3 days ago class-fs-plugin-manager.php 3 days ago index.php 3 days ago
class-fs-key-value-storage.php
402 lines
1 <?php
2 /**
3 * @package Freemius
4 * @copyright Copyright (c) 2015, Freemius, Inc.
5 * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3
6 * @since 1.0.7
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 /**
14 * Class FS_Key_Value_Storage
15 *
16 * @property int $install_timestamp
17 * @property int $activation_timestamp
18 * @property int $sync_timestamp
19 * @property object $sync_cron
20 * @property int $install_sync_timestamp
21 * @property array $connectivity_test
22 * @property array $is_on
23 * @property object $trial_plan
24 * @property bool $has_trial_plan
25 * @property bool $trial_promotion_shown
26 * @property string $sdk_version
27 * @property string $sdk_last_version
28 * @property bool $sdk_upgrade_mode
29 * @property bool $sdk_downgrade_mode
30 * @property bool $plugin_upgrade_mode
31 * @property bool $plugin_downgrade_mode
32 * @property string $plugin_version
33 * @property string $plugin_last_version
34 * @property bool $is_plugin_new_install
35 * @property bool $was_plugin_loaded
36 * @property object $plugin_main_file
37 * @property bool $prev_is_premium
38 * @property array $is_anonymous
39 * @property bool $is_pending_activation
40 * @property bool $sticky_optin_added
41 * @property object $uninstall_reason
42 * @property object $subscription
43 */
44 class FS_Key_Value_Storage implements ArrayAccess, Iterator, Countable {
45 /**
46 * @var string
47 */
48 protected $_id;
49
50 /**
51 * @since 1.2.2
52 *
53 * @var string
54 */
55 protected $_secondary_id;
56
57 /**
58 * @since 2.0.0
59 * @var int The ID of the blog that is associated with the current site level options.
60 */
61 private $_blog_id = 0;
62
63 /**
64 * @since 2.0.0
65 * @var bool
66 */
67 private $_is_multisite_storage;
68
69 /**
70 * @var array
71 */
72 protected $_data;
73
74 /**
75 * @var FS_Key_Value_Storage[]
76 */
77 private static $_instances = array();
78
79 /**
80 * @var FS_Logger
81 */
82 protected $_logger;
83
84 /**
85 * @param string $id
86 * @param string $secondary_id
87 * @param bool $network_level_or_blog_id
88 *
89 * @return FS_Key_Value_Storage
90 */
91 static function instance( $id, $secondary_id, $network_level_or_blog_id = false ) {
92 $key = $id . ':' . $secondary_id;
93
94 if ( is_multisite() ) {
95 if ( true === $network_level_or_blog_id ) {
96 $key .= ':ms';
97 } else if ( is_numeric( $network_level_or_blog_id ) && $network_level_or_blog_id > 0 ) {
98 $key .= ":{$network_level_or_blog_id}";
99 } else {
100 $network_level_or_blog_id = get_current_blog_id();
101
102 $key .= ":{$network_level_or_blog_id}";
103 }
104 }
105
106 if ( ! isset( self::$_instances[ $key ] ) ) {
107 self::$_instances[ $key ] = new FS_Key_Value_Storage( $id, $secondary_id, $network_level_or_blog_id );
108 }
109
110 return self::$_instances[ $key ];
111 }
112
113 protected function __construct( $id, $secondary_id, $network_level_or_blog_id = false ) {
114 $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $secondary_id . '_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
115
116 $this->_id = $id;
117 $this->_secondary_id = $secondary_id;
118
119 if ( is_multisite() ) {
120 $this->_is_multisite_storage = ( true === $network_level_or_blog_id );
121
122 if ( is_numeric( $network_level_or_blog_id ) ) {
123 $this->_blog_id = $network_level_or_blog_id;
124 }
125 } else {
126 $this->_is_multisite_storage = false;
127 }
128
129 $this->load();
130 }
131
132 protected function get_option_manager() {
133 return FS_Option_Manager::get_manager(
134 WP_FS__ACCOUNTS_OPTION_NAME,
135 true,
136 $this->_is_multisite_storage ?
137 true :
138 ( $this->_blog_id > 0 ? $this->_blog_id : false )
139 );
140 }
141
142 protected function get_all_data() {
143 return $this->get_option_manager()->get_option( $this->_id, array() );
144 }
145
146 /**
147 * Load plugin data from local DB.
148 *
149 * @author Vova Feldman (@svovaf)
150 * @since 1.0.7
151 */
152 function load() {
153 $all_plugins_data = $this->get_all_data();
154 $this->_data = isset( $all_plugins_data[ $this->_secondary_id ] ) ?
155 $all_plugins_data[ $this->_secondary_id ] :
156 array();
157 }
158
159 /**
160 * @author Vova Feldman (@svovaf)
161 * @since 1.0.7
162 *
163 * @param string $key
164 * @param mixed $value
165 * @param bool $flush
166 */
167 function store( $key, $value, $flush = true ) {
168 if ( $this->_logger->is_on() ) {
169 $this->_logger->entrance( $key . ' = ' . var_export( $value, true ) );
170 }
171
172 if ( array_key_exists( $key, $this->_data ) && $value === $this->_data[ $key ] ) {
173 // No need to store data if the value wasn't changed.
174 return;
175 }
176
177 $all_data = $this->get_all_data();
178
179 $this->_data[ $key ] = $value;
180
181 $all_data[ $this->_secondary_id ] = $this->_data;
182
183 $options_manager = $this->get_option_manager();
184 $options_manager->set_option( $this->_id, $all_data, $flush );
185 }
186
187 /**
188 * @author Vova Feldman (@svovaf)
189 * @since 2.0.0
190 */
191 function save() {
192 $this->get_option_manager()->store();
193 }
194
195 /**
196 * @author Vova Feldman (@svovaf)
197 * @since 1.0.7
198 *
199 * @param bool $store
200 * @param string[] $exceptions Set of keys to keep and not clear.
201 */
202 function clear_all( $store = true, $exceptions = array() ) {
203 $new_data = array();
204 foreach ( $exceptions as $key ) {
205 if ( isset( $this->_data[ $key ] ) ) {
206 $new_data[ $key ] = $this->_data[ $key ];
207 }
208 }
209
210 $this->_data = $new_data;
211
212 if ( $store ) {
213 $all_data = $this->get_all_data();
214 $all_data[ $this->_secondary_id ] = $this->_data;
215 $options_manager = $this->get_option_manager();
216 $options_manager->set_option( $this->_id, $all_data, true );
217 }
218 }
219
220 /**
221 * Delete key-value storage.
222 *
223 * @author Vova Feldman (@svovaf)
224 * @since 1.0.9
225 */
226 function delete() {
227 $this->_data = array();
228
229 $all_data = $this->get_all_data();
230 unset( $all_data[ $this->_secondary_id ] );
231 $options_manager = $this->get_option_manager();
232 $options_manager->set_option( $this->_id, $all_data, true );
233 }
234
235 /**
236 * @author Vova Feldman (@svovaf)
237 * @since 1.0.7
238 *
239 * @param string $key
240 * @param bool $store
241 */
242 function remove( $key, $store = true ) {
243 if ( ! array_key_exists( $key, $this->_data ) ) {
244 return;
245 }
246
247 unset( $this->_data[ $key ] );
248
249 if ( $store ) {
250 $all_data = $this->get_all_data();
251 $all_data[ $this->_secondary_id ] = $this->_data;
252 $options_manager = $this->get_option_manager();
253 $options_manager->set_option( $this->_id, $all_data, true );
254 }
255 }
256
257 /**
258 * @author Vova Feldman (@svovaf)
259 * @since 1.0.7
260 *
261 * @param string $key
262 * @param mixed $default
263 *
264 * @return bool|\FS_Plugin
265 */
266 function get( $key, $default = false ) {
267 return array_key_exists( $key, $this->_data ) ?
268 $this->_data[ $key ] :
269 $default;
270 }
271
272 /**
273 * @author Vova Feldman (@svovaf)
274 * @since 2.0.0
275 *
276 * @return string
277 */
278 function get_secondary_id() {
279 return $this->_secondary_id;
280 }
281
282
283 /* ArrayAccess + Magic Access (better for refactoring)
284 -----------------------------------------------------------------------------------*/
285 function __set( $k, $v ) {
286 $this->store( $k, $v );
287 }
288
289 function __isset( $k ) {
290 return array_key_exists( $k, $this->_data );
291 }
292
293 function __unset( $k ) {
294 $this->remove( $k );
295 }
296
297 function __get( $k ) {
298 return $this->get( $k, null );
299 }
300
301 #[ReturnTypeWillChange]
302 function offsetSet( $k, $v ) {
303 if ( is_null( $k ) ) {
304 throw new Exception( 'Can\'t append value to request params.' );
305 } else {
306 $this->{$k} = $v;
307 }
308 }
309
310 #[ReturnTypeWillChange]
311 function offsetExists( $k ) {
312 return array_key_exists( $k, $this->_data );
313 }
314
315 #[ReturnTypeWillChange]
316 function offsetUnset( $k ) {
317 unset( $this->$k );
318 }
319
320 #[ReturnTypeWillChange]
321 function offsetGet( $k ) {
322 return $this->get( $k, null );
323 }
324
325 /**
326 * (PHP 5 &gt;= 5.0.0)<br/>
327 * Return the current element
328 *
329 * @link http://php.net/manual/en/iterator.current.php
330 * @return mixed Can return any type.
331 */
332 #[ReturnTypeWillChange]
333 public function current() {
334 return current( $this->_data );
335 }
336
337 /**
338 * (PHP 5 &gt;= 5.0.0)<br/>
339 * Move forward to next element
340 *
341 * @link http://php.net/manual/en/iterator.next.php
342 * @return void Any returned value is ignored.
343 */
344 #[ReturnTypeWillChange]
345 public function next() {
346 next( $this->_data );
347 }
348
349 /**
350 * (PHP 5 &gt;= 5.0.0)<br/>
351 * Return the key of the current element
352 *
353 * @link http://php.net/manual/en/iterator.key.php
354 * @return mixed scalar on success, or null on failure.
355 */
356 #[ReturnTypeWillChange]
357 public function key() {
358 return key( $this->_data );
359 }
360
361 /**
362 * (PHP 5 &gt;= 5.0.0)<br/>
363 * Checks if current position is valid
364 *
365 * @link http://php.net/manual/en/iterator.valid.php
366 * @return boolean The return value will be casted to boolean and then evaluated.
367 * Returns true on success or false on failure.
368 */
369 #[ReturnTypeWillChange]
370 public function valid() {
371 $key = key( $this->_data );
372
373 return ( $key !== null && $key !== false );
374 }
375
376 /**
377 * (PHP 5 &gt;= 5.0.0)<br/>
378 * Rewind the Iterator to the first element
379 *
380 * @link http://php.net/manual/en/iterator.rewind.php
381 * @return void Any returned value is ignored.
382 */
383 #[ReturnTypeWillChange]
384 public function rewind() {
385 reset( $this->_data );
386 }
387
388 /**
389 * (PHP 5 &gt;= 5.1.0)<br/>
390 * Count elements of an object
391 *
392 * @link http://php.net/manual/en/countable.count.php
393 * @return int The custom count as an integer.
394 * </p>
395 * <p>
396 * The return value is cast to an integer.
397 */
398 #[ReturnTypeWillChange]
399 public function count() {
400 return count( $this->_data );
401 }
402 }