Happy Addons for Elementor (Mega Menu, Post Grid, Woocommerce Product Grid, Table, Event Calendar, Slider Elementor Widget) - Version 2.5.0

Version Description

  • 24 December 2019 =

  • New: Added Step Flow widget title heading level control

  • Update: Tracking system update to comply with wp.org user privacy policy

  • Fix: Dark mode Happy Effects heading color

Download this release

Release Info

Developer thehappymonster
Plugin Icon 128x128 Happy Addons for Elementor (Mega Menu, Post Grid, Woocommerce Product Grid, Table, Event Calendar, Slider Elementor Widget)
Version 2.5.0
Comparing to
See all releases

Code changes from version 2.4.2 to 2.5.0

assets/admin/css/editor.css CHANGED
@@ -47,7 +47,7 @@
47
 
48
  .elementor-panel .elementor-control-_section_happy_effects .elementor-panel-heading-toggle,
49
  .elementor-panel .elementor-control-_section_happy_effects .elementor-panel-heading-title {
50
- color: #562dd4;
51
  }
52
 
53
  .elementor-control-ha_floating_fx_translate_toggle + .elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-lower:after,
47
 
48
  .elementor-panel .elementor-control-_section_happy_effects .elementor-panel-heading-toggle,
49
  .elementor-panel .elementor-control-_section_happy_effects .elementor-panel-heading-title {
50
+ color: #e2498a;
51
  }
52
 
53
  .elementor-control-ha_floating_fx_translate_toggle + .elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-lower:after,
assets/admin/css/editor.min.css CHANGED
@@ -1 +1 @@
1
- .elementor-panel #elementor-panel-category-happy_addons_category .elementor-element:focus .icon,.elementor-panel #elementor-panel-category-happy_addons_category .elementor-element:focus .title,.elementor-panel #elementor-panel-category-happy_addons_category .elementor-element:hover .icon,.elementor-panel #elementor-panel-category-happy_addons_category .elementor-element:hover .title,.elementor-panel #elementor-panel-category-happy_addons_pro_category .elementor-element:focus .icon,.elementor-panel #elementor-panel-category-happy_addons_pro_category .elementor-element:focus .title,.elementor-panel #elementor-panel-category-happy_addons_pro_category .elementor-element:hover .icon,.elementor-panel #elementor-panel-category-happy_addons_pro_category .elementor-element:hover .title,.elementor-panel #elementor-panel-category-happy_addons_pro_category .is-ha-widget:focus .icon,.elementor-panel #elementor-panel-category-happy_addons_pro_category .is-ha-widget:focus .title,.elementor-panel #elementor-panel-category-happy_addons_pro_category .is-ha-widget:hover .icon,.elementor-panel #elementor-panel-category-happy_addons_pro_category .is-ha-widget:hover .title{background-image:-webkit-linear-gradient(315deg,#e2498a 25%,#562dd4 100%);background-image:linear-gradient(135deg,#e2498a 25%,#562dd4 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.elementor-panel .elementor-element .icon{position:relative;-webkit-transition:all .2s;transition:all .2s}.elementor-panel .elementor-element .icon .hm:after{position:absolute;top:5px;right:5px;content:"\ead0";font-size:15px;opacity:.3}.elementor-panel .elementor-element:focus .icon .hm:after,.elementor-panel .elementor-element:hover .icon .hm:after{opacity:1;background-image:-webkit-linear-gradient(315deg,#e2498a 25%,#562dd4 100%);background-image:linear-gradient(135deg,#e2498a 25%,#562dd4 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.elementor-panel .elementor-control-_section_happy_effects .elementor-panel-heading-title,.elementor-panel .elementor-control-_section_happy_effects .elementor-panel-heading-toggle{color:#562dd4}.elementor-control-ha_floating_fx_rotate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-lower:after,.elementor-control-ha_floating_fx_scale_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-lower:after,.elementor-control-ha_floating_fx_translate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-lower:after{left:-5px;box-shadow:-2px 2px 3px 0 rgba(0,0,0,.1)}.elementor-control-ha_floating_fx_rotate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper:after,.elementor-control-ha_floating_fx_scale_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper:after,.elementor-control-ha_floating_fx_translate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper:after{left:5px;box-shadow:2px -2px 3px 0 rgba(0,0,0,.1)}.elementor-control-ha_floating_fx_rotate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper .noUi-tooltip,.elementor-control-ha_floating_fx_scale_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper .noUi-tooltip,.elementor-control-ha_floating_fx_translate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper .noUi-tooltip{top:auto;bottom:calc(100% + 5px);left:100%}
1
+ .elementor-panel #elementor-panel-category-happy_addons_category .elementor-element:focus .icon,.elementor-panel #elementor-panel-category-happy_addons_category .elementor-element:focus .title,.elementor-panel #elementor-panel-category-happy_addons_category .elementor-element:hover .icon,.elementor-panel #elementor-panel-category-happy_addons_category .elementor-element:hover .title,.elementor-panel #elementor-panel-category-happy_addons_pro_category .elementor-element:focus .icon,.elementor-panel #elementor-panel-category-happy_addons_pro_category .elementor-element:focus .title,.elementor-panel #elementor-panel-category-happy_addons_pro_category .elementor-element:hover .icon,.elementor-panel #elementor-panel-category-happy_addons_pro_category .elementor-element:hover .title,.elementor-panel #elementor-panel-category-happy_addons_pro_category .is-ha-widget:focus .icon,.elementor-panel #elementor-panel-category-happy_addons_pro_category .is-ha-widget:focus .title,.elementor-panel #elementor-panel-category-happy_addons_pro_category .is-ha-widget:hover .icon,.elementor-panel #elementor-panel-category-happy_addons_pro_category .is-ha-widget:hover .title{background-image:-webkit-linear-gradient(315deg,#e2498a 25%,#562dd4 100%);background-image:linear-gradient(135deg,#e2498a 25%,#562dd4 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.elementor-panel .elementor-element .icon{position:relative;-webkit-transition:all .2s;transition:all .2s}.elementor-panel .elementor-element .icon .hm:after{position:absolute;top:5px;right:5px;content:"\ead0";font-size:15px;opacity:.3}.elementor-panel .elementor-element:focus .icon .hm:after,.elementor-panel .elementor-element:hover .icon .hm:after{opacity:1;background-image:-webkit-linear-gradient(315deg,#e2498a 25%,#562dd4 100%);background-image:linear-gradient(135deg,#e2498a 25%,#562dd4 100%);-webkit-background-clip:text;-webkit-text-fill-color:transparent}.elementor-panel .elementor-control-_section_happy_effects .elementor-panel-heading-title,.elementor-panel .elementor-control-_section_happy_effects .elementor-panel-heading-toggle{color:#e2498a}.elementor-control-ha_floating_fx_rotate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-lower:after,.elementor-control-ha_floating_fx_scale_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-lower:after,.elementor-control-ha_floating_fx_translate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-lower:after{left:-5px;box-shadow:-2px 2px 3px 0 rgba(0,0,0,.1)}.elementor-control-ha_floating_fx_rotate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper:after,.elementor-control-ha_floating_fx_scale_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper:after,.elementor-control-ha_floating_fx_translate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper:after{left:5px;box-shadow:2px -2px 3px 0 rgba(0,0,0,.1)}.elementor-control-ha_floating_fx_rotate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper .noUi-tooltip,.elementor-control-ha_floating_fx_scale_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper .noUi-tooltip,.elementor-control-ha_floating_fx_translate_toggle+.elementor-controls-popover .elementor-control-type-slider--handles-range .elementor-slider .noUi-handle-upper .noUi-tooltip{top:auto;bottom:calc(100% + 5px);left:100%}
changelog.txt CHANGED
@@ -1,3 +1,9 @@
 
 
 
 
 
 
1
  = 2.4.2 - 12 December 2019 =
2
 
3
  - Fix: Compatibility with Elementor 2.8.*
