0 ) { $key .= ":{$network_level_or_blog_id}"; } else { $network_level_or_blog_id = get_current_blog_id(); $key .= ":{$network_level_or_blog_id}"; } } if ( ! isset( self::$_instances[ $key ] ) ) { self::$_instances[ $key ] = new FS_Key_Value_Storage( $id, $secondary_id, $network_level_or_blog_id ); } return self::$_instances[ $key ]; } protected function __construct( $id, $secondary_id, $network_level_or_blog_id = false ) { $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $secondary_id . '_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); $this->_id = $id; $this->_secondary_id = $secondary_id; if ( is_multisite() ) { $this->_is_multisite_storage = ( true === $network_level_or_blog_id ); if ( is_numeric( $network_level_or_blog_id ) ) { $this->_blog_id = $network_level_or_blog_id; } } else { $this->_is_multisite_storage = false; } $this->load(); } protected function get_option_manager() { return FS_Option_Manager::get_manager( WP_FS__ACCOUNTS_OPTION_NAME, true, $this->_is_multisite_storage ? true : ( $this->_blog_id > 0 ? $this->_blog_id : false ) ); } protected function get_all_data() { return $this->get_option_manager()->get_option( $this->_id, array() ); } /** * Load plugin data from local DB. * * @author Vova Feldman (@svovaf) * @since 1.0.7 */ function load() { $all_plugins_data = $this->get_all_data(); $this->_data = isset( $all_plugins_data[ $this->_secondary_id ] ) ? $all_plugins_data[ $this->_secondary_id ] : array(); } /** * @author Vova Feldman (@svovaf) * @since 1.0.7 * * @param string $key * @param mixed $value * @param bool $flush */ function store( $key, $value, $flush = true ) { if ( $this->_logger->is_on() ) { $this->_logger->entrance( $key . ' = ' . var_export( $value, true ) ); } if ( array_key_exists( $key, $this->_data ) && $value === $this->_data[ $key ] ) { // No need to store data if the value wasn't changed. return; } $all_data = $this->get_all_data(); $this->_data[ $key ] = $value; $all_data[ $this->_secondary_id ] = $this->_data; $options_manager = $this->get_option_manager(); $options_manager->set_option( $this->_id, $all_data, $flush ); } /** * @author Vova Feldman (@svovaf) * @since 2.0.0 */ function save() { $this->get_option_manager()->store(); } /** * @author Vova Feldman (@svovaf) * @since 1.0.7 * * @param bool $store * @param string[] $exceptions Set of keys to keep and not clear. */ function clear_all( $store = true, $exceptions = array() ) { $new_data = array(); foreach ( $exceptions as $key ) { if ( isset( $this->_data[ $key ] ) ) { $new_data[ $key ] = $this->_data[ $key ]; } } $this->_data = $new_data; if ( $store ) { $all_data = $this->get_all_data(); $all_data[ $this->_secondary_id ] = $this->_data; $options_manager = $this->get_option_manager(); $options_manager->set_option( $this->_id, $all_data, true ); } } /** * Delete key-value storage. * * @author Vova Feldman (@svovaf) * @since 1.0.9 */ function delete() { $this->_data = array(); $all_data = $this->get_all_data(); unset( $all_data[ $this->_secondary_id ] ); $options_manager = $this->get_option_manager(); $options_manager->set_option( $this->_id, $all_data, true ); } /** * @author Vova Feldman (@svovaf) * @since 1.0.7 * * @param string $key * @param bool $store */ function remove( $key, $store = true ) { if ( ! array_key_exists( $key, $this->_data ) ) { return; } unset( $this->_data[ $key ] ); if ( $store ) { $all_data = $this->get_all_data(); $all_data[ $this->_secondary_id ] = $this->_data; $options_manager = $this->get_option_manager(); $options_manager->set_option( $this->_id, $all_data, true ); } } /** * @author Vova Feldman (@svovaf) * @since 1.0.7 * * @param string $key * @param mixed $default * * @return bool|\FS_Plugin */ function get( $key, $default = false ) { return array_key_exists( $key, $this->_data ) ? $this->_data[ $key ] : $default; } /** * @author Vova Feldman (@svovaf) * @since 2.0.0 * * @return string */ function get_secondary_id() { return $this->_secondary_id; } /* ArrayAccess + Magic Access (better for refactoring) -----------------------------------------------------------------------------------*/ function __set( $k, $v ) { $this->store( $k, $v ); } function __isset( $k ) { return array_key_exists( $k, $this->_data ); } function __unset( $k ) { $this->remove( $k ); } function __get( $k ) { return $this->get( $k, null ); } #[ReturnTypeWillChange] function offsetSet( $k, $v ) { if ( is_null( $k ) ) { throw new Exception( 'Can\'t append value to request params.' ); } else { $this->{$k} = $v; } } #[ReturnTypeWillChange] function offsetExists( $k ) { return array_key_exists( $k, $this->_data ); } #[ReturnTypeWillChange] function offsetUnset( $k ) { unset( $this->$k ); } #[ReturnTypeWillChange] function offsetGet( $k ) { return $this->get( $k, null ); } /** * (PHP 5 >= 5.0.0)
* Return the current element * * @link http://php.net/manual/en/iterator.current.php * @return mixed Can return any type. */ #[ReturnTypeWillChange] public function current() { return current( $this->_data ); } /** * (PHP 5 >= 5.0.0)
* Move forward to next element * * @link http://php.net/manual/en/iterator.next.php * @return void Any returned value is ignored. */ #[ReturnTypeWillChange] public function next() { next( $this->_data ); } /** * (PHP 5 >= 5.0.0)
* Return the key of the current element * * @link http://php.net/manual/en/iterator.key.php * @return mixed scalar on success, or null on failure. */ #[ReturnTypeWillChange] public function key() { return key( $this->_data ); } /** * (PHP 5 >= 5.0.0)
* Checks if current position is valid * * @link http://php.net/manual/en/iterator.valid.php * @return boolean The return value will be casted to boolean and then evaluated. * Returns true on success or false on failure. */ #[ReturnTypeWillChange] public function valid() { $key = key( $this->_data ); return ( $key !== null && $key !== false ); } /** * (PHP 5 >= 5.0.0)
* Rewind the Iterator to the first element * * @link http://php.net/manual/en/iterator.rewind.php * @return void Any returned value is ignored. */ #[ReturnTypeWillChange] public function rewind() { reset( $this->_data ); } /** * (PHP 5 >= 5.1.0)
* Count elements of an object * * @link http://php.net/manual/en/countable.count.php * @return int The custom count as an integer. *

*

* The return value is cast to an integer. */ #[ReturnTypeWillChange] public function count() { return count( $this->_data ); } }