Unyson - Version 2.5.11

Version Description

  • New extension: WordPress Shortcodes #1807
  • Option type wp-editor fixes #1615
  • Performance improvement in fw_get_db_..._option() functions
  • Added javascript helper fw.soleConfirm #1803
Download this release

Release Info

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

Code changes from version 2.5.10 to 2.5.11

framework/core/components/backend.php CHANGED
@@ -358,6 +358,8 @@ final class _FW_Component_Backend {
358
  'save' => __( 'Save', 'fw' ),
359
  'reset' => __( 'Reset', 'fw' ),
360
  'apply' => __( 'Apply', 'fw' ),
 
 
361
  ),
362
  ) );
363
  }
358
  'save' => __( 'Save', 'fw' ),
359
  'reset' => __( 'Reset', 'fw' ),
360
  'apply' => __( 'Apply', 'fw' ),
361
+ 'cancel' => __( 'Cancel', 'fw' ),
362
+ 'ok' => __( 'Ok', 'fw' )
363
  ),
364
  ) );
365
  }
framework/core/components/extensions/manager/available-extensions.php CHANGED
@@ -6,63 +6,66 @@ $thumbnails_uri = fw_get_framework_directory_uri( '/core/components/extensions/m
6
  $github_account = 'ThemeFuse';
7
 
8
  $extensions = array(
9
- 'slider' => array(
10
  'display' => true,
11
- 'parent' => 'media',
12
- 'name' => __( 'Sliders', 'fw' ),
13
- 'description' => __( 'Adds a sliders module to your website from where you\'ll be able to create different built in jQuery sliders for your homepage and rest of the pages.', 'fw' ),
14
- 'thumbnail' => $thumbnails_uri . '/sliders.jpg',
15
  'download' => array(
16
  'github' => array(
17
- 'user_repo' => $github_account . '/Unyson-Sliders-Extension',
18
  ),
19
  ),
20
  ),
21
- 'media' => array(
22
- 'display' => false,
23
- 'parent' => null,
24
- 'name' => __( 'Media', 'fw' ),
25
- 'description' => '',
26
- 'thumbnail' => 'about:blank',
 
 
 
27
  'download' => array(
28
  'github' => array(
29
- 'user_repo' => $github_account . '/Unyson-Empty-Extension',
30
  ),
31
  ),
32
  ),
33
- 'population-method' => array(
34
- 'display' => false,
35
- 'parent' => 'media',
36
- 'name' => __( 'Population method', 'fw' ),
37
- 'description' => '',
38
- 'thumbnail' => 'about:blank',
39
  'download' => array(
40
  'github' => array(
41
- 'user_repo' => $github_account . '/Unyson-PopulationMethods-Extension',
42
  ),
43
  ),
44
  ),
45
- 'styling' => array(
46
  'display' => true,
47
  'parent' => null,
48
- 'name' => __( 'Styling', 'fw' ),
49
- 'description' => __( 'This extension lets you control the website visual style. Starting from predefined styles to changing specific fonts and colors across the website.', 'fw' ),
50
- 'thumbnail' => $thumbnails_uri . '/styling.jpg',
51
  'download' => array(
52
  'github' => array(
53
- 'user_repo' => $github_account . '/Unyson-Styling-Extension',
54
  ),
55
  ),
56
  ),
57
- 'megamenu' => array(
58
  'display' => true,
59
- 'parent' => null,
60
- 'name' => __( 'Mega Menu', 'fw' ),
61
- 'description' => __( 'The Mega Menu extension adds a user-friendly drop down menu that will let you easily create highly customized menu configurations.', 'fw' ),
62
- 'thumbnail' => $thumbnails_uri . '/mega-menu.jpg',
63
  'download' => array(
64
  'github' => array(
65
- 'user_repo' => $github_account . '/Unyson-MegaMenu-Extension',
66
  ),
67
  ),
68
  ),
@@ -78,42 +81,15 @@ $extensions = array(
78
  ),
79
  ),
80
  ),
81
- 'page-builder' => array(
82
- 'display' => true,
83
- 'parent' => 'shortcodes',
84
- 'name' => __( 'Page Builder', 'fw' ),
85
- 'description' => __( "Let's you easily build countless pages with the help of the drag and drop visual page builder that comes with a lot of already created shortcodes.", 'fw' ),
86
- 'thumbnail' => $thumbnails_uri . '/page-builder.jpg',
87
- 'download' => array(
88
- 'github' => array(
89
- 'user_repo' => $github_account . '/Unyson-PageBuilder-Extension',
90
- ),
91
- ),
92
- ),
93
- /*'wp-shortcodes' => array(
94
  'display' => true,
95
- 'parent' => 'shortcodes',
96
- 'name' => __( 'WordPress Shortcodes', 'fw' ),
97
- 'description' => __(
98
- 'Lets you insert Unyson shortcodes inside any wp-editor',
99
- 'fw'
100
- ),
101
- 'thumbnail' => $thumbnails_uri . '/page-builder.jpg',
102
- 'download' => array(
103
- 'github' => array(
104
- 'user_repo' => 'ThemeFuse/Unyson-WP-Shortcodes-Extension',
105
- ),
106
- ),
107
- ),*/
108
- 'shortcodes' => array(
109
- 'display' => false,
110
  'parent' => null,
111
- 'name' => __( 'Shortcodes', 'fw' ),
112
- 'description' => '',
113
- 'thumbnail' => 'about:blank',
114
  'download' => array(
115
  'github' => array(
116
- 'user_repo' => $github_account . '/Unyson-Shortcodes-Extension',
117
  ),
118
  ),
119
  ),
