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