PluginProbe
Passster – Password Protect Pages and Content / 4.3.17
Passster – Password Protect Pages and Content v4.3.17
4.3.17 4.3.16 4.3.15 4.3.14 4.3.12 4.3.13 4.3.11 4.3.10 4.3.9 4.3.8 4.3.7 4.3.6 4.3.5 trunk 3.5.4 3.5.5.2 3.5.5.8 3.5.5.9 4.0 4.1.4 4.2.10 4.2.11 4.2.12 4.2.13 4.2.14 All 49 releases
← All changes | inc/freemius/includes/managers/class-fs-key-value-storage.php +401 -401 4.3.8 → 4.3.17 View file →
@@ -1,402 +1,402 @@
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 - }
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 402 }