@@ -141,75 +117,63 @@ $extensions = array(
141
  ),
142
  ),
143
  ),
144
- 'sidebars' => array(
145
- 'display' => true,
146
- 'parent' => null,
147
- 'name' => __( 'Sidebars', 'fw' ),
148
- 'description' => __( 'Brings a new layer of customization freedom to your website by letting you add more than one sidebar to a page, or different sidebars on different pages.', 'fw' ),
149
- 'thumbnail' => $thumbnails_uri . '/sidebars.jpg',
150
- 'download' => array(
151
- 'github' => array(
152
- 'user_repo' => $github_account . '/Unyson-Sidebars-Extension',
153
- ),
154
- ),
155
- ),
156
- 'feedback' => array(
157
  'display' => true,
158
  'parent' => null,
159
- 'name' => __( 'Feedback', 'fw' ),
160
- 'description' => __( 'Adds the possibility to leave feedback (comments, reviews and rating) about your products, articles, etc. This replaces the default comments system.', 'fw' ),
161
- 'thumbnail' => $thumbnails_uri . '/feedback.jpg',
162
  'download' => array(
163
  'github' => array(
164
- 'user_repo' => $github_account . '/Unyson-Feedback-Extension',
165
  ),
166
  ),
167
  ),
168
- 'backup' => array(
169
  'display' => true,
170
  'parent' => null,
171
- 'name' => __( 'Backup', 'fw' ),
172
- 'description' => __( 'This extension lets you set up daily, weekly or monthly backup schedule. You can choose between a full backup or a data base only backup.', 'fw' ),
173
- 'thumbnail' => $thumbnails_uri . '/backup.jpg',
174
  'download' => array(
175
  'github' => array(
176
- 'user_repo' => $github_account . '/Unyson-Backup-Extension',
177
  ),
178
  ),
179
  ),
180
- 'backups' => array(
181
  'display' => true,
182
  'parent' => null,
183
- 'name' => __( 'Backup & Demo Content', 'fw' ),
184
- 'description' => __( 'This extension lets you create an automated backup schedule, import demo content or even create a demo content archive for migration purposes.', 'fw' ),
185
- 'thumbnail' => $thumbnails_uri . '/backups.jpg',
186
  'download' => array(
187
  'github' => array(
188
- 'user_repo' => $github_account . '/Unyson-Backups-Extension',
189
  ),
190
  ),
191
  ),
192
- 'events' => array(
193
  'display' => true,
194
  'parent' => null,
195
- 'name' => __( 'Events', 'fw' ),
196
- 'description' => __( 'This extension adds a fully fledged Events module to your theme. It comes with built in pages that contain a calendar where events can be added.', 'fw' ),
197
- 'thumbnail' => $thumbnails_uri . '/events.jpg',
198
  'download' => array(
199
  'github' => array(
200
- 'user_repo' => $github_account . '/Unyson-Events-Extension',
201
  ),
202
  ),
203
  ),
204
- 'analytics' => array(
205
- 'display' => true,
206
  'parent' => null,
207
- 'name' => __( 'Analytics', 'fw' ),
208
- 'description' => __( 'Enables the possibility to add the Google Analytics tracking code that will let you get all the analytics about visitors, page views and more.', 'fw' ),
209
- 'thumbnail' => $thumbnails_uri . '/analytics.jpg',
210
  'download' => array(
211
  'github' => array(
212
- 'user_repo' => $github_account . '/Unyson-Analytics-Extension',
213
  ),
214
  ),
215
  ),
@@ -225,18 +189,6 @@ $extensions = array(
225
  ),
226
  ),
227
  ),
228
- 'learning' => array(
229
- 'display' => true,
230
- 'parent' => null,
231
- 'name' => __( 'Learning', 'fw' ),
232
- 'description' => __( 'This extension adds a Learning module to your theme. Using this extension you can add courses, lessons and tests for your users to take.', 'fw' ),
233
- 'thumbnail' => $thumbnails_uri . '/learning.jpg',
234
- 'download' => array(
235
- 'github' => array(
236
- 'user_repo' => $github_account . '/Unyson-Learning-Extension',
237
- ),
238
- ),
239
- ),
240
  'forms' => array(
241
  'display' => false,
242
  'parent' => null,
@@ -273,6 +225,54 @@ $extensions = array(
273
  ),
274
  ),
