EmbedPress – Embed Google Docs, YouTube, Maps, Vimeo, Wistia Videos & Upload PDF, PPT in Gutenberg & Elementor - Version 2.4.0

Version Description

Download this release

Release Info

Developer re_enter_rupok
Plugin Icon wp plugin EmbedPress – Embed Google Docs, YouTube, Maps, Vimeo, Wistia Videos & Upload PDF, PPT in Gutenberg & Elementor
Version 2.4.0
Comparing to
See all releases

Code changes from version 2.3.3 to 2.4.0

Files changed (47) hide show
  1. EmbedPress/Core.php +131 -133
  2. EmbedPress/CoreLegacy.php +4 -1
  3. EmbedPress/Ends/Back/Settings.php +54 -87
  4. EmbedPress/Ends/Back/index.html +0 -0
  5. EmbedPress/Ends/Front/index.html +0 -0
  6. EmbedPress/Ends/index.html +0 -0
  7. EmbedPress/Includes/Classes/EmbedPress_Core_Installer.php +107 -0
  8. EmbedPress/Includes/Classes/EmbedPress_Notice.php +904 -0
  9. EmbedPress/Includes/Classes/EmbedPress_Plugin_Usage_Tracker.php +996 -0
  10. EmbedPress/Includes/Traits/Shared.php +160 -0
  11. EmbedPress/Plugins/Html/Field.php +0 -45
  12. EmbedPress/Plugins/Plugin.php +14 -71
  13. EmbedPress/RestAPI.php +9 -4
  14. EmbedPress/Shortcode.php +12 -5
  15. EmbedPress/index.html +0 -0
  16. Gutenberg/src/common/core-embeds.js +0 -0
  17. Gutenberg/src/common/embed-controls.js +0 -0
  18. Gutenberg/src/common/embed-loading.js +0 -0
  19. Gutenberg/src/common/embed-placeholder.js +0 -0
  20. Gutenberg/src/common/icons.js +0 -0
  21. assets/css/admin.css +13 -10
  22. assets/css/embedpress.css +3 -0
  23. assets/css/index.html +0 -0
  24. assets/css/preview.css +1 -1
  25. assets/css/vendor/bootstrap/bootstrap.css +0 -0
  26. assets/css/vendor/bootstrap/bootstrap.css.map +0 -0
  27. assets/css/vendor/bootstrap/bootstrap.min.css +0 -0
  28. assets/css/vendor/bootstrap/index.html +0 -0
  29. assets/css/vendor/index.html +0 -0
  30. assets/fonts/embedpress.eot +0 -0
  31. assets/fonts/embedpress.svg +0 -0
  32. assets/fonts/embedpress.ttf +0 -0
  33. assets/fonts/embedpress.woff +0 -0
  34. assets/fonts/index.html +0 -0
  35. assets/images/index.html +0 -0
  36. assets/images/menu-icon.png +0 -0
  37. assets/images/nx-icon.svg +19 -0
  38. assets/index.html +0 -0
  39. assets/js/index.html +0 -0
  40. assets/js/vendor/bootstrap/bootstrap.js +0 -0
  41. assets/js/vendor/bootstrap/bootstrap.min.js +0 -0
  42. assets/js/vendor/bootstrap/index.html +0 -0
  43. assets/js/vendor/index.html +0 -0
  44. embedpress.php +13 -7
  45. includes.php +6 -5
  46. index.html +0 -0
  47. readme.txt +220 -121
EmbedPress/Core.php CHANGED
@@ -5,6 +5,7 @@ namespace EmbedPress;
5
  use EmbedPress\Ends\Back\Handler as EndHandlerAdmin;
6
  use EmbedPress\Ends\Front\Handler as EndHandlerPublic;
