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.3 |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
10
|
|
|
exit; |
11
|
|
|
} |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* 3-layer lazy options manager. |
15
|
|
|
* layer 3: Memory |
16
|
|
|
* layer 2: Cache (if there's any caching plugin and if WP_FS__DEBUG_SDK is FALSE) |
17
|
|
|
* layer 1: Database (options table). All options stored as one option record in the DB to reduce number of DB |
18
|
|
|
* queries. |
19
|
|
|
* |
20
|
|
|
* If load() is not explicitly called, starts as empty manager. Same thing about saving the data - you have to |
21
|
|
|
* explicitly call store(). |
22
|
|
|
* |
23
|
|
|
* Class Freemius_Option_Manager |
24
|
|
|
*/ |
25
|
|
|
class FS_Option_Manager { |
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var string |
28
|
|
|
*/ |
29
|
|
|
private $_id; |
30
|
|
|
/** |
31
|
|
|
* @var array |
32
|
|
|
*/ |
33
|
|
|
private $_options; |
34
|
|
|
/** |
35
|
|
|
* @var FS_Logger |
36
|
|
|
*/ |
37
|
|
|
private $_logger; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var FS_Option_Manager[] |
41
|
|
|
*/ |
42
|
|
|
private static $_MANAGERS = array(); |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @author Vova Feldman (@svovaf) |
46
|
|
|
* @since 1.0.3 |
47
|
|
|
* |
48
|
|
|
* @param string $id |
49
|
|
|
* @param bool $load |
50
|
|
|
*/ |
51
|
|
|
private function __construct( $id, $load = false ) { |
52
|
|
|
$this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_opt_mngr_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); |
53
|
|
|
|
54
|
|
|
$this->_logger->entrance(); |
55
|
|
|
$this->_logger->log( 'id = ' . $id ); |
56
|
|
|
|
57
|
|
|
$this->_id = $id; |
58
|
|
|
|
59
|
|
|
if ( $load ) { |
60
|
|
|
$this->load(); |
61
|
|
|
} |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @author Vova Feldman (@svovaf) |
66
|
|
|
* @since 1.0.3 |
67
|
|
|
* |
68
|
|
|
* @param $id |
69
|
|
|
* @param $load |
70
|
|
|
* |
71
|
|
|
* @return FS_Option_Manager |
72
|
|
|
*/ |
73
|
|
|
static function get_manager( $id, $load = false ) { |
|
|
|
|
74
|
|
|
$id = strtolower( $id ); |
75
|
|
|
|
76
|
|
|
if ( ! isset( self::$_MANAGERS[ $id ] ) ) { |
77
|
|
|
self::$_MANAGERS[ $id ] = new FS_Option_Manager( $id, $load ); |
78
|
|
|
} // If load required but not yet loaded, load. |
79
|
|
|
else if ( $load && ! self::$_MANAGERS[ $id ]->is_loaded() ) { |
80
|
|
|
self::$_MANAGERS[ $id ]->load(); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
return self::$_MANAGERS[ $id ]; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
private function _get_option_manager_name() { |
87
|
|
|
// return WP_FS__SLUG . '_' . $this->_id; |
88
|
|
|
return $this->_id; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* @author Vova Feldman (@svovaf) |
93
|
|
|
* @since 1.0.3 |
94
|
|
|
* |
95
|
|
|
* @param bool $flush |
96
|
|
|
*/ |
97
|
|
|
function load( $flush = false ) { |
|
|
|
|
98
|
|
|
$this->_logger->entrance(); |
99
|
|
|
|
100
|
|
|
$option_name = $this->_get_option_manager_name(); |
101
|
|
|
|
102
|
|
|
if ( $flush || ! isset( $this->_options ) ) { |
103
|
|
|
if ( isset( $this->_options ) ) { |
104
|
|
|
// Clear prev options. |
105
|
|
|
$this->clear(); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
if ( ! WP_FS__DEBUG_SDK ) { |
109
|
|
|
$this->_options = wp_cache_get( $option_name, WP_FS__SLUG ); |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
// $this->_logger->info('wp_cache_get = ' . var_export($this->_options, true)); |
|
|
|
|
113
|
|
|
|
114
|
|
|
// if ( is_array( $this->_options ) ) { |
|
|
|
|
115
|
|
|
// $this->clear(); |
116
|
|
|
// } |
117
|
|
|
|
118
|
|
|
$cached = true; |
119
|
|
|
|
120
|
|
|
if ( empty( $this->_options ) ) { |
121
|
|
|
$this->_options = get_option( $option_name ); |
122
|
|
|
|
123
|
|
|
if ( is_string( $this->_options ) ) { |
124
|
|
|
$this->_options = json_decode( $this->_options ); |
|
|
|
|
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
// $this->_logger->info('get_option = ' . var_export($this->_options, true)); |
|
|
|
|
128
|
|
|
|
129
|
|
|
if ( false === $this->_options ) { |
130
|
|
|
$this->clear(); |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
$cached = false; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
if ( ! WP_FS__DEBUG_SDK && ! $cached ) // Set non encoded cache. |
137
|
|
|
{ |
138
|
|
|
wp_cache_set( $option_name, $this->_options, WP_FS__SLUG ); |
139
|
|
|
} |
140
|
|
|
} |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* @author Vova Feldman (@svovaf) |
145
|
|
|
* @since 1.0.3 |
146
|
|
|
* |
147
|
|
|
* @return bool |
148
|
|
|
*/ |
149
|
|
|
function is_loaded() { |
|
|
|
|
150
|
|
|
return isset( $this->_options ); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* @author Vova Feldman (@svovaf) |
155
|
|
|
* @since 1.0.3 |
156
|
|
|
* |
157
|
|
|
* @return bool |
158
|
|
|
*/ |
159
|
|
|
function is_empty() { |
|
|
|
|
160
|
|
|
return ( $this->is_loaded() && false === $this->_options ); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* @author Vova Feldman (@svovaf) |
165
|
|
|
* @since 1.0.6 |
166
|
|
|
* |
167
|
|
|
* @param bool $flush |
168
|
|
|
*/ |
169
|
|
|
function clear( $flush = false ) { |
|
|
|
|
170
|
|
|
$this->_logger->entrance(); |
171
|
|
|
|
172
|
|
|
$this->_options = array(); |
173
|
|
|
|
174
|
|
|
if ( $flush ) { |
175
|
|
|
$this->store(); |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Delete options manager from DB. |
181
|
|
|
* |
182
|
|
|
* @author Vova Feldman (@svovaf) |
183
|
|
|
* @since 1.0.9 |
184
|
|
|
*/ |
185
|
|
|
function delete() { |
|
|
|
|
186
|
|
|
delete_option( $this->_get_option_manager_name() ); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* @author Vova Feldman (@svovaf) |
191
|
|
|
* @since 1.0.6 |
192
|
|
|
* |
193
|
|
|
* @param string $option |
194
|
|
|
* |
195
|
|
|
* @return bool |
196
|
|
|
*/ |
197
|
|
|
function has_option( $option ) { |
|
|
|
|
198
|
|
|
return array_key_exists( $option, $this->_options ); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* @author Vova Feldman (@svovaf) |
203
|
|
|
* @since 1.0.3 |
204
|
|
|
* |
205
|
|
|
* @param string $option |
206
|
|
|
* @param mixed $default |
207
|
|
|
* |
208
|
|
|
* @return mixed |
209
|
|
|
*/ |
210
|
|
|
function get_option( $option, $default = null ) { |
|
|
|
|
211
|
|
|
$this->_logger->entrance( 'option = ' . $option ); |
212
|
|
|
|
213
|
|
|
if ( is_array( $this->_options ) ) { |
214
|
|
|
return isset( $this->_options[ $option ] ) ? $this->_options[ $option ] : $default; |
215
|
|
|
} else if ( is_object( $this->_options ) ) { |
216
|
|
|
return isset( $this->_options->{$option} ) ? $this->_options->{$option} : $default; |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
return $default; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* @author Vova Feldman (@svovaf) |
224
|
|
|
* @since 1.0.3 |
225
|
|
|
* |
226
|
|
|
* @param string $option |
227
|
|
|
* @param mixed $value |
228
|
|
|
* @param bool $flush |
229
|
|
|
*/ |
230
|
|
|
function set_option( $option, $value, $flush = false ) { |
|
|
|
|
231
|
|
|
$this->_logger->entrance( 'option = ' . $option ); |
232
|
|
|
|
233
|
|
|
if ( ! $this->is_loaded() ) { |
234
|
|
|
$this->clear(); |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
if ( is_array( $this->_options ) ) { |
238
|
|
|
$this->_options[ $option ] = $value; |
239
|
|
|
} else if ( is_object( $this->_options ) ) { |
240
|
|
|
$this->_options->{$option} = $value; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
if ( $flush ) { |
244
|
|
|
$this->store(); |
245
|
|
|
} |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Unset option. |
250
|
|
|
* |
251
|
|
|
* @author Vova Feldman (@svovaf) |
252
|
|
|
* @since 1.0.3 |
253
|
|
|
* |
254
|
|
|
* @param string $option |
255
|
|
|
* @param bool $flush |
256
|
|
|
*/ |
257
|
|
|
function unset_option( $option, $flush = false ) { |
|
|
|
|
258
|
|
|
$this->_logger->entrance( 'option = ' . $option ); |
259
|
|
|
|
260
|
|
|
if ( is_array( $this->_options ) ) { |
261
|
|
|
if ( ! isset( $this->_options[ $option ] ) ) { |
262
|
|
|
return; |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
unset( $this->_options[ $option ] ); |
266
|
|
|
|
267
|
|
|
} else if ( is_object( $this->_options ) ) { |
268
|
|
|
if ( ! isset( $this->_options->{$option} ) ) { |
269
|
|
|
return; |
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
unset( $this->_options->{$option} ); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
if ( $flush ) { |
276
|
|
|
$this->store(); |
277
|
|
|
} |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* Dump options to database. |
282
|
|
|
* |
283
|
|
|
* @author Vova Feldman (@svovaf) |
284
|
|
|
* @since 1.0.3 |
285
|
|
|
*/ |
286
|
|
|
function store() { |
|
|
|
|
287
|
|
|
$this->_logger->entrance(); |
288
|
|
|
|
289
|
|
|
$option_name = $this->_get_option_manager_name(); |
290
|
|
|
|
291
|
|
|
if ( $this->_logger->is_on() ) { |
292
|
|
|
$this->_logger->info( $option_name . ' = ' . var_export( $this->_options, true ) ); |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
// Update DB. |
296
|
|
|
update_option( $option_name, $this->_options ); |
297
|
|
|
|
298
|
|
|
if ( ! WP_FS__DEBUG_SDK ) { |
299
|
|
|
wp_cache_set( $option_name, $this->_options, WP_FS__SLUG ); |
300
|
|
|
} |
301
|
|
|
} |
302
|
|
|
} |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.