1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
<?php
/**
* CMB2 Utility classes for handling multi-dimensional array data for options
*
* @category WordPress_Plugin
* @package CMB2
* @author CMB2 team
* @license GPL-2.0+
* @link https://cmb2.io
*/
/**
* Retrieves an instance of CMB2_Option based on the option key
*
* @package CMB2
* @author CMB2 team
*/
class CMB2_Options {
/**
* Array of all CMB2_Option instances
*
* @var array
* @since 1.0.0
*/
protected static $option_sets = array();
public static function get( $option_key ) {
if ( empty( self::$option_sets ) || empty( self::$option_sets[ $option_key ] ) ) {
self::$option_sets[ $option_key ] = new CMB2_Option( $option_key );
}
return self::$option_sets[ $option_key ];
}
}
/**
* Handles getting/setting of values to an option array
* for a specific option key
*
* @package CMB2
* @author CMB2 team
*/
class CMB2_Option {
/**
* Options array
*
* @var array
*/
protected $options = array();
/**
* Current option key
*
* @var string
*/
protected $key = '';
/**
* Initiate option object
*
* @param string $option_key Option key where data will be saved.
* Leave empty for temporary data store.
* @since 2.0.0
*/
public function __construct( $option_key = '' ) {
$this->key = ! empty( $option_key ) ? $option_key : '';
}
/**
* Delete the option from the db
*
* @since 2.0.0
* @return mixed Delete success or failure
*/
public function delete_option() {
$deleted = $this->key ? delete_option( $this->key ) : true;
$this->options = $deleted ? array() : $this->options;
return $this->options;
}
/**
* Removes an option from an option array
*
* @since 1.0.1
* @param string $field_id Option array field key.
* @param bool $resave Whether or not to resave.
* @return array Modified options
*/
public function remove( $field_id, $resave = false ) {
$this->get_options();
if ( isset( $this->options[ $field_id ] ) ) {
unset( $this->options[ $field_id ] );
}
if ( $resave ) {
$this->set();
}
return $this->options;
}
/**
* Retrieves an option from an option array
*
* @since 1.0.1
* @param string $field_id Option array field key.
* @param mixed $default Fallback value for the option.
* @return array Requested field or default
*/
public function get( $field_id, $default = false ) {
$opts = $this->get_options();
if ( 'all' == $field_id ) {
return $opts;
} elseif ( array_key_exists( $field_id, $opts ) ) {
return false !== $opts[ $field_id ] ? $opts[ $field_id ] : $default;
}
return $default;
}
/**
* Updates Option data
*
* @since 1.0.1
* @param string $field_id Option array field key.
* @param mixed $value Value to update data with.
* @param bool $resave Whether to re-save the data.
* @param bool $single Whether data should not be an array.
* @return boolean Return status of update.
*/
public function update( $field_id, $value = '', $resave = false, $single = true ) {
$this->get_options();
if ( true !== $field_id ) {
if ( ! $single ) {
// If multiple, add to array.
$this->options[ $field_id ][] = $value;
} else {
$this->options[ $field_id ] = $value;
}
}
if ( $resave || true === $field_id ) {
return $this->set();
}
return true;
}
/**
* Saves the option array
* Needs to be run after finished using remove/update_option
*
* @uses apply_filters() Calls 'cmb2_override_option_save_{$this->key}' hook
* to allow overwriting the option value to be stored.
*
* @since 1.0.1
* @param array $options Optional options to override.
* @return bool Success/Failure
*/
public function set( $options = array() ) {
if ( ! empty( $options ) || empty( $options ) && empty( $this->key ) ) {
$this->options = $options;
}
$this->options = wp_unslash( $this->options ); // get rid of those evil magic quotes.
if ( empty( $this->key ) ) {
return false;
}
$test_save = apply_filters( "cmb2_override_option_save_{$this->key}", 'cmb2_no_override_option_save', $this->options, $this );
if ( 'cmb2_no_override_option_save' !== $test_save ) {
// If override, do not proceed to update the option, just return result.
return $test_save;
}
/**
* Whether to auto-load the option when WordPress starts up.
*
* The dynamic portion of the hook name, $this->key, refers to the option key.
*
* @since 2.4.0
*
* @param bool $autoload Whether to load the option when WordPress starts up.
* @param CMB2_Option $cmb_option This object.
*/
$autoload = apply_filters( "cmb2_should_autoload_{$this->key}", true, $this );
return update_option(
$this->key,
$this->options,
! $autoload || 'no' === $autoload ? false : true
);
}
/**
* Retrieve option value based on name of option.
*
* @uses apply_filters() Calls 'cmb2_override_option_get_{$this->key}' hook to allow
* overwriting the option value to be retrieved.
*
* @since 1.0.1
* @param mixed $default Optional. Default value to return if the option does not exist.
* @return mixed Value set for the option.
*/
public function get_options( $default = null ) {
if ( empty( $this->options ) && ! empty( $this->key ) ) {
$test_get = apply_filters( "cmb2_override_option_get_{$this->key}", 'cmb2_no_override_option_get', $default, $this );
if ( 'cmb2_no_override_option_get' !== $test_get ) {
$this->options = $test_get;
} else {
// If no override, get the option.
$this->options = get_option( $this->key, $default );
}
}
$this->options = (array) $this->options;
return $this->options;
}
/**
* Magic getter for our object.
*
* @since 2.6.0
*
* @param string $field Requested property.
* @throws Exception Throws an exception if the field is invalid.
* @return mixed
*/
public function __get( $field ) {
switch ( $field ) {
case 'options':
case 'key':
return $this->{$field};
default:
throw new Exception( sprintf( esc_html__( 'Invalid %1$s property: %2$s', 'cmb2' ), __CLASS__, $field ) );
}
}
}