275
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  'translation' => array(
277
  'display' => true,
278
  'parent' => null,
6
  $github_account = 'ThemeFuse';
7
 
8
  $extensions = array(
9
+ 'page-builder' => array(
10
  'display' => true,
11
+ 'parent' => 'shortcodes',
12
+ 'name' => __( 'Page Builder', 'fw' ),
13
+ 'description' => __( "Let's you easily build countless pages with the help of the drag and drop visual page builder that comes with a lot of already created shortcodes.", 'fw' ),
14
+ 'thumbnail' => $thumbnails_uri . '/page-builder.jpg',
15
  'download' => array(
16
  'github' => array(
17
+ 'user_repo' => $github_account . '/Unyson-PageBuilder-Extension',
18
  ),
19
  ),
20
  ),
21
+ 'wp-shortcodes' => array(
22
+ 'display' => true,
23
+ 'parent' => 'shortcodes',
24
+ 'name' => __( 'WordPress Shortcodes', 'fw' ),
25
+ 'description' => __(
26
+ 'Lets you insert Unyson shortcodes inside any wp-editor',
27
+ 'fw'
28
+ ),
29
+ 'thumbnail' => $thumbnails_uri . '/wp-shortcodes.jpg',
30
  'download' => array(
31
  'github' => array(
32
+ 'user_repo' => 'ThemeFuse/Unyson-WP-Shortcodes-Extension',
33
  ),
34
  ),
35
  ),
36
+ 'backups' => array(
37
+ 'display' => true,
38
+ 'parent' => null,
39
+ 'name' => __( 'Backup & Demo Content', 'fw' ),
40
+ 'description' => __( 'This extension lets you create an automated backup schedule, import demo content or even create a demo content archive for migration purposes.', 'fw' ),
41
+ 'thumbnail' => $thumbnails_uri . '/backups.jpg',
42
  'download' => array(
43
  'github' => array(
44
+ 'user_repo' => $github_account . '/Unyson-Backups-Extension',
45
  ),
46
  ),
47
  ),
48
+ 'sidebars' => array(
49
  'display' => true,
50
  'parent' => null,
51
+ 'name' => __( 'Sidebars', 'fw' ),
52
+ 'description' => __( 'Brings a new layer of customization freedom to your website by letting you add more than one sidebar to a page, or different sidebars on different pages.', 'fw' ),
53
+ 'thumbnail' => $thumbnails_uri . '/sidebars.jpg',
54
  'download' => array(
55
  'github' => array(
56
+ 'user_repo' => $github_account . '/Unyson-Sidebars-Extension',
57
  ),
58
  ),
59
  ),
60
+ 'slider' => array(
61
  'display' => true,
62
+ 'parent' => 'media',
63
+ 'name' => __( 'Sliders', 'fw' ),
64
+ 'description' => __( 'Adds a sliders module to your website from where you\'ll be able to create different built in jQuery sliders for your homepage and rest of the pages.', 'fw' ),
65
+ 'thumbnail' => $thumbnails_uri . '/sliders.jpg',
66
  'download' => array(
67
  'github' => array(
68
+ 'user_repo' => $github_account . '/Unyson-Sliders-Extension',
69
  ),
70
  ),
71
  ),
81
  ),
82
  ),
83
  ),
84
+ 'megamenu' => array(
 
 
 
 
 
 
 
 
 
 
 
 
85
  'display' => true,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  'parent' => null,
87
+ 'name' => __( 'Mega Menu', 'fw' ),
88
+ 'description' => __( 'The Mega Menu extension adds a user-friendly drop down menu that will let you easily create highly customized menu configurations.', 'fw' ),
89
+ 'thumbnail' => $thumbnails_uri . '/mega-menu.jpg',
90
  'download' => array(
91
  'github' => array(
92
+ 'user_repo' => $github_account . '/Unyson-MegaMenu-Extension',
93
  ),
94
  ),
95
  ),
117
  ),
118
  ),
119
  ),
120
+ 'events' => array(
 
 
 
 
 
 
 
 
 
 
 
 
121
  'display' => true,
122
  'parent' => null,
123
+ 'name' => __( 'Events', 'fw' ),
124
+ 'description' => __( 'This extension adds a fully fledged Events module to your theme. It comes with built in pages that contain a calendar where events can be added.', 'fw' ),
125
+ 'thumbnail' => $thumbnails_uri . '/events.jpg',
126
  'download' => array(
127
  'github' => array(
128
+ 'user_repo' => $github_account . '/Unyson-Events-Extension',
129
  ),
130
  ),
131
  ),
132
+ 'analytics' => array(
133
  'display' => true,
134
  'parent' => null,
135
+ 'name' => __( 'Analytics', 'fw' ),
136
+ 'description' => __( 'Enables the possibility to add the Google Analytics tracking code that will let you get all the analytics about visitors, page views and more.', 'fw' ),
137
+ 'thumbnail' => $thumbnails_uri . '/analytics.jpg',
138
  'download' => array(
139
  'github' => array(
140
+ 'user_repo' => $github_account . '/Unyson-Analytics-Extension',
141
  ),
142
  ),
143
  ),
144
+ 'feedback' => array(
145
  'display' => true,
146
  'parent' => null,
147
+ 'name' => __( 'Feedback', 'fw' ),
148
+ 'description' => __( 'Adds the possibility to leave feedback (comments, reviews and rating) about your products, articles, etc. This replaces the default comments system.', 'fw' ),
149
+ 'thumbnail' => $thumbnails_uri . '/feedback.jpg',
150
  'download' => array(
151
  'github' => array(
152
+ 'user_repo' => $github_account . '/Unyson-Feedback-Extension',
153
  ),
154
  ),
155
  ),
