MetaSlider - Version 3.6.0

Version Description

  • 2017/Nov/14 =

  • FEATURE: Allow a slide to be restored after deletion

  • FEATURE: Allow the background image to be changed

  • FEATURE: Adds a guided tour

  • FIX: Loads inline JS properly

  • FIX: FlexSlider touch events respect pause on hover setting

  • FIX: Allow for https image URLs

  • TRANSLATIONS: Addresses spelling/localization issues

  • TWEAK: Accessibility enhancements

  • TWEAK: Adds links to activation page

  • TWEAK: Updates FlexSlider to latest

  • TWEAK: Change the label "Meta Slider" to "MetaSlider"

  • TWEAK: Add dashboard notices

Download this release

Release Info

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

Code changes from version 3.5.1 to 3.6.0

Files changed (140) hide show
  1. admin/Notices.php +638 -0
  2. admin/Pages.php +162 -0
  3. admin/Tour.php +143 -0
  4. admin/assets/css/admin.css +1529 -0
  5. assets/metaslider/global.css → admin/assets/css/icon.css +2 -1
  6. admin/assets/css/notices.css +97 -0
  7. admin/assets/css/upgrade.css +172 -0
  8. admin/assets/fonts/interface/Interface-Bold.woff +0 -0
  9. admin/assets/fonts/interface/Interface-Bold.woff2 +0 -0
  10. admin/assets/fonts/interface/Interface-BoldItalic.woff +0 -0
  11. admin/assets/fonts/interface/Interface-BoldItalic.woff2 +0 -0
  12. admin/assets/fonts/interface/Interface-Medium.woff +0 -0
  13. admin/assets/fonts/interface/Interface-Medium.woff2 +0 -0
  14. admin/assets/fonts/interface/Interface-MediumItalic.woff +0 -0
  15. admin/assets/fonts/interface/Interface-MediumItalic.woff2 +0 -0
  16. admin/assets/fonts/interface/Interface-Regular.woff +0 -0
  17. admin/assets/fonts/interface/Interface-Regular.woff2 +0 -0
  18. admin/assets/fonts/interface/Interface-RegularItalic.woff +0 -0
  19. admin/assets/fonts/interface/Interface-RegularItalic.woff2 +0 -0
  20. {assets → admin/assets}/fonts/metaslider.eot +0 -0
  21. {assets → admin/assets}/fonts/metaslider.svg +0 -0
  22. {assets → admin/assets}/fonts/metaslider.ttf +0 -0
  23. {assets → admin/assets}/fonts/metaslider.woff +0 -0
  24. admin/assets/js/admin.js +728 -0
  25. admin/assets/js/tour.js +261 -0
  26. admin/assets/tether-shepherd/LICENSE +8 -0
  27. admin/assets/tether-shepherd/shepherd-theme-arrows-fix.css +5 -0
  28. admin/assets/tether-shepherd/shepherd-theme-arrows-fix.min.css +1 -0
  29. admin/assets/tether-shepherd/shepherd-theme-arrows-plain-buttons.css +215 -0
  30. admin/assets/tether-shepherd/shepherd-theme-arrows-plain-buttons.min.css +1 -0
  31. admin/assets/tether-shepherd/shepherd-theme-arrows.css +229 -0
  32. admin/assets/tether-shepherd/shepherd-theme-arrows.min.css +1 -0
  33. admin/assets/tether-shepherd/shepherd-theme-dark.css +246 -0
  34. admin/assets/tether-shepherd/shepherd-theme-dark.min.css +1 -0
  35. admin/assets/tether-shepherd/shepherd-theme-default.css +246 -0
  36. admin/assets/tether-shepherd/shepherd-theme-default.min.css +1 -0
  37. admin/assets/tether-shepherd/shepherd-theme-square-dark.css +248 -0
  38. admin/assets/tether-shepherd/shepherd-theme-square-dark.min.css +1 -0
  39. admin/assets/tether-shepherd/shepherd-theme-square.css +248 -0
  40. admin/assets/tether-shepherd/shepherd-theme-square.min.css +1 -0
  41. admin/assets/tether-shepherd/shepherd.js +745 -0
  42. admin/assets/tether-shepherd/shepherd.min.js +1 -0
  43. admin/assets/tether-shepherd/tether.js +1443 -0
  44. admin/assets/tether/LICENSE +8 -0
  45. admin/assets/tether/tether.js +1811 -0
  46. admin/assets/tether/tether.min.js +1 -0
  47. {assets → admin/assets/vendor}/colorbox/colorbox.css +0 -0
  48. {assets → admin/assets/vendor}/colorbox/images/border.png +0 -0
  49. {assets → admin/assets/vendor}/colorbox/images/controls.png +0 -0
  50. {assets → admin/assets/vendor}/colorbox/images/ie6/borderBottomCenter.png +0 -0
  51. {assets → admin/assets/vendor}/colorbox/images/ie6/borderBottomLeft.png +0 -0
  52. {assets → admin/assets/vendor}/colorbox/images/ie6/borderBottomRight.png +0 -0
  53. {assets → admin/assets/vendor}/colorbox/images/ie6/borderMiddleLeft.png +0 -0
  54. {assets → admin/assets/vendor}/colorbox/images/ie6/borderMiddleRight.png +0 -0
  55. {assets → admin/assets/vendor}/colorbox/images/ie6/borderTopCenter.png +0 -0
  56. {assets → admin/assets/vendor}/colorbox/images/ie6/borderTopLeft.png +0 -0
  57. {assets → admin/assets/vendor}/colorbox/images/ie6/borderTopRight.png +0 -0
  58. {assets → admin/assets/vendor}/colorbox/images/loading.gif +0 -0
  59. {assets → admin/assets/vendor}/colorbox/images/loading_background.png +0 -0
  60. {assets → admin/assets/vendor}/colorbox/images/overlay.png +0 -0
  61. {assets → admin/assets/vendor}/colorbox/jquery.colorbox-min.js +0 -0
  62. {assets → admin/assets/vendor}/tipsy/jquery.tipsy.js +0 -0
  63. {assets → admin/assets/vendor}/tipsy/tipsy.css +0 -0
  64. admin/images/features/auto-optimize.png +0 -0
  65. admin/images/features/automatic-clean-ups.png +0 -0
  66. admin/images/features/automatically cleans.png +0 -0
  67. admin/images/features/choice-n-flexibility.png +0 -0
  68. admin/images/features/displays-database-table-sta.png +0 -0
  69. admin/images/features/enables-disables-trackbacks.png +0 -0
  70. admin/images/features/enhanced-robustness.png +0 -0
  71. admin/images/features/keyy_logo.png +0 -0
  72. admin/images/features/logging-n-reporting.png +0 -0
  73. admin/images/features/metaslider_logo.png +0 -0
  74. admin/images/features/multisite-support.png +0 -0
  75. admin/images/features/number_of_weeks.png +0 -0
  76. admin/images/features/optimize-individual.png +0 -0
  77. admin/images/features/premium-support.png +0 -0
  78. admin/images/features/remove-unwanted-img.png +0 -0
  79. admin/images/features/scheduling.png +0 -0
  80. admin/images/features/updraftcentral_logo.png +0 -0
  81. admin/images/features/updraftplus_logo.png +0 -0
  82. admin/images/features/wpo_logo.png +0 -0
  83. admin/images/keyy_logo.png +0 -0
  84. admin/images/metaslider_logo.png +0 -0
  85. admin/images/metaslider_logo3.png +0 -0
  86. admin/images/metaslider_logo_large.png +0 -0
  87. admin/images/notices/keyy_logo.png +0 -0
  88. admin/images/notices/metaslider_logo.png +0 -0
  89. admin/images/notices/updraft_logo.png +0 -0
  90. admin/images/notices/wp_optimize_logo.png +0 -0
  91. admin/images/seasonal/black_friday.png +0 -0
  92. admin/images/seasonal/christmas.png +0 -0
  93. admin/images/seasonal/new_year.png +0 -0
  94. admin/images/seasonal/spring.png +0 -0
  95. admin/images/seasonal/summer.png +0 -0
  96. admin/images/updraft_logo.png +0 -0
  97. admin/images/wp_optimize_logo.png +0 -0
  98. admin/lib/Updraft_Notices.php +212 -0
  99. admin/lib/helpers.php +170 -0
  100. admin/views/notices/dashboard-notice.php +28 -0
  101. admin/views/notices/header-notice.php +31 -0
  102. admin/views/pages/upgrade.php +169 -0
  103. assets/metaslider/admin.css +0 -948
  104. assets/metaslider/admin.js +0 -388
  105. assets/metaslider/public.css +96 -37
  106. assets/sliders/flexslider/LICENSE.md +339 -0
  107. assets/sliders/flexslider/flexslider.css +255 -141
  108. assets/sliders/flexslider/flexslider.min.css +1 -0
  109. assets/sliders/flexslider/{jquery.flexslider-min.js → jquery.flexslider.js} +151 -97
  110. assets/sliders/flexslider/jquery.flexslider.min.js +1 -0
  111. assets/sliders/nivoslider/jquery.nivo.slider.pack.js +1 -1
  112. inc/metaslider.imagehelper.class.php +51 -51
  113. inc/metaslider.systemcheck.class.php +2 -2
  114. inc/metaslider.widget.class.php +3 -3
  115. inc/slide/metaslide.class.php +103 -83
  116. inc/slide/metaslide.image.class.php +125 -47
  117. inc/slider/metaslider.class.php +15 -13
  118. inc/slider/metaslider.flex.class.php +2 -2
  119. languages/ml-slider-de_DE.po +4 -4
  120. languages/ml-slider-es_ES.po +3 -3
  121. languages/ml-slider-fa_IR.po +3 -3
  122. languages/ml-slider-fr_FR.po +5 -5
  123. languages/ml-slider-he_IL.po +8 -8
  124. languages/ml-slider-hr_HR.po +4 -4
  125. languages/ml-slider-hu_HU.po +4 -4
  126. languages/ml-slider-ja.po +4 -4
  127. languages/ml-slider-nb_NO.po +3 -3
  128. languages/ml-slider-nl_NL.po +3 -3
  129. languages/ml-slider-pl_PL.po +3 -3
  130. languages/ml-slider-pt_BR.po +4 -4
  131. languages/ml-slider-ro_RO.po +4 -4
  132. languages/ml-slider-ru_RU.po +3 -3
  133. languages/ml-slider-uk.po +4 -4
  134. languages/ml-slider-zh_CN.po +3 -3
  135. languages/ml-slider-zh_TW.po +3 -3
  136. languages/ml-slider.mo +0 -0
  137. languages/ml-slider.po +0 -676
  138. languages/ml-slider.pot +1226 -0
  139. ml-slider.php +414 -447
  140. readme.txt +46 -32
