Unyson - Version 2.1.9

Version Description

  • Fixed: Extension is not installing if directory already exists but is empty.
Download this release

Release Info

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

Code changes from version 2.1.8 to 2.1.9

framework/core/components/extensions.php CHANGED
@@ -19,7 +19,15 @@ final class _FW_Component_Extensions
19
 
20
  /**
21
  * Active extensions
22
- * Only this extensions should be available for other, inactive extensions =
 
 
 
 
 
 
 
 
23
  * @var FW_Extension[] { 'extension_name' => instance }
24
  */
25
  private static $active_extensions = array();
19
 
20
  /**
21
  * Active extensions
22
+ *
23
+ * On every extension activation, it will be pushed at the end of this array.
24
+ * The extensions order is important when including files.
25
+ * If extension A requires extension B, extension B is activated before extension A,
26
+ * and all files of the extension B (hooks.php, static.php, etc.) must be included before extension A
27
+ * For e.g. extension A may have in static.php:
28
+ * wp_enqueue_script( 'ext-A-script', 'script.js', array( 'ext-B-script' ) );
29
+ * so 'ext-B-script' must be registered before 'ext-A-script'
30
+ *
31
  * @var FW_Extension[] { 'extension_name' => instance }
32
  */
33
  private static $active_extensions = array();
framework/core/components/extensions/manager/class--fw-extensions-manager.php CHANGED
@@ -1234,6 +1234,10 @@ final class _FW_Extensions_Manager
1234
  'link_extension' => $link .'&sub-page=extension',
1235
  'extension_title' => $extension_title,
1236
  'tab' => $tab,
 
 
 
 
1237
  ), false);
1238
 
1239
  unset($installed_extensions);
@@ -1556,6 +1560,8 @@ final class _FW_Extensions_Manager
1556
  */
1557
  $extension = $data['data']['extension'];
1558
 
 
 
1559
  echo fw_html_tag('input', array(
1560
  'type' => 'hidden',
1561
  'name' => 'fw_extension_name',
@@ -1641,7 +1647,7 @@ final class _FW_Extensions_Manager
1641
 
1642
  $data['redirect'] = fw_current_url();
1643
 
1644
- do_action('fw_extension_settings_form_saved', $extension->get_name(), $options_before_save);
1645
 
1646
  return $data;
1647
  }
@@ -1895,26 +1901,24 @@ final class _FW_Extensions_Manager
1895
  );
1896
  }
1897
 
1898
- if (empty($destination_files)) {
1899
- // directory is empty, nothing to remove
1900
- return;
1901
- }
 
 
 
1902
 
1903
- foreach ($destination_files as $file) {
1904
- if ($file['name'] === 'extensions' && $file['type'] === 'd') {
1905
- // do not touch the extensions/ directory
1906
- continue;
 
 
1907
  }
1908
 
1909
- if (!$wp_filesystem->delete($destination_wp_fs_dir .'/'. $file['name'], true, $file['type'])) {
1910
- return new WP_Error(
1911
- $wp_error_id,
1912
- sprintf(__('Cannot delete "%s".', 'fw'), $destination_wp_fs_dir .'/'. $file['name'])
1913
- );
1914
- }
1915
  }
1916
-
1917
- unset($destination_files);
1918
  } else {
1919
  if (!FW_WP_Filesystem::mkdir_recursive($destination_wp_fs_dir)) {
1920
  return new WP_Error(
1234
  'link_extension' => $link .'&sub-page=extension',
1235
  'extension_title' => $extension_title,
1236
  'tab' => $tab,
1237
+ 'is_supported' =>
1238
+ fw()->theme->manifest->get('supported_extensions/'. $extension_name, false) !== false
1239
+ ||
1240
+ $installed_extensions[$extension_name]['source'] !== 'framework'
1241
  ), false);
1242
 
1243
  unset($installed_extensions);
1560
  */
1561
  $extension = $data['data']['extension'];
1562
 
1563
+ do_action('fw_extension_settings_form_render:'. $extension->get_name());
1564
+
1565
  echo fw_html_tag('input', array(
1566
  'type' => 'hidden',
1567
  'name' => 'fw_extension_name',
1647
 
1648
  $data['redirect'] = fw_current_url();
1649
 
1650
+ do_action('fw_extension_settings_form_saved:'. $extension->get_name(), $options_before_save);
1651
 
1652
  return $data;
1653
  }
1901
  );
1902
  }