7
 
 
8
  (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
9
 
10
  /**
@@ -16,8 +17,9 @@ use EmbedPress\Ends\Front\Handler as EndHandlerPublic;
16
  * @license GPLv2 or later
17
  * @since 1.0.0
18
  */
19
- class Core
20
- {
 
21
  /**
22
  * The name of the plugin.
23
  *
@@ -44,7 +46,7 @@ class Core
44
  * @since 1.0.0
45
  * @access protected
46
  *
47
- * @var \EmbedPress\Loader $pluginVersion The version of the plugin.
48
  */
49
  protected $loaderInstance;
50
 
@@ -62,63 +64,60 @@ class Core
62
  /**
63
  * Initialize the plugin and set its properties.
64
  *
 
65
  * @since 1.0.0
66
  *
67
- * @return void
68
  */
69
- public function __construct()
70
- {
71
- $this->pluginName = EMBEDPRESS_PLG_NAME;
72
  $this->pluginVersion = EMBEDPRESS_VERSION;
73
 
74
  $this->loaderInstance = new Loader();
 
 
75
  }
76
 
77
  /**
78
  * Method that retrieves the plugin name.
79
  *
 
80
  * @since 1.0.0
81
  *
82
- * @return string
83
  */
84
- public function getPluginName()
85
- {
86
  return $this->pluginName;
87
  }
88
 
89
  /**
90
  * Method that retrieves the plugin version.
91
  *
 
92
  * @since 1.0.0
93
  *
94
- * @return string
95
  */
96
- public function getPluginVersion()
97
- {
98
  return $this->pluginVersion;
99
  }
100
 
101
  /**
102
  * Method that retrieves the loader instance.
103
  *
 
104
  * @since 1.0.0
105
  *
106
- * @return \EmbedPress\Loader
107
  */
108
- public function getLoader()
109
- {
110
  return $this->loaderInstance;
111
  }
112
 
113
  /**
114
  * Method responsible to connect all required hooks in order to make the plugin work.
115
  *
 
116
  * @since 1.0.0
117
  *
118
- * @return void
119
  */
120
- public function initialize()
121
- {
122
  global $wp_actions;
123
 
124
  add_filter('oembed_providers', [$this, 'addOEmbedProviders']);
@@ -126,7 +125,7 @@ class Core
126
 
127
  if (is_admin()) {
128
  $plgSettings = self::getSettings();
129
-
130
  $settingsClassNamespace = '\\EmbedPress\\Ends\\Back\\Settings';
131
  add_action('admin_menu', [$settingsClassNamespace, 'registerMenuItem']);
132
  add_action('admin_init', [$settingsClassNamespace, 'registerActions']);
@@ -139,7 +138,7 @@ class Core
139
 
140
  $plgHandlerAdminInstance = new EndHandlerAdmin($this->getPluginName(), $this->getPluginVersion());
141
 
142
- if ((bool)$plgSettings->enablePluginInAdmin) {
143
  $this->loaderInstance->add_action('admin_enqueue_scripts', $plgHandlerAdminInstance, 'enqueueScripts');
144
  }
145
  } else {
@@ -157,7 +156,7 @@ class Core
157
  // Add support for our embeds on Beaver Builder. Without this it only run the native embeds.
158
  add_filter('fl_builder_before_render_shortcodes',
159
  ['\\EmbedPress\\ThirdParty\\BeaverBuilder', 'before_render_shortcodes']);
160
-
161
  $this->loaderInstance->run();
162
  }
163
 
@@ -166,153 +165,152 @@ class Core
166
  *
167
  * @return mixed
168
  */
169
- public function addOEmbedProviders($providers)
170
- {
171
  $newProviders = [
172
  // Viddler
173
- '#https?://(.+\.)?viddler\.com/v/.+#i' => 'viddler',
174
 
175
  // Deviantart.com (http://www.deviantart.com)
176
- '#https?://(.+\.)?deviantart\.com/art/.+#i' => 'devianart',
177
- '#https?://(.+\.)?deviantart\.com/.+#i' => 'devianart',
178
- '#https?://(.+\.)?deviantart\.com/.*/d.+#i' => 'devianart',
179
- '#https?://(.+\.)?fav\.me/.+#i' => 'devianart',
180
- '#https?://(.+\.)?sta\.sh/.+#i' => 'devianart',
181
 
182
  // chirbit.com (http://www.chirbit.com/)
183
- '#https?://(.+\.)?chirb\.it/.+#i' => 'chirbit',
184
 
185
 
186
  // nfb.ca (http://www.nfb.ca/)
187
- '#https?://(.+\.)?nfb\.ca/film/.+#i' => 'nfb',
188
 
189
  // Dotsub (http://dotsub.com/)
190
- '#https?://(.+\.)?dotsub\.com/view/.+#i' => 'dotsub',
191
 
192
  // Rdio (http://rdio.com/)
193
- '#https?://(.+\.)?rdio\.com/(artist|people)/.+#i' => 'rdio',
194
 
195
  // Sapo Videos (http://videos.sapo.pt)
196
- '#https?://(.+\.)?videos\.sapo\.pt/.+#i' => 'sapo',
197
 
198
  // Official FM (http://official.fm)
199
- '#https?://(.+\.)?official\.fm/(tracks|playlists)/.+#i' => 'officialfm',
200
 
201
  // HuffDuffer (http://huffduffer.com)
202
- '#https?://(.+\.)?huffduffer\.com/.+#i' => 'huffduffer',
203
 
204
  // Shoudio (http://shoudio.com)
205
- '#https?://(.+\.)?shoudio\.(com|io)/.+#i' => 'shoudio',
206
 
207
  // Moby Picture (http://www.mobypicture.com)
208
- '#https?://(.+\.)?mobypicture\.com/user/.+/view/.+#i' => 'mobypicture',
209
  '#https?://(.+\.)?moby\.to/.+#i',
210
 
211
  // 23HQ (http://www.23hq.com)
212
- '#https?://(.+\.)?23hq\.com/.+/photo/.+#i' => '23hq',
213
 
214
  // Cacoo (https://cacoo.com)
215
- '#https?://(.+\.)?cacoo\.com/diagrams/.+#i' => 'cacoo',
216
 
217
  // Dipity (http://www.dipity.com)
218
- '#https?://(.+\.)?dipity\.com/.+#i' => 'dipity',
219
 
220
  // Roomshare (http://roomshare.jp)
221
- '#https?://(.+\.)?roomshare\.jp/(en/)?post/.+#i' => 'roomshare',
222
 
223
  // Crowd Ranking (http://crowdranking.com)
224
- '#https?://(.+\.)?c9ng\.com/.+#i' => 'crowd',
225
 
226
  // CircuitLab (https://www.circuitlab.com/)
227
- '#https?://(.+\.)?circuitlab\.com/circuit/.+#i' => 'circuitlab',
228
 
229
  // Coub (http://coub.com/)
230
- '#https?://(.+\.)?coub\.com/(view|embed)/.+#i' => 'coub',
231
 
232
  // Ustream (http://www.ustream.tv)
233
- '#https?://(.+\.)?ustream\.(tv|com)/.+#i' => 'ustream',
234
 
235
  // Daily Mile (http://www.dailymile.com)
236
- '#https?://(.+\.)?dailymile\.com/people/.+/entries/.+#i' => 'daily',
237
 
238
  // Sketchfab (http://sketchfab.com)
239
- '#https?://(.+\.)?sketchfab\.com/models/.+#i' => 'sketchfab',
240
- '#https?://(.+\.)?sketchfab\.com/.+/folders/.+#i' => 'sketchfab',
241
 
242
  // AudioSnaps (http://audiosnaps.com)
243
- '#https?://(.+\.)?audiosnaps\.com/k/.+#i' => 'audiosnaps',
244
 
245
  // RapidEngage (https://rapidengage.com)
246
- '#https?://(.+\.)?rapidengage\.com/s/.+#i' => 'rapidengage',
247
 
248
  // Getty Images (http://www.gettyimages.com/)
249
- '#https?://(.+\.)?gty\.im/.+#i' => 'gettyimages',
250
- '#https?://(.+\.)?gettyimages\.com/detail/photo/.+#i' => 'gettyimages',
251
 
252
  // amCharts Live Editor (http://live.amcharts.com/)
253
- '#https?://(.+\.)?live\.amcharts\.com/.+#i' => 'amcharts',
254
 
255
  // Infogram (https://infogr.am/)
256
- '#https?://(.+\.)?infogr\.am/.+#i' => 'infogram',
257
 
258
  // ChartBlocks (http://www.chartblocks.com/)
259
- '#https?://(.+\.)?public\.chartblocks\.com/c/.+#i' => 'chartblocks',
260
 
261
  // ReleaseWire (http://www.releasewire.com/)
262
- '#https?://(.+\.)?rwire\.com/.+#i' => 'releasewire',
263
 
264
  // ShortNote (https://www.shortnote.jp/)
265
- '#https?://(.+\.)?shortnote\.jp/view/notes/.+#i' => 'shortnote',
266
 
267
  // EgliseInfo (http://egliseinfo.catholique.fr/)
268
- '#https?://(.+\.)?egliseinfo\.catholique\.fr/.+#i' => 'egliseinfo',
269
 
270
  // Silk (http://www.silk.co/)
271
- '#https?://(.+\.)?silk\.co/explore/.+#i' => 'silk',
272
- '#https?://(.+\.)?silk\.co/s/embed/.+#i' => 'silk',
273
 
274
  // http://bambuser.com
275
- '#https?://(.+\.)?bambuser\.com/v/.+#i' => 'bambuser',
276
 
277
  // https://clyp.it
278
- '#https?://(.+\.)?clyp\.it/.+#i' => 'clyp',
279
 
280
  // https://gist.github.com
281
- '#https?://(.+\.)?gist\.github\.com/.+#i' => 'github',
282
 
283
  // https://portfolium.com
284
- '#https?://(.+\.)?portfolium\.com/.+#i' => 'portfolium',
285
 
286
  // http://rutube.ru
287
- '#https?://(.+\.)?rutube\.ru/video/.+#i' => 'rutube',
288
 
289
  // http://www.videojug.com
290
- '#https?://(.+\.)?videojug\.com/.+#i' => 'videojug',
291
 
292
  // https://vine.com
293
- '#https?://(.+\.)?vine\.co/v/.+#i' => 'vine',
294
 
295
  // Google Shortened Url
296
- '#https?://(.+\.)?goo\.gl/.+#i' => 'google',
297
 
298
  // Google Maps
299
- '#https?://(.+\.)?google\.com/maps/.+#i' => 'googlemaps',
300
- '#https?://(.+\.)?maps\.google\.com/.+#i' => 'googlemaps',
301
 
302
  // Google Docs
303
  '#https?://(.+\.)?docs\.google\.com/(.+/)?(document|presentation|spreadsheets|forms|drawings)/.+#i' => 'googledocs',
304
 
305
  // Twitch.tv
306
- '#https?://(.+\.)?twitch\.tv/.+#i' => 'twitch',
307
 
308
  // Giphy
309
- '#https?://(.+\.)?giphy\.com/gifs/.+#i' => 'giphy',
310
- '#https?://(.+\.)?i\.giphy\.com/.+#i' => 'giphy',
311
- '#https?://(.+\.)?gph\.is/.+#i' => 'giphy',
312
 
313
  // Wistia
314
- '#https?://(.+\.)?wistia\.com/medias/.+#i' => 'wistia',
315
- '#https?://(.+\.)?fast\.wistia\.com/embed/medias/.+#i\.jsonp' => 'wistia',
316
  ];
317
 
318
  /**
@@ -324,22 +322,22 @@ class Core
324
  */
325
  global $wp_rewrite;
326
 
327
- if ( ! class_exists('\\WP_Rewrite')) {
328
- $path = ABSPATH . WPINC . '/class-wp-rewrite.php';
329
  if (file_exists($path)) {
330
  require_once $path;
331
  }
332
  }
333
 
334
- if ( ! is_object($wp_rewrite)) {
335
- $wp_rewrite = new \WP_Rewrite();
336
  $_GLOBALS['wp_write'] = $wp_rewrite;
337
  }
338
  /*========================================*/
339
 
340
  foreach ($newProviders as $url => &$data) {
341
  $data = [
342
- rest_url('embedpress/v1/oembed/' . $data),
343
  true,
344
  ];
345
  }
@@ -352,12 +350,11 @@ class Core
352
  /**
353
  * Register OEmbed Rest Routes
354
  */
355
- public function registerOEmbedRestRoutes()
356
- {
357
  register_rest_route(
358
  'embedpress/v1', '/oembed/(?P<provider>[a-zA-Z0-9\-]+)',
359
  [
360
- 'methods' => \WP_REST_Server::READABLE,
361
  'callback' => ['\\EmbedPress\\RestAPI', 'oembed'],
362
  ]
363
  );
@@ -366,40 +363,37 @@ class Core
366
  /**
367
  * Callback called right after the plugin has been activated.
368
  *
 
369
  * @since 1.0.0
370
  * @static
371
  *
372
- * @return void
373
  */
374
- public static function onPluginActivationCallback()
375
- {
376
  flush_rewrite_rules();
377
  }
378
 
379
  /**
380
  * Callback called right after the plugin has been deactivated.
381
  *
 
382
  * @since 1.0.0
383
  * @static
384
  *
385
- * @return void
386
  */
387
- public static function onPluginDeactivationCallback()
388
- {
389
  flush_rewrite_rules();
390
  }
391
 
392
  /**
393
  * Method that retrieves all additional service providers defined in the ~<plugin_root_path>/providers.php file.
394
  *
 
395
  * @since 1.0.0
396
  * @static
397
  *
398
- * @return array
399
  */
400
- public static function getAdditionalServiceProviders()
401
- {
402
- $additionalProvidersFilePath = EMBEDPRESS_PATH_BASE . 'providers.php';
403
  if (file_exists($additionalProvidersFilePath)) {
404
  include $additionalProvidersFilePath;
405
 
@@ -414,15 +408,14 @@ class Core
414
  /**
415
  * Method that checks if an embed of a given service provider can be responsive.
416
  *
 
 
 
417
  * @since 1.0.0
418
  * @static
419
  *
420
- * @param string $serviceProviderAlias The service's slug.
421
- *
422
- * @return boolean
423
  */
424
- public static function canServiceProviderBeResponsive($serviceProviderAlias)
425
- {
426
  return in_array($serviceProviderAlias, [
427
  "dailymotion",
428
  "kickstarter",
@@ -444,64 +437,70 @@ class Core
444
  /**
445
  * Method that retrieves the plugin settings defined by the user.
446
  *
 
447
  * @since 1.0.0
448
  * @static
449
  *
450
- * @return object
451
  */
452
- public static function getSettings()
453
- {
454
  $settings = get_option(EMBEDPRESS_PLG_NAME);
455
 
456
- if ( ! isset($settings['enablePluginInAdmin'])) {
457
  $settings['enablePluginInAdmin'] = true;
458
  }
459
 
460
- if ( ! isset($settings['enablePluginInFront'])) {
461
  $settings['enablePluginInFront'] = true;
462
  }
463
 
464
- return (object)$settings;
 
 
 
 
 
 
 
 
465
  }
466
 
467
  /**
468
  * Method that register an EmbedPress plugin.
469
  *
 
 
 
470
  * @since 1.4.0
471
  * @static
472
  *
473
- * @param array $pluginMeta Associative array containing plugin's name, slug and namespace
474
- *
475
- * @return void
476
  */
477
- public static function registerPlugin($pluginMeta)
478
- {
479
  $pluginMeta = json_decode(json_encode($pluginMeta));
480
 
481
  if (empty($pluginMeta->name) || empty($pluginMeta->slug) || empty($pluginMeta->namespace)) {
482
  return;
483
  }
484
 
485
- if ( ! isset(self::$plugins[$pluginMeta->slug])) {
486
  AutoLoader::register($pluginMeta->namespace,
487
- WP_PLUGIN_DIR . '/' . EMBEDPRESS_PLG_NAME . '-' . $pluginMeta->slug . '/' . $pluginMeta->name);
488
 
489
  $plugin = "{$pluginMeta->namespace}\Plugin";
490
  if (\defined("{$plugin}::SLUG") && $plugin::SLUG !== null) {
491
  self::$plugins[$pluginMeta->slug] = $pluginMeta->namespace;
492
 
493
- $bsFilePath = $plugin::PATH . EMBEDPRESS_PLG_NAME . '-' . $plugin::SLUG . '.php';
494
 
495
  register_activation_hook($bsFilePath, [$plugin::NAMESPACE_STRING, 'onActivationCallback']);
496
  register_deactivation_hook($bsFilePath, [$plugin::NAMESPACE_STRING, 'onDeactivationCallback']);
497
 
498
  add_action('admin_init', [$plugin, 'onLoadAdminCallback']);
499
 
500
- add_action(EMBEDPRESS_PLG_NAME . ':' . $plugin::SLUG . ':settings:register',
501
  [$plugin, 'registerSettings']);
502
- add_action(EMBEDPRESS_PLG_NAME . ':settings:render:tab', [$plugin, 'renderTab']);
503
 
504
- add_filter('plugin_action_links_embedpress-' . $plugin::SLUG . '/embedpress-' . $plugin::SLUG . '.php',
505
  [$plugin, 'handleActionLinks'], 10, 2);
506
 
507
  $plugin::registerEvents();
@@ -512,28 +511,26 @@ class Core
512
  /**
513
  * Retrieve all registered plugins.
514
  *
 
515
  * @since 1.4.0
516
  * @static
517
  *
518
- * @return array
519
  */
520
- public static function getPlugins()
521
- {
522
  return self::$plugins;
523
  }
524
 
525
  /**
526
  * Handle links displayed below the plugin name in the WordPress Installed Plugins page.
527
  *
 
528
  * @since 1.4.0
529
  * @static
530
  *
531
- * @return array
532
  */
533
- public static function handleActionLinks($links, $file)
534
- {
535
- $settingsLink = '<a href="' . admin_url('admin.php?page=embedpress') . '" aria-label="' . __('Open settings page',
536
- 'embedpress') . '">' . __('Settings', 'embedpress') . '</a>';
537
 
538
  array_unshift($links, $settingsLink);
539
 
@@ -543,21 +540,22 @@ class Core
543
  /**
544
  * Method that ensures the API's url are whitelisted to WordPress external requests.
545
  *
 
 
 
 
 
546
  * @since 1.4.0
547
  * @static
548
  *
549
- * @param boolean $isAllowed
550
- * @param string $host
551
- * @param string $url
552
- *
553
- * @return boolean
554
  */
555
- public static function allowApiHost($isAllowed, $host, $url)
556
- {
557
  if ($host === EMBEDPRESS_LICENSES_API_HOST) {
558
  $isAllowed = true;
559
  }
560
 
561
  return $isAllowed;
562
  }
 
 
563
  }
5
  use EmbedPress\Ends\Back\Handler as EndHandlerAdmin;
6
  use EmbedPress\Ends\Front\Handler as EndHandlerPublic;
7
 
8
+
9
  (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
10
 
11
  /**
17
  * @license GPLv2 or later
18
  * @since 1.0.0
19
  */
20
+ class Core {
21
+ use \EmbedPress\Includes\Traits\Shared;
22
+
23
  /**
24
  * The name of the plugin.
25
  *
46
  * @since 1.0.0
47
  * @access protected
48
  *
49
+ * @var Loader $pluginVersion The version of the plugin.
50
  */
51
  protected $loaderInstance;
52
 
64
  /**
65
  * Initialize the plugin and set its properties.
66
  *
67
+ * @return void
68
  * @since 1.0.0
69
  *
 
70
  */
71
+ public function __construct () {
72
+ $this->pluginName = EMBEDPRESS_PLG_NAME;
 
73
  $this->pluginVersion = EMBEDPRESS_VERSION;
74
 
75
  $this->loaderInstance = new Loader();
76
+
77
+ add_action('admin_notices',[$this,'embedpress_admin_notice']);
78
  }
79
 
80
  /**
81
  * Method that retrieves the plugin name.
82
  *
83
+ * @return string
84
  * @since 1.0.0
85
  *
 
86
  */
87
+ public function getPluginName () {
 
88
  return $this->pluginName;
89
  }
90
 
91
  /**
92
  * Method that retrieves the plugin version.
93
  *
94
+ * @return string
95
  * @since 1.0.0
96
  *
 
97
  */
98
+ public function getPluginVersion () {
 
99
  return $this->pluginVersion;
100
  }
101
 
102
  /**
103
  * Method that retrieves the loader instance.
104
  *
105
+ * @return Loader
106
  * @since 1.0.0
107
  *
 
108
  */
109
+ public function getLoader () {
 
110
  return $this->loaderInstance;
111
  }
112
 
113
  /**
114
  * Method responsible to connect all required hooks in order to make the plugin work.
115
  *
116
+ * @return void
117
  * @since 1.0.0
118
  *
 
119
  */
120
+ public function initialize () {
 
121
  global $wp_actions;
122
 
123
  add_filter('oembed_providers', [$this, 'addOEmbedProviders']);
125
 
126
  if (is_admin()) {
127
  $plgSettings = self::getSettings();
128
+ $this->admin_notice();
129
  $settingsClassNamespace = '\\EmbedPress\\Ends\\Back\\Settings';
130
  add_action('admin_menu', [$settingsClassNamespace, 'registerMenuItem']);
131
  add_action('admin_init', [$settingsClassNamespace, 'registerActions']);
138
 
139
  $plgHandlerAdminInstance = new EndHandlerAdmin($this->getPluginName(), $this->getPluginVersion());
140
 
141
+ if ((bool) $plgSettings->enablePluginInAdmin) {
142
  $this->loaderInstance->add_action('admin_enqueue_scripts', $plgHandlerAdminInstance, 'enqueueScripts');
143
  }
144
  } else {
156
  // Add support for our embeds on Beaver Builder. Without this it only run the native embeds.
157
  add_filter('fl_builder_before_render_shortcodes',
158
  ['\\EmbedPress\\ThirdParty\\BeaverBuilder', 'before_render_shortcodes']);
159
+ $this->start_plugin_tracking();
160
  $this->loaderInstance->run();
161
  }
162
 
165
  *
166
  * @return mixed
167
  */
168
+ public function addOEmbedProviders ($providers) {
 
169
  $newProviders = [
170
  // Viddler
171
+ '#https?://(.+\.)?viddler\.com/v/.+#i' => 'viddler',
172
 
173
  // Deviantart.com (http://www.deviantart.com)
174
+ '#https?://(.+\.)?deviantart\.com/art/.+#i' => 'devianart',
175
+ '#https?://(.+\.)?deviantart\.com/.+#i' => 'devianart',
176
+ '#https?://(.+\.)?deviantart\.com/.*/d.+#i' => 'devianart',
177
+ '#https?://(.+\.)?fav\.me/.+#i' => 'devianart',
178
+ '#https?://(.+\.)?sta\.sh/.+#i' => 'devianart',
179
 
180
  // chirbit.com (http://www.chirbit.com/)
181
+ '#https?://(.+\.)?chirb\.it/.+#i' => 'chirbit',
182
 
183
 
184
  // nfb.ca (http://www.nfb.ca/)
185
+ '#https?://(.+\.)?nfb\.ca/film/.+#i' => 'nfb',
186
 
187
  // Dotsub (http://dotsub.com/)
188
+ '#https?://(.+\.)?dotsub\.com/view/.+#i' => 'dotsub',
189
 
190
  // Rdio (http://rdio.com/)
191
+ '#https?://(.+\.)?rdio\.com/(artist|people)/.+#i' => 'rdio',
192
 
193
  // Sapo Videos (http://videos.sapo.pt)
194
+ '#https?://(.+\.)?videos\.sapo\.pt/.+#i' => 'sapo',
195
 
196
  // Official FM (http://official.fm)
197
+ '#https?://(.+\.)?official\.fm/(tracks|playlists)/.+#i' => 'officialfm',
198
 
199
  // HuffDuffer (http://huffduffer.com)
200
+ '#https?://(.+\.)?huffduffer\.com/.+#i' => 'huffduffer',
201
 
202
  // Shoudio (http://shoudio.com)
203
+ '#https?://(.+\.)?shoudio\.(com|io)/.+#i' => 'shoudio',
204
 
205
  // Moby Picture (http://www.mobypicture.com)
206
+ '#https?://(.+\.)?mobypicture\.com/user/.+/view/.+#i' => 'mobypicture',
207
  '#https?://(.+\.)?moby\.to/.+#i',
208
 
209
  // 23HQ (http://www.23hq.com)
210
+ '#https?://(.+\.)?23hq\.com/.+/photo/.+#i' => '23hq',
211
 
212
  // Cacoo (https://cacoo.com)
213
+ '#https?://(.+\.)?cacoo\.com/diagrams/.+#i' => 'cacoo',
214
 
215
  // Dipity (http://www.dipity.com)
216
+ '#https?://(.+\.)?dipity\.com/.+#i' => 'dipity',
217
 
218
  // Roomshare (http://roomshare.jp)
219
+ '#https?://(.+\.)?roomshare\.jp/(en/)?post/.+#i' => 'roomshare',
220
 
221
  // Crowd Ranking (http://crowdranking.com)
222
+ '#https?://(.+\.)?c9ng\.com/.+#i' => 'crowd',
223
 
224
  // CircuitLab (https://www.circuitlab.com/)
225
+ '#https?://(.+\.)?circuitlab\.com/circuit/.+#i' => 'circuitlab',
226
 
227
  // Coub (http://coub.com/)
228
+ '#https?://(.+\.)?coub\.com/(view|embed)/.+#i' => 'coub',
229
 
230
  // Ustream (http://www.ustream.tv)
231
+ '#https?://(.+\.)?ustream\.(tv|com)/.+#i' => 'ustream',
232
 
233
  // Daily Mile (http://www.dailymile.com)
234
+ '#https?://(.+\.)?dailymile\.com/people/.+/entries/.+#i' => 'daily',
235
 
236
  // Sketchfab (http://sketchfab.com)
237
+ '#https?://(.+\.)?sketchfab\.com/models/.+#i' => 'sketchfab',
238
+ '#https?://(.+\.)?sketchfab\.com/.+/folders/.+#i' => 'sketchfab',
239
 
240
  // AudioSnaps (http://audiosnaps.com)
241
+ '#https?://(.+\.)?audiosnaps\.com/k/.+#i' => 'audiosnaps',
242
 
243
  // RapidEngage (https://rapidengage.com)
244
+ '#https?://(.+\.)?rapidengage\.com/s/.+#i' => 'rapidengage',
245
 
246
  // Getty Images (http://www.gettyimages.com/)
247
+ '#https?://(.+\.)?gty\.im/.+#i' => 'gettyimages',
248
+ '#https?://(.+\.)?gettyimages\.com/detail/photo/.+#i' => 'gettyimages',
249
 
250
  // amCharts Live Editor (http://live.amcharts.com/)
251
+ '#https?://(.+\.)?live\.amcharts\.com/.+#i' => 'amcharts',
252
 
253
  // Infogram (https://infogr.am/)
254
+ '#https?://(.+\.)?infogr\.am/.+#i' => 'infogram',
255
 
256
  // ChartBlocks (http://www.chartblocks.com/)
257
+ '#https?://(.+\.)?public\.chartblocks\.com/c/.+#i' => 'chartblocks',
258
 
259
  // ReleaseWire (http://www.releasewire.com/)
260
+ '#https?://(.+\.)?rwire\.com/.+#i' => 'releasewire',
261
 
262
  // ShortNote (https://www.shortnote.jp/)
263
+ '#https?://(.+\.)?shortnote\.jp/view/notes/.+#i' => 'shortnote',
264
 
265
  // EgliseInfo (http://egliseinfo.catholique.fr/)
266
+ '#https?://(.+\.)?egliseinfo\.catholique\.fr/.+#i' => 'egliseinfo',
267
 
268
  // Silk (http://www.silk.co/)
269
+ '#https?://(.+\.)?silk\.co/explore/.+#i' => 'silk',
270
+ '#https?://(.+\.)?silk\.co/s/embed/.+#i' => 'silk',
271
 
272
  // http://bambuser.com
273
+ '#https?://(.+\.)?bambuser\.com/v/.+#i' => 'bambuser',
274
 
275
  // https://clyp.it
276
+ '#https?://(.+\.)?clyp\.it/.+#i' => 'clyp',
277
 
278
  // https://gist.github.com
279
+ '#https?://(.+\.)?gist\.github\.com/.+#i' => 'github',
280
 
281
  // https://portfolium.com
282
+ '#https?://(.+\.)?portfolium\.com/.+#i' => 'portfolium',
283
 
284
  // http://rutube.ru
285
+ '#https?://(.+\.)?rutube\.ru/video/.+#i' => 'rutube',
286
 
287
  // http://www.videojug.com
288
+ '#https?://(.+\.)?videojug\.com/.+#i' => 'videojug',
289
 
290
  // https://vine.com
291
+ '#https?://(.+\.)?vine\.co/v/.+#i' => 'vine',
292
 
293
  // Google Shortened Url
294
+ '#https?://(.+\.)?goo\.gl/.+#i' => 'google',
295
 
296
  // Google Maps
297
+ '#https?://(.+\.)?google\.com/maps/.+#i' => 'googlemaps',
298
+ '#https?://(.+\.)?maps\.google\.com/.+#i' => 'googlemaps',
299
 
300
  // Google Docs
301
  '#https?://(.+\.)?docs\.google\.com/(.+/)?(document|presentation|spreadsheets|forms|drawings)/.+#i' => 'googledocs',
302
 
303
  // Twitch.tv
304
+ '#https?://(.+\.)?twitch\.tv/.+#i' => 'twitch',
305
 
306
  // Giphy
307
+ '#https?://(.+\.)?giphy\.com/gifs/.+#i' => 'giphy',
308
+ '#https?://(.+\.)?i\.giphy\.com/.+#i' => 'giphy',
309
+ '#https?://(.+\.)?gph\.is/.+#i' => 'giphy',
310
 
311
  // Wistia
312
+ '#https?://(.+\.)?wistia\.com/medias/.+#i' => 'wistia',
313
+ '#https?://(.+\.)?fast\.wistia\.com/embed/medias/.+#i\.jsonp' => 'wistia',
314
  ];
315
 
316
  /**
322
  */
323
  global $wp_rewrite;
324
 
325
+ if (!class_exists('\\WP_Rewrite')) {
326
+ $path = ABSPATH.WPINC.'/class-wp-rewrite.php';
327
  if (file_exists($path)) {
328
  require_once $path;
329
  }
330
  }
331
 
332
+ if (!is_object($wp_rewrite)) {
333
+ $wp_rewrite = new \WP_Rewrite();
334
  $_GLOBALS['wp_write'] = $wp_rewrite;
335
  }
336
  /*========================================*/
337
 
338
  foreach ($newProviders as $url => &$data) {
339
  $data = [
340
+ rest_url('embedpress/v1/oembed/'.$data),
341
  true,
342
  ];
343
  }
350
  /**
351
  * Register OEmbed Rest Routes
352
  */
353
+ public function registerOEmbedRestRoutes () {
 
354
  register_rest_route(
355
  'embedpress/v1', '/oembed/(?P<provider>[a-zA-Z0-9\-]+)',
356
  [
357
+ 'methods' => \WP_REST_Server::READABLE,
358
  'callback' => ['\\EmbedPress\\RestAPI', 'oembed'],
359
  ]
360
  );
363
  /**
364
  * Callback called right after the plugin has been activated.
365
  *
366
+ * @return void
367
  * @since 1.0.0
368
  * @static
369
  *
 
370
  */
371
+ public static function onPluginActivationCallback () {
 
372
  flush_rewrite_rules();
373
  }
374
 
375
  /**
376
  * Callback called right after the plugin has been deactivated.
377
  *
378
+ * @return void
379
  * @since 1.0.0
380
  * @static
381
  *
 
382
  */
383
+ public static function onPluginDeactivationCallback () {
 
384
  flush_rewrite_rules();
385
  }
386
 
387
  /**
388
  * Method that retrieves all additional service providers defined in the ~<plugin_root_path>/providers.php file.
389
  *
390
+ * @return array
391
  * @since 1.0.0
392
  * @static
393
  *
 
394
  */
395
+ public static function getAdditionalServiceProviders () {
396
+ $additionalProvidersFilePath = EMBEDPRESS_PATH_BASE.'providers.php';
 
397
  if (file_exists($additionalProvidersFilePath)) {
398
  include $additionalProvidersFilePath;
399
 
408
  /**
409
  * Method that checks if an embed of a given service provider can be responsive.
410
  *
411
+ * @param string $serviceProviderAlias The service's slug.
412
+ *
413
+ * @return boolean
414
  * @since 1.0.0
415
  * @static
416
  *
 
 
 
417
  */
418
+ public static function canServiceProviderBeResponsive ($serviceProviderAlias) {
 
419
  return in_array($serviceProviderAlias, [
420
  "dailymotion",
421
  "kickstarter",
437
  /**
438
  * Method that retrieves the plugin settings defined by the user.
439
  *
440
+ * @return object
441
  * @since 1.0.0
442
  * @static
443
  *
 
444
  */
445
+ public static function getSettings () {
 
446
  $settings = get_option(EMBEDPRESS_PLG_NAME);
447
 
448
+ if (!isset($settings['enablePluginInAdmin'])) {
449
  $settings['enablePluginInAdmin'] = true;
450
  }
451
 
452
+ if (!isset($settings['enablePluginInFront'])) {
453
  $settings['enablePluginInFront'] = true;
454
  }
455
 
456
+ if (!isset($settings['enableEmbedResizeHeight'])) {
457
+ $settings['enableEmbedResizeHeight'] = 552;
458
+ }
459
+
460
+ if (!isset($settings['enableEmbedResizeWidth'])) {
461
+ $settings['enableEmbedResizeWidth'] = 652;
462
+ }
463
+
464
+ return (object) $settings;
465
  }
466
 
467
  /**
468
  * Method that register an EmbedPress plugin.
469
  *
470
+ * @param array $pluginMeta Associative array containing plugin's name, slug and namespace
471
+ *
472
+ * @return void
473
  * @since 1.4.0
474
  * @static
475
  *
 
 
 
476
  */
477
+ public static function registerPlugin ($pluginMeta) {
 
478
  $pluginMeta = json_decode(json_encode($pluginMeta));
479
 
480
  if (empty($pluginMeta->name) || empty($pluginMeta->slug) || empty($pluginMeta->namespace)) {
481
  return;
482
  }
483
 
484
+ if (!isset(self::$plugins[$pluginMeta->slug])) {
485
  AutoLoader::register($pluginMeta->namespace,
486
+ WP_PLUGIN_DIR.'/'.EMBEDPRESS_PLG_NAME.'-'.$pluginMeta->slug.'/'.$pluginMeta->name);
487
 
488
  $plugin = "{$pluginMeta->namespace}\Plugin";
489
  if (\defined("{$plugin}::SLUG") && $plugin::SLUG !== null) {
490
  self::$plugins[$pluginMeta->slug] = $pluginMeta->namespace;
491
 
492
+ $bsFilePath = $plugin::PATH.EMBEDPRESS_PLG_NAME.'-'.$plugin::SLUG.'.php';
493
 
494
  register_activation_hook($bsFilePath, [$plugin::NAMESPACE_STRING, 'onActivationCallback']);
495
  register_deactivation_hook($bsFilePath, [$plugin::NAMESPACE_STRING, 'onDeactivationCallback']);
496
 
497
  add_action('admin_init', [$plugin, 'onLoadAdminCallback']);
498
 
499
+ add_action(EMBEDPRESS_PLG_NAME.':'.$plugin::SLUG.':settings:register',
500
  [$plugin, 'registerSettings']);
501
+ add_action(EMBEDPRESS_PLG_NAME.':settings:render:tab', [$plugin, 'renderTab']);
502
 
503
+ add_filter('plugin_action_links_embedpress-'.$plugin::SLUG.'/embedpress-'.$plugin::SLUG.'.php',
504
  [$plugin, 'handleActionLinks'], 10, 2);
505
 
506
  $plugin::registerEvents();
511
  /**
512
  * Retrieve all registered plugins.
513
  *
514
+ * @return array
515
  * @since 1.4.0
516
  * @static
517
  *
 
518
  */
519
+ public static function getPlugins () {
 
520
  return self::$plugins;
521
  }
522
 
523
  /**
524
  * Handle links displayed below the plugin name in the WordPress Installed Plugins page.
525
  *
526
+ * @return array
527
  * @since 1.4.0
528
  * @static
529
  *
 
530
  */
531
+ public static function handleActionLinks ($links, $file) {
532
+ $settingsLink = '<a href="'.admin_url('admin.php?page=embedpress').'" aria-label="'.__('Open settings page',
533
+ 'embedpress').'">'.__('Settings', 'embedpress').'</a>';
 
534
 
535
  array_unshift($links, $settingsLink);
536
 
540
  /**
541
  * Method that ensures the API's url are whitelisted to WordPress external requests.
542
  *
543
+ * @param boolean $isAllowed
544
+ * @param string $host
545
+ * @param string $url
546
+ *
547
+ * @return boolean
548
  * @since 1.4.0
549
  * @static
550
  *
 
 
 
 
 
551
  */
552
+ public static function allowApiHost ($isAllowed, $host, $url) {
 
553
  if ($host === EMBEDPRESS_LICENSES_API_HOST) {
554
  $isAllowed = true;
555
  }
556
 
557
  return $isAllowed;
558
  }
559
+
560
+
561
  }
EmbedPress/CoreLegacy.php CHANGED
@@ -18,6 +18,7 @@ use EmbedPress\Ends\Front\Handler as EndHandlerPublic;
18
  */
19
  class CoreLegacy
20
  {
 
21
  /**
22
  * The name of the plugin.
23
  *
@@ -72,6 +73,7 @@ class CoreLegacy
72
  $this->pluginVersion = EMBEDPRESS_VERSION;
73
 
74
  $this->loaderInstance = new Loader();
 
75
  }
76
 
77
  /**
@@ -123,7 +125,7 @@ class CoreLegacy
123
 
124
  if (is_admin()) {
125
  $plgSettings = self::getSettings();
126
-
127
  $settingsClassNamespace = '\\EmbedPress\\Ends\\Back\\Settings';
128
  add_action('admin_menu', [$settingsClassNamespace, 'registerMenuItem']);
129
  add_action('admin_init', [$settingsClassNamespace, 'registerActions']);
@@ -171,6 +173,7 @@ class CoreLegacy
171
  add_filter('fl_builder_before_render_shortcodes',
172
  ['\\EmbedPress\\ThirdParty\\BeaverBuilder', 'before_render_shortcodes']);
173
 
 
174
  $this->loaderInstance->run();
175
  }
176
 
18
  */
19
  class CoreLegacy
20
  {
21
+ use \EmbedPress\Includes\Traits\Shared;
22
  /**
23
  * The name of the plugin.
24
  *
73
  $this->pluginVersion = EMBEDPRESS_VERSION;
74
 
75
  $this->loaderInstance = new Loader();
76
+ add_action('admin_notices',[$this,'embedpress_admin_notice']);
77
  }
78
 
79
  /**
125
 
126
  if (is_admin()) {
127
  $plgSettings = self::getSettings();
128
+ $this->admin_notice();
129
  $settingsClassNamespace = '\\EmbedPress\\Ends\\Back\\Settings';
130
  add_action('admin_menu', [$settingsClassNamespace, 'registerMenuItem']);
131
  add_action('admin_init', [$settingsClassNamespace, 'registerActions']);
173
  add_filter('fl_builder_before_render_shortcodes',
174
  ['\\EmbedPress\\ThirdParty\\BeaverBuilder', 'before_render_shortcodes']);
175
 
176
+ $this->start_plugin_tracking();
177
  $this->loaderInstance->run();
178
  }
179
 
EmbedPress/Ends/Back/Settings.php CHANGED
@@ -129,6 +129,14 @@ class Settings
129
  'label' => "Load previews in the frontend editor",
130
  'section' => "admin",
131
  ],
 
 
 
 
 
 
 
 
132
  ];
133
  }
134
 
@@ -197,106 +205,28 @@ class Settings
197
  </header>
198
 
199
  <?php settings_errors(); ?>
200
-
201
  <div>
202
  <h2 class="nav-tab-wrapper">
203
  <a href="?page=embedpress"
204
  class="nav-tab<?php echo $activeTab === 'embedpress' || empty($activeTab) ? ' nav-tab-active' : ''; ?> ">
205
  General settings
206
  </a>
207
-
208
  <?php do_action('embedpress:settings:render:tab', $activeTab); ?>
 
209
 
210
- <a href="?page=embedpress&tab=addons"
211
- class="nav-tab<?php echo $activeTab === 'addons' ? ' nav-tab-active' : ''; ?> ">
212
- Add-ons
213
- </a>
214
  </h2>
215
 
216
  <?php if ($activeTab !== 'addons') : ?>
217
  <form action="options.php" method="POST" style="padding-bottom: 20px;">
218
  <?php settings_fields($settingsFieldsIdentifier); ?>
219
  <?php do_settings_sections($settingsSectionsIdentifier); ?>
220
-
221
- <button type="submit" class="button button-primary">Save changes</button>
 
222
  </form>
223
  <?php endif; ?>
224
-
225
- <?php if ($activeTab === 'addons') : ?>
226
- <?php
227
- $icons_base_path = plugins_url('embedpress') . '/assets/images/';
228
-
229
- $addons = [
230
- 'embedpress-youtube' => [
231
- 'title' => __('The YouTube Add-on for EmbedPress', 'embedpress'),
232
- 'description' => __('Get more features for your YouTube embeds in WordPress.',
233
- 'embedpress'),
234
- 'available' => true,
235
- 'installed' => static::is_plugin_installed('embedpress-youtube'),
236
- 'active' => static::is_plugin_active('embedpress-youtube'),
237
- ],
238
- 'embedpress-vimeo' => [
239
- 'title' => __('The Vimeo Add-on for EmbedPress', 'embedpress'),
240
- 'description' => __('Get more features for your Vimeo embeds in WordPress.', 'embedpress'),
241
- 'available' => true,
242
- 'installed' => static::is_plugin_installed('embedpress-vimeo'),
243
- 'active' => static::is_plugin_active('embedpress-vimeo'),
244
- ],
245
- 'embedpress-wistia' => [
246
- 'title' => __('The Wistia Add-on for EmbedPress', 'embedpress'),
247
- 'description' => __('Get more features for your Wistia embeds in WordPress.', 'embedpress'),
248
- 'available' => true,
249
- 'installed' => static::is_plugin_installed('embedpress-wistia'),
250
- 'active' => static::is_plugin_active('embedpress-wistia'),
251
- ],
252
- ];
253
-
254
- $args = [
255
- 'addons' => $addons,
256
- 'icons_base_path' => $icons_base_path,
257
- 'labels' => [
258
- 'active' => __('Active', 'publishpress'),
259
- 'installed' => __('Installed', 'publishpress'),
260
- 'get_pro_addons' => __('Get Pro Add-ons!', 'publishpress'),
261
- 'coming_soon' => __('Coming soon', 'publishpress'),
262
- ],
263
- ];
264
-
265
- ?>
266
- <div class="ep-module-settings">
267
- <ul class="ep-block-addons-items">
268
- <?php foreach ($addons as $name => $addon): ?>
269
- <li class="ep-block-addons-item ">
270
- <img src="<?php echo $icons_base_path . $name; ?>.jpg">
271
- <h3><?php echo $addon['title']; ?></h3>
272
- <p><?php echo $addon['description']; ?></p>
273
-
274
- <?php if ($addon['available']): ?>
275
- <?php if ($addon['installed']): ?>
276
- <?php if ($addon['active']): ?>
277
- <div>
278
- <span class="dashicons dashicons-yes"></span><span><?php echo __('Active',
279
- 'embedpress'); ?></span>
280
- </div>
281
- <?php else: ?>
282
- <div>
283
- <span><?php echo __('Installed', 'embedpress'); ?></span>
284
- </div>
285
- <?php endif; ?>
286
- <?php else: ?>
287
- <a href="https://embedpress.com/embedpress-addons/"
288
- class="button button-primary">
289
- <span class="dashicons dashicons-cart"></span> <?php echo __('Get Pro Add-ons!',
290
- 'embedpress'); ?>
291
- </a>
292
- <?php endif; ?>
293
- <?php else: ?>
294
- <div><?php echo __('Coming soon', 'embedpress'); ?></div>
295
- <?php endif; ?>
296
- </li>
297
- <?php endforeach; ?>
298
- </ul>
299
- </div>
300
  <?php endif; ?>
301
  </div>
302
 
@@ -368,9 +298,11 @@ class Settings
368
  public static function validateForm($freshData)
369
  {
370
  $data = [
371
- 'enablePluginInAdmin' => isset($freshData['enablePluginInAdmin']) ? (bool)$freshData['enablePluginInAdmin'] : true,
372
- 'enablePluginInFront' => isset($freshData['enablePluginInFront']) ? (bool)$freshData['enablePluginInFront'] : true,
373
- 'fbLanguage' => $freshData['fbLanguage'],
 
 
374
  ];
375
 
376
  return $data;
@@ -416,6 +348,41 @@ class Settings
416
  echo '<p class="description">Do you want EmbedPress to run within editors in frontend (if there\'s any)? Disabling this <strong>will not</strong> affect embeds seem by your regular users in frontend.</p>';
417
  }
418
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
419
  /**
420
  * Method that renders the forceFacebookLanguage input.
421
  *
129
  'label' => "Load previews in the frontend editor",
130
  'section' => "admin",
131
  ],
132
+ 'enableEmbedResizeWidth' => [
133
+ 'label' => "Embed Iframe Width",
134
+ 'section' => "admin",
135
+ ],
136
+ 'enableEmbedResizeHeight' => [
137
+ 'label' => "Embed Iframe Height",
138
+ 'section' => "admin",
139
+ ]
140
  ];
141
  }
142
 
205
  </header>
206
 
207
  <?php settings_errors(); ?>
 
208
  <div>
209
  <h2 class="nav-tab-wrapper">
210
  <a href="?page=embedpress"
211
  class="nav-tab<?php echo $activeTab === 'embedpress' || empty($activeTab) ? ' nav-tab-active' : ''; ?> ">
212
  General settings
213
  </a>
 
214
  <?php do_action('embedpress:settings:render:tab', $activeTab); ?>
215
+ <?php do_action('embedpress_license_tab',$activeTab); ?>
216
 
 
 
 
 
217
  </h2>
218
 
219
  <?php if ($activeTab !== 'addons') : ?>
220
  <form action="options.php" method="POST" style="padding-bottom: 20px;">
221
  <?php settings_fields($settingsFieldsIdentifier); ?>
222
  <?php do_settings_sections($settingsSectionsIdentifier); ?>
223
+ <?php if ($activeTab !== 'embedpress_license') : ?>
224
+ <button type="submit" class="button button-primary embedpress-setting-save">Save changes</button>
225
+ <?php endif; ?>
226
  </form>
227
  <?php endif; ?>
228
+ <?php if ($activeTab == 'embedpress_license') : ?>
229
+ <?php echo do_action('embedpress_license'); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  <?php endif; ?>
231
  </div>
232
 
298
  public static function validateForm($freshData)
299
  {
300
  $data = [
301
+ 'enablePluginInAdmin' => isset($freshData['enablePluginInAdmin']) ? (bool)$freshData['enablePluginInAdmin'] : true,
302
+ 'enablePluginInFront' => isset($freshData['enablePluginInFront']) ? (bool)$freshData['enablePluginInFront'] : true,
303
+ 'enableEmbedResizeHeight' => isset($freshData['enableEmbedResizeHeight']) ? $freshData['enableEmbedResizeHeight'] : 552,
304
+ 'enableEmbedResizeWidth' => isset($freshData['enableEmbedResizeWidth']) ? $freshData['enableEmbedResizeWidth'] : 652,
305
+ 'fbLanguage' => $freshData['fbLanguage'],
306
  ];
307
 
308
  return $data;
348
  echo '<p class="description">Do you want EmbedPress to run within editors in frontend (if there\'s any)? Disabling this <strong>will not</strong> affect embeds seem by your regular users in frontend.</p>';
349
  }
350
 
351
+ /**
352
+ * Method that renders the enableEmbedResizeHeight input.
353
+ *
354
+ * @since 2.4.0
355
+ * @static
356
+ */
357
+ public static function renderField_enableEmbedResizeHeight()
358
+ {
359
+ $fieldName = "enableEmbedResizeHeight";
360
+
361
+ $options = get_option(self::$sectionGroupIdentifier);
362
+
363
+ $value = ! isset($options[$fieldName]) ? '552' : $options[$fieldName];
364
+
365
+ echo '<input type="number" value="'.absint($value).'" class="regular-text" name="' . self::$sectionGroupIdentifier . '[' . $fieldName . ']">';
366
+
367
+ echo '<p class="description">Global Embed Iframe Height</p>';
368
+ }
369
+
370
+ /**
371
+ * Method that renders the enableEmbedResizeWidth input.
372
+ *
373
+ * @since 2.4.0
374
+ * @static
375
+ */
376
+ public static function renderField_enableEmbedResizeWidth()
377
+ {
378
+ $fieldName = "enableEmbedResizeWidth";
379
+ $options = get_option(self::$sectionGroupIdentifier);
380
+ $value = ! isset($options[$fieldName]) ? '652' : $options[$fieldName];
381
+
382
+ echo '<input type="number" value="'.absint($value).'" class="regular-text" name="' . self::$sectionGroupIdentifier . '[' . $fieldName . ']">';
383
+ echo '<p class="description">Global Embed Iframe Width </p>';
384
+ }
385
+
386
  /**
387
  * Method that renders the forceFacebookLanguage input.
388
  *
EmbedPress/Ends/Back/index.html CHANGED
File without changes
EmbedPress/Ends/Front/index.html CHANGED
File without changes
EmbedPress/Ends/index.html CHANGED
File without changes
EmbedPress/Includes/Classes/EmbedPress_Core_Installer.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Includes\Classes;
3
+
4
+ if (!defined('ABSPATH')) {
5
+ exit;
6
+ } // Exit if accessed directly.
7
+
8
+ /**
9
+ * EmbedPress Core Install
10
+ */
11
+ class EmbedPress_Core_Installer {
12
+ /**
13
+ * Plugin Base Name
14
+ *
15
+ * @var string
16
+ */
17
+ private $plugin_basename;
18
+
19
+ /**
20
+ * Instantiate the class
21
+ *
22
+ * @param string $plugin_basename
23
+ */
24
+ function __construct( $plugin_basename = '' ) {
25
+ $this->plugin_basename = $plugin_basename;
26
+ add_action( 'init', array( $this, 'init_hooks' ) );
27
+ }
28
+ /**
29
+ * Initialize the hooks
30
+ *
31
+ * @return void
32
+ */
33
+ public function init_hooks() {
34
+ if ( ! current_user_can( 'manage_options' ) ) {
35
+ return;
36
+ }
37
+ add_action( 'wp_ajax_wpdeveloper_upsale_core_install_' . $this->plugin_basename, array( $this, 'core_install' ) );
38
+ }
39
+ /**
40
+ * Fail if plugin installtion/activation fails
41
+ *
42
+ * @param Object $thing
43
+ *
44
+ * @return void
45
+ */
46
+ public function fail_on_error( $thing ) {
47
+ if ( is_wp_error( $thing ) ) {
48
+ wp_send_json_error( $thing->get_error_message() );
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Install Upsale Plugin
54
+ *
55
+ * @return void
56
+ */
57
+ public function core_install() {
58
+ check_ajax_referer( 'wpdeveloper_upsale_core_install_' . $this->plugin_basename );
59
+
60
+ if ( ! current_user_can( 'manage_options' ) ) {
61
+ wp_send_json_error( __( 'You don\'t have permission to install the plugins' ) );
62
+ }
63
+
64
+ $plugin_slug = ( isset( $_POST['slug'] ) ) ? $_POST['slug'] : '';
65
+ $plugin_file = ( isset( $_POST['file'] ) ) ? $_POST['file'] : '';
66
+
67
+ if( empty( $plugin_file ) || empty( $plugin_slug ) ) {
68
+ wp_send_json_error( __( 'You don\'t have set any slug and file name to install the plugins' ) );
69
+ }
70
+
71
+ $plugin_status = $this->install_plugin( $plugin_slug, $plugin_file );
72
+ $this->fail_on_error( $plugin_status );
73
+
74
+ wp_send_json_success();
75
+ }
76
+ /**
77
+ * Install and activate a plugin
78
+ *
79
+ * @param string $slug
80
+ * @param string $file
81
+ *
82
+ * @return WP_Error|null
83
+ */
84
+ public function install_plugin( $slug, $file ) {
85
+ include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
86
+ include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
87
+
88
+ $plugin_basename = $slug . '/' . $file;
89
+
90
+ // if exists and not activated
91
+ if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin_basename ) ) {
92
+ return activate_plugin( $plugin_basename );
93
+ }
94
+
95
+ // seems like the plugin doesn't exists. Download and activate it
96
+ $upgrader = new \Plugin_Upgrader( new \WP_Ajax_Upgrader_Skin() );
97
+
98
+ $api = plugins_api( 'plugin_information', array( 'slug' => $slug, 'fields' => array( 'sections' => false ) ) );
99
+ $result = $upgrader->install( $api->download_link );
100
+
101
+ if ( is_wp_error( $result ) ) {
102
+ return $result;
103
+ }
104
+
105
+ return activate_plugin( $plugin_basename );
106
+ }
107
+ }
EmbedPress/Includes/Classes/EmbedPress_Notice.php ADDED
@@ -0,0 +1,904 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Includes\Classes;
3
+
4
+ if (!defined('ABSPATH')) {
5
+ exit;
6
+ } // Exit if accessed directly.
7
+
8
+ use EmbedPress\Includes\Classes\EmbedPress_Core_Installer;
9
+
10
+ class EmbedPress_Notice {
11
+ /**
12
+ * Admin Notice Key
13
+ *
14
+ * @var array
15
+ */
16
+ const ADMIN_UPDATE_NOTICE_KEY = 'wpdeveloper_notices_seen';
17
+ public $text_domain = 'embedpress';
18
+ /**
19
+ * All Data
20
+ * @var array
21
+ */
22
+ private $data = array();
23
+ private $properties = array(
24
+ 'links', 'message', 'thumbnail',
25
+ );
26
+ private $methods = array(
27
+ 'message', 'thumbnail', 'classes'
28
+ );
29
+ /**
30
+ * cne_day == current_notice_end_day
31
+ *
32
+ * @var integer
33
+ */
34
+ public $cne_time = '2 day';
35
+ public $maybe_later_time = '7 day';
36
+ public $finish_time = [];
37
+ /**
38
+ * Plugin Name
39
+ *
40
+ * @var string
41
+ */
42
+ private $plugin_name;
43
+ /**
44
+ * Plugin File Name
45
+ * @var string
46
+ */
47
+ private $plugin_file;
48
+ /**
49
+ * First Install Version Of The Plugin
50
+ *
51
+ * @var string
52
+ */
53
+ private $version;
54
+ /**
55
+ * Saved Data in DB
56
+ * @var array
57
+ */
58
+ private $options_data;
59
+ /**
60
+ * Current Timestamp
61
+ * @var integer
62
+ */
63
+ public $timestamp;
64
+ /**
65
+ * Primary Notice Action
66
+ *
67
+ * @var string
68
+ */
69
+ private $do_notice_action;
70
+ /**
71
+ * Default Options Set
72
+ *
73
+ * @var array
74
+ */
75
+ public $options_args = array(
76
+ // 'first_install' => true,
77
+ // 'notice_will_show' => [
78
+ // 'opt_in' => true,
79
+ // 'first_install' => false,
80
+ // 'update' => true,
81
+ // 'review' => true,
82
+ // 'upsale' => true,
83
+ // ]
84
+ );
85
+ /**
86
+ * Notice ID for users.
87
+ * @var string
88
+ */
89
+ private $notice_id;
90
+ /**
91
+ * Upsale Notice Arguments
92
+ * @var array
93
+ */
94
+ public $upsale_args;
95
+
96
+ /**
97
+ * Revoke this function when the object is created.
98
+ *
99
+ * @param string $plugin_file
100
+ * @param string $version
101
+ */
102
+ public function __construct( $plugin_file = '', $version = '' ) {
103
+ $this->plugin_file = $plugin_file;
104
+ $this->plugin_name = basename( $plugin_file, '.php' );
105
+ $this->version = $version;
106
+ $this->timestamp = intval( current_time( 'timestamp' ) );
107
+ $this->notice_id = 'wpdeveloper_notice_' . str_replace( '.', '_', $this->version );
108
+
109
+ $this->do_notice_action = 'wpdeveloper_notices_for_' . $this->plugin_name;
110
+ new EmbedPress_Core_Installer( $this->plugin_name );
111
+
112
+ }
113
+ /**
114
+ * Initiate The Plugin
115
+ * @return void
116
+ */
117
+ public function init(){
118
+ add_action( 'init', array( $this, 'first_install_track') );
119
+ add_action( 'deactivate_' . $this->plugin_file, array( $this, 'first_install_end' ) );
120
+ add_action( 'init', array( $this, 'hooks' ) );
121
+ }
122
+ /**
123
+ * All Hooks
124
+ * @return void
125
+ */
126
+ public function hooks(){
127
+ add_action( 'wpdeveloper_notice_clicked_for_' . $this->plugin_name, array( $this, 'clicked' ) );
128
+ add_action( 'wp_ajax_wpdeveloper_upsale_notice_dissmiss_for_' . $this->plugin_name, array( $this, 'upsale_notice_dissmiss' ) );
129
+ add_action( 'wp_ajax_wpdeveloper_notice_dissmiss_for_' . $this->plugin_name, array( $this, 'notice_dissmiss' ) );
130
+ add_action( 'wpdeveloper_before_notice_for_' . $this->plugin_name, array( $this, 'before' ) );
131
+ add_action( 'wpdeveloper_after_notice_for_' . $this->plugin_name, array( $this, 'after' ) );
132
+ add_action( 'wpdeveloper_before_upsale_notice_for_' . $this->plugin_name, array( $this, 'before_upsale' ) );
133
+ add_action( 'wpdeveloper_after_upsale_notice_for_' . $this->plugin_name, array( $this, 'after' ) );
134
+ add_action( $this->do_notice_action, array( $this, 'content' ) );
135
+ if( current_user_can( 'install_plugins' ) ) {
136
+ if( isset( $_GET['plugin'] ) && $_GET['plugin'] == $this->plugin_name ) {
137
+ if( isset( $_GET['tab'] ) && $_GET['tab'] === 'plugin-information' ) {
138
+ return;
139
+ }
140
+ do_action( 'wpdeveloper_notice_clicked_for_' . $this->plugin_name );
141
+ /**
142
+ * Redirect User To the Current URL, but without set query arguments.
143
+ */
144
+ wp_safe_redirect( $this->redirect_to() );
145
+ }
146
+ $return_notice = $this->next_notice();
147
+ $current_notice = current( $return_notice );
148
+ $next_notice = next( $return_notice );
149
+
150
+ $deserve_notice = $this->deserve_notice( $current_notice );
151
+ $options_data = $this->get_options_data();
152
+ $user_notices = $this->get_user_notices();
153
+
154
+ $notice_time = isset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] )
155
+ ? $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] : $this->timestamp;
156
+ $next_notice_time = $next_notice ? $options_data[ $this->plugin_name ]['notice_will_show'][ $next_notice ] : $this->timestamp;
157
+ $current_notice_end = $this->makeTime( $notice_time, $this->cne_time );
158
+
159
+ if( ! $deserve_notice ) {
160
+ unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
161
+ $this->update_options_data( $options_data[ $this->plugin_name ] );
162
+ }
163
+
164
+ if( $deserve_notice ) {
165
+ /**
166
+ * TODO: automatic maybe later setup with time.
167
+ */
168
+ if( ( $this->timestamp >= $current_notice_end ) || ( $this->timestamp > $next_notice_time ) ) {
169
+ $this->maybe_later( $current_notice );
170
+ $notice_time = false;
171
+ }
172
+
173
+ if( isset( $this->finish_time[ $current_notice ] ) ) {
174
+ if( $this->timestamp >= strtotime( $this->finish_time[ $current_notice ] ) ) {
175
+ unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
176
+ $this->update_options_data( $options_data[ $this->plugin_name ] );
177
+ $notice_time = false;
178
+ }
179
+ }
180
+
181
+ if( $notice_time != false ) {
182
+ if( $notice_time <= $this->timestamp ) {
183
+ if( $current_notice === 'upsale' ) {
184
+ $upsale_args = $this->get_upsale_args();
185
+ if( empty( $upsale_args ) ) {
186
+ unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
187
+ $this->update_options_data( $options_data[ $this->plugin_name ] );
188
+ } else {
189
+ if( isset( $upsale_args['condition'], $upsale_args['condition']['by'] ) ) {
190
+ switch( $upsale_args['condition']['by'] ) {
191
+ case 'class' :
192
+ if( isset( $upsale_args['condition']['class'] ) && class_exists( $upsale_args['condition']['class'] ) ) {
193
+ unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
194
+ $this->update_options_data( $options_data[ $this->plugin_name ] );
195
+ return;
196
+ }
197
+ break;
198
+ case 'function' :
199
+ if( isset( $upsale_args['condition']['function'] ) && function_exists( $upsale_args['condition']['function'] ) ) {
200
+ unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $current_notice ] );
201
+ $this->update_options_data( $options_data[ $this->plugin_name ] );
202
+ return;
203
+ }
204
+ break;
205
+ }
206
+ }
207
+ if ( ! function_exists( 'get_plugins' ) ) {
208
+ include ABSPATH . '/wp-admin/includes/plugin.php';
209
+ }
210
+ $plugins = get_plugins();
211
+ $pkey = $upsale_args['slug'] . '/' . $upsale_args['file'];
212
+ if( isset( $plugins[ $pkey ] ) ) {
213
+ $this->update( $current_notice );
214
+ return;
215
+ }
216
+ add_action( 'admin_notices', array( $this, 'upsale_notice' ) );
217
+ }
218
+ } else {
219
+ add_action( 'admin_notices', array( $this, 'admin_notices' ) );
220
+ }
221
+ }
222
+ }
223
+ }
224
+ }
225
+ }
226
+ /**
227
+ * Make time using timestamp and a string like 2 Hour, 2 Day, 30 Minutes, 1 Week, 1 year
228
+ * @param integer $current
229
+ * @param string $time
230
+ * @return integer
231
+ */
232
+ public function makeTime( $current, $time ) {
233
+ return intval( strtotime( date('r', $current) . " +$time" ) );
234
+ }
235
+ /**
236
+ * Automatice Maybe Later.
237
+ * @param string $notice
238
+ * @return void
239
+ */
240
+ private function maybe_later( $notice ){
241
+ if( empty( $notice ) ) {
242
+ return;
243
+ }
244
+ $options_data = $this->get_options_data();
245
+ $options_data[ $this->plugin_name ]['notice_will_show'][ $notice ] = $this->makeTime( $this->timestamp, $this->maybe_later_time );
246
+ $this->update_options_data( $options_data[ $this->plugin_name ] );
247
+ }
248
+ /**
249
+ * When links are clicked, this function will invoked.
250
+ * @return void
251
+ */
252
+ public function clicked(){
253
+ if( isset( $_GET['plugin'] ) ) {
254
+ $plugin = sanitize_text_field( $_GET['plugin'] );
255
+ if( $plugin === $this->plugin_name ) {
256
+ $options_data = $this->get_options_data();
257
+ $clicked_from = current( $this->next_notice() );
258
+ if( isset( $_GET['plugin_action'] ) ) {
259
+ $plugin_action = sanitize_text_field( $_GET['plugin_action'] );
260
+ }
261
+ if( isset( $_GET['dismiss'] ) ) {
262
+ $dismiss = sanitize_text_field( $_GET['dismiss'] );
263
+ }
264
+ if( isset( $_GET['later'] ) ) {
265
+ $later = sanitize_text_field( $_GET['later'] );
266
+ }
267
+
268
+ $later_time = '';
269
+
270
+ switch( $clicked_from ) {
271
+
272
+ case 'opt_in' :
273
+ $dismiss = ( isset( $plugin_action ) ) ? $plugin_action : false ;
274
+ $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
275
+ break;
276
+
277
+ case 'first_install' :
278
+ $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
279
+ break;
280
+
281
+ case 'update' :
282
+ $dismiss = ( isset( $plugin_action ) ) ? $plugin_action : false ;
283
+ $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
284
+ break;
285
+
286
+ case 'review' :
287
+ $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
288
+ break;
289
+
290
+ case 'upsale' :
291
+ $later_time = $this->makeTime( $this->timestamp, $this->maybe_later_time );
292
+ break;
293
+ }
294
+
295
+ if( isset( $later ) && $later == true ) {
296
+ $options_data[ $this->plugin_name ]['notice_will_show'][ $clicked_from ] = $later_time;
297
+ }
298
+ if( isset( $dismiss ) && $dismiss == true ) {
299
+ update_user_meta( get_current_user_id(), $this->plugin_name . '_' . $clicked_from, true );
300
+ $this->update( $clicked_from );
301
+ }
302
+ $this->update_options_data( $options_data[ $this->plugin_name ] );
303
+ }
304
+ }
305
+ }
306
+ /**
307
+ * For Redirecting Current Page without Arguments!
308
+ *
309
+ * @return void
310
+ */
311
+ private function redirect_to(){
312
+ $request_uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
313
+ $query_string = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_QUERY );
314
+ parse_str( $query_string, $current_url );
315
+
316
+ $unset_array = array( 'dismiss', 'plugin', '_wpnonce', 'later', 'plugin_action', 'marketing_optin' );
317
+
318
+ foreach( $unset_array as $value ) {
319
+ if( isset( $current_url[ $value ] ) ) {
320
+ unset( $current_url[ $value ] );
321
+ }
322
+ }
323
+
324
+ $current_url = http_build_query($current_url);
325
+ $redirect_url = $request_uri . '?' . $current_url;
326
+ return $redirect_url;
327
+ }
328
+ /**
329
+ * Before Notice
330
+ * @return void
331
+ */
332
+ public function before(){
333
+ $current_notice = current( $this->next_notice() );
334
+ $classes = 'notice notice-info put-dismiss-notice';
335
+ if( isset( $this->data['classes'] ) ) {
336
+ if( isset( $this->data['classes'][ $current_notice ] ) ) {
337
+ $classes = $this->data['classes'][ $current_notice ];
338
+ }
339
+ }
340
+
341
+ if( $this->has_thumbnail( $current_notice ) ) {
342
+ $classes .= 'notice-has-thumbnail';
343
+ }
344
+
345
+ echo '<div class="'. $classes .' wpdeveloper-'. $current_notice .'-notice">';
346
+ }
347
+ /**
348
+ * After Notice
349
+ * @return void
350
+ */
351
+ public function after(){
352
+ echo '</div>';
353
+ }
354
+ /**
355
+ * Content generation & Hooks Funciton.
356
+ * @return void
357
+ */
358
+ public function content(){
359
+ $options_data = $this->get_options_data();
360
+ $notice = current( $this->next_notice() );
361
+ switch( $notice ) {
362
+ case 'opt_in' :
363
+ do_action('wpdeveloper_optin_notice_for_' . $this->plugin_name );
364
+ break;
365
+ case 'first_install' :
366
+ if( $options_data[ $this->plugin_name ]['first_install'] !== 'deactivated' ) {
367
+ do_action( 'wpdeveloper_first_install_notice_for_' . $this->plugin_name );
368
+ $this->get_thumbnail( 'first_install' );
369
+ $this->get_message( 'first_install' );
370
+ }
371
+ break;
372
+ case 'update' :
373
+ do_action( 'wpdeveloper_update_notice_for_' . $this->plugin_name );
374
+ $this->get_thumbnail( 'update' );
375
+ $this->get_message( 'update' );
376
+ $this->dismiss_button_scripts();
377
+ break;
378
+ case 'review' :
379
+ do_action( 'wpdeveloper_review_notice_for_' . $this->plugin_name );
380
+ $this->get_thumbnail( 'review' );
381
+ $this->get_message( 'review' );
382
+ break;
383
+ }
384
+ }
385
+ /**
386
+ * Before Upsale Notice
387
+ * @return void
388
+ */
389
+ public function before_upsale(){
390
+ $classes = '';
391
+ if( $this->has_thumbnail('upsale') ) {
392
+ $classes = 'notice-has-thumbnail';
393
+ }
394
+ echo '<div class="error notice is-dismissible wpdeveloper-upsale-notice '. $classes .'">';
395
+ }
396
+ /**
397
+ * Upsale Notice
398
+ */
399
+ public function upsale_notice(){
400
+ do_action( 'wpdeveloper_before_upsale_notice_for_' . $this->plugin_name );
401
+ do_action('wpdeveloper_upsale_notice_for_' . $this->plugin_name);
402
+ $this->get_thumbnail( 'upsale' );
403
+ $this->get_message( 'upsale' );
404
+ do_action( 'wpdeveloper_after_upsale_notice_for_' . $this->plugin_name );
405
+ $this->upsale_button_script();
406
+ }
407
+ /**
408
+ * Get upsale arguments.
409
+ * @return void
410
+ */
411
+ private function get_upsale_args(){
412
+ return ( empty( $this->upsale_args ) ) ? array() : $this->upsale_args;
413
+ }
414
+ /**
415
+ * This function is responsible for making the button visible to the upsale notice.
416
+ */
417
+ private function upsale_button(){
418
+ $upsale_args = $this->get_upsale_args();
419
+ $plugin_slug = ( isset( $upsale_args['slug'] )) ? $upsale_args['slug'] : '' ;
420
+ if( empty( $plugin_slug ) ) {
421
+ return;
422
+ }
423
+ echo '<button data-slug="'. $plugin_slug .'" id="plugin-install-core-'. $this->plugin_name .'" class="button button-primary">'. __( 'Install Now!', $this->text_domain, 'notificationx' ) .'</button>';
424
+ }
425
+ /**
426
+ * This methods is responsible for get notice image.
427
+ *
428
+ * @param string $msg_for
429
+ * @return void
430
+ */
431
+ protected function get_thumbnail( $msg_for ){
432
+ $output = '';
433
+ if( isset( $this->data['thumbnail'] ) && isset( $this->data['thumbnail'][ $msg_for ] ) ) {
434
+ $output = '<div class="wpdeveloper-notice-thumbnail">';
435
+ $output .= '<img src="'. $this->data['thumbnail'][ $msg_for ] .'" alt="NotificationX">';
436
+ $output .= '</div>';
437
+ }
438
+ echo $output;
439
+ }
440
+ /**
441
+ * Has Thumbnail Check
442
+ *
443
+ * @param string $msg_for
444
+ * @return boolean
445
+ */
446
+ protected function has_thumbnail( $msg_for = '' ){
447
+ if( empty( $msg_for ) ) {
448
+ return false;
449
+ }
450
+ if( isset( $this->data['thumbnail'] ) && isset( $this->data['thumbnail'][ $msg_for ] ) ) {
451
+ return true;
452
+ }
453
+ return false;
454
+ }
455
+ /**
456
+ * This method is responsible for get messages.
457
+ *
458
+ * @param string $msg_for
459
+ * @return void
460
+ */
461
+ protected function get_message( $msg_for ){
462
+ if( isset( $this->data['message'] ) && isset( $this->data['message'][ $msg_for ] ) ) {
463
+ echo '<div class="wpdeveloper-notice-message">';
464
+ echo $this->data['message'][ $msg_for ];
465
+ if( $msg_for === 'upsale' ) {
466
+ $this->upsale_button();
467
+ }
468
+ $this->dismissible_notice( $msg_for );
469
+ echo '</div>';
470
+ }
471
+ }
472
+ /**
473
+ * Detect which notice will show @ next.
474
+ * @return void
475
+ */
476
+ protected function next_notice(){
477
+ $options_data = $this->get_options_data();
478
+ if( ! $options_data ) {
479
+ $args = $this->get_args();
480
+ $return_notice = $args['notice_will_show'];
481
+ } else {
482
+ $return_notice = $options_data[ $this->plugin_name ]['notice_will_show'];
483
+ }
484
+
485
+ if( is_array( $return_notice ) ) {
486
+ $return_notice = array_flip( $return_notice );
487
+ ksort( $return_notice );
488
+ }
489
+
490
+ return $return_notice;
491
+ }
492
+ /**
493
+ * Which notice is deserve to show in next slot.
494
+ * @param string $notice
495
+ * @return boolean
496
+ */
497
+ private function deserve_notice( $notice ) {
498
+ $notices = $this->get_user_notices();
499
+ if( $notice === false ) {
500
+ return false;
501
+ }
502
+ if( empty( $notices ) ) {
503
+ return true;
504
+ } else {
505
+ if( isset( $notices[ $this->notice_id ] ) && isset( $notices[ $this->notice_id ][ $this->plugin_name ] ) ) {
506
+ if( in_array( $notice, $notices[ $this->notice_id ][ $this->plugin_name ] ) ) {
507
+ return false;
508
+ } else {
509
+ return true;
510
+ }
511
+ } else {
512
+ return true;
513
+ }
514
+ }
515
+ }
516
+ /**
517
+ * This is the main methods for generate the notice.
518
+ * @return void
519
+ */
520
+ public function admin_notices(){
521
+ $current_notice = current( $this->next_notice() );
522
+ if( get_user_meta( get_current_user_id(), $this->plugin_name . '_' . $current_notice, true ) ) {
523
+ return;
524
+ }
525
+ if( $current_notice == 'opt_in' ) {
526
+ do_action( $this->do_notice_action );
527
+ return;
528
+ }
529
+ do_action( 'wpdeveloper_before_notice_for_' . $this->plugin_name );
530
+ do_action( $this->do_notice_action );
531
+ do_action( 'wpdeveloper_after_notice_for_' . $this->plugin_name );
532
+ }
533
+ /**
534
+ * This method is responsible for all dismissible links generation.
535
+ * @param string $links_for
536
+ * @return void
537
+ */
538
+ public function dismissible_notice( $links_for = '' ){
539
+ if( empty( $links_for ) ) {
540
+ return;
541
+ }
542
+ $links = isset( $this->data['links'][ $links_for ] ) ? $this->data['links'][ $links_for ] : false;
543
+ if( $links ) :
544
+ $output = '<ul class="wpdeveloper-notice-link">';
545
+ foreach( $links as $key => $link_value ) {
546
+ if( ! empty( $link_value['label'] ) ) {
547
+ $output .= '<li>';
548
+ if( isset( $link_value['link'] ) ) {
549
+ $link = $link_value['link'];
550
+ $target = isset( $link_value['target'] ) ? 'target="'. $link_value['target'] .'"' : '';
551
+ if( isset( $link_value['data_args'] ) && is_array( $link_value['data_args'] ) ) {
552
+ $data_args = [];
553
+ foreach( $link_value['data_args'] as $key => $args_value ) {
554
+ $data_args[ $key ] = $args_value;
555
+ }
556
+ $data_args[ 'plugin' ] = $this->plugin_name;
557
+ $normal_link = add_query_arg( $data_args, $link );
558
+ $link = wp_nonce_url( $normal_link, 'wpdeveloper-nonce' );
559
+ }
560
+ $class = '';
561
+ if( isset( $link_value['link_class'] ) ) {
562
+ $class = 'class="' . implode( ' ', $link_value['link_class'] ) . '"';
563
+ }
564
+ $output .= '<a '. $class .' href="'. esc_url( $link ) .'" '. $target .'>';
565
+ }
566
+ if( isset( $link_value['icon_class'] ) ) {
567
+ $output .= '<span class="'. $link_value['icon_class'] .'"></span>';
568
+ }
569
+ if( isset( $link_value['icon_img'] ) ) {
570
+ $output .= '<img src="'. $link_value['icon_img'] .'" />';
571
+ }
572
+ $output .= $link_value['label'];
573
+ if( isset( $link_value['link'] ) ) {
574
+ $output .= '</a>';
575
+ }
576
+ $output .= '</li>';
577
+ }
578
+ }
579
+ $output .= '</ul>';
580
+ echo $output;
581
+ endif;
582
+ }
583
+ /**
584
+ * First Installation Track
585
+ * @return void
586
+ */
587
+ public function first_install_track( $args = array() ){
588
+ if( ! current_user_can( 'manage_options' ) ) {
589
+ return;
590
+ }
591
+ if( empty( $args ) ) {
592
+ $args = array(
593
+ 'time' => $this->timestamp,
594
+ 'version' => $this->version,
595
+ );
596
+ }
597
+ $options_data = $this->get_options_data();
598
+ $args = wp_parse_args( $args, $this->get_args() );
599
+ if( ! isset( $options_data[ $this->plugin_name ] )
600
+ || ( isset( $options_data[ $this->plugin_name ]['version'] ) && version_compare( $options_data[ $this->plugin_name ]['version'], $this->version, '!=' ) ) ) {
601
+ $this->update_options_data( $args );
602
+ }
603
+ }
604
+ /**
605
+ * First Installation Deactive Track
606
+ *
607
+ * @return void
608
+ */
609
+ public function first_install_end(){
610
+ // $args = array(
611
+ // 'first_install' => 'deactivated'
612
+ // );
613
+ // $options_data = $this->get_options_data();
614
+ // if( isset( $options_data[ $this->plugin_name ] ) ) {
615
+ // $args = wp_parse_args( $args, $options_data[ $this->plugin_name ] );
616
+ // $this->update_options_data( $args );
617
+ // }
618
+ delete_option( 'wpdeveloper_plugins_data' );
619
+ }
620
+ /**
621
+ * Get all options from database!
622
+ * @return void
623
+ */
624
+ protected function get_options_data( $key = ''){
625
+ $options_data = get_option( 'wpdeveloper_plugins_data' );
626
+ if( empty( $key ) ) {
627
+ return $options_data;
628
+ }
629
+
630
+ if( isset( $options_data[ $this->plugin_name ][ $key ] ) ) {
631
+ return $options_data[ $this->plugin_name ][ $key ];
632
+ }
633
+ return false;
634
+ }
635
+ /**
636
+ * This will update the options table for plugins.
637
+ *
638
+ * @param mixed $new_data
639
+ * @param array $args
640
+ * @return void
641
+ */
642
+ protected function update_options_data( $args = array() ){
643
+ $options_data = $this->get_options_data();
644
+ $options_data[ $this->plugin_name ] = $args;
645
+ update_option( 'wpdeveloper_plugins_data', $options_data );
646
+ }
647
+ /**
648
+ * Set properties data, for some selected properties.
649
+ *
650
+ * @param string $name
651
+ * @param mixed $value
652
+ */
653
+ public function __set( $name, $value ){
654
+ if( in_array( $name, $this->properties ) ) {
655
+ $this->data[ $name ] = $value;
656
+ }
657
+ }
658
+ /**
659
+ * Invoked when some selected methods are called
660
+ *
661
+ * @param string $name
662
+ * @param array $values
663
+ * @return void
664
+ */
665
+ public function __call( $name, $values ){
666
+ if( in_array( $name, $this->methods ) ) {
667
+ $this->data[ $name ][ $values[0] ] = $values[1];
668
+ }
669
+ }
670
+ /**
671
+ * Get all option arguments.
672
+ * @param string $key
673
+ * @return array
674
+ */
675
+ private function get_args( $key = '' ){
676
+ if( empty( $key ) ) {
677
+ return $this->options_args;
678
+ }
679
+
680
+ if( isset( $this->options_args[ $key ] ) ) {
681
+ return $this->options_args[ $key ];
682
+ }
683
+
684
+ return false;
685
+ }
686
+ /**
687
+ * Resetting data on update.
688
+ * @return void
689
+ */
690
+ private function set_args_on_update(){
691
+ $args = $this->get_args();
692
+ $options_data = $this->get_options_data();
693
+ $set_data = $options_data[ $this->plugin_name ];
694
+ $args = wp_parse_args( $set_data, $args );
695
+ $this->update_options_data( $args );
696
+ }
697
+ /**
698
+ * When upgrade is complete. it will fired.
699
+ * @param WP_Upgrader $upgrader_object
700
+ * @param array $options
701
+ * @return void
702
+ */
703
+ public function upgrade_completed( $upgrader_object, $options ) {
704
+ // If an update has taken place and the updated type is plugins and the plugins element exists
705
+ if( isset( $options['action'] ) && $options['action'] == 'update' && $options['type'] == 'plugin' ) {
706
+ if( ! isset( $options['plugin'] ) && isset( $options['plugins'] ) ) {
707
+ foreach( $options['plugins'] as $plugin ) {
708
+ if( $plugin == $this->plugin_name ) {
709
+ $this->set_args_on_update();
710
+ }
711
+ }
712
+ }
713
+
714
+ if( isset( $options['plugin'] ) && $options['plugin'] == $this->plugin_name ) {
715
+ $this->set_args_on_update();
716
+ }
717
+ }
718
+ }
719
+ /**
720
+ * This function is responsible for get_user_notices
721
+ * @return void
722
+ */
723
+ private function get_user_notices() {
724
+ $notices = get_user_meta( get_current_user_id(), self::ADMIN_UPDATE_NOTICE_KEY, true );
725
+ return ! $notices ? array() : $notices;
726
+ }
727
+ /**
728
+ * This function is responsible for update meta information.
729
+ *
730
+ * @param string $notice
731
+ * @return void
732
+ */
733
+ private function update( $notice ){
734
+ if( empty( $notice ) ) {
735
+ return;
736
+ }
737
+ $options_data = $this->get_options_data();
738
+ $user_notices = $this->get_user_notices();
739
+ $user_notices[ $this->notice_id ][ $this->plugin_name ][] = $notice;
740
+ // Remove the upsale from notice_will_show field in options DB.
741
+ unset( $options_data[ $this->plugin_name ]['notice_will_show'][ $notice ] );
742
+ $this->update_options_data( $options_data[ $this->plugin_name ] );
743
+ // Set users meta, not to show again current_version notice.
744
+ update_user_meta( get_current_user_id(), self::ADMIN_UPDATE_NOTICE_KEY, $user_notices);
745
+ }
746
+
747
+ public function notice_dissmiss(){
748
+ if( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'wpdeveloper_notice_dissmiss' ) ) {
749
+ return;
750
+ }
751
+
752
+ if( ! isset( $_POST['action'] ) || ( $_POST['action'] !== 'wpdeveloper_notice_dissmiss_for_' . $this->plugin_name ) ) {
753
+ return;
754
+ }
755
+
756
+ $dismiss = isset( $_POST['dismiss'] ) ? $_POST['dismiss'] : false;
757
+ $notice = isset( $_POST['notice'] ) ? $_POST['notice'] : false;
758
+ if( $dismiss ) {
759
+ $this->update( $notice );
760
+ echo 'success';
761
+ } else {
762
+ echo 'failed';
763
+ }
764
+ die();
765
+ }
766
+
767
+ /**
768
+ * This function is responsible for do action when
769
+ * the dismiss button clicked in upsale notice.
770
+ */
771
+ public function upsale_notice_dissmiss(){
772
+
773
+ if( ! isset( $_POST['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['_wpnonce'] ) ), 'wpdeveloper_upsale_notice_dissmiss' ) ) {
774
+ return;
775
+ }
776
+
777
+ if( ! isset( $_POST['action'] ) || ( $_POST['action'] !== 'wpdeveloper_upsale_notice_dissmiss_for_' . $this->plugin_name ) ) {
778
+ return;
779
+ }
780
+
781
+ $dismiss = isset( $_POST['dismiss'] ) ? $_POST['dismiss'] : false;
782
+ if( $dismiss ) {
783
+ $this->update( 'upsale' );
784
+ echo 'success';
785
+ } else {
786
+ echo 'failed';
787
+ }
788
+ die();
789
+ }
790
+
791
+ public function dismiss_button_scripts(){
792
+ ?>
793
+ <script type="text/javascript">
794
+ jQuery(document).ready( function($) {
795
+ if( $('.notice').length > 0 ) {
796
+ if( $('.notice').find('.notice-dismiss').length > 0 ) {
797
+ $('.notice').on('click', 'button.notice-dismiss', function (e) {
798
+ e.preventDefault();
799
+ $.ajax({
800
+ url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
801
+ type: 'post',
802
+ data: {
803
+ action: 'wpdeveloper_notice_dissmiss_for_<?php echo $this->plugin_name; ?>',
804
+ _wpnonce: '<?php echo wp_create_nonce('wpdeveloper_notice_dissmiss'); ?>',
805
+ dismiss: true,
806
+ notice: $(this).data('notice'),
807
+ },
808
+ success: function(response) {
809
+ $('.notice').hide();
810
+ console.log('Successfully saved!');
811
+ },
812
+ error: function(error) {
813
+ console.log('Something went wrong!');
814
+ },
815
+ complete: function() {
816
+ console.log('Its Complete.');
817
+ }
818
+ });
819
+ });
820
+ }
821
+ }
822
+ } );
823
+ </script>
824
+ <?php
825
+ }
826
+
827
+ /**
828
+ * Upsale Button Script.
829
+ * When install button is clicked, it will do its own things.
830
+ * also for dismiss button JS.
831
+ * @return void
832
+ */
833
+ public function upsale_button_script(){
834
+ $upsale_args = $this->get_upsale_args();
835
+
836
+ $plugin_slug = ( isset( $upsale_args['slug'] ) ) ? $upsale_args['slug'] : '';
837
+ $plugin_file = ( isset( $upsale_args['file'] ) ) ? $upsale_args['file'] : '';
838
+ $page_slug = ( isset( $upsale_args['page_slug'] ) ) ? $upsale_args['page_slug'] : '';
839
+
840
+ ?>
841
+ <script type="text/javascript">
842
+ jQuery(document).ready( function($) {
843
+ <?php if( ! empty( $plugin_slug ) && ! empty( $plugin_file ) ) : ?>
844
+ $('#plugin-install-core-<?php echo $this->plugin_name; ?>').on('click', function (e) {
845
+ var self = $(this);
846
+ e.preventDefault();
847
+ self.addClass('install-now updating-message');
848
+ self.text('<?php echo esc_js( 'Installing...' ); ?>');
849
+
850
+ $.ajax({
851
+ url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
852
+ type: 'POST',
853
+ data: {
854
+ action: 'wpdeveloper_upsale_core_install_<?php echo $this->plugin_name; ?>',
855
+ _wpnonce: '<?php echo wp_create_nonce('wpdeveloper_upsale_core_install_' . $this->plugin_name); ?>',
856
+ slug : '<?php echo $plugin_slug; ?>',
857
+ file : '<?php echo $plugin_file; ?>'
858
+ },
859
+ success: function(response) {
860
+ self.text('<?php echo esc_js( 'Installed' ); ?>');
861
+ <?php if( ! empty( $page_slug ) ) : ?>
862
+ window.location.href = '<?php echo admin_url( "admin.php?page={$page_slug}" ); ?>';
863
+ <?php endif; ?>
864
+ },
865
+ error: function(error) {
866
+ self.removeClass('install-now updating-message');
867
+ alert( error );
868
+ },
869
+ complete: function() {
870
+ self.attr('disabled', 'disabled');
871
+ self.removeClass('install-now updating-message');
872
+ }
873
+ });
874
+ });
875
+
876
+ <?php endif; ?>
877
+
878
+ $('.wpdeveloper-upsale-notice').on('click', 'button.notice-dismiss', function (e) {
879
+ e.preventDefault();
880
+ $.ajax({
881
+ url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
882
+ type: 'post',
883
+ data: {
884
+ action: 'wpdeveloper_upsale_notice_dissmiss_for_<?php echo $this->plugin_name; ?>',
885
+ _wpnonce: '<?php echo wp_create_nonce('wpdeveloper_upsale_notice_dissmiss'); ?>',
886
+ dismiss: true
887
+ },
888
+ success: function(response) {
889
+ console.log('Successfully saved!');
890
+ },
891
+ error: function(error) {
892
+ console.log('Something went wrong!');
893
+ },
894
+ complete: function() {
895
+ console.log('Its Complete.');
896
+ }
897
+ });
898
+ });
899
+ } );
900
+ </script>
901
+
902
+ <?php
903
+ }
904
+ }
EmbedPress/Includes/Classes/EmbedPress_Plugin_Usage_Tracker.php ADDED
@@ -0,0 +1,996 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * This is the class that sends all the data back to the home site
4
+ * It also handles opting in and deactivation
5
+ * @version 1.1.2
6
+ */
7
+
8
+ namespace EmbedPress\Includes\Classes;
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit;
12
+ }// Exit if accessed directly
13
+
14
+ class EmbedPress_Plugin_Usage_Tracker {
15
+ private $wpins_version = '1.1.3';
16
+ private $home_url = '';
17
+ private $plugin_file = '';
18
+ private $plugin_name = '';
19
+ private $options = array();
20
+ private $require_optin = true;
21
+ private $include_goodbye_form = true;
22
+ private $marketing = false;
23
+ private $collect_email = false;
24
+
25
+ /**
26
+ * Class constructor
27
+ *
28
+ * @param $_home_url The URL to the site we're sending data to
29
+ * @param $_plugin_file The file path for this plugin
30
+ * @param $_options Plugin options to track
31
+ * @param $_require_optin Whether user opt-in is required (always required on WordPress.org)
32
+ * @param $_include_goodbye_form Whether to include a form when the user deactivates
33
+ * @param $_marketing Marketing method:
34
+ * 0: Don't collect email addresses
35
+ * 1: Request permission same time as tracking opt-in
36
+ * 2: Request permission after opt-in
37
+ */
38
+ public function __construct(
39
+ $_plugin_file,
40
+ $_home_url,
41
+ $_options,
42
+ $_require_optin=true,
43
+ $_include_goodbye_form=true,
44
+ $_marketing=false ) {
45
+
46
+ $this->plugin_file = $_plugin_file;
47
+ $this->home_url = trailingslashit( $_home_url );
48
+ $this->plugin_name = basename( $this->plugin_file, '.php' );
49
+ $this->options = $_options;
50
+ $this->require_optin = $_require_optin;
51
+ $this->include_goodbye_form = $_include_goodbye_form;
52
+ $this->marketing = $_marketing;
53
+
54
+ // Schedule some tracking when activated
55
+ register_activation_hook( $this->plugin_file, array( $this, 'schedule_tracking' ) );
56
+ // Deactivation hook
57
+ register_deactivation_hook( $this->plugin_file, array( $this, 'deactivate_this_plugin' ) );
58
+
59
+ // Get it going
60
+ $this->init();
61
+
62
+ }
63
+
64
+ public function init() {
65
+ // Check marketing
66
+ if( $this->marketing == 3 ) {
67
+ $this->set_can_collect_email( true, $this->plugin_name );
68
+ }
69
+ // Check whether opt-in is required
70
+ // If not, then tracking is allowed
71
+ if( ! $this->require_optin ) {
72
+ $this->set_can_collect_email( true, $this->plugin_name );
73
+ $this->set_is_tracking_allowed( true );
74
+ $this->update_block_notice();
75
+ $this->do_tracking( true );
76
+ }
77
+ // Hook our do_tracking function to the daily action
78
+ add_action( 'wpdeveloper_notice_clicked_for_' . $this->plugin_name, array( $this, 'clicked' ) );
79
+
80
+ add_action( 'put_do_weekly_action', array( $this, 'do_tracking' ) );
81
+ // Use this action for local testing and for one time force tracking in a life time.
82
+ // add_action( 'admin_init', array( $this, 'force_tracking' ) );
83
+
84
+ // Display the admin notice on activation
85
+ add_action( 'wpdeveloper_optin_notice_for_' . $this->plugin_name, array( $this, 'optin_notice' ) );
86
+ add_action( 'admin_notices', array( $this, 'marketing_notice' ) );
87
+
88
+ // Deactivation
89
+ add_filter( 'plugin_action_links_' . plugin_basename( $this->plugin_file ), array( $this, 'filter_action_links' ) );
90
+ add_action( 'admin_footer-plugins.php', array( $this, 'goodbye_ajax' ) );
91
+ add_action( 'wp_ajax_goodbye_form_' . esc_attr( $this->plugin_name ), array( $this, 'goodbye_form_callback' ) );
92
+
93
+ }
94
+
95
+ /**
96
+ * When the plugin is activated
97
+ * Create scheduled event
98
+ * And check if tracking is enabled - perhaps the plugin has been reactivated
99
+ *
100
+ * @since 1.0.0
101
+ */
102
+ public function schedule_tracking() {
103
+ // For historical reasons, this is called 'weekly' but is in fact daily
104
+ if ( ! wp_next_scheduled( 'put_do_weekly_action' ) ) {
105
+ wp_schedule_event( time(), 'daily', 'put_do_weekly_action' );
106
+ }
107
+ }
108
+ /**
109
+ * This function is responsible for force tracking the plugin,
110
+ * if users are allowed to do!
111
+ *
112
+ * @return void
113
+ */
114
+ public function force_tracking(){
115
+ $this->do_tracking( true );
116
+ }
117
+
118
+ /**
119
+ * This is our function to get everything going
120
+ * Check that user has opted in
121
+ * Collect data
122
+ * Then send it back
123
+ *
124
+ * @since 1.0.0
125
+ * @param $force Force tracking if it's not time
126
+ */
127
+ public function do_tracking( $force=false ) {
128
+ // If the home site hasn't been defined, we just drop out. Nothing much we can do.
129
+ if ( ! $this->home_url ) {
130
+ return;
131
+ }
132
+
133
+ // Check to see if the user has opted in to tracking
134
+ $allow_tracking = $this->get_is_tracking_allowed();
135
+ if( ! $allow_tracking ) {
136
+ return;
137
+ }
138
+
139
+ // Check to see if it's time to track
140
+ $track_time = $this->get_is_time_to_track();
141
+ if( ! $track_time && ! $force ) {
142
+ return;
143
+ }
144
+
145
+ $this->set_admin_email();
146
+
147
+ // Get our data
148
+ $body = $this->get_data();
149
+
150
+ // Send the data
151
+ $this->send_data( $body );
152
+ }
153
+
154
+ /**
155
+ * Send the data to the home site
156
+ *
157
+ * @since 1.0.0
158
+ */
159
+ public function send_data( $body ) {
160
+
161
+ $request = wp_remote_post(
162
+ esc_url( $this->home_url . '?usage_tracker=hello' ),
163
+ array(
164
+ 'method' => 'POST',
165
+ 'timeout' => 20,
166
+ 'redirection' => 5,
167
+ 'httpversion' => '1.1',
168
+ 'blocking' => true,
169
+ 'body' => $body,
170
+ 'user-agent' => 'PUT/1.0.0; ' . get_bloginfo( 'url' )
171
+ )
172
+ );
173
+
174
+ $this->set_track_time();
175
+
176
+ if( is_wp_error( $request ) ) {
177
+ return $request;
178
+ }
179
+
180
+ }
181
+
182
+ /**
183
+ * Here we collect most of the data
184
+ *
185
+ * @since 1.0.0
186
+ */
187
+ public function get_data() {
188
+
189
+ // Use this to pass error messages back if necessary
190
+ $body['message'] = '';
191
+ // Use this array to send data back
192
+ $body = array(
193
+ 'plugin_slug' => sanitize_text_field( $this->plugin_name ),
194
+ 'url' => get_bloginfo( 'url' ),
195
+ 'site_name' => get_bloginfo( 'name' ),
196
+ 'site_version' => get_bloginfo( 'version' ),
197
+ 'site_language' => get_bloginfo( 'language' ),
198
+ 'charset' => get_bloginfo( 'charset' ),
199
+ 'wpins_version' => $this->wpins_version,
200
+ 'php_version' => phpversion(),
201
+ 'multisite' => is_multisite(),
202
+ 'file_location' => __FILE__
203
+ );
204
+
205
+ // Collect the email if the correct option has been set
206
+ if( $this->get_can_collect_email() ) {
207
+ $body['email'] = $this->get_admin_email();
208
+ }
209
+ $body['marketing_method'] = $this->marketing;
210
+
211
+ $body['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '';
212
+
213
+ // Retrieve current plugin information
214
+ if( ! function_exists( 'get_plugins' ) ) {
215
+ include ABSPATH . '/wp-admin/includes/plugin.php';
216
+ }
217
+
218
+ $plugins = array_keys( get_plugins() );
219
+ $active_plugins = get_option( 'active_plugins', array() );
220
+
221
+ foreach ( $plugins as $key => $plugin ) {
222
+ if ( in_array( $plugin, $active_plugins ) ) {
223
+ // Remove active plugins from list so we can show active and inactive separately
224
+ unset( $plugins[$key] );
225
+ }
226
+ }
227
+
228
+ $body['active_plugins'] = $active_plugins;
229
+ $body['inactive_plugins'] = $plugins;
230
+
231
+ // Check text direction
232
+ $body['text_direction'] = 'LTR';
233
+ if( function_exists( 'is_rtl' ) ) {
234
+ if( is_rtl() ) {
235
+ $body['text_direction'] = 'RTL';
236
+ }
237
+ } else {
238
+ $body['text_direction'] = 'not set';
239
+ }
240
+
241
+ /**
242
+ * Get our plugin data
243
+ * Currently we grab plugin name and version
244
+ * Or, return a message if the plugin data is not available
245
+ * @since 1.0.0
246
+ */
247
+ $plugin = $this->plugin_data();
248
+ if( empty( $plugin ) ) {
249
+ // We can't find the plugin data
250
+ // Send a message back to our home site
251
+ $body['message'] .= __( 'We can\'t detect any plugin information. This is most probably because you have not included the code in the plugin main file.', 'notificationx' );
252
+ $body['status'] = 'Data not found'; // Never translated
253
+ } else {
254
+ if( isset( $plugin['Name'] ) ) {
255
+ $body['plugin'] = sanitize_text_field( $plugin['Name'] );
256
+ }
257
+ if( isset( $plugin['Version'] ) ) {
258
+ $body['version'] = sanitize_text_field( $plugin['Version'] );
259
+ }
260
+ $body['status'] = 'Active'; // Never translated
261
+ }
262
+
263
+ /**
264
+ * Get our plugin options
265
+ * @since 1.0.0
266
+ */
267
+ $options = $this->options;
268
+ $plugin_options = array();
269
+ if( ! empty( $options ) && is_array( $options ) ) {
270
+ foreach( $options as $option ) {
271
+ $fields = get_option( $option );
272
+ // Check for permission to send this option
273
+ if( isset( $fields['wpins_registered_setting'] ) ) {
274
+ foreach( $fields as $key=>$value ) {
275
+ $plugin_options[$key] = $value;
276
+ }
277
+ }
278
+ }
279
+ }
280
+ $body['plugin_options'] = $this->options; // Returns array
281
+ $body['plugin_options_fields'] = $plugin_options; // Returns object
282
+
283
+ /**
284
+ * Get our theme data
285
+ * Currently we grab theme name and version
286
+ * @since 1.0.0
287
+ */
288
+ $theme = wp_get_theme();
289
+ if( $theme->Name ) {
290
+ $body['theme'] = sanitize_text_field( $theme->Name );
291
+ }
292
+ if( $theme->Version ) {
293
+ $body['theme_version'] = sanitize_text_field( $theme->Version );
294
+ }
295
+
296
+ // Return the data
297
+ return $body;
298
+
299
+ }
300
+
301
+ /**
302
+ * Return plugin data
303
+ * @since 1.0.0
304
+ */
305
+ public function plugin_data() {
306
+ // Being cautious here
307
+ if( ! function_exists( 'get_plugin_data' ) ) {
308
+ include ABSPATH . '/wp-admin/includes/plugin.php';
309
+ }
310
+ // Retrieve current plugin information
311
+ $plugin = get_plugin_data( $this->plugin_file );
312
+ return $plugin;
313
+ }
314
+
315
+ /**
316
+ * Deactivating plugin
317
+ * @since 1.0.0
318
+ */
319
+ public function deactivate_this_plugin() {
320
+ // Check to see if the user has opted in to tracking
321
+ $allow_tracking = $this->get_is_tracking_allowed();
322
+ if( ! $allow_tracking ) {
323
+ return;
324
+ }
325
+ $body = $this->get_data();
326
+ $body['status'] = 'Deactivated'; // Never translated
327
+ $body['deactivated_date'] = time();
328
+
329
+ // Add deactivation form data
330
+ if( false !== get_option( 'wpins_deactivation_reason_' . $this->plugin_name ) ) {
331
+ $body['deactivation_reason'] = get_option( 'wpins_deactivation_reason_' . $this->plugin_name );
332
+ }
333
+ if( false !== get_option( 'wpins_deactivation_details_' . $this->plugin_name ) ) {
334
+ $body['deactivation_details'] = get_option( 'wpins_deactivation_details_' . $this->plugin_name );
335
+ }
336
+
337
+ $this->send_data( $body );
338
+ // Clear scheduled update
339
+ wp_clear_scheduled_hook( 'put_do_weekly_action' );
340
+ }
341
+
342
+ /**
343
+ * Is tracking allowed?
344
+ * @since 1.0.0
345
+ */
346
+ public function get_is_tracking_allowed() {
347
+ // First, check if the user has changed their mind and opted out of tracking
348
+ if( $this->has_user_opted_out() ) {
349
+ $this->set_is_tracking_allowed( false, $this->plugin_name );
350
+ return false;
351
+ }
352
+ // The wpins_allow_tracking option is an array of plugins that are being tracked
353
+ $allow_tracking = get_option( 'wpins_allow_tracking' );
354
+ // If this plugin is in the array, then tracking is allowed
355
+ if( isset( $allow_tracking[$this->plugin_name] ) ) {
356
+ return true;
357
+ }
358
+ return false;
359
+ }
360
+
361
+ /**
362
+ * Set if tracking is allowed
363
+ * Option is an array of all plugins with tracking permitted
364
+ * More than one plugin may be using the tracker
365
+ * @since 1.0.0
366
+ * @param $is_allowed Boolean true if tracking is allowed, false if not
367
+ */
368
+ public function set_is_tracking_allowed( $is_allowed, $plugin=null ) {
369
+ if( empty( $plugin ) ) {
370
+ $plugin = $this->plugin_name;
371
+ }
372
+ // The wpins_allow_tracking option is an array of plugins that are being tracked
373
+ $allow_tracking = get_option( 'wpins_allow_tracking' );
374
+
375
+ // If the user has decided to opt out
376
+ if( $this->has_user_opted_out() ) {
377
+ if( isset( $allow_tracking[$plugin] ) ) {
378
+ unset( $allow_tracking[$plugin] );
379
+ }
380
+ } else if( $is_allowed || ! $this->require_optin ) {
381
+ // If the user has agreed to allow tracking or if opt-in is not required
382
+ if( empty( $allow_tracking ) || ! is_array( $allow_tracking ) ) {
383
+ // If nothing exists in the option yet, start a new array with the plugin name
384
+ $allow_tracking = array( $plugin => $plugin );
385
+ } else {
386
+ // Else add the plugin name to the array
387
+ $allow_tracking[$plugin] = $plugin;
388
+ }
389
+ } else {
390
+ if( isset( $allow_tracking[$plugin] ) ) {
391
+ unset( $allow_tracking[$plugin] );
392
+ }
393
+ }
394
+ update_option( 'wpins_allow_tracking', $allow_tracking );
395
+ }
396
+
397
+ /**
398
+ * Has the user opted out of allowing tracking?
399
+ * @since 1.1.0
400
+ * @return Boolean
401
+ */
402
+ public function has_user_opted_out() {
403
+ // Iterate through the options that are being tracked looking for wpins_opt_out setting
404
+ if( ! empty( $this->options ) ) {
405
+ foreach( $this->options as $option_name ) {
406
+ // Check each option
407
+ $options = get_option( $option_name );
408
+ // If we find the setting, return true
409
+ if( ! empty( $options['wpins_opt_out'] ) ) {
410
+ return true;
411
+ }
412
+ }
413
+ }
414
+ return false;
415
+ }
416
+
417
+ /**
418
+ * Check if it's time to track
419
+ * @since 1.1.1
420
+ */
421
+ public function get_is_time_to_track() {
422
+ // Let's see if we're due to track this plugin yet
423
+ $track_times = get_option( 'wpins_last_track_time', array() );
424
+ if( ! isset( $track_times[$this->plugin_name] ) ) {
425
+ // If we haven't set a time for this plugin yet, then we must track it
426
+ return true;
427
+ } else {
428
+ // If the time is set, let's see if it's more than a day ago
429
+ if( $track_times[$this->plugin_name] < strtotime( '-1 day' ) ) {
430
+ return true;
431
+ }
432
+ }
433
+ return false;
434
+ }
435
+
436
+ /**
437
+ * Record the time we send tracking data
438
+ * @since 1.1.1
439
+ */
440
+ public function set_track_time() {
441
+ // We've tracked, so record the time
442
+ $track_times = get_option( 'wpins_last_track_time', array() );
443
+ // Set different times according to plugin, in case we are tracking multiple plugins
444
+ $track_times[$this->plugin_name] = time();
445
+ update_option( 'wpins_last_track_time', $track_times );
446
+ }
447
+
448
+ /**
449
+ * Set if we should block the opt-in notice for this plugin
450
+ * Option is an array of all plugins that have received a response from the user
451
+ * @since 1.0.0
452
+ */
453
+ public function update_block_notice( $plugin=null ) {
454
+ if( empty( $plugin ) ) {
455
+ $plugin = $this->plugin_name;
456
+ }
457
+ $block_notice = get_option( 'wpins_block_notice' );
458
+ if( empty( $block_notice ) || ! is_array( $block_notice ) ) {
459
+ // If nothing exists in the option yet, start a new array with the plugin name
460
+ $block_notice = array( $plugin => $plugin );
461
+ } else {
462
+ // Else add the plugin name to the array
463
+ $block_notice[$plugin] = $plugin;
464
+ }
465
+ update_option( 'wpins_block_notice', $block_notice );
466
+ }
467
+
468
+ /**
469
+ * Can we collect the email address?
470
+ * @since 1.0.0
471
+ */
472
+ public function get_can_collect_email() {
473
+ // The wpins_collect_email option is an array of plugins that are being tracked
474
+ $collect_email = get_option( 'wpins_collect_email' );
475
+ // If this plugin is in the array, then we can collect the email address
476
+ if( isset( $collect_email[$this->plugin_name] ) ) {
477
+ return true;
478
+ }
479
+ return false;
480
+ }
481
+
482
+ /**
483
+ * Set if user has allowed us to collect their email address
484
+ * Option is an array of all plugins with email collection permitted
485
+ * More than one plugin may be using the tracker
486
+ * @since 1.0.0
487
+ * @param $can_collect Boolean true if collection is allowed, false if not
488
+ */
489
+ public function set_can_collect_email( $can_collect, $plugin=null ) {
490
+ if( empty( $plugin ) ) {
491
+ $plugin = $this->plugin_name;
492
+ }
493
+ // The wpins_collect_email option is an array of plugins that are being tracked
494
+ $collect_email = get_option( 'wpins_collect_email' );
495
+ // If the user has agreed to allow tracking or if opt-in is not required
496
+ if( $can_collect ) {
497
+ if( empty( $collect_email ) || ! is_array( $collect_email ) ) {
498
+ // If nothing exists in the option yet, start a new array with the plugin name
499
+ $collect_email = array( $plugin => $plugin );
500
+ } else {
501
+ // Else add the plugin name to the array
502
+ $collect_email[$plugin] = $plugin;
503
+ }
504
+ } else {
505
+ if( isset( $collect_email[$plugin] ) ) {
506
+ unset( $collect_email[$plugin] );
507
+ }
508
+ }
509
+ update_option( 'wpins_collect_email', $collect_email );
510
+ }
511
+
512
+ /**
513
+ * Get the correct email address to use
514
+ * @since 1.1.2
515
+ * @return Email address
516
+ */
517
+ public function get_admin_email() {
518
+ // The wpins_collect_email option is an array of plugins that are being tracked
519
+ $email = get_option( 'wpins_admin_emails' );
520
+ // If this plugin is in the array, then we can collect the email address
521
+ if( isset( $email[$this->plugin_name] ) ) {
522
+ return $email[$this->plugin_name];
523
+ }
524
+ return false;
525
+ }
526
+
527
+ /**
528
+ * Set the correct email address to use
529
+ * There might be more than one admin on the site
530
+ * So we only use the first admin's email address
531
+ * @param $email Email address to set
532
+ * @param $plugin Plugin name to set email address for
533
+ * @since 1.1.2
534
+ */
535
+ public function set_admin_email( $email=null, $plugin=null ) {
536
+ if( empty( $plugin ) ) {
537
+ $plugin = $this->plugin_name;
538
+ }
539
+ // If no email address passed, try to get the current user's email
540
+ if( empty( $email ) ) {
541
+ // Have to check that current user object is available
542
+ if( function_exists( 'wp_get_current_user' ) ) {
543
+ $current_user = wp_get_current_user();
544
+ $email = $current_user->user_email;
545
+ }
546
+ }
547
+ // The wpins_admin_emails option is an array of admin email addresses
548
+ $admin_emails = get_option( 'wpins_admin_emails' );
549
+ if( empty( $admin_emails ) || ! is_array( $admin_emails ) ) {
550
+ // If nothing exists in the option yet, start a new array with the plugin name
551
+ $admin_emails = array( $plugin => sanitize_email( $email ) );
552
+ } else if( empty( $admin_emails[$plugin] ) ) {
553
+ // Else add the email address to the array, if not already set
554
+ $admin_emails[$plugin] = sanitize_email( $email );
555
+ }
556
+ update_option( 'wpins_admin_emails', $admin_emails );
557
+ }
558
+
559
+ public function clicked(){
560
+ // Check for plugin args
561
+ if( isset( $_GET['plugin'] ) && isset( $_GET['plugin_action'] ) ) {
562
+ $plugin = sanitize_text_field( $_GET['plugin'] );
563
+ $action = sanitize_text_field( $_GET['plugin_action'] );
564
+ if( $action == 'yes' ) {
565
+ $this->set_is_tracking_allowed( true, $plugin );
566
+ $this->do_tracking( true ); // Run this straightaway
567
+ } else {
568
+ $this->set_is_tracking_allowed( false, $plugin );
569
+ }
570
+ $this->update_block_notice( $plugin );
571
+ }
572
+ }
573
+
574
+ /**
575
+ * Display the admin notice to users to allow them to opt in
576
+ *
577
+ * @since 1.0.0
578
+ */
579
+ public function optin_notice() {
580
+ // Check whether to block the notice, e.g. because we're in a local environment
581
+ // wpins_block_notice works the same as wpins_allow_tracking, an array of plugin names
582
+ $block_notice = get_option( 'wpins_block_notice' );
583
+ if( isset( $block_notice[$this->plugin_name] ) ) {
584
+ return;
585
+ }
586
+
587
+ if ( ! current_user_can( 'manage_options' ) ) {
588
+ return;
589
+ }
590
+
591
+ // @credit EDD
592
+ // Don't bother asking user to opt in if they're in local dev
593
+ $is_local = false;
594
+ if( stristr( network_site_url( '/' ), '.dev' ) !== false || stristr( network_site_url( '/' ), 'localhost' ) !== false || stristr( network_site_url( '/' ), ':8888' ) !== false ) {
595
+ $is_local = true;
596
+ }
597
+ $is_local = apply_filters( 'wpins_is_local_' . $this->plugin_name, $is_local );
598
+ if ( $is_local ) {
599
+ $this->update_block_notice();
600
+ } else {
601
+
602
+ // Display the notice requesting permission to track
603
+ // Retrieve current plugin information
604
+ $plugin = $this->plugin_data();
605
+ $plugin_name = $plugin['Name'];
606
+
607
+ // Args to add to query if user opts in to tracking
608
+ $yes_args = array(
609
+ 'plugin' => $this->plugin_name,
610
+ 'plugin_action' => 'yes'
611
+ );
612
+
613
+ // Decide how to request permission to collect email addresses
614
+ if( $this->marketing == 1 ) {
615
+ // Option 1 combines permissions to track and collect email
616
+ $yes_args['marketing_optin'] = 'yes';
617
+ } else if( $this->marketing == 2 ) {
618
+ // Option 2 enables a second notice that fires after the user opts in to tracking
619
+ $yes_args['marketing'] = 'yes';
620
+ }
621
+ $url_yes = add_query_arg( $yes_args );
622
+ $url_no = add_query_arg( array(
623
+ 'plugin' => $this->plugin_name,
624
+ 'plugin_action' => 'no'
625
+ ) );
626
+
627
+ // Decide on notice text
628
+ if( $this->marketing != 1 ) {
629
+ // Standard notice text
630
+ $notice_text = __( 'Thank you for installing our plugin. We would like to track its usage on your site. We don\'t record any sensitive data, only information regarding the WordPress environment and plugin settings, which we will use to help us make improvements to the plugin. Tracking is completely optional.', 'notificationx' );
631
+ } else {
632
+ // If we have option 1 for marketing, we include reference to sending product information here
633
+ $notice_text = __( 'Want to help make <strong>EmbedPress</strong> even more awesome? You can get a <strong>10% discount coupon</strong> for Premium extensions if you allow us to track the usage. <a class="embedpress-insights-data-we-collect" href="#">What we collect.</a>', 'notificationx' );
634
+ }
635
+ // And we allow you to filter the text anyway
636
+ $notice_text = apply_filters( 'wpins_notice_text_' . esc_attr( $this->plugin_name ), $notice_text ); ?>
637
+
638
+ <div class="notice notice-info updated put-dismiss-notice">
639
+ <p><?php echo __( $notice_text, 'notificationx' ); ?></p>
640
+ <div class="embedpress-insights-data" style="display: none;">
641
+ <p><?php echo __( 'We collect non-sensitive diagnostic data and plugin usage information. Your site URL, WordPress & PHP version, plugins & themes and email address to send you the discount coupon. This data lets us make sure this plugin always stays compatible with the most popular plugins and themes. No spam, I promise.', 'notificationx' ); ?></p>
642
+ </div>
643
+ <p>
644
+ <a href="<?php echo esc_url( $url_yes ); ?>" class="button-primary"><?php _e( 'Sure, I\'d like to help', 'notificationx' ); ?></a>
645
+ <a href="<?php echo esc_url( $url_no ); ?>" class="button-secondary"><?php _e( 'No Thanks', 'notificationx' ); ?></a>
646
+ </p>
647
+ <?php echo "<script type='text/javascript'>jQuery('.embedpress-insights-data-we-collect').on('click', function(e) {
648
+ e.preventDefault();
649
+ jQuery('.embedpress-insights-data').slideToggle('fast');
650
+ });
651
+ </script>";?>
652
+ </div>
653
+ <?php
654
+ }
655
+ }
656
+ /**
657
+ * Display the marketing notice to users if enabled
658
+ * Only displays after the user has opted in to tracking
659
+ *
660
+ * @since 1.0.0
661
+ */
662
+ public function marketing_notice() {
663
+ // Check if user has opted in to marketing
664
+ if( isset( $_GET['marketing_optin'] ) ) {
665
+ // Set marketing optin
666
+ $this->set_can_collect_email( sanitize_text_field( $_GET['marketing_optin'] ), $this->plugin_name );
667
+ // Do tracking
668
+ $this->do_tracking( true );
669
+ } else if( isset( $_GET['marketing'] ) && $_GET['marketing']=='yes' ) {
670
+ // Display the notice requesting permission to collect email address
671
+ // Retrieve current plugin information
672
+ $plugin = $this->plugin_data();
673
+ $plugin_name = $plugin['Name'];
674
+
675
+ $url_yes = add_query_arg( array(
676
+ 'plugin' => $this->plugin_name,
677
+ 'marketing_optin' => 'yes'
678
+ ) );
679
+ $url_no = add_query_arg( array(
680
+ 'plugin' => $this->plugin_name,
681
+ 'marketing_optin' => 'no'
682
+ ) );
683
+
684
+ $marketing_text = __( 'Thank you for opting in to tracking. Would you like to receive occasional news about this plugin, including details of new features and special offers?', 'notificationx' );
685
+ $marketing_text = apply_filters( 'wpins_marketing_text_' . esc_attr( $this->plugin_name ), $marketing_text ); ?>
686
+
687
+ <div class="notice notice-info updated put-dismiss-notice">
688
+ <p><?php echo '<strong>' . esc_html( $plugin_name ) . '</strong>'; ?></p>
689
+ <p><?php echo esc_html( $marketing_text ); ?></p>
690
+ <p>
691
+ <a href="<?php echo esc_url( $url_yes ); ?>" data-putnotice="yes" class="button-secondary"><?php _e( 'Yes Please', 'notificationx' ); ?></a>
692
+ <a href="<?php echo esc_url( $url_no ); ?>" data-putnotice="no" class="button-secondary"><?php _e( 'No Thank You', 'notificationx' ); ?></a>
693
+ </p>
694
+ </div>
695
+ <?php }
696
+ }
697
+
698
+ /**
699
+ * Filter the deactivation link to allow us to present a form when the user deactivates the plugin
700
+ * @since 1.0.0
701
+ */
702
+ public function filter_action_links( $links ) {
703
+ // Check to see if the user has opted in to tracking
704
+ if( ! $this->get_is_tracking_allowed() ) {
705
+ return $links;
706
+ }
707
+ if( isset( $links['deactivate'] ) && $this->include_goodbye_form ) {
708
+ $deactivation_link = $links['deactivate'];
709
+
710
+
711
+ // Insert an onClick action to allow form before deactivating
712
+ $deactivation_link = str_replace( '<a ', '<div class="wpdev-put-goodbye-form-wrapper-'. esc_attr( $this->plugin_name ) .'"><div class="wpdev-put-goodbye-form-bg-'. esc_attr( $this->plugin_name ) .'"></div><span class="wpdev-put-goodbye-form" id="wpdev-put-goodbye-form-' . esc_attr( $this->plugin_name ) . '"></span></div><a onclick="javascript:event.preventDefault();" id="wpdev-put-goodbye-link-' . esc_attr( $this->plugin_name ) . '" ', $deactivation_link );
713
+ $links['deactivate'] = $deactivation_link;
714
+ }
715
+ return $links;
716
+ }
717
+
718
+ /*
719
+ * Form text strings
720
+ * These are non-filterable and used as fallback in case filtered strings aren't set correctly
721
+ * @since 1.0.0
722
+ */
723
+ public function form_default_text() {
724
+ $form = array();
725
+ $form['heading'] = __( 'Sorry to see you go', 'notificationx' );
726
+ $form['body'] = __( 'Before you deactivate the plugin, would you quickly give us your reason for doing so?', 'notificationx' );
727
+
728
+ $form['options'] = array(
729
+ __( 'I no longer need the plugin', 'notificationx' ),
730
+ [
731
+ 'label' => __( 'I found a better plugin', 'notificationx' ),
732
+ 'extra_field' => __( 'Please share which plugin', 'notificationx' )
733
+ ],
734
+ __( "I couldn't get the plugin to work", 'notificationx' ),
735
+ __( 'It\'s a temporary deactivation', 'notificationx' ),
736
+ [
737
+ 'label' => __( 'Other', 'notificationx' ),
738
+ 'extra_field' => __( 'Please share the reason', 'notificationx' ),
739
+ 'type' => 'textarea'
740
+ ]
741
+ );
742
+
743
+ return $form;
744
+ }
745
+
746
+ /**
747
+ * Form text strings
748
+ * These can be filtered
749
+ * The filter hook must be unique to the plugin
750
+ * @since 1.0.0
751
+ */
752
+ public function form_filterable_text() {
753
+ $form = $this->form_default_text();
754
+ return apply_filters( 'wpins_form_text_' . esc_attr( $this->plugin_name ), $form );
755
+ }
756
+
757
+ /**
758
+ * Form text strings
759
+ * These can be filtered
760
+ * @since 1.0.0
761
+ */
762
+ public function goodbye_ajax() {
763
+ // Get our strings for the form
764
+ $form = $this->form_filterable_text();
765
+ if( ! isset( $form['heading'] ) || ! isset( $form['body'] ) || ! isset( $form['options'] ) || ! is_array( $form['options'] ) || ! isset( $form['details'] ) ) {
766
+ // If the form hasn't been filtered correctly, we revert to the default form
767
+ $form = $this->form_default_text();
768
+ }
769
+ // Build the HTML to go in the form
770
+ $html = '<div class="wpdev-put-goodbye-form-head"><strong>' . esc_html( $form['heading'] ) . '</strong></div>';
771
+ $html .= '<div class="wpdev-put-goodbye-form-body"><p class="wpdev-put-goodbye-form-caption">' . esc_html( $form['body'] ) . '</p>';
772
+ if( is_array( $form['options'] ) ) {
773
+ $html .= '<div id="wpdev-'. esc_attr( $this->plugin_name ) .'-goodbye-options" class="wpdev-'. esc_attr( $this->plugin_name ) .'-goodbye-options"><ul>';
774
+ foreach( $form['options'] as $option ) {
775
+ if( is_array( $option ) ) {
776
+ $id = strtolower( str_replace( " ", "_", esc_attr( $option['label'] ) ) );
777
+ $id = $id . '_' . esc_attr( $this->plugin_name );
778
+ $html .= '<li class="has-goodbye-extra">';
779
+ $html .= '<input type="radio" name="wpdev-'. esc_attr( $this->plugin_name ) .'-goodbye-options" id="' . $id . '" value="' . esc_attr( $option['label'] ) . '">';
780
+ $html .= '<div><label for="' . $id . '">' . esc_attr( $option['label'] ) . '</label>';
781
+ if( isset( $option[ 'extra_field' ] ) && ! isset( $option['type'] )) {
782
+ $html .= '<input type="text" style="display: none" name="'. $id .'" id="' . str_replace( " ", "", esc_attr( $option['extra_field'] ) ) . '" placeholder="' . esc_attr( $option['extra_field'] ) . '">';
783
+ }
784
+ if( isset( $option[ 'extra_field' ] ) && isset( $option['type'] )) {
785
+ $html .= '<'. $option['type'] .' style="display: none" type="text" name="'. $id .'" id="' . str_replace( " ", "", esc_attr( $option['extra_field'] ) ) . '" placeholder="' . esc_attr( $option['extra_field'] ) . '"></' . $option['type'] . '>';
786
+ }
787
+ $html .= '</div></li>';
788
+ } else {
789
+ $id = strtolower( str_replace( " ", "_", esc_attr( $option ) ) );
790
+ $id = $id . '_' . esc_attr( $this->plugin_name );
791
+ $html .= '<li><input type="radio" name="wpdev-'. esc_attr( $this->plugin_name ) .'-goodbye-options" id="' . $id . '" value="' . esc_attr( $option ) . '"> <label for="' . $id . '">' . esc_attr( $option ) . '</label></li>';
792
+ }
793
+ }
794
+ $html .= '</ul></div><!-- .wpdev-'. esc_attr( $this->plugin_name ) .'-goodbye-options -->';
795
+ }
796
+ $html .= '</div><!-- .wpdev-put-goodbye-form-body -->';
797
+ $html .= '<p class="deactivating-spinner"><span class="spinner"></span> ' . __( 'Submitting form', 'notificationx' ) . '</p>';
798
+ ?>
799
+ <style type="text/css">
800
+ .wpdev-put-form-active-<?php echo esc_attr( $this->plugin_name ); ?> .wpdev-put-goodbye-form-bg-<?php echo esc_attr( $this->plugin_name ); ?> {
801
+ background: rgba( 0, 0, 0, .8 );
802
+ position: fixed;
803
+ top: 0;
804
+ left: 0;
805
+ width: 100%;
806
+ height: 100%;
807
+ z-index: 9;
808
+ }
809
+ .wpdev-put-goodbye-form-wrapper-<?php echo esc_attr( $this->plugin_name ); ?> {
810
+ position: relative;
811
+ display: none;
812
+ }
813
+ .wpdev-put-form-active-<?php echo esc_attr( $this->plugin_name ); ?> .wpdev-put-goodbye-form-wrapper-<?php echo esc_attr( $this->plugin_name ); ?> {
814
+ display: flex !important;
815
+ align-items: center;
816
+ justify-content: center;
817
+ width: 100%;
818
+ height: 100%;
819
+ position: fixed;
820
+ left: 0px;
821
+ top: 0px;
822
+ }
823
+ .wpdev-put-goodbye-form {
824
+ display: none;
825
+ }
826
+ .wpdev-put-form-active-<?php echo esc_attr( $this->plugin_name ); ?> .wpdev-put-goodbye-form {
827
+ position: relative !important;
828
+ width: 550px;
829
+ max-width: 80%;
830
+ background: #fff;
831
+ box-shadow: 2px 8px 23px 3px rgba(0,0,0,.2);
832
+ border-radius: 3px;
833
+ white-space: normal;
834
+ overflow: hidden;
835
+ display: block;
836
+ z-index: 999999;
837
+ }
838
+ .wpdev-put-goodbye-form-head {
839
+ background: #fff;
840
+ color: #495157;
841
+ padding: 18px;
842
+ box-shadow: 0 0 8px rgba(0,0,0,.1);
843
+ font-size: 15px;
844
+ }
845
+ .wpdev-put-goodbye-form .wpdev-put-goodbye-form-head strong {
846
+ font-size: 15px;
847
+ }
848
+ .wpdev-put-goodbye-form-body {
849
+ padding: 8px 18px;
850
+ color: #333;
851
+ }
852
+ .wpdev-put-goodbye-form-body label {
853
+ color: #6d7882;
854
+ padding-left: 5px;
855
+ }
856
+ .wpdev-put-goodbye-form-body .wpdev-put-goodbye-form-caption {
857
+ font-weight: 500;
858
+ font-size: 15px;
859
+ color: #495157;
860
+ line-height: 1.4;
861
+ }
862
+ .wpdev-put-goodbye-form-body #wpdev-<?php echo esc_attr( $this->plugin_name ); ?>-goodbye-options {
863
+ padding-top: 5px;
864
+ }
865
+ .wpdev-put-goodbye-form-body #wpdev-<?php echo esc_attr( $this->plugin_name ); ?>-goodbye-options ul > li {
866
+ margin-bottom: 15px;
867
+ }
868
+ .deactivating-spinner {
869
+ display: none;
870
+ padding-bottom: 20px !important;
871
+ }
872
+ .deactivating-spinner .spinner {
873
+ float: none;
874
+ margin: 4px 4px 0 18px;
875
+ vertical-align: bottom;
876
+ visibility: visible;
877
+ }
878
+ .wpdev-put-goodbye-form-footer {
879
+ padding: 8px 18px;
880
+ margin-bottom: 15px;
881
+ }
882
+ .wpdev-put-goodbye-form-footer > .wpdev-put-goodbye-form-buttons {
883
+ display: flex;
884
+ align-items: center;
885
+ justify-content: space-between;
886
+ }
887
+ .wpdev-put-goodbye-form-footer .wpsp-put-submit-btn {
888
+ background-color: #d30c5c;
889
+ -webkit-border-radius: 3px;
890
+ border-radius: 3px;
891
+ color: #fff;
892
+ line-height: 1;
893
+ padding: 15px 20px;
894
+ font-size: 13px;
895
+ }
896
+ .wpdev-put-goodbye-form-footer .wpsp-put-deactivate-btn {
897
+ font-size: 13px;
898
+ color: #a4afb7;
899
+ background: none;
900
+ float: right;
901
+ padding-right: 10px;
902
+ width: auto;
903
+ text-decoration: underline;
904
+ }
905
+ #wpdev-<?php echo esc_attr( $this->plugin_name ); ?>-goodbye-options ul li > div {
906
+ display: inline;
907
+ padding-left: 3px;
908
+ }
909
+ #wpdev-<?php echo esc_attr( $this->plugin_name ); ?>-goodbye-options ul li > div > input, #wpdev-<?php echo esc_attr( $this->plugin_name ); ?>-goodbye-options ul li > div > textarea {
910
+ margin: 10px 18px;
911
+ padding: 8px;
912
+ width: 80%;
913
+ }
914
+ </style>
915
+ <script>
916
+ jQuery(document).ready(function($){
917
+ $("#wpdev-put-goodbye-link-<?php echo esc_attr( $this->plugin_name ); ?>").on("click",function(){
918
+ // We'll send the user to this deactivation link when they've completed or dismissed the form
919
+ var url = document.getElementById("wpdev-put-goodbye-link-<?php echo esc_attr( $this->plugin_name ); ?>");
920
+ $('body').toggleClass('wpdev-put-form-active-<?php echo esc_attr( $this->plugin_name ); ?>');
921
+ $("#wpdev-put-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?>").fadeIn();
922
+ $("#wpdev-put-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?>").html( '<?php echo $html; ?>' + '<div class="wpdev-put-goodbye-form-footer"><div class="wpdev-put-goodbye-form-buttons"><a id="put-submit-form-<?php echo esc_attr( $this->plugin_name ); ?>" class="wpsp-put-submit-btn" href="#"><?php _e( 'Submit and Deactivate', 'notificationx' ); ?></a>&nbsp;<a class="wpsp-put-deactivate-btn" href="'+url+'"><?php _e( 'Just Deactivate', 'notificationx' ); ?></a></div></div>');
923
+ $('#put-submit-form-<?php echo esc_attr( $this->plugin_name ); ?>').on('click', function(e){
924
+ // As soon as we click, the body of the form should disappear
925
+ $("#wpdev-put-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?> .wpdev-put-goodbye-form-body").fadeOut();
926
+ $("#wpdev-put-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?> .wpdev-put-goodbye-form-footer").fadeOut();
927
+ // Fade in spinner
928
+ $("#wpdev-put-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?> .deactivating-spinner").fadeIn();
929
+ e.preventDefault();
930
+ var checkedInput = $("input[name='wpdev-<?php echo esc_attr( $this->plugin_name ); ?>-goodbye-options']:checked"),
931
+ checkedInputVal, details;
932
+ if( checkedInput.length > 0 ) {
933
+ checkedInputVal = checkedInput.val();
934
+ details = $('input[name="'+ checkedInput[0].id +'"], textarea[name="'+ checkedInput[0].id +'"]').val();
935
+ }
936
+
937
+ if( typeof details === 'undefined' ) {
938
+ details = '';
939
+ }
940
+ if( typeof checkedInputVal === 'undefined' ) {
941
+ checkedInputVal = 'No Reason';
942
+ }
943
+
944
+ var data = {
945
+ 'action': 'goodbye_form_<?php echo esc_attr( $this->plugin_name ); ?>',
946
+ 'values': checkedInputVal,
947
+ 'details': details,
948
+ 'security': "<?php echo wp_create_nonce ( 'wpins_goodbye_form' ); ?>",
949
+ 'dataType': "json"
950
+ }
951
+
952
+ $.post(
953
+ ajaxurl,
954
+ data,
955
+ function(response){
956
+ // Redirect to original deactivation URL
957
+ window.location.href = url;
958
+ }
959
+ );
960
+ });
961
+ $('#wpdev-<?php echo esc_attr( $this->plugin_name ); ?>-goodbye-options > ul ').on('click', 'li label, li > input', function( e ){
962
+ var parent = $(this).parents('li');
963
+ parent.siblings().find('label').next('input, textarea').css('display', 'none');
964
+ parent.find('label').next('input, textarea').css('display', 'block');
965
+ });
966
+ // If we click outside the form, the form will close
967
+ $('.wpdev-put-goodbye-form-bg-<?php echo esc_attr( $this->plugin_name ); ?>').on('click',function(){
968
+ $("#wpdev-put-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?>").fadeOut();
969
+ $('body').removeClass('wpdev-put-form-active-<?php echo esc_attr( $this->plugin_name ); ?>');
970
+ });
971
+ });
972
+
973
+
974
+ });
975
+ </script>
976
+ <?php }
977
+
978
+ /**
979
+ * AJAX callback when the form is submitted
980
+ * @since 1.0.0
981
+ */
982
+ public function goodbye_form_callback() {
983
+ check_ajax_referer( 'wpins_goodbye_form', 'security' );
984
+ if( isset( $_POST['values'] ) ) {
985
+ $values = $_POST['values'];
986
+ update_option( 'wpins_deactivation_reason_' . $this->plugin_name, $values );
987
+ }
988
+ if( isset( $_POST['details'] ) ) {
989
+ $details = sanitize_text_field( $_POST['details'] );
990
+ update_option( 'wpins_deactivation_details_' . $this->plugin_name, $details );
991
+ }
992
+ $this->do_tracking(); // Run this straightaway
993
+ echo 'success';
994
+ wp_die();
995
+ }
996
+ }
EmbedPress/Includes/Traits/Shared.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EmbedPress\Includes\Traits;
3
+
4
+ if (!defined('ABSPATH')) {
5
+ exit;
6
+ } // Exit if accessed directly
7
+ use \EmbedPress\Includes\Classes\EmbedPress_Plugin_Usage_Tracker;
8
+ use \EmbedPress\Includes\Classes\EmbedPress_Notice;
9
+
10
+ trait Shared {
11
+
12
+
13
+ /**
14
+ * Optional usage tracker
15
+ *
16
+ * @since v1.0.0
17
+ */
18
+ public function start_plugin_tracking() {
19
+ new EmbedPress_Plugin_Usage_Tracker(
20
+ EMBEDPRESS_FILE,
21
+ 'http://app.wpdeveloper.net',
22
+ array(),
23
+ true,
24
+ true,
25
+ 1
26
+ );
27
+ }
28
+
29
+ public function admin_notice() {
30
+ $notice = new EmbedPress_Notice(EMBEDPRESS_PLUGIN_BASENAME, EMBEDPRESS_VERSION);
31
+
32
+ /**
33
+ * Current Notice End Time.
34
+ * Notice will dismiss in 3 days if user does nothing.
35
+ */
36
+ $notice->cne_time = '3 Day';
37
+
38
+ /**
39
+ * Current Notice Maybe Later Time.
40
+ * Notice will show again in 7 days
41
+ */
42
+ $notice->maybe_later_time = '21 Day';
43
+
44
+ $notice->text_domain = 'embedpress';
45
+
46
+ $scheme = (parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY)) ? '&' : '?';
47
+ $url = $_SERVER['REQUEST_URI'] . $scheme;
48
+ $notice->links = [
49
+ 'review' => array(
50
+ 'later' => array(
51
+ 'link' => 'https://wordpress.org/support/plugin/embedpress/reviews/',
52
+ 'target' => '_blank',
53
+ 'label' => __('Ok, you deserve it!', 'embedpress'),
54
+ 'icon_class' => 'dashicons dashicons-external',
55
+ ),
56
+ 'allready' => array(
57
+ 'link' => $url,
58
+ 'label' => __('I already did', 'embedpress'),
59
+ 'icon_class' => 'dashicons dashicons-smiley',
60
+ 'data_args' => [
61
+ 'dismiss' => true,
62
+ ],
63
+ ),
64
+ 'maybe_later' => array(
65
+ 'link' => $url,
66
+ 'label' => __('Maybe Later', 'embedpress'),
67
+ 'icon_class' => 'dashicons dashicons-calendar-alt',
68
+ 'data_args' => [
69
+ 'later' => true,
70
+ ],
71
+ ),
72
+ 'support' => array(
73
+ 'link' => 'https://wordpress.org/support/plugin/embedpress/',
74
+ 'label' => __('I need help', 'embedpress'),
75
+ 'icon_class' => 'dashicons dashicons-sos',
76
+ ),
77
+ 'never_show_again' => array(
78
+ 'link' => $url,
79
+ 'label' => __('Never show again', 'embedpress'),
80
+ 'icon_class' => 'dashicons dashicons-dismiss',
81
+ 'data_args' => [
82
+ 'dismiss' => true,
83
+ ],
84
+ ),
85
+ ),
86
+ ];
87
+
88
+ /**
89
+ * This is review message and thumbnail.
90
+ */
91
+ $notice->message('review', '<p>' . __('We hope you\'re enjoying EmbedPress! Could you please do us a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation?', 'embedpress') . '</p>');
92
+ $notice->thumbnail('review', plugins_url('assets/images/icon-128x128.png', EMBEDPRESS_PLUGIN_BASENAME));
93
+ /**
94
+ * This is upsale notice settings
95
+ * classes for wrapper,
96
+ * Message message for showing.
97
+ */
98
+ $notice->classes( 'upsale', 'notice is-dismissible ' );
99
+ $notice->message( 'upsale', '<p>'. __( '8,000+ People already using <a href="https://wpdeveloper.net/ea/notificationX" target="_blank">EmbedPress</a> to increase their Sales & Engagement!', $notice->text_domain ) .'</p>' );
100
+ $notice->thumbnail( 'upsale', plugins_url( 'assets/images/nx-icon.svg', EMBEDPRESS_PLUGIN_BASENAME ) );
101
+
102
+ // Update Notice For PRO Version
103
+ if( $this->is_pro_active() && \version_compare( EMBEDPRESS_PRO_VERSION, '2.0.0', '<' ) ) {
104
+ $notice->classes( 'update', 'notice is-dismissible ' );
105
+ $notice->message( 'update', '<p>'. __( 'You are using an incompatible version of EmbedPress PRO. Please update to v3.4.0+. <a href="https://essential-addons.com/elementor/docs/manually-update-essential-addons-pro/" target="_blank">Follow manual update guide.</a>', $notice->text_domain ) .'</p>' );
106
+ $notice->thumbnail( 'update', plugins_url( 'assets/images/icon-128x128.png', EMBEDPRESS_PLUGIN_BASENAME ) );
107
+ }
108
+
109
+ $notice->upsale_args = array(
110
+ 'slug' => 'notificationx',
111
+ 'page_slug' => 'nx-builder',
112
+ 'file' => 'notificationx.php',
113
+ 'btn_text' => __( 'Install Free', 'embedpress'),
114
+ 'condition' => [
115
+ 'by' => 'class',
116
+ 'class' => 'NotificationX'
117
+ ],
118
+ );
119
+
120
+ $notice->options_args = array(
121
+ 'notice_will_show' => [
122
+ 'opt_in' => $notice->timestamp,
123
+ 'upsale' => $notice->makeTime($notice->timestamp, '14 Day'),
124
+ 'review' => $notice->makeTime($notice->timestamp, '7 Day'), // after 3 days
125
+ ],
126
+ );
127
+ if( $this->is_pro_active() && \version_compare( EMBEDPRESS_PRO_VERSION, '2.0.0', '<' ) ) {
128
+ $notice->options_args['notice_will_show']['update'] = $notice->timestamp;
129
+ }
130
+
131
+ $notice->init();
132
+ }
133
+
134
+ public function is_pro_active(){
135
+ return is_plugin_active('embedpress-pro/embedpress-pro.php');
136
+ }
137
+
138
+ public function embedpress_admin_notice(){
139
+ if ($this->is_pro_active()) {
140
+ return;
141
+ }
142
+
143
+ $plugin_list = [
144
+ 'embedpress-vimeo/embedpress-vimeo.php',
145
+ 'embedpress-wistia/embedpress-wistia.php',
146
+ 'embedpress-youtube/embedpress-youtube.php',
147
+ ];
148
+ $active_plugins = get_option('active_plugins');
149
+ foreach($active_plugins as $plugin){
150
+ if(in_array($plugin,$plugin_list)){
151
+ $msg = '<strong>[Good News]</strong> Introducing <strong>EmbedPress Pro</strong>! And as existing Loyal User you get Unlimited Sites access to EmbedPress Pro for free. Please update and claim your free license to continue. <br/><strong>[<a href="https://embedpress.com/ep-loyal-users" target="_blank" rel="noopener">Details</a>] - [<a href="https://embedpress.com/new-pro-2020-free" target="_blank" rel="noopener">Get EmbedPress Pro for Free</a>]</strong>';
152
+ echo '<div class="notice notice-info is-dismissible">
153
+ <p>'.$msg.'</p>
154
+ </div>';
155
+ break;
156
+ }
157
+ }
158
+ }
159
+
160
+ }
EmbedPress/Plugins/Html/Field.php CHANGED
@@ -145,51 +145,6 @@ class Field
145
 
146
  $html .= wp_nonce_field("{$pluginSlug}:nonce", "{$pluginSlug}:nonce");
147
 
148
- if ($field->slug === "license_key") {
149
- $licenseStatusClass = "ep-label-danger";
150
- $currentLicenseStatus = isset($options['license']['status']) ? trim(strtoupper($options['license']['status'])) : "";
151
- switch ($currentLicenseStatus) {
152
- case '':
153
- $licenseStatusMessage = "Missing license";
154
- break;
155
- case 'EXPIRED':
156
- $licenseStatusMessage = "Your license key is expired";
157
- break;
158
- case 'REVOKED':
159
- $licenseStatusMessage = "Your license key has been disabled";
160
- break;
161
- case 'MISSING':
162
- case 'INVALID':
163
- $licenseStatusMessage = "Invalid license";
164
- break;
165
- case 'SITE_INACTIVE':
166
- $licenseStatusMessage = "Your license is not active for this URL";
167
- break;
168
- case 'ITEM_NAME_MISMATCH':
169
- $licenseStatusMessage = "This appears to be an invalid license key for this product";
170
- break;
171
- case 'NO_ACTIVATIONS_LEFT':
172
- $licenseStatusMessage = "Your license key has reached its activation limit";
173
- break;
174
- case 'VALID':
175
- $licenseStatusClass = "ep-label-success";
176
- $licenseStatusMessage = "Activated";
177
- break;
178
- default:
179
- $licenseStatusMessage = "Not validated yet";
180
- break;
181
- }
182
-
183
- $html .= '<br/><br/><strong>Status: <span class="' . $licenseStatusClass . '">' . __($licenseStatusMessage) . '</span>.</strong><br/><br/>';
184
-
185
- if ( ! (isset($options['license']['status']) && $options['license']['status'] === 'valid')) {
186
- $html .= '<a href="' . EMBEDPRESS_LICENSES_MORE_INFO_URL . '" target="_blank" class="ep-small-link ep-small-spacing" rel="noopener noreferrer" style="display: inline-block; margin-left: 20px;" title="' . __('Click here to read more about licenses.') . '">' . __('More information') . '</a>';
187
- $html .= '<br/><br/>';
188
- }
189
-
190
- $html .= '<hr>';
191
- }
192
-
193
  if ( ! empty($field->description)) {
194
  $html .= '<br/>';
195
  $html .= '<p class="description">' . $field->description . '</p>';
145
 
146
  $html .= wp_nonce_field("{$pluginSlug}:nonce", "{$pluginSlug}:nonce");
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  if ( ! empty($field->description)) {
149
  $html .= '<br/>';
150
  $html .= '<p class="description">' . $field->description . '</p>';
EmbedPress/Plugins/Plugin.php CHANGED
@@ -2,10 +2,6 @@
2
 
3
  namespace EmbedPress\Plugins;
4
 
5
- use PublishPress\EDD_License\Core\Container as EDDContainer;
6
- use PublishPress\EDD_License\Core\Services as EDDServices;
7
- use PublishPress\EDD_License\Core\ServicesConfig as EDDServicesConfig;
8
-
9
  (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
10
 
11
  /**
@@ -22,36 +18,6 @@ abstract class Plugin
22
  {
23
  const VERSION = '0.0.0';
24
 
25
- protected static $eddContainer;
26
-
27
- protected static function getEddContainer()
28
- {
29
- if (empty(static::$eddContainer)) {
30
- $options = static::getOptions();
31
-
32
- $licenseKey = isset($options['license']['key']) ? (string)$options['license']['key'] : "";
33
- $licenseStatus = isset($options['license']['status']) ? (string)$options['license']['status'] : "missed";
34
-
35
- $config = new EDDServicesConfig();
36
- $config->setApiUrl(EMBEDPRESS_LICENSES_API_URL);
37
- $config->setLicenseKey($licenseKey);
38
- $config->setLicenseStatus($licenseStatus);
39
- $config->setPluginVersion(static::VERSION);
40
- $config->setEddItemId(static::EDD_ID);
41
- $config->setPluginAuthor('EmbedPress');
42
- $config->setPluginFile(EMBEDPRESS_PLG_NAME . '/' . EMBEDPRESS_PLG_NAME . '.php');
43
-
44
- $services = new EDDServices($config);
45
-
46
- $eddContainer = new EDDContainer();
47
- $eddContainer->register($services);
48
-
49
- static::$eddContainer = $eddContainer;
50
- }
51
-
52
- return static::$eddContainer;
53
- }
54
-
55
  /**
56
  * Method that register all EmbedPress events.
57
  *
@@ -76,9 +42,7 @@ abstract class Plugin
76
  */
77
  protected static function isEmbedPressActive()
78
  {
79
- $isEmbedPressActive = is_plugin_active(EMBEDPRESS_PLG_NAME . '/' . EMBEDPRESS_PLG_NAME . '.php');
80
-
81
- return $isEmbedPressActive;
82
  }
83
 
84
  /**
@@ -116,13 +80,6 @@ abstract class Plugin
116
  deactivate_plugins($pluginSignature);
117
  } else {
118
  static::registerSettings();
119
-
120
- $eddContainer = static::getEddContainer();
121
- /*
122
- * Instantiate the update manager. The variable is not used by purpose, only
123
- * to instantiate the manager.
124
- */
125
- $update = $eddContainer['update_manager'];
126
  }
127
  }
128
 
@@ -184,13 +141,9 @@ abstract class Plugin
184
 
185
  $data[$fieldSlug] = $value;
186
  }
187
-
188
  static::onAfterFormValidation($data);
189
-
190
- if (isset($data['license_key'])) {
191
- unset($data['license_key']);
192
- }
193
-
194
  return $data;
195
  }
196
 
@@ -215,6 +168,8 @@ abstract class Plugin
215
  * @since 1.4.0
216
  * @static
217
  *
 
 
218
  * @return void
219
  */
220
  public static function renderTab($activeTab)
@@ -238,7 +193,6 @@ abstract class Plugin
238
  public static function registerSettings()
239
  {
240
  $identifier = EMBEDPRESS_PLG_NAME . ':' . static::SLUG;
241
-
242
  register_setting($identifier, $identifier, [static::NAMESPACE_STRING, 'validateForm']);
243
  add_settings_section($identifier, EMBEDPRESS . ' > ' . static::NAME . ' Settings',
244
  [static::NAMESPACE_STRING, 'onAfterRegisterSettings'], $identifier);
@@ -261,7 +215,9 @@ abstract class Plugin
261
  $schema = static::getOptionsSchema();
262
  foreach ($schema as $fieldSlug => $field) {
263
  $field['slug'] = $fieldSlug;
264
-
 
 
265
  add_settings_field($fieldSlug, $field['label'], [__NAMESPACE__ . '\Html\Field', 'render'], $identifier,
266
  $identifier, [
267
  'pluginSlug' => static::SLUG,
@@ -305,7 +261,7 @@ abstract class Plugin
305
 
306
  if ($fieldSlug === "license_key") {
307
  $options['license'] = [
308
- 'key' => $value,
309
  'status' => "missing",
310
  ];
311
  } else {
@@ -314,6 +270,11 @@ abstract class Plugin
314
  }
315
  }
316
 
 
 
 
 
 
317
  return $options;
318
  }
319
 
@@ -334,22 +295,4 @@ abstract class Plugin
334
 
335
  return $links;
336
  }
337
-
338
- /**
339
- * Method that validates a license key.
340
- *
341
- * @since 1.4.0
342
- * @access protected
343
- * @static
344
- *
345
- * @return mixed
346
- */
347
- protected static function validateLicenseKey($licenseKey)
348
- {
349
- $licenseManager = static::$eddContainer['license_manager'];
350
-
351
- $licenseNewStatus = $licenseManager->validate_license_key($licenseKey, static::EDD_ID);
352
-
353
- return $licenseNewStatus;
354
- }
355
  }
2
 
3
  namespace EmbedPress\Plugins;
4
 
 
 
 
 
5
  (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
6
 
7
  /**
18
  {
19
  const VERSION = '0.0.0';
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  /**
22
  * Method that register all EmbedPress events.
23
  *
42
  */
43
  protected static function isEmbedPressActive()
44
  {
45
+ return is_plugin_active(EMBEDPRESS_PLG_NAME . '/' . EMBEDPRESS_PLG_NAME . '.php');
 
 
46
  }
47
 
48
  /**
80
  deactivate_plugins($pluginSignature);
81
  } else {
82
  static::registerSettings();
 
 
 
 
 
 
 
83
  }
84
  }
85
 
141
 
142
  $data[$fieldSlug] = $value;
143
  }
144
+ $data['license_key'] = true;
145
  static::onAfterFormValidation($data);
146
+
 
 
 
 
147
  return $data;
148
  }
149
 
168
  * @since 1.4.0
169
  * @static
170
  *
171
+ * @param $activeTab
172
+ *
173
  * @return void
174
  */
175
  public static function renderTab($activeTab)
193
  public static function registerSettings()
194
  {
195
  $identifier = EMBEDPRESS_PLG_NAME . ':' . static::SLUG;
 
196
  register_setting($identifier, $identifier, [static::NAMESPACE_STRING, 'validateForm']);
197
  add_settings_section($identifier, EMBEDPRESS . ' > ' . static::NAME . ' Settings',
198
  [static::NAMESPACE_STRING, 'onAfterRegisterSettings'], $identifier);
215
  $schema = static::getOptionsSchema();
216
  foreach ($schema as $fieldSlug => $field) {
217
  $field['slug'] = $fieldSlug;
218
+ if('license_key'===$fieldSlug){
219
+ continue;
220
+ }
221
  add_settings_field($fieldSlug, $field['label'], [__NAMESPACE__ . '\Html\Field', 'render'], $identifier,
222
  $identifier, [
223
  'pluginSlug' => static::SLUG,
261
 
262
  if ($fieldSlug === "license_key") {
263
  $options['license'] = [
264
+ 'key' => true,
265
  'status' => "missing",
266
  ];
267
  } else {
270
  }
271
  }
272
 
273
+ $options['license'] = [
274
+ 'key' => true,
275
+ 'status' => "missing",
276
+ ];
277
+
278
  return $options;
279
  }
280
 
295
 
296
  return $links;
297
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  }
EmbedPress/RestAPI.php CHANGED
@@ -2,6 +2,9 @@
2
 
3
  namespace EmbedPress;
4
 
 
 
 
5
  (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
6
 
7
  /**
@@ -16,14 +19,16 @@ namespace EmbedPress;
16
  class RestAPI
17
  {
18
  /**
19
- * @param \WP_REST_Request $request
 
 
20
  */
21
  public static function oembed($request)
22
  {
23
  $url = sanitize_url($request->get_param('url'));
24
 
25
  if (empty($url)) {
26
- return new \WP_Error('embedpress_invalid_url', 'Invalid Embed URL', ['status' => 404]);
27
  }
28
 
29
  $config = [];
@@ -43,9 +48,9 @@ class RestAPI
43
  }
44
 
45
  if (empty($urlInfo)) {
46
- return new \WP_Error('embedpress_invalid_url', 'Invalid Embed URL', ['status' => 404]);
47
  }
48
 
49
- return new \WP_REST_Response($urlInfo, 202);
50
  }
51
  }
2
 
3
  namespace EmbedPress;
4
 
5
+ use WP_Error as WP_ErrorAlias;
6
+ use WP_REST_Response;
7
+
8
  (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
9
 
10
  /**
19
  class RestAPI
20
  {
21
  /**
22
+ * @param WP_REST_Request $request
23
+ *
24
+ * @return WP_REST_Response
25
  */
26
  public static function oembed($request)
27
  {
28
  $url = sanitize_url($request->get_param('url'));
29
 
30
  if (empty($url)) {
31
+ return new WP_ErrorAlias('embedpress_invalid_url', 'Invalid Embed URL', ['status' => 404]);
32
  }
33
 
34
  $config = [];
48
  }
49
 
50
  if (empty($urlInfo)) {
51
+ return new WP_ErrorAlias('embedpress_invalid_url', 'Invalid Embed URL', ['status' => 404]);
52
  }
53
 
54
+ return new WP_REST_Response($urlInfo, 202);
55
  }
56
  }
EmbedPress/Shortcode.php CHANGED
@@ -55,8 +55,14 @@ class Shortcode
55
  *
56
  * @return string
57
  */
 
58
  public static function do_shortcode($attributes = [], $subject = null)
59
  {
 
 
 
 
 
60
  $embed = self::parseContent($subject, true, $attributes);
61
 
62
  return is_object($embed) ? $embed->embed : $embed;
@@ -88,7 +94,7 @@ class Shortcode
88
 
89
  // Check if the WP_oEmbed class is loaded
90
  if ( ! self::$oEmbedInstance) {
91
- require_once ABSPATH . 'wp-includes/class-oembed.php';
92
 
93
  self::$oEmbedInstance = _wp_oembed_get_object();
94
  }
@@ -315,12 +321,12 @@ class Shortcode
315
  }
316
 
317
  if (preg_match('~width\s+:\s+(\d+)~i', $parsedContent)) {
318
- $parsedContent = preg_replace('~width\s+:\s+(\d+)~i', 'width: ' . $customWidth, $parseContent);
319
  }
320
 
321
  if (preg_match('~height\s+:\s+(\d+)~i', $parsedContent)) {
322
  $parsedContent = preg_replace('~height\s+:\s+(\d+)~i', 'height: ' . $customHeight,
323
- $parseContent);
324
  }
325
  }
326
  }
@@ -337,9 +343,7 @@ class Shortcode
337
  'embed' => $parsedContent,
338
  'url' => $content,
339
  ]);
340
-
341
  $embed = apply_filters('embedpress:onAfterEmbed', $embed);
342
-
343
  return $embed;
344
  }
345
  }
@@ -500,6 +504,9 @@ class Shortcode
500
  }
501
 
502
  $attributes['class'] = implode(' ', array_unique(array_filter($attributes['class'])));
 
 
 
503
 
504
  return $attributes;
505
  }
55
  *
56
  * @return string
57
  */
58
+
59
  public static function do_shortcode($attributes = [], $subject = null)
60
  {
61
+ $plgSettings = Core::getSettings();
62
+ $attributes = wp_parse_args($attributes,[
63
+ 'width' => $plgSettings->enableEmbedResizeWidth,
64
+ 'height' => $plgSettings->enableEmbedResizeHeight
65
+ ]);
66
  $embed = self::parseContent($subject, true, $attributes);
67
 
68
  return is_object($embed) ? $embed->embed : $embed;
94
 
95
  // Check if the WP_oEmbed class is loaded
96
  if ( ! self::$oEmbedInstance) {
97
+ require_once ABSPATH . 'wp-includes/class-wp-oembed.php';
98
 
99
  self::$oEmbedInstance = _wp_oembed_get_object();
100
  }
321
  }
322
 
323
  if (preg_match('~width\s+:\s+(\d+)~i', $parsedContent)) {
324
+ $parsedContent = preg_replace('~width\s+:\s+(\d+)~i', 'width: ' . $customWidth, $parsedContent);
325
  }
326
 
327
  if (preg_match('~height\s+:\s+(\d+)~i', $parsedContent)) {
328
  $parsedContent = preg_replace('~height\s+:\s+(\d+)~i', 'height: ' . $customHeight,
329
+ $parsedContent);
330
  }
331
  }
332
  }
343
  'embed' => $parsedContent,
344
  'url' => $content,
345
  ]);
 
346
  $embed = apply_filters('embedpress:onAfterEmbed', $embed);
 
347
  return $embed;
348
  }
349
  }
504
  }
