public function test_empty_field_with_empty_object_id() { $field = new CMB2_Field(array('field_args' => $this->field_args)); // data should be empty since we have no object id $this->assertEmpty($field->get_data()); // add some xss for good measure $dirty_val = 'test<html><stuff><script>xss</script><a href="http://xssattackexamples.com/">Click to Download</a>'; $cleaned_val = sanitize_text_field($dirty_val); // Make sure it sanitizes as expected $this->assertEquals($cleaned_val, $field->sanitization_cb($dirty_val)); // Sanitize/store the field $this->assertTrue($field->save_field($dirty_val)); // Retrieve saved value(s) $this->assertEquals($cleaned_val, cmb2_options(0)->get($field->id())); $this->assertEquals(array('test_test' => $cleaned_val), cmb2_options(0)->get_options()); }
/** * Loops through and saves field data * @since 1.0.0 * @param int $object_id Object ID * @param string $object_type Type of object being saved. (e.g., post, user, or comment) * @param array $data_to_save Array of key => value data for saving. Likely $_POST data. */ public function save_fields($object_id = 0, $object_type = '', $data_to_save) { $this->data_to_save = $data_to_save; $object_id = $this->object_id($object_id); $object_type = $this->object_type($object_type); $this->process_fields(); // If options page, save the updated options if ('options-page' == $object_type) { cmb2_options($object_id)->set(); } /** * Fires after all fields have been saved. * * The dynamic portion of the hook name, $object_type, refers to the metabox/form's object type * Usually `post` (this applies to all post-types). * Could also be `comment`, `user` or `options-page`. * * @param int $object_id The ID of the current object * @param array $cmb_id The current box ID * @param string $updated All fields that were updated. * Will only include fields that had values change. * @param array $cmb This CMB2 object */ do_action("cmb2_save_{$object_type}_fields", $object_id, $this->cmb_id, $this->updated, $this); }
/** * Removes/updates metadata/option data * @since 1.0.1 * @param string $old Old value */ public function remove_data($old = '') { $a = $this->data_args(array('old' => $old)); /** * Filter whether to override removing of meta value. * Returning a non-null value will effectively short-circuit the function. * * @since 2.0.0 * * @param null|bool $delete Whether to allow metadata deletion of the given type. * @param array $args Array of data about current field including: * 'type' : Current object type * 'id' : Current object ID * 'field_id' : Current Field ID * 'repeat' : Whether current field is repeatable * 'single' : Whether to save as a * single meta value * @param array $field_args All field arguments * @param CMB2_Field object $field This field object */ $override = apply_filters('cmb2_override_meta_remove', null, $a, $this->args(), $this); /** * Filter whether to override removing of meta value. * * The dynamic portion of the hook, $a['field_id'], refers to the current * field id paramater. Returning a non-null value * will effectively short-circuit the function. * * @since 2.0.0 * * @param null|bool $delete Whether to allow metadata deletion of the given type. * @param array $args Array of data about current field including: * 'type' : Current object type * 'id' : Current object ID * 'field_id' : Current Field ID * 'repeat' : Whether current field is repeatable * 'single' : Whether to save as a * single meta value * @param array $field_args All field arguments * @param CMB2_Field object $field This field object */ $override = apply_filters("cmb2_override_{$a['field_id']}_meta_remove", $override, $a, $this->args(), $this); // If no override, remove as usual if (null !== $override) { return $override; } elseif ('options-page' === $a['type'] || empty($a['id'])) { return cmb2_options($a['id'])->remove($a['field_id']); } // Remove metadata return delete_metadata($a['type'], $a['id'], $a['field_id'], $old); }
/** * Removes/updates metadata/option data * @since 1.0.1 * @param string $old Old value */ public function remove_data($old = '') { $a = $this->data_args(); return 'options-page' === $a['type'] ? cmb2_options($a['id'])->remove($a['field_id']) : delete_metadata($a['type'], $a['id'], $a['field_id'], $old); }
/** * A helper function to update an option in a CMB2 options array * @since 2.0.0 * @param string $option_key Option key * @param string $field_id Option array field key * @param mixed $value Value to update data with * @param boolean $single Whether data should not be an array * @return boolean Success/Failure */ function cmb2_update_option($option_key, $field_id, $value, $single = true) { if (cmb2_options($option_key)->update($field_id, $value, false, $single)) { return cmb2_options($option_key)->set(); } return false; }
public function test_class_getters() { $this->assertInstanceOf('CMB2_Ajax', cmb2_ajax()); $this->assertInstanceOf('CMB2_Utils', cmb2_utils()); $this->assertInstanceOf('CMB2_Option', cmb2_options('test')); }
/** * Loops through and saves field data * @since 1.0.0 * @param int $object_id Object ID * @param string $object_type Type of object being saved. (e.g., post, user, or comment) */ public function save_fields($object_id = 0, $object_type = '', $_post) { $object_id = $this->object_id($object_id); $object_type = $this->object_type($object_type); $this->prop('show_on', array('key' => false, 'value' => false)); // save field ids of those that are updated $this->updated = array(); foreach ($this->prop('fields') as $field_args) { if ('group' == $field_args['type']) { $this->save_group($field_args); } elseif ('title' == $field_args['type']) { // Don't process title fields continue; } else { // Save default fields $field = new CMB2_Field(array('field_args' => $field_args, 'object_type' => $object_type, 'object_id' => $object_id)); $field->save_field($_post); } } // If options page, save the updated options if ($object_type == 'options-page') { cmb2_options($object_id)->set(); } /** * Fires after all fields have been saved. * * The dynamic portion of the hook name, $object_type, refers to the metabox/form's object type * Usually `post` (this applies to all post-types). * Could also be `comment`, `user` or `options-page`. * * @param int $object_id The ID of the current object * @param array $cmb_id The current box ID * @param string $updated All fields that were updated. * Will only include fields that had values change. * @param array $cmb This CMB2 object */ do_action("cmb2_save_{$object_type}_fields", $object_id, $this->cmb_id, $this->updated, $this); }
/** * Saves the cached oEmbed value to relevant object metadata (vs postmeta) * * @since 1.3.0 * @param string $meta_key Postmeta's key * @param mixed $meta_value Value of the postmeta to be saved */ public function oembed_cache_set($meta_key, $meta_value) { // Cache the result to our metadata return 'options-page' !== $this->object_type ? update_metadata($this->object_type, $this->object_id, $meta_key, $meta_value) : cmb2_options($this->object_id)->update($this->embed_args['cache_key'], $meta_value, true); }
/** * Hooks in when options-page data is saved to clean stale * oembed cache data from the option value. * @since 2.2.0 * @param string $option_key The options-page option key * @return void */ public static function clean_stale_options_page_oembeds($option_key) { $options = cmb2_options($option_key)->get_options(); if (is_array($options)) { $ttl = apply_filters('oembed_ttl', DAY_IN_SECONDS, '', array(), 0); $now = time(); $modified = false; foreach ($options as $key => $value) { // Check for cached oembed data if (0 === strpos($key, '_oembed_time_')) { $cached_recently = $now - $value < $ttl; if (!$cached_recently) { $modified = true; // Remove the the cached ttl expiration, and the cached oembed value. unset($options[$key]); unset($options[str_replace('_oembed_time_', '_oembed_', $key)]); } } elseif ('{{unknown}}' === $value) { $modified = true; unset($options[$key]); } } } // Update the option and remove stale cache data if ($modified) { $updated = cmb2_options($option_key)->set($options); } }
/** * A helper function to get an option from a CMB options array * @since 1.0.1 * @param string $option_key Option key * @param string $field_id Option array field key * @return array Options array or specific field */ function cmb2_get_option($option_key, $field_id = '') { return cmb2_options($option_key)->get($field_id); }
/** * Updates metadata/option data * @since 1.0.1 * * @param mixed $new_value Value to update data with * @param bool $single Whether data is an array (add_metadata) */ public function update_data($new_value, $single = true) { $a = $this->data_args(array('single' => $single)); $a['value'] = $a['repeat'] ? array_values($new_value) : $new_value; /** * Filter whether to override saving of meta value. * Returning a non-null value will effectively short-circuit the function. * * @since 2.0.0 * * @param null|bool $check Whether to allow updating metadata for the given type. * * @param array $args { * Array of data about current field including: * * @type string $value The value to set * @type string $type The current object type * @type int $id The current object ID * @type string $field_id The ID of the field being updated * @type bool $repeat Whether current field is repeatable * @type bool $single Whether current field is a single database row * } * * @param array $field_args All field arguments * * @param CMB2_Field object $field This field object */ $override = apply_filters('cmb2_override_meta_save', null, $a, $this->args(), $this); /** * Filter and parameters are documented for 'cmb2_override_meta_save' filter (above). * * The dynamic portion of the hook, $a['field_id'], refers to the current * field id paramater. Returning a non-null value * will effectively short-circuit the function. * * @since 2.0.0 */ $override = apply_filters("cmb2_override_{$a['field_id']}_meta_save", $override, $a, $this->args(), $this); // If override, return that if (null !== $override) { return $override; } // Options page handling (or temp data store) if ('options-page' === $a['type'] || empty($a['id'])) { return cmb2_options($a['id'])->update($a['field_id'], $a['value'], false, $a['single']); } // Add metadata if not single if (!$a['single']) { return add_metadata($a['type'], $a['id'], $a['field_id'], $a['value'], false); } // Delete meta if we have an empty array if (is_array($a['value']) && empty($a['value'])) { return delete_metadata($a['type'], $a['id'], $a['field_id'], $this->value); } // Update metadata return update_metadata($a['type'], $a['id'], $a['field_id'], $a['value']); }
/** * Uses CMB2 field processing to sanitize fields * (Only applies if cmb_metabox_config parameter exists) * * @since 0.1.0 * * @return array Array of sanitized fields */ public function sanitize_cmb_fields() { $cmb = $this->get_cmb_object(); $cmb->data_to_save = $_REQUEST; $object_id = $cmb->object_id($this->button_slug); $cmb->object_type('options-page'); $cmb->process_fields(); // output buffer on the action so we don't pollute our JSON response ob_start(); // Preserve CMB action do_action('cmb2_save_options-page_fields', $object_id, $cmb->cmb_id, $cmb->updated, $cmb); ob_end_clean(); $updated_fields = cmb2_options($object_id)->get_options(); $cmb_config = $this->get_cmb_config(); $whitelist_keys = wp_list_pluck($cmb_config['fields'], 'id'); $whitelist = array(); // Keep only the form values that correspond to the CMB2 fields foreach ($whitelist_keys as $key) { $value = isset($updated_fields[$key]) && !empty($updated_fields[$key]) ? $updated_fields[$key] : ''; // Don't keep empty values if ($value) { // Make checkbox values boolean $whitelist[$key] = 'on' == $value ? true : $value; } } return $this->filter_form_fields($whitelist, $updated_fields); }
/** * Loops through and saves field data * @since 1.0.0 * @param int $object_id Object ID * @param string $object_type Type of object being saved. (e.g., post, user, or comment) * @param array $data_to_save Array of key => value data for saving. Likely $_POST data. */ public function save_fields($object_id = 0, $object_type = '', $data_to_save = array()) { // Fall-back to $_POST data $this->data_to_save = !empty($data_to_save) ? $data_to_save : $_POST; $object_id = $this->object_id($object_id); $object_type = $this->object_type($object_type); $this->process_fields(); // If options page, save the updated options if ('options-page' == $object_type) { cmb2_options($object_id)->set(); } $this->after_save(); }
/** * Returns term meta with options to return a subset * @since 0.1.3 * @param string $term_id The term id for the options we're getting * @param string $key Term meta key to check * @return mixed Requested value | false */ public function get_meta($term_id, $key = '') { if (!class_exists('CMB2')) { return; } $this->do_override_filters($term_id); $value = $key ? cmb2_get_option($this->id($term_id), $key) : cmb2_options($this->id($term_id))->get_options(); return $value; }