Version Description
- Added option-type
unique
to make possible this - Added the
fw_get_google_fonts_v2()
function - Fixed: The newline character in textarea option in Customizer was replaced with
'rn'
string - Fixed: Post options (meta) lost after Quick Edit
- Option-type
multi-picker
: Allow support for any option type in picker (docs)
Download this release
Release Info
Developer | Unyson |
Plugin | Unyson |
Version | 2.3.2 |
Comparing to | |
See all releases |
Code changes from version 2.3.1 to 2.3.2
- framework/core/components/backend.php +48 -34
- framework/helpers/general.php +43 -3
- framework/includes/customizer/class--fw-customizer-control-option-wrapper.php +1 -35
- framework/includes/customizer/class--fw-customizer-setting-option.php +38 -0
- framework/includes/option-types/icon/static/js/backend.js +2 -2
- framework/includes/option-types/map/class-fw-option-type-map.php +2 -2
- framework/includes/option-types/multi-picker/class-fw-option-type-multi-picker.php +58 -61
- framework/includes/option-types/multi-picker/static/js/multi-picker.js +18 -5
- framework/includes/option-types/simple.php +92 -0
- framework/manifest.php +1 -1
- framework/static/css/fw.css +1 -0
- framework/static/css/option-types.css +2 -1
- readme.txt +8 -1
- unyson.php +1 -1
framework/core/components/backend.php
CHANGED
@@ -635,7 +635,13 @@ final class _FW_Component_Backend {
|
|
635 |
* @param bool $update
|
636 |
*/
|
637 |
public function _action_save_post( $post_id, $post, $update ) {
|
638 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
639 |
/**
|
640 |
* This happens on regular post form submit
|
641 |
* All data from $_POST belongs this $post
|
@@ -714,29 +720,37 @@ final class _FW_Component_Backend {
|
|
714 |
**/
|
715 |
public function _action_update_autosave_options( $post_id, $post ) {
|
716 |
remove_action( 'save_post', array( $this, '_action_update_autosave_options' ) );
|
|
|
717 |
remove_action( 'save_post', array( $this, '_action_save_post' ), 7 );
|
718 |
|
719 |
-
|
|
|
720 |
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
|
725 |
-
|
726 |
-
|
727 |
-
|
|
|
728 |
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
$
|
735 |
-
|
736 |
-
|
|
|
|
|
|
|
|
|
|
|
737 |
)
|
738 |
-
)
|
739 |
-
);
|
740 |
|
741 |
add_action( 'save_post', array( $this, '_action_save_post' ), 7, 3 );
|
742 |
}
|
@@ -1714,32 +1728,32 @@ final class _FW_Component_Backend {
|
|
1714 |
}
|
1715 |
}
|
1716 |
|
|
|
|
|
|
|
|
|
1717 |
if (!class_exists('_FW_Customizer_Control_Option_Wrapper')) {
|
1718 |
require_once fw_get_framework_directory('/includes/customizer/class--fw-customizer-control-option-wrapper.php');
|
1719 |
}
|
1720 |
|
1721 |
$wp_customize->add_setting(
|
1722 |
-
|
1723 |
-
|
1724 |
-
|
1725 |
-
|
1726 |
-
|
1727 |
-
|
|
|
1728 |
)
|
1729 |
);
|
1730 |
|
1731 |
-
$
|
1732 |
-
|
1733 |
-
|
1734 |
-
|
1735 |
-
|
1736 |
-
'fw_option' => $opt['option']
|
1737 |
)
|
1738 |
);
|
1739 |
-
|
1740 |
-
add_filter( "customize_sanitize_{$setting_id}", array($control, 'setting_sanitize_callback'), 10, 2 );
|
1741 |
-
|
1742 |
-
$wp_customize->add_control($control);
|
1743 |
break;
|
1744 |
default:
|
1745 |
trigger_error('Not supported option in customizer, type: '. $opt['type'], E_USER_WARNING); // todo: uncomment
|
635 |
* @param bool $update
|
636 |
*/
|
637 |
public function _action_save_post( $post_id, $post, $update ) {
|
638 |
+
if (
|
639 |
+
isset($_POST['post_ID'])
|
640 |
+
&&
|
641 |
+
intval($_POST['post_ID']) === intval($post_id)
|
642 |
+
&&
|
643 |
+
!empty($_POST[ FW_Option_Type::get_default_name_prefix() ]) // this happens on Quick Edit
|
644 |
+
) {
|
645 |
/**
|
646 |
* This happens on regular post form submit
|
647 |
* All data from $_POST belongs this $post
|
720 |
**/
|
721 |
public function _action_update_autosave_options( $post_id, $post ) {
|
722 |
remove_action( 'save_post', array( $this, '_action_update_autosave_options' ) );
|
723 |
+
|
724 |
remove_action( 'save_post', array( $this, '_action_save_post' ), 7 );
|
725 |
|
726 |
+
do {
|
727 |
+
$parent = get_post($post->post_parent);
|
728 |
|
729 |
+
if ( ! $parent instanceof WP_Post ) {
|
730 |
+
break;
|
731 |
+
}
|
732 |
|
733 |
+
if (empty($_POST[ FW_Option_Type::get_default_name_prefix() ])) {
|
734 |
+
// this happens on Quick Edit
|
735 |
+
break;
|
736 |
+
}
|
737 |
|
738 |
+
$current_values = fw_get_options_values_from_input(
|
739 |
+
fw()->theme->get_post_options($parent->post_type)
|
740 |
+
);
|
741 |
+
|
742 |
+
fw_set_db_post_option(
|
743 |
+
$post->ID,
|
744 |
+
null,
|
745 |
+
array_diff_key( // remove handled values
|
746 |
+
$current_values,
|
747 |
+
$this->process_options_handlers(
|
748 |
+
fw()->theme->get_post_options($parent->post_type),
|
749 |
+
$current_values
|
750 |
+
)
|
751 |
)
|
752 |
+
);
|
753 |
+
} while(false);
|
754 |
|
755 |
add_action( 'save_post', array( $this, '_action_save_post' ), 7, 3 );
|
756 |
}
|
1728 |
}
|
1729 |
}
|
1730 |
|
1731 |
+
if (!class_exists('_FW_Customizer_Setting_Option')) {
|
1732 |
+
require_once fw_get_framework_directory('/includes/customizer/class--fw-customizer-setting-option.php');
|
1733 |
+
}
|
1734 |
+
|
1735 |
if (!class_exists('_FW_Customizer_Control_Option_Wrapper')) {
|
1736 |
require_once fw_get_framework_directory('/includes/customizer/class--fw-customizer-control-option-wrapper.php');
|
1737 |
}
|
1738 |
|
1739 |
$wp_customize->add_setting(
|
1740 |
+
new _FW_Customizer_Setting_Option(
|
1741 |
+
$wp_customize,
|
1742 |
+
$setting_id,
|
1743 |
+
array(
|
1744 |
+
'default' => fw()->backend->option_type($opt['option']['type'])->get_value_from_input($opt['option'], null),
|
1745 |
+
'fw_option' => $opt['option'],
|
1746 |
+
)
|
1747 |
)
|
1748 |
);
|
1749 |
|
1750 |
+
$wp_customize->add_control(
|
1751 |
+
new _FW_Customizer_Control_Option_Wrapper(
|
1752 |
+
$wp_customize,
|
1753 |
+
$opt['id'],
|
1754 |
+
$args
|
|
|
1755 |
)
|
1756 |
);
|
|
|
|
|
|
|
|
|
1757 |
break;
|
1758 |
default:
|
1759 |
trigger_error('Not supported option in customizer, type: '. $opt['type'], E_USER_WARNING); // todo: uncomment
|
framework/helpers/general.php
CHANGED
@@ -570,12 +570,16 @@ function fw_get_variables_from_file($file_path, array $_variables) {
|
|
570 |
/**
|
571 |
* Use this function to not include files directly and to not give access to current context variables (like $this)
|
572 |
* @param string $file_path
|
|
|
573 |
* @return bool If was included or not
|
574 |
*/
|
575 |
-
function fw_include_file_isolated($file_path) {
|
576 |
if (file_exists($file_path)) {
|
577 |
-
|
578 |
-
|
|
|
|
|
|
|
579 |
return true;
|
580 |
} else {
|
581 |
return false;
|
@@ -830,6 +834,42 @@ function fw_get_google_fonts() {
|
|
830 |
}
|
831 |
}
|
832 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
833 |
/**
|
834 |
* @return string Current url
|
835 |
*/
|
570 |
/**
|
571 |
* Use this function to not include files directly and to not give access to current context variables (like $this)
|
572 |
* @param string $file_path
|
573 |
+
* @param bool $once
|
574 |
* @return bool If was included or not
|
575 |
*/
|
576 |
+
function fw_include_file_isolated($file_path, $once = false) {
|
577 |
if (file_exists($file_path)) {
|
578 |
+
if ( (bool) $once ) {
|
579 |
+
include_once $file_path;
|
580 |
+
} else {
|
581 |
+
include $file_path;
|
582 |
+
}
|
583 |
return true;
|
584 |
} else {
|
585 |
return false;
|
834 |
}
|
835 |
}
|
836 |
|
837 |
+
/**
|
838 |
+
* @return Array with Google fonts
|
839 |
+
*/
|
840 |
+
function fw_get_google_fonts_v2() {
|
841 |
+
$saved_data = get_option( 'fw_google_fonts', false );
|
842 |
+
|
843 |
+
if (
|
844 |
+
false === $saved_data
|
845 |
+
||
|
846 |
+
( time() - $saved_data['last_update'] > ( time() - 7 * DAY_IN_SECONDS ) )
|
847 |
+
) {
|
848 |
+
$response = wp_remote_get( apply_filters( 'fw_googleapis_webfonts_url', 'http://google-webfonts-cache.unyson.io/v1/webfonts' ) );
|
849 |
+
$body = wp_remote_retrieve_body( $response );
|
850 |
+
|
851 |
+
if (
|
852 |
+
200 === wp_remote_retrieve_response_code( $response )
|
853 |
+
&&
|
854 |
+
! is_wp_error( $body ) && ! empty( $body )
|
855 |
+
) {
|
856 |
+
update_option( 'fw_google_fonts', array(
|
857 |
+
'last_update' => time(),
|
858 |
+
'fonts' => $body
|
859 |
+
) );
|
860 |
+
|
861 |
+
return $body;
|
862 |
+
} else {
|
863 |
+
return ( ! empty( $saved_data['fonts'] ) )
|
864 |
+
? $saved_data['fonts']
|
865 |
+
: json_encode( array( 'items' => array() )
|
866 |
+
);
|
867 |
+
}
|
868 |
+
}
|
869 |
+
|
870 |
+
return $saved_data['fonts'];
|
871 |
+
}
|
872 |
+
|
873 |
/**
|
874 |
* @return string Current url
|
875 |
*/
|
framework/includes/customizer/class--fw-customizer-control-option-wrapper.php
CHANGED
@@ -1,14 +1,6 @@
|
|
1 |
<?php if (!defined('FW')) die('Forbidden');
|
2 |
|
3 |
class _FW_Customizer_Control_Option_Wrapper extends WP_Customize_Control {
|
4 |
-
private $fw_option = array();
|
5 |
-
|
6 |
-
public function __construct( $manager, $id, array $args, array $data ) {
|
7 |
-
parent::__construct( $manager, $id, $args);
|
8 |
-
|
9 |
-
$this->fw_option = $data['fw_option'];
|
10 |
-
}
|
11 |
-
|
12 |
public function render_content() {
|
13 |
fw()->backend->_set_default_render_design('customizer');
|
14 |
?>
|
@@ -17,7 +9,7 @@ class _FW_Customizer_Control_Option_Wrapper extends WP_Customize_Control {
|
|
17 |
<div class="fw-backend-customizer-option-inner fw-force-xs">
|
18 |
<?php
|
19 |
echo fw()->backend->render_options(
|
20 |
-
array($this->id => $this->
|
21 |
array(
|
22 |
$this->id => $this->value()
|
23 |
),
|
@@ -30,30 +22,4 @@ class _FW_Customizer_Control_Option_Wrapper extends WP_Customize_Control {
|
|
30 |
<?php
|
31 |
fw()->backend->_set_default_render_design();
|
32 |
}
|
33 |
-
|
34 |
-
public function setting_sanitize_callback($input) {
|
35 |
-
$input = json_decode($input, true);
|
36 |
-
|
37 |
-
if (is_null($input)) {
|
38 |
-
return null;
|
39 |
-
}
|
40 |
-
|
41 |
-
$POST = array();
|
42 |
-
foreach ($input as $var) {
|
43 |
-
fw_aks(
|
44 |
-
fw_html_attr_name_to_array_multi_key($var['name']),
|
45 |
-
$var['value'],
|
46 |
-
$POST
|
47 |
-
);
|
48 |
-
}
|
49 |
-
|
50 |
-
$value = fw_get_options_values_from_input(
|
51 |
-
array($this->id => $this->fw_option),
|
52 |
-
fw_akg(FW_Option_Type::get_default_name_prefix(), $POST)
|
53 |
-
);
|
54 |
-
|
55 |
-
$value = array_pop($value);
|
56 |
-
|
57 |
-
return $value;
|
58 |
-
}
|
59 |
}
|
1 |
<?php if (!defined('FW')) die('Forbidden');
|
2 |
|
3 |
class _FW_Customizer_Control_Option_Wrapper extends WP_Customize_Control {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
public function render_content() {
|
5 |
fw()->backend->_set_default_render_design('customizer');
|
6 |
?>
|
9 |
<div class="fw-backend-customizer-option-inner fw-force-xs">
|
10 |
<?php
|
11 |
echo fw()->backend->render_options(
|
12 |
+
array($this->id => $this->setting->get_fw_option()),
|
13 |
array(
|
14 |
$this->id => $this->value()
|
15 |
),
|
22 |
<?php
|
23 |
fw()->backend->_set_default_render_design();
|
24 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
framework/includes/customizer/class--fw-customizer-setting-option.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php if (!defined('FW')) die('Forbidden');
|
2 |
+
|
3 |
+
class _FW_Customizer_Setting_Option extends WP_Customize_Setting {
|
4 |
+
/**
|
5 |
+
* @var array
|
6 |
+
* This is sent in args and set in parent construct
|
7 |
+
*/
|
8 |
+
protected $fw_option = array();
|
9 |
+
|
10 |
+
public function get_fw_option() {
|
11 |
+
return $this->fw_option;
|
12 |
+
}
|
13 |
+
|
14 |
+
public function sanitize($value) {
|
15 |
+
$value = json_decode($value, true);
|
16 |
+
|
17 |
+
if (is_null($value) || !is_array($value)) {
|
18 |
+
return null;
|
19 |
+
}
|
20 |
+
|
21 |
+
$POST = array();
|
22 |
+
|
23 |
+
foreach ($value as $var) {
|
24 |
+
fw_aks(
|
25 |
+
fw_html_attr_name_to_array_multi_key($var['name']),
|
26 |
+
$var['value'],
|
27 |
+
$POST
|
28 |
+
);
|
29 |
+
}
|
30 |
+
|
31 |
+
$value = fw()->backend->option_type($this->fw_option['type'])->get_value_from_input(
|
32 |
+
$this->fw_option,
|
33 |
+
fw_akg(fw_html_attr_name_to_array_multi_key($this->id), $POST)
|
34 |
+
);
|
35 |
+
|
36 |
+
return $value;
|
37 |
+
}
|
38 |
+
}
|
framework/includes/option-types/icon/static/js/backend.js
CHANGED
@@ -11,10 +11,10 @@ jQuery(function ($) {
|
|
11 |
|
12 |
if ($this.hasClass('active')) {
|
13 |
$this.removeClass('active');
|
14 |
-
$this.closest(optionTypeClass).find('input').val('');
|
15 |
} else {
|
16 |
$this.addClass('active').siblings().removeClass('active');
|
17 |
-
$this.closest(optionTypeClass).find('input').val($this.data('value'));
|
18 |
}
|
19 |
});
|
20 |
|
11 |
|
12 |
if ($this.hasClass('active')) {
|
13 |
$this.removeClass('active');
|
14 |
+
$this.closest(optionTypeClass).find('input').val('').trigger('change');
|
15 |
} else {
|
16 |
$this.addClass('active').siblings().removeClass('active');
|
17 |
+
$this.closest(optionTypeClass).find('input').val($this.data('value')).trigger('change');
|
18 |
}
|
19 |
});
|
20 |
|
framework/includes/option-types/map/class-fw-option-type-map.php
CHANGED
@@ -80,9 +80,9 @@ class FW_Option_Type_Map extends FW_Option_Type {
|
|
80 |
'country' => ( isset ( $input_value['country'] ) ) ? $input_value['country'] : '',
|
81 |
'zip' => ( isset ( $input_value['zip'] ) ) ? $input_value['zip'] : '',
|
82 |
'coordinates' => ( isset ( $input_value['coordinates'] ) )
|
83 |
-
? ( is_array($input_value['coordinates']) )
|
84 |
? $input_value['coordinates']
|
85 |
-
: json_decode($input_value['coordinates'])
|
86 |
: ''
|
87 |
);
|
88 |
|
80 |
'country' => ( isset ( $input_value['country'] ) ) ? $input_value['country'] : '',
|
81 |
'zip' => ( isset ( $input_value['zip'] ) ) ? $input_value['zip'] : '',
|
82 |
'coordinates' => ( isset ( $input_value['coordinates'] ) )
|
83 |
+
? ( is_array($input_value['coordinates']) || is_object($input_value['coordinates']) )
|
84 |
? $input_value['coordinates']
|
85 |
+
: json_decode($input_value['coordinates'], true)
|
86 |
: ''
|
87 |
);
|
88 |
|
framework/includes/option-types/multi-picker/class-fw-option-type-multi-picker.php
CHANGED
@@ -41,13 +41,13 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
41 |
$uri = fw_get_framework_directory_uri('/includes/option-types/' . $this->get_type());
|
42 |
|
43 |
wp_enqueue_style(
|
44 |
-
'fw-option-type' . $this->get_type(),
|
45 |
$uri . '/static/css/multi-picker.css',
|
46 |
array(),
|
47 |
fw()->manifest->get_version()
|
48 |
);
|
49 |
wp_enqueue_script(
|
50 |
-
'fw-option-type' . $this->get_type(),
|
51 |
$uri . '/static/js/multi-picker.js',
|
52 |
array('jquery', 'fw-events'),
|
53 |
fw()->manifest->get_version(),
|
@@ -126,36 +126,13 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
126 |
return 'multi-picker';
|
127 |
}
|
128 |
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
}
|
137 |
-
|
138 |
-
{
|
139 |
-
reset($option['picker']);
|
140 |
-
$picker_key = key($option['picker']);
|
141 |
-
$picker = $option['picker'][$picker_key];
|
142 |
-
$picker_type = $picker['type'];
|
143 |
-
}
|
144 |
-
|
145 |
-
$supported_picker_types = array('select', 'short-select', 'radio', 'image-picker', 'switch',
|
146 |
-
'color-palette' // fixme: this is a temporary hardcode for a ThemeFuse theme option-type, think a way to allow other option-types here
|
147 |
-
);
|
148 |
-
if (!in_array($picker_type, $supported_picker_types)) {
|
149 |
-
trigger_error(
|
150 |
-
sprintf(
|
151 |
-
__('Invalid picker type for multi-picker option %s, only pickers of types %s are supported', 'fw'),
|
152 |
-
$id,
|
153 |
-
implode(', ', $supported_picker_types)
|
154 |
-
),
|
155 |
-
E_USER_ERROR
|
156 |
-
);
|
157 |
-
}
|
158 |
-
|
159 |
switch($picker_type) {
|
160 |
case 'switch':
|
161 |
$picker_choices = array_intersect_key($option['choices'], array(
|
@@ -177,10 +154,46 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
177 |
}
|
178 |
$picker_choices = array_intersect_key($option['choices'], $collected_choices);
|
179 |
break;
|
180 |
-
|
|
|
181 |
$picker_choices = array_intersect_key($option['choices'], $picker['choices']);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
}
|
183 |
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
$hide_picker = '';
|
185 |
$show_borders = '';
|
186 |
|
@@ -207,7 +220,10 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
207 |
if (!empty($set)) {
|
208 |
$choices_groups[$id . '-' . $key] = array(
|
209 |
'type' => 'group',
|
210 |
-
'attr' => array(
|
|
|
|
|
|
|
211 |
'options' => array(
|
212 |
$key => array(
|
213 |
'type' => 'multi',
|
@@ -257,33 +273,14 @@ class FW_Option_Type_Multi_Picker extends FW_Option_Type
|
|
257 |
);
|
258 |
}
|
259 |
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
$
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
case 'select':
|
269 |
-
case 'short-select':
|
270 |
-
// we need to treat the case with optgroups
|
271 |
-
$collected_choices = array();
|
272 |
-
foreach ($picker['choices'] as $key => $choice_value) {
|
273 |
-
if (is_array($choice_value) && isset($choice_value['choices'])) {
|
274 |
-
// we have an optgroup
|
275 |
-
$collected_choices = array_merge($collected_choices, $choice_value['choices']);
|
276 |
-
} else {
|
277 |
-
$collected_choices[$key] = $choice_value;
|
278 |
-
}
|
279 |
-
}
|
280 |
-
$choices = array_intersect_key($option['choices'], $collected_choices);
|
281 |
-
break;
|
282 |
-
default:
|
283 |
-
$choices = array_intersect_key($option['choices'], $picker['choices']);
|
284 |
-
}
|
285 |
-
|
286 |
-
foreach ($choices as $choice_id => $choice_options) {
|
287 |
if (is_null($input_value) && isset($option['value'][$choice_id])) {
|
288 |
$value[$choice_id] = $option['value'][$choice_id];
|
289 |
} else {
|
41 |
$uri = fw_get_framework_directory_uri('/includes/option-types/' . $this->get_type());
|
42 |
|
43 |
wp_enqueue_style(
|
44 |
+
'fw-option-type-' . $this->get_type(),
|
45 |
$uri . '/static/css/multi-picker.css',
|
46 |
array(),
|
47 |
fw()->manifest->get_version()
|
48 |
);
|
49 |
wp_enqueue_script(
|
50 |
+
'fw-option-type-' . $this->get_type(),
|
51 |
$uri . '/static/js/multi-picker.js',
|
52 |
array('jquery', 'fw-events'),
|
53 |
fw()->manifest->get_version(),
|
126 |
return 'multi-picker';
|
127 |
}
|
128 |
|
129 |
+
/**
|
130 |
+
* @param array $option
|
131 |
+
* @param array $picker
|
132 |
+
* @param string $picker_type
|
133 |
+
* @return array( 'choice_id' => array( Choice Options ) )
|
134 |
+
*/
|
135 |
+
private function get_picker_choices($option, $picker, $picker_type) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
switch($picker_type) {
|
137 |
case 'switch':
|
138 |
$picker_choices = array_intersect_key($option['choices'], array(
|
154 |
}
|
155 |
$picker_choices = array_intersect_key($option['choices'], $collected_choices);
|
156 |
break;
|
157 |
+
case 'radio':
|
158 |
+
case 'image-picker':
|
159 |
$picker_choices = array_intersect_key($option['choices'], $picker['choices']);
|
160 |
+
break;
|
161 |
+
default:
|
162 |
+
$picker_choices = apply_filters(
|
163 |
+
'fw_option_type_multi_picker_choices:'. $picker_type,
|
164 |
+
$option['choices'],
|
165 |
+
array(
|
166 |
+
'picker' => $picker,
|
167 |
+
'option' => $option,
|
168 |
+
)
|
169 |
+
);
|
170 |
+
}
|
171 |
+
|
172 |
+
return $picker_choices;
|
173 |
+
}
|
174 |
+
|
175 |
+
private function prepare_option($id, $option)
|
176 |
+
{
|
177 |
+
if (empty($option['picker'])) {
|
178 |
+
trigger_error(
|
179 |
+
sprintf(__('No \'picker\' key set for multi-picker option: %s', 'fw'), $id),
|
180 |
+
E_USER_ERROR
|
181 |
+
);
|
182 |
+
}
|
183 |
+
|
184 |
+
{
|
185 |
+
reset($option['picker']);
|
186 |
+
$picker_key = key($option['picker']);
|
187 |
+
$picker = $option['picker'][$picker_key];
|
188 |
+
$picker_type = $picker['type'];
|
189 |
}
|
190 |
|
191 |
+
$picker_choices = $this->get_picker_choices(
|
192 |
+
$option,
|
193 |
+
$picker,
|
194 |
+
$picker_type
|
195 |
+
);
|
196 |
+
|
197 |
$hide_picker = '';
|
198 |
$show_borders = '';
|
199 |
|
220 |
if (!empty($set)) {
|
221 |
$choices_groups[$id . '-' . $key] = array(
|
222 |
'type' => 'group',
|
223 |
+
'attr' => array(
|
224 |
+
'class' => 'choice-group',
|
225 |
+
'data-choice-key' => $key,
|
226 |
+
),
|
227 |
'options' => array(
|
228 |
$key => array(
|
229 |
'type' => 'multi',
|
273 |
);
|
274 |
}
|
275 |
|
276 |
+
foreach (
|
277 |
+
$this->get_picker_choices(
|
278 |
+
$option,
|
279 |
+
$picker,
|
280 |
+
$picker_type
|
281 |
+
)
|
282 |
+
as $choice_id => $choice_options
|
283 |
+
) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
284 |
if (is_null($input_value) && isset($option['value'][$choice_id])) {
|
285 |
$value[$choice_id] = $option['value'][$choice_id];
|
286 |
} else {
|
framework/includes/option-types/multi-picker/static/js/multi-picker.js
CHANGED
@@ -6,7 +6,7 @@
|
|
6 |
$choicesGroups: $this.find('> .choice-group')
|
7 |
},
|
8 |
chooseGroup = function(groupId) {
|
9 |
-
var $choicesToReveal = elements.$choicesGroups.filter('.choice-'
|
10 |
|
11 |
/**
|
12 |
* The group options html was rendered in an attribute to make page load faster.
|
@@ -40,8 +40,8 @@
|
|
40 |
var $this = $(this),
|
41 |
checked = $(this).is(':checked'),
|
42 |
value = checked
|
43 |
-
|
44 |
-
|
45 |
|
46 |
chooseGroup(value);
|
47 |
}).trigger('change');
|
@@ -66,10 +66,23 @@
|
|
66 |
}
|
67 |
};
|
68 |
|
69 |
-
if (!pickerType
|
70 |
console.error('unknown multi-picker type:', pickerType);
|
71 |
} else {
|
72 |
-
flows[pickerType]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
}
|
74 |
};
|
75 |
|
6 |
$choicesGroups: $this.find('> .choice-group')
|
7 |
},
|
8 |
chooseGroup = function(groupId) {
|
9 |
+
var $choicesToReveal = elements.$choicesGroups.filter('.choice-group[data-choice-key="'+ groupId +'"]');
|
10 |
|
11 |
/**
|
12 |
* The group options html was rendered in an attribute to make page load faster.
|
40 |
var $this = $(this),
|
41 |
checked = $(this).is(':checked'),
|
42 |
value = checked
|
43 |
+
? $this.attr('data-switch-right-value')
|
44 |
+
: $this.attr('data-switch-left-value');
|
45 |
|
46 |
chooseGroup(value);
|
47 |
}).trigger('change');
|
66 |
}
|
67 |
};
|
68 |
|
69 |
+
if (!pickerType) {
|
70 |
console.error('unknown multi-picker type:', pickerType);
|
71 |
} else {
|
72 |
+
if (flows[pickerType]) {
|
73 |
+
flows[pickerType]();
|
74 |
+
} else {
|
75 |
+
var eventName = 'fw:option-type:multi-picker:init:'+ pickerType;
|
76 |
+
|
77 |
+
if (fwe.hasListeners(eventName)) {
|
78 |
+
fwe.trigger(eventName, {
|
79 |
+
'$pickerGroup': elements.$pickerGroup,
|
80 |
+
'chooseGroup': chooseGroup
|
81 |
+
});
|
82 |
+
} else {
|
83 |
+
console.error('uninitialized multi-picker type:', pickerType);
|
84 |
+
}
|
85 |
+
}
|
86 |
}
|
87 |
};
|
88 |
|
framework/includes/option-types/simple.php
CHANGED
@@ -960,3 +960,95 @@ class FW_Option_Type_Select_Multiple extends FW_Option_Type_Select {
|
|
960 |
}
|
961 |
|
962 |
FW_Option_Type::register( 'FW_Option_Type_Select_Multiple' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
960 |
}
|
961 |
|
962 |
FW_Option_Type::register( 'FW_Option_Type_Select_Multiple' );
|
963 |
+
|
964 |
+
|
965 |
+
class FW_Option_Type_Unique extends FW_Option_Type
|
966 |
+
{
|
967 |
+
private static $ids = array();
|
968 |
+
|
969 |
+
public function get_type()
|
970 |
+
{
|
971 |
+
return 'unique';
|
972 |
+
}
|
973 |
+
|
974 |
+
protected function _get_defaults()
|
975 |
+
{
|
976 |
+
return array(
|
977 |
+
'value' => ''
|
978 |
+
);
|
979 |
+
}
|
980 |
+
|
981 |
+
protected function _render($id, $option, $data) {
|
982 |
+
return fw_html_tag('input', array(
|
983 |
+
'type' => 'hidden',
|
984 |
+
'name' => $option['attr']['name'],
|
985 |
+
'id' => $option['attr']['id'],
|
986 |
+
'value' => $data['value'],
|
987 |
+
));
|
988 |
+
}
|
989 |
+
|
990 |
+
protected function _init() {
|
991 |
+
add_action('save_post', array($this, '_action_reset_post_ids'), 8);
|
992 |
+
}
|
993 |
+
|
994 |
+
/**
|
995 |
+
* After the post has been saved
|
996 |
+
* other scripts may call wp_update_post() and the save will start again
|
997 |
+
* If the unique ids array will not be reset, on the next save
|
998 |
+
* the previously processed ids will all be detected as duplicate and will be regenerated
|
999 |
+
*
|
1000 |
+
* @param $post_id
|
1001 |
+
* @internal
|
1002 |
+
*/
|
1003 |
+
public function _action_reset_post_ids($post_id)
|
1004 |
+
{
|
1005 |
+
if ( wp_is_post_autosave( $post_id ) ) {
|
1006 |
+
$original_id = wp_is_post_autosave( $post_id );
|
1007 |
+
} else if ( wp_is_post_revision( $post_id ) ) {
|
1008 |
+
$original_id = wp_is_post_revision( $post_id );
|
1009 |
+
} else {
|
1010 |
+
$original_id = $post_id;
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
self::$ids[$post_id] = array();
|
1014 |
+
self::$ids[$original_id] = array();
|
1015 |
+
}
|
1016 |
+
|
1017 |
+
protected function _get_value_from_input($option, $input_value) {
|
1018 |
+
if (is_null($input_value)) {
|
1019 |
+
$id = empty($option['value']) ? fw_rand_md5() : $option['value'];
|
1020 |
+
} else {
|
1021 |
+
$id = $input_value;
|
1022 |
+
}
|
1023 |
+
|
1024 |
+
if (empty($id) || !is_string($id)) {
|
1025 |
+
$id = fw_rand_md5();
|
1026 |
+
}
|
1027 |
+
|
1028 |
+
/**
|
1029 |
+
* Regenerate if found the same id again
|
1030 |
+
*/
|
1031 |
+
{
|
1032 |
+
global $post;
|
1033 |
+
|
1034 |
+
if ($post) {
|
1035 |
+
$post_id = $post->ID;
|
1036 |
+
} else {
|
1037 |
+
$post_id = '~';
|
1038 |
+
}
|
1039 |
+
|
1040 |
+
if (!isset(self::$ids[$post_id])) {
|
1041 |
+
self::$ids[$post_id] = array();
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
while (isset(self::$ids[$post_id][$id])) {
|
1045 |
+
$id = fw_rand_md5();
|
1046 |
+
}
|
1047 |
+
|
1048 |
+
self::$ids[$post_id][$id] = true;
|
1049 |
+
}
|
1050 |
+
|
1051 |
+
return $id;
|
1052 |
+
}
|
1053 |
+
}
|
1054 |
+
FW_Option_Type::register('FW_Option_Type_Unique');
|
framework/manifest.php
CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
|
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
-
$manifest['version'] = '2.3.
|
4 |
|
5 |
$manifest['name'] = __('Unyson', 'fw');
|
6 |
|
7 |
+
$manifest['version'] = '2.3.2';
|
framework/static/css/fw.css
CHANGED
@@ -3005,6 +3005,7 @@ body.rtl .fw-options-modal .media-frame-content > form .fw-options-tabs-contents
|
|
3005 |
|
3006 |
.fw-sole-modal .fw-sole-modal-content h2 {
|
3007 |
font-size: 22px;
|
|
|
3008 |
}
|
3009 |
|
3010 |
.fw-sole-modal .fw-sole-modal-content p {
|
3005 |
|
3006 |
.fw-sole-modal .fw-sole-modal-content h2 {
|
3007 |
font-size: 22px;
|
3008 |
+
line-height: initial;
|
3009 |
}
|
3010 |
|
3011 |
.fw-sole-modal .fw-sole-modal-content p {
|
framework/static/css/option-types.css
CHANGED
@@ -54,7 +54,8 @@ textarea.fw-option-type-textarea {
|
|
54 |
}
|
55 |
|
56 |
|
57 |
-
.fw-backend-option-type-hidden
|
|
|
58 |
display: none;
|
59 |
}
|
60 |
|
54 |
}
|
55 |
|
56 |
|
57 |
+
.fw-backend-option-type-hidden,
|
58 |
+
.fw-backend-option-type-unique {
|
59 |
display: none;
|
60 |
}
|
61 |
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson, themefusecom
|
|
3 |
Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
|
4 |
Requires at least: 4.0.0
|
5 |
Tested up to: 4.2
|
6 |
-
Stable tag: 2.3.
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
@@ -86,6 +86,13 @@ Yes; Unyson will work with any theme.
|
|
86 |
|
87 |
== Changelog ==
|
88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
= 2.3.1 =
|
90 |
* Fixed [#566](https://github.com/ThemeFuse/Unyson/issues/566), [#550](https://github.com/ThemeFuse/Unyson/issues/550)
|
91 |
* Fixed: Options default values not working in Customizer [#410](https://github.com/ThemeFuse/Unyson/issues/410#issuecomment-103343955)
|
3 |
Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio, framework
|
4 |
Requires at least: 4.0.0
|
5 |
Tested up to: 4.2
|
6 |
+
Stable tag: 2.3.2
|
7 |
License: GPLv2 or later
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
|
86 |
|
87 |
== Changelog ==
|
88 |
|
89 |
+
= 2.3.2 =
|
90 |
+
* Added option-type `unique` to make possible [this](http://manual.unyson.io/en/latest/extension/shortcodes/index.html#enqueue-shortcode-dynamic-css-in-page-head)
|
91 |
+
* Added the `fw_get_google_fonts_v2()` function
|
92 |
+
* Fixed: The newline character in textarea option in Customizer was replaced with `'rn'` string
|
93 |
+
* Fixed: Post options (meta) lost after Quick Edit
|
94 |
+
* Option-type `multi-picker`: Allow support for any option type in picker ([docs](http://manual.unyson.io/en/latest/options/built-in-option-types.html#multi-picker-add-support-for-new-option-type-in-picker))
|
95 |
+
|
96 |
= 2.3.1 =
|
97 |
* Fixed [#566](https://github.com/ThemeFuse/Unyson/issues/566), [#550](https://github.com/ThemeFuse/Unyson/issues/550)
|
98 |
* Fixed: Options default values not working in Customizer [#410](https://github.com/ThemeFuse/Unyson/issues/410#issuecomment-103343955)
|
unyson.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.themefuse.com/
|
5 |
* Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
|
6 |
-
* Version: 2.3.
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|
3 |
* Plugin Name: Unyson
|
4 |
* Plugin URI: http://unyson.themefuse.com/
|
5 |
* Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
|
6 |
+
* Version: 2.3.2
|
7 |
* Author: ThemeFuse
|
8 |
* Author URI: http://themefuse.com
|
9 |
* License: GPL2+
|