505
 
506
  $attributes['class'] = implode(' ', array_unique(array_filter($attributes['class'])));
507
+ if(isset($attributes['width'])){
508
+ $attributes['style'] = "width:{$attributes['width'] }px;height:{$attributes['height'] }px;";
509
+ }
510
 
511
  return $attributes;
512
  }
EmbedPress/index.html CHANGED
File without changes
Gutenberg/src/common/core-embeds.js CHANGED
File without changes
Gutenberg/src/common/embed-controls.js CHANGED
File without changes
Gutenberg/src/common/embed-loading.js CHANGED
File without changes
Gutenberg/src/common/embed-placeholder.js CHANGED
File without changes
Gutenberg/src/common/icons.js CHANGED
File without changes
assets/css/admin.css CHANGED
@@ -204,16 +204,19 @@
204
  }
205
 
206
  #embedpress-settings-wrapper .button-primary {
207
- background-color: #FFB300;
208
- border-color: #C58C07;
209
- color: #754D26;
210
- }
211
-
212
- #embedpress-settings-wrapper .button-primary:hover,
213
- #embedpress-settings-wrapper .button-primary:active,
214
- #embedpress-settings-wrapper .button-primary:focus {
215
- background-color: #F3AC04;
216
- color: #333;
 
 
 
217
  }
