Unyson - Version 2.5.9

Version Description

  • Fixed missing function in WP < 4.5 #1767
  • New option-type: icon-v2
  • Fixed wp-editor option-type bugs #1739
  • Process fw-storage parameter in all options (Theme Settings, Customizer, Post, Term, Extension Settings) #1551
Download this release

Release Info

Developer Unyson
Plugin Icon 128x128 Unyson
Version 2.5.9
Comparing to
See all releases

Code changes from version 2.5.8 to 2.5.9

framework/bootstrap.php CHANGED
@@ -49,6 +49,8 @@ if (defined('FW')) {
49
  'class-fw-session',
50
  'class-fw-wp-option',
51
  'class-fw-wp-meta',
 
 
52
  'database',
53
  'class-fw-flash-messages',
54
  'class-fw-resize',
49
  'class-fw-session',
50
  'class-fw-wp-option',
51
  'class-fw-wp-meta',
52
+ 'class-fw-db-options-model',
53
+ 'fw-storage',
54
  'database',
55
  'class-fw-flash-messages',
56
  'class-fw-resize',
framework/core/components/backend.php CHANGED
@@ -449,15 +449,15 @@ final class _FW_Component_Backend {
449
 
450
  wp_register_script(
451
  'fw-moment',
 
 
 
 
452
  fw_get_framework_directory_uri( '/static/libs/moment/moment-with-locales.min.js' ),
453
  array(),
454
  fw()->manifest->get_version(),
455
  true
456
  );
457
- wp_add_inline_script(
458
- 'fw-moment',
459
- 'moment.locale("'. esc_js(substr(get_locale(), 0, 2)) .'");'
460
- );
461
 
462
  wp_register_script(
463
  'fw-form-helpers',
449
 
450
  wp_register_script(
451
  'fw-moment',
452
+ /**
453
+ * IMPORTANT: At the end of the script is added this line:
454
+ * moment.locale(document.documentElement.lang.slice(0, 2)); // fixes https://github.com/ThemeFuse/Unyson/issues/1767
455
+ */
456
  fw_get_framework_directory_uri( '/static/libs/moment/moment-with-locales.min.js' ),
457
  array(),
458
  fw()->manifest->get_version(),
459
  true
460
  );
 
 
 
 
461
 
462
  wp_register_script(
463
  'fw-form-helpers',
framework/core/extends/class-fw-option-type.php CHANGED
@@ -118,8 +118,10 @@ abstract class FW_Option_Type
118
  * @param array $option
119
  * @param array $data
120
  * @return array
 
 
121
  */
122
- private function prepare(&$id, &$option, &$data)
123
  {
124
  $data = array_merge(
125
  array(
@@ -397,4 +399,4 @@ abstract class FW_Option_Type
397
  protected function _storage_save($id, array $option, $value, array $params) {
398
  return fw_db_option_storage_save($id, $option, $value, $params);
399
  }
400
- }
118
  * @param array $option
119
  * @param array $data
120
  * @return array
121
+ *
122
+ * @since 2.5.10
123
  */
124
+ public function prepare(&$id, &$option, &$data)
125
  {
126
  $data = array_merge(
127
  array(
399
  protected function _storage_save($id, array $option, $value, array $params) {
400
  return fw_db_option_storage_save($id, $option, $value, $params);
401
  }
402
+ }
framework/helpers/class-fw-db-options-model.php ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('FW')) die('Forbidden');
2
+
3
+ /**
4
+ * Lets you create easy functions for get/set database option values
5
+ * it will handle all clever logic with default values, multikeys and processing options fw-storage parameter
6
+ * @since 2.5.9
7
+ */
8
+ abstract class FW_Db_Options_Model {
9
+ /**
10
+ * @return string Must not contain '/'
11
+ */
12
+ abstract protected function get_id();
13
+
14
+ /**
15
+ * @param null|int|string $item_id
16
+ * @param array $extra_data
17
+ * @return mixed
18
+ */
19
+ abstract protected function get_values($item_id, array $extra_data = array());
20
+
21
+ /**
22
+ * @param null|int|string $item_id
23
+ * @param mixed $values
24
+ * @param array $extra_data
25
+ * @return void
26
+ */
27
+ abstract protected function set_values($item_id, $values, array $extra_data = array());
28
+
29
+ /**
30
+ * @param null|int|string $item_id
31
+ * @param array $extra_data
32
+ * @return array
33
+ */
34
+ abstract protected function get_options($item_id, array $extra_data = array());
35
+
36
+ /**
37
+ * @param null|int|string $item_id
38
+ * @param array $extra_data
39
+ * @return array E.g. for post options {'post-id': $item_id}
40
+ * @see fw_db_option_storage_type()
41
+ */
42
+ abstract protected function get_fw_storage_params($item_id, array $extra_data = array());
43
+
44
+ abstract protected function _init();
45
+
46
+ /**
47
+ * @param null|int|string $item_id
48
+ * @param null|string $option_id
49
+ * @param null|string $sub_keys
50
+ * @param mixed $old_value
51
+ * @param array $extra_data
52
+ */
53
+ protected function _after_set($item_id, $option_id, $sub_keys, $old_value, array $extra_data = array()) {}
54
+
55
+ /**
56
+ * @param string $key
57
+ * @param null|int|string $item_id
58
+ * @param array $extra_data
59
+ * @return null|string
60
+ */
61
+ protected function _get_cache_key($key, $item_id, array $extra_data = array()) {
62
+ return empty($item_id) ? null : $item_id;
63
+ }
64
+
65
+ /**
66
+ * @var array {'id': bool}
67
+ */
68
+ private static $merge_values_with_defaults = array();
69
+
70
+ /**
71
+ * @var array {'id': mixed}
72
+ */
73
+ private static $instances = array();
74
+
75
+ /**
76
+ * @param string $id
77
+ * @return FW_Db_Options_Model
78
+ * @internal
79
+ */
80
+ final public static function _get_instance($id) {
81
+ return self::$instances[$id];
82
+ }
83
+
84
+ final public function __construct() {
85
+ if (isset(self::$instances[ $this->get_id() ])) {
86
+ trigger_error(__CLASS__ .' with id "'. $this->get_id() .'" was already defined', E_USER_ERROR);
87
+ } else {
88
+ self::$instances[ $this->get_id() ] = $this;
89
+ }
90
+
91
+ $this->_init();
92
+ }
93
+
94
+ private function get_cache_key($key, $item_id, array $extra_data = array()) {
95
+ $item_key = $this->_get_cache_key($key, $item_id, $extra_data);
96
+
97
+ return 'fw-options-model:'. $this->get_id() .'/'. $key . (empty($item_key) ? '' : '/'. $item_key);
98
+ }
99
+
100
+ /**
101
+ * @param null|int|string $item_id
102
+ * @param null|string $option_id
103
+ * @param mixed $default_value
104
+ * @param array $extra_data
105
+ * @return mixed
106
+ */
107
+ final public function get( $item_id = null, $option_id = null, $default_value = null, array $extra_data = array() ) {
108
+ if (empty($option_id)) {
109
+ $sub_keys = null;
110
+ } else {
111
+ $option_id = explode('/', $option_id); // 'option_id/sub/keys'
112
+ $_option_id = array_shift($option_id); // 'option_id'
113
+ $sub_keys = empty($option_id) ? null : implode('/', $option_id); // 'sub/keys'
114
+ $option_id = $_option_id;
115
+ unset($_option_id);
116
+ }
117
+
118
+ try {
119
+ /**
120
+ * Cached because values are merged with extracted default values
121
+ */
122
+ $values = FW_Cache::get($cache_key_values = $this->get_cache_key('values', $item_id, $extra_data));
123
+ } catch (FW_Cache_Not_Found_Exception $e) {
124
+ FW_Cache::set(
125
+ $cache_key_values,
126
+ $values = is_array($values = $this->get_values($item_id, $extra_data)) ? $values : array()
127
+ );
128
+
129
+ self::$merge_values_with_defaults[ $this->get_id() ] = true;
130
+ }
131
+
132
+ /**
133
+ * If db value is not found and default value is provided
134
+ * return default value before loading options file
135
+ * to prevent infinite recursion in case if this function is called in options file
136
+ */
137
+ if ( ! is_null($default_value) ) {
138
+ if ( empty( $option_id ) ) {
139
+ if ( empty( $values ) && is_array( $default_value ) ) {
140
+ return $default_value;
141
+ }
142
+ } else {
143
+ if ( is_null( $sub_keys ) ) {
144
+ if ( ! isset( $values[ $option_id ] ) ) {
145
+ return $default_value;
146
+ }
147
+ } else {
148
+ if ( is_null( fw_akg( $sub_keys, $values[ $option_id ] ) ) ) {
149
+ return $default_value;
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ try {
156
+ $options = FW_Cache::get( $cache_key = $this->get_cache_key('options', $item_id, $extra_data));
157
+ } catch (FW_Cache_Not_Found_Exception $e) {
158
+ FW_Cache::set($cache_key, array()); // prevent recursion
159
+ FW_Cache::set($cache_key, $options = fw_extract_only_options($this->get_options($item_id, $extra_data)));
160
+ }
161
+
162
+ /**
163
+ * Complete missing db values with default values from options array
164
+ */
165
+ if (self::$merge_values_with_defaults[ $this->get_id() ]) {
166
+ self::$merge_values_with_defaults[ $this->get_id() ] = false;
167
+ FW_Cache::set(
168
+ $cache_key_values,
169
+ $values = array_merge(
170
+ fw_get_options_values_from_input($options, array()),
171
+ $values
172
+ )
173
+ );
174
+ }
175
+
176
+ if (empty($option_id)) {
177
+ foreach ($options as $id => $option) {
178
+ $values[$id] = fw()->backend->option_type($options[$id]['type'])->storage_load(
179
+ $id,
180
+ $options[$id],
181
+ isset($values[$id]) ? $values[$id] : null,
182
+ $this->get_fw_storage_params($item_id, $extra_data)
183
+ );
184
+ }
185
+ } else {
186
+ if (isset($options[$option_id])) {
187
+ $values[ $option_id ] = fw()->backend->option_type( $options[ $option_id ]['type'] )->storage_load(
188
+ $option_id,
189
+ $options[ $option_id ],
190
+ isset($values[ $option_id ]) ? $values[ $option_id ] : null,
191
+ $this->get_fw_storage_params($item_id, $extra_data)
192
+ );
193
+ }
194
+ }
195
+
196
+ if (empty($option_id)) {
197
+ return (empty($values) && is_array($default_value)) ? $default_value : $values;
198
+ } else {
199
+ if (is_null($sub_keys)) {
200
+ return isset($values[$option_id]) ? $values[$option_id] : $default_value;
201
+ } else {
202
+ return fw_akg($sub_keys, $values[$option_id], $default_value);
203
+ }
204
+ }
205
+ }
206
+
207
+ final public function set( $item_id = null, $option_id = null, $value, array $extra_data = array() ) {
208
+ FW_Cache::del($cache_key_values = $this->get_cache_key('values', $item_id, $extra_data));
209
+
210
+ try {
211
+ $options = FW_Cache::get($cache_key = $this->get_cache_key('options', $item_id, $extra_data));
212
+ } catch (FW_Cache_Not_Found_Exception $e) {
213
+ FW_Cache::set($cache_key, array()); // prevent recursion
214
+ FW_Cache::set($cache_key, $options = fw_extract_only_options($this->get_options($item_id, $extra_data)));
215
+ }
216
+
217
+ $sub_keys = null;
218
+
219
+ if ($option_id) {
220
+ $option_id = explode('/', $option_id); // 'option_id/sub/keys'
221
+ $_option_id = array_shift($option_id); // 'option_id'
222
+ $sub_keys = empty($option_id) ? null : implode('/', $option_id); // 'sub/keys'
223
+ $option_id = $_option_id;
224
+ unset($_option_id);
225
+
226
+ $old_values = is_array($old_values = $this->get_values($item_id, $extra_data)) ? $old_values : array();
227
+ $old_value = isset($old_values[$option_id]) ? $old_values[$option_id] : null;
228
+
229
+ if ($sub_keys) { // update sub_key in old_value and use the entire value
230
+ $new_value = $old_value;
231
+ fw_aks($sub_keys, $value, $new_value);
232
+ $value = $new_value;
233
+ unset($new_value);
234
+
235
+ $old_value = fw_akg($sub_keys, $old_value);
236
+ }
237
+
238
+ if (isset($options[$option_id])) {
239
+ $value = fw()->backend->option_type($options[$option_id]['type'])->storage_save(
240
+ $option_id,
241
+ $options[$option_id],
242
+ $value,
243
+ $this->get_fw_storage_params($item_id, $extra_data)
244
+ );
245
+ }
246
+
247
+ $old_values[$option_id] = $value;
248
+
249
+ $this->set_values($item_id, $old_values, $extra_data);
250
+
251
+ unset($old_values);
252
+ } else {
253
+ $old_value = is_array($old_values = $this->get_values($item_id, $extra_data)) ? $old_values : array();
254
+
255
+ if ( ! is_array($value) ) {
256
+ $value = array();
257
+ }
258
+
259
+ foreach ($value as $_option_id => $_option_value) {
260
+ if (isset($options[$_option_id])) {
261
+ $value[$_option_id] = fw()->backend->option_type($options[$_option_id]['type'])->storage_save(
262
+ $_option_id,
263
+ $options[$_option_id],
264
+ $_option_value,
265
+ $this->get_fw_storage_params($item_id, $extra_data)
266
+ );
267
+ }
268
+ }
269
+
270
+ $this->set_values($item_id, $value, $extra_data);
271
+ }
272
+
273
+ FW_Cache::del($cache_key_values); // fixes https://github.com/ThemeFuse/Unyson/issues/1538
274
+
275
+ $this->_after_set($item_id, $option_id, $sub_keys, $old_value, $extra_data);
276
+ }
277
+ }
framework/helpers/class-fw-form.php CHANGED
@@ -417,6 +417,8 @@ class FW_Form {
417
 
418
  echo '<form '. fw_attr_to_html( $render_data['attr'] ) .' >';
419
 
 
 
420
  echo fw_html_tag('input', array(
421
  'type' => 'hidden',
422
  'name' => self::$id_input_name,
@@ -457,6 +459,8 @@ class FW_Form {
457
  ));
458
  }
459
 
 
 
460
  echo '</form>';
461
  }
462
 
417
 
418
  echo '<form '. fw_attr_to_html( $render_data['attr'] ) .' >';
419
 
420
+ do_action('fw_form_display:before', $this);
421
+
422
  echo fw_html_tag('input', array(
423
  'type' => 'hidden',
424
  'name' => self::$id_input_name,
459
  ));
460
  }
461
 
462
+ do_action('fw_form_display:after', $this);
463
+
464
  echo '</form>';
465
  }
466
 
framework/helpers/database.php CHANGED
@@ -2,414 +2,160 @@
2
  die( 'Forbidden' );
3
  }
4
 
5
- /** Theme Settings Options */
6
- {
7
- /**
8
- * Get a theme settings option value from the database
9
- *
10
- * @param string|null $option_id Specific option id (accepts multikey). null - all options
11
- * @param null|mixed $default_value If no option found in the database, this value will be returned
12
- * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
13
- *
14
- * @return mixed|null
15
- */
16
- function fw_get_db_settings_option( $option_id = null, $default_value = null, $get_original_value = null ) {
17
- static $merge_values_with_defaults = false;
18
 
19
- if (empty($option_id)) {
20
- $sub_keys = null;
21
- } else {
22
- $option_id = explode('/', $option_id); // 'option_id/sub/keys'
23
- $_option_id = array_shift($option_id); // 'option_id'
24
- $sub_keys = empty($option_id) ? null : implode('/', $option_id); // 'sub/keys'
25
- $option_id = $_option_id;
26
- unset($_option_id);
27
- }
28
 
29
- try {
30
- /**
31
- * Cached because values are merged with extracted default values
32
- */
33
- $values = FW_Cache::get($cache_key = 'fw_settings_options/values');
34
- } catch (FW_Cache_Not_Found_Exception $e) {
35
- FW_Cache::set(
36
- $cache_key,
37
- $values = (array)FW_WP_Option::get(
38
- 'fw_theme_settings_options:'. fw()->theme->manifest->get_id(), null, array(), $get_original_value
39
- )
40
- );
41
 
42
- $merge_values_with_defaults = true;
43
- }
 
44
 
 
 
 
 
 
 
 
45
  /**
46
- * If db value is not found and default value is provided
47
- * return default value before loading options file
48
- * to prevent infinite recursion in case if this function is called in options file
 
 
 
 
49
  */
50
- if ( ! is_null($default_value) ) {
51
- if ( empty( $option_id ) ) {
52
- if ( empty( $values ) && is_array( $default_value ) ) {
53
- return $default_value;
54
- }
55
- } else {
56
- if ( is_null( $sub_keys ) ) {
57
- if ( ! isset( $values[ $option_id ] ) ) {
58
- return $default_value;
59
- }
60
- } else {
61
- if ( is_null( fw_akg( $sub_keys, $values[ $option_id ] ) ) ) {
62
- return $default_value;
63
- }
64
- }
65
- }
66
- }
67
-
68
- try {
69
- $options = FW_Cache::get( $cache_key = 'fw_only_options/settings' );
70
- } catch (FW_Cache_Not_Found_Exception $e) {
71
- FW_Cache::set($cache_key, array()); // prevent recursion
72
- FW_Cache::set(
73
- $cache_key,
74
- $options = fw_extract_only_options(fw()->theme->get_settings_options())
75
- );
76
  }
77
 
78
  /**
79
- * Complete missing db values with default values from options array
 
 
 
80
  */
81
- if ($merge_values_with_defaults) {
82
- $merge_values_with_defaults = false;
83
- FW_Cache::set(
84
- 'fw_settings_options/values',
85
- $values = array_merge(fw_get_options_values_from_input($options, array()), $values)
86
- );
87
- }
88
-
89
- if (empty($option_id)) {
90
- foreach ($options as $id => $option) {
91
- $values[$id] = fw()->backend->option_type($options[$id]['type'])->storage_load(
92
- $id, $options[$id], isset($values[$id]) ? $values[$id] : null, array()
93
- );
94
- }
95
- } else {
96
- if (isset($options[$option_id])) {
97
- $values[ $option_id ] = fw()->backend->option_type( $options[ $option_id ]['type'] )->storage_load(
98
- $option_id,
99
- $options[ $option_id ],
100
- isset($values[ $option_id ]) ? $values[ $option_id ] : null,
101
- array()
102
- );
103
- }
104
- }
105
-
106
- if (empty($option_id)) {
107
- return (empty($values) && is_array($default_value)) ? $default_value : $values;
108
- } else {
109
- if (is_null($sub_keys)) {
110
- return isset($values[$option_id]) ? $values[$option_id] : $default_value;
111
- } else {
112
- return fw_akg($sub_keys, $values[$option_id], $default_value);
113
- }
114
  }
115
  }
116
-
117
- /**
118
- * Set a theme settings option value in database
119
- *
120
- * @param null $option_id Specific option id (accepts multikey). null - all options
121
- * @param mixed $value
122
- */
123
- function fw_set_db_settings_option( $option_id = null, $value ) {
124
- FW_Cache::del('fw_settings_options/values');
125
-
126
- try {
127
- $options = FW_Cache::get( $cache_key = 'fw_only_options/settings' );
128
- } catch ( FW_Cache_Not_Found_Exception $e ) {
129
- FW_Cache::set(
130
- $cache_key,
131
- $options = fw_extract_only_options(fw()->theme->get_settings_options())
132
- );
133
- }
134
-
135
- if (empty($option_id)) {
136
- foreach ($options as $id => $option) {
137
- if (isset($value[$id])) {
138
- $value[ $id ] = fw()->backend->option_type( $options[ $id ]['type'] )->storage_save(
139
- $id, $options[ $id ], $value[$id], array()
140
- );
141
- }
142
- }
143
- } else {
144
- if (isset($options[$option_id]) && isset($value[ $option_id ])) {
145
- $value[ $option_id ] = fw()->backend->option_type( $options[ $option_id ]['type'] )->storage_save(
146
- $option_id,
147
- $options[ $option_id ],
148
- $value[ $option_id ],
149
- array()
150
- );
151
- }
152
- }
153
-
154
- FW_WP_Option::set(
155
- 'fw_theme_settings_options:' . fw()->theme->manifest->get_id(),
156
- $option_id, $value
157
- );
158
- }
159
  }
 
160
 
161
- /** Post Options */
162
- {
163
- /**
164
- * Get post option value from the database
165
- *
166
- * @param null|int $post_id
167
- * @param string|null $option_id Specific option id (accepts multikey). null - all options
168
- * @param null|mixed $default_value If no option found in the database, this value will be returned
169
- * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
170
- *
171
- * @return mixed|null
172
- */
173
- function fw_get_db_post_option(
174
- $post_id = null,
175
- $option_id = null,
176
- $default_value = null,
177
- $get_original_value = null
178
- ) {
179
- $meta_key = 'fw_options';
180
-
181
- if ( ! $post_id ) {
182
- /** @var WP_Post $post */
183
- global $post;
184
-
185
- if ( ! $post ) {
186
- return $default_value;
187
- } else {
188
- $post_id = $post->ID;
189
- }
190
 
191
- /**
192
- * Check if is Preview and use the preview post_id instead of real/current post id
193
- *
194
- * Note: WordPress changes the global $post content on preview:
195
- * 1. https://github.com/WordPress/WordPress/blob/2096b451c704715db3c4faf699a1184260deade9/wp-includes/query.php#L3573-L3583
196
- * 2. https://github.com/WordPress/WordPress/blob/4a31dd6fe8b774d56f901a29e72dcf9523e9ce85/wp-includes/revision.php#L485-L528
197
- */
198
- if ( is_preview() && is_object($preview = wp_get_post_autosave($post->ID)) ) {
199
- $post_id = $preview->ID;
200
- }
201
- }
202
 
203
- $post_type = get_post_type(
204
- ($post_revision_id = wp_is_post_revision($post_id)) ? $post_revision_id : $post_id
205
- );
206
 
207
  try {
208
- $options = FW_Cache::get(
209
- $cache_key = 'fw_post_options/only/'. $post_type
210
- );
211
  } catch (FW_Cache_Not_Found_Exception $e) {
212
- FW_Cache::set($cache_key, $options = array()); // prevent recursion
 
 
 
 
 
 
 
 
213
 
214
- if (apply_filters('fw_get_db_post_option:fw-storage-enabled',
215
  /**
216
- * Slider extension has too many fw_get_db_post_option()
217
- * inside post options altering filter and it creates recursive mess.
218
- * add_filter() was added in Slider extension
219
- * but this hardcode can be replaced with `true`
220
- * only after all users will install new version 1.1.15.
221
  */
222
- $post_type !== 'fw-slider',
223
- $post_type
224
- )) {
225
- FW_Cache::set(
226
- $cache_key,
227
- $options = fw_extract_only_options(
228
- fw()->theme->get_post_options( $post_type )
229
- )
230
- );
231
- }
232
- }
233
-
234
- if ($option_id) {
235
- $option_id = explode('/', $option_id); // 'option_id/sub/keys'
236
- $_option_id = array_shift($option_id); // 'option_id'
237
- $sub_keys = empty($option_id) ? null : implode('/', $option_id); // 'sub/keys'
238
- $option_id = $_option_id;
239
- unset($_option_id);
240
-
241
- $value = FW_WP_Meta::get(
242
- 'post',
243
- $post_id,
244
- $meta_key .'/'. $option_id,
245
- null,
246
- $get_original_value
247
- );
248
-
249
- if (isset($options[$option_id])) {
250
- try {
251
- $value = FW_Cache::get( $cache_key = 'fw_post_options/values/'. $post_id .'/'. $option_id );
252
- } catch (FW_Cache_Not_Found_Exception $e) {
253
- FW_Cache::set($cache_key, array()); // prevent recursion
254
- FW_Cache::set(
255
- $cache_key,
256
- $value = fw()->backend->option_type($options[$option_id]['type'])->storage_load(
257
- $option_id,
258
- $options[$option_id],
259
- $value,
260
- array( 'post-id' => $post_id, )
261
- )
262
- );
263
  }
264
  }
265
 
266
- if ($sub_keys) {
267
- return fw_akg($sub_keys, $value, $default_value);
268
- } else {
269
- return is_null($value) ? $default_value : $value;
270
- }
271
- } else {
272
- $value = FW_WP_Meta::get(
273
- 'post',
274
- $post_id,
275
- $meta_key,
276
- $default_value,
277
- $get_original_value
278
- );
279
-
280
- if (!is_array($value)) {
281
- $value = array();
282
- }
283
-
284
- foreach ($options as $_option_id => $_option) {
285
- try {
286
- $value[$_option_id] = FW_Cache::get( $cache_key = 'fw_post_options/values/'. $post_id .'/'. $_option_id );
287
- } catch (FW_Cache_Not_Found_Exception $e) {
288
- FW_Cache::set($cache_key, array()); // prevent recursion
289
- FW_Cache::set(
290
- $cache_key,
291
- $value[$_option_id] = fw()->backend->option_type($_option['type'])->storage_load(
292
- $_option_id,
293
- $_option,
294
- isset($value[$_option_id]) ? $value[$_option_id] : null,
295
- array( 'post-id' => $post_id, )
296
- )
297
- );
298
- }
299
- }
300
 
301
- return $value;
302
  }
303
  }
304
 
305
- /**
306
- * Set post option value in database
307
- *
308
- * @param null|int $post_id
309
- * @param string|null $option_id Specific option id (accepts multikey). null - all options
310
- * @param $value
311
- */
312
- function fw_set_db_post_option( $post_id = null, $option_id = null, $value ) {
313
- FW_Cache::del('fw_post_options/values');
314
-
315
- $meta_key = 'fw_options';
316
- $post_id = intval($post_id);
317
-
318
- if ( ! $post_id ) {
319
- /** @var WP_Post $post */
320
- global $post;
321
-
322
- if ( ! $post ) {
323
- return;
324
- } else {
325
- $post_id = $post->ID;
326
- }
327
- }
328
-
329
- $post_type = get_post_type(
330
- ($post_revision_id = wp_is_post_revision($post_id)) ? $post_revision_id : $post_id
331
- );
332
 
333
  try {
334
- $options = FW_Cache::get(
335
- $cache_key = 'fw_post_options/only/'. $post_type
336
- );
337
  } catch (FW_Cache_Not_Found_Exception $e) {
338
- FW_Cache::set($cache_key, $options = array()); // prevent recursion
 
 
 
 
 
339
 
340
- if (apply_filters('fw_get_db_post_option:fw-storage-enabled',
341
- /**
342
- * Slider extension has too many fw_get_db_post_option()
343
- * inside post options altering filter and it creates recursive mess.
344
- * add_filter() was added in Slider extension
345
- * but this hardcode can be replaced with `true`
346
- * only after all users will install new version 1.1.15.
347
- */
348
- $post_type !== 'fw-slider',
349
- $post_type
350
- )) {
351
- FW_Cache::set(
352
- $cache_key,
353
- $options = fw_extract_only_options(
354
- fw()->theme->get_post_options( $post_type )
355
- )
356
- );
357
- }
358
  }
 
359
 
360
- $sub_keys = null;
361
-
362
- if ($option_id) {
363
- $option_id = explode('/', $option_id); // 'option_id/sub/keys'
364
- $_option_id = array_shift($option_id); // 'option_id'
365
- $sub_keys = empty($option_id) ? null : implode('/', $option_id); // 'sub/keys'
366
- $option_id = $_option_id;
367
- unset($_option_id);
368
 
369
- $old_value = fw_get_db_post_option($post_id, $option_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370
 
371
- if ($sub_keys) { // update sub_key in old_value and use the entire value
372
- $new_value = $old_value;
373
- fw_aks($sub_keys, $value, $new_value);
374
- $value = $new_value;
375
- unset($new_value);
376
 
377
- $old_value = fw_akg($sub_keys, $old_value);
378
- }
 
379
 
380
- if (isset($options[$option_id])) {
381
- $value = fw()->backend->option_type($options[$option_id]['type'])->storage_save(
382
- $option_id,
383
- $options[$option_id],
384
- $value,
385
- array( 'post-id' => $post_id, )
386
- );
387
- }
388
 
389
- FW_WP_Meta::set( 'post', $post_id, $meta_key .'/'. $option_id, $value );
 
 
390
  } else {
391
- $old_value = fw_get_db_post_option($post_id);
392
-
393
- if (!is_array($value)) {
394
- $value = array();
395
- }
396
-
397
- foreach ($value as $_option_id => $_option_value) {
398
- if (isset($options[$_option_id])) {
399
- $value[$_option_id] = fw()->backend->option_type($options[$_option_id]['type'])->storage_save(
400
- $_option_id,
401
- $options[$_option_id],
402
- $_option_value,
403
- array( 'post-id' => $post_id, )
404
- );
405
- }
406
- }
407
-
408
- FW_WP_Meta::set( 'post', $post_id, $meta_key, $value );
409
  }
 
410
 
411
- FW_Cache::del('fw_post_options/values'); // fixes https://github.com/ThemeFuse/Unyson/issues/1538
412
-
413
  /**
414
  * @deprecated
415
  */
@@ -449,180 +195,229 @@
449
  $old_value
450
  );
451
  }
452
- }
453
 
454
- /** Terms Options */
455
- {
456
- /**
457
- * Get term option value from the database
458
- *
459
- * @param int $term_id
460
- * @param string $taxonomy
461
- * @param string|null $option_id Specific option id (accepts multikey). null - all options
462
- * @param null|mixed $default_value If no option found in the database, this value will be returned
463
- * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
464
- *
465
- * @return mixed|null
466
- */
467
- function fw_get_db_term_option( $term_id, $taxonomy, $option_id = null, $default_value = null, $get_original_value = null ) {
468
- if ( ! taxonomy_exists( $taxonomy ) ) {
469
- return null;
470
  }
471
 
472
- $option_id = 'fw_options' . ( $option_id !== null ? '/' . $option_id : '' );
 
 
 
 
 
 
 
 
 
473
 
474
- return FW_WP_Meta::get( 'fw_term', $term_id, $option_id, $default_value, $get_original_value );
475
  }
 
 
476
 
477
- /**
478
- * Set term option value in database
479
- *
480
- * @param int $term_id
481
- * @param string $taxonomy
482
- * @param string|null $option_id Specific option id (accepts multikey). null - all options
483
- * @param mixed $value
484
- *
485
- * @return null
486
- */
487
- function fw_set_db_term_option( $term_id, $taxonomy, $option_id = null, $value ) {
488
- if ( ! taxonomy_exists( $taxonomy ) ) {
489
- return null;
490
- }
491
- $option_id = 'fw_options' . ( $option_id !== null ? '/' . $option_id : '' );
492
 
493
- FW_WP_Meta::set( 'fw_term', $term_id, $option_id, $value );
 
494
  }
495
- }
496
 
497
- /**
498
- * Extensions Data
499
- *
500
- * Used by extensions to store custom data in database.
501
- * By using these functions, extension prevent database spam with wp options for each extension,
502
- * because these functions store all data in one wp option.
503
- */
504
- {
505
- /**
506
- * Get extension's data from the database
507
- *
508
- * @param string $extension_name
509
- * @param string|null $multi_key The key of the data you want to get. null - all data
510
- * @param null|mixed $default_value If no option found in the database, this value will be returned
511
- * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
512
- *
513
- * @return mixed|null
514
- */
515
- function fw_get_db_extension_data( $extension_name, $multi_key = null, $default_value = null, $get_original_value = null ) {
516
- if ( ! fw()->extensions->get( $extension_name ) ) {
517
- trigger_error( 'Invalid extension: ' . $extension_name, E_USER_WARNING );
518
 
519
- return null;
520
- }
 
521
 
522
- if ( $multi_key ) {
523
- $multi_key = $extension_name . '/' . $multi_key;
 
 
 
 
 
 
 
 
524
  } else {
525
- $multi_key = $extension_name;
526
  }
527
-
528
- return FW_WP_Option::get( 'fw_extensions', $multi_key, $default_value, $get_original_value );
529
  }
530
 
531
- /**
532
- * Set some extension's data in database
533
- *
534
- * @param string $extension_name
535
- * @param string|null $multi_key The key of the data you want to set. null - all data
536
- * @param mixed $value
537
- */
538
- function fw_set_db_extension_data( $extension_name, $multi_key = null, $value ) {
539
- if ( ! fw()->extensions->get( $extension_name ) ) {
540
- trigger_error( 'Invalid extension: ' . $extension_name, E_USER_WARNING );
 
 
 
 
 
 
541
 
542
- return;
 
 
543
  }
544
 
545
- if ( $multi_key ) {
546
- $multi_key = $extension_name . '/' . $multi_key;
547
- } else {
548
- $multi_key = $extension_name;
549
- }
 
 
 
 
 
 
 
 
 
550
 
551
- FW_WP_Option::set( 'fw_extensions', $multi_key, $value );
 
 
 
552
  }
553
  }
 
554
 
555
- /**
556
- * Extensions Settings Options
557
- */
558
- {
559
- /**
560
- * Get extension's settings option value from the database
561
- *
562
- * @param string $extension_name
563
- * @param string|null $option_id
564
- * @param null|mixed $default_value If no option found in the database, this value will be returned
565
- * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
566
- *
567
- * @return mixed|null
568
- */
569
- function fw_get_db_ext_settings_option( $extension_name, $option_id = null, $default_value = null, $get_original_value = null ) {
570
- if ( ! ( $extension = fw()->extensions->get( $extension_name ) ) ) {
571
- trigger_error( 'Invalid extension: ' . $extension_name, E_USER_WARNING );
572
-
573
- return null;
574
- }
575
 
576
- $value = FW_WP_Option::get( 'fw_ext_settings_options:' . $extension_name, $option_id, $default_value, $get_original_value );
 
 
577
 
578
- if ( is_null( $value ) ) {
579
- /**
580
- * Maybe the options was never saved or the given option id does not exists
581
- * Extract the default values from the options array and try to find there the option id
582
- */
583
 
584
- $cache_key = 'fw_default_options_values/ext_settings:' . $extension_name;
 
 
585
 
586
- try {
587
- $all_options_values = FW_Cache::get( $cache_key );
588
- } catch ( FW_Cache_Not_Found_Exception $e ) {
589
- // extract the default values from options array
590
- $all_options_values = fw_get_options_values_from_input(
591
- $extension->get_settings_options(),
592
- array()
593
- );
594
 
595
- FW_Cache::set( $cache_key, $all_options_values );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
596
  }
597
 
598
- if ( empty( $option_id ) ) {
599
- // option id not specified, return all options values
600
- return $all_options_values;
601
- } else {
602
- return fw_akg( $option_id, $all_options_values, $default_value );
 
 
 
 
 
 
 
 
 
 
603
  }
604
- } else {
605
- return $value;
606
  }
607
  }
 
 
608
 
609
- /**
610
- * Set extension's setting option value in database
611
- *
612
- * @param string $extension_name
613
- * @param string|null $option_id
614
- * @param mixed $value
615
- */
616
- function fw_set_db_ext_settings_option( $extension_name, $option_id = null, $value ) {
617
- if ( ! fw()->extensions->get( $extension_name ) ) {
618
- trigger_error( 'Invalid extension: ' . $extension_name, E_USER_WARNING );
619
 
620
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
621
  }
622
 
623
- FW_WP_Option::set( 'fw_ext_settings_options:' . $extension_name, $option_id, $value );
 
 
 
 
 
 
 
 
624
  }
625
  }
 
626
 
627
  {
628
  /**
@@ -680,204 +475,60 @@
680
  }
681
  }
682
 
683
- /** Customizer Framework Options */
 
 
 
 
 
 
684
  {
685
  /**
686
- * Get a customizer framework option value from the database
687
  *
688
- * @param string|null $option_id Specific option id (accepts multikey). null - all options
 
689
  * @param null|mixed $default_value If no option found in the database, this value will be returned
 
690
  *
691
  * @return mixed|null
692
  */
693
- function fw_get_db_customizer_option( $option_id = null, $default_value = null ) {
694
- // note: this contains only changed controls/options
695
- $db_values = get_theme_mod(FW_Option_Type::get_default_name_prefix(), null);
696
-
697
- if (
698
- !is_null($default_value)
699
- &&
700
- is_null($option_id ? fw_akg($option_id, $db_values) : $db_values)
701
- ) {
702
- /**
703
- * Default value was provided in case db value is empty.
704
- *
705
- * Do not extract default values from options files (below)
706
- * maybe this function was called from options files and it will cause infinite loop,
707
- * that's why the developer provided a default value to prevent that.
708
- */
709
- return $default_value;
710
- }
711
-
712
- if (is_null($db_values)) {
713
- $db_values = array();
714
- }
715
-
716
- if (
717
- is_null($option_id)
718
- ||
719
- (
720
- ($base_key = explode('/', $option_id)) // note: option_id can be a multi-key 'a/b/c'
721
- &&
722
- ($base_key = array_shift($base_key))
723
- &&
724
- !array_key_exists($base_key, $db_values)
725
- )
726
- ) {
727
- // extract options default values
728
- {
729
- $cache_key = 'fw_default_options_values/customizer';
730
-
731
- try {
732
- $default_values = FW_Cache::get( $cache_key );
733
- } catch ( FW_Cache_Not_Found_Exception $e ) {
734
- // extract the default values from options array
735
- $default_values = fw_get_options_values_from_input(
736
- fw()->theme->get_customizer_options(),
737
- array()
738
- );
739
-
740
- FW_Cache::set( $cache_key, $default_values );
741
- }
742
- }
743
 
744
- $db_values = array_merge($default_values, $db_values);
745
  }
746
 
747
- return is_null($option_id)
748
- ? $db_values
749
- : fw_akg($option_id, $db_values, $default_value);
750
- }
751
-
752
- /**
753
- * Set a theme customizer option value in database
754
- *
755
- * @param null $option_id Specific option id (accepts multikey). null - all options
756
- * @param mixed $value
757
- */
758
- function fw_set_db_customizer_option( $option_id = null, $value ) {
759
- $db_value = get_theme_mod(FW_Option_Type::get_default_name_prefix(), array());
760
-
761
- if (is_null($option_id)) {
762
- $db_value = $value;
763
  } else {
764
- fw_aks($option_id, $value, $db_value);
765
  }
766
 
767
- set_theme_mod(
768
- FW_Option_Type::get_default_name_prefix(),
769
- $db_value
770
- );
771
  }
772
- }
773
 
774
- {
775
  /**
776
- * @param string $id
777
- * @param array $option
778
- * @param mixed $value
779
- * @param array $params
780
- *
781
- * @return mixed
782
  *
783
- * @since 2.5.0
784
- */
785
- function fw_db_option_storage_save($id, array $option, $value, array $params = array()) {
786
- if (
787
- !empty($option['fw-storage'])
788
- &&
789
- ($storage = is_array($option['fw-storage'])
790
- ? $option['fw-storage']
791
- : array('type' => $option['fw-storage'])
792
- )
793
- &&
794
- !empty($storage['type'])
795
- &&
796
- ($storage_type = fw_db_option_storage_type($storage['type']))
797
- ) {
798
- $option['fw-storage'] = $storage;
799
- } else {
800
- return $value;
801
- }
802
-
803
- /** @var FW_Option_Storage_Type $storage_type */
804
-
805
- return $storage_type->save($id, $option, $value, $params);
806
- }
807
-
808
- /**
809
- * @param string $id
810
- * @param array $option
811
  * @param mixed $value
812
- * @param array $params
813
- *
814
- * @return mixed
815
- *
816
- * @since 2.5.0
817
  */
818
- function fw_db_option_storage_load($id, array $option, $value, array $params = array()) {
819
- if (
820
- !empty($option['fw-storage'])
821
- &&
822
- ($storage = is_array($option['fw-storage'])
823
- ? $option['fw-storage']
824
- : array('type' => $option['fw-storage'])
825
- )
826
- &&
827
- !empty($storage['type'])
828
- &&
829
- ($storage_type = fw_db_option_storage_type($storage['type']))
830
- ) {
831
- $option['fw-storage'] = $storage;
832
- } else {
833
- return $value;
834
- }
835
-
836
- /** @var FW_Option_Storage_Type $storage_type */
837
-
838
- return $storage_type->load($id, $option, $value, $params);
839
- }
840
-
841
- /**
842
- * @param null|string $type
843
- * @return FW_Option_Storage_Type|FW_Option_Storage_Type[]|null
844
- * @since 2.5.0
845
- */
846
- function fw_db_option_storage_type($type = null) {
847
- static $types = null;
848
-
849
- if (is_null($types)) {
850
- $dir = fw_get_framework_directory('/includes/option-storage');
851
-
852
- if (!class_exists('FW_Option_Storage_Type')) {
853
- require_once $dir .'/class-fw-option-storage-type.php';
854
- }
855
- if (!class_exists('_FW_Option_Storage_Type_Register')) {
856
- require_once $dir .'/class--fw-option-storage-type-register.php';
857
- }
858
-
859
- $access_key = new FW_Access_Key('fw:option-storage-register');
860
- $register = new _FW_Option_Storage_Type_Register($access_key->get_key());
861
-
862
- {
863
- require_once $dir .'/type/class-fw-option-storage-type-post-meta.php';
864
- $register->register(new FW_Option_Storage_Type_Post_Meta());
865
-
866
- require_once $dir .'/type/class-fw-option-storage-type-wp-option.php';
867
- $register->register(new FW_Option_Storage_Type_WP_Option());
868
- }
869
-
870
- do_action('fw:option-storage-types:register', $register);
871
 
872
- $types = $register->_get_types($access_key);
873
  }
874
 
875
- if (empty($type)) {
876
- return $types;
877
- } elseif (isset($types[$type])) {
878
- return $types[$type];
879
  } else {
880
- return null;
881
  }
 
 
882
  }
883
  }
2
  die( 'Forbidden' );
3
  }
4
 
5
+ // Theme Settings Options
6
+ class FW_Db_Options_Model_Settings extends FW_Db_Options_Model {
7
+ protected function get_id() {
8
+ return 'settings';
9
+ }
 
 
 
 
 
 
 
 
10
 
11
+ protected function get_options($item_id, array $extra_data = array()) {
12
+ return fw()->theme->get_settings_options();
13
+ }
 
 
 
 
 
 
14
 
15
+ protected function get_values($item_id, array $extra_data = array()) {
16
+ return FW_WP_Option::get('fw_theme_settings_options:'. fw()->theme->manifest->get_id(), null, array());
17
+ }
 
 
 
 
 
 
 
 
 
18
 
19
+ protected function set_values($item_id, $values, array $extra_data = array()) {
20
+ FW_WP_Option::set('fw_theme_settings_options:' . fw()->theme->manifest->get_id(), null, $values);
21
+ }
22
 
23
+ protected function get_fw_storage_params($item_id, array $extra_data = array()) {
24
+ return array(
25
+ 'settings' => true
26
+ );
27
+ }
28
+
29
+ protected function _init() {
30
  /**
31
+ * Get a theme settings option value from the database
32
+ *
33
+ * @param string|null $option_id Specific option id (accepts multikey). null - all options
34
+ * @param null|mixed $default_value If no option found in the database, this value will be returned
35
+ * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
36
+ *
37
+ * @return mixed|null
38
  */
39
+ function fw_get_db_settings_option( $option_id = null, $default_value = null, $get_original_value = null ) {
40
+ return FW_Db_Options_Model_Settings::_get_instance('settings')->get(null, $option_id, $default_value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  }
42
 
43
  /**
44
+ * Set a theme settings option value in database
45
+ *
46
+ * @param null $option_id Specific option id (accepts multikey). null - all options
47
+ * @param mixed $value
48
  */
49
+ function fw_set_db_settings_option( $option_id = null, $value ) {
50
+ FW_Db_Options_Model_Settings::_get_instance('settings')->set(null, $option_id, $value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
+ new FW_Db_Options_Model_Settings();
55
 
56
+ // Post Options
57
+ class FW_Db_Options_Model_Post extends FW_Db_Options_Model {
58
+ protected function get_id() {
59
+ return 'post';
60
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ private function get_cache_key($key) {
63
+ return 'fw-options-model:'. $this->get_id() .'/'. $key;
64
+ }
 
 
 
 
 
 
 
 
65
 
66
+ private function get_post_id($post_id) {
67
+ $post_id = intval($post_id);
 
68
 
69
  try {
70
+ // Prevent too often execution of wp_get_post_autosave() because it does WP Query
71
+ return FW_Cache::get($cache_key = $this->get_cache_key('id/'. $post_id));
 
72
  } catch (FW_Cache_Not_Found_Exception $e) {
73
+ if ( ! $post_id ) {
74
+ /** @var WP_Post $post */
75
+ global $post;
76
+
77
+ if ( ! $post ) {
78
+ return null;
79
+ } else {
80
+ $post_id = $post->ID;
81
+ }
82
 
 
83
  /**
84
+ * Check if is Preview and use the preview post_id instead of real/current post id
85
+ *
86
+ * Note: WordPress changes the global $post content on preview:
87
+ * 1. https://github.com/WordPress/WordPress/blob/2096b451c704715db3c4faf699a1184260deade9/wp-includes/query.php#L3573-L3583
88
+ * 2. https://github.com/WordPress/WordPress/blob/4a31dd6fe8b774d56f901a29e72dcf9523e9ce85/wp-includes/revision.php#L485-L528
89
  */
90
+ if ( is_preview() && is_object($preview = wp_get_post_autosave($post->ID)) ) {
91
+ $post_id = $preview->ID;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  }
93
  }
94
 
95
+ FW_Cache::set($cache_key, $post_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
 
97
+ return $post_id;
98
  }
99
  }
100
 
101
+ private function get_post_type($post_id) {
102
+ $post_id = $this->get_post_id($post_id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  try {
105
+ return FW_Cache::get($cache_key = $this->get_cache_key('type/'. $post_id));
 
 
106
  } catch (FW_Cache_Not_Found_Exception $e) {
107
+ FW_Cache::set(
108
+ $cache_key,
109
+ $post_type = get_post_type(
110
+ ($post_revision_id = wp_is_post_revision($post_id)) ? $post_revision_id : $post_id
111
+ )
112
+ );
113
 
114
+ return $post_type;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  }
116
+ }
117
 
118
+ protected function get_options($item_id, array $extra_data = array()) {
119
+ $post_type = $this->get_post_type($item_id);
 
 
 
 
 
 
120
 
121
+ if (apply_filters('fw_get_db_post_option:fw-storage-enabled',
122
+ /**
123
+ * Slider extension has too many fw_get_db_post_option()
124
+ * inside post options altering filter and it creates recursive mess.
125
+ * add_filter() was added in Slider extension
126
+ * but this hardcode can be replaced with `true`
127
+ * only after all users will install new version 1.1.15.
128
+ */
129
+ $post_type !== 'fw-slider',
130
+ $post_type
131
+ )) {
132
+ return fw()->theme->get_post_options( $post_type );
133
+ } else {
134
+ return array();
135
+ }
136
+ }
137
 
138
+ protected function get_values($item_id, array $extra_data = array()) {
139
+ return FW_WP_Meta::get( 'post', $item_id, 'fw_options', array() );
140
+ }
 
 
141
 
142
+ protected function set_values($item_id, $values, array $extra_data = array()) {
143
+ FW_WP_Meta::set( 'post', $item_id, 'fw_options', $values );
144
+ }
145
 
146
+ protected function get_fw_storage_params($item_id, array $extra_data = array()) {
147
+ return array( 'post-id' => $item_id );
148
+ }
 
 
 
 
 
149
 
150
+ protected function _get_cache_key($key, $item_id, array $extra_data = array()) {
151
+ if ($key === 'options') {
152
+ return $this->get_post_type($item_id); // Cache options grouped by post-type, not by post id
153
  } else {
154
+ return $item_id;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  }
156
+ }
157
 
158
+ protected function _after_set($post_id, $option_id, $sub_keys, $old_value, array $extra_data = array()) {
 
159
  /**
160
  * @deprecated
161
  */
195
  $old_value
196
  );
197
  }
 
198
 
199
+ protected function _init() {
200
+ /**
201
+ * Get post option value from the database
202
+ *
203
+ * @param null|int $post_id
204
+ * @param string|null $option_id Specific option id (accepts multikey). null - all options
205
+ * @param null|mixed $default_value If no option found in the database, this value will be returned
206
+ * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
207
+ *
208
+ * @return mixed|null
209
+ */
210
+ function fw_get_db_post_option($post_id = null, $option_id = null, $default_value = null, $get_original_value = null) {
211
+ return FW_Db_Options_Model::_get_instance('post')->get(intval($post_id), $option_id, $default_value);
 
 
 
212
  }
213
 
214
+ /**
215
+ * Set post option value in database
216
+ *
217
+ * @param null|int $post_id
218
+ * @param string|null $option_id Specific option id (accepts multikey). null - all options
219
+ * @param $value
220
+ */
221
+ function fw_set_db_post_option( $post_id = null, $option_id = null, $value ) {
222
+ FW_Db_Options_Model::_get_instance('post')->set(intval($post_id), $option_id, $value);
223
+ }
224
 
225
+ // todo: add_action() to clear the FW_Cache
226
  }
227
+ }
228
+ new FW_Db_Options_Model_Post();
229
 
230
+ // Term Options
231
+ class FW_Db_Options_Model_Term extends FW_Db_Options_Model {
232
+ protected function get_id() {
233
+ return 'term';
234
+ }
 
 
 
 
 
 
 
 
 
 
235
 
236
+ protected function get_values($item_id, array $extra_data = array()) {
237
+ return FW_WP_Meta::get( 'fw_term', $item_id, 'fw_options', array(), null );
238
  }
 
239
 
240
+ protected function set_values($item_id, $values, array $extra_data = array()) {
241
+ FW_WP_Meta::set( 'fw_term', $item_id, 'fw_options', $values );
242
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
+ protected function get_options($item_id, array $extra_data = array()) {
245
+ return fw()->theme->get_taxonomy_options($extra_data['taxonomy']);
246
+ }
247
 
248
+ protected function get_fw_storage_params($item_id, array $extra_data = array()) {
249
+ return array(
250
+ 'term-id' => $item_id,
251
+ 'taxonomy' => $extra_data['taxonomy'],
252
+ );
253
+ }
254
+
255
+ protected function _get_cache_key($key, $item_id, array $extra_data = array()) {
256
+ if ($key === 'options') {
257
+ return $extra_data['taxonomy']; // Cache options grouped by taxonomy, not by term id
258
  } else {
259
+ return $item_id;
260
  }
 
 
261
  }
262
 
263
+ protected function _init() {
264
+ /**
265
+ * Get term option value from the database
266
+ *
267
+ * @param int $term_id
268
+ * @param string $taxonomy
269
+ * @param string|null $option_id Specific option id (accepts multikey). null - all options
270
+ * @param null|mixed $default_value If no option found in the database, this value will be returned
271
+ * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
272
+ *
273
+ * @return mixed|null
274
+ */
275
+ function fw_get_db_term_option( $term_id, $taxonomy, $option_id = null, $default_value = null, $get_original_value = null ) {
276
+ if ( ! taxonomy_exists( $taxonomy ) ) {
277
+ return null;
278
+ }
279
 
280
+ return FW_Db_Options_Model::_get_instance('term')->get(intval($term_id), $option_id, $default_value, array(
281
+ 'taxonomy' => $taxonomy
282
+ ));
283
  }
284
 
285
+ /**
286
+ * Set term option value in database
287
+ *
288
+ * @param int $term_id
289
+ * @param string $taxonomy
290
+ * @param string|null $option_id Specific option id (accepts multikey). null - all options
291
+ * @param mixed $value
292
+ *
293
+ * @return null
294
+ */
295
+ function fw_set_db_term_option( $term_id, $taxonomy, $option_id = null, $value ) {
296
+ if ( ! taxonomy_exists( $taxonomy ) ) {
297
+ return null;
298
+ }
299
 
300
+ FW_Db_Options_Model::_get_instance('term')->set(intval($term_id), $option_id, $value, array(
301
+ 'taxonomy' => $taxonomy
302
+ ));
303
+ }
304
  }
305
  }
306
+ new FW_Db_Options_Model_Term();
307
 
308
+ // Extensions Settings Options
309
+ class FW_Db_Options_Model_Extension extends FW_Db_Options_Model {
310
+ protected function get_id() {
311
+ return 'extension';
312
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
 
314
+ protected function get_values($item_id, array $extra_data = array()) {
315
+ return FW_WP_Option::get( 'fw_ext_settings_options:' . $item_id, null, array() );
316
+ }
317
 
318
+ protected function set_values($item_id, $values, array $extra_data = array()) {
319
+ FW_WP_Option::set( 'fw_ext_settings_options:' . $item_id, null, $values );
320
+ }
 
 
321
 
322
+ protected function get_options($item_id, array $extra_data = array()) {
323
+ return fw_ext($item_id)->get_settings_options();
324
+ }
325
 
326
+ protected function get_fw_storage_params($item_id, array $extra_data = array()) {
327
+ return array(
328
+ 'extension' => $item_id,
329
+ );
330
+ }
 
 
 
331
 
332
+ protected function _init() {
333
+ /**
334
+ * Get extension's settings option value from the database
335
+ *
336
+ * @param string $extension_name
337
+ * @param string|null $option_id
338
+ * @param null|mixed $default_value If no option found in the database, this value will be returned
339
+ * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
340
+ *
341
+ * @return mixed|null
342
+ */
343
+ function fw_get_db_ext_settings_option( $extension_name, $option_id = null, $default_value = null, $get_original_value = null ) {
344
+ if ( ! ( $extension = fw_ext( $extension_name ) ) ) {
345
+ trigger_error( 'Invalid extension: ' . $extension_name, E_USER_WARNING );
346
+ return null;
347
  }
348
 
349
+ return FW_Db_Options_Model::_get_instance('extension')->get($extension_name, $option_id, $default_value);
350
+ }
351
+
352
+ /**
353
+ * Set extension's setting option value in database
354
+ *
355
+ * @param string $extension_name
356
+ * @param string|null $option_id
357
+ * @param mixed $value
358
+ */
359
+ function fw_set_db_ext_settings_option( $extension_name, $option_id = null, $value ) {
360
+ if ( ! fw_ext( $extension_name ) ) {
361
+ trigger_error( 'Invalid extension: ' . $extension_name, E_USER_WARNING );
362
+
363
+ return;
364
  }
365
+
366
+ FW_Db_Options_Model::_get_instance('extension')->set($extension_name, $option_id, $value);
367
  }
368
  }
369
+ }
370
+ new FW_Db_Options_Model_Extension();
371
 
372
+ // Customizer Options
373
+ class FW_Db_Options_Model_Customizer extends FW_Db_Options_Model {
374
+ protected function get_id() {
375
+ return 'customizer';
376
+ }
 
 
 
 
 
377
 
378
+ protected function get_values($item_id, array $extra_data = array()) {
379
+ return get_theme_mod(FW_Option_Type::get_default_name_prefix(), array());
380
+ }
381
+
382
+ protected function set_values($item_id, $values, array $extra_data = array()) {
383
+ set_theme_mod(FW_Option_Type::get_default_name_prefix(), $values);
384
+ }
385
+
386
+ protected function get_options($item_id, array $extra_data = array()) {
387
+ return fw()->theme->get_customizer_options();
388
+ }
389
+
390
+ protected function get_fw_storage_params($item_id, array $extra_data = array()) {
391
+ return array(
392
+ 'customizer' => true
393
+ );
394
+ }
395
+
396
+ protected function _init() {
397
+ /**
398
+ * Get a customizer framework option value from the database
399
+ *
400
+ * @param string|null $option_id Specific option id (accepts multikey). null - all options
401
+ * @param null|mixed $default_value If no option found in the database, this value will be returned
402
+ *
403
+ * @return mixed|null
404
+ */
405
+ function fw_get_db_customizer_option( $option_id = null, $default_value = null ) {
406
+ FW_Db_Options_Model::_get_instance('customizer')->get(null, $option_id, $default_value);
407
  }
408
 
409
+ /**
410
+ * Set a theme customizer option value in database
411
+ *
412
+ * @param null $option_id Specific option id (accepts multikey). null - all options
413
+ * @param mixed $value
414
+ */
415
+ function fw_set_db_customizer_option( $option_id = null, $value ) {
416
+ FW_Db_Options_Model::_get_instance('customizer')->set(null, $option_id, $value);
417
+ }
418
  }
419
  }
420
+ new FW_Db_Options_Model_Customizer();
421
 
422
  {
423
  /**
475
  }
476
  }
477
 
478
+ /**
479
+ * Extensions Data
480
+ *
481
+ * Used by extensions to store custom data in database.
482
+ * By using these functions, extension prevent database spam with wp options for each extension,
483
+ * because these functions store all data in one wp option.
484
+ */
485
  {
486
  /**
487
+ * Get extension's data from the database
488
  *
489
+ * @param string $extension_name
490
+ * @param string|null $multi_key The key of the data you want to get. null - all data
491
  * @param null|mixed $default_value If no option found in the database, this value will be returned
492
+ * @param null|bool $get_original_value REMOVED https://github.com/ThemeFuse/Unyson/issues/1676
493
  *
494
  * @return mixed|null
495
  */
496
+ function fw_get_db_extension_data( $extension_name, $multi_key = null, $default_value = null, $get_original_value = null ) {
497
+ if ( ! fw()->extensions->get( $extension_name ) ) {
498
+ trigger_error( 'Invalid extension: ' . $extension_name, E_USER_WARNING );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
 
500
+ return null;
501
  }
502
 
503
+ if ( $multi_key ) {
504
+ $multi_key = $extension_name . '/' . $multi_key;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
505
  } else {
506
+ $multi_key = $extension_name;
507
  }
508
 
509
+ return FW_WP_Option::get( 'fw_extensions', $multi_key, $default_value, $get_original_value );
 
 
 
510
  }
 
511
 
 
512
  /**
513
+ * Set some extension's data in database
 
 
 
 
 
514
  *
515
+ * @param string $extension_name
516
+ * @param string|null $multi_key The key of the data you want to set. null - all data
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517
  * @param mixed $value
 
 
 
 
 
518
  */
519
+ function fw_set_db_extension_data( $extension_name, $multi_key = null, $value ) {
520
+ if ( ! fw()->extensions->get( $extension_name ) ) {
521
+ trigger_error( 'Invalid extension: ' . $extension_name, E_USER_WARNING );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522
 
523
+ return;
524
  }
525
 
526
+ if ( $multi_key ) {
527
+ $multi_key = $extension_name . '/' . $multi_key;
 
 
528
  } else {
529
+ $multi_key = $extension_name;
530
  }
531
+
532
+ FW_WP_Option::set( 'fw_extensions', $multi_key, $value );
533
  }
534
  }
framework/helpers/fw-storage.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('FW')) die('Forbidden');
2
+
3
+ // Process the `fw-storage` option parameter
4
+
5
+ /**
6
+ * @param string $id
7
+ * @param array $option
8
+ * @param mixed $value
9
+ * @param array $params
10
+ *
11
+ * @return mixed
12
+ *
13
+ * @since 2.5.0
14
+ */
15
+ function fw_db_option_storage_save($id, array $option, $value, array $params = array()) {
16
+ if (
17
+ !empty($option['fw-storage'])
18
+ &&
19
+ ($storage = is_array($option['fw-storage'])
20
+ ? $option['fw-storage']
21
+ : array('type' => $option['fw-storage'])
22
+ )
23
+ &&
24
+ !empty($storage['type'])
25
+ &&
26
+ ($storage_type = fw_db_option_storage_type($storage['type']))
27
+ ) {
28
+ $option['fw-storage'] = $storage;
29
+ } else {
30
+ return $value;
31
+ }
32
+
33
+ /** @var FW_Option_Storage_Type $storage_type */
34
+
35
+ return $storage_type->save($id, $option, $value, $params);
36
+ }
37
+
38
+ /**
39
+ * @param string $id
40
+ * @param array $option
41
+ * @param mixed $value
42
+ * @param array $params
43
+ *
44
+ * @return mixed
45
+ *
46
+ * @since 2.5.0
47
+ */
48
+ function fw_db_option_storage_load($id, array $option, $value, array $params = array()) {
49
+ if (
50
+ !empty($option['fw-storage'])
51
+ &&
52
+ ($storage = is_array($option['fw-storage'])
53
+ ? $option['fw-storage']
54
+ : array('type' => $option['fw-storage'])
55
+ )
56
+ &&
57
+ !empty($storage['type'])
58
+ &&
59
+ ($storage_type = fw_db_option_storage_type($storage['type']))
60
+ ) {
61
+ $option['fw-storage'] = $storage;
62
+ } else {
63
+ return $value;
64
+ }
65
+
66
+ /** @var FW_Option_Storage_Type $storage_type */
67
+
68
+ return $storage_type->load($id, $option, $value, $params);
69
+ }
70
+
71
+ /**
72
+ * @param null|string $type
73
+ * @return FW_Option_Storage_Type|FW_Option_Storage_Type[]|null
74
+ * @since 2.5.0
75
+ */
76
+ function fw_db_option_storage_type($type = null) {
77
+ static $types = null;
78
+
79
+ if (is_null($types)) {
80
+ $dir = fw_get_framework_directory('/includes/option-storage');
81
+
82
+ if (!class_exists('FW_Option_Storage_Type')) {
83
+ require_once $dir .'/class-fw-option-storage-type.php';
84
+ }
85
+ if (!class_exists('_FW_Option_Storage_Type_Register')) {
86
+ require_once $dir .'/class--fw-option-storage-type-register.php';
87
+ }
88
+
89
+ $access_key = new FW_Access_Key('fw:option-storage-register');
90
+ $register = new _FW_Option_Storage_Type_Register($access_key->get_key());
91
+
92
+ {
93
+ require_once $dir .'/type/class-fw-option-storage-type-post-meta.php';
94
+ $register->register(new FW_Option_Storage_Type_Post_Meta());
95
+
96
+ require_once $dir .'/type/class-fw-option-storage-type-wp-option.php';
97
+ $register->register(new FW_Option_Storage_Type_WP_Option());
98
+ }
99
+
100
+ do_action('fw:option-storage-types:register', $register);
101
+
102
+ $types = $register->_get_types($access_key);
103
+ }
104
+
105
+ if (empty($type)) {
106
+ return $types;
107
+ } elseif (isset($types[$type])) {
108
+ return $types[$type];
109
+ } else {
110
+ return null;
111
+ }
112
+ }
framework/includes/hooks.php CHANGED
@@ -20,6 +20,11 @@
20
  */
21
  if (is_admin()) {
22
  require_once dirname(__FILE__) . '/option-types/multi-select/class-fw-option-type-multi-select.php';
 
 
 
 
 
23
  }
24
  }
25
 
20
  */
21
  if (is_admin()) {
22
  require_once dirname(__FILE__) . '/option-types/multi-select/class-fw-option-type-multi-select.php';
23
+
24
+ if (!class_exists('FW_Option_Type_Icon_v2')) {
25
+ require_once dirname(__FILE__) .
26
+ '/option-types/icon-v2/class-fw-option-type-icon-v2.php';
27
+ }
28
  }
29
  }
30
 
framework/includes/option-types/date-picker/static/js/scripts.js CHANGED
@@ -18,13 +18,13 @@ function fw_option_type_date_picker_initialize(object) {
18
  var date = null;
19
 
20
  if (options.minDate != null || options.minDate != undefined) {
21
- date = options.minDate.split('-');
22
- defaults.startDate = new Date(date[2], date[1], date[0]);
23
  }
24
 
25
  if (options.maxDate != null || options.maxDate != undefined) {
26
- date = options.maxDate.split('-');
27
- defaults.endDate = new Date(date[2], date[1], date[0]);
28
  }
29
 
30
  if (options.weekStart != null || options.weekStart != undefined) {
18
  var date = null;
19
 
20
  if (options.minDate != null || options.minDate != undefined) {
21
+ date = options.minDate.split('-').map(Number);
22
+ defaults.startDate = new Date(date[2], date[1] - 1, date[0]);
23
  }
24
 
25
  if (options.maxDate != null || options.maxDate != undefined) {
26
+ date = options.maxDate.split('-').map(Number);
27
+ defaults.endDate = new Date(date[2], date[1] - 1, date[0]);
28
  }
29
 
30
  if (options.weekStart != null || options.weekStart != undefined) {
framework/includes/option-types/icon-v2/class-fw-option-type-icon-v2.php CHANGED
@@ -19,15 +19,17 @@ class FW_Option_Type_Icon_v2 extends FW_Option_Type
19
  {
20
  $this->packs_loader = new FW_Icon_V2_Packs_Loader();
21
  $this->favorites = new FW_Icon_V2_Favorites_Manager();
22
- $this->favorites->attach_ajax_actions();
23
 
24
- add_action(
25
- 'wp_enqueue_scripts',
26
- array($this->packs_loader, 'enqueue_frontend_css' )
27
- );
 
 
 
28
  }
29
 
30
- protected function _enqueue_static($id, $option, $data)/*{{{*/
31
  {
32
  $this->packs_loader->enqueue_admin_css();
33
 
@@ -66,7 +68,7 @@ class FW_Option_Type_Icon_v2 extends FW_Option_Type
66
  'fw-option-type-'. $this->get_type() .'-backend-previews',
67
  'fw_icon_v2_data',
68
  array(
69
- 'edit_icon_label' => __('Edit Icon', 'fw'),
70
  'add_icon_label' => __('Add Icon', 'fw'),
71
  'icon_fonts_label' => __('Icons', 'fw'),
72
  'custom_upload_label' => __('Upload', 'fw'),
@@ -178,8 +180,8 @@ class FW_Option_Type_Icon_v2 extends FW_Option_Type
178
  // 'url' => false
179
  ),
180
 
181
- 'preview-size' => 'medium',
182
- 'popup-size' => 'large'
183
  );
184
  }
185
 
@@ -189,4 +191,7 @@ class FW_Option_Type_Icon_v2 extends FW_Option_Type
189
  }
190
  }
191
 
 
 
 
192
  FW_Option_Type::register( 'FW_Option_Type_Icon_v2' );
19
  {
20
  $this->packs_loader = new FW_Icon_V2_Packs_Loader();
21
  $this->favorites = new FW_Icon_V2_Favorites_Manager();
 
22
 
23
+ /**
24
+ * CSS for each pack is not loaded by default in frontend.
25
+ *
26
+ * You should load it by yourself in your theme, like this:
27
+ *
28
+ * fw()->backend->option_type('icon-v2')->packs_loader->enqueue_frontend_css()
29
+ */
30
  }
31
 
32
+ protected function _enqueue_static($id, $option, $data)
33
  {
34
  $this->packs_loader->enqueue_admin_css();
35
 
68
  'fw-option-type-'. $this->get_type() .'-backend-previews',
69
  'fw_icon_v2_data',
70
  array(
71
+ 'edit_icon_label' => __('Change Icon', 'fw'),
72
  'add_icon_label' => __('Add Icon', 'fw'),
73
  'icon_fonts_label' => __('Icons', 'fw'),
74
  'custom_upload_label' => __('Upload', 'fw'),
180
  // 'url' => false
181
  ),
182
 
183
+ 'preview_size' => 'medium',
184
+ 'popup_size' => 'medium'
185
  );
186
  }
187
 
191
  }
192
  }
193
 
194
+ $favorites = new FW_Icon_V2_Favorites_Manager();
195
+ $favorites->attach_ajax_actions();
196
+
197
  FW_Option_Type::register( 'FW_Option_Type_Icon_v2' );
framework/includes/option-types/icon-v2/includes/class-fw-icon-v2-packs-loader.php CHANGED
@@ -24,7 +24,7 @@ class FW_Icon_V2_Packs_Loader
24
  * Example:
25
  *
26
  * add_filter(
27
- * 'fw:option-type:icon-v2:packs',
28
  * '_add_more_packs'
29
  * );
30
  *
@@ -134,7 +134,8 @@ class FW_Icon_V2_Packs_Loader
134
 
135
  wp_enqueue_style(
136
  'fw-option-type-icon-v2-pack-' . $pack_name . '-css',
137
- $pack['css_file_uri']
 
138
  );
139
 
140
  }
24
  * Example:
25
  *
26
  * add_filter(
27
+ * 'fw:option_type:icon-v2:packs',
28
  * '_add_more_packs'
29
  * );
30
  *
134
 
135
  wp_enqueue_style(
136
  'fw-option-type-icon-v2-pack-' . $pack_name . '-css',
137
+ $pack['css_file_uri'],
138
+ array()
139
  );
140
 
141
  }
framework/includes/option-types/icon-v2/static/css/picker.css CHANGED
@@ -3,9 +3,13 @@
3
  align-items: center;
4
  }
5
 
 
 
 
 
 
6
  .fw-icon-v2-preview {
7
- background-color: #fafafa;
8
- border: 1px dashed #b7b7b7;
9
  margin-right: 25px;
10
  position: relative;
11
  display: flex;
@@ -16,6 +20,10 @@
16
  box-sizing: border-box;
17
  }
18
 
 
 
 
 
19
  .fw-icon-v2-preview i {
20
  color: #7a7a7a;
21
  background-repeat: no-repeat;
@@ -23,13 +31,21 @@
23
 
24
  .fw-icon-v2-preview a {
25
  position: absolute;
26
- top: -10px;
27
- right: -10px;
28
- display: none;
 
 
 
 
29
  }
30
 
31
- .fw-has-icon .fw-icon-v2-preview a {
32
- display: block;
 
 
 
 
33
  }
34
 
35
  .fw-icon-v2-preview a:before {
@@ -37,9 +53,11 @@
37
  border-radius: 100%;
38
  }
39
 
40
- .fw-icon-v2-preview-small [data-icon-type="icon-font"] .fw-icon-v2-preview i,
41
- .fw-icon-v2-preview-medium [data-icon-type="icon-font"] .fw-icon-v2-preview i,
42
- .fw-icon-v2-preview-large [data-icon-type="icon-font"] .fw-icon-v2-preview i {
 
 
43
  display: flex;
44
  align-items: center;
45
  justify-content: center;
@@ -53,9 +71,9 @@
53
  }
54
 
55
  .fw-icon-v2-preview-small .fw-icon-v2-preview i {
56
- font-size: 15px;
57
- width: 15px;
58
- height: 15px;
59
  }
60
 
61
  /*** Medium Preview ***/
@@ -65,10 +83,9 @@
65
  }
66
 
67
  .fw-icon-v2-preview-medium .fw-icon-v2-preview i {
68
- font-size: 30px;
69
- width: 30px;
70
- height: 30px;
71
- background-size: cover;
72
  }
73
 
74
  /*** Large Preview ***/
@@ -78,11 +95,23 @@
78
  }
79
 
80
  .fw-icon-v2-preview-large .fw-icon-v2-preview i {
81
- font-size: 45px;
82
- width: 45px;
83
- height: 45px;
84
  }
85
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
  /*** Icon Picker Modal *******************************************************/
88
  .fw-icon-v2-picker-modal li:first-child .nav-tab {
@@ -116,7 +145,7 @@
116
 
117
  .fw-icon-v2-picker-modal .fw-icon-v2-library-packs-wrapper {
118
  overflow-y: auto;
119
- height: 460px;
120
  padding: 0 20px;
121
  }
122
 
@@ -156,12 +185,15 @@
156
  float: left;
157
  }
158
 
 
 
 
 
159
  .fw-icon-v2-picker-modal h2 {
160
  position: relative;
161
  text-align: left;
162
  font-size: 13px;
163
  color: #0085ba;
164
- /*overflow: hidden;*/
165
  }
166
 
167
  .fw-icon-v2-picker-modal h2:first-of-type {
@@ -222,7 +254,6 @@
222
  border: 3px solid transparent;
223
  border-radius: 4px;
224
  cursor: pointer;
225
- transition: all 0.2s ease;
226
  }
227
 
228
  .fw-icon-v2-picker-modal .fw-option-html ul li:hover {
@@ -250,26 +281,42 @@
250
 
251
  .fw-icon-v2-picker-modal .fw-option-html ul li.selected:after {
252
  opacity: 1;
253
- transition: opacity 0.2s ease;
254
  }
255
 
256
  .fw-icon-v2-picker-modal .fw-option-html ul li > i {
257
  color: #666;
258
  font-size: 22px;
259
  text-align: center;
260
- transition: color 0.2s ease;
261
  }
262
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
  /*** Favorited Icons ***/
264
  .fw-icon-v2-picker-modal .fw-option-html ul li a {
265
  position: absolute;
266
  padding: 5px;
267
  top: -2px;
268
- right: -3px;
269
  width: 12px;
270
  height: 12px;
271
  cursor: pointer;
272
- transition: all 0.2s ease;
 
 
 
 
273
  }
274
 
275
  .fw-icon-v2-picker-modal .fw-option-html ul li a i {
@@ -277,31 +324,15 @@
277
  width: 12px;
278
  height: 12px;
279
  color: #e0e0e0;
280
- transition: all 0.2s ease;
281
- }
282
-
283
- .fw-icon-v2-picker-modal .fw-option-html ul li:not(.fw-icon-v2-favorite) a {
284
- opacity: 0;
285
- }
286
-
287
- .fw-icon-v2-picker-modal .fw-option-html ul li:hover a {
288
- opacity: 1;
289
  }
290
 
291
  .fw-icon-v2-picker-modal .fw-option-html ul li a:hover i,
292
- .fw-icon-v2-picker-modal .fw-option-html ul li.fw-icon-v2-favorite a i {
293
- color: #FFC93C;
294
- }
295
-
296
-
297
- .fw-icon-v2-picker-modal .fw-option-html .fw-icon-v2-icon-favorites ul li a {
298
- opacity: 1;
299
- }
300
-
301
- .fw-icon-v2-picker-modal .fw-option-html .fw-icon-v2-icon-favorites ul li a:hover i {
302
- color: #FF4617;
303
  }
304
 
 
305
  .fw-icon-v2-icon-favorites h4 {
306
  margin-top: 4px;
307
  margin-bottom: 15px;
@@ -309,12 +340,25 @@
309
  font-weight: 600;
310
  }
311
 
 
312
  .fw-icon-v2-info {
313
  font-size: 12px !important;
314
  line-height: 18px !important;
315
  color: #FFC93C;
316
  }
317
 
 
 
 
 
 
318
 
 
 
 
 
319
 
320
-
 
 
 
3
  align-items: center;
4
  }
5
 
6
+ .fw-icon-v2-preview-wrapper.fw-has-icon .fw-icon-v2-preview {
7
+ background-image: url(../img/transparent_bg.png);
8
+ background-size: 10px;
9
+ }
10
+
11
  .fw-icon-v2-preview {
12
+ background-image: url('../img/no-image.png');
 
13
  margin-right: 25px;
14
  position: relative;
15
  display: flex;
20
  box-sizing: border-box;
21
  }
22
 
23
+ .fw-icon-v2-preview:hover {
24
+ opacity: 0.9;
25
+ }
26
+
27
  .fw-icon-v2-preview i {
28
  color: #7a7a7a;
29
  background-repeat: no-repeat;
31
 
32
  .fw-icon-v2-preview a {
33
  position: absolute;
34
+ opacity: 0;
35
+ width: 12px;
36
+ height: 12px;
37
+ top: -9px;
38
+ right: -6px;
39
+ font-size: 14px !important;
40
+ outline: none;
41
  }
42
 
43
+ .fw-icon-v2-preview-wrapper.fw-has-icon .fw-icon-v2-preview:hover {
44
+ opacity: 1;
45
+ }
46
+
47
+ .fw-icon-v2-preview-wrapper.fw-has-icon .fw-icon-v2-preview:hover a {
48
+ opacity: 1;
49
  }
50
 
51
  .fw-icon-v2-preview a:before {
53
  border-radius: 100%;
54
  }
55
 
56
+ .fw-icon-v2-preview-wrapper[data-icon-type="custom-upload"] .fw-icon-v2-preview i {
57
+ background-size: cover;
58
+ }
59
+
60
+ .fw-icon-v2-preview-wrapper[data-icon-type="icon-font"] .fw-icon-v2-preview i {
61
  display: flex;
62
  align-items: center;
63
  justify-content: center;
71
  }
72
 
73
  .fw-icon-v2-preview-small .fw-icon-v2-preview i {
74
+ font-size: 26px;
75
+ width: 26px;
76
+ height: 26px;
77
  }
78
 
79
  /*** Medium Preview ***/
83
  }
84
 
85
  .fw-icon-v2-preview-medium .fw-icon-v2-preview i {
86
+ font-size: 50px;
87
+ width: 50px;
88
+ height: 50px;
 
89
  }
90
 
91
  /*** Large Preview ***/
95
  }
96
 
97
  .fw-icon-v2-preview-large .fw-icon-v2-preview i {
98
+ font-size: 65px;
99
+ width: 65px;
100
+ height: 65px;
101
  }
102
 
103
+ /*** Sauron Preview :) ***/
104
+ .fw-icon-v2-preview-sauron .fw-icon-v2-preview {
105
+ background-image: url('../img/sauron.png');
106
+ width: 70px;
107
+ height: 70px;
108
+ }
109
+
110
+ .fw-icon-v2-preview-sauron .fw-icon-v2-preview i {
111
+ font-size: 65px;
112
+ width: 65px;
113
+ height: 65px;
114
+ }
115
 
116
  /*** Icon Picker Modal *******************************************************/
117
  .fw-icon-v2-picker-modal li:first-child .nav-tab {
145
 
146
  .fw-icon-v2-picker-modal .fw-icon-v2-library-packs-wrapper {
147
  overflow-y: auto;
148
+ overflow-x: hidden;
149
  padding: 0 20px;
150
  }
151
 
185
  float: left;
186
  }
187
 
188
+ .fw-icon-v2-picker-modal .fw-icon-v2-toolbar .selectize-control .selectize-input > input {
189
+ display: none !important;
190
+ }
191
+
192
  .fw-icon-v2-picker-modal h2 {
193
  position: relative;
194
  text-align: left;
195
  font-size: 13px;
196
  color: #0085ba;
 
197
  }
198
 
199
  .fw-icon-v2-picker-modal h2:first-of-type {
254
  border: 3px solid transparent;
255
  border-radius: 4px;
256
  cursor: pointer;
 
257
  }
258
 
259
  .fw-icon-v2-picker-modal .fw-option-html ul li:hover {
281
 
282
  .fw-icon-v2-picker-modal .fw-option-html ul li.selected:after {
283
  opacity: 1;
 
284
  }
285
 
286
  .fw-icon-v2-picker-modal .fw-option-html ul li > i {
287
  color: #666;
288
  font-size: 22px;
289
  text-align: center;
 
290
  }
291
 
292
+ /*** Icon Grid Size, depending on modal size ***/
293
+ /*** Small Modal ***/
294
+ .fw-icon-v2-picker-modal.fw-modal-small .fw-option-html ul li {
295
+ width: 58.5px;
296
+ height: 58.5px;
297
+ }
298
+
299
+ /*** Large Modal ***/
300
+ .fw-icon-v2-picker-modal.fw-modal-large .fw-option-html ul li {
301
+ width: 62.2px;
302
+ height: 62.2px;
303
+ }
304
+
305
+
306
  /*** Favorited Icons ***/
307
  .fw-icon-v2-picker-modal .fw-option-html ul li a {
308
  position: absolute;
309
  padding: 5px;
310
  top: -2px;
311
+ right: -2px;
312
  width: 12px;
313
  height: 12px;
314
  cursor: pointer;
315
+ opacity: 0;
316
+ }
317
+
318
+ .fw-icon-v2-picker-modal .fw-option-html ul li:hover a {
319
+ opacity: 1;
320
  }
321
 
322
  .fw-icon-v2-picker-modal .fw-option-html ul li a i {
324
  width: 12px;
325
  height: 12px;
326
  color: #e0e0e0;
 
 
 
 
 
 
 
 
 
327
  }
328
 
329
  .fw-icon-v2-picker-modal .fw-option-html ul li a:hover i,
330
+ .fw-icon-v2-picker-modal .fw-option-html ul li.fw-icon-v2-favorite i,
331
+ .fw-icon-v2-picker-modal .fw-option-html .fw-icon-v2-icon-favorites ul li i {
332
+ color: #ffb900;
 
 
 
 
 
 
 
 
333
  }
334
 
335
+ /*** Icon Packs Divider ***/
336
  .fw-icon-v2-icon-favorites h4 {
337
  margin-top: 4px;
338
  margin-bottom: 15px;
340
  font-weight: 600;
341
  }
342
 
343
+ /*** Favorited Icons Info **/
344
  .fw-icon-v2-info {
345
  font-size: 12px !important;
346
  line-height: 18px !important;
347
  color: #FFC93C;
348
  }
349
 
350
+ /*** Style Input Placeholder ***/
351
+ .fw-icon-v2-picker-modal .fw-icon-v2-toolbar > input::-webkit-input-placeholder {
352
+ font-style: normal;
353
+ color: #333333;
354
+ }
355
 
356
+ .fw-icon-v2-picker-modal .fw-icon-v2-toolbar > input::-moz-placeholder {
357
+ font-style: normal;
358
+ color: #333333;
359
+ }
360
 
361
+ .fw-icon-v2-picker-modal .fw-icon-v2-toolbar > input:-ms-input-placeholder {
362
+ font-style: normal;
363
+ color: #333333;
364
+ }
framework/includes/option-types/icon-v2/static/img/no-image.png ADDED
Binary file
framework/includes/option-types/icon-v2/static/img/sauron.png ADDED
Binary file
framework/includes/option-types/icon-v2/static/img/transparent_bg.png ADDED
Binary file
framework/includes/option-types/icon-v2/static/js/icon-picker.js CHANGED
@@ -31,7 +31,10 @@ window.fwOptionTypeIconV2Picker = (function ($) {
31
  }
32
 
33
  function createModal (modalSize) {
34
- if (modal) return;
 
 
 
35
 
36
  modal = new fw.OptionsModal({
37
  modalCustomClass: 'fw-icon-v2-picker-modal',
@@ -379,7 +382,9 @@ window.fwOptionTypeIconV2Picker = (function ($) {
379
  renderIconsLibrary({
380
  search: search,
381
  packs: packs
382
- })
 
 
383
  }
384
 
385
  function fuzzyConsecutive (query, search) {
@@ -431,7 +436,7 @@ window.fwOptionTypeIconV2Picker = (function ($) {
431
  $icons.height(
432
  modal.frame.$el.find(
433
  '.fw-options-tabs-contents.metabox-holder'
434
- ).height() - toolbarHeight
435
  );
436
  }
437
 
31
  }
32
 
33
  function createModal (modalSize) {
34
+ if (modal) {
35
+ modal.set('size', modalSize);
36
+ return;
37
+ }
38
 
39
  modal = new fw.OptionsModal({
40
  modalCustomClass: 'fw-icon-v2-picker-modal',
382
  renderIconsLibrary({
383
  search: search,
384
  packs: packs
385
+ });
386
+
387
+ refreshFavoritesClasses(currentFavorites);
388
  }
389
 
390
  function fuzzyConsecutive (query, search) {
436
  $icons.height(
437
  modal.frame.$el.find(
438
  '.fw-options-tabs-contents.metabox-holder'
439
+ ).height() - toolbarHeight - 50
440
  );
441
  }
442
 
framework/includes/option-types/icon-v2/view.php CHANGED
@@ -14,9 +14,9 @@ fw_print($json);
14
  */
15
 
16
  $wrapper_attr = array(
17
- 'class' => $option['attr']['class'] . ' fw-icon-v2-preview-' . $option['preview-size'],
18
  'id' => $option['attr']['id'],
19
- 'data-fw-modal-size' => $option['popup-size']
20
  );
21
 
22
  unset($option['attr']['class'], $option['attr']['id']);
14
  */
15
 
16
  $wrapper_attr = array(
17
+ 'class' => $option['attr']['class'] . ' fw-icon-v2-preview-' . $option['preview_size'],
18
  'id' => $option['attr']['id'],
19
+ 'data-fw-modal-size' => $option['popup_size']
20
  );
21
 
22
  unset($option['attr']['class'], $option['attr']['id']);
framework/includes/option-types/init.php CHANGED
@@ -5,7 +5,6 @@ $dir = dirname(__FILE__);
5
  require $dir . '/simple.php';
6
 
7
  require $dir . '/icon/class-fw-option-type-icon.php';
8
- //require $dir . '/icon-v2/class-fw-option-type-icon-v2.php';
9
  require $dir . '/image-picker/class-fw-option-type-image-picker.php';
10
  require $dir . '/upload/class-fw-option-type-upload.php';
11
  require $dir . '/color-picker/class-fw-option-type-color-picker.php';
@@ -32,6 +31,11 @@ require $dir . '/range-slider/class-fw-option-type-range-slider.php';
32
  require $dir . '/rgba-color-picker/class-fw-option-type-rgba-color-picker.php';
33
  require $dir . '/typography-v2/class-fw-option-type-typography-v2.php';
34
  require $dir . '/oembed/class-fw-option-type-oembed.php';
 
35
  if (!class_exists('FW_Option_Type_Multi_Select')) {
36
  require $dir . '/multi-select/class-fw-option-type-multi-select.php';
37
  }
 
 
 
 
5
  require $dir . '/simple.php';
6
 
7
  require $dir . '/icon/class-fw-option-type-icon.php';
 
8
  require $dir . '/image-picker/class-fw-option-type-image-picker.php';
9
  require $dir . '/upload/class-fw-option-type-upload.php';
10
  require $dir . '/color-picker/class-fw-option-type-color-picker.php';
31
  require $dir . '/rgba-color-picker/class-fw-option-type-rgba-color-picker.php';
32
  require $dir . '/typography-v2/class-fw-option-type-typography-v2.php';
33
  require $dir . '/oembed/class-fw-option-type-oembed.php';
34
+
35
  if (!class_exists('FW_Option_Type_Multi_Select')) {
36
  require $dir . '/multi-select/class-fw-option-type-multi-select.php';
37
  }
38
+
39
+ if (!class_exists('FW_Option_Type_Icon_v2')) {
40
+ require_once $dir . '/icon-v2/class-fw-option-type-icon-v2.php';
41
+ }
framework/includes/option-types/wp-editor/includes/class-fw-wp-editor-settings.php CHANGED
@@ -11,28 +11,10 @@ class FW_WP_Editor_Manager {
11
  private $option = null;
12
  private $data = null;
13
 
14
- /**
15
- * https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-editor.php#L305
16
- * An _WP_Editors::editor_settings call mutates those fields I list below.
17
- *
18
- * I need them to be mocked and after the manipulations are done to be
19
- * safely restored. I don't to cause troubles to WordPress execution engine.
20
-
21
- * 1. self::$first_init set to array() in order to skip add_action(), then restore
22
- * 2. preserve self::$qt_settings value
23
- * 3. preserve self::$qt_buttons
24
- * 4. preserve self::$baseurl
25
- * 5. preserve self::$mce_locale
26
- * 6. preserve self::$first_init
27
- * 7. $set['teeny'] should be not set
28
- * 8. preserve self::$mce_settings
29
- */
30
- private $fields_to_mock_in_wp_editors = array(
31
- 'first_init', 'qt_settings', 'qt_buttons', 'baseurl',
32
- 'mce_locale', 'first_init', 'mce_settings'
33
- );
34
- private $mock_data = null;
35
- private $reflection_class = null;
36
 
37
  public function __construct($id, $option, $data) {
38
  $this->id = $id;
@@ -47,6 +29,7 @@ class FW_WP_Editor_Manager {
47
  $this->editor_id = fw()->backend->option_type('wp-editor')->get_id_prefix() . fw_rand_md5();
48
  }
49
 
 
50
  public function get_html() {
51
  ob_start();
52
 
@@ -76,7 +59,6 @@ class FW_WP_Editor_Manager {
76
  $option['attr']['data-fw-mce-settings'] = json_encode($preinit_data['mce_settings']);
77
  $option['attr']['data-fw-qt-settings'] = json_encode($preinit_data['qt_settings']);
78
 
79
-
80
  if ($option['shortcodes']) {
81
  $option['attr']['data-fw-shortcodes-list'] = json_encode(
82
  $option['shortcodes']
@@ -141,7 +123,6 @@ class FW_WP_Editor_Manager {
141
  }
142
 
143
  public function get_set() {
144
-
145
  $set = _WP_Editors::parse_settings(
146
  $this->editor_id,
147
  $this->get_settings()
@@ -162,21 +143,7 @@ class FW_WP_Editor_Manager {
162
  * fingerprints there.
163
  */
164
  public function get_preinit_data_for_editor() {
165
- $this->mock_wp_editors_class();
166
-
167
- /**
168
- * We are safe to do any modifications to the _WP_Editors here.
169
- * Any mocked data will be restored after our manipulations.
170
- */
171
-
172
- /**
173
- * Skip add_action()
174
- * https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-editor.php#L308
175
- */
176
- $this->set_static_field(
177
- 'first_init',
178
- array()
179
- );
180
 
181
  /**
182
  * Set:
@@ -191,14 +158,8 @@ class FW_WP_Editor_Manager {
191
  $this->get_set()
192
  );
193
 
194
- $mce_settings = $this->get_static_field('mce_settings');
195
- $qt_settings = $this->get_static_field('qt_settings');
196
-
197
- $mce_settings = fw_akg(
198
- $this->editor_id,
199
- $mce_settings,
200
- array()
201
- );
202
 
203
  if ( isset($mce_settings['formats']) ) {
204
  /**
@@ -235,60 +196,64 @@ class FW_WP_Editor_Manager {
235
  }
236
  }
237
 
238
- $qt_settings = fw_akg(
239
- $this->editor_id,
240
- $qt_settings,
241
- array()
242
- );
243
-
244
  $preinit_data = array(
245
  'mce_settings' => $mce_settings,
246
  'qt_settings' => $qt_settings
247
  );
248
 
249
- $this->restore_wp_editors_class();
250
 
251
  return $preinit_data;
252
  }
253
 
254
- public function mock_wp_editors_class() {
255
- $this->reflection_class = new ReflectionClass('_WP_Editors');
256
- $this->mock_data = array();
257
-
258
- array_map(
259
- array($this, 'backup_static_field'),
260
- $this->fields_to_mock_in_wp_editors
261
  );
262
- }
263
 
264
- public function restore_wp_editors_class() {
265
- array_map(
266
- array($this, 'restore_static_field'),
267
- $this->fields_to_mock_in_wp_editors
268
  );
269
 
270
- $this->reflection_class = null;
271
- $this->mock_data = null;
 
 
 
272
  }
273
 
274
- public function backup_static_field($field) {
275
- $this->mock_data[$field] = $this->get_static_field($field);
276
- }
 
 
 
277
 
278
- public function restore_static_field($field) {
279
- $this->set_static_field($field, $this->mock_data[$field]);
 
 
 
 
 
 
 
 
 
280
  }
281
 
282
- public function set_static_field($field, $value) {
283
- $property = $this->reflection_class->getProperty($field);
284
- $property->setAccessible(true);
285
- $property->setValue($value);
286
  }
287
 
288
- public function get_static_field($field) {
289
- $property = $this->reflection_class->getProperty($field);
290
- $property->setAccessible(true);
291
- return $property->getValue();
292
  }
293
  }
294
 
11
  private $option = null;
12
  private $data = null;
13
 
14
+ private $qt_settings = null;
15
+ private $mce_settings = null;
16
+
17
+ private $priority = 999999999999999;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  public function __construct($id, $option, $data) {
20
  $this->id = $id;
29
  $this->editor_id = fw()->backend->option_type('wp-editor')->get_id_prefix() . fw_rand_md5();
30
  }
31
 
32
+
33
  public function get_html() {
34
  ob_start();
35
 
59
  $option['attr']['data-fw-mce-settings'] = json_encode($preinit_data['mce_settings']);
60
  $option['attr']['data-fw-qt-settings'] = json_encode($preinit_data['qt_settings']);
61
 
 
62
  if ($option['shortcodes']) {
63
  $option['attr']['data-fw-shortcodes-list'] = json_encode(
64
  $option['shortcodes']
123
  }
124
 
125
  public function get_set() {
 
126
  $set = _WP_Editors::parse_settings(
127
  $this->editor_id,
128
  $this->get_settings()
143
  * fingerprints there.
144
  */
145
  public function get_preinit_data_for_editor() {
146
+ $this->attach_filters();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
  /**
149
  * Set:
158
  $this->get_set()
159
  );
160
 
161
+ $mce_settings = $this->mce_settings;
162
+ $qt_settings = $this->qt_settings;
 
 
 
 
 
 
163
 
164
  if ( isset($mce_settings['formats']) ) {
165
  /**
196
  }
197
  }
198
 
 
 
 
 
 
 
199
  $preinit_data = array(
200
  'mce_settings' => $mce_settings,
201
  'qt_settings' => $qt_settings
202
  );
203
 
204
+ $this->dettach_filters();
205
 
206
  return $preinit_data;
207
  }
208
 
209
+ public function attach_filters() {
210
+ add_filter(
211
+ 'tiny_mce_before_init',
212
+ array($this, 'mce_settings_callback'),
213
+ $this->priority
 
 
214
  );
 
215
 
216
+ add_filter(
217
+ 'quicktags_settings',
218
+ array($this, 'quicktags_settings_callback'),
219
+ $this->priority
220
  );
221
 
222
+ add_filter(
223
+ 'teeny_mce_before_init',
224
+ array($this, 'mce_settings_callback'),
225
+ $this->priority
226
+ );
227
  }
228
 
229
+ public function dettach_filters() {
230
+ remove_filter(
231
+ 'quicktags_settings',
232
+ array($this, 'quicktags_settings_callback'),
233
+ $this->priority
234
+ );
235
 
236
+ remove_filter(
237
+ 'tiny_mce_before_init',
238
+ array($this, 'mce_settings_callback'),
239
+ $this->priority
240
+ );
241
+
242
+ remove_filter(
243
+ 'teeny_mce_before_init',
244
+ array($this, 'mce_settings_callback'),
245
+ $this->priority
246
+ );
247
  }
248
 
249
+ public function quicktags_settings_callback($qt_settings) {
250
+ $this->qt_settings = $qt_settings;
251
+ return $qt_settings;
 
252
  }
253
 
254
+ public function mce_settings_callback($mce_settings) {
255
+ $this->mce_settings = $mce_settings;
256
+ return $mce_settings;
 
257
  }
258
  }
259
 
framework/manifest.php CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
- $manifest['version'] = '2.5.8';
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
+ $manifest['version'] = '2.5.9';
framework/static/css/backend-options.css CHANGED
@@ -58,7 +58,7 @@ Included on pages where backend options are rendered
58
 
59
  .fw-options-tabs-wrapper > .fw-options-tabs-list {
60
  border-bottom: 1px solid #CCC;
61
- padding: 0 10px;
62
  }
63
 
64
  .fw-options-tabs-wrapper > .fw-options-tabs-list ul,
@@ -69,8 +69,8 @@ Included on pages where backend options are rendered
69
 
70
  .fw-options-tabs-wrapper > .fw-options-tabs-list ul li {
71
  float: left;
72
- margin-right: 6px;
73
  }
 
74
  body.rtl .fw-options-tabs-wrapper > .fw-options-tabs-list ul li {
75
  float: right;
76
  margin-right: 0px;
@@ -95,7 +95,7 @@ body.rtl .fw-options-tabs-wrapper > .fw-options-tabs-list ul li {
95
  }
96
 
97
  .postbox .fw-options-tabs-wrapper > .fw-options-tabs-list {
98
- padding-top: 10px;
99
  }
100
 
101
  .postbox .fw-options-tabs-wrapper > .fw-options-tabs-list ul li a.nav-tab {
@@ -881,6 +881,10 @@ body.rtl .fw-postbox .handlediv:before {
881
  border-bottom: 1px solid #eeeeee;
882
  }
883
 
 
 
 
 
884
  .fw-force-xs .fw-backend-option-design-default {
885
  padding: 15px 12px;
886
  }
58
 
59
  .fw-options-tabs-wrapper > .fw-options-tabs-list {
60
  border-bottom: 1px solid #CCC;
61
+ /*padding: 0 10px;*/
62
  }
63
 
64
  .fw-options-tabs-wrapper > .fw-options-tabs-list ul,
69
 
70
  .fw-options-tabs-wrapper > .fw-options-tabs-list ul li {
71
  float: left;
 
72
  }
73
+
74
  body.rtl .fw-options-tabs-wrapper > .fw-options-tabs-list ul li {
75
  float: right;
76
  margin-right: 0px;
95
  }
96
 
97
  .postbox .fw-options-tabs-wrapper > .fw-options-tabs-list {
98
+ padding: 10px 10px 0 10px;
99
  }
100
 
101
  .postbox .fw-options-tabs-wrapper > .fw-options-tabs-list ul li a.nav-tab {
881
  border-bottom: 1px solid #eeeeee;
882
  }
883
 
884
+ .fw-backend-option-design-default.fw-bottom-border-hidden {
885
+ border-bottom-color: transparent;
886
+ }
887
+
888
  .fw-force-xs .fw-backend-option-design-default {
889
  padding: 15px 12px;
890
  }
framework/static/css/fw.css CHANGED
@@ -3036,7 +3036,7 @@ body.wp-customizer > div:not(.fw-modal) > .media-modal-backdrop {
3036
  /* tabs fixes */
3037
 
3038
  .fw-modal .fw-options-tabs-first-level > .fw-options-tabs-list {
3039
- padding-top: 20px;
3040
  }
3041
 
3042
  .fw-modal .fw-options-tabs-wrapper > .fw-options-tabs-contents > .fw-inner > .fw-options-tab > .fw-options-tabs-wrapper > .fw-options-tabs-list {
3036
  /* tabs fixes */
3037
 
3038
  .fw-modal .fw-options-tabs-first-level > .fw-options-tabs-list {
3039
+ padding: 20px 10px 0 10px;
3040
  }
3041
 
3042
  .fw-modal .fw-options-tabs-wrapper > .fw-options-tabs-contents > .fw-inner > .fw-options-tab > .fw-options-tabs-wrapper > .fw-options-tabs-list {
framework/static/js/fw.js CHANGED
@@ -650,8 +650,19 @@ fw.getQueryString = function(name) {
650
  this.afterHtmlReplaceFixes();
651
  }
652
  },
 
 
 
 
 
 
 
 
 
 
653
  initialize: function() {
654
  this.listenTo(this.model, 'change:html', this.render);
 
655
  },
656
  /**
657
  * Call this after html replace
650
  this.afterHtmlReplaceFixes();
651
  }
652
  },
653
+ renderSizeClass: function () {
654
+ var $modalWrapper = this.model.frame.modal.$el;
655
+ var allSizes = ['large', 'medium', 'small'];
656
+
657
+ $modalWrapper.removeClass(
658
+ _.map(allSizes, formSizeClass).join(' ')
659
+ ).addClass(formSizeClass(this.model.get('size')));
660
+
661
+ function formSizeClass (size) { return 'fw-modal-' + size; }
662
+ },
663
  initialize: function() {
664
  this.listenTo(this.model, 'change:html', this.render);
665
+ this.listenTo(this.model, 'change:size', this.renderSizeClass);
666
  },
667
  /**
668
  * Call this after html replace
framework/static/libs/moment/moment-with-locales.min.js CHANGED
@@ -670,4 +670,6 @@ doy:4}}),kg.defineLocale("x-pseudo",{months:"J~áñúá~rý_F~ébrú~árý_~Már
670
  doy:4}}),kg.defineLocale("zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah点mm分",LTS:"Ah点m分s秒",L:"YYYY-MM-DD",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah点mm分",LLLL:"YYYY年MMMD日ddddAh点mm分",l:"YYYY-MM-DD",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah点mm分",llll:"YYYY年MMMD日ddddAh点mm分"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"凌晨"===b||"早上"===b||"上午"===b?a:"下午"===b||"晚上"===b?a+12:a>=11?a:a+12},meridiem:function(a,b,c){var d=100*a+b;return 600>d?"凌晨":900>d?"早上":1130>d?"上午":1230>d?"中午":1800>d?"下午":"晚上"},calendar:{sameDay:function(){return 0===this.minutes()?"[今天]Ah[点整]":"[今天]LT"},nextDay:function(){return 0===this.minutes()?"[明天]Ah[点整]":"[明天]LT"},lastDay:function(){return 0===this.minutes()?"[昨天]Ah[点整]":"[昨天]LT"},nextWeek:function(){var a,b;return a=kg().startOf("week"),b=this.diff(a,"days")>=7?"[下]":"[本]",0===this.minutes()?b+"dddAh点整":b+"dddAh点mm"},lastWeek:function(){var a,b;return a=kg().startOf("week"),b=this.unix()<a.unix()?"[上]":"[本]",0===this.minutes()?b+"dddAh点整":b+"dddAh点mm"},sameElse:"LL"},ordinalParse:/\d{1,2}(日|月|周)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"周";default:return a}},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"},week:{
671
  // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
672
  dow:1,// Monday is the first day of the week.
673
- doy:4}}),kg.defineLocale("zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah點mm分",LTS:"Ah點m分s秒",L:"YYYY年MMMD日",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah點mm分",LLLL:"YYYY年MMMD日ddddAh點mm分",l:"YYYY年MMMD日",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah點mm分",llll:"YYYY年MMMD日ddddAh點mm分"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"凌晨"===b||"早上"===b||"上午"===b?a:"中午"===b?a>=11?a:a+12:"下午"===b||"晚上"===b?a+12:void 0},meridiem:function(a,b,c){var d=100*a+b;return 600>d?"凌晨":900>d?"早上":1130>d?"上午":1230>d?"中午":1800>d?"下午":"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},ordinalParse:/\d{1,2}(日|月|週)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"週";default:return a}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}}),kg);return sh.locale("en"),sh});
 
 
670
  doy:4}}),kg.defineLocale("zh-cn",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"周日_周一_周二_周三_周四_周五_周六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah点mm分",LTS:"Ah点m分s秒",L:"YYYY-MM-DD",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah点mm分",LLLL:"YYYY年MMMD日ddddAh点mm分",l:"YYYY-MM-DD",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah点mm分",llll:"YYYY年MMMD日ddddAh点mm分"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"凌晨"===b||"早上"===b||"上午"===b?a:"下午"===b||"晚上"===b?a+12:a>=11?a:a+12},meridiem:function(a,b,c){var d=100*a+b;return 600>d?"凌晨":900>d?"早上":1130>d?"上午":1230>d?"中午":1800>d?"下午":"晚上"},calendar:{sameDay:function(){return 0===this.minutes()?"[今天]Ah[点整]":"[今天]LT"},nextDay:function(){return 0===this.minutes()?"[明天]Ah[点整]":"[明天]LT"},lastDay:function(){return 0===this.minutes()?"[昨天]Ah[点整]":"[昨天]LT"},nextWeek:function(){var a,b;return a=kg().startOf("week"),b=this.diff(a,"days")>=7?"[下]":"[本]",0===this.minutes()?b+"dddAh点整":b+"dddAh点mm"},lastWeek:function(){var a,b;return a=kg().startOf("week"),b=this.unix()<a.unix()?"[上]":"[本]",0===this.minutes()?b+"dddAh点整":b+"dddAh点mm"},sameElse:"LL"},ordinalParse:/\d{1,2}(日|月|周)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"周";default:return a}},relativeTime:{future:"%s内",past:"%s前",s:"几秒",m:"1 分钟",mm:"%d 分钟",h:"1 小时",hh:"%d 小时",d:"1 天",dd:"%d 天",M:"1 个月",MM:"%d 个月",y:"1 年",yy:"%d 年"},week:{
671
  // GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
672
  dow:1,// Monday is the first day of the week.
673
+ doy:4}}),kg.defineLocale("zh-tw",{months:"一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月".split("_"),monthsShort:"1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月".split("_"),weekdays:"星期日_星期一_星期二_星期三_星期四_星期五_星期六".split("_"),weekdaysShort:"週日_週一_週二_週三_週四_週五_週六".split("_"),weekdaysMin:"日_一_二_三_四_五_六".split("_"),longDateFormat:{LT:"Ah點mm分",LTS:"Ah點m分s秒",L:"YYYY年MMMD日",LL:"YYYY年MMMD日",LLL:"YYYY年MMMD日Ah點mm分",LLLL:"YYYY年MMMD日ddddAh點mm分",l:"YYYY年MMMD日",ll:"YYYY年MMMD日",lll:"YYYY年MMMD日Ah點mm分",llll:"YYYY年MMMD日ddddAh點mm分"},meridiemParse:/凌晨|早上|上午|中午|下午|晚上/,meridiemHour:function(a,b){return 12===a&&(a=0),"凌晨"===b||"早上"===b||"上午"===b?a:"中午"===b?a>=11?a:a+12:"下午"===b||"晚上"===b?a+12:void 0},meridiem:function(a,b,c){var d=100*a+b;return 600>d?"凌晨":900>d?"早上":1130>d?"上午":1230>d?"中午":1800>d?"下午":"晚上"},calendar:{sameDay:"[今天]LT",nextDay:"[明天]LT",nextWeek:"[下]ddddLT",lastDay:"[昨天]LT",lastWeek:"[上]ddddLT",sameElse:"L"},ordinalParse:/\d{1,2}(日|月|週)/,ordinal:function(a,b){switch(b){case"d":case"D":case"DDD":return a+"日";case"M":return a+"月";case"w":case"W":return a+"週";default:return a}},relativeTime:{future:"%s內",past:"%s前",s:"幾秒",m:"1 分鐘",mm:"%d 分鐘",h:"1 小時",hh:"%d 小時",d:"1 天",dd:"%d 天",M:"1 個月",MM:"%d 個月",y:"1 年",yy:"%d 年"}}),kg);return sh.locale("en"),sh});
674
+
675
+ moment.locale(document.documentElement.lang.slice(0, 2)); // fixes https://github.com/ThemeFuse/Unyson/issues/1767
framework/views/backend-option-design-default.php CHANGED
@@ -93,6 +93,11 @@
93
  $classes['input']['responsive'] = 'fw-col-xs-12';
94
  $classes['desc']['responsive'] = 'fw-col-xs-12';
95
  }
 
 
 
 
 
96
  }
97
 
98
  /** Additional classes for input div */
93
  $classes['input']['responsive'] = 'fw-col-xs-12';
94
  $classes['desc']['responsive'] = 'fw-col-xs-12';
95
  }
96
+
97
+ $hide_bottom_border = fw_akg( 'hide-bottom-border', $option, false );
98
+ if( $hide_bottom_border ) {
99
+ $classes['option'][] = 'fw-bottom-border-hidden';
100
+ }
101
  }
102
 
103
  /** Additional classes for input div */
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson
3
  Tags: page builder, 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.3
5
  Tested up to: 4.5
6
- Stable tag: 2.5.8
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -83,6 +83,12 @@ Yes; Unyson will work with any theme.
83
 
84
  == Changelog ==
85
 
 
 
 
 
 
 
86
  = 2.5.8 =
87
  * Fixed `wp-editor` bugs
88
  * Updated FontAwesome
3
  Tags: page builder, 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.3
5
  Tested up to: 4.5
6
+ Stable tag: 2.5.9
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
83
 
84
  == Changelog ==
85
 
86
+ = 2.5.9 =
87
+ * Fixed missing function in WP < 4.5 [#1767](https://github.com/ThemeFuse/Unyson/issues/1767)
88
+ * New option-type: [icon-v2](http://manual.unyson.io/en/latest/options/built-in-option-types.html#icon-v2)
89
+ * Fixed `wp-editor` option-type bugs [#1739](https://github.com/ThemeFuse/Unyson/issues/1739)
90
+ * Process `fw-storage` parameter in all options *(Theme Settings, Customizer, Post, Term, Extension Settings)* [#1551](https://github.com/ThemeFuse/Unyson/issues/1551)
91
+
92
  = 2.5.8 =
93
  * Fixed `wp-editor` bugs
94
  * Updated FontAwesome
unyson.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Unyson
4
  * Plugin URI: http://unyson.io/
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.5.8
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+
3
  * Plugin Name: Unyson
4
  * Plugin URI: http://unyson.io/
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.5.9
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+