156
+ 'learning' => array(
157
  'display' => true,
158
  'parent' => null,
159
+ 'name' => __( 'Learning', 'fw' ),
160
+ 'description' => __( 'This extension adds a Learning module to your theme. Using this extension you can add courses, lessons and tests for your users to take.', 'fw' ),
161
+ 'thumbnail' => $thumbnails_uri . '/learning.jpg',
162
  'download' => array(
163
  'github' => array(
164
+ 'user_repo' => $github_account . '/Unyson-Learning-Extension',
165
  ),
166
  ),
167
  ),
168
+ 'shortcodes' => array(
169
+ 'display' => false,
170
  'parent' => null,
171
+ 'name' => __( 'Shortcodes', 'fw' ),
172
+ 'description' => '',
173
+ 'thumbnail' => 'about:blank',
174
  'download' => array(
175
  'github' => array(
176
+ 'user_repo' => $github_account . '/Unyson-Shortcodes-Extension',
177
  ),
178
  ),
179
  ),
189
  ),
190
  ),
191
  ),
 
 
 
 
 
 
 
 
 
 
 
 
192
  'forms' => array(
193
  'display' => false,
194
  'parent' => null,
225
  ),
226
  ),
227
  ),
228
+ 'backup' => array(
229
+ 'display' => true,
230
+ 'parent' => null,
231
+ 'name' => __( 'Backup', 'fw' ),
232
+ 'description' => __( 'This extension lets you set up daily, weekly or monthly backup schedule. You can choose between a full backup or a data base only backup.', 'fw' ),
233
+ 'thumbnail' => $thumbnails_uri . '/backup.jpg',
234
+ 'download' => array(
235
+ 'github' => array(
236
+ 'user_repo' => $github_account . '/Unyson-Backup-Extension',
237
+ ),
238
+ ),
239
+ ),
240
+ 'media' => array(
241
+ 'display' => false,
242
+ 'parent' => null,
243
+ 'name' => __( 'Media', 'fw' ),
244
+ 'description' => '',
245
+ 'thumbnail' => 'about:blank',
246
+ 'download' => array(
247
+ 'github' => array(
248
+ 'user_repo' => $github_account . '/Unyson-Empty-Extension',
249
+ ),
250
+ ),
251
+ ),
252
+ 'population-method' => array(
253
+ 'display' => false,
254
+ 'parent' => 'media',
255
+ 'name' => __( 'Population method', 'fw' ),
256
+ 'description' => '',
257
+ 'thumbnail' => 'about:blank',
258
+ 'download' => array(
259
+ 'github' => array(
260
+ 'user_repo' => $github_account . '/Unyson-PopulationMethods-Extension',
261
+ ),
262
+ ),
263
+ ),
264
+ 'styling' => array(
265
+ 'display' => true,
266
+ 'parent' => null,
267
+ 'name' => __( 'Styling', 'fw' ),
268
+ 'description' => __( 'This extension lets you control the website visual style. Starting from predefined styles to changing specific fonts and colors across the website.', 'fw' ),
269
+ 'thumbnail' => $thumbnails_uri . '/styling.jpg',
270
+ 'download' => array(
271
+ 'github' => array(
272
+ 'user_repo' => $github_account . '/Unyson-Styling-Extension',
273
+ ),
274
+ ),
275
+ ),
276
  'translation' => array(
277
  'display' => true,
278
  'parent' => null,
framework/core/components/extensions/manager/static/img/thumbnails/wp-shortcodes.jpg ADDED
Binary file
framework/core/components/extensions/manager/views/extensions-page.php CHANGED
@@ -8,6 +8,30 @@
8
  * @var bool $can_install
9
  */
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  $dir = dirname(__FILE__);
12
  $extension_view_path = $dir .'/extension.php';
13
 
8
  * @var bool $can_install
9
  */
10
 
11
+ // Set extensions order same as in available extensions list
12
+ {
13
+ $ordered = array(
14
+ 'active' => array(),
15
+ 'installed' => array(),
16
+ );
17
+
18
+ foreach ($lists['available'] as $name => &$_ext) {
19
+ foreach ($ordered as $type => &$_exts) {
20
+ if (isset($lists[$type][$name])) {
21
+ $ordered[$type][$name] = $lists[$type][$name];
22
+ }
23
+ }
24
+ }
25
+
26
+ foreach ($ordered as $type => &$_exts) {
27
+ if (!empty($ordered[$type])) {
28
+ $lists[$type] = array_merge($ordered[$type], $lists[$type]);
29
+ }
30
+ }
31
+
32
+ unset($ordered, $name, $_ext, $_exts, $type);
33
+ }
34
+
35
  $dir = dirname(__FILE__);
36
  $extension_view_path = $dir .'/extension.php';
37
 
framework/helpers/class-fw-db-options-model.php CHANGED
@@ -62,11 +62,6 @@ abstract class FW_Db_Options_Model {
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
  */
@@ -80,7 +75,7 @@ abstract class FW_Db_Options_Model {
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);
@@ -120,13 +115,15 @@ abstract class FW_Db_Options_Model {
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
  /**
@@ -159,38 +156,25 @@ abstract class FW_Db_Options_Model {
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)) {
@@ -206,7 +190,7 @@ abstract class FW_Db_Options_Model {
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) {
62
  return empty($item_id) ? null : $item_id;
63
  }
64
 
 
 
 
 
 
65
  /**
66
  * @var array {'id': mixed}
67
  */
75
  final public static function _get_instance($id) {
76
  return self::$instances[$id];
77
  }
78
+
79
  final public function __construct() {
80
  if (isset(self::$instances[ $this->get_id() ])) {
81
  trigger_error(__CLASS__ .' with id "'. $this->get_id() .'" was already defined', E_USER_ERROR);
115
  * Cached because values are merged with extracted default values
116
  */
117
  $values = FW_Cache::get($cache_key_values = $this->get_cache_key('values', $item_id, $extra_data));
118
+
119
+ $values_loaded = false;
120
  } catch (FW_Cache_Not_Found_Exception $e) {
121
  FW_Cache::set(
122
  $cache_key_values,
123
  $values = is_array($values = $this->get_values($item_id, $extra_data)) ? $values : array()
124
  );
125
 
126
+ $values_loaded = true;
127
  }
128
 
129
  /**
156
  FW_Cache::set($cache_key, $options = fw_extract_only_options($this->get_options($item_id, $extra_data)));
157
  }
158
 
159
+ if ($values_loaded && $options) {
160
+ /**
161
+ * Complete missing db values with default values from options array
162
+ */
163
+ $values = array_merge(
164
+ fw_get_options_values_from_input($options, array()),
165
+ $values
 
 
 
 
166
  );
 
167
 
 
168
  foreach ($options as $id => $option) {
169
+ $values[$id] = fw()->backend->option_type($option['type'])->storage_load(
170
  $id,
171
+ $option,
172
  isset($values[$id]) ? $values[$id] : null,
173
  $this->get_fw_storage_params($item_id, $extra_data)
174
  );
175
  }
176
+
177
+ FW_Cache::set($cache_key_values, $values);
 
 
 
 
 
 
 
178
  }
179
 
180
  if (empty($option_id)) {
190
 
191
  final public function set( $item_id = null, $option_id = null, $value, array $extra_data = array() ) {
192
  FW_Cache::del($cache_key_values = $this->get_cache_key('values', $item_id, $extra_data));
193
+
194
  try {
195
  $options = FW_Cache::get($cache_key = $this->get_cache_key('options', $item_id, $extra_data));
196
  } catch (FW_Cache_Not_Found_Exception $e) {
framework/helpers/database.php CHANGED
@@ -151,7 +151,7 @@ class FW_Db_Options_Model_Post extends FW_Db_Options_Model {
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
 
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 $this->get_post_id($item_id);
155
  }
156
  }
157
 
framework/includes/option-types/simple.php CHANGED
@@ -1026,6 +1026,7 @@ FW_Option_Type::register( 'FW_Option_Type_Select_Multiple' );
1026
  class FW_Option_Type_Unique extends FW_Option_Type
1027
  {
1028
  private static $ids = array();
 
1029
 
1030
  public function get_type()
1031
  {
@@ -1092,6 +1093,10 @@ class FW_Option_Type_Unique extends FW_Option_Type
1092
  self::$ids[$original_id] = array();
1093
  }
1094
 
 
 
 
 
1095
  protected function _get_value_from_input($option, $input_value) {
1096
  if (is_null($input_value)) {
1097
  $id = empty($option['value']) ? $this->generate_id($option['length']) : $option['value'];
@@ -1105,8 +1110,14 @@ class FW_Option_Type_Unique extends FW_Option_Type
1105
 
1106
  /**
1107
  * Regenerate if found the same id again
 
 
 
 
 
 
1108
  */
1109
- {
1110
  global $post;
1111
 
1112
  if ($post) {
@@ -1225,4 +1236,4 @@ class FW_Option_Type_GMap_Key extends FW_Option_Type_Text {
1225
  }
1226
  }
1227
 
1228
- FW_Option_Type::register( 'FW_Option_Type_GMap_Key' );
1026
  class FW_Option_Type_Unique extends FW_Option_Type
1027
  {
1028
  private static $ids = array();
1029
+ private static $should_do_regeneration = true;
1030
 
1031
  public function get_type()
1032
  {
1093
  self::$ids[$original_id] = array();
1094
  }
1095
 
1096
+ public function set_should_do_regeneration($new) {
1097
+ self::$should_do_regeneration = $new;
1098
+ }
1099
+
1100
  protected function _get_value_from_input($option, $input_value) {
1101
  if (is_null($input_value)) {
1102
  $id = empty($option['value']) ? $this->generate_id($option['length']) : $option['value'];
1110
 
1111
  /**
1112
  * Regenerate if found the same id again
1113
+ *
1114
+ * Sometimes you don't need to to regeneration of ids.
1115
+ * You can use set_should_do_regeneration() method in order to skip
1116
+ * this step. You really should use this hook only if you know what
1117
+ * you're doing. You can really break some things around without
1118
+ * proper care.
1119
  */
1120
+ if (self::$should_do_regeneration) {
1121
  global $post;
1122
 
1123
  if ($post) {
1236
  }
1237
  }
1238
 
1239
+ FW_Option_Type::register( 'FW_Option_Type_GMap_Key' );
framework/includes/option-types/wp-editor/static/scripts.js CHANGED
@@ -3,7 +3,12 @@
3
  var init = function () {
4
  var $option = $(this),
5
  $textarea = $option.find('.wp-editor-area:first'),
6
- id = $option.attr('data-fw-editor-id');
 
 
 
 
 
7
 
8
  /**
9
  * Dynamically set tinyMCEPreInit.mceInit and tinyMCEPreInit.qtInit
@@ -26,7 +31,7 @@
26
  * TinyMCE Editor
27
  * http://stackoverflow.com/a/21519323/1794248
28
  */
29
- {
30
  if (typeof tinyMCEPreInit.mceInit[ id ] == 'undefined') {
31
  console.error('Can\'t find "'+ id +'" in tinyMCEPreInit.mceInit');
32
  return;
@@ -37,11 +42,7 @@
37
  tinyMCEPreInit.mceInit[ id ].setup = function(ed) {
38
  ed.once('init', function (e) {
39
  var editor = e.target,
40
- id = editor.id,
41
- $wrap = $textarea.closest('.wp-editor-wrap'),
42
- visualMode = (typeof $option.attr('data-mode') != 'undefined')
43
- ? ($option.attr('data-mode') == 'tinymce')
44
- : $wrap.hasClass('tmce-active');
45
 
46
  editor.on('change', function(){ editor.save(); });
47
 
@@ -79,8 +80,7 @@
79
 
80
  $wrap.find('.switch-'+ (visualMode ? 'tmce' : 'html')).trigger('click');
81
 
82
-
83
- if (!editor.getParam('wpautop') && !visualMode) {
84
  $textarea.val(wp.editor.removep(editor.getContent()));
85
  }
86
  }
@@ -97,6 +97,29 @@
97
  console.error('wp-editor init error', id, e);
98
  return;
99
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
  }
101
  };
102
 
3
  var init = function () {
4
  var $option = $(this),
5
  $textarea = $option.find('.wp-editor-area:first'),
6
+ id = $option.attr('data-fw-editor-id'),
7
+ $wrap = $textarea.closest('.wp-editor-wrap'),
8
+ visualMode = (typeof $option.attr('data-mode') != 'undefined')
9
+ ? ($option.attr('data-mode') == 'tinymce')
10
+ : $wrap.hasClass('tmce-active'),
11
+ hasAutoP = $option.attr('data-fw-has-autop') === 'true';
12
 
13
  /**
14
  * Dynamically set tinyMCEPreInit.mceInit and tinyMCEPreInit.qtInit
31
  * TinyMCE Editor
32
  * http://stackoverflow.com/a/21519323/1794248
33
  */
34
+ if (mceSettings) {
35
  if (typeof tinyMCEPreInit.mceInit[ id ] == 'undefined') {
36
  console.error('Can\'t find "'+ id +'" in tinyMCEPreInit.mceInit');
37
  return;
42
  tinyMCEPreInit.mceInit[ id ].setup = function(ed) {
43
  ed.once('init', function (e) {
44
  var editor = e.target,
45
+ id = editor.id;
 
 
 
 
46
 
47
  editor.on('change', function(){ editor.save(); });
48
 
80
 
81
  $wrap.find('.switch-'+ (visualMode ? 'tmce' : 'html')).trigger('click');
82
 
83
+ if (!hasAutoP && !visualMode) {
 
84
  $textarea.val(wp.editor.removep(editor.getContent()));
85
  }
86
  }
97
  console.error('wp-editor init error', id, e);
98
  return;
99
  }
100
+
101
+ // fixes https://github.com/ThemeFuse/Unyson/issues/1615
102
+ if (typeof window.wpLink != 'undefined') {
103
+ window.wpLink.open(id);
104
+ window.wpLink.close();
105
+
106
+ /**
107
+ * hide link edit toolbar on wp-editor destroy (on options modal close)
108
+ */
109
+ $option.one('remove', function(){
110
+ window.wpLink.close();
111
+ });
112
+ }
113
+ } else {
114
+ /**
115
+ * Quick Tags
116
+ * http://stackoverflow.com/a/21519323/1794248
117
+ */
118
+ {
119
+ new QTags( tinyMCEPreInit.qtInit[ id ] );
120
+
121
+ QTags._buttonsInit();
122
+ }
123
  }
124
  };
125
 
framework/manifest.php CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
- $manifest['version'] = '2.5.10';
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
+ $manifest['version'] = '2.5.11';
framework/static/css/fw.css CHANGED
@@ -3031,6 +3031,33 @@ body.wp-customizer > div:not(.fw-modal) > .media-modal-backdrop {
3031
  max-height: 800px;
3032
  }
3033
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3034
  /* end: sizes */
3035
 
3036
  /* tabs fixes */
3031
  max-height: 800px;
3032
  }
3033
 
3034
+ .fw-sole-modal.fw-sole-confirm-modal {
3035
+ text-align: center;
3036
+ }
3037
+
3038
+ .fw-sole-modal.fw-sole-confirm-modal .fw-sole-confirm-button:not(:last-child) {
3039
+ margin-right: 10px;
3040
+ }
3041
+
3042
+ .fw-sole-modal.fw-sole-confirm-modal .fw-sole-confirm-button {
3043
+ min-width: 65px;
3044
+ }
3045
+
3046
+ .fw-sole-modal.fw-sole-confirm-modal span.dashicons {
3047
+ font-size: 60px;
3048
+ width: 60px;
3049
+ height: 60px;
3050
+ margin-top: 10px;
3051
+ }
3052
+
3053
+ .fw-sole-modal.fw-sole-confirm-modal.fw-sole-confirm-warning span.dashicons {
3054
+ color: #e04139;
3055
+ }
3056
+
3057
+ .fw-sole-modal.fw-sole-confirm-modal.fw-sole-confirm-info span.dashicons {
3058
+ color: #5dab20;
3059
+ }
3060
+
3061
  /* end: sizes */
3062
 
3063
  /* tabs fixes */
framework/static/js/fw.js CHANGED
@@ -1945,7 +1945,7 @@ fw.soleModal = (function(){
1945
 
1946
  this.setSize(this.current.width, this.current.height);
1947
 
1948
- this.current.afterOpenStart();
1949
  this.currentMethodTimeoutId = setTimeout(_.bind(function() {
1950
  this.current.afterOpen();
1951
 
@@ -2005,7 +2005,7 @@ fw.soleModal = (function(){
2005
 
2006
  if (this.queue.length && !this.queue[0].hidePrevious) {
2007
  // replace content
2008
- this.current.afterCloseStart();
2009
  this.$getContent().fadeOut('fast', _.bind(function(){
2010
  this.current.afterClose();
2011
 
@@ -2028,7 +2028,7 @@ fw.soleModal = (function(){
2028
 
2029
  this.$modal.addClass('fw-modal-closing');
2030
 
2031
- this.current.afterCloseStart();
2032
  this.currentMethodTimeoutId = setTimeout(_.bind(function(){
2033
  this.current.afterClose();
2034
 
@@ -2121,3 +2121,158 @@ fw.soleModal = (function(){
2121
  }
2122
  };
2123
  })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1945
 
1946
  this.setSize(this.current.width, this.current.height);
1947
 
1948
+ this.current.afterOpenStart(this.$modal);
1949
  this.currentMethodTimeoutId = setTimeout(_.bind(function() {
1950
  this.current.afterOpen();
1951
 
2005
 
2006
  if (this.queue.length && !this.queue[0].hidePrevious) {
2007
  // replace content
2008
+ this.current.afterCloseStart(this.$modal);
2009
  this.$getContent().fadeOut('fast', _.bind(function(){
2010
  this.current.afterClose();
2011
 
2028
 
2029
  this.$modal.addClass('fw-modal-closing');
2030
 
2031
+ this.current.afterCloseStart(this.$modal);
2032
  this.currentMethodTimeoutId = setTimeout(_.bind(function(){
2033
  this.current.afterClose();
2034
 
2121
  }
2122
  };
2123
  })();
2124
+
2125
+ /**
2126
+ * Simple mechanism of getting confirmations from the user.
2127
+ *
2128
+ * Usage:
2129
+ *
2130
+ * var confirm = fw.soleConfirm.create();
2131
+ * confirm.result.then(function (confirm_object) {
2132
+ * // SUCCESS!!
2133
+ * });
2134
+ *
2135
+ * confirm.result.fail(function (confirm_object) {
2136
+ * // FAIL!!
2137
+ * });
2138
+ *
2139
+ * confirm.show();
2140
+ *
2141
+ * Note: confirm.result is a full-featured jQuery.Deferred object, you can also
2142
+ * use methods like always, done, jQuery.when with it.
2143
+ *
2144
+ * Warning:
2145
+ * You confirm object will be garbage collected after the user will pick an
2146
+ * option, that is, it will become null. You should create one more confirm
2147
+ * afterwards, if you need it.
2148
+ *
2149
+ * TODO:
2150
+ * 1. Maybe pass unknown options to fw.soleModal itself.
2151
+ */
2152
+ fw.soleConfirm = (function ($) {
2153
+ var hashMap = {};
2154
+
2155
+ function create (opts) {
2156
+ var confirm = new Confirm(opts);
2157
+ hashMap[confirm.id] = confirm;
2158
+ return hashMap[confirm.id];
2159
+ }
2160
+
2161
+ function Confirm (opts) {
2162
+ this.result = jQuery.Deferred();
2163
+ this.id = fw.randomMD5();
2164
+
2165
+ this.opts = _.extend({
2166
+ severity: 'info', // warning | info
2167
+ message: null,
2168
+ backdrop: null
2169
+ }, opts);
2170
+ }
2171
+
2172
+ Confirm.prototype.destroy = function () {
2173
+ hashMap[this.id] = null;
2174
+ delete hashMap[this.id];
2175
+ }
2176
+
2177
+ /**
2178
+ * Attached listeners on this.result will be lost after this operation.
2179
+ * You'll have to add them once again.
2180
+ */
2181
+ Confirm.prototype.reset = function () {
2182
+ if (hashMap[this.id]) {
2183
+ throw "You can't reset till your promise is not resolved! Do a .destroy() if you don't need Confirm anymore!";
2184
+ }
2185
+
2186
+ if (this.result.isRejected() || this.result.isResolved()) {
2187
+ this.result = jQuery.Deferred();
2188
+ }
2189
+
2190
+ hashMap[this.id] = this;
2191
+ };
2192
+
2193
+ Confirm.prototype.show = function () {
2194
+ this._checkIsSet();
2195
+
2196
+ fw.soleModal.show(this.id, this._getHtml(), {
2197
+ wrapWithTable: false,
2198
+ showCloseButton: false,
2199
+ allowClose: false, // a confirm window can't be closed on click of it's backdrop
2200
+ backdrop: this.opts.backdrop,
2201
+ customClass: 'fw-sole-confirm-modal fw-sole-confirm-' + this.opts.severity,
2202
+ updateIfCurrent: true,
2203
+
2204
+ afterOpenStart: _.bind(this._fireEvents, this),
2205
+ afterCloseStart: _.bind(this._teardownEvents, this)
2206
+ });
2207
+ };
2208
+
2209
+ Confirm.prototype.hide = function (reason) {
2210
+ this._checkIsSet();
2211
+
2212
+ fw.soleModal.hide(this.id);
2213
+ };
2214
+
2215
+ //////////////////
2216
+
2217
+ Confirm.prototype._fireEvents = function ($modal) {
2218
+ $modal.find('.fw-sole-confirm-button')
2219
+ .on('click.fw-sole-confirm', _.bind(this._handleClose, this));
2220
+ };
2221
+
2222
+ Confirm.prototype._teardownEvents = function ($modal) {
2223
+ $modal.find('.fw-sole-confirm-button').off('click.fw-sole-confirm');
2224
+ };
2225
+
2226
+ Confirm.prototype._checkIsSet = function () {
2227
+ if (! hashMap[this.id]) {
2228
+ throw "You can't do operations on fullfilled Confirm! Do a .reset() first.";
2229
+ }
2230
+ };
2231
+
2232
+ Confirm.prototype._handleClose = function (event) {
2233
+ var action = $(event.target).attr('data-fw-sole-confirm-action');
2234
+ var id = $(event.target).attr('data-fw-sole-confirm-id');
2235
+ var confirm = hashMap[id];
2236
+
2237
+ if (confirm) {
2238
+ _.contains(['reject', 'resolve'], action) &&
2239
+ confirm.result[action](this) &&
2240
+ confirm.hide();
2241
+
2242
+ confirm.destroy();
2243
+ confirm = null;
2244
+ }
2245
+ };
2246
+
2247
+ Confirm.prototype._getHtml = function () {
2248
+ var iconClass = 'dashicons-' + this.opts.severity;
2249
+ var icon = '<span class="dashicons ' + iconClass + '"></span>';
2250
+ var heading = '<h1>' + fw.capitalizeFirstLetter(this.opts.severity) + '</h1>';
2251
+ var message = this.opts.message ? '<p>' + this.opts.message + '</p>' : '';
2252
+
2253
+ var cancelButton = $('<button>', {
2254
+ html: _fw_localized.l10n.cancel
2255
+ }).attr({
2256
+ 'data-fw-sole-confirm-action': 'reject',
2257
+ 'data-fw-sole-confirm-id': this.id,
2258
+ type: 'button',
2259
+ }).addClass('fw-sole-confirm-button button');
2260
+
2261
+ var okButton = $('<button>', {
2262
+ html: _fw_localized.l10n.ok
2263
+ }).attr({
2264
+ 'data-fw-sole-confirm-action': 'resolve',
2265
+ 'data-fw-sole-confirm-id': this.id,
2266
+ type: 'button',
2267
+ }).addClass('fw-sole-confirm-button button button-primary');
2268
+
2269
+ return icon + heading + message + selfHtml(cancelButton) + selfHtml(okButton);
2270
+
2271
+ function selfHtml (el) { return $('<div>').append(el).html(); }
2272
+ };
2273
+
2274
+ return {
2275
+ create: create
2276
+ };
2277
+ })(jQuery);
2278
+
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.10
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.10 =
87
  * Fixed `fw_get_db_customizer_option()` bug [#1796](https://github.com/ThemeFuse/Unyson/issues/1796)
88
 
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.11
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.11 =
87
+ * New extension: WordPress Shortcodes [#1807](https://github.com/ThemeFuse/Unyson/issues/1807)
88
+ * Option type `wp-editor` fixes [#1615](https://github.com/ThemeFuse/Unyson/issues/1615)
89
+ * Performance improvement in `fw_get_db_..._option()` functions
90
+ * Added javascript helper `fw.soleConfirm` [#1803](https://github.com/ThemeFuse/Unyson/pull/1803)
91
+
92
  = 2.5.10 =
93
  * Fixed `fw_get_db_customizer_option()` bug [#1796](https://github.com/ThemeFuse/Unyson/issues/1796)
94
 
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.10
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.11
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+