admin/Notices.php ADDED
@@ -0,0 +1,638 @@
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')) die('No direct access allowed');
4
+
5
+ if (!class_exists('Updraft_Notices_1_0')) require_once(METASLIDER_PATH.'admin/lib/Updraft_Notices.php');
6
+
7
+ class MetaSlider_Notices extends Updraft_Notices_1_0 {
8
+
9
+ /**
10
+ * @var object $ads - all ads
11
+ */
12
+ protected $ads;
13
+
14
+ /**
15
+ * @var object $notices_content
16
+ */
17
+ protected $notices_content;
18
+
19
+ /**
20
+ * @var object $plugin
21
+ */
22
+ protected $plugin;
23
+
24
+
25
+ /**
26
+ * Populates ad content and loads assets
27
+ */
28
+ public function __construct($plugin) {
29
+ $this->ads = $this->is_metasliderpro_installed() ? $this->pro_notices() : $this->lite_notices();
30
+
31
+ // To avoid showing the user ads off the start, lets wait
32
+ $this->notices_content = ($this->ad_delay_has_finished()) ? $this->ads : array();
33
+ $this->plugin = $plugin;
34
+
35
+ add_action('admin_enqueue_scripts', array($this, 'add_notice_assets'));
36
+ add_action('wp_ajax_notice_handler', array($this, 'ajax_notice_handler'));
37
+ add_action('admin_notices', array($this, 'show_dashboard_notices'));
38
+ }
39
+
40
+ /**
41
+ * Handles assets for the notices
42
+ */
43
+ public function add_notice_assets() {
44
+ wp_enqueue_style('ml-slider-notices-css', METASLIDER_ADMIN_URL . 'assets/css/notices.css', false, METASLIDER_VERSION);
45
+ wp_localize_script('jquery', 'metaslider_notices', array(
46
+ 'handle_notices_nonce' => wp_create_nonce('metaslider_handle_notices_nonce')
47
+ ));
48
+ }
49
+
50
+ /**
51
+ * Deprecated for MetaSlider for now
52
+ */
53
+ public function notices_init() { return; }
54
+
55
+ /**
56
+ * Returns notices that free/lite users should see. dismiss_time should match the key
57
+ * hide_time is in weeks. Use a string to hide for 9999 weeks.
58
+ * @return array returns an array of notices
59
+ */
60
+ protected function lite_notices() {
61
+ return array_merge(array(
62
+ 'updraftplus' => array(
63
+ 'title' => __('Always backup WordPress to avoid losing your site!', 'ml-slider'),
64
+ 'text' => __("UpdraftPlus is the world's #1 backup plugin from the makers of MetaSlider. Backup to the cloud, on a schedule and restore with 1 click!", 'ml-slider'),
65
+ 'image' => 'updraft_logo.png',
66
+ 'button_link' => 'https://wordpress.org/plugins/updraftplus/',
67
+ 'button_meta' => 'updraftplus',
68
+ 'dismiss_time' => 'updraftplus',
69
+ 'hide_time' => 12,
70
+ 'supported_positions' => array('header', 'dashboard'),
71
+ 'validity_function' => 'is_updraftplus_installed',
72
+ ),
73
+ 'keyy' => array(
74
+ 'title' => __('Keyy: Instant and secure logon with a wave of your phone', 'ml-slider'),
75
+ 'text' => __('No more forgotten passwords. Find out more about our revolutionary new WordPress plugin', 'ml-slider'),
76
+ 'image' => 'keyy_logo.png',
77
+ 'button_link' => 'https://getkeyy.com/?utm_source=metaslider-plugin-page&utm_medium=banner',
78
+ 'button_meta' => 'keyy',
79
+ 'dismiss_time' => 'keyy',
80
+ 'hide_time' => 12,
81
+ 'supported_positions' => array('header', 'dashboard'),
82
+ 'validity_function' => 'is_keyy_installed',
83
+ ),
84
+ 'updraftcentral' => array(
85
+ 'title' => __('Save Time and Money. Manage multiple WordPress sites from one location.', 'ml-slider'),
86
+ 'text' => __('UpdraftCentral is a highly efficient way to take backup, update and manage multiple WP sites from one location', 'ml-slider'),
87
+ 'image' => 'updraft_logo.png',
88
+ 'button_link' => 'https://updraftcentral.com?utm_source=metaslider-plugin-page&utm_medium=banner',
89
+ 'button_meta' => 'updraftcentral',
90
+ 'dismiss_time' => 'updraftcentral',
91
+ 'hide_time' => 12,
92
+ 'supported_positions' => array('header', 'dashboard'),
93
+ 'validity_function' => 'is_updraftcentral_installed',
94
+ ),
95
+ 'rate_plugin' => array(
96
+ 'title' => __('Like MetaSlider and have a minute to spare?', 'ml-slider'),
97
+ 'text' => __('Please help MetaSlider by giving a positive review at wordpress.org.', 'ml-slider'),
98
+ 'image' => 'metaslider_logo.png',
99
+ 'button_link' => 'https://wordpress.org/support/plugin/ml-slider/reviews/?rate=5#new-post',
100
+ 'button_meta' => 'review',
101
+ 'dismiss_time' => 'rate_plugin',
102
+ 'hide_time' => 12,
103
+ 'supported_positions' => array('header', 'dashboard'),
104
+ ),
105
+ 'lite_survey' => array(
106
+ 'title' => __('Help us to get even better MetaSlider', 'ml-slider'),
107
+ 'text' => __('Let us know how you use MetaSlider by answering 4 simple questions. We will make MetaSlider to suit you better.', 'ml-slider'),
108
+ 'image' => 'metaslider_logo.png',
109
+ 'button_link' => 'https://www.metaslider.com/survey?utm_source=metaslider-plugin-page&utm_medium=banner',
110
+ 'button_meta' => 'lets_start',
111
+ 'dismiss_time' => 'lite_survey',
112
+ 'hide_time' => 12,
113
+ 'supported_positions' => array('header'),
114
+ ),
115
+ 'pro_layers' => array(
116
+ 'title' => __('Spice up your site with animated layers and video slides', 'ml-slider'),
117
+ 'text' => __('With the MetaSlider Add-on pack you can give your slideshows a professional look!', 'ml-slider'),
118
+ 'image' => 'metaslider_logo.png',
119
+ 'button_link' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade') . '?utm_source=metaslider-plugin-page&utm_medium=banner',
120
+ 'button_meta' => 'ml-slider',
121
+ 'dismiss_time' => 'pro_layers',
122
+ 'hide_time' => 12,
123
+ 'supported_positions' => array('header'),
124
+ ),
125
+ 'pro_features' => array(
126
+ 'title' => __('Increase your revenue and conversion with video slides and many more features', 'ml-slider'),
127
+ 'text' => __('Upgrade today to benefit from many more premium features. Find out more.', 'ml-slider'),
128
+ 'image' => 'metaslider_logo.png',
129
+ 'button_link' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade') . '?utm_source=metaslider-plugin-page&utm_medium=banner',
130
+ 'button_meta' => 'ml-slider',
131
+ 'dismiss_time' => 'pro_features',
132
+ 'hide_time' => 12,
133
+ 'supported_positions' => array('header'),
134
+ ),
135
+ 'translation' => array(
136
+ 'title' => __('Can you translate? Want to improve MetaSlider for speakers of your language?', 'ml-slider'),
137
+ 'text' => __('Please go here for instructions - it is easy.', 'ml-slider'),
138
+ 'image' => 'metaslider_logo.png',
139
+ 'button_link' => 'https://translate.wordpress.org/projects/wp-plugins/ml-slider',
140
+ 'button_meta' => 'lets_start',
141
+ 'dismiss_time' => 'translation',
142
+ 'hide_time' => 12,
143
+ 'supported_positions' => array('header'),
144
+ 'validity_function' => 'translation_needed',
145
+ ),
146
+ 'thankyou' => array(
147
+ 'title' => __('Thank you for installing MetaSlider', 'ml-slider'),
148
+ 'text' => __('Supercharge & secure your WordPress site with our other top plugins:', 'ml-slider'),
149
+ 'image' => 'metaslider_logo_large.png',
150
+ 'dismiss_time' => 'thankyou',
151
+ 'hide_time' => 24,
152
+ 'mega' => true,
153
+ 'supported_positions' => array('dashboard'),
154
+ ),
155
+ ), $this->valid_seasonal_notices());
156
+ }
157
+
158
+ /**
159
+ * Premium user notices, if any.
160
+ * @return string
161
+ */
162
+ protected function pro_notices() {
163
+ return array(
164
+ 'pro_survey' => array(
165
+ 'title' => __("We’re making changes and need your help.", 'ml-slider'),
166
+ 'text' => __('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!', 'ml-slider'),
167
+ 'image' => 'metaslider_logo.png',
168
+ 'button_link' => 'https://www.metaslider.com/survey-pro',
169
+ 'button_meta' => 'lets_start',
170
+ 'dismiss_time' => 'pro_survey',
171
+ 'hide_time' => __('forever', 'ml-slider'),
172
+ 'supported_positions' => array('header'),
173
+ ),
174
+ );
175
+ }
176
+
177
+ /**
178
+ * Seasonal Notices. Note that if dismissed, they will stay dismissed for two weeks
179
+ * which is the default for any notice. Since the parent class forces these,
180
+ * there's no need to edit the key/dismiss_time
181
+ * @return string
182
+ */
183
+ protected function seasonal_notices() {
184
+ return array(
185
+ 'blackfriday' => array(
186
+ 'title' => __('Black Friday - 50% off the MetaSlider Add-on Pack until November 30th', 'ml-slider'),
187
+ 'text' => __('To benefit, use this discount code:', 'ml-slider').' ',
188
+ 'image' => 'seasonal/black_friday.png',
189
+ 'button_link' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade') . '?utm_source=metaslider-plugin-page&utm_medium=banner',
190
+ 'button_meta' => 'ml-slider',
191
+ 'dismiss_time' => 'blackfriday',
192
+ 'discount_code' => 'blackfriday2017sale',
193
+ 'valid_from' => '2017-11-20 00:00:00',
194
+ 'valid_to' => '2017-11-30 23:59:59',
195
+ 'hide_time' => __('until next year', 'ml-slider'),
196
+ 'supported_positions' => array('header', 'dashboard'),
197
+ ),
198
+ 'christmas' => array(
199
+ 'title' => __('Christmas sale - 50% off the MetaSlider Add-on Pack until December 25th', 'ml-slider'),
200
+ 'text' => __('To benefit, use this discount code:', 'ml-slider').' ',
201
+ 'image' => 'seasonal/christmas.png',
202
+ 'button_link' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade') . '?utm_source=metaslider-plugin-page&utm_medium=banner',
203
+ 'button_meta' => 'ml-slider',
204
+ 'dismiss_time' => 'christmas',
205
+ 'discount_code' => 'christmas2017sale',
206
+ 'valid_from' => '2017-12-01 00:00:00',
207
+ 'valid_to' => '2017-12-25 23:59:59',
208
+ 'hide_time' => __('until next year', 'ml-slider'),
209
+ 'supported_positions' => array('header', 'dashboard'),
210
+ ),
211
+ 'newyear' => array(
212
+ 'title' => __('Happy New Year - 50% off the MetaSlider Add-on Pack until January 1st', 'ml-slider'),
213
+ 'text' => __('To benefit, use this discount code:', 'ml-slider').' ',
214
+ 'image' => 'seasonal/new_year.png',
215
+ 'button_link' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade') . '?utm_source=metaslider-plugin-page&utm_medium=banner',
216
+ 'button_meta' => 'ml-slider',
217
+ 'dismiss_time' => 'newyear',
218
+ 'discount_code' => 'newyear2018sale',
219
+ 'valid_from' => '2017-12-26 00:00:00',
220
+ 'valid_to' => '2018-01-14 23:59:59',
221
+ 'hide_time' => __('until next year', 'ml-slider'),
222
+ 'supported_positions' => array('header', 'dashboard'),
223
+ ),
224
+ 'spring' => array(
225
+ 'title' => __('Spring sale - 50% off the MetaSlider Add-on Pack until April 31st', 'ml-slider'),
226
+ 'text' => __('To benefit, use this discount code:', 'ml-slider').' ',
227
+ 'image' => 'seasonal/spring.png',
228
+ 'button_link' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade') . '?utm_source=metaslider-plugin-page&utm_medium=banner',
229
+ 'button_meta' => 'ml-slider',
230
+ 'dismiss_time' => 'spring',
231
+ 'discount_code' => 'spring2018sale',
232
+ 'valid_from' => '2018-04-01 00:00:00',
233
+ 'valid_to' => '2018-04-30 23:59:59',
234
+ 'hide_time' => __('until next year', 'ml-slider'),
235
+ 'supported_positions' => array('header', 'dashboard'),
236
+ ),
237
+ 'summer' => array(
238
+ 'title' => __('Summer sale - 50% off the MetaSlider Add-on Pack until July 31st', 'ml-slider'),
239
+ 'text' => __('To benefit, use this discount code:', 'ml-slider').' ',
240
+ 'image' => 'seasonal/summer.png',
241
+ 'button_link' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade') . '?utm_source=metaslider-plugin-page&utm_medium=banner',
242
+ 'button_meta' => 'ml-slider',
243
+ 'dismiss_time' => 'summer',
244
+ 'discount_code' => 'summer2018sale',
245
+ 'valid_from' => '2018-07-01 00:00:00',
246
+ 'valid_to' => '2018-07-31 23:59:59',
247
+ 'hide_time' => __('until next year', 'ml-slider'),
248
+ 'supported_positions' => array('header', 'dashboard'),
249
+ )
250
+ );
251
+ }
252
+
253
+ /**
254
+ * These appear inside a mega ad.
255
+ * @return string
256
+ */
257
+ protected function mega_notice_parts() {
258
+ return array(
259
+ 'ms_pro' => array(
260
+ 'title' => __('MetaSlider Add-on Pack:'),
261
+ 'text' => __('Increase your conversion rate with video slides and many more options.', 'ml-slider'),
262
+ 'image' => '',
263
+ 'button_link' => apply_filters('metaslider_hoplink', 'https://www.metaslider.com/upgrade') . '?utm_source=metaslider-plugin-page&utm_medium=banner',
264
+ 'button_meta' => 'ml-slider',
265
+ ),
266
+ // 'wpo_pro' => array(
267
+ // 'title' => __('WP-Optimize Premium'),
268
+ // 'text' => __('offers unparalleled choice and flexibility, allowing you to select one or a combination of over a dozen optimization options.', 'ml-slider'),
269
+ // 'image' => '',
270
+ // 'button_link' => 'https://getwpo.com?utm_source=metaslider-plugin-page&utm_medium=banner',
271
+ // 'button_meta' => 'ml-slider',
272
+ // ),
273
+ // 'udp_pro' => array(
274
+ // 'title' => __('UpdraftPlus Premium'),
275
+ // 'text' => __('provides personal support, the ability to copy sites, more storage destinations, encrypted backups for security, multiple backup destinations, better reporting, no adverts and plenty more.', 'ml-slider'),
276
+ // 'image' => '',
277
+ // 'button_link' => 'https://updraftplus.com?utm_source=metaslider-plugin-page&utm_medium=banner',
278
+ // 'button_meta' => 'ml-slider',
279
+ // ),
280
+ 'udp' => array(
281
+ 'title' => __('UpdraftPlus'),
282
+ 'text' => __('simplifies backups and restoration. It is the world\'s highest ranking and most popular scheduled backup plugin, with over a million currently-active installs.', 'ml-slider'),
283
+ 'image' => '',
284
+ 'button_link' => 'https://wordpress.org/plugins/updraftplus/',
285
+ 'button_meta' => 'updraftplus',
286
+ ),
287
+ 'wpo' => array(
288
+ 'title' => __('WP-Optimize:'),
289
+ 'text' => __('auto-clean your WordPress database so that it runs at maximum efficiency.', 'ml-slider'),
290
+ 'image' => '',
291
+ 'button_link' => 'https://wordpress.org/plugins/wp-optimize/',
292
+ 'button_meta' => 'wp-optimize',
293
+ ),
294
+ 'keyy' => array(
295
+ 'title' => __('Keyy:'),
296
+ 'text' => htmlspecialchars(__('Simple & secure login with a wave of your phone.', 'ml-slider')),
297
+ 'image' => '',
298
+ 'button_link' => 'https://getkeyy.com/?utm_source=metaslider-plugin-page&utm_medium=banner',
299
+ 'button_meta' => 'keyy',
300
+ ),
301
+ 'updraftcentral' => array(
302
+ 'title' => __('UpdraftCentral'),
303
+ 'text' => __('is a highly efficient way to manage, update and backup multiple websites from one place.', 'ml-slider'),
304
+ 'image' => '',
305
+ 'button_link' => 'https://updraftcentral.com?utm_source=metaslider-plugin-page&utm_medium=banner',
306
+ 'button_meta' => 'updraftcentral',
307
+ ),
308
+ );
309
+ }
310
+
311
+ /**
312
+ * Check to disable ads on the Pro version. The parent function returns
313
+ * false if installed, so this is reversed and shouldn't be used for the validity function
314
+ * @return bool
315
+ */
316
+ protected function is_metasliderpro_installed() {
317
+ return !parent::is_plugin_installed('ml-slider-pro', false);
318
+ }
319
+
320
+ /**
321
+ * Check to see if UpdraftPlus is installed
322
+ * @return bool
323
+ */
324
+ protected function is_updraftplus_installed() {
325
+ return parent::is_plugin_installed('updraftplus', false);
326
+ }
327
+
328
+ /**
329
+ * Check to see if UpdraftPlus is installed
330
+ * @return bool
331
+ */
332
+ protected function is_keyy_installed() {
333
+ return parent::is_plugin_installed('keyy', false);
334
+ }
335
+
336
+ /**
337
+ * Check to see if UpdraftCentral is installed
338
+ * @return bool
339
+ */
340
+ protected function is_updraftcentral_installed() {
341
+ return parent::is_plugin_installed('updraftcentral', false);
342
+ }
343
+
344
+ /**
345
+ * Checks if the user agent isn't set as en_GB or en_US, and if the language file doesn't exist
346
+ * @param string $plugin_base_dir
347
+ * @param string $product_name
348
+ * @return bool
349
+ */
350
+ protected function translation_needed($plugin_base_dir = null, $product_name = null) {
351
+ return parent::translation_needed(METASLIDER_PATH, 'ml-slider');
352
+ }
353
+
354
+ /**
355
+ * This method checks to see if the ad has been dismissed
356
+ * @param string $ad_identifier - identifier for the ad
357
+ * @return bool returns true when we dont want to show the ad
358
+ */
359
+ protected function check_notice_dismissed($ad_identifier) {
360
+ return (time() < get_option("ms_hide_{$ad_identifier}_ads_until"));
361
+ }
362
+
363
+ /**
364
+ * Returns all active seasonal ads
365
+ * @return array
366
+ */
367
+ protected function valid_seasonal_notices() {
368
+ $valid = array();
369
+ $time_now = time();
370
+ // $time_now = strtotime('2017-11-20 00:00:01'); // Black Friday
371
+ // $time_now = strtotime('2017-12-01 00:00:01'); // XMAS
372
+ // $time_now = strtotime('2017-12-26 00:00:01'); // NY
373
+ // $time_now = strtotime('2018-04-01 00:00:01'); // Spring
374
+ // $time_now = strtotime('2018-07-01 00:00:01'); // Summer
375
+ foreach($this->seasonal_notices() as $ad_identifier => $notice) {
376
+ $valid_from = strtotime($notice['valid_from']);
377
+ $valid_to = strtotime($notice['valid_to']);
378
+ if ($valid_from < $time_now && $time_now <= $valid_to) {
379
+ $valid[$ad_identifier] = $notice;
380
+ }
381
+ }
382
+ return $valid;
383
+ }
384
+
385
+ /**
386
+ * The logic is handled elsewhere. This being true does not skip
387
+ * the seasonal notices. Overrides parent function
388
+ * @return array
389
+ */
390
+ protected function skip_seasonal_notices($notice_data) {
391
+ return true;
392
+ }
393
+
394
+ /**
395
+ * Checks whether this is an ad page - hard-coded
396
+ * @return bool
397
+ */
398
+ protected function is_page_with_ads() {
399
+ global $pagenow;
400
+ $page = isset($_GET['page']) ? $_GET['page'] : '';
401
+
402
+ // I'm thinking to limit the check to the actual settings page for now
403
+ // This way, if the activaye the plugin but don't start using it until
404
+ // a few weeks after, it won't bother them with ads.
405
+ // return ('index.php' === $pagenow) || ($page === 'metaslider');
406
+ return ($page === 'metaslider');
407
+ }
408
+
409
+ /**
410
+ * This method checks to see if the ad waiting period is over (2 weeks)
411
+ * If not, it will set a two week time
412
+ * @return bool returns true when we dont want to show the ad
413
+ */
414
+ protected function ad_delay_has_finished() {
415
+
416
+ if (metaslider_is_pro_installed()) {
417
+
418
+ // If they are pro don't check anything but show the pro ad.
419
+ return true;
420
+ }
421
+
422
+ // Disable this for now so that after a dismiss, ads hide for 24 hours
423
+ // if (get_option("ms_ads_first_seen_on")) {
424
+
425
+ // // They have seen ads before which means the delay is over
426
+ // return true;
427
+ // }
428
+
429
+
430
+ $delay = get_option("ms_hide_all_ads_until");
431
+
432
+ // Only start the timer if they see a page that has ads
433
+ if (!$this->is_page_with_ads() && !$delay) {
434
+ return false;
435
+ }
436
+ if (!$delay) {
437
+
438
+ // Set the delay for when to see an ad, 2 weeks; returns false
439
+ return !update_option("ms_hide_all_ads_until", time() + 2*7*86400);
440
+ } else if ((time() > $delay) && !get_option("ms_ads_first_seen_on")) {
441
+
442
+ // Note the time they first saw ads
443
+ update_option("ms_ads_first_seen_on", time());
444
+
445
+ // Now that they can see ads, make sure the rate_plugin is shown first
446
+ // TODO: Enable this next time
447
+ // $notices = $this->lite_notices();
448
+ // $this->ads = array('rate_plugin' => $notices['rate_plugin']);
449
+ return true;
450
+ } else if (time() < $delay) {
451
+
452
+ // This means an ad was dismissed and there's a 24h delay
453
+ return false;
454
+ } else if (get_option("ms_ads_first_seen_on")) {
455
+
456
+ // This means the delay has elapsed, the 24hr period expired
457
+ // and there are still ads that haven't been dismissed
458
+ return true;
459
+ }
460
+ // Default to not show an ad, in case there's some error
461
+ return false;
462
+ }
463
+
464
+ /*
465
+ * Method to handle dashboard notices
466
+ */
467
+ public function show_dashboard_notices() {
468
+ $current_page = get_current_screen();
469
+ if ('dashboard' === $current_page->base && metaslider_sees_notices($this->plugin)) {
470
+
471
+ // Override the delay to show the thankyou notice on activation
472
+ // if (!empty($_GET['ms_activated'])) {
473
+ // $lite_notices = $this->lite_notices();
474
+ // $this->notices_content['thankyou'] = $lite_notices['thankyou'];
475
+ // }
476
+ echo $this->do_notice(false, 'dashboard', true);
477
+ }
478
+ }
479
+
480
+ /**
481
+ * Selects the template and returns or displays the notice
482
+ * @param array $notice_information - variable names/values to pass through to the template
483
+ * @param bool $return_instead_of_echo - whether to
484
+ * @param string $position - where the notice is being displayed
485
+ * @return null|string - depending on the value of $return_instead_of_echo
486
+ */
487
+ protected function render_specified_notice($notice_information, $return_instead_of_echo = false, $position = 'header') {
488
+ $views = array(
489
+ 'header' => 'header-notice.php',
490
+ 'dashboard' => 'dashboard-notice.php',
491
+ );
492
+ $view = isset($views[$position]) ? $views[$position] : 'header-notice.php';
493
+ return $this->include_template($view, $return_instead_of_echo, $notice_information);
494
+ }
495
+
496
+ /**
497
+ * Displays or returns the template
498
+ * @param string $path file name of the template
499
+ * @param bool $return_instead_of_echo
500
+ * @param array $args
501
+ * @return null|string
502
+ */
503
+ public function include_template($path, $return_instead_of_echo = false, $args = array()) {
504
+ if ($return_instead_of_echo) ob_start();
505
+
506
+ extract($args);
507
+ if (is_int($hide_time)) {
508
+ $hide_time = $hide_time . ' ' . __('weeks', 'ml-slider');
509
+ }
510
+ include METASLIDER_PATH.'admin/views/notices/'.$path;
511
+
512
+ if ($return_instead_of_echo) return ob_get_clean();
513
+ }
514
+
515
+ /**
516
+ * Builds a link based on the type of notice being requested
517
+ * @param string $link - the URL to link to
518
+ * @param string $type - which notice is being displayed
519
+ * @return string - the resulting HTML
520
+ */
521
+ public function get_button_link($link, $type) {
522
+ $messages = array(
523
+ 'updraftplus' => __('Get UpdraftPlus', 'ml-slider'),
524
+ 'keyy' => __('Get Keyy', 'ml-slider'),
525
+ 'wp-optimize' => __('Optimize today', 'ml-slider'),
526
+ 'updraftcentral' => __('Get UpdraftCentral', 'ml-slider'),
527
+ 'lets_start' => __('Let\'s Start', 'ml-slider'),
528
+ 'review' => __('Review MetaSlider', 'ml-slider'),
529
+ 'ml-slider' => __('Find out more', 'ml-slider'),
530
+ 'signup' => __('Sign up', 'ml-slider'),
531
+ 'go_there' => __('Go there', 'ml-slider')
532
+ );
533
+ $message = isset($messages[$type]) ? $messages[$type] : __('Read more', 'ml-slider');
534
+ $link = apply_filters('updraftplus_com_link', $link);
535
+
536
+ return '<a class="updraft_notice_link" href="' . esc_url($link) . '">' . $message . '</a>';
537
+ }
538
+
539
+ /**
540
+ * Handles any notice related ajax calls
541
+ * @return string - (JSON) Sends a success response unless an error is encountered
542
+ */
543
+ public function ajax_notice_handler() {
544
+ if (!wp_verify_nonce($_REQUEST['_wpnonce'], 'metaslider_handle_notices_nonce')) {
545
+ return wp_send_json_error(array(
546
+ 'message' => __('The security check failed. Please refresh the page and try again.', 'ml-slider')
547
+ ), 401);
548
+ }
549
+
550
+ if (is_wp_error($ad_data = $this->ad_exists($_POST['ad_identifier']))) {
551
+ return wp_send_json_error(array(
552
+ 'message' => __('This item does not exist. Please refresh the page and try again.', 'ml-slider')
553
+ ), 401);
554
+ }
555
+
556
+ $result = $this->dismiss_ad($ad_data['dismiss_time'], $ad_data['hide_time']);
557
+
558
+ if (is_wp_error($result)) {
559
+ return wp_send_json_error(array(
560
+ 'message' => $result->get_error_message()
561
+ ), 409);
562
+ }
563
+
564
+ return wp_send_json_success(array(
565
+ 'message' => __('The option was successfully updated', 'ml-slider'),
566
+ ), 200);
567
+ }
568
+
569
+ /**
570
+ * Returns the available ads that havent been dismissed by the user
571
+ * @param string|array the location for the ad
572
+ * @return array the identifier for the ad
573
+ */
574
+ public function active_ads($location = 'header', $bypass_delay = false) {
575
+ $dismissed_ads = array();
576
+
577
+ $ads = ($bypass_delay) ? $this->ads : $this->notices_content;
578
+
579
+ // Filter through all site options (cached)
580
+ foreach(wp_load_alloptions() as $key => $value){
581
+ if (strpos($key, 'ms_hide_') && strpos($key, '_ads_until')) {
582
+ $key = str_replace(array('ms_hide_', '_ads_until'), '', $key);
583
+ $dismissed_ads[$key] = $value;
584
+ }
585
+ }
586
+
587
+ // Filter out if the dismiss time has expired, then compare to the database
588
+ $valid_ads = array();
589
+ foreach ($ads as $ad_identifier => $values) {
590
+ $is_valid = isset($values['validity_function']) ? call_user_func(array($this, $values['validity_function'])) : true;
591
+ $not_dismissed = !$this->check_notice_dismissed($ad_identifier);
592
+ $is_supported = in_array($location, $values['supported_positions']);
593
+ if ($is_valid && $not_dismissed && $is_supported) {
594
+ $valid_ads[$ad_identifier] = $values;
595
+ }
596
+ }
597
+
598
+ return array_diff_key($valid_ads, $dismissed_ads);
599
+ }
600
+
601
+ /**
602
+ * Returns all possible ads or the specified identifier
603
+ * @param string $ad_identifier
604
+ * @return string|null the data of the ad
605
+ */
606
+ public function get_ad($ad_identifier = null) {
607
+ $all_notices = array_merge($this->pro_notices(), $this->lite_notices());
608
+ return is_null($ad_identifier) ? $all_notices : $all_notices['ad_identifier'];
609
+ }
610
+
611
+ /**
612
+ * Checks if the ad identifier exists in any of the ads above
613
+ * @param string $ad_identifier
614
+ * @return bool the data of the ad
615
+ */
616
+ public function ad_exists($ad_identifier) {
617
+ $all_notices = array_merge($this->pro_notices(), $this->lite_notices());
618
+ return isset($all_notices[$ad_identifier]) ? $all_notices[$ad_identifier] : new WP_Error('bad_call', __('The requested data does not exist.', 'ml-slider'), array('status' => 401));
619
+ }
620
+
621
+ /**
622
+ * Updates the stored value for how long to hide the ads
623
+ * @param string $ad_identifier
624
+ * @param int|string time in weeks or a string to show
625
+ * @return bool|WP_Error whether the update was a success
626
+ */
627
+ public function dismiss_ad($ad_identifier, $weeks) {
628
+
629
+ // if the time isn't specified it will hide forever (9999 weeks)
630
+ $weeks = is_int($weeks) ? $weeks : 9999;
631
+ $result = update_option("ms_hide_{$ad_identifier}_ads_until", time() + $weeks*7*86400);
632
+
633
+ // Hide all ads for 24 hours
634
+ update_option("ms_hide_all_ads_until", time() + 1*86400);
635
+
636
+ return $result ? $result : new WP_Error('update_failed', __('The attempt to update the option failed.', 'ml-slider'), array('status' => 409));
637
+ }
638
+ }
admin/Pages.php ADDED
@@ -0,0 +1,162 @@
1
+ <?php
2
+
3
+ /*
4
+ * Entry point for building the wordpress admin pages.
5
+ * Temporarily extends the MetaSlider Class until more refactoring can be done.
6
+ */
7
+
8
+ Class MetaSlider_Admin_Pages extends MetaSliderPlugin {
9
+
10
+ /**
11
+ * @property string $capability - The minimum capability to view the admin page
12
+ */
13
+ private $capability;
14
+
15
+ /**
16
+ * @property object $plugin - The MetaSlider plugin class
17
+ */
18
+ private $plugin;
19
+
20
+ /*
21
+ * @property string $current_page - The current admin page
22
+ */
23
+ private $current_page;
24
+
25
+ /**
26
+ * Sets up the notices, security and loads assets for the admin page
27
+ */
28
+ public function __construct($plugin) {
29
+ $this->plugin = $plugin;
30
+ $this->capability = apply_filters('metaslider_capability', 'edit_others_posts');
31
+ $this->notices = new MetaSlider_Notices($plugin);
32
+ $this->tour = new MetaSlider_Tour($plugin, 'toplevel_page_metaslider');
33
+ add_action('admin_enqueue_scripts', array($this, 'load_icon_css'));
34
+ add_action('admin_enqueue_scripts', array($this, 'load_upgrade_page_assets'));
35
+ }
36
+
37
+ /**
38
+ * Loads the icon on the top levelmenu page name
39
+ */
40
+ public function load_icon_css() {
41
+ wp_enqueue_style('metaslider-global', METASLIDER_ADMIN_URL . 'assets/css/icon.css', array(), METASLIDER_VERSION);
42
+ }
43
+
44
+ /**
45
+ * Loads in the overlay assets
46
+ */
47
+ public function load_overlay() {
48
+ wp_enqueue_style('metaslider-colorbox-styles', METASLIDER_ADMIN_URL . 'assets/vendor/colorbox/colorbox.css', false, METASLIDER_VERSION);
49
+ wp_enqueue_script('metaslider-colorbox', METASLIDER_ADMIN_URL . 'assets/vendor/colorbox/jquery.colorbox-min.js', array('jquery'), METASLIDER_VERSION, true);
50
+ }
51
+
52
+ /**
53
+ * Loads in tooltips
54
+ */
55
+ public function load_tooltips() {
56
+ wp_enqueue_style('metaslider-tipsy-styles', METASLIDER_ADMIN_URL . 'assets/vendor/tipsy/tipsy.css', false, METASLIDER_VERSION);
57
+ wp_enqueue_script('metaslider-tipsy', METASLIDER_ADMIN_URL . 'assets/vendor/tipsy/jquery.tipsy.js', array('jquery'), METASLIDER_VERSION, true);
58
+ }
59
+
60
+ /**
61
+ * Loads in custom javascript
62
+ */
63
+ public function load_javascript() {
64
+
65
+ wp_enqueue_media();
66
+ wp_enqueue_script('jquery-ui-core');
67
+ wp_enqueue_script('jquery-ui-sortable');
68
+
69
+ wp_register_script('metaslider-admin-script', METASLIDER_ADMIN_URL . 'assets/js/admin.js', array('jquery'), METASLIDER_VERSION, true);
70
+ wp_localize_script('metaslider-admin-script', 'metaslider', array(
71
+ 'url' => __("URL", "ml-slider"),
72
+ 'caption' => __("Caption", "ml-slider"),
73
+ 'new_window' => __("New Window", "ml-slider"),
74
+ 'confirm' => __("Are you sure?", "ml-slider"),
75
+ 'restore_language' => __("Undo", "ml-slider"),
76
+ 'restored_language' => __("Slide restored", "ml-slider"),
77
+ 'deleted_language' => __("Slide deleted", "ml-slider"),
78
+ 'click_to_undo_language' => __("Press to undo", "ml-slider"),
79
+ 'ajaxurl' => admin_url('admin-ajax.php'),
80
+ 'update_image' => __("Select replacement image", "ml-slider"),
81
+ 'resize_nonce' => wp_create_nonce('metaslider_resize'),
82
+ 'create_slide_nonce' => wp_create_nonce('metaslider_create_slide'),
83
+ 'delete_slide_nonce' => wp_create_nonce('metaslider_delete_slide'),
84
+ 'undelete_slide_nonce' => wp_create_nonce('metaslider_undelete_slide'),
85
+ 'update_slide_image_nonce' => wp_create_nonce('metaslider_update_slide_image'),
86
+ 'handle_notices_nonce' => wp_create_nonce('metaslider_handle_notices_nonce'),
87
+ 'iframeurl' => admin_url('admin-post.php?action=metaslider_preview'),
88
+ 'useWithCaution' => __("Caution: This setting is for advanced developers only. If you're unsure, leave it checked.", "ml-slider")
89
+ ));
90
+ wp_enqueue_script('metaslider-admin-script');
91
+ do_action('metaslider_register_admin_scripts');
92
+ }
93
+
94
+ /**
95
+ * Loads in custom styling for upgrade page
96
+ */
97
+ public function load_upgrade_page_assets() {
98
+ if ('upgrade' == $this->current_page) {
99
+ wp_enqueue_style('metaslider-upgrade-styles', METASLIDER_ADMIN_URL . 'assets/css/upgrade.css', false, METASLIDER_VERSION);
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Loads in custom styling
105
+ */
106
+ public function load_styles() {
107
+ wp_enqueue_style('metaslider-admin-styles', METASLIDER_ADMIN_URL . 'assets/css/admin.css', false, METASLIDER_VERSION);
108
+
109
+ // Hook to load more styles and scripts (from pro)
110
+ do_action('metaslider_register_admin_styles');
111
+ }
112
+
113
+ /**
114
+ * Area used to handle any third-party plugin conflicts
115
+ */
116
+ public function fix_conflicts() {
117
+
118
+ // WP Posts Filter Fix (Advanced Settings not toggling)
119
+ wp_dequeue_script('link');
120
+
121
+ // All In One Events Calendar Fix (Advanced Settings not toggling)
122
+ wp_dequeue_script('ai1ec_requirejs');
123
+ }
124
+
125
+ /**
126
+ * Method to add pages
127
+ * @param string $title - The title of the page
128
+ * @param string $slug - The slug used for the page
129
+ * @param string $parent - Setting a parent will make this page a submenu item
130
+ */
131
+ public function add_page($title, $slug = '', $parent = '') {
132
+ $slug = ('' == $slug) ? sanitize_title($title) : $slug;
133
+ $method = 'render_'.str_replace("-", "_", $slug).'_page';
134
+ if (!method_exists($this, $method)) {
135
+ return false;
136
+ }
137
+ $this->current_page = $slug;
138
+ $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));
139
+
140
+ // Load assets on all pages
141
+ add_action('load-' . $page, array($this, 'fix_conflicts'));
142
+ add_action('load-' . $page, array($this, 'load_overlay'));
143
+ add_action('load-' . $page, array($this, 'load_tooltips'));
144
+ add_action('load-' . $page, array($this, 'load_javascript'));
145
+ add_action('load-' . $page, array($this, 'load_styles'));
146
+ }
147
+
148
+ /**
149
+ * Sets up any logic needed for the main page
150
+ * TODO continue refactoring from here
151
+ */
152
+ public function render_metaslider_page() {
153
+ parent::render_admin_page();
154
+ }
155
+
156
+ /**
157
+ * Sets up any logic needed for the upgrade page
158
+ */
159
+ public function render_upgrade_page() {
160
+ include METASLIDER_PATH."admin/views/pages/upgrade.php";
161
+ }
162
+ }
admin/Tour.php ADDED
@@ -0,0 +1,143 @@
1
+ <?php
2
+
3
+ if (!defined('ABSPATH')) die('No direct access allowed');
4
+
5
+ /*
6
+ * Class for guided tour
7
+ */
8
+
9
+ Class MetaSlider_Tour {
10
+
11
+ /**
12
+ * The plugin object
13
+ */
14
+ protected $plugin;
15
+
16
+ /**
17
+ * Sets up the notices, security and loads assets for the admin page
18
+ */
19
+ public function __construct($plugin, $page) {
20
+ $this->plugin = $plugin;
21
+ add_action('load-' . $page, array($this, 'load_tour'));
22
+ add_action('wp_ajax_set_tour_status', array($this, 'handle_ajax'));
23
+ add_action('wp_ajax_reset_tour_status', array($this, 'handle_ajax'));
24
+ }
25
+
26
+ /**
27
+ * Loads in tour assets
28
+ */
29
+ public function load_tour() {
30
+ wp_enqueue_script('metaslider-tether-js', METASLIDER_ADMIN_URL . 'assets/tether/tether.min.js', METASLIDER_VERSION, true);
31
+ wp_enqueue_script('metaslider-shepherd-js', METASLIDER_ADMIN_URL . 'assets/tether-shepherd/shepherd.min.js', array('metaslider-tether-js'), METASLIDER_VERSION, true);
32
+ wp_enqueue_style('metaslider-shepherd-css', METASLIDER_ADMIN_URL . 'assets/tether-shepherd/shepherd-theme-arrows.css', false, METASLIDER_VERSION);
33
+
34
+ wp_register_script('metaslider-tour-js', METASLIDER_ADMIN_URL . 'assets/js/tour.js', array('metaslider-tether-js'), METASLIDER_VERSION, true);
35
+ wp_localize_script('metaslider-tour-js', 'metaslider_tour', array(
36
+ 'no_slideshows' => array(
37
+ 'show' => ! (bool) count($this->plugin->all_meta_sliders()),
38
+ 'title' => __("Welcome", "ml-slider"),
39
+ 'message' => __("Thanks for using the MetaSlider WordPress plugin. It looks like you don’t have any slideshows yet! To get started, click above to add your first one.", "ml-slider")
40
+ ),
41
+ 'main_tour' => array(
42
+ 'show' => (bool) count($this->plugin->all_meta_sliders()) && ! (bool) get_option('metaslider_tour_cancelled_on'),
43
+ 'nonce' => wp_create_nonce('metaslider_tour_nonce'),
44
+ // 'has_slides' => ms
45
+ 'learn_more_language' => __('Learn More', 'ml-slider'),
46
+ 'next_language' => __('Next', 'ml-slider'),
47
+ 'skip_language' => __('Skip this step', 'ml-slider'),
48
+ 'upgrade_link' => metaslider_get_upgrade_link(),
49
+ 'is_pro' => metaslider_is_pro_active(),
50
+ 'step1' => array(
51
+ 'title' => __("Add A Slide", "ml-slider"),
52
+ 'message' => __("Congratulations! Now that you've created a slideshow, click here to add a slide.", "ml-slider")
53
+ ),
54
+ 'step2a' => array(
55
+ 'title' => __("Select Slide Type", "ml-slider"),
56
+ '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")
57
+ ),
58
+ 'step2b' => array(
59
+ 'title' => __("Select Media", "ml-slider"),
60
+ 'message' => __("After you have selected your media from the left, click below to continue.", "ml-slider")
61
+ ),
62
+ 'step3' => array(
63
+ 'title' => __("Preview Slideshow", "ml-slider"),
64
+ 'message' => __("Now that you have some slides set, you can preview your slideshow by clicking here.", "ml-slider")
65
+ ),
66
+ 'step4' => array(
67
+ 'title' => __("Adjust Settings", "ml-slider"),
68
+ 'message' => __("If you need to adjust the settings for this slideshow, you may do so here.", "ml-slider")
69
+ ),
70
+ 'step5' => array(
71
+ 'title' => __("Shortcode Usage", "ml-slider"),
72
+ 'message' => __("You are all set! If you want to add the slideshow to a post, you may use this shortcode.", "ml-slider"),
73
+ 'button' => __('Finish')
74
+ ),
75
+ 'final_ad' => array(
76
+ 'title' => __("Congratulations!", "ml-slider"),
77
+ 'message' => __("You've completed the tour and are ready to add great slideshows to your website. Don't forget, if you want your slideshows to really stand out, pick up the add-on pack today. ", "ml-slider"),
78
+ 'button' => __('Finish')
79
+ )
80
+ )
81
+ ));
82
+ wp_enqueue_script('metaslider-tour-js');
83
+ }
84
+
85
+ /**
86
+ * Removes the tour status so the tour can be seen again
87
+ *
88
+ * @return bool|WP_Error The Boolean should be true
89
+ */
90
+ public function reset_tour_status() {
91
+
92
+ // If the option isn't set, the tour hasn't been cancelled
93
+ if (!get_option('metaslider_tour_cancelled_on')) {
94
+ return 'The tour is still active. Everything should be ok.';
95
+ }
96
+
97
+ $result = delete_option('metaslider_tour_cancelled_on');
98
+ return $result ? 'The tour status was successfully reset' : new WP_Error('update_failed', 'The attempt to update the tour option failed.', array('status' => 409));
99
+ }
100
+
101
+ /**
102
+ * Updates the stored value for which step the tour ended on
103
+ * @param object $request - the http $_REQUEST obj
104
+ * @return bool|WP_Error The Boolean should be true
105
+ */
106
+ public function set_tour_status($request) {
107
+ $result = update_option('metaslider_tour_cancelled_on', $request['current_step']);
108
+ return $result ? 'The tour status was successfully updated' : new WP_Error('update_failed', 'The attempt to update the tour option failed.', array('status' => 409));
109
+ }
110
+
111
+ /**
112
+ * Handles AJAX calls
113
+ *
114
+ * @return String - (JSON) Sends a success response unless an error is encountered
115
+ */
116
+ public function handle_ajax() {
117
+ if (!wp_verify_nonce($_REQUEST['_wpnonce'], 'metaslider_tour_nonce')) {
118
+ return wp_send_json_error(array(
119
+ 'message' => __('The security check failed. Please refresh the page and try again.', 'ml-slider')
120
+ ), 401);
121
+ }
122
+
123
+ $method = str_replace('ajax_', '', $_POST['action']);
124
+ if (!method_exists($this, $method)) {
125
+ return wp_send_json_error(array(
126
+ 'message' => __('This method does not exist. Please refresh the page and try again.', 'ml-slider')
127
+ ), 401);
128
+ }
129
+
130
+ // Call the dynamic method
131
+ $result = $this->{$method}($_REQUEST);
132
+
133
+ if (is_wp_error($result)) {
134
+ return wp_send_json_error(array(
135
+ 'message' => $result->get_error_message()
136
+ ), 409);
137
+ }
138
+
139
+ return wp_send_json_success(array(
140
+ 'message' => $result,
141
+ ), 200);
142
+ }
143
+ }
admin/assets/css/admin.css ADDED
@@ -0,0 +1,1529 @@
1
+ .metaslider.wrap div.updated,
2
+ .metaslider.wrap div.error {
3
+ clear: both
4
+ }
5
+
6
+ .metaslider #post-body.columns-2 #postbox-container-1 {
7
+ margin-right: -320px;
8
+ width: 300px;
9
+ }
10
+
11
+ .metaslider #poststuff #post-body.columns-2 {
12
+ margin-right: 320px;
13
+ }
14
+
15
+ .rtl .metaslider #post-body.columns-2 #postbox-container-1 {
16
+ margin-left: -320px;
17
+ margin-right: 0;
18
+ }
19
+
20
+ .rtl .metaslider #poststuff #post-body.columns-2 {
21
+ margin-left: 320px;
22
+ margin-right: 0;
23
+ }
24
+
25
+
26
+ .metaslider .left input,
27
+ .metaslider .left textarea {
28
+ border: 1px solid #ccc;
29
+ border-radius: 0;
30
+ resize: none;
31
+ box-shadow: inherit;
32
+ }
33
+
34
+ .media-frame-menu .separator {
35
+ display: none
36
+ }
37
+
38
+ .msTipsy .tipsy-arrow-s {
39
+ border-top-color: #555
40
+ }
41
+
42
+ .msTipsy .tipsy-arrow-w {
43
+ border-right-color: #555
44
+ }
45
+
46
+ .msTipsy .tipsy-arrow-n {
47
+ border-bottom-color: #555
48
+ }
49
+
50
+ .msTipsy .tipsy-inner {
51
+ color: white;
52
+ background-color: #555;
53
+ }
54
+
55
+ .msTipsy .tipsy-arrow-e {
56
+ border-left-color: #555
57
+ }
58
+
59
+ #cboxLoadedContent {
60
+ overflow: hidden !important
61
+ }
62
+
63
+ #cboxLoadedContent iframe {
64
+ border: 0 none;
65
+ display: block;
66
+ height: 100%;
67
+ width: 100%;
68
+ }
69
+
70
+ .metaslider .right input[type=submit] {
71
+ margin: 0 3px;
72
+ }
73
+
74
+ .metaslider #poststuff .right .configuration {
75
+ padding: 7px 7px 7px 12px;
76
+ line-height: 27px;
77
+ float: left;
78
+ width: 100%;
79
+ box-sizing: border-box;
80
+ }
81
+
82
+ .metaslider .left table tr.slide input.url {
83
+ width: 100%;
84
+ margin: 0;
85
+ padding: 4px;
86
+ }
87
+
88
+ .metaslider .section {
89
+ cursor: pointer
90
+ }
91
+
92
+ .metaslider .hidden {
93
+ display: none
94
+ }
95
+
96
+ .metaslider .tipsy-tooltip {
97
+ cursor: default
98
+ }
99
+
100
+ .metaslider .ui-sortable-helper {
101
+ box-shadow: 3px 3px 5px #cccccc
102
+ }
103
+
104
+ .metaslider .left table tr.slide textarea {
105
+ width: 100%;
106
+ height: 60px;
107
+ margin: 0 0 5px 0;
108
+ padding: 2px 5px;
109
+ }
110
+
111
+ .branch-3-5 .metaslider .left table tr.slide .tabs-content .new_window,
112
+ .branch-3-6 .metaslider .left table tr.slide .tabs-content .new_window,
113
+ .branch-3-7 .metaslider .left table tr.slide .tabs-content .new_window {
114
+ right: 6px;
115
+ bottom: 20px;
116
+ }
117
+
118
+ .branch-3-5 .metaslider .left table tr.slide .tabs-content .new_window label,
119
+ .branch-3-6 .metaslider .left table tr.slide .tabs-content .new_window label,
120
+ .branch-3-7 .metaslider .left table tr.slide .tabs-content .new_window label {
121
+ line-height: 18px;
122
+ vertical-align: top;
123
+ }
124
+
125
+ .branch-3-5 .metaslider .left table tr.slide .tabs-content .new_window input,
126
+ .branch-3-6 .metaslider .left table tr.slide .tabs-content .new_window input,
127
+ .branch-3-7 .metaslider .left table tr.slide .tabs-content .new_window input {
128
+ margin: -2px 0 0 4px;
129
+ }
130
+
131
+ .metaslider .left table tr.slide .tabs-content .new_window {
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;
144
+ }
145
+
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
+ }
163
+
164
+ .metaslider .right .highlight {
165
+ background: transparent;
166
+ border: 0;
167
+ font-weight: bold;
168
+ }
169
+
170
+ /* *
171
+ * Change background color for label next to checked radio button
172
+ * to make it look like highlighted button
173
+ ================================================== */
174
+
175
+ .metaslider .right .slider-lib-row input[type=radio]:checked + label {
176
+ background-image: none;
177
+ background-color: #d0d0d0;
178
+ }
179
+
180
+ .metaslider .right .slider-lib-row input[type=radio] {
181
+ display: none;
182
+ }
183
+
184
+ .ie8 .metaslider .right .slider-lib-row input[type=radio] {
185
+ display: inline;
186
+ }
187
+
188
+ .metaslider .right .slider-lib-row input[type=radio] + label {
189
+ display: inline-block;
190
+ margin: -2px;
191
+ padding: 4px 0;
192
+ margin-bottom: 0;
193
+ font-size: 11px;
194
+ line-height: 20px;
195
+ color: #333;
196
+ text-align: center;
197
+ vertical-align: middle;
198
+ cursor: pointer;
199
+ background-color: #f5f5f5;
200
+ background-image: -moz-linear-gradient(top,#fff,#e6e6e6);
201
+ background-image: -webkit-gradient(linear,0 0,0 100%,from(#fff),to(#e6e6e6));
202
+ background-image: -webkit-linear-gradient(top,#fff,#e6e6e6);
203
+ background-image: -o-linear-gradient(top,#fff,#e6e6e6);
204
+ background-image: linear-gradient(to bottom,#fff,#e6e6e6);
205
+ background-repeat: repeat-x;
206
+ border: 1px solid #ddd;
207
+ border-color: #e6e6e6 #e6e6e6 #bfbfbf;
208
+ border-color: rgba(0,0,0,0.1) rgba(0,0,0,0.1) rgba(0,0,0,0.25);
209
+ border-bottom-color: #b3b3b3;
210
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0);
211
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
212
+ -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);
213
+ -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);
214
+ box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05);
215
+ width: 24%;
216
+ }
217
+
218
+ input[type=radio]:checked + label {
219
+ background-image: none;
220
+ outline: 0;
221
+ -webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
222
+ -moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
223
+ box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
224
+ background-color: #e0e0e0;
225
+ }
226
+
227
+ .metaslider .right #nivo + label:hover,
228
+ .metaslider .right #nivo:checked + label {
229
+ color: white;
230
+ background: #b6e026;
231
+ background: -moz-linear-gradient(top, #b6e026 0%, #abdc28 100%);
232
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #b6e026), color-stop(100%, #abdc28));
233
+ background: -webkit-linear-gradient(top, #b6e026 0%, #abdc28 100%);
234
+ background: -o-linear-gradient(top, #b6e026 0%, #abdc28 100%);
235
+ background: -ms-linear-gradient(top, #b6e026 0%, #abdc28 100%);
236
+ background: linear-gradient(to bottom, #b6e026 0%, #abdc28 100%);
237
+ }
238
+
239
+ .metaslider .right #responsive + label:hover,
240
+ .metaslider .right #responsive:checked + label,
241
+ .metaslider .right #responsive:checked {
242
+ color: white;
243
+ background: #ff5db1; /* Old browsers */
244
+ background: -moz-linear-gradient(top, #ff5db1 0%, #ef017c 100%); /* FF3.6+ */
245
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff5db1), color-stop(100%,#ef017c)); /* Chrome,Safari4+ */
246
+ background: -webkit-linear-gradient(top, #ff5db1 0%,#ef017c 100%); /* Chrome10+,Safari5.1+ */
247
+ background: -o-linear-gradient(top, #ff5db1 0%,#ef017c 100%); /* Opera 11.10+ */
248
+ background: -ms-linear-gradient(top, #ff5db1 0%,#ef017c 100%); /* IE10+ */
249
+ background: linear-gradient(to bottom, #ff5db1 0%,#ef017c 100%); /* W3C */
250
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff5db1', endColorstr='#ef017c',GradientType=0 ); /* IE6-9 */
251
+ }
252
+
253
+ .metaslider .right #coin + label:hover,
254
+ .metaslider .right #coin:checked + label {
255
+ color: white;
256
+ background: #ffd65e;
257
+ background: -moz-linear-gradient(top, #ffd65e 0%, #febf04 100%);
258
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ffd65e), color-stop(100%, #febf04));
259
+ background: -webkit-linear-gradient(top, #ffd65e 0%, #febf04 100%);
260
+ background: -o-linear-gradient(top, #ffd65e 0%, #febf04 100%);
261
+ background: -ms-linear-gradient(top, #ffd65e 0%, #febf04 100%);
262
+ background: linear-gradient(to bottom, #ffd65e 0%, #febf04 100%);
263
+ }
264
+
265
+ .metaslider .right #flex + label:hover,
266
+ .metaslider .right #flex:checked + label {
267
+ color: white;
268
+ background: #00b7ea;
269
+ background: -moz-linear-gradient(top, #00b7ea 0%, #009ec3 100%);
270
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #00b7ea), color-stop(100%, #009ec3));
271
+ background: -webkit-linear-gradient(top, #00b7ea 0%, #009ec3 100%);
272
+ background: -o-linear-gradient(top, #00b7ea 0%, #009ec3 100%);
273
+ background: -ms-linear-gradient(top, #00b7ea 0%, #009ec3 100%);
274
+ background: linear-gradient(to bottom, #00b7ea 0%, #009ec3 100%);
275
+ }
276
+ .metaslider .right .slider-lib-row label:focus,
277
+ .metaslider .right .slider-lib-row label:active {
278
+ background: #acd7fd !important;
279
+ box-shadow: none !important;
280
+ outline: none;
281
+ }
282
+ .metaslider .right .slider-lib-row {
283
+ padding: 17px 0 9px 0;
284
+ text-align: center;
285
+ }
286
+
287
+ .metaslider .right #save {
288
+ margin-right: 0
289
+ }
290
+ .rtl .metaslider .right #save {
291
+ margin-right: 4px;
292
+ margin-left: 0;
293
+ }
294
+
295
+ .metaslider .right .number input:focus {
296
+ outline: none;
297
+ outline-style: none;
298
+ box-shadow: none;
299
+ background-color: #acd7fd;
300
+ color: #444;
301
+ }
302
+
303
+ .metaslider .right .number .after,
304
+ .metaslider .right .number input {
305
+ display: block;
306
+ float: left;
307
+ height: 26px;
308
+ margin: 0;
309
+ }
310
+
311
+ .rtl .metaslider .right .number .after,
312
+ .rtl .metaslider .right .number input {
313
+ float: right;
314
+ }
315
+ .rtl .metaslider .right .number .after {
316
+ border-left: 1px solid #ddd;
317
+ border-right: 0;
318
+ }
319
+ .rtl .metaslider .right .number input {
320
+ border-right: 1px solid #ddd;
321
+ border-left: 0;
322
+ }
323
+
324
+ .metaslider .right .radio ul {
325
+ margin: 0;
326
+ }
327
+ .metaslider .right .radio li {
328
+ margin: 0 0 2px 0;
329
+ clear: both;
330
+ }
331
+ .metaslider .right .radio input[type="radio"] {
332
+ margin-top: 0;
333
+ }
334
+ .rtl .metaslider .right .radio input[type="radio"] {
335
+ float: right;
336
+ }
337
+
338
+ .metaslider .right .number input {
339
+ width: 70px;
340
+ margin-right: 0;
341
+ box-shadow: none;
342
+ border-right: 0;
343
+ }
344
+
345
+ .metaslider .right .number .after {
346
+ border: 1px solid #ddd;
347
+ border-left: 0;
348
+ box-shadow: none;
349
+ font-size: 11px;
350
+ height: 24px;
351
+ line-height: 24px;
352
+ padding: 0 3px;
353
+ background: white;
354
+ }
355
+
356
+ .metaslider .right input[type="text"],
357
+ .metaslider .right select {
358
+ width: 130px;
359
+ }
360
+
361
+ .metaslider #poststuff .right .ms-postbox .inside {
362
+ padding: 8px 12px 12px 12px;
363
+ margin: 0;
364
+ }
365
+
366
+ .ms-postbox .handlediv {
367
+ float: right;
368
+ width: 27px;
369
+ height: 30px;
370
+ cursor: pointer;
371
+ color: #aaa;
372
+ }
373
+
374
+ .ms-postbox .handlediv:before {
375
+ right: 12px;
376
+ font: 400 20px/1 dashicons;
377
+ speak: none;
378
+ display: inline-block;
379
+ padding: 8px 10px;
380
+ top: 0;
381
+ position: relative;
382
+ -webkit-font-smoothing: antialiased;
383
+ -moz-osx-font-smoothing: grayscale;
384
+ text-decoration: none !important;
385
+ content: '\f142';
386
+ }
387
+
388
+ .ms-postbox.closed .handlediv:before {
389
+ content: '\f140';
390
+ }
391
+
392
+ .metaslider .shortcode .inside {
393
+ padding: 15px 10px;
394
+ }
395
+
396
+ .metaslider .social .inside {
397
+ padding: 10px;
398
+ }
399
+
400
+ .metaslider .social .inside ul.info {
401
+ width: 100%;
402
+ margin: 0;
403
+ height: 20px;
404
+ }
405
+
406
+ .metaslider .shortcode input[type=text],
407
+ .metaslider .shortcode input[type=text]:active,
408
+ .metaslider .shortcode textarea,
409
+ .metaslider .shortcode textarea:active {
410
+ font-family: monospace;
411
+ font-size: 11px;
412
+ width: 100%;
413
+ background: transparent;
414
+ border: 0;
415
+ box-shadow: none;
416
+ }
417
+
418
+ .metaslider .shortcode textarea {
419
+ height: 65px;
420
+ }
421
+
422
+ .metaslider .shortcode ul.tabs {
423
+ margin: 0;
424
+ }
425
+
426
+ .metaslider .shortcode ul.tabs li.selected {
427
+ background: #fdfdfd;
428
+ border-bottom: 1px solid #fdfdfd;
429
+ }
430
+
431
+ .metaslider .shortcode .tabs-content {
432
+ clear: both;
433
+ background: #fdfdfd;
434
+ border-left: 1px solid #ccc;
435
+ border-right: 1px solid #ccc;
436
+ border-bottom: 1px solid #ccc;
437
+ padding: 10px;
438
+ }
439
+
440
+ .metaslider .right .ms-postbox table {
441
+ border: 0;
442
+ width: 100%;
443
+ }
444
+
445
+ .metaslider .right .ms-postbox table textarea {
446
+ width: 100%;
447
+ height: 100px;
448
+ font-family: monospace;
449
+ background: #272822;
450
+ color: #a6e22e;
451
+ }
452
+
453
+ .metaslider .right .ms-postbox h3 {
454
+ cursor: inherit;
455
+ }
456
+
457
+ .metaslider .right .ms-postbox.ms-toggle h3 {
458
+ cursor: pointer;
459
+ }
460
+
461
+ .metaslider .right table {
462
+ margin: 0 0 5px 0;
463
+ }
464
+
465
+ .metaslider .right table td {
466
+ vertical-align: middle;
467
+ padding: 8px 4px;
468
+ border: 0;
469
+ height: 21px;
470
+ }
471
+
472
+ .metaslider select {
473
+ height: auto;
474
+ }
475
+
476
+ .metaslider .warning {
477
+ background-color: #ffebe8;
478
+ border: 1px solid #c00;
479
+ margin-bottom: 5px;
480
+ border-radius: 3px;
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
+
492
+ .attachment-display-settings {
493
+ display: none;
494
+ }
495
+
496
+ .metaslider .tabs-content,
497
+