MetaSlider - Version 3.7.0

Version Description

  • 2018/Feb/26 =

  • FEATURE: Allows users to inherit default captions and other data from the image.

  • FIX: Adds capability filter to pages.

  • TWEAK: Updates to the correct support link.

Download this release

Release Info

Developer DavidAnderson
Plugin Icon 128x128 MetaSlider
Version 3.7.0
Comparing to
See all releases

Code changes from version 3.6.8 to 3.7.0

admin/Notices.php CHANGED
@@ -37,14 +37,14 @@ class MetaSlider_Notices extends Updraft_Notices_1_0 {
37
  * @param array $plugin Plugin details
38
  */
39
  public function __construct($plugin) {
40
- $this->ads = $this->is_metasliderpro_installed() ? $this->pro_notices() : $this->lite_notices();
41
 
42
  // To avoid showing the user ads off the start, lets wait
43
  $this->notices_content = ($this->ad_delay_has_finished()) ? $this->ads : array();
44
  $this->plugin = $plugin;
45
 
46
  // If $notices_content is empty, we still want to offer seasonal ads
47
- if (empty($this->notices_content) && !$this->is_metasliderpro_installed()) {
48
  $this->notices_content = $this->valid_seasonal_notices();
49
  }
50
 
@@ -186,7 +186,7 @@ class MetaSlider_Notices extends Updraft_Notices_1_0 {
186
  'button_link' => 'https://www.metaslider.com/survey-pro',
187
  'button_meta' => 'lets_start',
188
  'dismiss_time' => 'pro_survey',
189
- 'hide_time' => __('forever', 'ml-slider'),
190
  'supported_positions' => array('header'),
191
  ),
192
  );
@@ -328,16 +328,6 @@ class MetaSlider_Notices extends Updraft_Notices_1_0 {
328
  );
329
  }
330
 
331
- /**
332
- * Check to disable ads on the Pro version. The parent function returns
333
- * false if installed, so this is reversed and shouldn't be used for the validity function
334
- *
335
- * @return bool
336
- */
337
- protected function is_metasliderpro_installed() {
338
- return !parent::is_plugin_installed('ml-slider-pro', false);
339
- }
340
-
341
  /**
342
  * Check to see if UpdraftPlus is installed
343
  *
@@ -444,7 +434,7 @@ class MetaSlider_Notices extends Updraft_Notices_1_0 {
444
  */
