public function get_value_from_attributes($attributes) { $attributes['type'] = $this->get_type(); $options = $this->get_shortcode_options(); if (!empty($options)) { if (empty($attributes['atts'])) { /** * The options popup was never opened and there are no attributes. * Extract options default values. */ $attributes['atts'] = fw_get_options_values_from_input($options, array()); } else { /** * There are saved attributes. * But we need to execute the _get_value_from_input() method for all options, * because some of them may be (need to be) changed (auto-generated) https://github.com/ThemeFuse/Unyson/issues/275 * Add the values to $option['value'] */ $options = fw_extract_only_options($options); foreach ($attributes['atts'] as $option_id => $option_value) { if (isset($options[$option_id])) { $options[$option_id]['value'] = $option_value; } } $attributes['atts'] = fw_get_options_values_from_input($options, array()); } } return $attributes; }
/** * @internal */ protected function _get_value_from_input($option, $input_value) { if (is_array($input_value) || empty($option['value'])) { $value = array(); } else { $value = $option['value']; } foreach (fw_extract_only_options($option['inner-options']) as $inner_id => $inner_option) { $value[$inner_id] = fw()->backend->option_type($inner_option['type'])->get_value_from_input(isset($value[$inner_id]) ? array_merge($inner_option, array('value' => $value[$inner_id])) : $inner_option, isset($input_value[$inner_id]) ? $input_value[$inner_id] : null); } return $value; }
/** * @internal */ protected function _get_value_from_input($option, $input_value) { if (!is_array($input_value)) { return $option['value']; } $value = array(); $box_options = fw_extract_only_options($option['box-options']); foreach ($input_value as &$list_item_value) { $current_value = array(); foreach ($box_options as $id => $input_option) { $current_value[$id] = fw()->backend->option_type($input_option['type'])->get_value_from_input($input_option, isset($list_item_value[$id]) ? $list_item_value[$id] : null); } $value[] = $current_value; } return $value; }
protected function get_fixed_attributes($attributes) { // do not allow sub items unset($attributes['_items']); $default_attributes = array('type' => $this->get_type(), 'shortcode' => false, 'width' => '', 'options' => array()); // remove unknown attributes $attributes = array_intersect_key($attributes, $default_attributes); $attributes = array_merge($default_attributes, $attributes); $only_options = array(); foreach (fw_extract_only_options($this->get_options()) as $option_id => $option) { if (array_key_exists($option_id, $attributes['options'])) { $option['value'] = $attributes['options'][$option_id]; } $only_options[$option_id] = $option; } $attributes['options'] = fw_get_options_values_from_input($only_options, array()); unset($only_options, $option_id, $option); $constraints = $attributes['options']['constraints']; if (!empty($constraints['constraint'])) { $constraint = $constraints['constraint']; $constraint_data = $constraints[$constraint]; switch ($constraint) { case 'characters': case 'words': if (!empty($constraint_data['min'])) { $constraint_data['min'] = intval($constraint_data['min']); if ($constraint_data['min'] < 0) { $constraint_data['min'] = 0; } } if (!empty($constraint_data['max'])) { $constraint_data['max'] = intval($constraint_data['max']); if ($constraint_data['max'] < 0 || $constraint_data['max'] < $constraint_data['min']) { $constraint_data['max'] = null; } } break; default: trigger_error('Invalid constraint: ' . $constraint, E_USER_WARNING); $attributes['options']['constraints']['constraint'] = ''; } $attributes['options']['constraints'][$constraint] = $constraint_data; } return $attributes; }
protected function get_fixed_attributes($attributes) { // do not allow sub items unset($attributes['_items']); $default_attributes = array('type' => $this->get_type(), 'shortcode' => 'form-header-title', 'width' => '', 'options' => array()); // remove unknown attributes $attributes = array_intersect_key($attributes, $default_attributes); $attributes = array_merge($default_attributes, $attributes); $only_options = array(); foreach (fw_extract_only_options($this->get_options()) as $option_id => $option) { if (array_key_exists($option_id, $attributes['options'])) { $option['value'] = $attributes['options'][$option_id]; } $only_options[$option_id] = $option; } $attributes['options'] = fw_get_options_values_from_input($only_options, array()); unset($only_options, $option_id, $option); return $attributes; }
protected function check_settings() { if (!$this->get_config('display')) { return; } $theme_options = fw_extract_only_options($this->get_parent()->get_settings_options()); $options = false; foreach ($theme_options as $option_name => $option_settings) { if ($option_settings['type'] !== 'style') { unset($theme_options[$option_name]); continue; } $options = $option_settings; break; } if (!empty($options['predefined'])) { $this->options = $options; $this->add_theme_actions(); } }
protected function check_settings() { if (!fw_get_db_ext_settings_option($this->get_parent()->get_name(), 'switch_style_panel_display')) { return; } $theme_options = fw_extract_only_options($this->get_parent()->get_options('appearance-settings')); $options = false; foreach ($theme_options as $option_name => $option_settings) { if ($option_settings['type'] !== 'style') { unset($theme_options[$option_name]); continue; } $options = $option_settings; break; } if (!empty($options['predefined'])) { $this->options = $options; $this->add_theme_actions(); } }
/** * @internal * {@inheritdoc} */ protected function _get_value_from_input($option, $input_value) { if (is_null($input_value)) { $value = $option['value']; } elseif (is_array($input_value)) { $option['limit'] = intval($option['limit']); $value = array(); $box_options = fw_extract_only_options($option['box-options']); foreach ($input_value as &$list_item_value) { $current_value = array(); foreach ($box_options as $id => $input_option) { $current_value[$id] = fw()->backend->option_type($input_option['type'])->get_value_from_input($input_option, isset($list_item_value[$id]) ? $list_item_value[$id] : null); } $value[] = $current_value; if ($option['limit'] && count($value) === $option['limit']) { break; } } } else { $value = array(); } return $value; }
/** * @internal */ protected function _get_value_from_input($option, $input_value) { reset($option['picker']); $picker_key = key($option['picker']); $picker_type = $option['picker'][$picker_key]['type']; $picker = $option['picker'][$picker_key]; $value = array(); if (is_null($input_value) && isset($option['value'][$picker_key])) { $value[$picker_key] = $option['value'][$picker_key]; } else { $value[$picker_key] = fw()->backend->option_type($picker_type)->get_value_from_input($picker, isset($input_value[$picker_key]) ? $input_value[$picker_key] : null); } // choices switch ($picker_type) { case 'switch': $choices = array_intersect_key($option['choices'], array($picker['left-choice']['value'] => array(), $picker['right-choice']['value'] => array())); break; case 'select': case 'short-select': // we need to treat the case with optgroups $collected_choices = array(); foreach ($picker['choices'] as $key => $choice_value) { if (is_array($choice_value) && isset($choice_value['choices'])) { // we have an optgroup $collected_choices = array_merge($collected_choices, $choice_value['choices']); } else { $collected_choices[$key] = $choice_value; } } $choices = array_intersect_key($option['choices'], $collected_choices); break; default: $choices = array_intersect_key($option['choices'], $picker['choices']); } foreach ($choices as $choice_id => $choice_options) { if (is_null($input_value) && isset($option['value'][$choice_id])) { $value[$choice_id] = $option['value'][$choice_id]; } else { foreach (fw_extract_only_options($choice_options) as $choice_option_id => $choice_option) { $value[$choice_id][$choice_option_id] = fw()->backend->option_type($choice_option['type'])->get_value_from_input($choice_option, isset($input_value[$choice_id][$choice_option_id]) ? $input_value[$choice_id][$choice_option_id] : null); } } } return $value; }
/** * Set post option value in database * * @param null|int $post_id * @param string|null $option_id Specific option id (accepts multikey). null - all options * @param $value */ function fw_set_db_post_option($post_id = null, $option_id = null, $value) { $post_id = intval($post_id); if (!$post_id) { /** @var WP_Post $post */ global $post; if (!$post) { return; } else { $post_id = $post->ID; } } $options = fw_extract_only_options(fw()->theme->get_post_options(get_post_type(($post_revision_id = wp_is_post_revision($post_id)) ? $post_revision_id : $post_id))); $sub_keys = null; if ($option_id) { $option_id = explode('/', $option_id); // 'option_id/sub/keys' $_option_id = array_shift($option_id); // 'option_id' $sub_keys = implode('/', $option_id); // 'sub/keys' $option_id = $_option_id; unset($_option_id); $old_value = fw_get_db_post_option($post_id, $option_id); if ($sub_keys) { // update sub_key in old_value and use the entire value $new_value = $old_value; fw_aks($sub_keys, $value, $new_value); $value = $new_value; unset($new_value); $old_value = fw_akg($sub_keys, $old_value); } if (isset($options[$option_id])) { $value = fw()->backend->option_type($options[$option_id]['type'])->storage_save($option_id, $options[$option_id], $value, array('post-id' => $post_id)); } FW_WP_Meta::set('post', $post_id, 'fw_options/' . $option_id, $value); } else { $old_value = fw_get_db_post_option($post_id); if (!is_array($value)) { $value = array(); } foreach ($value as $_option_id => $_option_value) { if (isset($options[$_option_id])) { $value[$_option_id] = fw()->backend->option_type($options[$_option_id]['type'])->storage_save($_option_id, $options[$_option_id], $_option_value, array('post-id' => $post_id)); } } FW_WP_Meta::set('post', $post_id, 'fw_options', $value); } /** * @deprecated */ fw()->backend->_sync_post_separate_meta($post_id); /** * @since 2.2.8 */ do_action('fw_post_options_update', $post_id, $option_id, explode('/', $sub_keys), $old_value); }
/** * Render options html from input json * * POST vars: * - options: '[{option_id: {...}}, {option_id: {...}}, ...]' // Required // String JSON * - values: {option_id: value, option_id: {...}, ...} // Optional // Object * - data: {id_prefix: 'fw_options-a-b-', name_prefix: 'fw_options[a][b]'} // Optional // Object */ public function _action_ajax_options_render() { if (!isset($_POST['options'])) { wp_send_json_error(array('message' => 'No options')); } $options = json_decode(FW_Request::POST('options'), true); if (!$options) { wp_send_json_error(array('message' => 'Wrong options')); } if (isset($_POST['values'])) { $values = FW_Request::POST('values'); } else { $values = array(); } if (isset($_POST['data'])) { $data = FW_Request::POST('data'); } else { $data = array(); } foreach (fw_extract_only_options($options) as $option_id => $option) { if (!isset($values[$option_id])) { continue; } /** * We detect if option is using booleans by sending it a boolean input value * If it returns a boolean, then it works with booleans */ if (!is_bool(fw()->backend->option_type($option['type'])->get_value_from_input($option, true))) { continue; } if (is_bool($values[$option_id])) { // value is already boolean, does not need to fix continue; } $values[$option_id] = $values[$option_id] === 'true'; } wp_send_json_success(array('html' => fw()->backend->render_options($options, $values, $data))); }
/** * Extract correct value for $option['value'] from input array * If input value is empty, will be returned $option['value'] * * @param array $option * @param array|string|null $input_value * * @return string|array|int|bool Correct value * @internal */ protected function _get_value_from_input($option, $input_value) { if (empty($input_value)) { if (empty($option['popup-options'])) { return array(); } $popup_options = array(); foreach (fw_extract_only_options($option['popup-options']) as $popup_option_id => $popup_option) { if (isset($option['value'][$popup_option_id])) { $popup_option['value'] = $option['value'][$popup_option_id]; } $popup_options[$popup_option_id] = $popup_option; } $values = fw_get_options_values_from_input($popup_options, array()); } else { if (is_array($input_value)) { /** * Don't decode if we have already an array */ $values = $input_value; } else { $values = json_decode($input_value, true); } } return $values; }
/** * {@inheritdoc} * fixes https://github.com/ThemeFuse/Unyson/issues/1440 */ protected function _storage_save($id, array $option, $value, array $params) { if (apply_filters('fw:option-type:multi-picker:fw-storage:process-inner-options', false)) { foreach ($option['choices'] as $choice_id => $choice) { foreach (fw_extract_only_options($choice) as $opt_id => $opt) { $value[$choice_id][$opt_id] = fw()->backend->option_type($opt['type'])->storage_save($opt_id, $opt, $value[$choice_id][$opt_id], $params); } } } return fw_db_option_storage_save($id, $option, $value, $params); }
/** * Triggers when the extension settings are saved, * it generates css from the styling settings and stores it * @internal */ public function _admin_action_generate_css() { $theme_options = fw_extract_only_options($this->get_options('appearance-settings')); $saved_data = fw_get_db_extension_data($this->get_name(), 'options'); $css_for_style_options = FW_Styling_Css_Generator::get_css($theme_options, $saved_data); fw_set_db_extension_data($this->get_name(), 'css', $css_for_style_options); }
/** * Extract correct value for $option['value'] from input array * If input value is empty, will be returned $option['value'] * @param array $option * @param array|string|null $input_value * @return string|array|int|bool Correct value * @internal */ protected function _get_value_from_input($option, $input_value) { if (!is_array($input_value)) { return $option['value']; } // unset the last slide that is default for add array_pop($input_value); $value = array(); $slides_options = fw_extract_only_options($option['slides_options']); foreach ($input_value as &$list_item_value) { $current_value = array(); foreach ($slides_options as $id => $input_option) { $current_value[$id] = fw()->backend->option_type($input_option['type'])->get_value_from_input($input_option, isset($list_item_value[$id]) ? $list_item_value[$id] : null); $current_value['thumb'] = isset($list_item_value['thumb']) ? $list_item_value['thumb'] : null; } $value[] = $current_value; } return $value; }
/** * Render options html from input json * * POST vars: * - options: '[{option_id: {...}}, {option_id: {...}}, ...]' // Required // String JSON * - values: {option_id: value, option_id: {...}, ...} // Optional // Object * - data: {id_prefix: 'fw_options-a-b-', name_prefix: 'fw_options[a][b]'} // Optional // Object */ public function _action_ajax_options_render() { if (!isset($_POST['options'])) { wp_send_json_error(array('message' => 'No options')); } $options = json_decode(FW_Request::POST('options'), true); if (!$options) { wp_send_json_error(array('message' => 'Wrong options')); } if (isset($_POST['values'])) { $values = FW_Request::POST('values'); if (is_string($values)) { $values = json_decode($values, true); } } else { $values = array(); } if (isset($_POST['data'])) { $data = FW_Request::POST('data'); } else { $data = array(); } foreach (fw_extract_only_options($options) as $option_id => $option) { if (!isset($values[$option_id])) { continue; } /** * Fix booleans * * In POST, booleans are transformed to strings: 'true' and 'false' * Transform them back to booleans */ do { /** * Detect if option is using booleans by sending it a boolean input value * If it returns a boolean, then it works with booleans */ if (!is_bool(fw()->backend->option_type($option['type'])->get_value_from_input($option, true))) { break; } if (is_bool($values[$option_id])) { // value is already boolean, does not need to fix break; } $values[$option_id] = $values[$option_id] === 'true'; continue 2; } while (false); /** * Fix integers * * In POST, integers are transformed to strings: '0', '1', '2', ... * Transform them back to integers */ do { if (!is_numeric($values[$option_id])) { // do nothing if value is not a number break; } /** * Detect if option is using integer value by checking $option['value'] */ if (isset($option['value']) && !is_int($option['value'])) { continue; } $values[$option_id] = (double) $values[$option_id]; continue 2; } while (false); } wp_send_json_success(array('html' => fw()->backend->render_options($options, $values, $data))); }
/** * Get correct values from input (POST) for given options * This values can be saved in db then replaced with $option['value'] for each option * @param array $options * @param array $input_array * @return array Values */ function fw_get_options_values_from_input(array $options, $input_array = null) { if (!is_array($input_array)) { $input_array = FW_Request::POST(FW_Option_Type::get_default_name_prefix()); } $values = array(); foreach (fw_extract_only_options($options) as $id => $option) { $values[$id] = fw()->backend->option_type($option['type'])->get_value_from_input($option, isset($input_array[$id]) ? $input_array[$id] : null); if (is_null($values[$id])) { // do not save null values unset($values[$id]); } } return $values; }
/** * Enqueue options static * * Useful when you have dynamic options html on the page (for e.g. options modal) * and in order to initialize that html properly, the option types scripts styles must be enqueued on the page * * @param array $options */ public function enqueue_options_static($options) { /** * register scripts and styles * in case if this method is called before enqueue_scripts action * and option types has some of these in their dependencies */ $this->register_static(); wp_enqueue_media(); wp_enqueue_style('fw-backend-options'); wp_enqueue_script('fw-backend-options'); foreach (fw_extract_only_options($options) as $option_id => $option) { fw()->backend->option_type($option['type'])->enqueue_static($option_id, $option); } }
/** * @internal */ protected function _get_value_from_input($option, $input_value) { reset($option['picker']); $picker_key = key($option['picker']); $picker_type = $option['picker'][$picker_key]['type']; $picker = $option['picker'][$picker_key]; $value = array(); if (is_null($input_value) && isset($option['value'][$picker_key])) { $value[$picker_key] = $option['value'][$picker_key]; } else { $value[$picker_key] = fw()->backend->option_type($picker_type)->get_value_from_input($picker, isset($input_value[$picker_key]) ? $input_value[$picker_key] : null); } foreach ($this->get_picker_choices($option, $picker, $picker_type) as $choice_id => $choice_options) { if (is_null($input_value) && isset($option['value'][$choice_id])) { $value[$choice_id] = $option['value'][$choice_id]; } else { foreach (fw_extract_only_options($choice_options) as $choice_option_id => $choice_option) { $value[$choice_id][$choice_option_id] = fw()->backend->option_type($choice_option['type'])->get_value_from_input($choice_option, isset($input_value[$choice_id][$choice_option_id]) ? $input_value[$choice_id][$choice_option_id] : null); } } } return $value; }
/** * Extract correct value for $option['value'] from input array * If input value is empty, will be returned $option['value'] * * @param array $option * @param array|string|null $input_value * * @return string|array|int|bool Correct value * @internal */ protected function _get_value_from_input($option, $input_value) { if (empty($input_value)) { if (empty($option['popup-options'])) { return array(); } /** * $option['value'] has DB format (not $input_value HTML format) * so it can't be used as second parameter in fw_get_options_values_from_input() * thus we need to move each option value in option array default values */ $popup_options = array(); foreach (fw_extract_only_options($option['popup-options']) as $popup_option_id => $popup_option) { if (isset($option['value'][$popup_option_id])) { $popup_option['value'] = $option['value'][$popup_option_id]; } $popup_options[$popup_option_id] = $popup_option; } $values = fw_get_options_values_from_input($popup_options, array()); } else { if (is_array($input_value)) { /** * Don't decode if we have already an array */ $values = fw_get_options_values_from_input($option['popup-options'], $input_value); } else { $values = fw_get_options_values_from_input($option['popup-options'], json_decode($input_value, true)); } } return $values; }
/** * Set post option value in database * * @param null|int $post_id * @param string|null $option_id Specific option id (accepts multikey). null - all options * @param $value */ function fw_set_db_post_option($post_id = null, $option_id = null, $value) { FW_Cache::del('fw_post_options/values'); $meta_key = 'fw_options'; $post_id = intval($post_id); if (!$post_id) { /** @var WP_Post $post */ global $post; if (!$post) { return; } else { $post_id = $post->ID; } } $post_type = get_post_type(($post_revision_id = wp_is_post_revision($post_id)) ? $post_revision_id : $post_id); try { $options = FW_Cache::get($cache_key = 'fw_post_options/only/' . $post_type); } catch (FW_Cache_Not_Found_Exception $e) { FW_Cache::set($cache_key, $options = array()); // prevent recursion if (apply_filters('fw_get_db_post_option:fw-storage-enabled', $post_type !== 'fw-slider', $post_type)) { FW_Cache::set($cache_key, $options = fw_extract_only_options(fw()->theme->get_post_options($post_type))); } } $sub_keys = null; if ($option_id) { $option_id = explode('/', $option_id); // 'option_id/sub/keys' $_option_id = array_shift($option_id); // 'option_id' $sub_keys = empty($option_id) ? null : implode('/', $option_id); // 'sub/keys' $option_id = $_option_id; unset($_option_id); $old_value = fw_get_db_post_option($post_id, $option_id); if ($sub_keys) { // update sub_key in old_value and use the entire value $new_value = $old_value; fw_aks($sub_keys, $value, $new_value); $value = $new_value; unset($new_value); $old_value = fw_akg($sub_keys, $old_value); } if (isset($options[$option_id])) { $value = fw()->backend->option_type($options[$option_id]['type'])->storage_save($option_id, $options[$option_id], $value, array('post-id' => $post_id)); } FW_WP_Meta::set('post', $post_id, $meta_key . '/' . $option_id, $value); } else { $old_value = fw_get_db_post_option($post_id); if (!is_array($value)) { $value = array(); } foreach ($value as $_option_id => $_option_value) { if (isset($options[$_option_id])) { $value[$_option_id] = fw()->backend->option_type($options[$_option_id]['type'])->storage_save($_option_id, $options[$_option_id], $_option_value, array('post-id' => $post_id)); } } FW_WP_Meta::set('post', $post_id, $meta_key, $value); } FW_Cache::del('fw_post_options/values'); // fixes https://github.com/ThemeFuse/Unyson/issues/1538 /** * @deprecated */ fw()->backend->_sync_post_separate_meta($post_id); /** * @since 2.2.8 */ do_action('fw_post_options_update', $post_id, $option_id, explode('/', $sub_keys), $old_value); }
/** * Render options html from input json * * POST vars: * - options: '[{option_id: {...}}, {option_id: {...}}, ...]' // Required // String JSON * - values: {option_id: value, option_id: {...}, ...} // Optional // Object * - data: {id_prefix: 'fw_options-a-b-', name_prefix: 'fw_options[a][b]'} // Optional // Object */ public function _action_ajax_options_render() { if (!isset($_POST['options'])) { wp_send_json_error(array('message' => 'No options')); } $options = json_decode(FW_Request::POST('options'), true); if (!$options) { wp_send_json_error(array('message' => 'Wrong options')); } if (isset($_POST['values'])) { $values = FW_Request::POST('values'); if (is_string($values)) { $values = json_decode($values, true); } } else { $values = array(); } $values = array_intersect_key($values, fw_extract_only_options($options)); if (isset($_POST['data'])) { $data = FW_Request::POST('data'); } else { $data = array(); } wp_send_json_success(array('html' => fw()->backend->render_options($options, $values, $data))); }
public final function set($item_id = null, $option_id = null, $value, array $extra_data = array()) { FW_Cache::del($cache_key_values = $this->get_cache_key('values', $item_id, $extra_data)); FW_Cache::del($cache_key_values_processed = $this->get_cache_key('values:processed', $item_id, $extra_data)); try { $options = FW_Cache::get($cache_key = $this->get_cache_key('options', $item_id, $extra_data)); } catch (FW_Cache_Not_Found_Exception $e) { FW_Cache::set($cache_key, array()); // prevent recursion FW_Cache::set($cache_key, $options = fw_extract_only_options($this->get_options($item_id, $extra_data))); } $sub_keys = null; if ($option_id) { $option_id = explode('/', $option_id); // 'option_id/sub/keys' $_option_id = array_shift($option_id); // 'option_id' $sub_keys = empty($option_id) ? null : implode('/', $option_id); // 'sub/keys' $option_id = $_option_id; unset($_option_id); $old_values = is_array($old_values = $this->get_values($item_id, $extra_data)) ? $old_values : array(); $old_value = isset($old_values[$option_id]) ? $old_values[$option_id] : null; if ($sub_keys) { // update sub_key in old_value and use the entire value $new_value = $old_value; fw_aks($sub_keys, $value, $new_value); $value = $new_value; unset($new_value); $old_value = fw_akg($sub_keys, $old_value); } if (isset($options[$option_id])) { $value = fw()->backend->option_type($options[$option_id]['type'])->storage_save($option_id, $options[$option_id], $value, $this->get_fw_storage_params($item_id, $extra_data)); } $old_values[$option_id] = $value; $this->set_values($item_id, $old_values, $extra_data); unset($old_values); } else { $old_value = is_array($old_values = $this->get_values($item_id, $extra_data)) ? $old_values : array(); if (!is_array($value)) { $value = array(); } foreach ($value as $_option_id => $_option_value) { if (isset($options[$_option_id])) { $value[$_option_id] = fw()->backend->option_type($options[$_option_id]['type'])->storage_save($_option_id, $options[$_option_id], $_option_value, $this->get_fw_storage_params($item_id, $extra_data)); } } $this->set_values($item_id, $value, $extra_data); } FW_Cache::del($cache_key_values); // fixes https://github.com/ThemeFuse/Unyson/issues/1538 FW_Cache::del($cache_key_values_processed); $this->_after_set($item_id, $option_id, $sub_keys, $old_value, $extra_data); }