1
+ = 2.5.0 - 24 December 2019 =
2
+
3
+ - New: Added Step Flow widget title heading level control
4
+ - Update: Tracking system update to comply with wp.org user privacy policy
5
+ - Fix: Dark mode Happy Effects heading color
6
+
7
  = 2.4.2 - 12 December 2019 =
8
 
9
  - Fix: Compatibility with Elementor 2.8.*
plugin.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Happy Elementor Addons
4
  * Plugin URI: https://happyaddons.com/
5
  * Description: <a href="https://happyaddons.com/">HappyAddons</a> is a collection of slick, powerful widgets that works seamlessly with Elementor page builder. It’s trendy look with detail customization features allows to create extraordinary designs instantly. <a href="https://happyaddons.com/">HappyAddons</a> is free, rapidly growing and comes with great support.
6
- * Version: 2.4.2
7
  * Author: weDevs
8
  * Author URI: https://happyaddons.com/
9
  * License: GPLv2
@@ -34,7 +34,7 @@ Copyright 2019 HappyMonster <http://happymonster.me>
34
 
35
  defined( 'ABSPATH' ) || die();
36
 
37
- define( 'HAPPY_ADDONS_VERSION', '2.4.2' );
38
  define( 'HAPPY_ADDONS__FILE__', __FILE__ );
39
  define( 'HAPPY_ADDONS_DIR_PATH', plugin_dir_path( HAPPY_ADDONS__FILE__ ) );
40
  define( 'HAPPY_ADDONS_DIR_URL', plugin_dir_url( HAPPY_ADDONS__FILE__ ) );
3
  * Plugin Name: Happy Elementor Addons
4
  * Plugin URI: https://happyaddons.com/
5
  * Description: <a href="https://happyaddons.com/">HappyAddons</a> is a collection of slick, powerful widgets that works seamlessly with Elementor page builder. It’s trendy look with detail customization features allows to create extraordinary designs instantly. <a href="https://happyaddons.com/">HappyAddons</a> is free, rapidly growing and comes with great support.
6
+ * Version: 2.5.0
7
  * Author: weDevs
8
  * Author URI: https://happyaddons.com/
9
  * License: GPLv2
34
 
35
  defined( 'ABSPATH' ) || die();
36
 
37
+ define( 'HAPPY_ADDONS_VERSION', '2.5.0' );
38
  define( 'HAPPY_ADDONS__FILE__', __FILE__ );
39
  define( 'HAPPY_ADDONS_DIR_PATH', plugin_dir_path( HAPPY_ADDONS__FILE__ ) );
40
  define( 'HAPPY_ADDONS_DIR_URL', plugin_dir_url( HAPPY_ADDONS__FILE__ ) );
readme.txt CHANGED
@@ -1,12 +1,12 @@
1
  === Happy Elementor Addons ===
2
  Plugin Name: Happy Elementor Addons
3
- Version: 2.4.2
4
  Author: weDevs
5
  Author URI: https://happyaddons.com/
6
  Contributors: thehappymonster, happyaddons, hasinhayder, mosaddek73, tareq1988, sourav926, wedevs, iqbalrony, obiplabon
7
  Tags: elementor, elementor addon, elementor widget, essential widget, elements
8
  Requires at least: 4.7
9
- Tested up to: 5.2.4
10
  Stable tag: trunk
11
  Requires PHP: 5.4
12
  License: GPLv2