445
  protected function ad_delay_has_finished() {
446
 
447
- if (metaslider_is_pro_installed()) {
448
 
449
  // If they are pro don't check anything but show the pro ad.
450
  return true;
@@ -493,7 +483,7 @@ class MetaSlider_Notices extends Updraft_Notices_1_0 {
493
  */
494
  public function show_dashboard_notices() {
495
  $current_page = get_current_screen();
496
- if ('dashboard' === $current_page->base && metaslider_sees_notices($this->plugin)) {
497
 
498
  // Override the delay to show the thankyou notice on activation
499
  // if (!empty($_GET['ms_activated'])) {
37
  * @param array $plugin Plugin details
38
  */
39
  public function __construct($plugin) {
40
+ $this->ads = metaslider_pro_is_installed() ? $this->pro_notices() : $this->lite_notices();
41
 
42
  // To avoid showing the user ads off the start, lets wait
43
  $this->notices_content = ($this->ad_delay_has_finished()) ? $this->ads : array();
44
  $this->plugin = $plugin;
45
 
46
  // If $notices_content is empty, we still want to offer seasonal ads
47
+ if (empty($this->notices_content) && !metaslider_pro_is_installed()) {
48
  $this->notices_content = $this->valid_seasonal_notices();
49
  }
50
 
186
  'button_link' => 'https://www.metaslider.com/survey-pro',
187
  'button_meta' => 'lets_start',
188
  'dismiss_time' => 'pro_survey',
189
+ 'hide_time' => '',
190
  'supported_positions' => array('header'),
191
  ),
192
  );
328
  );
329
  }
330
 
 
 
 
 
 
 
 
 
 
 
331
  /**
332
  * Check to see if UpdraftPlus is installed
333
  *
434
  */
435
  protected function ad_delay_has_finished() {
436
 
437
+ if (metaslider_pro_is_installed()) {
438
 
439
  // If they are pro don't check anything but show the pro ad.
440
  return true;
483
  */
484
  public function show_dashboard_notices() {
485
  $current_page = get_current_screen();
486
+ if ('dashboard' === $current_page->base && metaslider_user_sees_notices($this->plugin)) {
487
 
488
  // Override the delay to show the thankyou notice on activation
489
  // if (!empty($_GET['ms_activated'])) {
admin/Pages.php CHANGED
@@ -5,13 +5,6 @@
5
  */
6
  Class MetaSlider_Admin_Pages extends MetaSliderPlugin {
7
 
8
- /**
9
- * The minimum capability to view the admin page
10
- *
11
- * @var string $capability
12
- */
13
- private $capability;
14
-
15
  /**
16
  * The MetaSlider plugin class
17
  *
@@ -33,7 +26,6 @@ Class MetaSlider_Admin_Pages extends MetaSliderPlugin {
33
  */
34
  public function __construct($plugin) {
35
  $this->plugin = $plugin;
36
- $this->capability = apply_filters('metaslider_capability', 'edit_others_posts');
37
  $this->notices = new MetaSlider_Notices($plugin);
38
  $this->tour = new MetaSlider_Tour($plugin, 'toplevel_page_metaslider');
39
  add_action('admin_enqueue_scripts', array($this, 'load_icon_css'));
@@ -144,7 +136,9 @@ Class MetaSlider_Admin_Pages extends MetaSliderPlugin {
144
  return false;
145
  }
146
  $this->current_page = $slug;
147
- $page = ('' == $parent) ? add_menu_page($title, $title, $this->capability, $slug, array($this, $method)) : add_submenu_page($parent, $title, $title, $this->capability, $slug, array($this, $method));
 
 
148
 
149
  // Load assets on all pages
150
  add_action('load-' . $page, array($this, 'fix_conflicts'));
5
  */
6
  Class MetaSlider_Admin_Pages extends MetaSliderPlugin {
7
 
 
 
 
 
 
 
 
8
  /**
9
  * The MetaSlider plugin class
10
  *
26
  */
27
  public function __construct($plugin) {
28
  $this->plugin = $plugin;
 
29
  $this->notices = new MetaSlider_Notices($plugin);
30
  $this->tour = new MetaSlider_Tour($plugin, 'toplevel_page_metaslider');
31
  add_action('admin_enqueue_scripts', array($this, 'load_icon_css'));
136
  return false;
137
  }
138
  $this->current_page = $slug;
139
+ $capability = apply_filters('metaslider_capability', 'edit_others_posts');
140
+
141
+ $page = ('' == $parent) ? add_menu_page($title, $title, $capability, $slug, array($this, $method)) : add_submenu_page($parent, $title, $title, $capability, $slug, array($this, $method));
142
 
143
  // Load assets on all pages
144
  add_action('load-' . $page, array($this, 'fix_conflicts'));
admin/Tour.php CHANGED
@@ -49,14 +49,14 @@ Class MetaSlider_Tour {
49
  'next_language' => __('Next', 'ml-slider'),
50
  'skip_language' => __('Skip this step', 'ml-slider'),
51
  'upgrade_link' => metaslider_get_upgrade_link(),
52
- 'is_pro' => metaslider_is_pro_active(),
53
  'step1' => array(
54
  'title' => __("Add A Slide", "ml-slider"),
55
  'message' => __("Congratulations! Now that you've created a slideshow, click here to add a slide.", "ml-slider")
56
  ),
57
  'step2a' => array(
58
  'title' => __("Select Slide Type", "ml-slider"),
59
- 'message' => metaslider_is_pro_active() ? 'Thanks for activating the Add-on Pack! Premium users can choose from any of these slide types' : __("Premium users that have the Add-on Pack activated can access additional slide types!", "ml-slider")
60
  ),
61
  'step2b' => array(
62
  'title' => __("Select Media", "ml-slider"),
49
  'next_language' => __('Next', 'ml-slider'),
50
  'skip_language' => __('Skip this step', 'ml-slider'),
51
  'upgrade_link' => metaslider_get_upgrade_link(),
52
+ 'is_pro' => metaslider_pro_is_active(),
53
  'step1' => array(
54
  'title' => __("Add A Slide", "ml-slider"),
55
  'message' => __("Congratulations! Now that you've created a slideshow, click here to add a slide.", "ml-slider")
56
  ),
57
  'step2a' => array(
58
  'title' => __("Select Slide Type", "ml-slider"),
59
+ 'message' => metaslider_pro_is_active() ? 'Thanks for activating the Add-on Pack! Premium users can choose from any of these slide types' : __("Premium users that have the Add-on Pack activated can access additional slide types!", "ml-slider")
60
  ),
61
  'step2b' => array(
62
  'title' => __("Select Media", "ml-slider"),
admin/assets/css/admin.css CHANGED
@@ -132,12 +132,14 @@
132
  position: relative;
133
  float: right;
134
  padding: 0px;
 
 
135
  color: #a9a9a9;
136
- line-height: 20px;
137
- bottom: 22px;
138
- right: 0;
 
139
  }
140
-
141
  .rtl .metaslider .left table tr.slide .tabs-content .new_window {
142
  position: relative;
143
  float: left;
@@ -146,17 +148,67 @@
146
  .metaslider .left table tr.slide .tabs-content .new_window input {
147
  margin-left: 3px
148
  }
149
-
150
  .rtl .metaslider .left table tr.slide .tabs-content .new_window input {
151
- margin-right: 3px
152
  }
153
-
154
  .metaslider .left table tr.slide .tabs-content .new_window label {
155
- width: 120px;
156
  text-align: right;
157
  font-size: 11px;
158
  }
159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  .metaslider tr.radio {
161
  display: table-row;
162
  }
@@ -481,11 +533,8 @@ input[type=radio]:checked + label {
481
  padding: 5px 10px;
482
  }
483
 
484
- input:-ms-input-placeholder {
485
- color: LightGray;
486
- }
487
-
488
- textarea:-ms-input-placeholder {
489
  color: LightGray;
490
  }
491
 
@@ -495,7 +544,8 @@ textarea:-ms-input-placeholder {
495
 
496
  .metaslider .tabs-content,
497
  .metaslider .tabs-content ul,
498
- .metaslider .tabs-content li {
 
499
  font-size: 12px;
500
  }
501
 
@@ -542,6 +592,10 @@ textarea:-ms-input-placeholder {
542
  .metaslider .tabs-content .row input[type=text] {
543
  width: 100%;
544
  }
 
 
 
 
545
 
546
  .metaslider .tabs-content ul {
547
  margin: 0;
@@ -1028,7 +1082,7 @@ textarea:-ms-input-placeholder {
1028
  padding: 0.5rem;
1029
  max-width: 100px;
1030
  text-overflow: ellipsis;
1031
- /* overflow: hidden; */
1032
  outline: 0;
1033
  float: left;
1034
  }
132
  position: relative;
133
  float: right;
134
  padding: 0px;
135
+ padding-left: 5px;
136
+ margin-right: 0;
137
  color: #a9a9a9;
138
+ line-height: 20px;
139
+ right: 0;
140
+ width: 155px;
141
+ text-align: right;
142
  }
 
143
  .rtl .metaslider .left table tr.slide .tabs-content .new_window {
144
  position: relative;
145
  float: left;
148
  .metaslider .left table tr.slide .tabs-content .new_window input {
149
  margin-left: 3px
150
  }
 
151
  .rtl .metaslider .left table tr.slide .tabs-content .new_window input {
152
+ margin-right: 0px
153
  }
 
154
  .metaslider .left table tr.slide .tabs-content .new_window label {
 
155
  text-align: right;
156
  font-size: 11px;
157
  }
158
 
159
+ /* small label */
160
+ .metaslider .input-label.right {
161
+ float: right;
162
+ color: #a9a9a9;
163
+ font-size: 11px;
164
+ }
165
+ .metaslider .tabs-content .input-label.right input{
166
+ margin-right: 0;
167
+ }
168
+
169
+ /* Caption */
170
+ .metaslider .tabs-content .caption {
171
+ position: relative;
172
+ }
173
+ .metaslider .tabs-content .caption label {
174
+ }
175
+
176
+
177
+ .metaslider .tabs-content .can-inherit textarea,
178
+ .metaslider .tabs-content .can-inherit input[type=text] {
179
+ display: block;
180
+ }
181
+
182
+ .metaslider .tabs-content .default {
183
+ display: none;
184
+ width: 100%;
185
+ overflow: hidden;
186
+ padding: 2px 5px;
187
+ border: 1px solid #cccccc;
188
+ background: #eeeeee;
189
+ line-height: 16px;
190
+ font-size: 11px;
191
+ }
192
+ .metaslider .tabs-content .caption .default {
193
+ height: 60px;
194
+ overflow: auto;
195
+ margin: 0 0 5px 0;
196
+ font-size: 12px;
197
+ }
198
+ .metaslider .tabs-content .caption.inherit-from-image textarea {
199
+ display: none;
200
+ }
201
+ .metaslider .tabs-content .inherit-from-image input[type=text] {
202
+ display: none;
203
+ }
204
+ .metaslider .tabs-content .inherit-from-image .default {
205
+ display: block;
206
+ }
207
+ .metaslider .tabs-content .default .no-content {
208
+ opacity: 0.3;
209
+ font-style: italic;
210
+ }
211
+
212
  .metaslider tr.radio {
213
  display: table-row;
214
  }
533
  padding: 5px 10px;
534
  }
535
 
536
+ .metaslider input::placeholder,
537
+ .metaslider textarea::placeholder {
 
 
 
538
  color: LightGray;
539
  }
540
 
544
 
545
  .metaslider .tabs-content,
546
  .metaslider .tabs-content ul,
547
+ .metaslider .tabs-content li,
548
+ .metaslider .tabs-content textarea {
549
  font-size: 12px;
550
  }
551
 
592
  .metaslider .tabs-content .row input[type=text] {
593
  width: 100%;
594
  }
595
+ .metaslider .tabs-content .row.has-right-checkbox > input[type=text] {
596
+ width: calc( 100% - 155px );
597
+ }
598
+
599
 
600
  .metaslider .tabs-content ul {
601
  margin: 0;
1082
  padding: 0.5rem;
1083
  max-width: 100px;
1084
  text-overflow: ellipsis;
1085
+ overflow: hidden;
1086
  outline: 0;
1087
  float: left;
1088
  }
admin/assets/js/admin.js CHANGED
@@ -49,19 +49,55 @@ jQuery(function($) {
49
  */
50
  document.getElementById('ms-entire-code')
51
  .addEventListener('copy', function(event) {
52
- var text = window.getSelection()
53
- .toString().split("'").map(function(string, index) {
54
- return (index === 1) ? string.replace(/\s/g, '').replace('ri', 'r i') : string;
55
- }).join("'");
56
  event.clipboardData.setData('text/plain', text);
57
  event.preventDefault()
58
  });
59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  /**
61
  * UI for adding a slide. Managed through the WP media upload UI
62
  * Event managed here.
63
  */
64
- var create_slides = wp.media.frames.file_frame = wp.media({
65
  multiple: 'add',
66
  frame: 'post',
67
  library: {type: 'image'}
@@ -80,7 +116,7 @@ jQuery(function($) {
80
  selection: slide_ids,
81
  _wpnonce: metaslider.create_slide_nonce
82
  };
83
-
84
  // TODO: Create micro feedback to the user.
85
  // TODO: Adding lots of slides locks up the page due to 'resizeSlides' event
86
  $.ajax({
@@ -88,7 +124,7 @@ jQuery(function($) {
88
  data: data,
89
  type: 'POST',
90
  beforeSend: function() { MetaSlider_Helpers.loading(true); },
91
- complete: function() {MetaSlider_Helpers.loading(false); },
92
  error: function(response) {
93
  alert(response.responseJSON.data.message);
94
  },
@@ -99,12 +135,21 @@ jQuery(function($) {
99
  * TODO: instead have it return data and use JS to render it
100
  */
101
  $(".metaslider .left table").append(response);
102
- MetaSlider_Helpers.loading(false)
103
  $(".metaslider .left table").trigger('resizeSlides');
104
  }
105
  });
106
  });
107
-
 
 
 
 
 
 
 
 
 
108
  /**
109
  * I for changing slide image. Managed through the WP media upload UI
110
  * Initialized dynamically due to multiple slides.
@@ -114,7 +159,7 @@ jQuery(function($) {
114
  /**
115
  * Opens the UI for the slide selection.
116
  */
117
- $('.metaslider').on('click', '.add-slide', function(event){
118
  event.preventDefault();
119
  create_slides.open();
120
 
@@ -129,7 +174,8 @@ jQuery(function($) {
129
  $('.metaslider').on('click', '.update-image', function(event) {
130
  event.preventDefault();
131
  var $this = $(this);
132
-
 
133
  /**
134
  * Opens up a media window showing images
135
  */
@@ -139,8 +185,32 @@ jQuery(function($) {
139
  button: {
140
  text: MetaSlider_Helpers.capitalize($this.attr('data-button-text'))
141
  }
142
- }).open();
143
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
  /**
145
  * Handles changing an image in DB and UI
146
  */
@@ -149,12 +219,13 @@ jQuery(function($) {
149
  selection.map(function(attachment) {
150
  attachment = attachment.toJSON();
151
  new_image_id = attachment.id;
 
152
  });
153
 
154
  /**
155
  * Updates the meta information on the slide
156
  */
157
- var data = {
158
  action: 'update_slide_image',
159
  _wpnonce: metaslider.update_slide_image_nonce,
160
  slide_id: $this.data('slideId'),
@@ -172,19 +243,50 @@ jQuery(function($) {
172
  alert(response.responseJSON.data.message);
173
  },
174
  success: function(response) {
175
-
176
  /**
177
  * Updates the image on success
178
  */
179
  $('#slide-' + $this.data('slideId') + ' .thumb')
180
  .css('background-image', 'url(' + response.data.img_url + ')');
181
- $(".metaslider .left table").trigger('resizeSlides');
 
 
 
 
 
 
 
 
 
 
 
182
  }
183
  });
184
  });
185
  });
186
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
 
 
188
  /**
189
  * delete a slide using ajax (avoid losing changes)
190
  */
@@ -421,7 +523,7 @@ jQuery(function($) {
421
  var slide_row = $(this).closest('tr');
422
  var crop_changed = slide_row.data('crop_changed');
423
 
424
- if (thumb_width != slideshow_width || thumb_height != slideshow_height || crop_changed === true ) {
425
  $this.attr("data-width", slideshow_width);
426
  $this.attr("data-height", slideshow_height);
427
 
@@ -442,7 +544,7 @@ jQuery(function($) {
442
  if (crop_changed === true) {
443
  slide_row.data('crop_changed', false);
444
  }
445
-
446
  if (console && console.log) {
447
  console.log(data);
448
  }
@@ -655,7 +757,7 @@ var MetaSlider_Helpers = {
655
  * @return string Returns capitalised string
656
  */
657
  capitalize: function(string) {
658
- return string.replace(/\b\w/g, function(l){ return l.toUpperCase(); });
659
  },
660
 
661
  /**
49
  */
50
  document.getElementById('ms-entire-code')
51
  .addEventListener('copy', function(event) {
52
+ var text = window.getSelection()
53
+ .toString().split("'").map(function(string, index) {
54
+ return (index === 1) ? string.replace(/\s/g, '').replace('ri', 'r i') : string;
55
+ }).join("'");
56
  event.clipboardData.setData('text/plain', text);
57
  event.preventDefault()
58
  });
59
 
60
+ /**
61
+ * Event listening to media library edits
62
+ */
63
+ var media_library_events = {
64
+ loaded: false,
65
+ /**
66
+ * Attaches listenTo event to the library collection
67
+ *
68
+ * @param modal object wp.media modal
69
+ */
70
+ attach_event: function(modal) {
71
+ var library = modal.state().get('library');
72
+ modal.listenTo(library, 'change', function(model) {
73
+ media_library_events.update_slide_infos({
74
+ id: model.get('id'),
75
+ caption: model.get('caption'),
76
+ title: model.get('title'),
77
+ alt: model.get('alt'),
78
+ });
79
+ });
80
+ },
81
+ /**
82
+ * Updates slide caption and other infos when a media is edited in a modal
83
+ *
84
+ * @param object infos
85
+ */
86
+ update_slide_infos: function(infos) {
87
+ var $slides = $('.slide').filter(function(i){
88
+ return $(this).data('attachment-id') == infos.id;
89
+ });
90
+ infos.caption ? $('.caption .default', $slides).html(infos.caption) : $('.caption .default', $slides).html(' ');
91
+ infos.title ? $('.title .default', $slides).html(infos.title) : $('.title .default', $slides).html(' ');
92
+ infos.alt ? $('.alt .default', $slides).html(infos.alt) : $('.alt .default', $slides).html(' ');
93
+ }
94
+ };
95
+
96
  /**
97
  * UI for adding a slide. Managed through the WP media upload UI
98
  * Event managed here.
99
  */
100
+ var create_slides = window.create_slides = wp.media.frames.file_frame = wp.media({
101
  multiple: 'add',
102
  frame: 'post',
103
  library: {type: 'image'}
116
  selection: slide_ids,
117
  _wpnonce: metaslider.create_slide_nonce
118
  };
119
+
120
  // TODO: Create micro feedback to the user.
121
  // TODO: Adding lots of slides locks up the page due to 'resizeSlides' event
122
  $.ajax({
124
  data: data,
125
  type: 'POST',
126
  beforeSend: function() { MetaSlider_Helpers.loading(true); },
127
+ complete: function() { MetaSlider_Helpers.loading(false); },
128
  error: function(response) {
129
  alert(response.responseJSON.data.message);
130
  },
135
  * TODO: instead have it return data and use JS to render it
136
  */
137
  $(".metaslider .left table").append(response);
138
+ MetaSlider_Helpers.loading(false);
139
  $(".metaslider .left table").trigger('resizeSlides');
140
  }
141
  });
142
  });
143
+
144
+ /**
145
+ * Starts to watch the media library for changes
146
+ */
147
+ create_slides.on('attach', function() {
148
+ if (!media_library_events.loaded) {
149
+ media_library_events.attach_event(create_slides);
150
+ }
151
+ });
152
+
153
  /**
154
  * I for changing slide image. Managed through the WP media upload UI
155
  * Initialized dynamically due to multiple slides.
159
  /**
160
  * Opens the UI for the slide selection.
161
  */
162
+ $('.metaslider').on('click', '.add-slide', function(event) {
163
  event.preventDefault();
164
  create_slides.open();
165
 
174
  $('.metaslider').on('click', '.update-image', function(event) {
175
  event.preventDefault();
176
  var $this = $(this);
177
+ var current_id = $this.data('attachment-id');
178
+
179
  /**
180
  * Opens up a media window showing images
181
  */
185
  button: {
186
  text: MetaSlider_Helpers.capitalize($this.attr('data-button-text'))
187
  }
188
+ });
189
+
190
+ /**
191
+ * Selects current image
192
+ */
193
+ update_slide_frame.on('open', function() {
194
+ if (current_id) {
195
+ var selection = update_slide_frame.state().get('selection');
196
+ selection.reset([wp.media.attachment(current_id)]);
197
+ }
198
+ });
199
+
200
+ /**
201
+ * Starts to watch the media library for changes
202
+ */
203
+ update_slide_frame.on('attach', function() {
204
+ if (!media_library_events.loaded) {
205
+ media_library_events.attach_event(update_slide_frame);
206
+ }
207
+ });
208
+
209
+ /**
210
+ * Open media modal
211
+ */
212
+ update_slide_frame.open();
213
+
214
  /**
215
  * Handles changing an image in DB and UI
216
  */
219
  selection.map(function(attachment) {
220
  attachment = attachment.toJSON();
221
  new_image_id = attachment.id;
222
+ selected_item = attachment;
223
  });
224
 
225
  /**
226
  * Updates the meta information on the slide
227
  */
228
+ var data = {
229
  action: 'update_slide_image',
230
  _wpnonce: metaslider.update_slide_image_nonce,
231
  slide_id: $this.data('slideId'),
243
  alert(response.responseJSON.data.message);
244
  },
245
  success: function(response) {
 
246
  /**
247
  * Updates the image on success
248
  */
249
  $('#slide-' + $this.data('slideId') + ' .thumb')
250
  .css('background-image', 'url(' + response.data.img_url + ')');
251
+ // set new attachment ID
252
+ var $edited_slide_elms = $('#slide-' + $this.data('slideId') + ', #slide-' + $this.data('slideId') + ' .update-image');
253
+ $edited_slide_elms.data('attachment-id', selected_item.id);
254
+
255
+ // update default infos to new image
256
+ media_library_events.update_slide_infos({
257
+ id: selected_item.id,
258
+ caption: selected_item.caption,
259
+ title: selected_item.title,
260
+ alt: selected_item.alt,
261
+ });
262
+ $(".metaslider .left table").trigger('resizeSlides');
263
  }
264
  });
265
  });
266
  });
267
 
268
+ /**
269
+ * Handles changing caption mode
270
+ */
271
+ $('.metaslider').on('change', '.js-inherit-from-image', function(e){
272
+ var $this = $(this);
273
+ var $parent = $this.parents('.can-inherit');
274
+ var input = $parent.children('textarea,input[type=text]');
275
+ var default_item = $parent.children('.default');
276
+ if ($this.is(':checked')) {
277
+ $parent.addClass('inherit-from-image');
278
+ } else {
279
+ $parent.removeClass('inherit-from-image');
280
+ input.focus();
281
+ if ('' === input.val()) {
282
+ if (0 === default_item.find('.no-content').length) {
283
+ input.val(default_item.html());
284
+ }
285
+ }
286
+ }
287
 
288
+ });
289
+
290
  /**
291
  * delete a slide using ajax (avoid losing changes)
292
  */
523
  var slide_row = $(this).closest('tr');
524
  var crop_changed = slide_row.data('crop_changed');
525
 
526
+ if (thumb_width != slideshow_width || thumb_height != slideshow_height || crop_changed === true) {
527
  $this.attr("data-width", slideshow_width);
528
  $this.attr("data-height", slideshow_height);
529
 
544
  if (crop_changed === true) {
545
  slide_row.data('crop_changed', false);
546
  }
547
+
548
  if (console && console.log) {
549
  console.log(data);
550
  }
757
  * @return string Returns capitalised string
758
  */
759
  capitalize: function(string) {
760
+ return string.replace(/\b\w/g, function(l) { return l.toUpperCase(); });
761
  },
762
 
763
  /**
admin/lib/helpers.php CHANGED
@@ -8,7 +8,8 @@ if (!defined('ABSPATH')) die('No direct access.');
8
  * @param string $name name of the plugin 'ml-slider'
9
  * @return bool|string - will return path, ex. 'ml-slider/ml-slider.php'
10
  */
11
- function metaslider_is_plugin_installed($name) {
 
12
  foreach (get_plugins() as $plugin => $data) {
13
  if ($data['TextDomain'] == $name)
14
  return $plugin;
@@ -20,8 +21,8 @@ function metaslider_is_plugin_installed($name) {
20
  *
21
  * @return bool
22
  */
23
- function metaslider_is_pro_installed() {
24
- return (bool) metaslider_is_plugin_installed('ml-slider-pro');
25
  }
26
 
27
  /**
@@ -29,16 +30,16 @@ function metaslider_is_pro_installed() {
29
  *
30
  * @return bool
31
  */
32
- function metaslider_is_pro_active() {
33
- return is_plugin_active(metaslider_is_plugin_installed('ml-slider-pro'));
34
  }
35
  /**
36
  * Returns true if the user does not have the pro version installed
37
  *
38
  * @return bool
39
  */
40
- function metaslider_sees_upgrade_page() {
41
- return (bool) apply_filters('metaslider_show_upgrade_page', !metaslider_is_pro_installed());
42
  }
43
 
44
  /**
@@ -46,8 +47,8 @@ function metaslider_sees_upgrade_page() {
46
  *
47
  * @return bool
48
  */
49
- function metaslider_sees_call_to_action() {
50
- return (bool) apply_filters('metaslider_show_upgrade_page', !metaslider_is_pro_installed());
51
  }
52
 
53
  /**
@@ -57,7 +58,7 @@ function metaslider_sees_call_to_action() {
57
  * @param array $plugin Plugin details
58
  * @return boolean
59
  */
60
- function metaslider_sees_notices($plugin) {
61
 
62
  // If no slideshows, don't show an ad
63
  if (!count($plugin->all_meta_sliders())) {
@@ -75,7 +76,7 @@ function metaslider_sees_notices($plugin) {
75
  * @param string $page_name Admin page name
76
  * @return boolean
77
  */
78
- function metaslider_is_on_admin_page($page_name = 'admin.php') {
79
  global $pagenow;
80
  return ($pagenow == $page_name);
81
  }
8
  * @param string $name name of the plugin 'ml-slider'
9
  * @return bool|string - will return path, ex. 'ml-slider/ml-slider.php'
10
  */
11
+ function metaslider_plugin_is_installed($name) {
12
+ if (!function_exists('get_plugins')) include_once(ABSPATH.'wp-admin/includes/plugin.php');
13
  foreach (get_plugins() as $plugin => $data) {
14
  if ($data['TextDomain'] == $name)
15
  return $plugin;
21
  *
22
  * @return bool
23
  */
24
+ function metaslider_pro_is_installed() {
25
+ return (bool) metaslider_plugin_is_installed('ml-slider-pro');
26
  }
27
 
28
  /**
30
  *
31
  * @return bool
32
  */
33
+ function metaslider_pro_is_active() {
34
+ return is_plugin_active(metaslider_plugin_is_installed('ml-slider-pro'));
35
  }
36
  /**
37
  * Returns true if the user does not have the pro version installed
38
  *
39
  * @return bool
40
  */
41
+ function metaslider_user_sees_upgrade_page() {
42
+ return (bool) apply_filters('metaslider_show_upgrade_page', !metaslider_pro_is_installed());
43
  }
44
 
45
  /**
47
  *
48
  * @return bool
49
  */
50
+ function metaslider_user_sees_call_to_action() {
51
+ return (bool) apply_filters('metaslider_show_upgrade_page', !metaslider_pro_is_installed());
52
  }
53
 
54
  /**
58
  * @param array $plugin Plugin details
59
  * @return boolean
60
  */
61
+ function metaslider_user_sees_notices($plugin) {
62
 
63
  // If no slideshows, don't show an ad
64
  if (!count($plugin->all_meta_sliders())) {
76
  * @param string $page_name Admin page name
77
  * @return boolean
78
  */
79
+ function metaslider_user_is_on_admin_page($page_name = 'admin.php') {
80
  global $pagenow;
81
  return ($pagenow == $page_name);
82
  }
admin/views/pages/upgrade.php CHANGED
@@ -5,7 +5,7 @@
5
  $our_plugins = array('updraftplus', 'updraftcentral', 'wp-optimize', 'keyy');
6
  $installed_plugins = array();
7
  foreach ($our_plugins as $plugin) {
8
- $installed_plugins[$plugin] = metaslider_is_plugin_installed($plugin);
9
  }
10
  // If they have any plugins missing, make room for ads
11
  $width = (in_array(false, $installed_plugins, true)) ? 'metaslider_half_width' : ''
5
  $our_plugins = array('updraftplus', 'updraftcentral', 'wp-optimize', 'keyy');
6
  $installed_plugins = array();
7
  foreach ($our_plugins as $plugin) {
8
+ $installed_plugins[$plugin] = metaslider_plugin_is_installed($plugin);
9
  }
10
  // If they have any plugins missing, make room for ads
11
  $width = (in_array(false, $installed_plugins, true)) ? 'metaslider_half_width' : ''
admin/views/slides/tabs/crop.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('ABSPATH')) die('No direct access.'); ?>
2
+ <div class="row">
3
+ <label><?php _e("Crop Position", "ml-slider"); ?></label>
4
+ </div>
5
+ <div class="row">
6
+ <select class="crop_position" name="attachment[<?php echo $slide_id; ?>][crop_position]">
7
+ <option value="left-top" <?php echo selected($crop_position, 'left-top', false); ?>> <?php _e("Top Left", "ml-slider"); ?></option>
8
+ <option value="center-top" <?php echo selected($crop_position, 'center-top', false); ?>> <?php _e("Top Center", "ml-slider"); ?></option>
9
+ <option value="right-top" <?php echo selected($crop_position, 'right-top', false); ?>> <?php _e("Top Right", "ml-slider"); ?></option>
10
+ <option value="left-center" <?php echo selected($crop_position, 'left-center', false); ?>> <?php _e("Center Left", "ml-slider"); ?></option>
11
+ <option value="center-center" <?php echo selected($crop_position, 'center-center', false); ?>> <?php _e("Center Center", "ml-slider"); ?></option>
12
+ <option value="right-center" <?php echo selected($crop_position, 'right-center', false); ?>> <?php _e("Center Right", "ml-slider"); ?></option>
13
+ <option value="left-bottom" <?php echo selected($crop_position, 'left-bottom', false); ?>> <?php _e("Bottom Left", "ml-slider"); ?></option>
14
+ <option value="center-bottom" <?php echo selected($crop_position, 'center-bottom', false); ?>> <?php _e("Bottom Center", "ml-slider"); ?></option>
15
+ <option value="right-bottom" <?php echo selected($crop_position, 'right-bottom', false); ?>> <?php _e("Bottom Right", "ml-slider"); ?></option>
16
+ </select>
17
+ </div>
admin/views/slides/tabs/general.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('ABSPATH')) die('No direct access.'); ?>
2
+ <div class="row can-inherit caption<?php echo $inherit_image_caption_class; ?>">
3
+ <label><?php _e("Caption", "ml-slider"); ?></label>
4
+ <div class="input-label right">
5
+ <label class="small" title="<?php _e('Enable this to inherit the caption from the image', 'ml-slider'); ?>">
6
+ <?php _e("Use the image caption", "ml-slider"); ?> <input autocomplete="off" type="checkbox" class="js-inherit-from-image" name="attachment[<?php echo $slide_id; ?>][inherit_image_caption]" <?php echo $inherit_image_caption_check; ?>>
7
+ </label>
8
+ </div>
9
+ <div class="default"><?php echo $image_caption ? $image_caption : '<span class="no-content">' . __('No default caption set', 'ml-slider') . '</span>'; ?></div>
10
+ <textarea name="attachment[<?php echo $slide_id; ?>][post_excerpt]"><?php echo $caption; ?></textarea>
11
+ </div>
12
+ <div class="row has-right-checkbox">
13
+ <input class="url" type="text" name="attachment[<?php echo $slide_id; ?>][url]" placeholder="<?php _e("URL", "ml-slider"); ?>" value="<?php echo $url; ?>" />
14
+ <div class="input-label right new_window">
15
+ <label><?php _e("Open in a new window", "ml-slider"); ?> <input autocomplete="off" tabindex="0" type="checkbox" name="attachment[<?php echo $slide_id; ?>][new_window]" <?php echo $target; ?> /></label>
16
+ </div>
17
+ </div>
admin/views/slides/tabs/seo.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if (!defined('ABSPATH')) {
2
+ die('No direct access.');
3
+ } ?>
4
+ <div class="row can-inherit title<?php echo $inherit_image_title_class; ?>">
5
+ <label><?php _e("Image Title Text", "ml-slider"); ?></label>
6
+ <div class="input-label right">
7
+ <label class="small" title="<?php _e("Enable this to inherit the image title", "ml-slider"); ?>">
8
+ <?php _e("Use the image title", "ml-slider"); ?> <input autocomplete="off" type="checkbox" class="js-inherit-from-image" name="attachment[<?php echo $slide_id; ?>][inherit_image_title]" <?php echo $inherit_image_title_check; ?>>
9
+ </label>
10
+ </div>
11
+ <div class="default"><?php echo $image_title ? $image_title : "<span class='no-content'>&nbsp;</span>"; ?></div>
12
+ <input tabindex="0" type="text" size="50" name="attachment[<?php echo $slide_id; ?>][title]" value="<?php echo $title; ?>">
13
+ </div>
14
+ <div class="row can-inherit alt<?php echo $inherit_image_alt_class; ?>">
15
+ <label><?php _e("Image Alt Text", "ml-slider"); ?></label>
16
+ <div class="input-label right">
17
+ <label class="small" title="<?php _e('Enable this to inherit the image alt text', 'ml-slider'); ?>">
18
+ <?php _e("Use the image alt text", "ml-slider"); ?> <input autocomplete="off" type="checkbox" class="js-inherit-from-image" name="attachment[<?php echo $slide_id; ?>][inherit_image_alt]" <?php echo $inherit_image_alt_check; ?>>
19
+ </label>
20
+ </div>
21
+ <div class="default"><?php echo $image_alt ? $image_alt : "<span class='no-content'>&nbsp;</span>"; ?></div>
22
+ <input tabindex="0" type="text" size="50" name="attachment[<?php echo $slide_id; ?>][alt]" value="<?php echo $alt; ?>">
23
+ </div>
inc/slide/metaslide.class.php CHANGED
@@ -266,18 +266,6 @@ class MetaSlide {
266
  // Set the image to the slide
267
  set_post_thumbnail($slide_id, $media_id);
268
 
269
- // Check if the post is an image and add some extra info
270
- if ('image' == $type) {
271
- $alt = get_post_meta($media_id, '_wp_attachment_image_alt', true);
272
- add_post_meta($slide_id, '_wp_attachment_image_alt', $alt);
273
- $caption = has_excerpt($media_id) ? get_the_excerpt($media_id) : '';
274
-
275
- // Update the post and caption
276
- wp_update_post(array(
277
- 'ID' => $slide_id,
278
- 'post_excerpt' => $caption
279
- ));
280
- }
281
  $this->add_or_update_or_delete_meta($slide_id, 'type', $type);
282
  return $slide_id;
283
  }
@@ -374,7 +362,8 @@ class MetaSlide {
374
  * @return string The html for the edit button on a slide image
375
  */
376
  public function get_update_image_button_html() {
377
- return "<button class='update-image alignright' data-button-text='" . __("Update slide image", "ml-slider") . "' title='" . __("Update slide image", "ml-slider") . "' data-slide-id='{$this->slide->ID}'><i><svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-edit-2'><polygon points='16 3 21 8 8 21 3 21 3 16 16 3'/></svg></i></button>";
 
378
  }
379
 
380
  /**
@@ -506,6 +495,18 @@ class MetaSlide {
506
  return false;
507
  }
508
 
 
 
 
 
 
 
 
 
 
 
 
 
509
 
510
  /**
511
  * Get the thumbnail for the slide
266
  // Set the image to the slide
267
  set_post_thumbnail($slide_id, $media_id);
268
 
 
 
 
 
 
 
 
 
 
 
 
 
269
  $this->add_or_update_or_delete_meta($slide_id, 'type', $type);
270
  return $slide_id;
271
  }
362
  * @return string The html for the edit button on a slide image
363
  */
364
  public function get_update_image_button_html() {
365
+ $attachment_id = $this->get_attachment_id();
366
+ return "<button class='update-image alignright' data-button-text='" . __("Update slide image", "ml-slider") . "' title='" . __("Update slide image", "ml-slider") . "' data-slide-id='{$this->slide->ID}' data-attachment-id='{$attachment_id}'><i><svg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-edit-2'><polygon points='16 3 21 8 8 21 3 21 3 16 16 3'/></svg></i></button>";
367
  }
368
 
369
  /**
495
  return false;
496
  }
497
 
498
+ /**
499
+ * Get the attachment ID
500
+ *
501
+ * @return Integer - the attachment ID
502
+ */
503
+ public function get_attachment_id() {
504
+ if ('attachment' == $this->slide->post_type) {
505
+ return $this->slide->ID;
506
+ } else {
507
+ return get_post_thumbnail_id($this->slide->ID);
508
+ }
509
+ }
510
 
511
  /**
512
  * Get the thumbnail for the slide
inc/slide/metaslide.image.class.php CHANGED
@@ -79,12 +79,18 @@ class MetaImageSlide extends MetaSlide {
79
  $slide_id = $this->insert_slide($data['id'], $data['type'], $slider_id);
80
  if (is_wp_error($slide_id)) {
81
  return $slide_id;
82
- }
83
-
 
84
  // TODO refactor these and investigate why they are needed (legacy?)
85
  $this->set_slide($slide_id);
86
  $this->set_slider($slider_id);
87
  $this->tag_slide_to_slider();
 
 
 
 
 
88
 
89
  // TODO investigate if this is really needed
90
  $this->settings['width'] = 0;
@@ -178,10 +184,11 @@ class MetaImageSlide extends MetaSlide {
178
 
179
  // get some slide settings
180
  $thumb = $this->get_thumb();
181
- $slide_label = apply_filters( "metaslider_image_slide_label", __( "Image Slide", "ml-slider" ), $this->slide, $this->settings );
182
-
 
183
  // slide row HTML
184
- $row = "<tr id='slide-{$this->slide->ID}' class='slide image flex responsive nivo coin'>
185
  <td class='col-1'>
186
  <div class='metaslider-ui-controls ui-sortable-handle'>
187
  <h4 class='slide-details'>{$slide_label}</h4>";
@@ -197,7 +204,7 @@ class MetaImageSlide extends MetaSlide {
197
  }
198
  $row .= "</div>
199
  <div class='metaslider-ui-inner'>
200
- <button class='update-image image-button' data-button-text='" . __("Update slide image", "ml-slider") . "' title='" . __("Update slide image", "ml-slider") . "' data-slide-id='{$this->slide->ID}'>
201
  <div class='thumb' style='background-image: url({$thumb})'></div>
202
  </button>
203
  </div>
@@ -221,63 +228,81 @@ class MetaImageSlide extends MetaSlide {
221
  */
222
  public function get_admin_tabs() {
223
 
224
- $slide_id = absint( $this->slide->ID);
225
- $alt = esc_attr( get_post_meta( $slide_id, '_wp_attachment_image_alt', true ) );
226
- $url = esc_attr( get_post_meta( $slide_id, 'ml-slider_url', true ) );
227
- $title = esc_attr( get_post_meta( $slide_id, 'ml-slider_title', true ) );
228
- $target = get_post_meta( $slide_id, 'ml-slider_new_window', true ) ? 'checked=checked' : '';
229
- $caption = esc_textarea( $this->slide->post_excerpt );
230
-
231
- $general_tab = "<textarea name='attachment[{$slide_id}][post_excerpt]' placeholder='" . __( "Caption", "ml-slider" ) . "'>{$caption}</textarea>
232
- <input class='url' type='text' name='attachment[{$slide_id}][url]' placeholder='" . __( "URL", "ml-slider" ) . "' value='{$url}' />
233
- <div class='new_window'>
234
- <label>" . __( "New Window", "ml-slider" ) . "<input tabindex='0' type='checkbox' name='attachment[{$slide_id}][new_window]' {$target} /></label>
235
- </div>";
236
 
237
- if ( ! $this->is_valid_image() ) {
238
- $message = __( "Warning: Image data does not exist. Please re-upload the image.", "ml-slider" );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
  $general_tab = "<div class='warning'>{$message}</div>" . $general_tab;
241
  }
242
 
243
- $seo_tab = sprintf("<div class='row'><label>%s</label><input tabindex='0' type='text' size='50' name='attachment[%s][title]' value='%s'></div><div class='row'><label>%s</label><input tabindex='0' type='text' size='50' name='attachment[%s][alt]' value='%s'></div>", __("Image Title Text", "ml-slider"), $slide_id, $title, __("Image Alt Text", "ml-slider"), $slide_id, $alt);
 
 
244
 
245
  $tabs = array(
246
  'general' => array(
247
- 'title' => __( "General", "ml-slider" ),
248
  'content' => $general_tab
249
  ),
250
  'seo' => array(
251
- 'title' => __( "SEO", "ml-slider" ),
252
  'content' => $seo_tab
253
  )
254
  );
255
 
256
- if ( version_compare( get_bloginfo('version'), 3.9, '>=' ) ) {
257
 
258
- $crop_position = get_post_meta( $slide_id, 'ml-slider_crop_position', true);
259
 
260
- if ( ! $crop_position ) {
261
  $crop_position = 'center-center';
262
  }
263
 
264
- $crop_tab = "<div class='row'><label>" . __( "Crop Position", "ml-slider" ) . "</label></div>
265
- <div class='row'>
266
- <select class='crop_position' name='attachment[{$slide_id}][crop_position]'>
267
- <option value='left-top' " . selected( $crop_position, 'left-top', false ) . ">" . __( "Top Left", "ml-slider" ) . "</option>
268
- <option value='center-top' " . selected( $crop_position, 'center-top', false ) . ">" . __( "Top Center", "ml-slider" ) . "</option>
269
- <option value='right-top' " . selected( $crop_position, 'right-top', false ) . ">" . __( "Top Right", "ml-slider" ) . "</option>
270
- <option value='left-center' " . selected( $crop_position, 'left-center', false ) . ">" . __( "Center Left", "ml-slider" ) . "</option>
271
- <option value='center-center' " . selected( $crop_position, 'center-center', false ) . ">" . __( "Center Center", "ml-slider" ) . "</option>
272
- <option value='right-center' " . selected( $crop_position, 'right-center', false ) . ">" . __( "Center Right", "ml-slider" ) . "</option>
273
- <option value='left-bottom' " . selected( $crop_position, 'left-bottom', false ) . ">" . __( "Bottom Left", "ml-slider" ) . "</option>
274
- <option value='center-bottom' " . selected( $crop_position, 'center-bottom', false ) . ">" . __( "Bottom Center", "ml-slider" ) . "</option>
275
- <option value='right-bottom' " . selected( $crop_position, 'right-bottom', false ) . ">" . __( "Bottom Right", "ml-slider" ) . "</option>
276
- </select>
277
- </div>";
278
-
279
  $tabs['crop'] = array(
280
- 'title' => __( "Crop", "ml-slider" ),
281
  'content' => $crop_tab
282
  );
283
 
@@ -336,55 +361,73 @@ class MetaImageSlide extends MetaSlide {
336
  $this->slide->ID,
337
  $this->settings['width'],
338
  $this->settings['height'],
339
- isset( $this->settings['smartCrop'] ) ? $this->settings['smartCrop'] : 'false',
340
  $this->use_wp_image_editor()
341
  );
342
 
343
  $thumb = $imageHelper->get_image_url();
344
-
345
- if ( $this->detect_self_metaslider_shortcode( $this->slide->post_excerpt ) ) {
346
- $caption = str_replace( array( "[metaslider", "[ml-slider" ), "[metaslider-disabled", $this->slide->post_excerpt );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  } else {
348
- $caption = $this->slide->post_excerpt;
349
  }
 
 
350
 
351
  // store the slide details
352
  $slide = array(
353
  'id' => $this->slide->ID,
354
- 'url' => __( get_post_meta( $this->slide->ID, 'ml-slider_url', true ) ),
355
- 'title' => __( get_post_meta( $this->slide->ID, 'ml-slider_title', true ) ),
356
- 'target' => get_post_meta( $this->slide->ID, 'ml-slider_new_window', true ) ? '_blank' : '_self',
357
  'src' => $thumb,
358
  'thumb' => $thumb, // backwards compatibility with Vantage
359
  'width' => $this->settings['width'],
360
  'height' => $this->settings['height'],
361
- 'alt' => __( get_post_meta( $this->slide->ID, '_wp_attachment_image_alt', true ) ),
362
- 'caption' => __( html_entity_decode( do_shortcode( $caption ), ENT_NOQUOTES, 'UTF-8' ) ),
363
- 'caption_raw' => __( do_shortcode( $caption ) ),
364
  'class' => "slider-{$this->slider->ID} slide-{$this->slide->ID}",
365
  'rel' => "",
366
  'data-thumb' => ""
367
  );
368
 
369
  // fix slide URLs
370
- if ( strpos( $slide['url'], 'www.' ) === 0 ) {
371
  $slide['url'] = 'http://' . $slide['url'];
372
  }
373
 
374
- $slide = apply_filters( 'metaslider_image_slide_attributes', $slide, $this->slider->ID, $this->settings );
375
 
376
  // return the slide HTML
377
- switch ( $this->settings['type'] ) {
378
  case "coin":
379
- return $this->get_coin_slider_markup( $slide );
380
  case "flex":
381
- return $this->get_flex_slider_markup( $slide );
382
  case "nivo":
383
- return $this->get_nivo_slider_markup( $slide );
384
  case "responsive":
385
- return $this->get_responsive_slides_markup( $slide );
386
  default:
387
- return $this->get_flex_slider_markup( $slide );
388
  }
389
 
390
  }
@@ -395,9 +438,9 @@ class MetaImageSlide extends MetaSlide {
395
  * @param string $slide html
396
  * @return string slide html
397
  */
398
- private function get_nivo_slider_markup( $slide ) {
399
 
400
- $attributes = apply_filters( 'metaslider_nivo_slider_image_attributes', array(
401
  'src' => $slide['src'],
402
  'height' => $slide['height'],
403
  'width' => $slide['width'],
@@ -409,18 +452,18 @@ class MetaImageSlide extends MetaSlide {
409
  'class' => $slide['class']
410
  ), $slide, $this->slider->ID );
411
 
412
- $html = $this->build_image_tag( $attributes );
413
 
414
- $anchor_attributes = apply_filters( 'metaslider_nivo_slider_anchor_attributes', array(
415
  'href' => $slide['url'],
416
  'target' => $slide['target']
417
- ), $slide, $this->slider->ID );
418
 
419
- if ( strlen( $anchor_attributes['href'] ) ) {
420
- $html = $this->build_anchor_tag( $anchor_attributes, $html );
421
  }
422
 
423
- return apply_filters( 'metaslider_image_nivo_slider_markup', $html, $slide, $this->settings );
424
 
425
  }
426
 
@@ -611,27 +654,56 @@ class MetaImageSlide extends MetaSlide {
611
  protected function save( $fields ) {
612
 
613
  // update the slide
614
- wp_update_post( array(
615
  'ID' => $this->slide->ID,
616
  'post_excerpt' => $fields['post_excerpt'],
617
  'menu_order' => $fields['menu_order']
618
- ) );
619
 
620
  // store the URL as a meta field against the attachment
621
- $this->add_or_update_or_delete_meta( $this->slide->ID, 'url', $fields['url'] );
622
 
623
- $this->add_or_update_or_delete_meta( $this->slide->ID, 'title', $fields['title'] );
624
 
625
- $this->add_or_update_or_delete_meta( $this->slide->ID, 'crop_position', $fields['crop_position'] );
626
 
627
- if ( isset( $fields['alt'] ) ) {
628
- update_post_meta( $this->slide->ID, '_wp_attachment_image_alt', $fields['alt'] );
 
 
 
 
 
629
  }
630
 
631
  // store the 'new window' setting
632
- $new_window = isset( $fields['new_window'] ) && $fields['new_window'] == 'on' ? 'true' : 'false';
 
 
633
 
634
- $this->add_or_update_or_delete_meta( $this->slide->ID, 'new_window', $new_window );
635
 
 
 
 
 
 
 
 
 
636
  }
637
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  $slide_id = $this->insert_slide($data['id'], $data['type'], $slider_id);
80
  if (is_wp_error($slide_id)) {
81
  return $slide_id;
82
+ }
83
+
84
+
85
  // TODO refactor these and investigate why they are needed (legacy?)
86
  $this->set_slide($slide_id);
87
  $this->set_slider($slider_id);
88
  $this->tag_slide_to_slider();
89
+
90
+ // set default inherit values
91
+ $this->set_field_inherited('caption', true);
92
+ $this->set_field_inherited('title', true);
93
+ $this->set_field_inherited('alt', true);
94
 
95
  // TODO investigate if this is really needed
96
  $this->settings['width'] = 0;
184
 
185
  // get some slide settings
186
  $thumb = $this->get_thumb();
187
+ $slide_label = apply_filters("metaslider_image_slide_label", __("Image Slide", "ml-slider"), $this->slide, $this->settings);
188
+ $attachment_id = $this->get_attachment_id();
189
+
190
  // slide row HTML
191
+ $row = "<tr id='slide-{$this->slide->ID}' class='slide image flex responsive nivo coin' data-attachment-id='{$attachment_id}'>
192
  <td class='col-1'>
193
  <div class='metaslider-ui-controls ui-sortable-handle'>
194
  <h4 class='slide-details'>{$slide_label}</h4>";
204
  }
205
  $row .= "</div>
206
  <div class='metaslider-ui-inner'>
207
+ <button class='update-image image-button' data-button-text='" . __("Update slide image", "ml-slider") . "' title='" . __("Update slide image", "ml-slider") . "' data-slide-id='{$this->slide->ID}' data-attachment-id='{$attachment_id}'>
208
  <div class='thumb' style='background-image: url({$thumb})'></div>
209
  </button>
210
  </div>
228
  */
229
  public function get_admin_tabs() {
230
 
231
+ $slide_id = absint($this->slide->ID);
232
+ $attachment_id = $this->get_attachment_id();
233
+ $attachment = get_post($attachment_id);
 
 
 
 
 
 
 
 
 
234
 
235
+ $url = esc_attr(get_post_meta($slide_id, 'ml-slider_url', true));
236
+ $target = get_post_meta($slide_id, 'ml-slider_new_window', true) ? 'checked=checked' : '';
237
+
238
+ // TODO: make this DRY
239
+ // caption
240
+ $caption = esc_textarea($this->slide->post_excerpt);
241
+ $image_caption = html_entity_decode($attachment->post_excerpt, ENT_NOQUOTES, 'UTF-8');
242
+ $inherit_image_caption_check = '';
243
+ $inherit_image_caption_class = '';
244
+ if ($this->is_field_inherited('caption')) {
245
+ $inherit_image_caption_check = 'checked=checked';
246
+ $inherit_image_caption_class = ' inherit-from-image';
247
+ }
248
+ // alt
249
+ $alt = esc_attr(get_post_meta($slide_id, '_wp_attachment_image_alt', true));
250
+ $image_alt = esc_attr(get_post_meta($attachment_id, '_wp_attachment_image_alt', true ));
251
+ $inherit_image_alt_check = '';
252
+ $inherit_image_alt_class = '';
253
+ if ($this->is_field_inherited('alt')) {
254
+ $inherit_image_alt_check = 'checked=checked';
255
+ $inherit_image_alt_class = ' inherit-from-image';
256
+ }
257
+ // title
258
+ $title = esc_attr(get_post_meta($slide_id, 'ml-slider_title', true));
259
+ $image_title = esc_attr($attachment->post_title);
260
+ $inherit_image_title_check = '';
261
+ $inherit_image_title_class = '';
262
+ if ($this->is_field_inherited('title')) {
263
+ $inherit_image_title_check = 'checked=checked';
264
+ $inherit_image_title_class = ' inherit-from-image';
265
+ }
266
+
267
+ ob_start();
268
+ include(METASLIDER_PATH . 'admin/views/slides/tabs/general.php');
269
+ $general_tab = ob_get_clean();
270
+
271
+ if (!$this->is_valid_image()) {
272
+ $message = __("Warning: The image data does not exist. Please re-upload the image.", "ml-slider");
273
 
274
  $general_tab = "<div class='warning'>{$message}</div>" . $general_tab;
275
  }
276
 
277
+ ob_start();
278
+ include(METASLIDER_PATH .'admin/views/slides/tabs/seo.php');
279
+ $seo_tab = ob_get_clean();
280
 
281
  $tabs = array(
282
  'general' => array(
283
+ 'title' => __("General", "ml-slider"),
284
  'content' => $general_tab
285
  ),
286
  'seo' => array(
287
+ 'title' => __("SEO", "ml-slider"),
288
  'content' => $seo_tab
289
  )
290
  );
291
 
292
+ if (version_compare(get_bloginfo('version'), 3.9, '>=')) {
293
 
294
+ $crop_position = get_post_meta($slide_id, 'ml-slider_crop_position', true);
295
 
296
+ if (!$crop_position) {
297
  $crop_position = 'center-center';
298
  }
299
 
300
+ ob_start();
301
+ include(METASLIDER_PATH .'admin/views/slides/tabs/crop.php');
302
+ $crop_tab = ob_get_clean();
303
+
 
 
 
 
 
 
 
 
 
 
 
304
  $tabs['crop'] = array(
305
+ 'title' => __("Crop", "ml-slider"),
306
  'content' => $crop_tab
307
  );
308
 
361
  $this->slide->ID,
362
  $this->settings['width'],
363
  $this->settings['height'],
364
+ isset($this->settings['smartCrop']) ? $this->settings['smartCrop'] : 'false',
365
  $this->use_wp_image_editor()
366
  );
367
 
368
  $thumb = $imageHelper->get_image_url();
369
+ $attachment_id = get_post_thumbnail_id($this->slide->ID);
370
+ $attachment = get_post($attachment_id);
371
+ if ($this->is_field_inherited('caption')) {
372
+ $caption = $attachment->post_excerpt;
373
+ } else {
374
+ $caption = $this->slide->post_excerpt;
375
+ }
376
+ if ($this->detect_self_metaslider_shortcode($this->slide->post_excerpt)) {
377
+ $caption = str_replace(array("[metaslider", "[ml-slider"), "[metaslider-disabled", $this->slide->post_excerpt);
378
+ }
379
+
380
+ if ($this->is_field_inherited('title')) {
381
+ $title = $attachment->post_title;
382
+ } else {
383
+ $title = get_post_meta($this->slide->ID, 'ml-slider_title', true);
384
+ }
385
+
386
+ if ($this->is_field_inherited('alt')) {
387
+ $alt = get_post_meta($attachment_id, '_wp_attachment_image_alt', true);
388
  } else {
389
+ $alt = get_post_meta($this->slide->ID, '_wp_attachment_image_alt', true);
390
  }
391
+
392
+
393
 
394
  // store the slide details
395
  $slide = array(
396
  'id' => $this->slide->ID,
397
+ 'url' => get_post_meta($this->slide->ID, 'ml-slider_url', true),
398
+ 'title' => $title,
399
+ 'target' => get_post_meta($this->slide->ID, 'ml-slider_new_window', true) ? '_blank' : '_self',
400
  'src' => $thumb,
401
  'thumb' => $thumb, // backwards compatibility with Vantage
402
  'width' => $this->settings['width'],
403
  'height' => $this->settings['height'],
404
+ 'alt' => $alt,
405
+ 'caption' => html_entity_decode(do_shortcode($caption), ENT_NOQUOTES, 'UTF-8'),
406
+ 'caption_raw' => do_shortcode($caption),
407
  'class' => "slider-{$this->slider->ID} slide-{$this->slide->ID}",
408
  'rel' => "",
409
  'data-thumb' => ""
410
  );
411
 
412
  // fix slide URLs
413
+ if (strpos($slide['url'], 'www.') === 0) {
414
  $slide['url'] = 'http://' . $slide['url'];
415
  }
416
 
417
+ $slide = apply_filters('metaslider_image_slide_attributes', $slide, $this->slider->ID, $this->settings);
418
 
419
  // return the slide HTML
420
+ switch ($this->settings['type']) {
421
  case "coin":
422
+ return $this->get_coin_slider_markup($slide);
423
  case "flex":
424
+ return $this->get_flex_slider_markup($slide);
425
  case "nivo":
426
+ return $this->get_nivo_slider_markup($slide);
427
  case "responsive":
428
+ return $this->get_responsive_slides_markup($slide);
429
  default:
430
+ return $this->get_flex_slider_markup($slide);
431
  }
432
 
433
  }
438
  * @param string $slide html
439
  * @return string slide html
440
  */
441
+ private function get_nivo_slider_markup($slide) {
442
 
443
+ $attributes = apply_filters('metaslider_nivo_slider_image_attributes', array(
444
  'src' => $slide['src'],
445
  'height' => $slide['height'],
446
  'width' => $slide['width'],
452
  'class' => $slide['class']
453
  ), $slide, $this->slider->ID );
454
 
455
+ $html = $this->build_image_tag($attributes);
456
 
457
+ $anchor_attributes = apply_filters('metaslider_nivo_slider_anchor_attributes', array(
458
  'href' => $slide['url'],
459
  'target' => $slide['target']
460
+ ), $slide, $this->slider->ID);
461
 
462
+ if (strlen( $anchor_attributes['href'])) {
463
+ $html = $this->build_anchor_tag($anchor_attributes, $html);
464
  }
465
 
466
+ return apply_filters('metaslider_image_nivo_slider_markup', $html, $slide, $this->settings);
467
 
468
  }
469
 
654
  protected function save( $fields ) {
655
 
656
  // update the slide
657
+ wp_update_post(array(
658
  'ID' => $this->slide->ID,
659
  'post_excerpt' => $fields['post_excerpt'],
660
  'menu_order' => $fields['menu_order']
661
+ ));
662
 
663
  // store the URL as a meta field against the attachment
664
+ $this->add_or_update_or_delete_meta($this->slide->ID, 'url', $fields['url']);
665
 
666
+ $this->add_or_update_or_delete_meta($this->slide->ID, 'title', $fields['title']);
667
 
668
+ $this->add_or_update_or_delete_meta($this->slide->ID, 'crop_position', $fields['crop_position']);
669
 
670
+ // store the inherit custom caption, title and alt settings
671
+ $this->set_field_inherited('title', isset($fields['inherit_image_title']));
672
+ $this->set_field_inherited('caption', isset($fields['inherit_image_caption']));
673
+ $this->set_field_inherited('alt', isset($fields['inherit_image_alt']));
674
+
675
+ if (isset($fields['alt'])) {
676
+ update_post_meta($this->slide->ID, '_wp_attachment_image_alt', $fields['alt']);
677
  }
678
 
679
  // store the 'new window' setting
680
+ $new_window = isset($fields['new_window']) ? 'true' : 'false';
681
+
682
+ $this->add_or_update_or_delete_meta($this->slide->ID, 'new_window', $new_window);
683
 
684
+ }
685
 
686
+ /**
687
+ * Gets the inheritn parameter of a field
688
+ *
689
+ * @param string $field Field to check
690
+ * @return bool
691
+ */
692
+ private function is_field_inherited($field) {
693
+ return (bool) get_post_meta($this->slide->ID, 'ml-slider_inherit_image_' . $field, true);
694
  }
695
+
696
+ /**
697
+ * Sets the inherit parameter of a field.
698
+ *
699
+ * @param string $field Field to set
700
+ * @param bool $value Value is currently isset($fields['checkbox_parameter'])
701
+ * @return mixed Returns meta_id if the meta doesn't exist, otherwise returns true on success and false on failure. NOTE: If the meta_value passed to this function is the same as the value that is already in the database, this function returns false.
702
+ */
703
+ private function set_field_inherited($field, $value) {
704
+
705
+ // TODO eventually I would like to handle errors / successful updates to the database even if just sending it to a log file
706
+ return update_post_meta($this->slide->ID, 'ml-slider_inherit_image_' . $field, (bool) $value);
707
+ }
708
+
709
+ }
languages/ml-slider.pot CHANGED
@@ -97,10 +97,6 @@ msgstr ""
97
  msgid "If you could spare a minute, we would like to ask you 4 easy questions about how you use MetaSlider. Your voice is important to us!"
98
  msgstr ""
99
 
100
- #: src/admin/Notices.php:189
101
- msgid "forever"
102
- msgstr ""
103
-
104
  #: src/admin/Notices.php:205
105
  msgid "Black Friday - 50% off the MetaSlider Add-on Pack until November 30th"
106
  msgstr ""
@@ -153,115 +149,115 @@ msgstr ""
153
  msgid "is a highly efficient way to manage, update and backup multiple websites from one place."
154
  msgstr ""
155
 
156
- #: src/admin/Notices.php:537
157
  msgid "weeks"
158
  msgstr ""
159
 
160
- #: src/admin/Notices.php:553
161
  msgid "Get UpdraftPlus"
162
  msgstr ""
163
 
164
- #: src/admin/Notices.php:554
165
  msgid "Get Keyy"
166
  msgstr ""
167
 
168
- #: src/admin/Notices.php:555
169
  msgid "Optimize today"
170
  msgstr ""
171
 
172
- #: src/admin/Notices.php:556
173
  msgid "Get UpdraftCentral"
174
  msgstr ""
175
 
176
- #: src/admin/Notices.php:557
177
  msgid "Let's Start"
178
  msgstr ""
179
 
180
- #: src/admin/Notices.php:558
181
  msgid "Review MetaSlider"
182
  msgstr ""
183
 
184
- #: src/admin/Notices.php:559
185
  msgid "Find out more"
186
  msgstr ""
187
 
188
- #: src/admin/Notices.php:560
189
  msgid "Sign up"
190
  msgstr ""
191
 
192
- #: src/admin/Notices.php:561
193
  msgid "Go there"
194
  msgstr ""
195
 
196
- #: src/admin/Notices.php:563
197
  msgid "Read more"
198
  msgstr ""
199
 
200
- #: src/admin/Notices.php:577, src/admin/Tour.php:123, src/inc/slide/metaslide.class.php:120, src/inc/slide/metaslide.image.class.php:107, src/ml-slider.php:638, src/ml-slider.php:687
201
  msgid "The security check failed. Please refresh the page and try again."
202
  msgstr ""
203
 
204
- #: src/admin/Notices.php:583
205
  msgid "This item does not exist. Please refresh the page and try again."
206
  msgstr ""
207
 
208
- #: src/admin/Notices.php:596
209
  msgid "The option was successfully updated"
210
  msgstr ""
211
 
212
- #: src/admin/Notices.php:653
213
  msgid "The requested data does not exist."
214
  msgstr ""
215
 
216
- #: src/admin/Notices.php:677
217
  msgid "The attempt to update the option failed."
218
  msgstr ""
219
 
220
- #: src/admin/Pages.php:77, src/inc/slide/metaslide.image.class.php:232
221
  msgid "URL"
222
  msgstr ""
223
 
224
- #: src/admin/Pages.php:78, src/inc/slide/metaslide.image.class.php:231
225
  msgid "Caption"
226
  msgstr ""
227
 
228
- #: src/admin/Pages.php:79, src/inc/slide/metaslide.image.class.php:234
229
  msgid "New Window"
230
  msgstr ""
231
 
232
- #: src/admin/Pages.php:80
233
  msgid "Are you sure?"
234
  msgstr ""
235
 
236
- #: src/admin/Pages.php:81
237
  msgid "Undo"
238
  msgstr ""
239
 
240
- #: src/admin/Pages.php:82
241
  msgid "Slide restored"
242
  msgstr ""
243
 
244
- #: src/admin/Pages.php:83
245
  msgid "Slide deleted"
246
  msgstr ""
247
 
248
- #: src/admin/Pages.php:84
249
  msgid "Success"
250
  msgstr ""
251
 
252
- #: src/admin/Pages.php:85
253
  msgid "Item was copied to your clipboard"
254
  msgstr ""
255
 
256
- #: src/admin/Pages.php:86
257
  msgid "Press to undo"
258
  msgstr ""
259
 
260
- #: src/admin/Pages.php:88
261
  msgid "Select replacement image"
262
  msgstr ""
263
 
264
- #: src/admin/Pages.php:96
265
  msgid "Caution: This setting is for advanced developers only. If you're unsure, leave it checked."
266
  msgstr ""
267
 
@@ -365,7 +361,7 @@ msgstr ""
365
  msgid "free"
366
  msgstr ""
367
 
368
- #: src/admin/views/pages/upgrade.php:21, src/ml-slider.php:319, src/ml-slider.php:1959
369
  msgid "Add-ons"
370
  msgstr ""
371
 
@@ -557,6 +553,86 @@ msgstr ""
557
  msgid "Logging in with %s is simple. Once users have installed the app onto their smartphone and secured it using a fingerprint or 4-number pin, they just open the app, point it at the moving on-screen barcode and voila!"
558
  msgstr ""
559
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
  #: src/inc/metaslider.widget.class.php:18
561
  msgid "MetaSlider"
562
  msgstr ""
@@ -593,11 +669,11 @@ msgstr ""
593
  msgid "There was an error while updating the database. Please try again."
594
  msgstr ""
595
 
596
- #: src/inc/slide/metaslide.class.php:347
597
  msgid "Delete Slide"
598
  msgstr ""
599
 
600
- #: src/inc/slide/metaslide.class.php:377, src/inc/slide/metaslide.class.php:377, src/inc/slide/metaslide.image.class.php:200, src/inc/slide/metaslide.image.class.php:200
601
  msgid "Update slide image"
602
  msgstr ""
603
 
@@ -609,71 +685,23 @@ msgstr ""
609
  msgid "This isn't an accepted image. Please try again."
610
  msgstr ""
611
 
612
- #: src/inc/slide/metaslide.image.class.php:181
613
  msgid "Image Slide"
614
  msgstr ""
615
 
616
- #: src/inc/slide/metaslide.image.class.php:238
617
- msgid "Warning: Image data does not exist. Please re-upload the image."
618
- msgstr ""
619
-
620
- #: src/inc/slide/metaslide.image.class.php:243
621
- msgid "Image Title Text"
622
- msgstr ""
623
-
624
- #: src/inc/slide/metaslide.image.class.php:243
625
- msgid "Image Alt Text"
626
  msgstr ""
627
 
628
- #: src/inc/slide/metaslide.image.class.php:247
629
  msgid "General"
630
  msgstr ""
631
 
632
- #: src/inc/slide/metaslide.image.class.php:251
633
  msgid "SEO"
634
  msgstr ""
635
 
636
- #: src/inc/slide/metaslide.image.class.php:264
637
- msgid "Crop Position"
638
- msgstr ""
639
-
640
- #: src/inc/slide/metaslide.image.class.php:267
641
- msgid "Top Left"
642
- msgstr ""
643
-
644
- #: src/inc/slide/metaslide.image.class.php:268
645
- msgid "Top Center"
646
- msgstr ""
647
-
648
- #: src/inc/slide/metaslide.image.class.php:269
649
- msgid "Top Right"
650
- msgstr ""
651
-
652
- #: src/inc/slide/metaslide.image.class.php:270
653
- msgid "Center Left"
654
- msgstr ""
655
-
656
- #: src/inc/slide/metaslide.image.class.php:271
657
- msgid "Center Center"
658
- msgstr ""
659
-
660
- #: src/inc/slide/metaslide.image.class.php:272
661
- msgid "Center Right"
662
- msgstr ""
663
-
664
- #: src/inc/slide/metaslide.image.class.php:273
665
- msgid "Bottom Left"
666
- msgstr ""
667
-
668
- #: src/inc/slide/metaslide.image.class.php:274
669
- msgid "Bottom Center"
670
- msgstr ""
671
-
672
- #: src/inc/slide/metaslide.image.class.php:275
673
- msgid "Bottom Right"
674
- msgstr ""
675
-
676
- #: src/inc/slide/metaslide.image.class.php:280
677
  msgid "Crop"
678
  msgstr ""
679
 
@@ -1189,12 +1217,12 @@ msgstr ""
1189
  msgid "Take a tour"
1190
  msgstr ""
1191
 
1192
- #: src/ml-slider.php:1960
1193
- msgid "Support"
1194
  msgstr ""
1195
 
1196
  #: src/ml-slider.php:1962
1197
- msgid "Premium Support"
1198
  msgstr ""
1199
 
1200
  #: src/ml-slider.php:1964, src/ml-slider.php:2042
97
  msgid "If you could spare a minute, we would like to ask you 4 easy questions about how you use MetaSlider. Your voice is important to us!"
98
  msgstr ""
99
 
 
 
 
 
100
  #: src/admin/Notices.php:205
101
  msgid "Black Friday - 50% off the MetaSlider Add-on Pack until November 30th"
102
  msgstr ""
149
  msgid "is a highly efficient way to manage, update and backup multiple websites from one place."
150
  msgstr ""
151
 
152
+ #: src/admin/Notices.php:527
153
  msgid "weeks"
154
  msgstr ""
155
 
156
+ #: src/admin/Notices.php:543
157
  msgid "Get UpdraftPlus"
158
  msgstr ""
159
 
160
+ #: src/admin/Notices.php:544
161
  msgid "Get Keyy"
162
  msgstr ""
163
 
164
+ #: src/admin/Notices.php:545
165
  msgid "Optimize today"
166
  msgstr ""
167
 
168
+ #: src/admin/Notices.php:546
169
  msgid "Get UpdraftCentral"
170
  msgstr ""
171
 
172
+ #: src/admin/Notices.php:547
173
  msgid "Let's Start"
174
  msgstr ""
175
 
176
+ #: src/admin/Notices.php:548
177
  msgid "Review MetaSlider"
178
  msgstr ""
179
 
180
+ #: src/admin/Notices.php:549
181
  msgid "Find out more"
182
  msgstr ""
183
 
184
+ #: src/admin/Notices.php:550
185
  msgid "Sign up"
186
  msgstr ""
187
 
188
+ #: src/admin/Notices.php:551
189
  msgid "Go there"
190
  msgstr ""
191
 
192
+ #: src/admin/Notices.php:553
193
  msgid "Read more"
194
  msgstr ""
195
 
196
+ #: src/admin/Notices.php:567, src/admin/Tour.php:123, src/inc/slide/metaslide.class.php:120, src/inc/slide/metaslide.image.class.php:113, src/ml-slider.php:638, src/ml-slider.php:687
197
  msgid "The security check failed. Please refresh the page and try again."
198
  msgstr ""
199
 
200
+ #: src/admin/Notices.php:573
201
  msgid "This item does not exist. Please refresh the page and try again."
202
  msgstr ""
203
 
204
+ #: src/admin/Notices.php:586
205
  msgid "The option was successfully updated"
206
  msgstr ""
207
 
208
+ #: src/admin/Notices.php:643
209
  msgid "The requested data does not exist."
210
  msgstr ""
211
 
212
+ #: src/admin/Notices.php:667
213
  msgid "The attempt to update the option failed."
214
  msgstr ""
215
 
216
+ #: src/admin/Pages.php:69, src/admin/views/slides/tabs/general.php:13
217
  msgid "URL"
218
  msgstr ""
219
 
220
+ #: src/admin/Pages.php:70, src/admin/views/slides/tabs/general.php:3
221
  msgid "Caption"
222
  msgstr ""
223
 
224
+ #: src/admin/Pages.php:71
225
  msgid "New Window"
226
  msgstr ""
227
 
228
+ #: src/admin/Pages.php:72
229
  msgid "Are you sure?"
230
  msgstr ""
231
 
232
+ #: src/admin/Pages.php:73
233
  msgid "Undo"
234
  msgstr ""
235
 
236
+ #: src/admin/Pages.php:74
237
  msgid "Slide restored"
238
  msgstr ""
239
 
240
+ #: src/admin/Pages.php:75
241
  msgid "Slide deleted"
242
  msgstr ""
243
 
244
+ #: src/admin/Pages.php:76
245
  msgid "Success"
246
  msgstr ""
247
 
248
+ #: src/admin/Pages.php:77
249
  msgid "Item was copied to your clipboard"
250
  msgstr ""
251
 
252
+ #: src/admin/Pages.php:78
253
  msgid "Press to undo"
254
  msgstr ""
255
 
256
+ #: src/admin/Pages.php:80
257
  msgid "Select replacement image"
258
  msgstr ""
259
 
260
+ #: src/admin/Pages.php:88
261
  msgid "Caution: This setting is for advanced developers only. If you're unsure, leave it checked."
262
  msgstr ""
263
 
361
  msgid "free"
362
  msgstr ""
363
 
364
+ #: src/admin/views/pages/upgrade.php:21, src/ml-slider.php:319, src/ml-slider.php:1961
365
  msgid "Add-ons"
366
  msgstr ""
367
 
553
  msgid "Logging in with %s is simple. Once users have installed the app onto their smartphone and secured it using a fingerprint or 4-number pin, they just open the app, point it at the moving on-screen barcode and voila!"
554
  msgstr ""
555
 
556
+ #: src/admin/views/slides/tabs/crop.php:3
557
+ msgid "Crop Position"
558
+ msgstr ""
559
+
560
+ #: src/admin/views/slides/tabs/crop.php:7
561
+ msgid "Top Left"
562
+ msgstr ""
563
+
564
+ #: src/admin/views/slides/tabs/crop.php:8
565
+ msgid "Top Center"
566
+ msgstr ""
567
+
568
+ #: src/admin/views/slides/tabs/crop.php:9
569
+ msgid "Top Right"
570
+ msgstr ""
571
+
572
+ #: src/admin/views/slides/tabs/crop.php:10
573
+ msgid "Center Left"
574
+ msgstr ""
575
+
576
+ #: src/admin/views/slides/tabs/crop.php:11
577
+ msgid "Center Center"
578
+ msgstr ""
579
+
580
+ #: src/admin/views/slides/tabs/crop.php:12
581
+ msgid "Center Right"
582
+ msgstr ""
583
+
584
+ #: src/admin/views/slides/tabs/crop.php:13
585
+ msgid "Bottom Left"
586
+ msgstr ""
587
+
588
+ #: src/admin/views/slides/tabs/crop.php:14
589
+ msgid "Bottom Center"
590
+ msgstr ""
591
+
592
+ #: src/admin/views/slides/tabs/crop.php:15
593
+ msgid "Bottom Right"
594
+ msgstr ""
595
+
596
+ #: src/admin/views/slides/tabs/general.php:5
597
+ msgid "Enable this to inherit the caption from the image"
598
+ msgstr ""
599
+
600
+ #: src/admin/views/slides/tabs/general.php:6
601
+ msgid "Use the image caption"
602
+ msgstr ""
603
+
604
+ #: src/admin/views/slides/tabs/general.php:9
605
+ msgid "No default caption set"
606
+ msgstr ""
607
+
608
+ #: src/admin/views/slides/tabs/general.php:15
609
+ msgid "Open in a new window"
610
+ msgstr ""
611
+
612
+ #: src/admin/views/slides/tabs/seo.php:5
613
+ msgid "Image Title Text"
614
+ msgstr ""
615
+
616
+ #: src/admin/views/slides/tabs/seo.php:7
617
+ msgid "Enable this to inherit the image title"
618
+ msgstr ""
619
+
620
+ #: src/admin/views/slides/tabs/seo.php:8
621
+ msgid "Use the image title"
622
+ msgstr ""
623
+
624
+ #: src/admin/views/slides/tabs/seo.php:15
625
+ msgid "Image Alt Text"
626
+ msgstr ""
627
+
628
+ #: src/admin/views/slides/tabs/seo.php:17
629
+ msgid "Enable this to inherit the image alt text"
630
+ msgstr ""
631
+
632
+ #: src/admin/views/slides/tabs/seo.php:18
633
+ msgid "Use the image alt text"
634
+ msgstr ""
635
+
636
  #: src/inc/metaslider.widget.class.php:18
637
  msgid "MetaSlider"
638
  msgstr ""
669
  msgid "There was an error while updating the database. Please try again."
670
  msgstr ""
671
 
672
+ #: src/inc/slide/metaslide.class.php:335
673
  msgid "Delete Slide"
674
  msgstr ""
675
 
676
+ #: src/inc/slide/metaslide.class.php:366, src/inc/slide/metaslide.class.php:366, src/inc/slide/metaslide.image.class.php:207, src/inc/slide/metaslide.image.class.php:207
677
  msgid "Update slide image"
678
  msgstr ""
679
 
685
  msgid "This isn't an accepted image. Please try again."
686
  msgstr ""
687
 
688
+ #: src/inc/slide/metaslide.image.class.php:187
689
  msgid "Image Slide"
690
  msgstr ""
691
 
692
+ #: src/inc/slide/metaslide.image.class.php:272
693
+ msgid "Warning: The image data does not exist. Please re-upload the image."
 
 
 
 
 
 
 
 
694
  msgstr ""
695
 
696
+ #: src/inc/slide/metaslide.image.class.php:283
697
  msgid "General"
698
  msgstr ""
699
 
700
+ #: src/inc/slide/metaslide.image.class.php:287
701
  msgid "SEO"
702
  msgstr ""
703
 
704
+ #: src/inc/slide/metaslide.image.class.php:305
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
705
  msgid "Crop"
706
  msgstr ""
707
 
1217
  msgid "Take a tour"
1218
  msgstr ""
1219
 
1220
+ #: src/ml-slider.php:1958
1221
+ msgid "Premium Support"
1222
  msgstr ""
1223
 
1224
  #: src/ml-slider.php:1962
1225
+ msgid "Support"
1226
  msgstr ""
1227
 
1228
  #: src/ml-slider.php:1964, src/ml-slider.php:2042
ml-slider.php CHANGED
@@ -6,7 +6,7 @@
6
  * Plugin Name: MetaSlider
7
  * Plugin URI: https://www.metaslider.com
8
  * Description: Easy to use slideshow plugin. Create SEO optimised responsive slideshows with Nivo Slider, Flex Slider, Coin Slider and Responsive Slides.
9
- * Version: 3.6.8
10
  * Author: Team Updraft
11
  * Author URI: https://www.metaslider.com
12
  * License: GPL-2.0+
@@ -34,7 +34,7 @@ class MetaSliderPlugin {
34
  *
35
  * @var string
36
  */
37
- public $version = '3.6.8';
38
 
39
  /**
40
  * The lowest tier price for upgrades
@@ -309,13 +309,13 @@ class MetaSliderPlugin {
309
  * Add the menu pages
310
  */
311
  public function register_admin_pages() {
312
- if (metaslider_is_pro_active()) {
313
  $this->admin->add_page('MetaSlider Pro', 'metaslider');
314
  } else {
315
  $this->admin->add_page('MetaSlider');
316
  }
317
 
318
- if (metaslider_sees_upgrade_page()) {
319
  $this->admin->add_page(__('Add-ons', 'ml-slider'), 'upgrade', 'metaslider');
320
  }
321
  }
@@ -1273,7 +1273,7 @@ class MetaSliderPlugin {
1273
  echo $this->documentation_button();
1274
  echo $this->toggle_layout_button();
1275
 
1276
- if (metaslider_sees_call_to_action()) {
1277
  echo $this->addons_page_button();
1278
  echo $this->upgrade_to_pro_top_button();
1279
  }
@@ -1293,11 +1293,11 @@ class MetaSliderPlugin {
1293
  <h1 class="wp-heading-inline metaslider-title">
1294
  <img width=50 height=50 src="<?php echo METASLIDER_ADMIN_URL ?>images/metaslider_logo_large.png" alt="MetaSlider">
1295
  MetaSlider
1296
- <?php if (metaslider_is_pro_active()) {
1297
  echo ' Pro';
1298
  } ?>
1299
  </h1>
1300
- <?php if (metaslider_sees_notices($this)) {
1301
  echo $this->notices->do_notice(false, 'header', true);
1302
  } ?>
1303
  <form accept-charset="UTF-8" action="<?php echo admin_url( 'admin-post.php'); ?>" method="post">
@@ -1954,12 +1954,12 @@ class MetaSliderPlugin {
1954
  if (plugin_basename(__FILE__) == $file) {
1955
  $plugin_page = admin_url('admin.php?page=metaslider');
1956
  $meta[] = "<a href='{$plugin_page}' onclick=\"event.preventDefault();var link = jQuery(this);jQuery.post(ajaxurl, {action: 'reset_tour_status', _wpnonce: metaslider_tour_nonce }, function(data) {window.location = link.attr('href');});\">" . __('Take a tour', 'ml-slider') . "</a>";
1957
- if (metaslider_is_pro_installed()) {
 
 
1958
  $upgrade_link = apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade/');
1959
  $meta[] = "<a href='{$upgrade_link}' target='_blank'>" . __('Add-ons', 'ml-slider') . "</a>";
1960
  $meta[] = "<a href='https://wordpress.org/support/plugin/ml-slider/' target='_blank'>" . __('Support', 'ml-slider') . "</a>";
1961
- } else {
1962
- $meta[] = "<a href='https://www.metaslider.com/support/' target='_blank'>" . __('Premium Support', 'ml-slider') . "</a>";
1963
  }
1964
  $meta[] = "<a href='https://www.metaslider.com/documentation/' target='_blank'>" . __('Documentation', 'ml-slider') . "</a>";
1965
  $meta[] = "<a href='https://wordpress.org/support/plugin/ml-slider/reviews#new-post' target='_blank' title='" . __('Leave a review', 'ml-slider') . "'><i class='ml-stars'><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg></i></a>";
@@ -1971,7 +1971,7 @@ class MetaSliderPlugin {
1971
  * Adds styles to admin head to allow for stars animation and coloring
1972
  */
1973
  public function add_star_styles() {
1974
- if (metaslider_is_on_admin_page('plugins.php')) {?>
1975
  <style>
1976
  .ml-stars{display:inline-block;color:#ffb900;position:relative;top:3px}
1977
  .ml-stars svg{fill:#ffb900}
@@ -1985,7 +1985,7 @@ class MetaSliderPlugin {
1985
  * Add nonce to activation pa
1986
  */
1987
  public function add_tour_nonce_to_activation_page() {
1988
- if (metaslider_is_on_admin_page('plugins.php')) {?>
1989
  <script>
1990
  var metaslider_tour_nonce = "<?php echo wp_create_nonce('metaslider_tour_nonce'); ?>";
1991
  </script>
6
  * Plugin Name: MetaSlider
7
  * Plugin URI: https://www.metaslider.com
8
  * Description: Easy to use slideshow plugin. Create SEO optimised responsive slideshows with Nivo Slider, Flex Slider, Coin Slider and Responsive Slides.
9
+ * Version: 3.7.0
10
  * Author: Team Updraft
11
  * Author URI: https://www.metaslider.com
12
  * License: GPL-2.0+
34
  *
35
  * @var string
36
  */
37
+ public $version = '3.7.0';
38
 
39
  /**
40
  * The lowest tier price for upgrades
309
  * Add the menu pages
310
  */
311
  public function register_admin_pages() {
312
+ if (metaslider_pro_is_active()) {
313
  $this->admin->add_page('MetaSlider Pro', 'metaslider');
314
  } else {
315
  $this->admin->add_page('MetaSlider');
316
  }
317
 
318
+ if (metaslider_user_sees_upgrade_page()) {
319
  $this->admin->add_page(__('Add-ons', 'ml-slider'), 'upgrade', 'metaslider');
320
  }
321
  }
1273
  echo $this->documentation_button();
1274
  echo $this->toggle_layout_button();
1275
 
1276
+ if (metaslider_user_sees_call_to_action()) {
1277
  echo $this->addons_page_button();
1278
  echo $this->upgrade_to_pro_top_button();
1279
  }
1293
  <h1 class="wp-heading-inline metaslider-title">
1294
  <img width=50 height=50 src="<?php echo METASLIDER_ADMIN_URL ?>images/metaslider_logo_large.png" alt="MetaSlider">
1295
  MetaSlider
1296
+ <?php if (metaslider_pro_is_active()) {
1297
  echo ' Pro';
1298
  } ?>
1299
  </h1>
1300
+ <?php if (metaslider_user_sees_notices($this)) {
1301
  echo $this->notices->do_notice(false, 'header', true);
1302
  } ?>
1303
  <form accept-charset="UTF-8" action="<?php echo admin_url( 'admin-post.php'); ?>" method="post">
1954
  if (plugin_basename(__FILE__) == $file) {
1955
  $plugin_page = admin_url('admin.php?page=metaslider');
1956
  $meta[] = "<a href='{$plugin_page}' onclick=\"event.preventDefault();var link = jQuery(this);jQuery.post(ajaxurl, {action: 'reset_tour_status', _wpnonce: metaslider_tour_nonce }, function(data) {window.location = link.attr('href');});\">" . __('Take a tour', 'ml-slider') . "</a>";
1957
+ if (metaslider_pro_is_installed()) {
1958
+ $meta[] = "<a href='https://www.metaslider.com/support/' target='_blank'>" . __('Premium Support', 'ml-slider') . "</a>";
1959
+ } else {
1960
  $upgrade_link = apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade/');
1961
  $meta[] = "<a href='{$upgrade_link}' target='_blank'>" . __('Add-ons', 'ml-slider') . "</a>";
1962
  $meta[] = "<a href='https://wordpress.org/support/plugin/ml-slider/' target='_blank'>" . __('Support', 'ml-slider') . "</a>";
 
 
1963
  }
1964
  $meta[] = "<a href='https://www.metaslider.com/documentation/' target='_blank'>" . __('Documentation', 'ml-slider') . "</a>";
1965
  $meta[] = "<a href='https://wordpress.org/support/plugin/ml-slider/reviews#new-post' target='_blank' title='" . __('Leave a review', 'ml-slider') . "'><i class='ml-stars'><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg><svg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-star'><polygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2'/></svg></i></a>";
1971
  * Adds styles to admin head to allow for stars animation and coloring
1972
  */
1973
  public function add_star_styles() {
1974
+ if (metaslider_user_is_on_admin_page('plugins.php')) {?>
1975
  <style>
1976
  .ml-stars{display:inline-block;color:#ffb900;position:relative;top:3px}
1977
  .ml-stars svg{fill:#ffb900}
1985
  * Add nonce to activation pa
1986
  */
1987
  public function add_tour_nonce_to_activation_page() {
1988
+ if (metaslider_user_is_on_admin_page('plugins.php')) {?>
1989
  <script>
1990
  var metaslider_tour_nonce = "<?php echo wp_create_nonce('metaslider_tour_nonce'); ?>";
1991
  </script>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: matchalabs, DavidAnderson, dnutbourne, kbat82
3
  Tags: wordpress slideshow,seo,slideshow,slider,widget,wordpress slider,image slider,flexslider,flex slider,nivoslider,nivo slider,responsive,responsive slides,coinslider,coin slider,slideshow,carousel,responsive slider,vertical slides
4
  Donate link: https://david.dw-perspective.org.uk/donate
5
  Requires at least: 3.5
6
- Stable tag: 3.6.8
7
  Tested up to: 4.9
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
@@ -151,15 +151,22 @@ See https://www.metaslider.com/documentation/image-cropping/
151
 
152
  == Changelog ==
153
 
 
 
 
 
 
 
154
  = 3.6.8 - 2018/Jan/26 =
155
 
 
156
  * FIX: Updates compatibility for various themes (including Genesis)
157
 
158
  = 3.6.7 - 2017/Dec/15 =
159
 
160
  * FEATURE: Adds back in some instructions on how to display the slideshow
161
  * TWEAK: Removes unnecessary type attribute that was causing valiation errors
162
- * TWEAK: Add DocBlock checking with CI for PHP and JS files
163
  * FIX: Adds compatibility fixes for older WP versions.
164
 
165
  = 3.6.6 - 2017/Nov/23 =
@@ -626,4 +633,4 @@ More info/Comments: http://www.metaslider.com/coming-soon-meta-slider-2-6-free/
626
  * Initial version
627
 
628
  == Upgrade Notice ==
629
- * 3.6.8 : Updates compatibility for various themes (including Genesis)
3
  Tags: wordpress slideshow,seo,slideshow,slider,widget,wordpress slider,image slider,flexslider,flex slider,nivoslider,nivo slider,responsive,responsive slides,coinslider,coin slider,slideshow,carousel,responsive slider,vertical slides
4
  Donate link: https://david.dw-perspective.org.uk/donate
5
  Requires at least: 3.5
6
+ Stable tag: 3.7.0
7
  Tested up to: 4.9
8
  License: GPLv2 or later
9
  License URI: https://www.gnu.org/licenses/gpl-2.0.html
151
 
152
  == Changelog ==
153
 
154
+ = 3.7.0 - 2018/Feb/26 =
155
+
156
+ * FEATURE: Allows users to inherit default captions and other data from the image.
157
+ * FIX: Adds capability filter to pages.
158
+ * TWEAK: Updates to the correct support link.
159
+
160
  = 3.6.8 - 2018/Jan/26 =
161
 
162
+ * FIX: Updates support links to their correct locations
163
  * FIX: Updates compatibility for various themes (including Genesis)
164
 
165
  = 3.6.7 - 2017/Dec/15 =
166
 
167
  * FEATURE: Adds back in some instructions on how to display the slideshow
168
  * TWEAK: Removes unnecessary type attribute that was causing valiation errors
169
+ * TWEAK: Adds DocBlock checking with CI for PHP and JS files
170
  * FIX: Adds compatibility fixes for older WP versions.
171
 
172
  = 3.6.6 - 2017/Nov/23 =
633
  * Initial version
634
 
635
  == Upgrade Notice ==
636
+ * 3.7.0 : One new feature, one bug-fix, one tweak; a recommended update for all