1903
 
1904
+ if (!empty($destination_files)) {
1905
+ // the directory contains some files, delete everything
1906
+ foreach ($destination_files as $file) {
1907
+ if ($file['name'] === 'extensions' && $file['type'] === 'd') {
1908
+ // do not touch the extensions/ directory
1909
+ continue;
1910
+ }
1911
 
1912
+ if (!$wp_filesystem->delete($destination_wp_fs_dir .'/'. $file['name'], true, $file['type'])) {
1913
+ return new WP_Error(
1914
+ $wp_error_id,
1915
+ sprintf(__('Cannot delete "%s".', 'fw'), $destination_wp_fs_dir .'/'. $file['name'])
1916
+ );
1917
+ }
1918
  }
1919
 
1920
+ unset($destination_files);
 
 
 
 
 
1921
  }
 
 
1922
  } else {
1923
  if (!FW_WP_Filesystem::mkdir_recursive($destination_wp_fs_dir)) {
1924
  return new WP_Error(
framework/core/components/extensions/manager/views/extension-page-header.php CHANGED
@@ -6,6 +6,7 @@
6
  * @var string $link_delete
7
  * @var string $link_extension
8
  * @var string $tab
 
9
  */
10
 
11
  ?>
@@ -17,6 +18,10 @@
17
  if (!file_exists($extension_data['path'] .'/readme.md.php')) {
18
  break;
19
  }
 
 
 
 
20
  ?><a href="<?php echo esc_attr($link_extension) ?>&extension=<?php echo esc_attr($extension_name) ?>&tab=docs" class="button-primary"><?php _e('Install Instructions', 'fw') ?></a><?php
21
  break;
22
  case 'docs':
6
  * @var string $link_delete
7
  * @var string $link_extension
8
  * @var string $tab
9
+ * @var bool $is_supported
10
  */
11
 
12
  ?>
18
  if (!file_exists($extension_data['path'] .'/readme.md.php')) {
19
  break;
20
  }
21
+ if ($is_supported) {
22
+ // do not show install instructions for supported extensions
23
+ break;
24
+ }
25
  ?><a href="<?php echo esc_attr($link_extension) ?>&extension=<?php echo esc_attr($extension_name) ?>&tab=docs" class="button-primary"><?php _e('Install Instructions', 'fw') ?></a><?php
26
  break;
27
  case 'docs':
framework/extensions/update/class-fw-extension-update.php CHANGED
@@ -545,6 +545,24 @@ class FW_Extension_Update extends FW_Extension
545
  $source_extension_dir = $source_dir .'/'. $ext_dir['name'];
546
  $destination_extension_dir = $destination_dir .'/'. $ext_dir['name'];
547
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
  // prepare destination
549
  {
550
  // create if not exists
@@ -590,13 +608,6 @@ class FW_Extension_Update extends FW_Extension
590
 
591
  // move files from source to destination extension directory
592
  {
593
- $source_ext_files = $wp_filesystem->dirlist($source_extension_dir, true);
594
- if ($source_ext_files === false) {
595
- return new WP_Error($wp_error_id,
596
- __('Cannot access directory: ', 'fw') . $source_extension_dir
597
- );
598
- }
599
-
600
  $source_has_extensions_dir = false;
601
 
602
  foreach ($source_ext_files as $source_ext_file) {
545
  $source_extension_dir = $source_dir .'/'. $ext_dir['name'];
546
  $destination_extension_dir = $destination_dir .'/'. $ext_dir['name'];
547
 
548
+ {
549
+ $source_ext_files = $wp_filesystem->dirlist($source_extension_dir, true);
550
+ if ($source_ext_files === false) {
551
+ return new WP_Error($wp_error_id,
552
+ __('Cannot access directory: ', 'fw') . $source_extension_dir
553
+ );
554
+ }
555
+
556
+ if (empty($source_ext_files)) {
557
+ /**
558
+ * Source extension directory is empty, do nothing.
559
+ * This happens when the extension is a git submodule in repository
560
+ * but in zip it comes as an empty directory.
561
+ */
562
+ continue;
563
+ }
564
+ }
565
+
566
  // prepare destination
567
  {
568
  // create if not exists
608
 
609
  // move files from source to destination extension directory
610
  {
 
 
 
 
 
 
 
611
  $source_has_extensions_dir = false;
612
 
613
  foreach ($source_ext_files as $source_ext_file) {
framework/extensions/update/manifest.php CHANGED
@@ -6,5 +6,5 @@ $manifest['name'] = __('Update', 'fw');
6
  $manifest['description'] = __('Keep you framework, extensions and theme up to date.', 'fw');
7
  $manifest['standalone'] = true;
8
 
9
- $manifest['version'] = '1.0.4';
10
  $manifest['github_update'] = 'ThemeFuse/Unyson-Update-Extension';
6
  $manifest['description'] = __('Keep you framework, extensions and theme up to date.', 'fw');
7
  $manifest['standalone'] = true;
8
 
9
+ $manifest['version'] = '1.0.5';
10
  $manifest['github_update'] = 'ThemeFuse/Unyson-Update-Extension';
framework/helpers/class-fw-flash-messages.php CHANGED
@@ -17,6 +17,8 @@ class FW_Flash_Messages
17
 
18
  private static $session_key = 'fw_flash_messages';
19
 
 
 
20
  private static function get_messages()
21
  {
22
  $messages = FW_Session::get(self::$session_key);
@@ -138,7 +140,6 @@ class FW_Flash_Messages
138
 
139
  /**
140
  * Use this method to print messages html in frontend
141
- * @internal
142
  */
143
  public static function _print_frontend()
144
  {
@@ -150,12 +151,12 @@ class FW_Flash_Messages
150
  foreach ($all_messages as $type => $messages) {
151
  if (!empty($messages)) {
152
  foreach ($messages as $id => $data) {
153
- $html[$type] .= '<div class="fw-flash-message"><p>'. nl2br($data['message']) .'</p></div>';
154
 
155
  unset($all_messages[$type][$id]);
156
  }
157
 
158
- $html[$type] = '<div class="fw-flash-type-'. $type .'">'. $html[$type] .'</div>';
159
  }
160
  }
161
 
@@ -164,6 +165,13 @@ class FW_Flash_Messages
164
  echo '<div class="fw-flash-messages">';
165
  echo implode("\n\n", $html);
166
  echo '</div>';
 
 
 
 
 
 
 
167
  }
168
  }
169
 
@@ -194,4 +202,34 @@ if (is_admin()) {
194
  }
195
  }
196
  add_action('send_headers', '_action_fw_flash_message_frontend_prepare', 9999);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
  }
17
 
18
  private static $session_key = 'fw_flash_messages';
19
 
20
+ private static $frontend_printed = false;
21
+
22
  private static function get_messages()
23
  {
24
  $messages = FW_Session::get(self::$session_key);
140
 
141
  /**
142
  * Use this method to print messages html in frontend
 
143
  */
144
  public static function _print_frontend()
145
  {
151
  foreach ($all_messages as $type => $messages) {
152
  if (!empty($messages)) {
153
  foreach ($messages as $id => $data) {
154
+ $html[$type] .= '<li class="fw-flash-message">'. nl2br($data['message']) .'</li>';
155
 
156
  unset($all_messages[$type][$id]);
157
  }
158
 
159
+ $html[$type] = '<ul class="fw-flash-type-'. $type .'">'. $html[$type] .'</ul>';
160
  }
161
  }
162
 
165
  echo '<div class="fw-flash-messages">';
166
  echo implode("\n\n", $html);
167
  echo '</div>';
168
+
169
+ self::$frontend_printed = true;
170
+ }
171
+
172
+ public static function _frontend_printed()
173
+ {
174
+ return self::$frontend_printed;
175
  }
176
  }
177
 
202
  }
203
  }
204
  add_action('send_headers', '_action_fw_flash_message_frontend_prepare', 9999);
205
+
206
+ /**
207
+ * Print flash messages in frontend if this has not been done from theme
208
+ */
209
+ function _action_fw_flash_message_frontend_print() {
210
+ if (FW_Flash_Messages::_frontend_printed()) {
211
+ return;
212
+ }
213
+
214
+ FW_Flash_Messages::_print_frontend();
215
+
216
+ echo
217
+ '<script type="text/javascript">'.
218
+ ' (function(){'.
219
+ ' if (typeof jQuery === "undefined") return;'.
220
+ ' jQuery(function($){'.
221
+ ' var $container = $("#content .entry-content:first");'.
222
+ ' if (!$container.length) $container = $(document.body);'.
223
+ ' $(".fw-flash-messages").prependTo($container);'.
224
+ ' });'.
225
+ ' })();'.
226
+ '</script>'.
227
+ '<style type="text/css">'.
228
+ ' .fw-flash-messages .fw-flash-type-error { color: #f00; }'.
229
+ ' .fw-flash-messages .fw-flash-type-warning { color: #f70; }'.
230
+ ' .fw-flash-messages .fw-flash-type-success { color: #070; }'.
231
+ ' .fw-flash-messages .fw-flash-type-info { color: #07f; }'.
232
+ '</style>';
233
+ }
234
+ add_action('wp_footer', '_action_fw_flash_message_frontend_print', 9999);
235
  }
framework/helpers/class-fw-form.php CHANGED
@@ -42,6 +42,12 @@ class FW_Form {
42
  */
43
  protected $errors;
44
 
 
 
 
 
 
 
45
  /**
46
  * If current request is the submit of this form
47
  * @var bool
@@ -389,9 +395,16 @@ class FW_Form {
389
  return array( '~' => true );
390
  }
391
 
 
 
392
  return $this->errors;
393
  }
394
 
 
 
 
 
 
395
  /**
396
  * Get submitted form instance (or false if no form is currently submitted)
397
  * @return FW_Form|false
@@ -422,6 +435,7 @@ class FW_Form {
422
  if ( is_admin() ) {
423
  /**
424
  * Display form errors in admin side
 
425
  */
426
  function _action_show_fw_form_errors_in_admin() {
427
  $form = FW_Form::get_submitted();
@@ -434,6 +448,39 @@ if ( is_admin() ) {
434
  FW_Flash_Messages::add( 'fw-form-admin-' . $input_name, $error_message, 'error' );
435
  }
436
  }
437
-
438
  add_action( 'wp_loaded', '_action_show_fw_form_errors_in_admin', 111 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  }
42
  */
43
  protected $errors;
44
 
45
+ /**
46
+ * If the get_errors() method was called at leas once
47
+ * @var bool
48
+ */
49
+ protected $errors_accessed = false;
50
+
51
  /**
52
  * If current request is the submit of this form
53
  * @var bool
395
  return array( '~' => true );
396
  }
397
 
398
+ $this->errors_accessed = true;
399
+
400
  return $this->errors;
401
  }
402
 
403
+ public function errors_accessed()
404
+ {
405
+ return $this->errors_accessed;
406
+ }
407
+
408
  /**
409
  * Get submitted form instance (or false if no form is currently submitted)
410
  * @return FW_Form|false
435
  if ( is_admin() ) {
436
  /**
437
  * Display form errors in admin side
438
+ * @internal
439
  */
440
  function _action_show_fw_form_errors_in_admin() {
441
  $form = FW_Form::get_submitted();
448
  FW_Flash_Messages::add( 'fw-form-admin-' . $input_name, $error_message, 'error' );
449
  }
450
  }
 
451
  add_action( 'wp_loaded', '_action_show_fw_form_errors_in_admin', 111 );
452
+ } else {
453
+ /**
454
+ * Detect if form errors was not displayed in frontend then display them with default design
455
+ * Do nothing if the theme already displayed the errors
456
+ * @internal
457
+ */
458
+ function _action_show_fw_form_errors_in_frontend() {
459
+ $form = FW_Form::get_submitted();
460
+
461
+ if ( ! $form || $form->is_valid() ) {
462
+ return;
463
+ }
464
+
465
+ if ( $form->errors_accessed() ) {
466
+ // already displayed
467
+ return;
468
+ }
469
+
470
+ foreach ($form->get_errors() as $input_name => $error_message) {
471
+ FW_Flash_Messages::add(
472
+ 'fw-form-error-'. $input_name,
473
+ $error_message,
474
+ 'error'
475
+ );
476
+ }
477
+ }
478
+ add_action( 'wp_footer', '_action_show_fw_form_errors_in_frontend',
479
+ /**
480
+ * Use priority later than the default 10.
481
+ * In docs (to customize the error messages) will be easier to explain
482
+ * to use just add_action('wp_footer', ...) and not bother about priority
483
+ */
484
+ 11
485
+ );
486
  }
framework/includes/option-types/addable-option/static/css/styles.css CHANGED
@@ -67,4 +67,9 @@ body.rtl .fw-option-type-addable-option tr.fw-option-type-addable-option-option.
67
 
68
  .fw-option-type-addable-option tr.fw-option-type-addable-option-option.ui-sortable-helper td.td-option {
69
  width: calc(100% - 35px);
 
 
 
 
 
70
  }
67
 
68
  .fw-option-type-addable-option tr.fw-option-type-addable-option-option.ui-sortable-helper td.td-option {
69
  width: calc(100% - 35px);
70
+ }
71
+
72
+
73
+ .fw-backend-option-input-type-addable-option .fw-option-help-in-input {
74
+ top: 4px !important;
75
  }
framework/includes/option-types/datetime-picker/static/css/style.css CHANGED
@@ -1,3 +1,8 @@
1
  .xdsoft_datetimepicker.xdsoft_noselect {
2
  z-index: 160013;
3
  }
 
 
 
 
 
1
  .xdsoft_datetimepicker.xdsoft_noselect {
2
  z-index: 160013;
3
  }
4
+
5
+
6
+ .fw-backend-option-input-type-datetime-picker .fw-option-help-in-input {
7
+ top: 4px !important;
8
+ }
framework/includes/option-types/datetime-range/static/css/styles.css CHANGED
@@ -15,4 +15,9 @@
15
  .fw-option-type-datetime-range .fw-option-type-datetime-picker,
16
  .fw-backend-option-input-type-datetime-range .fw-option-type-datetime-picker {
17
  width: 150px;
 
 
 
 
 
18
  }
15
  .fw-option-type-datetime-range .fw-option-type-datetime-picker,
16
  .fw-backend-option-input-type-datetime-range .fw-option-type-datetime-picker {
17
  width: 150px;
18
+ }
19
+
20
+
21
+ .fw-backend-option-input-type-datetime-range .fw-option-help-in-input {
22
+ top: 4px !important;
23
  }
framework/includes/option-types/multi-select/static/css/style.css CHANGED
@@ -20,4 +20,8 @@
20
 
21
  .fw-option-type-multi-select .selectize-input.focus.input-active.dropdown-active:after {
22
  border-width: 5px 5px 0 5px;
 
 
 
 
23
  }
20
 
21
  .fw-option-type-multi-select .selectize-input.focus.input-active.dropdown-active:after {
22
  border-width: 5px 5px 0 5px;
23
+ }
24
+
25
+ .fw-backend-option-input-type-multi-select .fw-option-help-in-input {
26
+ top: 4px !important;
27
  }
framework/includes/option-types/multi-upload/static/css/any-files.css CHANGED
@@ -8,10 +8,16 @@
8
  }
9
  .fw-option-type-multi-upload.any-files em {
10
  font-style: normal;
 
11
  }
12
  .fw-option-type-multi-upload.any-files a {
13
  outline: none;
14
  }
15
- .fw-option-type-multi-upload.any-files button {
16
  vertical-align: middle;
17
  }
 
 
 
 
 
8
  }
9
  .fw-option-type-multi-upload.any-files em {
10
  font-style: normal;
11
+ vertical-align: middle;
12
  }
13
  .fw-option-type-multi-upload.any-files a {
14
  outline: none;
15
  }
16
+ .fw-option-type.any-files button {
17
  vertical-align: middle;
18
  }
19
+
20
+
21
+ .fw-backend-option-input-type-multi-upload .fw-option-help-in-input {
22
+ top: 4px !important;
23
+ }
framework/includes/option-types/multi-upload/static/css/images-only.css CHANGED
@@ -65,3 +65,8 @@
65
  .fw-option-type-multi-upload.images-only .no-image-img {
66
  cursor: pointer;
67
  }
 
 
 
 
 
65
  .fw-option-type-multi-upload.images-only .no-image-img {
66
  cursor: pointer;
67
  }
68
+
69
+
70
+ .fw-backend-option-input-type-multi-upload .fw-option-help-in-input {
71
+ top: 4px !important;
72
+ }
framework/includes/option-types/radio-text/static/css/styles.css CHANGED
@@ -24,4 +24,9 @@
24
 
25
  .fw-option-type-radio-text .custom input.fw-option-type-text:first-child{
26
  margin: 0;
 
 
 
 
 
27
  }
24
 
25
  .fw-option-type-radio-text .custom input.fw-option-type-text:first-child{
26
  margin: 0;
27
+ }
28
+
29
+
30
+ .fw-backend-option-input-type-radio-text .fw-option-help-in-input {
31
+ top: 4px !important;
32
  }
framework/includes/option-types/upload/static/css/any-files.css CHANGED
@@ -15,3 +15,8 @@
15
  .fw-option-type-upload.any-files button {
16
  vertical-align: middle;
17
  }
 
 
 
 
 
15
  .fw-option-type-upload.any-files button {
16
  vertical-align: middle;
17
  }
18
+
19
+
20
+ .fw-backend-option-input-type-upload .fw-option-help-in-input {
21
+ top: 4px !important;
22
+ }
framework/includes/option-types/upload/static/css/images-only.css CHANGED
@@ -46,4 +46,9 @@
46
 
47
  .fw-option-type-upload.images-only .no-image-img {
48
  cursor: pointer;
 
 
 
 
 
49
  }
46
 
47
  .fw-option-type-upload.images-only .no-image-img {
48
  cursor: pointer;
49
+ }
50
+
51
+
52
+ .fw-backend-option-input-type-upload .fw-option-help-in-input {
53
+ top: 4px !important;
54
  }
framework/manifest.php CHANGED
@@ -4,4 +4,4 @@ $manifest = array();
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
- $manifest['version'] = '2.1.8';
4
 
5
  $manifest['name'] = __('Unyson', 'fw');
6
 
7
+ $manifest['version'] = '2.1.9';
framework/static/js/fw.js CHANGED
@@ -1116,3 +1116,69 @@ jQuery.expr[':']['fw-external'] = function(obj){
1116
  && !obj.href.match(/^javascript\:/)
1117
  && !obj.href.match(/^$/);
1118
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1116
  && !obj.href.match(/^javascript\:/)
1117
  && !obj.href.match(/^$/);
1118
  };
1119
+
1120
+ /**
1121
+ * Check if an event fired from an element has listeners within specified container/parent element
1122
+ * @param $element
1123
+ * @param {String} event
1124
+ * @param $container
1125
+ * @return {Boolean}
1126
+ */
1127
+ fw.elementEventHasListenerInContainer = function ($element, event, $container) {
1128
+ "use strict";
1129
+
1130
+ var events, container = $container.get(0);
1131
+
1132
+ /**
1133
+ * Check if container element has delegated event that matches the element
1134
+ */
1135
+ {
1136
+ var foundListener = false;
1137
+
1138
+ if (
1139
+ (events = $container.data('events'))
1140
+ &&
1141
+ events[event]
1142
+ ) {
1143
+ jQuery.each(events[event], function(i, eventData){
1144
+ if ($element.is(eventData.selector)) {
1145
+ foundListener = true;
1146
+ return false;
1147
+ }
1148
+ });
1149
+ }
1150
+
1151
+ if (foundListener) {
1152
+ return true;
1153
+ }
1154
+ }
1155
+
1156
+ /**
1157
+ * Check every parent if has event listener
1158
+ */
1159
+ {
1160
+ var $currentParent = $element;
1161
+
1162
+ while ($currentParent.get(0) !== container) {
1163
+ if (
1164
+ (events = $currentParent.data('events'))
1165
+ &&
1166
+ events[event]
1167
+ ) {
1168
+ return true;
1169
+ }
1170
+
1171
+ $currentParent = $currentParent.parent();
1172
+
1173
+ if (!$currentParent.length) {
1174
+ /**
1175
+ * The element doesn't exist in DOM
1176
+ * This means that the event was processed, so it has listener
1177
+ */
1178
+ return true;
1179
+ }
1180
+ }
1181
+ }
1182
+
1183
+ return false;
1184
+ };
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: unyson, themefusecom
3
  Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio
4
  Requires at least: 4.0.0
5
  Tested up to: 4.0.1
6
- Stable tag: 2.1.8
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -84,6 +84,9 @@ Yes; Unyson will work with any theme.
84
 
85
  == Changelog ==
86
 
 
 
 
87
  = 2.1.8 =
88
  * Minor fixes [#117](https://github.com/ThemeFuse/Unyson/issues/117)
89
 
3
  Tags: page builder, cms, grid, layout, responsive, back up, backup, db backup, dump, migrate, schedule, search engine optimization, seo, media, slideshow, shortcode, slide, slideshare, slideshow, google sitemaps, sitemaps, analytics, google analytics, calendar, event, events, google maps, learning, lessons, sidebars, breadcrumbs, review, portfolio
4
  Requires at least: 4.0.0
5
  Tested up to: 4.0.1
6
+ Stable tag: 2.1.9
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
84
 
85
  == Changelog ==
86
 
87
+ = 2.1.9 =
88
+ * Fixed: Extension is not installing if directory already exists but is empty.
89
+
90
  = 2.1.8 =
91
  * Minor fixes [#117](https://github.com/ThemeFuse/Unyson/issues/117)
92
 
unyson.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Unyson
4
  * Plugin URI: http://unyson.themefuse.com/
5
  * Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
6
- * Version: 2.1.8
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+
3
  * Plugin Name: Unyson
4
  * Plugin URI: http://unyson.themefuse.com/
5
  * Description: A free drag & drop framework that comes with a bunch of built in extensions that will help you develop premium themes fast & easy.
6
+ * Version: 2.1.9
7
  * Author: ThemeFuse
8
  * Author URI: http://themefuse.com
9
  * License: GPL2+