@@ -201,6 +201,16 @@ Please give us feedback, contribute and file technical bugs on [GitHub Repo](htt
201
  In case you want to share any ideas on Happy Addons with other users or if you are in any trouble, don’t feel stranded. Stay connected with [the Happy addons community](https://www.facebook.com/groups/HappyAddonsCommunity/).
202
 
203
 
 
 
 
 
 
 
 
 
 
 
204
  == Frequently Asked Questions ==
205
 
206
  = Can I use Happy Elementor Addons without Elementor? =
@@ -258,6 +268,12 @@ It's really easy and super simple to install **Happy Elementor Addons** plugin b
258
 
259
  == Changelog ==
260
 
 
 
 
 
 
 
261
  = 2.4.2 - 12 December 2019 =
262
 
263
  - Fix: Compatibility with Elementor 2.8.*
1
  === Happy Elementor Addons ===
2
  Plugin Name: Happy Elementor Addons
3
+ Version: 2.5.0
4
  Author: weDevs
5
  Author URI: https://happyaddons.com/
6
  Contributors: thehappymonster, happyaddons, hasinhayder, mosaddek73, tareq1988, sourav926, wedevs, iqbalrony, obiplabon
7
  Tags: elementor, elementor addon, elementor widget, essential widget, elements
8
  Requires at least: 4.7
9
+ Tested up to: 5.3.2
10
  Stable tag: trunk
11
  Requires PHP: 5.4
12
  License: GPLv2
201
  In case you want to share any ideas on Happy Addons with other users or if you are in any trouble, don’t feel stranded. Stay connected with [the Happy addons community](https://www.facebook.com/groups/HappyAddonsCommunity/).
202
 
203
 
204
+ ## Privacy Policy
205
+ **Happy Elementor Addons** uses [Appsero](https://appsero.com) SDK to collect some telemetry data upon user's confirmation. This helps us to troubleshoot problems faster & make product improvements.
206
+
207
+ Appsero SDK **does not gather any data by default.** The SDK only starts gathering basic telemetry data **when a user allows it via the admin notice**. We collect the data to ensure great user experience for all our users.
208
+
209
+ Integrating Appsero SDK **DOES NOT IMMEDIATELY** start gathering data, **without confirmation from users in any case.**
210
+
211
+ Learn more how [Appsero collects and uses this data](https://appsero.com/privacy-policy/). Additionally, read weDevs [privacy policy](https://wedevs.com/privacy-policy/) for more.
212
+
213
+
214
  == Frequently Asked Questions ==
215
 
216
  = Can I use Happy Elementor Addons without Elementor? =
268
 
269
  == Changelog ==
270
 
271
+ = 2.5.0 - 24 December 2019 =
272
+
273
+ - New: Added Step Flow widget title heading level control
274
+ - Update: Tracking system update to comply with wp.org user privacy policy
275
+ - Fix: Dark mode Happy Effects heading color
276
+
277
  = 2.4.2 - 12 December 2019 =
278
 
279
  - Fix: Compatibility with Elementor 2.8.*
templates/admin/dashboard-home.php CHANGED
@@ -93,7 +93,7 @@ defined( 'ABSPATH' ) || die();
93
  <p class="f16">Are you interested to contribute to making this plugin more awesome?</p>
94
  <a class="link btn-how-to-contribute" href="#">How am I going to contribute?</a>
95
  <p class="ha-mb-0" style="display: none;">By allow Happy Elementor Addons to collect non-sensitive diagnostic data and usage information so that we can make sure optimum compatibility.
96
- Happy Elementor Addons collect - Server environment details (php, mysql, server, WordPress versions), Number of users in your site, Site language, Number of active and inactive plugins, Site name and url, Your name and email address</p>
97
  </div>
98
  <div class="ha-cta-action ha-col-4 ha-align-right">
99
  <a class="btn-contribute" href="<?php echo esc_url( $optin_url ); ?>">I like to contribute</a>
93
  <p class="f16">Are you interested to contribute to making this plugin more awesome?</p>
94
  <a class="link btn-how-to-contribute" href="#">How am I going to contribute?</a>
95
  <p class="ha-mb-0" style="display: none;">By allow Happy Elementor Addons to collect non-sensitive diagnostic data and usage information so that we can make sure optimum compatibility.
96
+ Happy Elementor Addons collect - Server environment details (php, mysql, server, WordPress versions), Number of users in your site, Site language, Number of active and inactive plugins, Site name and url, Your name and email address. We are using Appsero to collect your data. <a href="https://appsero.com/privacy-policy/" target="_blank" style="color:#fff">Learn more</a> about how Appsero collects and handle your data.</p>
97
  </div>
98
  <div class="ha-cta-action ha-col-4 ha-align-right">
99
  <a class="btn-contribute" href="<?php echo esc_url( $optin_url ); ?>">I like to contribute</a>
vendor/appsero/src/Client.php CHANGED
@@ -13,7 +13,7 @@ class Client {
13
  *
14
  * @var string
15
  */
16
- public $version = '1.1.2';
17
 
18
  /**
19
  * Hash identifier of the plugin
@@ -67,7 +67,14 @@ class Client {
67
  */
68
  public $type;
69
 
70
- /**
 
 
 
 
 
 
 
71
  * Initialize the class
72
  *
73
  * @param string $hash hash of the plugin
@@ -85,7 +92,7 @@ class Client {
85
  /**
86
  * Initialize insights class
87
  *
88
- * @return Appsero\Insights
89
  */
90
  public function insights() {
91
 
@@ -99,7 +106,7 @@ class Client {
99
  /**
100
  * Initialize plugin/theme updater
101
  *
102
- * @return Appsero\Updater
103
  */
104
  public function updater() {
105
 
@@ -113,7 +120,7 @@ class Client {
113
  /**
114
  * Initialize license checker
115
  *
116
- * @return Appsero\License
117
  */
118
  public function license() {
119
 
@@ -154,6 +161,7 @@ class Client {
154
 
155
  $this->project_version = $plugin_data['Version'];
156
  $this->type = 'plugin';
 
157
 
158
  } else {
159
 
13
  *
14
  * @var string
15
  */
16
+ public $version = '1.1.9';
17
 
18
  /**
19
  * Hash identifier of the plugin
67
  */
68
  public $type;
69
 
70
+ /**
71
+ * textdomain
72
+ *
73
+ * @var string
74
+ */
75
+ public $textdomain;
76
+
77
+ /**
78
  * Initialize the class
79
  *
80
  * @param string $hash hash of the plugin
92
  /**
93
  * Initialize insights class
94
  *
95
+ * @return Happy_Addons\Appsero\Insights
96
  */
97
  public function insights() {
98
 
106
  /**
107
  * Initialize plugin/theme updater
108
  *
109
+ * @return Happy_Addons\Appsero\Updater
110
  */
111
  public function updater() {
112
 
120
  /**
121
  * Initialize license checker
122
  *
123
+ * @return Happy_Addons\Appsero\License
124
  */
125
  public function license() {
126
 
161
 
162
  $this->project_version = $plugin_data['Version'];
163
  $this->type = 'plugin';
164
+ $this->textdomain = $this->slug;
165
 
166
  } else {
167
 
vendor/appsero/src/Insights.php CHANGED
@@ -41,7 +41,7 @@ class Insights {
41
  /**
42
  * Initialize the class
43
  *
44
- * @param AppSero\Client
45
  */
46
  public function __construct( $client, $name = null, $file = null ) {
47
 
@@ -152,7 +152,7 @@ class Insights {
152
  add_action( 'wp_ajax_' . $this->client->slug . '_submit-uninstall-reason', array( $this, 'uninstall_reason_submission' ) );
153
 
154
  // cron events
155
- add_action( 'cron_schedules', array( $this, 'add_weekly_schedule' ) );
156
  add_action( $this->client->slug . '_tracker_send_event', array( $this, 'send_tracking_data' ) );
157
  // add_action( 'admin_init', array( $this, 'send_tracking_data' ) ); // test
158
  }
@@ -297,7 +297,7 @@ class Insights {
297
  * @return boolean
298
  */
299
  public function notice_dismissed() {
300
- $hide_notice = get_option( $this->client->slug . '_tracking_notice', 'no' );
301
 
302
  if ( 'hide' == $hide_notice ) {
303
  return true;
@@ -325,8 +325,11 @@ class Insights {
325
  * @return void
326
  */
327
  private function schedule_event() {
328
- wp_schedule_event( time(), 'weekly', $this->client->slug . '_tracker_send_event' );
329
- wp_schedule_event( time(), 'daily', $this->client->slug . '_license_check_event' );
 
 
 
330
  }
331
 
332
  /**
@@ -336,7 +339,6 @@ class Insights {
336
  */
337
  private function clear_schedule_event() {
338
  wp_clear_scheduled_hook( $this->client->slug . '_tracker_send_event' );
339
- wp_clear_scheduled_hook( $this->client->slug . '_license_check_event' );
340
  }
341
 
342
  /**
@@ -364,28 +366,26 @@ class Insights {
364
  $optout_url = add_query_arg( $this->client->slug . '_tracker_optout', 'true' );
365
 
366
  if ( empty( $this->notice ) ) {
367
- $notice = sprintf( __( 'Want to help make <strong>%1$s</strong> even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.', 'textdomain' ), $this->client->name );
368
  } else {
369
  $notice = $this->notice;
370
  }
371
 
372
- $notice .= ' (<a class="' . $this->client->slug . '-insights-data-we-collect" href="#">' . __( 'what we collect', 'textdomain' ) . '</a>)';
373
- $notice .= '<p class="description" style="display:none;">' . implode( ', ', $this->data_we_collect() ) . '. No sensitive data is tracked.</p>';
 
374
 
375
  echo '<div class="updated"><p>';
376
- echo $notice;
377
- echo '</p><p class="submit">';
378
- echo '&nbsp;<a href="' . esc_url( $optin_url ) . '" class="button-primary button-large">' . __( 'Allow', 'textdomain' ) . '</a>';
379
- echo '&nbsp;<a href="' . esc_url( $optout_url ) . '" class="button-secondary button-large">' . __( 'No thanks', 'textdomain' ) . '</a>';
380
  echo '</p></div>';
381
 
382
  echo "<script type='text/javascript'>jQuery('." . $this->client->slug . "-insights-data-we-collect').on('click', function(e) {
383
  e.preventDefault();
384
  jQuery(this).parents('.updated').find('p.description').slideToggle('fast');
385
  });
386
- jQuery.getJSON('https://api.ipify.org?format=jsonp&callback=?', function(json) {
387
- json.ip;
388
- } );
389
  </script>
390
  ";
391
  }
@@ -575,7 +575,7 @@ class Insights {
575
 
576
  $schedules['weekly'] = array(
577
  'interval' => DAY_IN_SECONDS * 7,
578
- 'display' => __( 'Once Weekly', 'textdomain' )
579
  );
580
 
581
  return $schedules;
@@ -595,7 +595,11 @@ class Insights {
595
  }
596
 
597
  // re-schedule and delete the last sent time so we could force send again
598
- wp_schedule_event( time(), 'weekly', $this->client->slug . '_tracker_send_event' );
 
 
 
 
599
  delete_option( $this->client->slug . '_tracking_last_send' );
600
 
601
  $this->send_tracking_data( true );
@@ -740,7 +744,7 @@ class Insights {
740
  <div class="wd-dr-modal" id="<?php echo $this->client->slug; ?>-wd-dr-modal">
741
  <div class="wd-dr-modal-wrap">
742
  <div class="wd-dr-modal-header">
743
- <h3><?php _e( 'If you have a moment, please let us know why you are deactivating:', 'domain' ); ?></h3>
744
  </div>
745
 
746
  <div class="wd-dr-modal-body">
@@ -751,12 +755,13 @@ class Insights {
751
  </li>
752
  <?php } ?>
753
  </ul>
 
754
  </div>
755
 
756
  <div class="wd-dr-modal-footer">
757
- <a href="#" class="dont-bother-me"><?php _e( 'I rather wouldn\'t say', 'domain' ); ?></a>
758
- <button class="button-secondary"><?php _e( 'Submit & Deactivate', 'domain' ); ?></button>
759
- <button class="button-primary"><?php _e( 'Cancel', 'domain' ); ?></button>
760
  </div>
761
  </div>
762
  </div>
@@ -807,6 +812,9 @@ class Insights {
807
  padding: 12px 20px;
808
  text-align: right;
809
  }
 
 
 
810
  </style>
811
 
812
  <script type="text/javascript">
41
  /**
42
  * Initialize the class
43
  *
44
+ * @param Happy_Addons\Appsero\Client
45
  */
46
  public function __construct( $client, $name = null, $file = null ) {
47
 
152
  add_action( 'wp_ajax_' . $this->client->slug . '_submit-uninstall-reason', array( $this, 'uninstall_reason_submission' ) );
153
 
154
  // cron events
155
+ add_filter( 'cron_schedules', array( $this, 'add_weekly_schedule' ) );
156
  add_action( $this->client->slug . '_tracker_send_event', array( $this, 'send_tracking_data' ) );
157
  // add_action( 'admin_init', array( $this, 'send_tracking_data' ) ); // test
158
  }
297
  * @return boolean
298
  */
299
  public function notice_dismissed() {
300
+ $hide_notice = get_option( $this->client->slug . '_tracking_notice', null );
301
 
302
  if ( 'hide' == $hide_notice ) {
303
  return true;
325
  * @return void
326
  */
327
  private function schedule_event() {
328
+ $hook_name = $this->client->slug . '_tracker_send_event';
329
+
330
+ if ( ! wp_next_scheduled( $hook_name ) ) {
331
+ wp_schedule_event( time(), 'weekly', $hook_name );
332
+ }
333
  }
334
 
335
  /**
339
  */
340
  private function clear_schedule_event() {
341
  wp_clear_scheduled_hook( $this->client->slug . '_tracker_send_event' );
 
342
  }
343
 
344
  /**
366
  $optout_url = add_query_arg( $this->client->slug . '_tracker_optout', 'true' );
367
 
368
  if ( empty( $this->notice ) ) {
369
+ $notice = sprintf( __( 'Want to help make <strong>%1$s</strong> even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.', $this->client->textdomain ), $this->client->name );
370
  } else {
371
  $notice = $this->notice;
372
  }
373
 
374
+ $notice .= ' (<a class="' . $this->client->slug . '-insights-data-we-collect" href="#">' . __( 'what we collect', $this->client->textdomain ) . '</a>)';
375
+ $notice .= '<p class="description" style="display:none;">' . implode( ', ', $this->data_we_collect() ) . '. No sensitive data is tracked. ';
376
+ $notice .= 'We are using Appsero to collect your data. <a href="https://appsero.com/privacy-policy/">Learn more</a> about how Appsero collects and handle your data.</p>';
377
 
378
  echo '<div class="updated"><p>';
379
+ echo $notice;
380
+ echo '</p><p class="submit">';
381
+ echo '&nbsp;<a href="' . esc_url( $optin_url ) . '" class="button-primary button-large">' . __( 'Allow', $this->client->textdomain ) . '</a>';
382
+ echo '&nbsp;<a href="' . esc_url( $optout_url ) . '" class="button-secondary button-large">' . __( 'No thanks', $this->client->textdomain ) . '</a>';
383
  echo '</p></div>';
384
 
385
  echo "<script type='text/javascript'>jQuery('." . $this->client->slug . "-insights-data-we-collect').on('click', function(e) {
386
  e.preventDefault();
387
  jQuery(this).parents('.updated').find('p.description').slideToggle('fast');
388
  });
 
 
 
389
  </script>
390
  ";
391
  }
575
 
576
  $schedules['weekly'] = array(
577
  'interval' => DAY_IN_SECONDS * 7,
578
+ 'display' => 'Once Weekly',
579
  );
580
 
581
  return $schedules;
595
  }
596
 
597
  // re-schedule and delete the last sent time so we could force send again
598
+ $hook_name = $this->client->slug . '_tracker_send_event';
599
+ if ( ! wp_next_scheduled( $hook_name ) ) {
600
+ wp_schedule_event( time(), 'weekly', $hook_name );
601
+ }
602
+
603
  delete_option( $this->client->slug . '_tracking_last_send' );
604
 
605
  $this->send_tracking_data( true );
744
  <div class="wd-dr-modal" id="<?php echo $this->client->slug; ?>-wd-dr-modal">
745
  <div class="wd-dr-modal-wrap">
746
  <div class="wd-dr-modal-header">
747
+ <h3><?php _e( 'If you have a moment, please let us know why you are deactivating:', $this->client->textdomain ); ?></h3>
748
  </div>
749
 
750
  <div class="wd-dr-modal-body">
755
  </li>
756
  <?php } ?>
757
  </ul>
758
+ <p class="wd-dr-modal-reasons-bottom">We share your data with <a href="https://appsero.com/">Appsero</a> to troubleshoot problems &amp; make product improvements. <a href="https://appsero.com/privacy-policy/">Learn more</a> about how Appsero handles your data.</p>
759
  </div>
760
 
761
  <div class="wd-dr-modal-footer">
762
+ <a href="#" class="dont-bother-me"><?php _e( 'I rather wouldn\'t say', $this->client->textdomain ); ?></a>
763
+ <button class="button-secondary"><?php _e( 'Submit & Deactivate', $this->client->textdomain ); ?></button>
764
+ <button class="button-primary"><?php _e( 'Cancel', $this->client->textdomain ); ?></button>
765
  </div>
766
  </div>
767
  </div>
812
  padding: 12px 20px;
813
  text-align: right;
814
  }
815
+ .wd-dr-modal-reasons-bottom {
816
+ margin: 15px 0 0 0;
817
+ }
818
  </style>
819
 
820
  <script type="text/javascript">
vendor/appsero/src/License.php CHANGED
@@ -34,14 +34,21 @@ class License {
34
  *
35
  * @var string
36
  */
37
- protected $error;
38
 
39
  /**
40
  * Success message on form submit
41
  *
42
  * @var string
43
  */
44
- protected $success;
 
 
 
 
 
 
 
45
 
46
  /**
47
  * Set value for valid licnese
@@ -53,12 +60,20 @@ class License {
53
  /**
54
  * Initialize the class
55
  *
56
- * @param Appsero\Client
57
  */
58
  public function __construct( Client $client ) {
59
  $this->client = $client;
60
 
61
  $this->option_key = 'appsero_' . md5( $this->client->slug ) . '_manage_license';
 
 
 
 
 
 
 
 
62
  }
63
 
64
  /**
@@ -149,7 +164,7 @@ class License {
149
  'page_title' => 'Manage License',
150
  'menu_title' => 'Manage License',
151
  'capability' => 'manage_options',
152
- 'menu_slug' => 'manage-license',
153
  'icon_url' => '',
154
  'position' => null,
155
  'parent_slug' => '',
@@ -157,9 +172,7 @@ class License {
157
 
158
  $this->menu_args = wp_parse_args( $args, $defaults );
159
 
160
- add_action( 'admin_menu', array( $this, 'admin_menu' ), 30 );
161
-
162
- add_action( $this->client->slug . '_license_check_event', array( $this, 'check_license_status' ) );
163
  }
164
 
165
  /**
@@ -168,147 +181,103 @@ class License {
168
  * @return void
169
  */
170
  public function admin_menu() {
171
- $add_page = 'add_' . $this->menu_args['type'] . '_page';
172
-
173
  switch ( $this->menu_args['type'] ) {
174
  case 'menu':
175
- $add_page(
176
- $this->menu_args['page_title'],
177
- $this->menu_args['menu_title'],
178
- $this->menu_args['capability'],
179
- $this->menu_args['menu_slug'],
180
- array( $this, 'menu_output' ),
181
- $this->menu_args['icon_url'],
182
- $this->menu_args['position']
183
- );
184
  break;
185
 
186
  case 'submenu':
187
- $add_page(
188
- $this->menu_args['parent_slug'],
189
- $this->menu_args['page_title'],
190
- $this->menu_args['menu_title'],
191
- $this->menu_args['capability'],
192
- $this->menu_args['menu_slug'],
193
- array( $this, 'menu_output' )
194
- );
195
  break;
196
 
197
  case 'options':
198
- $add_page(
199
- $this->menu_args['page_title'],
200
- $this->menu_args['menu_title'],
201
- $this->menu_args['capability'],
202
- $this->menu_args['menu_slug'],
203
- array( $this, 'menu_output' )
204
- );
205
  break;
206
  }
207
  }
208
 
209
- protected function make_license_key_unreadable( $key ) {
210
- $len = strlen( $key );
211
- return str_pad( substr( $key, 0, $len / 2 ), $len, '*' );
212
- }
213
-
214
  /**
215
  * License menu output
216
  */
217
  public function menu_output() {
218
 
219
  if ( isset( $_POST['submit'] ) ) {
220
- $this->license_page_form( $_POST );
221
  }
222
 
223
  $license = get_option( $this->option_key, null );
224
- $action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'Deactive' : 'Active';
 
225
  ?>
226
 
227
- <div class="wrap">
228
- <h1><?php echo $this->menu_args['menu_title']; ?></h1>
229
-
230
- <?php if ( ! empty( $this->error ) ) : ?>
231
- <div class="notice notice-error is-dismissible" style="max-width: 745px;">
232
- <p><?php echo $this->error; ?></p>
233
- </div>
234
- <?php endif; ?>
235
 
236
- <?php if ( ! empty( $this->success ) ) : ?>
237
- <div class="notice notice-success is-dismissible" style="max-width: 745px;">
238
- <p><?php echo $this->success; ?></p>
239
- </div>
240
- <?php endif; ?>
241
 
242
- <br />
 
243
 
244
- <div class="widget open" style="max-width: 800px; margin: 0;">
245
- <div class="widget-top">
246
- <div class="widget-title"><h3>License Settings</h3></div>
247
- </div>
248
-
249
- <div class="widget-inside" style="display: block; padding: 5px 15px;">
250
- <form method="post" action="<?php echo esc_url( admin_url( 'admin.php?page=' . $this->menu_args['menu_slug'] ) ); ?>" novalidate="novalidate">
251
- <table class="form-table">
252
- <tbody>
253
- <tr>
254
- <th scope="row">
255
- <label>License key</label>
256
- </th>
257
- <td>
258
- <input type="text" class="regular-text code" value="<?php echo $this->make_license_key_unreadable( $license['key'] ); ?>"
259
- placeholder="Enter your license key" name="license_key"
260
- <?php echo ( 'Deactive' == $action ) ? 'readonly="readonly"' : ''; ?> />
261
- </td>
262
- </tr>
263
- </tbody>
264
- </table>
265
  <input type="hidden" name="_action" value="<?php echo $action; ?>">
266
- <p>
267
- <button type="submit" name="submit" class="button button-primary"><?php echo $action; ?></button>
268
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
269
  </form>
 
 
 
 
 
 
270
  </div>
271
- </div> <!-- /.widget -->
272
- </div>
273
 
 
 
274
  <?php
275
  }
276
 
277
  /**
278
  * License form submit
279
  */
280
- private function license_page_form( $form ) {
281
- if ( $form['_action'] == 'Active' ) {
282
- $response = $this->activate( $form['license_key'] );
283
-
284
- if ( ! empty( $response['success'] ) ) {
285
- $data = array(
286
- 'key' => $form['license_key'],
287
- 'status' => 'activate',
288
- );
289
- update_option( $this->option_key, $data, false );
290
- $this->success = 'License activated successfully.';
291
- }
292
- } else if ( $form['_action'] == 'Deactive' ) {
293
- $response = $this->deactivate( $form['license_key'] );
294
-
295
- if ( ! empty( $response['success'] ) ) {
296
- $this->success = 'License deactivated successfully.';
297
- }
298
-
299
- $data = array(
300
- 'key' => '',
301
- 'status' => 'deactivate',
302
- );
303
-
304
- update_option( $this->option_key, $data, false );
305
  }
306
 
307
- if ( isset( $response['error'] ) && ! empty( $response['error'] ) ) {
308
- $this->error = $response['error'];
 
309
  }
310
 
311
- // var_export( $response );
 
 
 
 
 
 
 
 
312
  }
313
 
314
  /**
@@ -321,9 +290,16 @@ class License {
321
  $response = $this->check( $license['key'] );
322
 
323
  if ( isset( $response['success'] ) && $response['success'] ) {
324
- $license['status'] = 'activate';
 
 
 
 
 
 
325
  } else {
326
- $license['status'] = 'deactivate';
 
327
  }
328
 
329
  update_option( $this->option_key, $license, false );
@@ -342,10 +318,384 @@ class License {
342
  if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
343
  $this->is_valid_licnese = true;
344
  } else {
345
- $this->is_valid_licnese = false;
346
  }
347
 
348
  return $this->is_valid_licnese;
349
  }
350
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  }
34
  *
35
  * @var string
36
  */
37
+ public $error;
38
 
39
  /**
40
  * Success message on form submit
41
  *
42
  * @var string
43
  */
44
+ public $success;
45
+
46
+ /**
47
+ * Corn schedule hook name
48
+ *
49
+ * @var string
50
+ */
51
+ protected $schedule_hook;
52
 
53
  /**
54
  * Set value for valid licnese
60
  /**
61
  * Initialize the class
62
  *
63
+ * @param Happy_Addons\Appsero\Client
64
  */
65
  public function __construct( Client $client ) {
66
  $this->client = $client;
67
 
68
  $this->option_key = 'appsero_' . md5( $this->client->slug ) . '_manage_license';
69
+
70
+ $this->schedule_hook = $this->client->slug . '_license_check_event';
71
+
72
+ // Run hook to check license status daily
73
+ add_action( $this->schedule_hook, array( $this, 'check_license_status' ) );
74
+
75
+ // Active/Deactive corn schedule
76
+ $this->run_schedule();
77
  }
78
 
79
  /**
164
  'page_title' => 'Manage License',
165
  'menu_title' => 'Manage License',
166
  'capability' => 'manage_options',
167
+ 'menu_slug' => $this->client->slug . '-manage-license',
168
  'icon_url' => '',
169
  'position' => null,
170
  'parent_slug' => '',
172
 
173
  $this->menu_args = wp_parse_args( $args, $defaults );
174
 
175
+ add_action( 'admin_menu', array( $this, 'admin_menu' ), 99 );
 
 
176
  }
177
 
178
  /**
181
  * @return void
182
  */
183
  public function admin_menu() {
 
 
184
  switch ( $this->menu_args['type'] ) {
185
  case 'menu':
186
+ $this->add_menu_page();
 
 
 
 
 
 
 
 
187
  break;
188
 
189
  case 'submenu':
190
+ $this->add_submenu_page();
 
 
 
 
 
 
 
191
  break;
192
 
193
  case 'options':
194
+ $this->add_options_page();
 
 
 
 
 
 
195
  break;
196
  }
197
  }
198
 
 
 
 
 
 
199
  /**
200
  * License menu output
201
  */
202
  public function menu_output() {
203
 
204
  if ( isset( $_POST['submit'] ) ) {
205
+ $this->license_form_submit( $_POST );
206
  }
207
 
208
  $license = get_option( $this->option_key, null );
209
+ $action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'deactive' : 'active';
210
+ $this->licenses_style();
211
  ?>
212
 
213
+ <div class="wrap appsero-license-settings-wrapper">
214
+ <h1>License Settings</h1>
 
 
 
 
 
 
215
 
216
+ <?php
217
+ $this->show_license_page_notices();
218
+ do_action( 'before_appsero_license_section' );
219
+ ?>
 
220
 
221
+ <div class="appsero-license-settings appsero-license-section">
222
+ <?php $this->show_license_page_card_header(); ?>
223
 
224
+ <div class="appsero-license-details">
225
+ <p>Active <strong><?php echo $this->client->name; ?></strong> by your license key to get professional support and automatic update from your WordPress dashboard.</p>
226
+ <form method="post" action="<?php $this->formActionUrl(); ?>" novalidate="novalidate" spellcheck="false">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
  <input type="hidden" name="_action" value="<?php echo $action; ?>">
228
+ <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( $this->client->name ); ?>">
229
+ <div class="license-input-fields">
230
+ <div class="license-input-key">
231
+ <svg enable-background="new 0 0 512 512" version="1.1" viewBox="0 0 512 512" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
232
+ <path d="m463.75 48.251c-64.336-64.336-169.01-64.335-233.35 1e-3 -43.945 43.945-59.209 108.71-40.181 167.46l-185.82 185.82c-2.813 2.813-4.395 6.621-4.395 10.606v84.858c0 8.291 6.709 15 15 15h84.858c3.984 0 7.793-1.582 10.605-4.395l21.211-21.226c3.237-3.237 4.819-7.778 4.292-12.334l-2.637-22.793 31.582-2.974c7.178-0.674 12.847-6.343 13.521-13.521l2.974-31.582 22.793 2.651c4.233 0.571 8.496-0.85 11.704-3.691 3.193-2.856 5.024-6.929 5.024-11.206v-27.929h27.422c3.984 0 7.793-1.582 10.605-4.395l38.467-37.958c58.74 19.043 122.38 4.929 166.33-39.046 64.336-64.335 64.336-169.01 0-233.35zm-42.435 106.07c-17.549 17.549-46.084 17.549-63.633 0s-17.549-46.084 0-63.633 46.084-17.549 63.633 0 17.548 46.084 0 63.633z"/>
233
+ </svg>
234
+ <input type="text" value="<?php echo $this->get_input_license_value( $action, $license ); ?>"
235
+ placeholder="Enter your license key to activate" name="license_key"
236
+ <?php echo ( 'deactive' == $action ) ? 'readonly="readonly"' : ''; ?>
237
+ />
238
+ </div>
239
+ <button type="submit" name="submit" class="<?php echo 'deactive' == $action ? 'deactive-button' : ''; ?>">
240
+ <?php echo $action == 'active' ? 'Activate License' : 'Deactivate License' ; ?>
241
+ </button>
242
+ </div>
243
  </form>
244
+
245
+ <?php
246
+ if ( 'deactive' == $action && isset( $license['remaining'] ) ) {
247
+ $this->show_active_license_info( $license );
248
+ }
249
+ ?>
250
  </div>
251
+ </div> <!-- /.appsero-license-settings -->
 
252
 
253
+ <?php do_action( 'after_appsero_license_section' ); ?>
254
+ </div>
255
  <?php
256
  }
257
 
258
  /**
259
  * License form submit
260
  */
261
+ public function license_form_submit( $form ) {
262
+ if ( ! isset( $form['_nonce'], $form['_action'] ) ) {
263
+ $this->error = "Please add all information";
264
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  }
266
 
267
+ if ( ! wp_verify_nonce( $form['_nonce'], $this->client->name ) ) {
268
+ $this->error = "You don't have permission to manage license.";
269
+ return;
270
  }
271
 
272
+ switch ( $form['_action'] ) {
273
+ case 'active':
274
+ $this->active_client_license( $form );
275
+ break;
276
+
277
+ case 'deactive':
278
+ $this->deactive_client_license( $form );
279
+ break;
280
+ }
281
  }
282
 
283
  /**
290
  $response = $this->check( $license['key'] );
291
 
292
  if ( isset( $response['success'] ) && $response['success'] ) {
293
+ $license['status'] = 'activate';
294
+ $license['remaining'] = $response['remaining'];
295
+ $license['activation_limit'] = $response['activation_limit'];
296
+ $license['expiry_days'] = $response['expiry_days'];
297
+ $license['title'] = $response['title'];
298
+ $license['source_id'] = $response['source_identifier'];
299
+ $license['recurring'] = $response['recurring'];
300
  } else {
301
+ $license['status'] = 'deactivate';
302
+ $license['expiry_days'] = 0;
303
  }
304
 
305
  update_option( $this->option_key, $license, false );
318
  if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
319
  $this->is_valid_licnese = true;
320
  } else {
321
+ $this->is_valid_licnese = false;
322
  }
323
 
324
  return $this->is_valid_licnese;
325
  }
326
 
327
+ /**
328
+ * Check this is a valid license
329
+ */
330
+ public function is_valid_by( $option, $value ) {
331
+ $license = get_option( $this->option_key, null );
332
+
333
+ if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
334
+ if ( isset( $license[ $option ] ) && $license[ $option ] == $value ) {
335
+ return true;
336
+ }
337
+ }
338
+
339
+ return false;
340
+ }
341
+
342
+ /**
343
+ * Styles for licenses page
344
+ */
345
+ private function licenses_style() {
346
+ ?>
347
+ <style type="text/css">
348
+ .appsero-license-section {
349
+ width: 100%;
350
+ max-width: 1100px;
351
+ min-height: 1px;
352
+ box-sizing: border-box;
353
+ }
354
+ .appsero-license-settings {
355
+ background-color: #fff;
356
+ box-shadow: 0px 3px 10px rgba(16, 16, 16, 0.05);
357
+ }
358
+ .appsero-license-settings * {
359
+ box-sizing: border-box;
360
+ }
361
+ .appsero-license-title {
362
+ background-color: #F8FAFB;
363
+ border-bottom: 2px solid #EAEAEA;
364
+ display: flex;
365
+ align-items: center;
366
+ padding: 10px 20px;
367
+ }
368
+ .appsero-license-title svg {
369
+ width: 30px;
370
+ height: 30px;
371
+ fill: #0082BF;
372
+ }
373
+ .appsero-license-title span {
374
+ font-size: 17px;
375
+ color: #444444;
376
+ margin-left: 10px;
377
+ }
378
+ .appsero-license-details {
379
+ padding: 20px;
380
+ }
381
+ .appsero-license-details p {
382
+ font-size: 15px;
383
+ margin: 0 0 20px 0;
384
+ }
385
+ .license-input-key {
386
+ position: relative;
387
+ flex: 0 0 72%;
388
+ max-width: 72%;
389
+ }
390
+ .license-input-key input {
391
+ background-color: #F9F9F9;
392
+ padding: 10px 15px 10px 48px;
393
+ border: 1px solid #E8E5E5;
394
+ border-radius: 3px;
395
+ height: 45px;
396
+ font-size: 16px;
397
+ color: #71777D;
398
+ width: 100%;
399
+ box-shadow: 0 0 0 transparent;
400
+ }
401
+ .license-input-key input:focus {
402
+ outline: 0 none;
403
+ border: 1px solid #E8E5E5;
404
+ box-shadow: 0 0 0 transparent;
405
+ }
406
+ .license-input-key svg {
407
+ width: 22px;
408
+ height: 22px;
409
+ fill: #0082BF;
410
+ position: absolute;
411
+ left: 14px;
412
+ top: 13px;
413
+ }
414
+ .license-input-fields {
415
+ display: flex;
416
+ justify-content: space-between;
417
+ margin-bottom: 30px;
418
+ max-width: 850px;
419
+ width: 100%;
420
+ }
421
+ .license-input-fields button {
422
+ color: #fff;
423
+ font-size: 17px;
424
+ padding: 8px;
425
+ height: 46px;
426
+ background-color: #0082BF;
427
+ border-radius: 3px;
428
+ cursor: pointer;
429
+ flex: 0 0 25%;
430
+ max-width: 25%;
431
+ border: 1px solid #0082BF;
432
+ }
433
+ .license-input-fields button.deactive-button {
434
+ background-color: #E40055;
435
+ border-color: #E40055;
436
+ }
437
+ .license-input-fields button:focus {
438
+ outline: 0 none;
439
+ }
440
+ .active-license-info {
441
+ display: flex;
442
+ }
443
+ .single-license-info {
444
+ min-width: 220px;
445
+ flex: 0 0 30%;
446
+ }
447
+ .single-license-info h3 {
448
+ font-size: 18px;
449
+ margin: 0 0 12px 0;
450
+ }
451
+ .single-license-info p {
452
+ margin: 0;
453
+ color: #00C000;
454
+ }
455
+ .single-license-info p.occupied {
456
+ color: #E40055;
457
+ }
458
+ </style>
459
+ <?php
460
+ }
461
+
462
+ /**
463
+ * Show active license information
464
+ */
465
+ private function show_active_license_info( $license ) {
466
+ ?>
467
+ <div class="active-license-info">
468
+ <div class="single-license-info">
469
+ <h3>Activation Remaining</h3>
470
+ <?php if ( empty( $license['activation_limit'] ) ): ?>
471
+ <p>Unlimited</p>
472
+ <?php else: ?>
473
+ <p class="<?php echo $license['remaining'] ? '' : 'occupied'; ?>">
474
+ <?php echo $license['remaining']; ?> out of <?php echo $license['activation_limit']; ?>
475
+ </p>
476
+ <?php endif; ?>
477
+ </div>
478
+ <div class="single-license-info">
479
+ <h3>Expires in</h3>
480
+ <?php
481
+ if ( $license['recurring'] && false !== $license['expiry_days'] ) {
482
+ $occupied = $license['expiry_days'] > 10 ? '' : 'occupied';
483
+ echo '<p class="' . $occupied . '">' . $license['expiry_days'] . ' days</p>';
484
+ } else {
485
+ echo '<p>Never</p>';
486
+ }
487
+ ?>
488
+ </div>
489
+ </div>
490
+ <?php
491
+ }
492
+
493
+ /**
494
+ * Show license settings page notices
495
+ */
496
+ private function show_license_page_notices() {
497
+ if ( ! empty( $this->error ) ) :
498
+ ?>
499
+ <div class="notice notice-error is-dismissible appsero-license-section">
500
+ <p><?php echo $this->error; ?></p>
501
+ </div>
502
+ <?php
503
+ endif;
504
+ if ( ! empty( $this->success ) ) :
505
+ ?>
506
+ <div class="notice notice-success is-dismissible appsero-license-section">
507
+ <p><?php echo $this->success; ?></p>
508
+ </div>
509
+ <?php
510
+ endif;
511
+ echo '<br />';
512
+ }
513
+
514
+ /**
515
+ * Card header
516
+ */
517
+ private function show_license_page_card_header() {
518
+ ?>
519
+ <div class="appsero-license-title">
520
+ <svg enable-background="new 0 0 299.995 299.995" version="1.1" viewBox="0 0 300 300" xml:space="preserve" xmlns="http://www.w3.org/2000/svg">
521
+ <path d="m150 161.48c-8.613 0-15.598 6.982-15.598 15.598 0 5.776 3.149 10.807 7.817 13.505v17.341h15.562v-17.341c4.668-2.697 7.817-7.729 7.817-13.505 0-8.616-6.984-15.598-15.598-15.598z"/>
522
+ <path d="m150 85.849c-13.111 0-23.775 10.665-23.775 23.775v25.319h47.548v-25.319c-1e-3 -13.108-10.665-23.775-23.773-23.775z"/>
523
+ <path d="m150 1e-3c-82.839 0-150 67.158-150 150 0 82.837 67.156 150 150 150s150-67.161 150-150c0-82.839-67.161-150-150-150zm46.09 227.12h-92.173c-9.734 0-17.626-7.892-17.626-17.629v-56.919c0-8.491 6.007-15.582 14.003-17.25v-25.697c0-27.409 22.3-49.711 49.711-49.711 27.409 0 49.709 22.3 49.709 49.711v25.697c7.993 1.673 14 8.759 14 17.25v56.919h2e-3c0 9.736-7.892 17.629-17.626 17.629z"/>
524
+ </svg>
525
+ <span>Activate License</span>
526
+ </div>
527
+ <?php
528
+ }
529
+
530
+ /**
531
+ * Active client license
532
+ */
533
+ private function active_client_license( $form ) {
534
+ if ( empty( $form['license_key'] ) ) {
535
+ $this->error = 'The license key field is required.';
536
+ return;
537
+ }
538
+
539
+ $license_key = sanitize_text_field( $form['license_key'] );
540
+ $response = $this->activate( $license_key );
541
+
542
+ if ( ! $response['success'] ) {
543
+ $this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
544
+ return;
545
+ }
546
+
547
+ $data = array(
548
+ 'key' => $license_key,
549
+ 'status' => 'activate',
550
+ 'remaining' => $response['remaining'],
551
+ 'activation_limit' => $response['activation_limit'],
552
+ 'expiry_days' => $response['expiry_days'],
553
+ 'title' => $response['title'],
554
+ 'source_id' => $response['source_identifier'],
555
+ 'recurring' => $response['recurring'],
556
+ );
557
+
558
+ update_option( $this->option_key, $data, false );
559
+
560
+ $this->success = 'License activated successfully.';
561
+ }
562
+
563
+ /**
564
+ * Deactive client license
565
+ */
566
+ private function deactive_client_license( $form ) {
567
+ $license = get_option( $this->option_key, null );
568
+
569
+ if ( empty( $license['key'] ) ) {
570
+ $this->error = 'License key not found.';
571
+ return;
572
+ }
573
+
574
+ $response = $this->deactivate( $license['key'] );
575
+
576
+ $data = array(
577
+ 'key' => '',
578
+ 'status' => 'deactivate',
579
+ );
580
+
581
+ update_option( $this->option_key, $data, false );
582
+
583
+ if ( ! $response['success'] ) {
584
+ $this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
585
+ return;
586
+ }
587
+
588
+ $this->success = 'License deactivated successfully.';
589
+ }
590
+
591
+ /**
592
+ * Add license menu page
593
+ */
594
+ private function add_menu_page() {
595
+ add_menu_page(
596
+ $this->menu_args['page_title'],
597
+ $this->menu_args['menu_title'],
598
+ $this->menu_args['capability'],
599
+ $this->menu_args['menu_slug'],
600
+ array( $this, 'menu_output' ),
601
+ $this->menu_args['icon_url'],
602
+ $this->menu_args['position']
603
+ );
604
+ }
605
+
606
+ /**
607
+ * Add submenu page
608
+ */
609
+ private function add_submenu_page() {
610
+ add_submenu_page(
611
+ $this->menu_args['parent_slug'],
612
+ $this->menu_args['page_title'],
613
+ $this->menu_args['menu_title'],
614
+ $this->menu_args['capability'],
615
+ $this->menu_args['menu_slug'],
616
+ array( $this, 'menu_output' ),
617
+ $this->menu_args['position']
618
+ );
619
+ }
620
+
621
+ /**
622
+ * Add submenu page
623
+ */
624
+ private function add_options_page() {
625
+ add_options_page(
626
+ $this->menu_args['page_title'],
627
+ $this->menu_args['menu_title'],
628
+ $this->menu_args['capability'],
629
+ $this->menu_args['menu_slug'],
630
+ array( $this, 'menu_output' ),
631
+ $this->menu_args['position']
632
+ );
633
+ }
634
+
635
+ /**
636
+ * Schedule daily sicense checker event
637
+ */
638
+ public function schedule_cron_event() {
639
+ if ( ! wp_next_scheduled( $this->schedule_hook ) ) {
640
+ wp_schedule_event( time(), 'daily', $this->schedule_hook );
641
+
642
+ wp_schedule_single_event( time() + 20, $this->schedule_hook );
643
+ }
644
+ }
645
+
646
+ /**
647
+ * Clear any scheduled hook
648
+ */
649
+ public function clear_scheduler() {
650
+ wp_clear_scheduled_hook( $this->schedule_hook );
651
+ }
652
+
653
+ /**
654
+ * Enable/Disable schedule
655
+ */
656
+ private function run_schedule() {
657
+ switch ( $this->client->type ) {
658
+ case 'plugin':
659
+ register_activation_hook( $this->client->file, array( $this, 'schedule_cron_event' ) );
660
+ register_deactivation_hook( $this->client->file, array( $this, 'clear_scheduler' ) );
661
+ break;
662
+
663
+ case 'theme':
664
+ add_action( 'after_switch_theme', array( $this, 'schedule_cron_event' ) );
665
+ add_action( 'switch_theme', array( $this, 'clear_scheduler' ) );
666
+ break;
667
+ }
668
+ }
669
+
670
+ /**
671
+ * Form action URL
672
+ */
673
+ private function formActionUrl() {
674
+ echo add_query_arg(
675
+ array( 'page' => $_GET['page'] ),
676
+ admin_url( basename( $_SERVER['SCRIPT_NAME'] ) )
677
+ );
678
+ }
679
+
680
+ /**
681
+ * Get input license key
682
+ * @param $action
683
+ * @return $license
684
+ */
685
+ private function get_input_license_value( $action, $license ) {
686
+ if ( 'active' == $action ) {
687
+ return isset( $license['key'] ) ? $license['key'] : '';
688
+ }
689
+
690
+ if ( 'deactive' == $action ) {
691
+ $key_length = strlen( $license['key'] );
692
+
693
+ return str_pad(
694
+ substr( $license['key'], 0, $key_length / 2 ), $key_length, '*'
695
+ );
696
+ }
697
+
698
+ return '';
699
+ }
700
+
701
  }
vendor/appsero/src/Updater.php CHANGED
@@ -18,7 +18,7 @@ class Updater {
18
  /**
19
  * Initialize the class
20
  *
21
- * @param Appsero\Client
22
  */
23
  public function __construct( Client $client ) {
24
 
18
  /**
19
  * Initialize the class
20
  *
21
+ * @param Happy_Addons\Appsero\Client
22
  */
23
  public function __construct( Client $client ) {
24
 
widgets/step-flow/widget.php CHANGED
@@ -97,7 +97,7 @@ class Step_Flow extends Base {
97
  $this->add_control(
98
  'title',
99
  [
100
- 'label' => __( 'Title & Description', 'happy-elementor-addons' ),
101
  'type' => Controls_Manager::TEXT,
102
  'label_block' => true,
103
  'placeholder' => __( 'Title', 'happy-elementor-addons' ),
@@ -113,7 +113,6 @@ class Step_Flow extends Base {
113
  'description',
114
  [
115
  'label' => __( 'Description', 'happy-elementor-addons' ),
116
- 'show_label' => false,
117
  'description' => ha_get_allowed_html_desc( 'intermediate' ),
118
  'type' => Controls_Manager::TEXTAREA,
119
  'placeholder' => __( 'Description', 'happy-elementor-addons' ),
@@ -136,12 +135,48 @@ class Step_Flow extends Base {
136
  ]
137
  );
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  $this->add_control(
140
  'content_alignment',
141
  [
142
  'label' => __( 'Alignment', 'happy-elementor-addons' ),
143
  'type' => Controls_Manager::CHOOSE,
144
- 'separator' => 'before',
145
  'options' => [
146
  'left' => [
147
  'title' => __( 'Left', 'happy-elementor-addons' ),
@@ -643,6 +678,16 @@ class Step_Flow extends Base {
643
  } else {
644
  $this->add_inline_editing_attributes( 'title', 'basic' );
645
  }
 
 
 
 
 
 
 
 
 
 
646
  ?>
647
 
648
  <div class="ha-steps-icon">
@@ -659,13 +704,14 @@ class Step_Flow extends Base {
659
  <?php endif; ?>
660
  </div>
661
 
662
- <h2 <?php $this->print_render_attribute_string( 'title' ); ?>>
663
- <?php if ( ! empty( $settings['link']['url'] ) ) : ?>
664
- <a <?php $this->print_render_attribute_string( 'link' ); ?>><?php echo ha_kses_basic( $settings['title'] ); ?></a>
665
- <?php else : ?>
666
- <?php echo ha_kses_basic( $settings['title'] ); ?>
667
- <?php endif; ?>
668
- </h2>
 
669
 
670
  <?php if ( $settings['description'] ) : ?>
671
  <p <?php $this->print_render_attribute_string( 'description' ); ?>><?php echo ha_kses_intermediate( $settings['description'] ); ?></p>
97
  $this->add_control(
98
  'title',
99
  [
100
+ 'label' => __( 'Title', 'happy-elementor-addons' ),
101
  'type' => Controls_Manager::TEXT,
102
  'label_block' => true,
103
  'placeholder' => __( 'Title', 'happy-elementor-addons' ),
113
  'description',
114
  [
115
  'label' => __( 'Description', 'happy-elementor-addons' ),
 
116
  'description' => ha_get_allowed_html_desc( 'intermediate' ),
117
  'type' => Controls_Manager::TEXTAREA,
118
  'placeholder' => __( 'Description', 'happy-elementor-addons' ),
135
  ]
136
  );
137
 
138
+ $this->add_control(
139
+ 'title_tag',
140
+ [
141
+ 'label' => __( 'Title HTML Tag', 'happy-elementor-addons' ),
142
+ 'type' => Controls_Manager::CHOOSE,
143
+ 'separator' => 'before',
144
+ 'options' => [
145
+ 'h1' => [
146
+ 'title' => __( 'H1', 'happy-elementor-addons' ),
147
+ 'icon' => 'eicon-editor-h1'
148
+ ],
149
+ 'h2' => [
150
+ 'title' => __( 'H2', 'happy-elementor-addons' ),
151
+ 'icon' => 'eicon-editor-h2'
152
+ ],
153
+ 'h3' => [
154
+ 'title' => __( 'H3', 'happy-elementor-addons' ),
155
+ 'icon' => 'eicon-editor-h3'
156
+ ],
157
+ 'h4' => [
158
+ 'title' => __( 'H4', 'happy-elementor-addons' ),
159
+ 'icon' => 'eicon-editor-h4'
160
+ ],
161
+ 'h5' => [
162
+ 'title' => __( 'H5', 'happy-elementor-addons' ),
163
+ 'icon' => 'eicon-editor-h5'
164
+ ],
165
+ 'h6' => [
166
+ 'title' => __( 'H6', 'happy-elementor-addons' ),
167
+ 'icon' => 'eicon-editor-h6'
168
+ ]
169
+ ],
170
+ 'default' => 'h2',
171
+ 'toggle' => false,
172
+ ]
173
+ );
174
+
175
  $this->add_control(
176
  'content_alignment',
177
  [
178
  'label' => __( 'Alignment', 'happy-elementor-addons' ),
179
  'type' => Controls_Manager::CHOOSE,
 
180
  'options' => [
181
  'left' => [
182
  'title' => __( 'Left', 'happy-elementor-addons' ),
678
  } else {
679
  $this->add_inline_editing_attributes( 'title', 'basic' );
680
  }
681
+
682
+ if ( ! empty( $settings['link']['url'] ) ) {
683
+ $title = sprintf(
684
+ '<a %1$s>%2$s</a>',
685
+ $this->print_render_attribute_string( 'link' ),
686
+ ha_kses_basic( $settings['title'] )
687
+ );
688
+ } else {
689
+ $title = ha_kses_basic( $settings['title'] );
690
+ }
691
  ?>
692
 
693
  <div class="ha-steps-icon">
704
  <?php endif; ?>
705
  </div>
706
 
707
+ <?php
708
+ printf(
709
+ '<%1$s %2$s>%3$s</%1$s>',
710
+ tag_escape( $settings['title_tag'] ),
711
+ $this->get_render_attribute_string( 'title' ),
712
+ $title
713
+ );
714
+ ?>
715
 
716
  <?php if ( $settings['description'] ) : ?>
717
  <p <?php $this->print_render_attribute_string( 'description' ); ?>><?php echo ha_kses_intermediate( $settings['description'] ); ?></p>