218
 
219
  #embedpress-settings-wrapper button:not(.notice-dismiss).button-secondary {
204
  }
205
 
206
  #embedpress-settings-wrapper .button-primary {
207
+ line-height: 1;
208
+ border: none;
209
+ border-radius: 0;
210
+ background-color: #dc4444;
211
+ color: #ffffff;
212
+ font-size: 14px;
213
+ width: 150px;
214
+ height: 38px;
215
+ border-radius: 5px;
216
+ transition: all .3s;
217
+ text-shadow: none;
218
+ box-shadow: none;
219
+ margin: 0;
220
  }
221
 
222
  #embedpress-settings-wrapper button:not(.notice-dismiss).button-secondary {
assets/css/embedpress.css CHANGED
@@ -5,6 +5,9 @@
5
  * @license GPLv2 or later
6
  * @since 1.0
7
  */
 
 
 
8
 
9
  .ose-dailymotion.responsive,
10
  .ose-kickstarter.responsive,
5
  * @license GPLv2 or later
6
  * @since 1.0
7
  */
8
+ .embedpress-wrapper {
9
+ position: relative;
10
+ }
11
 
12
  .ose-dailymotion.responsive,
13
  .ose-kickstarter.responsive,
assets/css/index.html CHANGED
File without changes
assets/css/preview.css CHANGED
@@ -56,9 +56,9 @@
56
  .embedpress_controller_panel {
57
  display: inline-block;
58
  position: absolute;
 
59
  padding: 8px;
60
  margin-left: -45px;
61
- width: 62px;
62
  top: 1px;
63
  left: 50%;
64
  background: #796FAB;
56
  .embedpress_controller_panel {
57
  display: inline-block;
58
  position: absolute;
59
+ width: initial;
60
  padding: 8px;
61
  margin-left: -45px;
 
62
  top: 1px;
63
  left: 50%;
64
  background: #796FAB;
assets/css/vendor/bootstrap/bootstrap.css CHANGED
File without changes
assets/css/vendor/bootstrap/bootstrap.css.map CHANGED
File without changes
assets/css/vendor/bootstrap/bootstrap.min.css CHANGED
File without changes
assets/css/vendor/bootstrap/index.html CHANGED
File without changes
assets/css/vendor/index.html CHANGED
File without changes
assets/fonts/embedpress.eot CHANGED
File without changes
assets/fonts/embedpress.svg CHANGED
File without changes
assets/fonts/embedpress.ttf CHANGED
File without changes
assets/fonts/embedpress.woff CHANGED
File without changes
assets/fonts/index.html CHANGED
File without changes
assets/images/index.html CHANGED
File without changes
assets/images/menu-icon.png CHANGED
File without changes
assets/images/nx-icon.svg ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg width="387px" height="392px" viewBox="0 0 387 392" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
2
+ <!-- Generator: Sketch 51.2 (57519) - http://www.bohemiancoding.com/sketch -->
3
+ <desc>Created with Sketch.</desc>
4
+ <defs></defs>
5
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
6
+ <g id="NotificationX_final" transform="translate(-1564.000000, -253.000000)">
7
+ <g id="Group" transform="translate(1564.000000, 253.000000)">
8
+ <path d="M135.45,358.68 C173.45,358.68 211.27,358.68 249.07,358.68 C247.02,371.83 221.24,388.59 199.26,390.98 C173.92,393.73 143.23,378.38 135.45,358.68 Z" id="Shape" fill="#5614D5" fill-rule="nonzero"></path>
9
+ <path d="M372.31,305.79 C369.97,305.59 367.6,305.71 365.24,305.71 C359.63,305.7 354.02,305.71 347.08,305.71 C347.08,301.43 347.08,298.42 347.08,295.41 C347.07,248.75 347.25,202.09 346.91,155.43 C346.83,144.89 345.88,134.19 343.79,123.87 C326.39,37.9 239.94,-16.19 154.81,5.22 C86.84,22.31 37.91,84.26 38.19,154.7 C38.36,197.12 38.21,239.54 38.2,281.96 C38.2,285.8 38.18,297.79 38.16,305.7 C32.98,305.66 18.07,305.57 12.86,305.88 C5.13,306.33 -0.06,312.31 0.04,319.97 C0.14,327.43 5.08,332.74 12.67,333.42 C14.78,333.61 16.91,333.57 19.03,333.57 C134.74,333.61 250.46,333.64 366.17,333.66 C368.29,333.66 370.42,333.69 372.53,333.48 C380.01,332.73 385.14,327.23 385.28,319.95 C385.41,312.58 379.86,306.44 372.31,305.79 Z" id="Shape" fill="#5614D5" fill-rule="nonzero"></path>
10
+ <circle id="Oval" fill="#836EFF" fill-rule="nonzero" cx="281.55" cy="255.92" r="15.49"></circle>
11
+ <path d="M295.67,140.1 L295.91,139.94 C295.7,138.63 295.52,137.29 295.27,136.02 C285.87,89.57 245.83,55.34 198.79,52.53 C198.73,52.53 198.67,52.52 198.61,52.52 C196.59,52.4 194.57,52.32 192.53,52.32 C192.48,52.32 192.44,52.32 192.39,52.32 C192.34,52.32 192.3,52.32 192.25,52.32 C190.21,52.32 188.18,52.4 186.17,52.52 C186.11,52.52 186.05,52.53 185.99,52.53 C138.95,55.34 98.91,89.57 89.51,136.02 C89.25,137.29 89.07,138.63 88.87,139.94 L89.11,140.1 C88.2,145.6 87.72,151.22 87.74,156.9 C87.76,161.42 87.77,256.77 87.78,269.74 L119.91,304.42 C119.91,280.14 119.9,170.57 119.85,156.78 C119.72,124.18 142.81,94.69 174.76,86.66 C177.41,85.99 180.09,85.5 182.78,85.13 C183.23,85.07 183.67,85 184.13,84.95 C185.15,84.83 186.17,84.74 187.18,84.66 C188.64,84.56 190.1,84.48 191.58,84.47 C191.85,84.47 192.12,84.45 192.39,84.44 C192.66,84.44 192.93,84.46 193.2,84.47 C194.68,84.48 196.14,84.56 197.6,84.66 C198.62,84.74 199.64,84.83 200.65,84.95 C201.1,85 201.55,85.07 202,85.13 C204.69,85.5 207.37,85.99 210.02,86.66 C241.96,94.69 265.06,124.19 264.93,156.78 C264.91,161.95 264.9,207.07 264.89,228.18 L297.03,206.73 C297.03,194.5 297.04,158.28 297.04,156.91 C297.06,151.21 296.59,145.6 295.67,140.1 Z" id="Shape" fill="#836EFF" fill-rule="nonzero"></path>
12
+ <path d="M31.94,305.72 C25.58,305.85 19.2,305.51 12.86,305.88 C5.13,306.33 -0.06,312.31 0.04,319.97 C0.14,327.43 5.08,332.74 12.67,333.42 C14.78,333.61 16.91,333.57 19.03,333.57 C134.74,333.61 250.45,333.63 366.17,333.66 C368.29,333.66 370.42,333.69 372.53,333.48 C380.01,332.73 385.14,327.23 385.28,319.95 C385.42,312.58 379.87,306.45 372.32,305.79 C369.98,305.59 367.61,305.71 365.25,305.71 C359.64,305.7 354.03,305.71 347.09,305.71 C347.09,301.43 347.09,298.42 347.09,295.41 C347.08,254.74 347.2,214.07 347.01,173.41 L131.62,317.03 L53.58,232.81 L87.05,202.02 L138.72,257.62 L343.2,121.26 C324.59,36.81 239.08,-15.98 154.82,5.21 C86.85,22.3 37.92,84.25 38.2,154.69 C38.37,197.11 38.22,239.53 38.21,281.95 C38.21,287.84 38.3,293.74 38.16,299.62" id="Shape"></path>
13
+ <path d="M346.91,155.42 C346.95,161.41 346.97,167.41 347,173.4 L386.14,147.41 L360.9,109.57 L343.2,121.26 C343.39,122.13 343.62,122.98 343.8,123.85 C345.88,134.18 346.84,144.89 346.91,155.42 Z" id="Shape" fill="#00F9AC" fill-rule="nonzero"></path>
14
+ <path d="M87.05,202.03 L53.58,232.82 L131.62,317.04 L347,173.41 C346.97,167.42 346.96,161.42 346.91,155.43 C346.83,144.89 345.88,134.19 343.79,123.87 C343.61,122.99 343.39,122.14 343.19,121.28 L138.72,257.63 L87.05,202.03 Z" id="Shape"></path>
15
+ <path d="M87.05,202.03 L53.58,232.82 L131.62,317.04 L347,173.41 C346.97,167.42 346.96,161.42 346.91,155.43 C346.83,144.89 345.88,134.19 343.79,123.87 C343.61,122.99 343.39,122.14 343.19,121.28 L138.72,257.63 L87.05,202.03 Z" id="Shape" fill="#21D8A3" fill-rule="nonzero" opacity="0.9"></path>
16
+ </g>
17
+ </g>
18
+ </g>
19
+ </svg>
assets/index.html CHANGED
File without changes
assets/js/index.html CHANGED
File without changes
assets/js/vendor/bootstrap/bootstrap.js CHANGED
File without changes
assets/js/vendor/bootstrap/bootstrap.min.js CHANGED
File without changes
assets/js/vendor/bootstrap/index.html CHANGED
File without changes
assets/js/vendor/index.html CHANGED
File without changes
embedpress.php CHANGED
@@ -4,19 +4,19 @@
4
  * Plugin URI: https://embedpress.com/
5
  * Description: WordPress supports around 35 embed sources, but PublishPress Embeds adds over 40 more, including
6
  * Facebook, Google Maps, Google Docs, UStream! Just use the URL!
7
- * Author:EmbedPress
8
- * Author URI:http://embedpress.com
9
- * Version: 2.3.3
10
  * Text Domain: embedpress
11
  * Domain Path: /languages
12
  *
13
- * Copyright (c) 2018 EmbedPress
14
  *
15
  * EmbedPress plugin bootstrap file.
16
  *
17
  * @package EmbedPress
18
  * @author EmbedPress <help@embedpress.com>
19
- * @copyright Copyright (C) 2018 EmbedPress. All rights reserved.
20
  * @license GPLv2 or later
21
  * @since 1.0.0
22
  */
@@ -25,6 +25,9 @@ use EmbedPress\Compatibility;
25
 
26
  defined('ABSPATH') or die("No direct script access allowed.");
27
 
 
 
 
28
  require_once plugin_dir_path(__FILE__) . 'includes.php';
29
 
30
  include_once ABSPATH . 'wp-admin/includes/plugin.php';
@@ -46,12 +49,15 @@ function onPluginDeactivationCallback()
46
  register_activation_hook(__FILE__, 'onPluginActivationCallback');
47
  register_deactivation_hook(__FILE__, 'onPluginDeactivationCallback');
48
 
 
49
  if ( ! is_plugin_active('gutenberg/gutenberg.php')) {
 
 
 
50
  if (Compatibility::isWordPress5() && ! Compatibility::isClassicalEditorActive()) {
51
  $embedPressPlugin = new \EmbedPress\Core();
52
  } else {
53
  $embedPressPlugin = new \EmbedPress\CoreLegacy();
54
  }
55
-
56
  $embedPressPlugin->initialize();
57
- }
4
  * Plugin URI: https://embedpress.com/
5
  * Description: WordPress supports around 35 embed sources, but PublishPress Embeds adds over 40 more, including
6
  * Facebook, Google Maps, Google Docs, UStream! Just use the URL!
7
+ * Author: WPDeveloper
8
+ * Author URI: https://wpdeveloper.net
9
+ * Version: 2.4.0
10
  * Text Domain: embedpress
11
  * Domain Path: /languages
12
  *
13
+ * Copyright (c) 2020 WPDeveloper
14
  *
15
  * EmbedPress plugin bootstrap file.
16
  *
17
  * @package EmbedPress
18
  * @author EmbedPress <help@embedpress.com>
19
+ * @copyright Copyright (C) 2020 WPDeveloper. All rights reserved.
20
  * @license GPLv2 or later
21
  * @since 1.0.0
22
  */
25
 
26
  defined('ABSPATH') or die("No direct script access allowed.");
27
 
28
+ define('EMBEDPRESS_PLUGIN_BASENAME', plugin_basename(__FILE__));
29
+ define('EMBEDPRESS_FILE', __FILE__);
30
+
31
  require_once plugin_dir_path(__FILE__) . 'includes.php';
32
 
33
  include_once ABSPATH . 'wp-admin/includes/plugin.php';
49
  register_activation_hook(__FILE__, 'onPluginActivationCallback');
50
  register_deactivation_hook(__FILE__, 'onPluginDeactivationCallback');
51
 
52
+
53
  if ( ! is_plugin_active('gutenberg/gutenberg.php')) {
54
+ add_action( 'plugins_loaded', function() {
55
+ do_action( 'embedpress_before_init' );
56
+ } );
57
  if (Compatibility::isWordPress5() && ! Compatibility::isClassicalEditorActive()) {
58
  $embedPressPlugin = new \EmbedPress\Core();
59
  } else {
60
  $embedPressPlugin = new \EmbedPress\CoreLegacy();
61
  }
 
62
  $embedPressPlugin->initialize();
63
+ }
includes.php CHANGED
@@ -13,6 +13,7 @@ defined('ABSPATH') or die("No direct script access allowed.");
13
 
14
 
15
  if ( ! defined('EMBEDPRESS')) {
 
16
  define('EMBEDPRESS', "EmbedPress");
17
  }
18
 
@@ -21,13 +22,17 @@ if ( ! defined('EMBEDPRESS_PLG_NAME')) {
21
  }
22
 
23
  if ( ! defined('EMBEDPRESS_VERSION')) {
24
- define('EMBEDPRESS_VERSION', "2.3.3");
25
  /**
26
  * @deprecated 2.2.0
27
  */
28
  define('EMBEDPRESS_PLG_VERSION', EMBEDPRESS_VERSION);
29
  }
30
 
 
 
 
 
31
  if ( ! defined('EMBEDPRESS_ROOT')) {
32
  define('EMBEDPRESS_ROOT', dirname(__FILE__));
33
  }
@@ -71,10 +76,6 @@ if ( ! defined('EMBEDPRESS_LICENSES_MORE_INFO_URL')) {
71
  if (file_exists(__DIR__ . '/vendor/autoload.php')) {
72
  require_once __DIR__ . '/vendor/autoload.php';
73
  }
74
-
75
- // Includes the EDD integration library
76
- require_once __DIR__ . '/vendor/publishpress/wordpress-edd-license-integration/src/includes.php';
77
-
78
  // Run the plugin autoload script
79
  if ( ! defined('EMBEDPRESS_IS_LOADED')) {
80
  require_once EMBEDPRESS_PATH_BASE . "autoloader.php";
13
 
14
 
15
  if ( ! defined('EMBEDPRESS')) {
16
+
17
  define('EMBEDPRESS', "EmbedPress");
18
  }
19
 
22
  }
23
 
24
  if ( ! defined('EMBEDPRESS_VERSION')) {
25
+ define('EMBEDPRESS_VERSION', "2.4.0");
26
  /**
27
  * @deprecated 2.2.0
28
  */
29
  define('EMBEDPRESS_PLG_VERSION', EMBEDPRESS_VERSION);
30
  }
31
 
32
+ if ( ! defined('EMBEDPRESS_PRO_VERSION')) {
33
+ define('EMBEDPRESS_PRO_VERSION', "2.0.0");
34
+ }
35
+
36
  if ( ! defined('EMBEDPRESS_ROOT')) {
37
  define('EMBEDPRESS_ROOT', dirname(__FILE__));
38
  }
76
  if (file_exists(__DIR__ . '/vendor/autoload.php')) {
77
  require_once __DIR__ . '/vendor/autoload.php';
78
  }
 
 
 
 
79
  // Run the plugin autoload script
80
  if ( ! defined('EMBEDPRESS_IS_LOADED')) {
81
  require_once EMBEDPRESS_PATH_BASE . "autoloader.php";
index.html CHANGED
File without changes
readme.txt CHANGED
@@ -1,164 +1,245 @@
 
1
  === EmbedPress – Embed Google Docs, Vimeo and Wistia videos, Giphy and Imgur photos, and more ===
2
- Contributors: EmbedPress, andergmartins, stevejburge, pressshack, deenison
3
- Author: EmbedPress, PressShack
4
- Author URI: https://embedpress.com
5
- Tags: YouTube, Google, Facebook, Wistia, Vimeo
6
  Requires at least: 4.6
7
- Tested up to: 5.2.4
8
- Stable tag: 2.3.3
 
9
  License: GPLv2 or later
10
- License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
12
- EmbedPress provides embeds for major sites, from YouTube and Twitch videos, to Google Maps and Docs, to Soundcloud and Spotify audio files.
13
 
14
  == Description ==
15
 
16
- EmbedPress easily connects WordPress to all the web services you use.
 
 
 
17
 
18
  With EmbedPress, all you need is the URL. Find the URL for your video, image, audio file or map and simply cut-and-paste the URL into a WordPress post. EmbedPress automatically understands the URL and embeds your content. You can embed media from over 75 sites.
19
 
20
- Here are some of the most popular sites you can use with EmbedPress:
 
 
 
 
 
 
 
 
21
 
22
- * **Google**: You can embed Google Maps, Docs, Forms, Sheets and more.
23
- * **Facebook**: You can embed Facebook posts and videos to your site.
24
- * **Videos**: You can quickly embed YouTube, Wistia, Vimeo or Twitch videos.
25
- * **Audio**: You can embed Spotify, Soundcloud and Mixcloud audio.
26
- * **Images**: You can embed Imgur, Giphy and Deviantart images, plus others.
27
 
28
- = YOUTUBE, VIMEO AND WISTIA VIDEOS =
29
 
30
- The add-ons for EmbedPress give you far more control over your videos. With these add-ons, your videos will be responsive. You can also customize the video display to match your site’s design. Other features include auto-play and looping. Click the links below to get a full listing of all the features the add-ons provide:
31
 
32
- * [Click here to get more YouTube features](https://embedpress.com/addons/embedpress-youtube/)
33
- * [Click here to get more Vimeo features](https://embedpress.com/addons/embedpress-vimeo/)
34
- * [Click here to get more Wistia features](https://embedpress.com/addons/embedpress-wistia/)
35
 
36
- = GOOGLE DRIVE: DOCS, SHEETS, DRAWINGS, FORMS, SLIDES, MAPS =
 
 
 
 
 
 
 
37
 
38
  Google Drive is an enormously popular service that has replaced Microsoft Office for many companies. Using Google Drives can bring your information to life, whether it’s stored in documents, maps, drawings, spreadsheets, or presentations. EmbedPress supports all of these Google Drive options:
39
 
40
- * [How to use Google Docs in WordPress](https://embedpress.com/docs/google-docs-embed-wordpress/)
41
- * [How to use Google Forms in WordPress](https://embedpress.com/docs/google-forms-embed-wordpress/)
42
- * [How to use Google Maps in WordPress ](https://embedpress.com/docs/google-maps-embed-wordpress/)
43
- * [How to use Google Drawings in WordPress](https://embedpress.com/docs/google-drawings-embed-wordpress/)
44
- * [How to use Google Sheets in WordPress](https://embedpress.com/docs/embed-google-sheets-wordpress/)
45
- * [How to use Google Slides in WordPress](https://embedpress.com/docs/embed-google-slides-wordpress/)
46
 
47
- = FACEBOOK POSTS AND VIDEOS =
 
 
 
 
 
 
 
48
 
49
  With EmbedPress, you can add Facebook Posts to WordPress, using just a URL. Facebook post embeds are possible, but they’re not easy to use via normal methods. EmbedPress is different:
50
 
51
- * [How to use Facebook embeds in WordPress](https://embedpress.com/docs/embed-facebook-posts-wordpress/)
52
 
53
- = AUDIO: SPOTIFY, SOUNDCLOUD AND MIXCLOUD =
 
54
 
55
  EmbedPress supports all of these major options for audio on your WordPress site:
56
 
57
- * [How to use Spotify in WordPress](https://embedpress.com/docs/embed-spotify-audios-wordpress/)
58
- * [How to use MixCloud in WordPress](https://embedpress.com/docs/embed-mixcloud-audio-wordpress/)
59
- * [How to use SoundCloud in WordPress](https://embedpress.com/docs/embed-soundcloud-audio-wordpress/)
 
 
 
60
 
61
  Here are multiple other audio options supported by EmbedPress:
62
 
63
- * [How to use Shoudio in WordPress](https://embedpress.com/docs/embed-shoudio-audios-wordpress/)
64
- * [How to use HuffDuffer in WordPress](https://embedpress.com/docs/embed-huffduffer-audios-wordpress/)
65
- * [How to use Chirbit in WordPress](https://embedpress.com/docs/embed-chirbit-audio-wordpress/)
66
- * [How to use Clyp in WordPress](https://embedpress.com/docs/embed-clypit-audio-wordpress/)
67
- * [How to use ReverbNation in WordPress](https://embedpress.com/docs/embed-reverbnation-audio-wordpress/)
 
 
 
 
 
68
 
69
- = PHOTOS: DEVIANTART, GIPHY, FLICK, IMGUR AND INSTAGRAM =
70
 
71
  EmbedPress supports most popular image-hosting sites, including Deviantart, Giphy, Imgur, Flick and Instagram:
72
 
73
- * [How to use Deviantart in WordPress](https://embedpress.com/docs/embed-deviantart-image-wordpress/)
74
- * [How to use Giphy in WordPress](https://embedpress.com/docs/embed-giphy-gifs-wordpress/)
75
- * [How to use Flickr in WordPress](https://embedpress.com/docs/embed-flickr-image-wordpress/)
76
- * [How to use Imgur in WordPress](https://embedpress.com/docs/embed-imgur-images-wordpress/)
77
- * [How to use Instagram in WordPress](https://embedpress.com/docs/embed-instagram-wordpress/)
78
 
79
- = CHARTS AND DIAGRAMS =
 
 
 
 
 
 
 
 
 
80
 
81
  With EmbedPress, you have a wide variety of options for adding charts and diagrams to your WordPress site. We already saw that EmbedPress supports Google Drawings, but here are 5 more options for charts:
82
 
83
- * [AmCharts embeds](https://embedpress.com/docs/embed-amcharts-wordpress/)
84
- * [Cacoo embeds](https://embedpress.com/docs/embed-cacoo-charts-wordpress/)
85
- * [ChartBlocks embeds](https://embedpress.com/docs/embed-chartblocks-charts-wordpress/)
86
- * [CircuitLab embeds](https://embedpress.com/docs/embed-circuitlab-circuit-wordpress/)
87
- * [Infogram embeds](https://embedpress.com/docs/embed-infogram-charts-wordpress/)
88
 
89
- = OTHER VIDEO OPTIONS =
 
 
 
 
 
90
 
91
  We’ve seen that EmbedPress supports YouTube, Wistia and Vimeo, but EmbedPress also supports around 20 more video sources:
92
 
93
- * [Animoto embeds](https://embedpress.com/docs/embed-animoto-videos-wordpress/)
94
- * [Bambuser embeds](https://embedpress.com/docs/embed-bambuser-videos-wordpress/)
95
- * [College Humor embeds](https://embedpress.com/docs/embed-collegehumor-videos-wordpress/)
96
- * [Coub embeds](https://embedpress.com/docs/embed-coub-videos-iwordpress/)
97
- * [Crowd Ranking embeds](https://embedpress.com/docs/embed-crowdranking-polls-wordpress/)
98
- * [Cloudup embeds](https://embedpress.com/docs/embed-cloudup-videos-images-or-audios-wordpress/)
99
- * [Daily Motion embeds](https://embedpress.com/docs/embed-dailymotion-videos-wordpress/)
100
- * [Dotsub embeds](https://embedpress.com/docs/embed-dotsub-videos-wordpress/)
101
- * [Funny or Die embeds](https://embedpress.com/docs/embed-funnyordie-videos-wordpress/)
102
- * [Hulu embeds](https://embedpress.com/docs/embed-hulu-videos-wordpress/)
103
- * [Kickstarter embeds](https://embedpress.com/docs/embed-kickstarter-videos-wordpress/)
104
- * [NFB embeds](https://embedpress.com/docs/embed-nfb-videos-wordpress/)
105
- * [RuTube embeds](https://embedpress.com/docs/embed-rutube-videos-wordpress/)
106
- * [Sapo Videos embeds](https://embedpress.com/docs/embed-sapo-videos-wordpress/)
107
- * [TED embeds](https://embedpress.com/docs/embed-ted-videos-wordpress/)
108
- * [Ustream embeds](https://embedpress.com/docs/embed-ustream-videos-wordpress/)
109
- * [Viddler embeds](https://embedpress.com/docs/embed-viddler-videos-wordpress/)
110
- * [VideoJug embeds](https://embedpress.com/docs/embed-videojug-videos-wordpress/)
111
- * [VideoPress embeds](https://embedpress.com/docs/embed-videopress-videos-wordpress/)
112
-
113
- = OTHER SITES SUPPORTED BY EMBEDPRESS =
114
-
115
- * [23hq embeds](https://embedpress.com/docs/embed-23hq-photos-wordpress/) (Images)
116
- * [Daily Mile embeds](https://embedpress.com/docs/embed-dailymile-activity-wordpress/) (Activity)
117
- * [GettyImages embeds](https://embedpress.com/docs/embed-getty-images-wordpress/) (Images)
118
- * [Github Gist embeds](https://embedpress.com/docs/embed-github-gist-snippets-wordpress/) (Code)
119
- * [Issuu embeds](https://embedpress.com/docs/embed-issuu-documents-wordpress/) (Documents)
120
- * [Meetup embeds](https://embedpress.com/docs/embed-meetup-groups-events-wordpress/) (Groups, Events)
121
- * [MobyPicture embeds](https://embedpress.com/docs/embed-mobypicture-photos-wordpress/) (Image)
122
- * [PhotoBucket embeds](https://embedpress.com/docs/embed-photobucket-images-wordpress/) (Images)
123
- * [PollDaddy embeds](https://embedpress.com/docs/polldaddy-embed-wordpress/) (Polls, Surveys, Quizzes)
124
- * [Porfolium embeds](https://embedpress.com/docs/embed-portfolium-projects-wordpress/) (Projects)
125
- * [Reddit embeds](https://embedpress.com/docs/embed-reddit-post-wordpress/) (Posts, Comments)
126
- * [ReleaseWire embeds](https://embedpress.com/docs/embed-releasewire-press-releases-wordpress/) (Press releases)
127
- * [Scribd embeds](https://embedpress.com/docs/embed-scribd-document-wordpress/) (Documents)
128
- * [ShortNote embeds](https://embedpress.com/docs/embed-shortnote-notes-wordpress/) (Notes in Japanese)
129
- * [Sketchfab embeds](https://embedpress.com/docs/embed-sketchfab-drawings-wordpress/) (Drawings)
130
- * [SlideShare embeds](https://embedpress.com/docs/embed-slideshare-presentations-wordpress/) (Presentations)
131
- * [SmugMug embeds](https://embedpress.com/docs/embed-smugmug-images-wordpress/) (Images)
132
- * [SpeakerDeck embeds](https://embedpress.com/docs/embed-speakerdeck-presentations-wordpress/) (Presentations)
133
-
134
- = ALSO CHECK OUT THE PUBLISHPRESS PLUGIN =
135
-
136
- If you like EmbedPress, then consider checking out [PublishPress](https://embedpress.com/publishpress/). The PublishPress plugin is essential for any WordPress site with multiple writers.
137
-
138
- PublishPress is a plugin with several tools that help your team stay organized:
139
-
140
- * Use the [Editorial Calendar](https://embedpress.com/publishpress/docs/calendar/) and [Content Overview](https://embedpress.com/publishpress/docs/calendar/) to get a clear picture of all your planned and published content.
141
- * You can create [Comments](https://embedpress.com/publishpress/docs/editorial-comments/) and [Notifications](https://embedpress.com/publishpress/docs/notifications/) to leave feedback and keep your team in the loop.
142
- * You can add [Metadata](https://embedpress.com/publishpress/docs/editorial-metadata/) to give your team extra information about each post.
143
- * Create [Custom Statuses](https://embedpress.com/publishpress/docs/custom-statuses/) so that WordPress matches your team’s workflow.
144
-
145
- = WORDPRESS TRAINING =
146
-
147
- Visit [OSTraining](https://www.ostraining.com/) to learn from our [WordPress Training](https://www.ostraining.com/wordpress-training/) and to read our [best WordPress blog posts](https://www.ostraining.com/blog/wordpress). If you’re interested in a specific WordPress topic, try specific topic areas such as these:
148
-
149
- * [WordPress Development Classes - learn to build plugins](https://www.ostraining.com/classes/wordpress-development)
150
- * [WordPress Theme Design Classes - create your first theme](https://www.ostraining.com/classes/wordpress-themes)
151
- * [WordPress eCommerce Classes - set up a WordPress store](https://www.ostraining.com/classes/wordpress-ecommerce)
152
-
153
- == Installation ==
154
-
155
- You can install EmbedPress through your WordPress admin area:
156
-
157
- Access the “Plugins” page.
158
- Click on the “Add New” button.
159
- Search for “EmbedPress”.
160
- Install the EmbedPress plugin.
161
- Activate the EmbedPress plugin.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
  == Frequently Asked Questions ==
164
 
@@ -183,8 +264,22 @@ Not at all. You can set up everything your team needs without any coding knowled
183
 
184
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
185
  and this project adheres to [Semantic Versioning](http://semver.org/).
186
- = [2.3.3] - 2019-11-11 =
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  Minor Fix for EmbedPress version in includes.php file
 
188
  = [2.3.2] - 2019-11-11 =
189
  Refactoring Gutenberg Blocks
190
 
@@ -477,3 +572,7 @@ Added Wistia and Twitch blocks for Gutenberg
477
  = [1.0.0] - 2016-07-27 =
478
 
479
  * Initial release.
 
 
 
 
1
+
2
  === EmbedPress – Embed Google Docs, Vimeo and Wistia videos, Giphy and Imgur photos, and more ===
3
+ Contributors: EmbedPress, asif2bd, re_enter_rupok, wpdevteam, manzurahammed, andergmartins, stevejburge, pressshack, deenison
4
+ Author: WPDeveloper
5
+ Author URI: https://wpdeveloper.net
6
+ Tags: embed, code, video embed, Youtube embed, map embed, content embed, iframes
7
  Requires at least: 4.6
8
+ Tested up to: 5.3
9
+ Requires PHP: 5.6
10
+ Stable tag: 2.4.0
11
  License: GPLv2 or later
12
+ License URI: https://opensource.org/licenses/GPL-3.0
13
 
14
+ EmbedPress lets you embed videos, images, posts, audio, maps and all other types of content into your WordPress site with one-click and showcase it beautifully for the visitors.
15
 
16
  == Description ==
17
 
18
+
19
+ EmbedPress lets you embed videos, images, posts, audio, maps and all other types of content into your WordPress site with one-click and showcase it beautifully for the visitors.
20
+
21
+ 🔥RICH MEDIA EMBEDS FROM MORE THAN 75 SITES
22
 
23
  With EmbedPress, all you need is the URL. Find the URL for your video, image, audio file or map and simply cut-and-paste the URL into a WordPress post. EmbedPress automatically understands the URL and embeds your content. You can embed media from over 75 sites.
24
 
25
+ 🌟Most Popular Sites People Are Embedding with EmbedPress:
26
+
27
+ - Google: You can embed Google Maps, Docs, Forms, Sheets and more.
28
+
29
+ - Facebook: You can embed Facebook posts and videos to your site.
30
+
31
+ - Videos: You can quickly embed YouTube, Wistia, Vimeo or Twitch videos.
32
+
33
+ - Audio: You can embed Spotify, Soundcloud and Mixcloud audio.
34
 
35
+ - Images: You can embed Imgur, Giphy and Deviantart images, plus others.
 
 
 
 
36
 
 
37
 
38
+ #### 🎥YOUTUBE, VIMEO AND WISTIA VIDEOS
39
 
40
+ The add-ons for EmbedPress give you far more control over your videos. With these add-ons, your videos will be responsive. You can also customize the video display to match your site’s design. Other features include auto-play and looping. Click the links below to get a full listing of all the features the add-ons provide:
 
 
41
 
42
+ - [Click here to get more YouTube features](https://embedpress.com/addons/embedpress-youtube/)
43
+
44
+ - [Click here to get more Vimeo features](https://embedpress.com/addons/embedpress-vimeo/)
45
+
46
+ - [Click here to get more Wistia features](https://embedpress.com/addons/embedpress-wistia/)
47
+
48
+
49
+ #### ☁️GOOGLE DRIVE: DOCS, SHEETS, DRAWINGS, FORMS, SLIDES, MAPS
50
 
51
  Google Drive is an enormously popular service that has replaced Microsoft Office for many companies. Using Google Drives can bring your information to life, whether it’s stored in documents, maps, drawings, spreadsheets, or presentations. EmbedPress supports all of these Google Drive options:
52
 
53
+ - [How to use Google Docs in WordPress](https://embedpress.com/docs/google-docs-embed-wordpress/)
54
+
55
+ - [How to use Google Forms in WordPress](https://embedpress.com/docs/google-forms-embed-wordpress/)
56
+
57
+ - [How to use Google Maps in WordPress](https://embedpress.com/docs/google-maps-embed-wordpress/)
 
58
 
59
+ - [How to use Google Drawings in WordPress](https://embedpress.com/docs/google-drawings-embed-wordpress/)
60
+
61
+ - [How to use Google Sheets in WordPress](https://embedpress.com/docs/embed-google-sheets-wordpress/)
62
+
63
+ - [How to use Google Slides in WordPress](https://embedpress.com/docs/embed-google-slides-wordpress/)
64
+
65
+
66
+ #### 👍FACEBOOK POSTS AND VIDEOS
67
 
68
  With EmbedPress, you can add Facebook Posts to WordPress, using just a URL. Facebook post embeds are possible, but they’re not easy to use via normal methods. EmbedPress is different:
69
 
70
+ - [How to use Facebook embeds in WordPress](https://embedpress.com/docs/embed-facebook-posts-wordpress/)
71
 
72
+
73
+ #### 🎧AUDIO: SPOTIFY, SOUNDCLOUD AND MIXCLOUD
74
 
75
  EmbedPress supports all of these major options for audio on your WordPress site:
76
 
77
+ - [How to use Spotify in WordPress](https://embedpress.com/docs/embed-spotify-audios-wordpress/)
78
+
79
+ - [How to use MixCloud in WordPress](https://embedpress.com/docs/embed-mixcloud-audio-wordpress/)
80
+
81
+ - [How to use SoundCloud in WordPress](https://embedpress.com/docs/embed-soundcloud-audio-wordpress/)
82
+
83
 
84
  Here are multiple other audio options supported by EmbedPress:
85
 
86
+ - [How to use Shoudio in WordPress](https://embedpress.com/docs/embed-shoudio-audios-wordpress/)
87
+
88
+ - [How to use HuffDuffer in WordPress](https://embedpress.com/docs/embed-huffduffer-audios-wordpress/)
89
+
90
+ - [How to use Chirbit in WordPress](https://embedpress.com/docs/embed-chirbit-audio-wordpress/)
91
+
92
+ - [How to use Clyp in WordPress](https://embedpress.com/docs/embed-clypit-audio-wordpress/)
93
+
94
+ - [How to use ReverbNation in WordPress](https://embedpress.com/docs/embed-reverbnation-audio-wordpress/)
95
+
96
 
97
+ #### 🖼️PHOTOS: DEVIANTART, GIPHY, FLICK, IMGUR AND INSTAGRAM
98
 
99
  EmbedPress supports most popular image-hosting sites, including Deviantart, Giphy, Imgur, Flick and Instagram:
100
 
101
+ - [How to use Deviantart in WordPress](https://embedpress.com/docs/embed-deviantart-image-wordpress/)
 
 
 
 
102
 
103
+ - [How to use Giphy in WordPress](https://embedpress.com/docs/embed-giphy-gifs-wordpress/)
104
+
105
+ - [How to use Flickr in WordPress](https://embedpress.com/docs/embed-flickr-image-wordpress/)
106
+
107
+ - [How to use Imgur in WordPress](https://embedpress.com/docs/embed-imgur-images-wordpress/)
108
+
109
+ - [How to use Instagram in WordPress](https://embedpress.com/docs/embed-instagram-wordpress/)
110
+
111
+
112
+ #### 📊CHARTS AND DIAGRAMS
113
 
114
  With EmbedPress, you have a wide variety of options for adding charts and diagrams to your WordPress site. We already saw that EmbedPress supports Google Drawings, but here are 5 more options for charts:
115
 
116
+ - [AmCharts embeds](https://embedpress.com/docs/embed-amcharts-wordpress/)
117
+
118
+ - [Cacoo embeds](https://embedpress.com/docs/embed-cacoo-charts-wordpress/)
119
+
120
+ - [ChartBlocks embeds](https://embedpress.com/docs/embed-chartblocks-charts-wordpress/)
121
 
122
+ - [CircuitLab embeds](https://embedpress.com/docs/embed-circuitlab-circuit-wordpress/)
123
+
124
+ - [Infogram embeds](https://embedpress.com/docs/embed-infogram-charts-wordpress/)
125
+
126
+
127
+ #### 🎬OTHER VIDEO OPTIONS
128
 
129
  We’ve seen that EmbedPress supports YouTube, Wistia and Vimeo, but EmbedPress also supports around 20 more video sources:
130
 
131
+ - [Animoto embeds](https://embedpress.com/docs/embed-animoto-videos-wordpress/)
132
+
133
+ - [Bambuser embeds](https://embedpress.com/docs/embed-bambuser-videos-wordpress/)
134
+
135
+ - [College Humor embeds](https://embedpress.com/docs/embed-collegehumor-videos-wordpress/)
136
+
137
+ - [Coub embeds](https://embedpress.com/docs/embed-coub-videos-iwordpress/)
138
+
139
+ - [Crowd Ranking embeds](https://embedpress.com/docs/embed-crowdranking-polls-wordpress/)
140
+
141
+ - [Cloudup embeds](https://embedpress.com/docs/embed-cloudup-videos-images-or-audios-wordpress/)
142
+
143
+ - [Daily Motion embeds](https://embedpress.com/docs/embed-dailymotion-videos-wordpress/)
144
+
145
+ - [Dotsub embeds](https://embedpress.com/docs/embed-dotsub-videos-wordpress/)
146
+
147
+ - [Funny or Die embeds](https://embedpress.com/docs/embed-funnyordie-videos-wordpress/)
148
+
149
+ - [Hulu embeds](https://embedpress.com/docs/embed-hulu-videos-wordpress/)
150
+
151
+ - [Kickstarter embeds](https://embedpress.com/docs/embed-kickstarter-videos-wordpress/)
152
+
153
+ - [NFB embeds](https://embedpress.com/docs/embed-nfb-videos-wordpress/)
154
+
155
+ - [RuTube embeds](https://embedpress.com/docs/embed-rutube-videos-wordpress/)
156
+
157
+ - [Sapo Videos embeds](https://embedpress.com/docs/embed-sapo-videos-wordpress/)
158
+
159
+ - [TED embeds](https://embedpress.com/docs/embed-ted-videos-wordpress/)
160
+
161
+ - [Ustream embeds](https://embedpress.com/docs/embed-ustream-videos-wordpress/)
162
+
163
+ - [Viddler embeds](https://embedpress.com/docs/embed-viddler-videos-wordpress/)
164
+
165
+ - [VideoJug embeds](https://embedpress.com/docs/embed-videojug-videos-wordpress/)
166
+
167
+ - [VideoPress embeds](https://embedpress.com/docs/embed-videopress-videos-wordpress/)
168
+
169
+
170
+ #### ✅MORE SITES SUPPORTED BY EMBEDPRESS
171
+
172
+ - [23hq embeds](https://embedpress.com/docs/embed-23hq-photos-wordpress/) (Images)
173
+
174
+ - [Daily Mile embeds](https://embedpress.com/docs/embed-dailymile-activity-wordpress/) (Activity)
175
+
176
+ - [GettyImages embeds](https://embedpress.com/docs/embed-getty-images-wordpress/) (Images)
177
+
178
+ - [Github Gist embeds](https://embedpress.com/docs/embed-github-gist-snippets-wordpress/) (Code)
179
+
180
+ - [Issuu embeds](https://embedpress.com/docs/embed-issuu-documents-wordpress/) (Documents)
181
+
182
+ - [Meetup embeds](https://embedpress.com/docs/embed-meetup-groups-events-wordpress/) (Groups, Events)
183
+
184
+ - [MobyPicture embeds](https://embedpress.com/docs/embed-mobypicture-photos-wordpress/) (Image)
185
+
186
+ - [PhotoBucket embeds](https://embedpress.com/docs/embed-photobucket-images-wordpress/) (Images)
187
+
188
+ - [PollDaddy embeds](https://embedpress.com/docs/polldaddy-embed-wordpress/) (Polls, Surveys, Quizzes)
189
+
190
+ - [Porfolium embeds](https://embedpress.com/docs/embed-portfolium-projects-wordpress/) (Projects)
191
+
192
+ - [Reddit embeds](https://embedpress.com/docs/embed-reddit-post-wordpress/) (Posts, Comments)
193
+
194
+ - [ReleaseWire embeds](https://embedpress.com/docs/embed-releasewire-press-releases-wordpress/) (Press releases)
195
+
196
+ - [Scribd embeds](https://embedpress.com/docs/embed-scribd-document-wordpress/) (Documents)
197
+
198
+ - [ShortNote embeds](https://embedpress.com/docs/embed-shortnote-notes-wordpress/) (Notes in Japanese)
199
+
200
+ - [Sketchfab embeds](https://embedpress.com/docs/embed-sketchfab-drawings-wordpress/) (Drawings)
201
+
202
+ - [SlideShare embeds](https://embedpress.com/docs/embed-slideshare-presentations-wordpress/) (Presentations)
203
+
204
+ - [SmugMug embeds](https://embedpress.com/docs/embed-smugmug-images-wordpress/) (Images)
205
+
206
+ - [SpeakerDeck embeds](https://embedpress.com/docs/embed-speakerdeck-presentations-wordpress/) (Presentations)
207
+
208
+
209
+ 🙌After reading this feature list, you can probably imagine EmbedPress is the best plugin in the market. So, do you want to unlock the advanced features? [Upgrade to our Pro version.](https://embedpress.com/everything-club/)
210
+
211
+ ## 🚀BACKED BY A TRUSTED TEAM
212
+
213
+ This embed plugin is brought to you by the team behind [WPDeveloper](https://wpdeveloper.net/), a dedicated marketplace for WordPress, trusted by 500,000+ happy users.
214
+
215
+ ### 👨‍💻 DOCUMENTATION AND SUPPORT
216
+
217
+ - For documentation and tutorials go to our [Documentation](https://embedpress.com/documentation/)
218
+
219
+ - If you have any more questions, visit our support on the [Plugin’s Forum](https://wordpress.org/support/plugin/embedpress/)
220
+
221
+ - For more information about features, FAQs and documentation, check out our website at [EmbedPress](https://embedpress.com/)
222
+
223
+
224
+ ### 💙 LOVED EmbedPress?
225
+
226
+ - Join our [Facebook Group](https://www.facebook.com/groups/wpdeveloper.net/)
227
+
228
+ - If you love EmbedPress, [rate us on WordPress](https://wordpress.org/support/plugin/embedpress/reviews/#new-post)
229
+
230
+
231
+
232
+ 🔥 WHAT’S NEXT
233
+ If you like EmbedPress, then consider checking out our other WordPress Plugins:
234
+
235
+ 🔝[Essential Addons For Elementor](https://wordpress.org/plugins/essential-addons-for-elementor-lite/) – Most popular Elementor extensions with 400,000+ active users in the WordPress repository.
236
+
237
+ 🔔[NotificationX](https://notificationx.com/) – Best Social Proof & FOMO Marketing Solution to increase conversion rates,
238
+
239
+ ⏰[WP Scheduled Posts](https://wordpress.org/plugins/wp-scheduled-posts/) – Complete solution for WordPress Post Scheduling to manage schedules through an editorial calendar.
240
+
241
+
242
+ Visit [WPDeveloper](https://wpdeveloper.net/) to learn more about how to do better in WordPress with [Help Tutorial, Tips & Tricks](https://wpdeveloper.net/blog).
243
 
244
  == Frequently Asked Questions ==
245
 
264
 
265
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
266
  and this project adheres to [Semantic Versioning](http://semver.org/).
267
+
268
+
269
+ = [2.4.0] - 2020-03-02 =
270
+ * Gutenberg Compatibility improvement
271
+ * wp ombed class update
272
+ * Global iFrame resize capacity
273
+ * Removal of all pro licensing class from free
274
+ * Minor typo fix
275
+ * License update to GPL 3.0
276
+ * V2.3.3 and prior had slug issue with pro addons' slug issue, its fixed from 2.4.0
277
+ * Code is now maintained by WPDeveloper.
278
+
279
+
280
+ = [2.3.3] - 2019-11-11 =
281
  Minor Fix for EmbedPress version in includes.php file
282
+
283
  = [2.3.2] - 2019-11-11 =
284
  Refactoring Gutenberg Blocks
285
 
572
  = [1.0.0] - 2016-07-27 =
573
 
574
  * Initial release.
575
+
576
+ == Upgrade Notice ==
577
+
578
+ * Must Update. Compatibility release.