WP VR – 360 Panorama and virtual tour creator for WordPress - Version 8.2.6

Version Description

(15-12-2022) = * Fixed: Security Patch.

Download this release

Release Info

Developer rextheme
Plugin Icon 128x128 WP VR – 360 Panorama and virtual tour creator for WordPress
Version 8.2.6
Comparing to
See all releases

Code changes from version 8.2.5 to 8.2.6

README.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: rextheme, coderexco
3
  Tags: virtual tour, real estate tour, panorama, panorama viewer, virtual tour, 360 panorama, interactive tour, 360, Streetview, virtual reality, 360 video, virtual, vr, interactive, 360-degree, equirectangular, google street view, panoramas
4
  Donate link: https://rextheme.com/wp-vr-360-panorama-and-virtual-tour-creator-for-wordpress/
5
  Requires at least: 5.0
6
- Tested up to: 6.0
7
  Requires PHP: 7.0.0
8
- Stable tag: 8.2.5
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -309,6 +309,9 @@ Admins can remove the access from Authors and Editors at any time.
309
 
310
  == Changelog ==
311
 
 
 
 
312
  = 8.2.5 (25-11-2022) =
313
  * BFCM banner & notice added.
314
 
3
  Tags: virtual tour, real estate tour, panorama, panorama viewer, virtual tour, 360 panorama, interactive tour, 360, Streetview, virtual reality, 360 video, virtual, vr, interactive, 360-degree, equirectangular, google street view, panoramas
4
  Donate link: https://rextheme.com/wp-vr-360-panorama-and-virtual-tour-creator-for-wordpress/
5
  Requires at least: 5.0
6
+ Tested up to: 6.1.1
7
  Requires PHP: 7.0.0
8
+ Stable tag: 8.2.6
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
309
 
310
  == Changelog ==
311
 
312
+ = 8.2.6 (15-12-2022) =
313
+ * Fixed: Security Patch.
314
+
315
  = 8.2.5 (25-11-2022) =
316
  * BFCM banner & notice added.
317
 
appsero/src/Client.php CHANGED
@@ -13,7 +13,7 @@ class Client {
13
  *
14
  * @var string
15
  */
16
- public $version = '1.1.11';
17
 
18
  /**
19
  * Hash identifier of the plugin
@@ -74,6 +74,27 @@ class Client {
74
  */
75
  public $textdomain;
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  /**
78
  * Initialize the class
79
  *
@@ -100,7 +121,14 @@ class Client {
100
  require_once __DIR__ . '/Insights.php';
101
  }
102
 
103
- return new Insights( $this );
 
 
 
 
 
 
 
104
  }
105
 
106
  /**
@@ -114,7 +142,14 @@ class Client {
114
  require_once __DIR__ . '/Updater.php';
115
  }
116
 
117
- return new Updater( $this );
 
 
 
 
 
 
 
118
  }
119
 
120
  /**
@@ -128,7 +163,14 @@ class Client {
128
  require_once __DIR__ . '/License.php';
129
  }
130
 
131
- return new License( $this );
 
 
 
 
 
 
 
132
  }
133
 
134
  /**
@@ -170,7 +212,7 @@ class Client {
170
  $this->project_version = $theme->version;
171
  $this->type = 'theme';
172
  }
173
-
174
  $this->textdomain = $this->slug;
175
  }
176
 
13
  *
14
  * @var string
15
  */
16
+ public $version = '1.2.0';
17
 
18
  /**
19
  * Hash identifier of the plugin
74
  */
75
  public $textdomain;
76
 
77
+ /**
78
+ * The Object of Insights Class
79
+ *
80
+ * @var object
81
+ */
82
+ private $insights;
83
+
84
+ /**
85
+ * The Object of Updater Class
86
+ *
87
+ * @var object
88
+ */
89
+ private $updater;
90
+
91
+ /**
92
+ * The Object of License Class
93
+ *
94
+ * @var object
95
+ */
96
+ private $license;
97
+
98
  /**
99
  * Initialize the class
100
  *
121
  require_once __DIR__ . '/Insights.php';
122
  }
123
 
124
+ // if already instantiated, return the cached one
125
+ if ( $this->insights ) {
126
+ return $this->insights;
127
+ }
128
+
129
+ $this->insights = new Insights( $this );
130
+
131
+ return $this->insights;
132
  }
133
 
134
  /**
142
  require_once __DIR__ . '/Updater.php';
143
  }
144
 
145
+ // if already instantiated, return the cached one
146
+ if ( $this->updater ) {
147
+ return $this->updater;
148
+ }
149
+
150
+ $this->updater = new Updater( $this );
151
+
152
+ return $this->updater;
153
  }
154
 
155
  /**
163
  require_once __DIR__ . '/License.php';
164
  }
165
 
166
+ // if already instantiated, return the cached one
167
+ if ( $this->license ) {
168
+ return $this->license;
169
+ }
170
+
171
+ $this->license = new License( $this );
172
+
173
+ return $this->license;
174
  }
175
 
176
  /**
212
  $this->project_version = $theme->version;
213
  $this->type = 'theme';
214
  }
215
+
216
  $this->textdomain = $this->slug;
217
  }
218
 
appsero/src/Insights.php CHANGED
@@ -38,10 +38,18 @@ class Insights {
38
  */
39
  protected $client;
40
 
 
 
 
 
 
 
41
  /**
42
  * Initialize the class
43
  *
44
- * @param AppSero\Client
 
 
45
  */
46
  public function __construct( $client, $name = null, $file = null ) {
47
 
@@ -65,6 +73,17 @@ class Insights {
65
  return $this;
66
  }
67
 
 
 
 
 
 
 
 
 
 
 
 
68
  /**
69
  * Add extra data if needed
70
  *
@@ -85,7 +104,7 @@ class Insights {
85
  *
86
  * @return \self
87
  */
88
- public function notice( $text ) {
89
  $this->notice = $text;
90
 
91
  return $this;
@@ -165,11 +184,6 @@ class Insights {
165
  * @return void
166
  */
167
  public function send_tracking_data( $override = false ) {
168
- // skip on AJAX Requests
169
- if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
170
- return;
171
- }
172
-
173
  if ( ! $this->tracking_allowed() && ! $override ) {
174
  return;
175
  }
@@ -180,7 +194,7 @@ class Insights {
180
  if ( $last_send && $last_send > strtotime( '-1 week' ) ) {
181
  return;
182
  }
183
-
184
  $tracking_data = $this->get_tracking_data();
185
 
186
  $response = $this->client->send_request( $tracking_data, 'track' );
@@ -227,8 +241,33 @@ class Insights {
227
  'ip_address' => $this->get_user_ip_address(),
228
  'project_version' => $this->client->project_version,
229
  'tracking_skipped' => false,
 
230
  );
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  // Add metadata
233
  if ( $extra = $this->get_extra_data() ) {
234
  $data['extra'] = $extra;
@@ -274,10 +313,14 @@ class Insights {
274
  'Number of users in your site',
275
  'Site language',
276
  'Number of active and inactive plugins',
277
- 'Site name and url',
278
  'Your name and email address',
279
  );
280
 
 
 
 
 
281
  return $data;
282
  }
283
 
@@ -322,9 +365,17 @@ class Insights {
322
  * @return boolean
323
  */
324
  private function is_local_server() {
325
- return false;
326
 
327
- $is_local = in_array( $_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1' ) );
 
 
 
 
 
 
 
 
 
328
 
329
  return apply_filters( 'appsero_is_local', $is_local );
330
  }
@@ -388,7 +439,7 @@ class Insights {
388
 
389
  $notice .= ' (<a class="' . $this->client->slug . '-insights-data-we-collect" href="#">' . $this->client->__trans( 'what we collect' ) . '</a>)';
390
  $notice .= '<p class="description" style="display:none;">' . implode( ', ', $this->data_we_collect() ) . '. No sensitive data is tracked. ';
391
- $notice .= 'We are using Appsero to collect your data. <a href="' . $policy_url . '">Learn more</a> about how Appsero collects and handle your data.</p>';
392
 
393
  echo '<div class="updated"><p>';
394
  echo $notice;
@@ -585,7 +636,7 @@ class Insights {
585
  if ( ! $count ) {
586
  continue;
587
  }
588
-
589
  $user_count[ $role ] = $count;
590
  }
591
 
@@ -674,45 +725,45 @@ class Insights {
674
  $reasons = array(
675
  array(
676
  'id' => 'could-not-understand',
677
- 'text' => $this->client->__trans( "I couldn't understand how to make it work" ),
678
- 'type' => 'textarea',
679
- 'placeholder' => $this->client->__trans( 'Would you like us to assist you?' )
680
  ),
681
  array(
682
  'id' => 'found-better-plugin',
683
- 'text' => $this->client->__trans( 'I found a better plugin' ),
684
- 'type' => 'text',
685
- 'placeholder' => $this->client->__trans( 'Which plugin?' )
686
  ),
687
  array(
688
  'id' => 'not-have-that-feature',
689
- 'text' => $this->client->__trans( "The plugin is great, but I need specific feature that you don't support" ),
690
- 'type' => 'textarea',
691
- 'placeholder' => $this->client->__trans( 'Could you tell us more about that feature?' )
692
  ),
693
  array(
694
  'id' => 'is-not-working',
695
- 'text' => $this->client->__trans( 'The plugin is not working' ),
696
- 'type' => 'textarea',
697
- 'placeholder' => $this->client->__trans( 'Could you tell us a bit more whats not working?' )
698
  ),
699
  array(
700
  'id' => 'looking-for-other',
701
- 'text' => $this->client->__trans( "It's not what I was looking for" ),
702
- 'type' => '',
703
- 'placeholder' => ''
704
  ),
705
  array(
706
  'id' => 'did-not-work-as-expected',
707
- 'text' => $this->client->__trans( "The plugin didn't work as expected" ),
708
- 'type' => 'textarea',
709
- 'placeholder' => $this->client->__trans( 'What did you expect?' )
710
  ),
711
  array(
712
  'id' => 'other',
713
- 'text' => $this->client->__trans( 'Other' ),
714
- 'type' => 'textarea',
715
- 'placeholder' => $this->client->__trans( 'Could you tell us a bit more?' )
716
  ),
717
  );
718
 
@@ -729,11 +780,19 @@ class Insights {
729
  if ( ! isset( $_POST['reason_id'] ) ) {
730
  wp_send_json_error();
731
  }
732
-
 
 
 
 
 
 
 
 
733
  $data = $this->get_tracking_data();
734
  $data['reason_id'] = sanitize_text_field( $_POST['reason_id'] );
735
  $data['reason_info'] = isset( $_REQUEST['reason_info'] ) ? trim( stripslashes( $_REQUEST['reason_info'] ) ) : '';
736
-
737
  $this->client->send_request( $data, 'deactivate' );
738
 
739
  wp_send_json_success();
@@ -751,99 +810,69 @@ class Insights {
751
  return;
752
  }
753
 
 
754
  $reasons = $this->get_uninstall_reasons();
 
755
  ?>
756
 
757
  <div class="wd-dr-modal" id="<?php echo $this->client->slug; ?>-wd-dr-modal">
758
  <div class="wd-dr-modal-wrap">
759
  <div class="wd-dr-modal-header">
760
- <h3><?php $this->client->_etrans( 'If you have a moment, please let us know why you are deactivating:' ); ?></h3>
761
  </div>
762
 
763
  <div class="wd-dr-modal-body">
764
- <ul class="reasons">
765
- <?php foreach ($reasons as $reason) { ?>
766
- <li data-type="<?php echo esc_attr( $reason['type'] ); ?>" data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>">
767
- <label><input type="radio" name="selected-reason" value="<?php echo $reason['id']; ?>"> <?php echo $reason['text']; ?></label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
768
  </li>
769
  <?php } ?>
770
  </ul>
 
 
771
  <p class="wd-dr-modal-reasons-bottom">
772
- <?php
773
  echo sprintf(
774
  $this->client->__trans( 'We share your data with <a href="%1$s" target="_blank">Appsero</a> to troubleshoot problems &amp; make product improvements. <a href="%2$s" target="_blank">Learn more</a> about how Appsero handles your data.'),
775
  esc_url( 'https://appsero.com/' ),
776
  esc_url( 'https://appsero.com/privacy-policy' )
777
- );
778
  ?>
779
  </p>
780
  </div>
781
 
782
  <div class="wd-dr-modal-footer">
783
- <a href="#" class="dont-bother-me"><?php $this->client->_etrans( "I rather wouldn't say" ); ?></a>
784
- <button class="button-secondary"><?php $this->client->_etrans( 'Submit & Deactivate' ); ?></button>
785
- <button class="button-primary"><?php $this->client->_etrans( 'Cancel' ); ?></button>
786
  </div>
787
  </div>
788
  </div>
789
 
790
- <style type="text/css">
791
- .wd-dr-modal {
792
- position: fixed;
793
- z-index: 99999;
794
- top: 0;
795
- right: 0;
796
- bottom: 0;
797
- left: 0;
798
- background: rgba(0,0,0,0.5);
799
- display: none;
800
- }
801
-
802
- .wd-dr-modal.modal-active {
803
- display: block;
804
- }
805
-
806
- .wd-dr-modal-wrap {
807
- width: 475px;
808
- position: relative;
809
- margin: 10% auto;
810
- background: #fff;
811
- }
812
-
813
- .wd-dr-modal-header {
814
- border-bottom: 1px solid #eee;
815
- padding: 8px 20px;
816
- }
817
-
818
- .wd-dr-modal-header h3 {
819
- line-height: 150%;
820
- margin: 0;
821
- }
822
-
823
- .wd-dr-modal-body {
824
- padding: 5px 20px 20px 20px;
825
- }
826
-
827
- .wd-dr-modal-body .reason-input {
828
- margin-top: 5px;
829
- margin-left: 20px;
830
- }
831
- .wd-dr-modal-footer {
832
- border-top: 1px solid #eee;
833
- padding: 12px 20px;
834
- text-align: right;
835
- }
836
- .wd-dr-modal-reasons-bottom {
837
- margin: 15px 0 0 0;
838
- }
839
- </style>
840
-
841
  <script type="text/javascript">
842
  (function($) {
843
  $(function() {
844
  var modal = $( '#<?php echo $this->client->slug; ?>-wd-dr-modal' );
845
  var deactivateLink = '';
846
 
 
847
  $( '#the-list' ).on('click', 'a.<?php echo $this->client->slug; ?>-deactivate-link', function(e) {
848
  e.preventDefault();
849
 
@@ -852,28 +881,41 @@ class Insights {
852
  modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left');
853
  });
854
 
855
- modal.on('click', 'button.button-primary', function(e) {
 
856
  e.preventDefault();
857
-
858
  modal.removeClass('modal-active');
859
  });
860
 
 
861
  modal.on('click', 'input[type="radio"]', function () {
862
- var parent = $(this).parents('li:first');
 
 
863
 
864
- modal.find('.reason-input').remove();
 
 
 
865
 
866
- var inputType = parent.data('type'),
867
- inputPlaceholder = parent.data('placeholder'),
868
- reasonInputHtml = '<div class="reason-input">' + ( ( 'text' === inputType ) ? '<input type="text" size="40" />' : '<textarea rows="5" cols="45"></textarea>' ) + '</div>';
 
869
 
870
- if ( inputType !== '' ) {
871
- parent.append( $(reasonInputHtml) );
872
- parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
873
  }
 
 
 
 
 
874
  });
875
 
876
- modal.on('click', 'button.button-secondary', function(e) {
 
877
  e.preventDefault();
878
 
879
  var button = $(this);
@@ -883,14 +925,13 @@ class Insights {
883
  }
884
 
885
  var $radio = $( 'input[type="radio"]:checked', modal );
886
-
887
- var $selected_reason = $radio.parents('li:first'),
888
- $input = $selected_reason.find('textarea, input[type="text"]');
889
 
890
  $.ajax({
891
  url: ajaxurl,
892
  type: 'POST',
893
  data: {
 
894
  action: '<?php echo $this->client->slug; ?>_submit-uninstall-reason',
895
  reason_id: ( 0 === $radio.length ) ? 'none' : $radio.val(),
896
  reason_info: ( 0 !== $input.length ) ? $input.val().trim() : ''
@@ -968,10 +1009,10 @@ class Insights {
968
  private function send_tracking_skipped_request() {
969
  $skipped = get_option( $this->client->slug . '_tracking_skipped' );
970
 
971
- $data = [
972
  'hash' => $this->client->hash,
973
  'previously_skipped' => false,
974
- ];
975
 
976
  if ( $skipped === 'yes' ) {
977
  $data['previously_skipped'] = true;
@@ -981,4 +1022,167 @@ class Insights {
981
 
982
  $this->client->send_request( $data, 'tracking-skipped' );
983
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
984
  }
38
  */
39
  protected $client;
40
 
41
+ /**
42
+ * @var boolean
43
+ */
44
+ private $plugin_data = false;
45
+
46
+
47
  /**
48
  * Initialize the class
49
  *
50
+ * @param $client
51
+ * @param null $name
52
+ * @param null $file
53
  */
54
  public function __construct( $client, $name = null, $file = null ) {
55
 
73
  return $this;
74
  }
75
 
76
+ /**
77
+ * Add plugin data if needed
78
+ *
79
+ * @return \self
80
+ */
81
+ public function add_plugin_data() {
82
+ $this->plugin_data = true;
83
+
84
+ return $this;
85
+ }
86
+
87
  /**
88
  * Add extra data if needed
89
  *
104
  *
105
  * @return \self
106
  */
107
+ public function notice($text='' ) {
108
  $this->notice = $text;
109
 
110
  return $this;
184
  * @return void
185
  */
186
  public function send_tracking_data( $override = false ) {
 
 
 
 
 
187
  if ( ! $this->tracking_allowed() && ! $override ) {
188
  return;
189
  }
194
  if ( $last_send && $last_send > strtotime( '-1 week' ) ) {
195
  return;
196
  }
197
+
198
  $tracking_data = $this->get_tracking_data();
199
 
200
  $response = $this->client->send_request( $tracking_data, 'track' );
241
  'ip_address' => $this->get_user_ip_address(),
242
  'project_version' => $this->client->project_version,
243
  'tracking_skipped' => false,
244
+ 'is_local' => $this->is_local_server(),
245
  );
246
 
247
+ // Add Plugins
248
+ if ($this->plugin_data) {
249
+
250
+ $plugins_data = array();
251
+
252
+ foreach ($all_plugins['active_plugins'] as $slug => $plugin) {
253
+ $slug = strstr($slug, '/', true);
254
+ if (! $slug) {
255
+ continue;
256
+ }
257
+
258
+ $plugins_data[ $slug ] = array(
259
+ 'name' => isset($plugin['name']) ? $plugin['name'] : '',
260
+ 'version' => isset($plugin['version']) ? $plugin['version'] : '',
261
+ );
262
+ }
263
+
264
+ if (array_key_exists($this->client->slug, $plugins_data)) {
265
+ unset($plugins_data[$this->client->slug]);
266
+ }
267
+
268
+ $data['plugins'] = $plugins_data;
269
+ }
270
+
271
  // Add metadata
272
  if ( $extra = $this->get_extra_data() ) {
273
  $data['extra'] = $extra;
313
  'Number of users in your site',
314
  'Site language',
315
  'Number of active and inactive plugins',
316
+ 'Site name and URL',
317
  'Your name and email address',
318
  );
319
 
320
+ if ($this->plugin_data) {
321
+ array_splice($data, 4, 0, ["active plugins' name"]);
322
+ }
323
+
324
  return $data;
325
  }
326
 
365
  * @return boolean
366
  */
367
  private function is_local_server() {
 
368
 
369
+ $host = isset( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : 'localhost';
370
+ $ip = isset( $_SERVER['SERVER_ADDR'] ) ? $_SERVER['SERVER_ADDR'] : '127.0.0.1';
371
+ $is_local = false;
372
+
373
+ if( in_array( $ip,array( '127.0.0.1', '::1' ) )
374
+ || ! strpos( $host, '.' )
375
+ || in_array( strrchr( $host, '.' ), array( '.test', '.testing', '.local', '.localhost', '.localdomain' ) )
376
+ ) {
377
+ $is_local = true;
378
+ }
379
 
380
  return apply_filters( 'appsero_is_local', $is_local );
381
  }
439
 
440
  $notice .= ' (<a class="' . $this->client->slug . '-insights-data-we-collect" href="#">' . $this->client->__trans( 'what we collect' ) . '</a>)';
441
  $notice .= '<p class="description" style="display:none;">' . implode( ', ', $this->data_we_collect() ) . '. No sensitive data is tracked. ';
442
+ $notice .= 'We are using Appsero to collect your data. <a href="' . $policy_url . '" target="_blank">Learn more</a> about how Appsero collects and handle your data.</p>';
443
 
444
  echo '<div class="updated"><p>';
445
  echo $notice;
636
  if ( ! $count ) {
637
  continue;
638
  }
639
+
640
  $user_count[ $role ] = $count;
641
  }
642
 
725
  $reasons = array(
726
  array(
727
  'id' => 'could-not-understand',
728
+ 'text' => $this->client->__trans( "Couldn't understand" ),
729
+ 'placeholder' => $this->client->__trans( 'Would you like us to assist you?' ),
730
+ 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" viewBox="0 0 23 23"><g fill="none"><g fill="#3B86FF"><path d="M11.5 0C17.9 0 23 5.1 23 11.5 23 17.9 17.9 23 11.5 23 10.6 23 9.6 22.9 8.8 22.7L8.8 22.6C9.3 22.5 9.7 22.3 10 21.9 10.3 21.6 10.4 21.3 10.4 20.9 10.8 21 11.1 21 11.5 21 16.7 21 21 16.7 21 11.5 21 6.3 16.7 2 11.5 2 6.3 2 2 6.3 2 11.5 2 13 2.3 14.3 2.9 15.6 2.7 16 2.4 16.3 2.2 16.8L2.1 17.1 2.1 17.3C2 17.5 2 17.7 2 18 0.7 16.1 0 13.9 0 11.5 0 5.1 5.1 0 11.5 0ZM6 13.6C6 13.7 6.1 13.8 6.1 13.9 6.3 14.5 6.2 15.7 6.1 16.4 6.1 16.6 6 16.9 6 17.1 6 17.1 6.1 17.1 6.1 17.1 7.1 16.9 8.2 16 9.3 15.5 9.8 15.2 10.4 15 10.9 15 11.2 15 11.4 15 11.6 15.2 11.9 15.4 12.1 16 11.6 16.4 11.5 16.5 11.3 16.6 11.1 16.7 10.5 17 9.9 17.4 9.3 17.7 9 17.9 9 18.1 9.1 18.5 9.2 18.9 9.3 19.4 9.3 19.8 9.4 20.3 9.3 20.8 9 21.2 8.8 21.5 8.5 21.6 8.1 21.7 7.9 21.8 7.6 21.9 7.3 21.9L6.5 22C6.3 22 6 21.9 5.8 21.9 5 21.8 4.4 21.5 3.9 20.9 3.3 20.4 3.1 19.6 3 18.8L3 18.5C3 18.2 3 17.9 3.1 17.7L3.1 17.6C3.2 17.1 3.5 16.7 3.7 16.3 4 15.9 4.2 15.4 4.3 15 4.4 14.6 4.4 14.5 4.6 14.2 4.6 13.9 4.7 13.7 4.9 13.6 5.2 13.2 5.7 13.2 6 13.6ZM11.7 11.2C13.1 11.2 14.3 11.7 15.2 12.9 15.3 13 15.4 13.1 15.4 13.2 15.4 13.4 15.3 13.8 15.2 13.8 15 13.9 14.9 13.8 14.8 13.7 14.6 13.5 14.4 13.2 14.1 13.1 13.5 12.6 12.8 12.3 12 12.2 10.7 12.1 9.5 12.3 8.4 12.8 8.3 12.8 8.2 12.8 8.1 12.8 7.9 12.8 7.8 12.4 7.8 12.2 7.7 12.1 7.8 11.9 8 11.8 8.4 11.7 8.8 11.5 9.2 11.4 10 11.2 10.9 11.1 11.7 11.2ZM16.3 5.9C17.3 5.9 18 6.6 18 7.6 18 8.5 17.3 9.3 16.3 9.3 15.4 9.3 14.7 8.5 14.7 7.6 14.7 6.6 15.4 5.9 16.3 5.9ZM8.3 5C9.2 5 9.9 5.8 9.9 6.7 9.9 7.7 9.2 8.4 8.2 8.4 7.3 8.4 6.6 7.7 6.6 6.7 6.6 5.8 7.3 5 8.3 5Z"/></g></g></svg>'
731
  ),
732
  array(
733
  'id' => 'found-better-plugin',
734
+ 'text' => $this->client->__trans( 'Found a better plugin' ),
735
+ 'placeholder' => $this->client->__trans( 'Which plugin?' ),
736
+ 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" viewBox="0 0 23 23"><g fill="none"><g fill="#3B86FF"><path d="M17.1 14L22.4 19.3C23.2 20.2 23.2 21.5 22.4 22.4 21.5 23.2 20.2 23.2 19.3 22.4L19.3 22.4 14 17.1C15.3 16.3 16.3 15.3 17.1 14L17.1 14ZM8.6 0C13.4 0 17.3 3.9 17.3 8.6 17.3 13.4 13.4 17.2 8.6 17.2 3.9 17.2 0 13.4 0 8.6 0 3.9 3.9 0 8.6 0ZM8.6 2.2C5.1 2.2 2.2 5.1 2.2 8.6 2.2 12.2 5.1 15.1 8.6 15.1 12.2 15.1 15.1 12.2 15.1 8.6 15.1 5.1 12.2 2.2 8.6 2.2ZM8.6 3.6L8.6 5C6.6 5 5 6.6 5 8.6L5 8.6 3.6 8.6C3.6 5.9 5.9 3.6 8.6 3.6L8.6 3.6Z"/></g></g></svg>',
737
  ),
738
  array(
739
  'id' => 'not-have-that-feature',
740
+ 'text' => $this->client->__trans( "Missing a specific feature" ),
741
+ 'placeholder' => $this->client->__trans( 'Could you tell us more about that feature?' ),
742
+ 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="17" viewBox="0 0 24 17"><g fill="none"><g fill="#3B86FF"><path d="M19.4 0C19.7 0.6 19.8 1.3 19.8 2 19.8 3.2 19.4 4.4 18.5 5.3 17.6 6.2 16.5 6.7 15.2 6.7 15.2 6.7 15.2 6.7 15.2 6.7 14 6.7 12.9 6.2 12 5.3 11.2 4.4 10.7 3.3 10.7 2 10.7 1.3 10.8 0.6 11.1 0L7.6 0 7 0 6.5 0 6.5 5.7C6.3 5.6 5.9 5.3 5.6 5.1 5 4.6 4.3 4.3 3.5 4.3 3.5 4.3 3.5 4.3 3.4 4.3 1.6 4.4 0 5.9 0 7.9 0 8.6 0.2 9.2 0.5 9.7 1.1 10.8 2.2 11.5 3.5 11.5 4.3 11.5 5 11.2 5.6 10.8 6 10.5 6.3 10.3 6.5 10.2L6.5 10.2 6.5 17 6.5 17 7 17 7.6 17 22.5 17C23.3 17 24 16.3 24 15.5L24 0 19.4 0Z"/></g></g></svg>',
743
  ),
744
  array(
745
  'id' => 'is-not-working',
746
+ 'text' => $this->client->__trans( 'Not working' ),
747
+ 'placeholder' => $this->client->__trans( 'Could you tell us a bit more whats not working?' ),
748
+ 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" viewBox="0 0 23 23"><g fill="none"><g fill="#3B86FF"><path d="M11.5 0C17.9 0 23 5.1 23 11.5 23 17.9 17.9 23 11.5 23 5.1 23 0 17.9 0 11.5 0 5.1 5.1 0 11.5 0ZM11.8 14.4C11.2 14.4 10.7 14.8 10.7 15.4 10.7 16 11.2 16.4 11.8 16.4 12.4 16.4 12.8 16 12.8 15.4 12.8 14.8 12.4 14.4 11.8 14.4ZM12 7C10.1 7 9.1 8.1 9 9.6L10.5 9.6C10.5 8.8 11.1 8.3 11.9 8.3 12.7 8.3 13.2 8.8 13.2 9.5 13.2 10.1 13 10.4 12.2 10.9 11.3 11.4 10.9 12 11 12.9L11 13.4 12.5 13.4 12.5 13C12.5 12.4 12.7 12.1 13.5 11.6 14.4 11.1 14.9 10.4 14.9 9.4 14.9 8 13.7 7 12 7Z"/></g></g></svg>',
749
  ),
750
  array(
751
  'id' => 'looking-for-other',
752
+ 'text' => $this->client->__trans( "Not what I was looking" ),
753
+ 'placeholder' => $this->client->__trans( 'Could you tell us a bit more?' ),
754
+ 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="17" viewBox="0 0 24 17"><g fill="none"><g fill="#3B86FF"><path d="M23.5 9C23.5 9 23.5 8.9 23.5 8.9 23.5 8.9 23.5 8.9 23.5 8.9 23.4 8.6 23.2 8.3 23 8 22.2 6.5 20.6 3.7 19.8 2.6 18.8 1.3 17.7 0 16.1 0 15.7 0 15.3 0.1 14.9 0.2 13.8 0.6 12.6 1.2 12.3 2.7L11.7 2.7C11.4 1.2 10.2 0.6 9.1 0.2 8.7 0.1 8.3 0 7.9 0 6.3 0 5.2 1.3 4.2 2.6 3.4 3.7 1.8 6.5 1 8 0.8 8.3 0.6 8.6 0.5 8.9 0.5 8.9 0.5 8.9 0.5 8.9 0.5 8.9 0.5 9 0.5 9 0.2 9.7 0 10.5 0 11.3 0 14.4 2.5 17 5.5 17 7.3 17 8.8 16.1 9.8 14.8L14.2 14.8C15.2 16.1 16.7 17 18.5 17 21.5 17 24 14.4 24 11.3 24 10.5 23.8 9.7 23.5 9ZM5.5 15C3.6 15 2 13.2 2 11 2 8.8 3.6 7 5.5 7 7.4 7 9 8.8 9 11 9 13.2 7.4 15 5.5 15ZM18.5 15C16.6 15 15 13.2 15 11 15 8.8 16.6 7 18.5 7 20.4 7 22 8.8 22 11 22 13.2 20.4 15 18.5 15Z"/></g></g></svg>',
755
  ),
756
  array(
757
  'id' => 'did-not-work-as-expected',
758
+ 'text' => $this->client->__trans( "Didn't work as expected" ),
759
+ 'placeholder' => $this->client->__trans( 'What did you expect?' ),
760
+ 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="23" height="23" viewBox="0 0 23 23"><g fill="none"><g fill="#3B86FF"><path d="M11.5 0C17.9 0 23 5.1 23 11.5 23 17.9 17.9 23 11.5 23 5.1 23 0 17.9 0 11.5 0 5.1 5.1 0 11.5 0ZM11.5 2C6.3 2 2 6.3 2 11.5 2 16.7 6.3 21 11.5 21 16.7 21 21 16.7 21 11.5 21 6.3 16.7 2 11.5 2ZM12.5 12.9L12.7 5 10.2 5 10.5 12.9 12.5 12.9ZM11.5 17.4C12.4 17.4 13 16.8 13 15.9 13 15 12.4 14.4 11.5 14.4 10.6 14.4 10 15 10 15.9 10 16.8 10.6 17.4 11.5 17.4Z"/></g></g></svg>',
761
  ),
762
  array(
763
  'id' => 'other',
764
+ 'text' => $this->client->__trans( 'Others' ),
765
+ 'placeholder' => $this->client->__trans( 'Could you tell us a bit more?' ),
766
+ 'icon' => '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="23" viewBox="0 0 24 6"><g fill="none"><g fill="#3B86FF"><path d="M3 0C4.7 0 6 1.3 6 3 6 4.7 4.7 6 3 6 1.3 6 0 4.7 0 3 0 1.3 1.3 0 3 0ZM12 0C13.7 0 15 1.3 15 3 15 4.7 13.7 6 12 6 10.3 6 9 4.7 9 3 9 1.3 10.3 0 12 0ZM21 0C22.7 0 24 1.3 24 3 24 4.7 22.7 6 21 6 19.3 6 18 4.7 18 3 18 1.3 19.3 0 21 0Z"/></g></g></svg>',
767
  ),
768
  );
769
 
780
  if ( ! isset( $_POST['reason_id'] ) ) {
781
  wp_send_json_error();
782
  }
783
+
784
+ if ( ! wp_verify_nonce( $_POST['nonce'], 'appsero-security-nonce' ) ) {
785
+ wp_send_json_error( 'Nonce verification failed' );
786
+ }
787
+
788
+ if ( ! current_user_can( 'manage_options' ) ) {
789
+ wp_send_json_error( 'You are not allowed for this task' );
790
+ }
791
+
792
  $data = $this->get_tracking_data();
793
  $data['reason_id'] = sanitize_text_field( $_POST['reason_id'] );
794
  $data['reason_info'] = isset( $_REQUEST['reason_info'] ) ? trim( stripslashes( $_REQUEST['reason_info'] ) ) : '';
795
+
796
  $this->client->send_request( $data, 'deactivate' );
797
 
798
  wp_send_json_success();
810
  return;
811
  }
812
 
813
+ $this->deactivation_modal_styles();
814
  $reasons = $this->get_uninstall_reasons();
815
+ $custom_reasons = apply_filters( 'appsero_custom_deactivation_reasons', array() );
816
  ?>
817
 
818
  <div class="wd-dr-modal" id="<?php echo $this->client->slug; ?>-wd-dr-modal">
819
  <div class="wd-dr-modal-wrap">
820
  <div class="wd-dr-modal-header">
821
+ <h3><?php $this->client->_etrans( 'Goodbyes are always hard. If you have a moment, please let us know how we can improve.' ); ?></h3>
822
  </div>
823
 
824
  <div class="wd-dr-modal-body">
825
+ <ul class="wd-de-reasons">
826
+ <?php foreach ( $reasons as $reason ) { ?>
827
+ <li data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>">
828
+ <label>
829
+ <input type="radio" name="selected-reason" value="<?php echo $reason['id']; ?>">
830
+ <div class="wd-de-reason-icon"><?php echo $reason['icon']; ?></div>
831
+ <div class="wd-de-reason-text"><?php echo $reason['text']; ?></div>
832
+ </label>
833
+ </li>
834
+ <?php } ?>
835
+ </ul>
836
+ <?php if ( $custom_reasons && is_array( $custom_reasons ) ) : ?>
837
+ <ul class="wd-de-reasons wd-de-others-reasons">
838
+ <?php foreach ( $custom_reasons as $reason ) { ?>
839
+ <li data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>" data-customreason="true">
840
+ <label>
841
+ <input type="radio" name="selected-reason" value="<?php echo $reason['id']; ?>">
842
+ <div class="wd-de-reason-icon"><?php echo $reason['icon']; ?></div>
843
+ <div class="wd-de-reason-text"><?php echo $reason['text']; ?></div>
844
+ </label>
845
  </li>
846
  <?php } ?>
847
  </ul>
848
+ <?php endif; ?>
849
+ <div class="wd-dr-modal-reason-input"><textarea></textarea></div>
850
  <p class="wd-dr-modal-reasons-bottom">
851
+ <?php
852
  echo sprintf(
853
  $this->client->__trans( 'We share your data with <a href="%1$s" target="_blank">Appsero</a> to troubleshoot problems &amp; make product improvements. <a href="%2$s" target="_blank">Learn more</a> about how Appsero handles your data.'),
854
  esc_url( 'https://appsero.com/' ),
855
  esc_url( 'https://appsero.com/privacy-policy' )
856
+ );
857
  ?>
858
  </p>
859
  </div>
860
 
861
  <div class="wd-dr-modal-footer">
862
+ <a href="#" class="dont-bother-me wd-dr-button-secondary"><?php $this->client->_etrans( "Skip & Deactivate" ); ?></a>
863
+ <button class="wd-dr-button-secondary wd-dr-cancel-modal"><?php $this->client->_etrans( 'Cancel' ); ?></button>
864
+ <button class="wd-dr-submit-modal"><?php $this->client->_etrans( 'Submit & Deactivate' ); ?></button>
865
  </div>
866
  </div>
867
  </div>
868
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
869
  <script type="text/javascript">
870
  (function($) {
871
  $(function() {
872
  var modal = $( '#<?php echo $this->client->slug; ?>-wd-dr-modal' );
873
  var deactivateLink = '';
874
 
875
+ // Open modal
876
  $( '#the-list' ).on('click', 'a.<?php echo $this->client->slug; ?>-deactivate-link', function(e) {
877
  e.preventDefault();
878
 
881
  modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left');
882
  });
883
 
884
+ // Close modal; Cancel
885
+ modal.on('click', 'button.wd-dr-cancel-modal', function(e) {
886
  e.preventDefault();
 
887
  modal.removeClass('modal-active');
888
  });
889
 
890
+ // Reason change
891
  modal.on('click', 'input[type="radio"]', function () {
892
+ var parent = $(this).parents('li');
893
+ var isCustomReason = parent.data('customreason');
894
+ var inputValue = $(this).val();
895
 
896
+ if ( isCustomReason ) {
897
+ $('ul.wd-de-reasons.wd-de-others-reasons li').removeClass('wd-de-reason-selected');
898
+ } else {
899
+ $('ul.wd-de-reasons li').removeClass('wd-de-reason-selected');
900
 
901
+ if ( "other" != inputValue ) {
902
+ $('ul.wd-de-reasons.wd-de-others-reasons').css('display', 'none');
903
+ }
904
+ }
905
 
906
+ // Show if has custom reasons
907
+ if ( "other" == inputValue ) {
908
+ $('ul.wd-de-reasons.wd-de-others-reasons').css('display', 'flex');
909
  }
910
+
911
+ parent.addClass('wd-de-reason-selected');
912
+ $('.wd-dr-modal-reason-input').show();
913
+
914
+ $('.wd-dr-modal-reason-input textarea').attr('placeholder', parent.data('placeholder')).focus();
915
  });
916
 
917
+ // Submit response
918
+ modal.on('click', 'button.wd-dr-submit-modal', function(e) {
919
  e.preventDefault();
920
 
921
  var button = $(this);
925
  }
926
 
927
  var $radio = $( 'input[type="radio"]:checked', modal );
928
+ var $input = $('.wd-dr-modal-reason-input textarea');
 
 
929
 
930
  $.ajax({
931
  url: ajaxurl,
932
  type: 'POST',
933
  data: {
934
+ nonce: '<?php echo wp_create_nonce( 'appsero-security-nonce' ); ?>',
935
  action: '<?php echo $this->client->slug; ?>_submit-uninstall-reason',
936
  reason_id: ( 0 === $radio.length ) ? 'none' : $radio.val(),
937
  reason_info: ( 0 !== $input.length ) ? $input.val().trim() : ''
1009
  private function send_tracking_skipped_request() {
1010
  $skipped = get_option( $this->client->slug . '_tracking_skipped' );
1011
 
1012
+ $data = array(
1013
  'hash' => $this->client->hash,
1014
  'previously_skipped' => false,
1015
+ );
1016
 
1017
  if ( $skipped === 'yes' ) {
1018
  $data['previously_skipped'] = true;
1022
 
1023
  $this->client->send_request( $data, 'tracking-skipped' );
1024
  }
1025
+
1026
+ /**
1027
+ * Deactivation modal styles
1028
+ */
1029
+ private function deactivation_modal_styles() {
1030
+ ?>
1031
+ <style type="text/css">
1032
+ .wd-dr-modal {
1033
+ position: fixed;
1034
+ z-index: 99999;
1035
+ top: 0;
1036
+ right: 0;
1037
+ bottom: 0;
1038
+ left: 0;
1039
+ background: rgba(0,0,0,0.5);
1040
+ display: none;
1041
+ box-sizing: border-box;
1042
+ overflow: scroll;
1043
+ }
1044
+ .wd-dr-modal * {
1045
+ box-sizing: border-box;
1046
+ }
1047
+ .wd-dr-modal.modal-active {
1048
+ display: block;
1049
+ }
1050
+ .wd-dr-modal-wrap {
1051
+ max-width: 870px;
1052
+ width: 100%;
1053
+ position: relative;
1054
+ margin: 10% auto;
1055
+ background: #fff;
1056
+ }
1057
+ .wd-dr-modal-header {
1058
+ border-bottom: 1px solid #E8E8E8;
1059
+ padding: 20px 20px 18px 20px;
1060
+ }
1061
+ .wd-dr-modal-header h3 {
1062
+ line-height: 1.8;
1063
+ margin: 0;
1064
+ color: #4A5568;
1065
+ }
1066
+ .wd-dr-modal-body {
1067
+ padding: 5px 20px 20px 20px;
1068
+ }
1069
+ .wd-dr-modal-body .reason-input {
1070
+ margin-top: 5px;
1071
+ margin-left: 20px;
1072
+ }
1073
+ .wd-dr-modal-footer {
1074
+ border-top: 1px solid #E8E8E8;
1075
+ padding: 20px;
1076
+ text-align: right;
1077
+ }
1078
+ .wd-dr-modal-reasons-bottom {
1079
+ margin: 0;
1080
+ }
1081
+ ul.wd-de-reasons {
1082
+ display: flex;
1083
+ margin: 0 -5px 0 -5px;
1084
+ padding: 15px 0 20px 0;
1085
+ }
1086
+ ul.wd-de-reasons.wd-de-others-reasons {
1087
+ padding-top: 0;
1088
+ display: none;
1089
+ }
1090
+ ul.wd-de-reasons li {
1091
+ padding: 0 5px;
1092
+ margin: 0;
1093
+ width: 14.26%;
1094
+ }
1095
+ ul.wd-de-reasons label {
1096
+ position: relative;
1097
+ border: 1px solid #E8E8E8;
1098
+ border-radius: 4px;
1099
+ display: block;
1100
+ text-align: center;
1101
+ height: 100%;
1102
+ padding: 15px 3px 8px 3px;
1103
+ }
1104
+ ul.wd-de-reasons label:after {
1105
+ width: 0;
1106
+ height: 0;
1107
+ border-left: 8px solid transparent;
1108
+ border-right: 8px solid transparent;
1109
+ border-top: 10px solid #3B86FF;
1110
+ position: absolute;
1111
+ left: 50%;
1112
+ top: 100%;
1113
+ margin-left: -8px;
1114
+ }
1115
+ ul.wd-de-reasons label input[type="radio"] {
1116
+ position: absolute;
1117
+ left: 0;
1118
+ right: 0;
1119
+ visibility: hidden;
1120
+ }
1121
+ .wd-de-reason-text {
1122
+ color: #4A5568;
1123
+ font-size: 13px;
1124
+ }
1125
+ .wd-de-reason-icon {
1126
+ margin-bottom: 7px;
1127
+ }
1128
+ ul.wd-de-reasons li.wd-de-reason-selected label {
1129
+ background-color: #3B86FF;
1130
+ border-color: #3B86FF;
1131
+ }
1132
+ li.wd-de-reason-selected .wd-de-reason-icon svg,
1133
+ li.wd-de-reason-selected .wd-de-reason-icon svg g {
1134
+ fill: #fff;
1135
+ }
1136
+ li.wd-de-reason-selected .wd-de-reason-text {
1137
+ color: #fff;
1138
+ }
1139
+ ul.wd-de-reasons li.wd-de-reason-selected label:after {
1140
+ content: "";
1141
+ }
1142
+ .wd-dr-modal-reason-input {
1143
+ margin-bottom: 15px;
1144
+ display: none;
1145
+ }
1146
+ .wd-dr-modal-reason-input textarea {
1147
+ background: #FAFAFA;
1148
+ border: 1px solid #287EB8;
1149
+ border-radius: 4px;
1150
+ width: 100%;
1151
+ height: 100px;
1152
+ color: #524242;
1153
+ font-size: 13px;
1154
+ line-height: 1.4;
1155
+ padding: 11px 15px;
1156
+ resize: none;
1157
+ }
1158
+ .wd-dr-modal-reason-input textarea:focus {
1159
+ outline: 0 none;
1160
+ box-shadow: 0 0 0;
1161
+ }
1162
+ .wd-dr-button-secondary, .wd-dr-button-secondary:hover {
1163
+ border: 1px solid #EBEBEB;
1164
+ border-radius: 3px;
1165
+ font-size: 13px;
1166
+ line-height: 1.5;
1167
+ color: #718096;
1168
+ padding: 5px 12px;
1169
+ cursor: pointer;
1170
+ background-color: transparent;
1171
+ text-decoration: none;
1172
+ }
1173
+ .wd-dr-submit-modal, .wd-dr-submit-modal:hover {
1174
+ border: 1px solid #3B86FF;
1175
+ background-color: #3B86FF;
1176
+ border-radius: 3px;
1177
+ font-size: 13px;
1178
+ line-height: 1.5;
1179
+ color: #fff;
1180
+ padding: 5px 12px;
1181
+ cursor: pointer;
1182
+ margin-left: 4px;
1183
+ }
1184
+ </style>
1185
+ <?php
1186
+ }
1187
+
1188
  }
appsero/src/License.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  namespace Appsero;
3
 
4
  /**
@@ -51,11 +52,11 @@ class License {
51
  protected $schedule_hook;
52
 
53
  /**
54
- * Set value for valid licnese
55
  *
56
- * @var boolean
57
  */
58
- private $is_valid_licnese = null;
59
 
60
  /**
61
  * Initialize the class
@@ -69,6 +70,9 @@ class 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
 
@@ -76,10 +80,38 @@ class License {
76
  $this->run_schedule();
77
  }
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  /**
80
  * Check license
81
  *
82
- * @return boolean
83
  */
84
  public function check( $license_key ) {
85
  $route = 'public/license/' . $this->client->hash . '/check';
@@ -90,7 +122,7 @@ class License {
90
  /**
91
  * Active a license
92
  *
93
- * @return boolean
94
  */
95
  public function activate( $license_key ) {
96
  $route = 'public/license/' . $this->client->hash . '/activate';
@@ -101,7 +133,7 @@ class License {
101
  /**
102
  * Deactivate a license
103
  *
104
- * @return boolean
105
  */
106
  public function deactivate( $license_key ) {
107
  $route = 'public/license/' . $this->client->hash . '/deactivate';
@@ -138,7 +170,7 @@ class License {
138
  if ( empty( $response ) || isset( $response['exception'] )) {
139
  return array(
140
  'success' => false,
141
- 'error' => 'Unknown error occurred, Please try again.'
142
  );
143
  }
144
 
@@ -152,6 +184,20 @@ class License {
152
  return $response;
153
  }
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  /**
156
  * Add settings page for license
157
  *
@@ -201,13 +247,12 @@ class License {
201
  * License menu output
202
  */
203
  public function menu_output() {
204
-
205
  if ( isset( $_POST['submit'] ) ) {
206
  $this->license_form_submit( $_POST );
207
  }
208
 
209
- $license = get_option( $this->option_key, null );
210
- $action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'deactive' : 'active';
211
  $this->licenses_style();
212
  ?>
213
 
@@ -220,11 +265,13 @@ class License {
220
  ?>
221
 
222
  <div class="appsero-license-settings appsero-license-section">
223
- <?php $this->show_license_page_card_header(); ?>
224
 
225
  <div class="appsero-license-details">
226
- <p>Activate <strong><?php echo $this->client->name; ?></strong> by your license key to get professional support and automatic update from your WordPress dashboard.</p>
227
- <form method="post" action="<?php $this->formActionUrl(); ?>" novalidate="novalidate" spellcheck="false">
 
 
228
  <input type="hidden" name="_action" value="<?php echo $action; ?>">
229
  <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( $this->client->name ); ?>">
230
  <div class="license-input-fields">
@@ -233,12 +280,12 @@ class License {
233
  <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"/>
234
  </svg>
235
  <input type="text" value="<?php echo $this->get_input_license_value( $action, $license ); ?>"
236
- placeholder="Enter your license key to activate" name="license_key"
237
  <?php echo ( 'deactive' == $action ) ? 'readonly="readonly"' : ''; ?>
238
  />
239
  </div>
240
  <button type="submit" name="submit" class="<?php echo 'deactive' == $action ? 'deactive-button' : ''; ?>">
241
- <?php echo $action == 'active' ? 'Activate License' : 'Deactivate License' ; ?>
242
  </button>
243
  </div>
244
  </form>
@@ -246,8 +293,7 @@ class License {
246
  <?php
247
  if ( 'deactive' == $action && isset( $license['remaining'] ) ) {
248
  $this->show_active_license_info( $license );
249
- }
250
- ?>
251
  </div>
252
  </div> <!-- /.appsero-license-settings -->
253
 
@@ -261,12 +307,14 @@ class License {
261
  */
262
  public function license_form_submit( $form ) {
263
  if ( ! isset( $form['_nonce'], $form['_action'] ) ) {
264
- $this->error = "Please add all information";
 
265
  return;
266
  }
267
 
268
  if ( ! wp_verify_nonce( $form['_nonce'], $this->client->name ) ) {
269
- $this->error = "You don't have permission to manage license.";
 
270
  return;
271
  }
272
 
@@ -278,6 +326,10 @@ class License {
278
  case 'deactive':
279
  $this->deactive_client_license( $form );
280
  break;
 
 
 
 
281
  }
282
  }
283
 
@@ -285,7 +337,7 @@ class License {
285
  * Check license status on schedule
286
  */
287
  public function check_license_status() {
288
- $license = get_option( $this->option_key, null );
289
 
290
  if ( isset( $license['key'] ) && ! empty( $license['key'] ) ) {
291
  $response = $this->check( $license['key'] );
@@ -311,25 +363,26 @@ class License {
311
  * Check this is a valid license
312
  */
313
  public function is_valid() {
314
- if ( null !== $this->is_valid_licnese ) {
315
- return $this->is_valid_licnese;
316
  }
317
 
318
- $license = get_option( $this->option_key, null );
 
319
  if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
320
- $this->is_valid_licnese = true;
321
  } else {
322
- $this->is_valid_licnese = false;
323
  }
324
 
325
- return $this->is_valid_licnese;
326
  }
327
 
328
  /**
329
  * Check this is a valid license
330
  */
331
  public function is_valid_by( $option, $value ) {
332
- $license = get_option( $this->option_key, null );
333
 
334
  if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
335
  if ( isset( $license[ $option ] ) && $license[ $option ] == $value ) {
@@ -456,6 +509,22 @@ class License {
456
  .single-license-info p.occupied {
457
  color: #E40055;
458
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  </style>
460
  <?php
461
  }
@@ -467,25 +536,24 @@ class License {
467
  ?>
468
  <div class="active-license-info">
469
  <div class="single-license-info">
470
- <h3>Activation Remaining</h3>
471
- <?php if ( empty( $license['activation_limit'] ) ): ?>
472
- <p>Unlimited</p>
473
- <?php else: ?>
474
  <p class="<?php echo $license['remaining'] ? '' : 'occupied'; ?>">
475
- <?php echo $license['remaining']; ?> out of <?php echo $license['activation_limit']; ?>
476
  </p>
477
- <?php endif; ?>
478
  </div>
479
  <div class="single-license-info">
480
- <h3>Expires in</h3>
481
  <?php
482
- if ( $license['recurring'] && false !== $license['expiry_days'] ) {
483
- $occupied = $license['expiry_days'] > 10 ? '' : 'occupied';
484
  echo '<p class="' . $occupied . '">' . $license['expiry_days'] . ' days</p>';
485
  } else {
486
- echo '<p>Never</p>';
487
- }
488
- ?>
489
  </div>
490
  </div>
491
  <?php
@@ -495,27 +563,28 @@ class License {
495
  * Show license settings page notices
496
  */
497
  private function show_license_page_notices() {
498
- if ( ! empty( $this->error ) ) :
499
- ?>
500
  <div class="notice notice-error is-dismissible appsero-license-section">
501
  <p><?php echo $this->error; ?></p>
502
  </div>
503
  <?php
504
- endif;
505
- if ( ! empty( $this->success ) ) :
506
- ?>
 
507
  <div class="notice notice-success is-dismissible appsero-license-section">
508
  <p><?php echo $this->success; ?></p>
509
  </div>
510
  <?php
511
- endif;
512
- echo '<br />';
513
  }
514
 
515
  /**
516
  * Card header
517
  */
518
- private function show_license_page_card_header() {
519
  ?>
520
  <div class="appsero-license-title">
521
  <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">
@@ -523,7 +592,19 @@ class License {
523
  <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"/>
524
  <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"/>
525
  </svg>
526
- <span>Activate License</span>
 
 
 
 
 
 
 
 
 
 
 
 
527
  </div>
528
  <?php
529
  }
@@ -533,15 +614,17 @@ class License {
533
  */
534
  private function active_client_license( $form ) {
535
  if ( empty( $form['license_key'] ) ) {
536
- $this->error = 'The license key field is required.';
 
537
  return;
538
  }
539
 
540
  $license_key = sanitize_text_field( $form['license_key'] );
541
- $response = $this->activate( $license_key );
542
 
543
  if ( ! $response['success'] ) {
544
- $this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
 
545
  return;
546
  }
547
 
@@ -558,17 +641,18 @@ class License {
558
 
559
  update_option( $this->option_key, $data, false );
560
 
561
- $this->success = 'License activated successfully.';
562
  }
563
 
564
  /**
565
  * Deactive client license
566
  */
567
  private function deactive_client_license( $form ) {
568
- $license = get_option( $this->option_key, null );
569
 
570
  if ( empty( $license['key'] ) ) {
571
- $this->error = 'License key not found.';
 
572
  return;
573
  }
574
 
@@ -582,11 +666,28 @@ class License {
582
  update_option( $this->option_key, $data, false );
583
 
584
  if ( ! $response['success'] ) {
585
- $this->error = $response['error'] ? $response['error'] : 'Unknown error occurred.';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
586
  return;
587
  }
588
 
589
- $this->success = 'License deactivated successfully.';
 
 
590
  }
591
 
592
  /**
@@ -674,16 +775,20 @@ class License {
674
  /**
675
  * Form action URL
676
  */
677
- private function formActionUrl() {
678
- echo add_query_arg(
679
- array( 'page' => $_GET['page'] ),
680
  admin_url( basename( $_SERVER['SCRIPT_NAME'] ) )
681
  );
 
 
682
  }
683
 
684
  /**
685
  * Get input license key
 
686
  * @param $action
 
687
  * @return $license
688
  */
689
  private function get_input_license_value( $action, $license ) {
@@ -701,5 +806,4 @@ class License {
701
 
702
  return '';
703
  }
704
-
705
  }
1
  <?php
2
+
3
  namespace Appsero;
4
 
5
  /**
52
  protected $schedule_hook;
53
 
54
  /**
55
+ * Set value for valid license
56
  *
57
+ * @var bool
58
  */
59
+ private $is_valid_license = null;
60
 
61
  /**
62
  * Initialize the class
70
 
71
  $this->schedule_hook = $this->client->slug . '_license_check_event';
72
 
73
+ // Creating WP Ajax Endpoint to refresh license remotely
74
+ add_action( "wp_ajax_appsero_refresh_license_" . $this->client->hash, array( $this, 'refresh_license_api' ) );
75
+
76
  // Run hook to check license status daily
77
  add_action( $this->schedule_hook, array( $this, 'check_license_status' ) );
78
 
80
  $this->run_schedule();
81
  }
82
 
83
+ /**
84
+ * Set the license option key.
85
+ *
86
+ * If someone wants to override the default generated key.
87
+ *
88
+ * @param string $key
89
+ *
90
+ * @since 1.3.0
91
+ *
92
+ * @return License
93
+ */
94
+ public function set_option_key( $key ) {
95
+ $this->option_key = $key;
96
+
97
+ return $this;
98
+ }
99
+
100
+ /**
101
+ * Get the license key
102
+ *
103
+ * @since 1.3.0
104
+ *
105
+ * @return string|null
106
+ */
107
+ public function get_license() {
108
+ return get_option( $this->option_key, null );
109
+ }
110
+
111
  /**
112
  * Check license
113
  *
114
+ * @return bool
115
  */
116
  public function check( $license_key ) {
117
  $route = 'public/license/' . $this->client->hash . '/check';
122
  /**
123
  * Active a license
124
  *
125
+ * @return bool
126
  */
127
  public function activate( $license_key ) {
128
  $route = 'public/license/' . $this->client->hash . '/activate';
133
  /**
134
  * Deactivate a license
135
  *
136
+ * @return bool
137
  */
138
  public function deactivate( $license_key ) {
139
  $route = 'public/license/' . $this->client->hash . '/deactivate';
170
  if ( empty( $response ) || isset( $response['exception'] )) {
171
  return array(
172
  'success' => false,
173
+ 'error' => $this->client->__trans( 'Unknown error occurred, Please try again.' ),
174
  );
175
  }
176
 
184
  return $response;
185
  }
186
 
187
+ /**
188
+ * License Refresh Endpoint
189
+ */
190
+ public function refresh_license_api() {
191
+ $this->check_license_status();
192
+
193
+ return wp_send_json(
194
+ array(
195
+ 'message' => 'License refreshed successfully.'
196
+ ),
197
+ 200
198
+ );
199
+ }
200
+
201
  /**
202
  * Add settings page for license
203
  *
247
  * License menu output
248
  */
249
  public function menu_output() {
 
250
  if ( isset( $_POST['submit'] ) ) {
251
  $this->license_form_submit( $_POST );
252
  }
253
 
254
+ $license = $this->get_license();
255
+ $action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'deactive' : 'active';
256
  $this->licenses_style();
257
  ?>
258
 
265
  ?>
266
 
267
  <div class="appsero-license-settings appsero-license-section">
268
+ <?php $this->show_license_page_card_header( $license ); ?>
269
 
270
  <div class="appsero-license-details">
271
+ <p>
272
+ <?php printf( $this->client->__trans( 'Activate <strong>%s</strong> by your license key to get professional support and automatic update from your WordPress dashboard.' ), $this->client->name ); ?>
273
+ </p>
274
+ <form method="post" action="<?php $this->form_action_url(); ?>" novalidate="novalidate" spellcheck="false">
275
  <input type="hidden" name="_action" value="<?php echo $action; ?>">
276
  <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( $this->client->name ); ?>">
277
  <div class="license-input-fields">
280
  <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"/>
281
  </svg>
282
  <input type="text" value="<?php echo $this->get_input_license_value( $action, $license ); ?>"
283
+ placeholder="<?php echo esc_attr( $this->client->__trans( 'Enter your license key to activate' ) ); ?>" name="license_key"
284
  <?php echo ( 'deactive' == $action ) ? 'readonly="readonly"' : ''; ?>
285
  />
286
  </div>
287
  <button type="submit" name="submit" class="<?php echo 'deactive' == $action ? 'deactive-button' : ''; ?>">
288
+ <?php echo $action == 'active' ? $this->client->__trans( 'Activate License' ) : $this->client->__trans( 'Deactivate License' ); ?>
289
  </button>
290
  </div>
291
  </form>
293
  <?php
294
  if ( 'deactive' == $action && isset( $license['remaining'] ) ) {
295
  $this->show_active_license_info( $license );
296
+ } ?>
 
297
  </div>
298
  </div> <!-- /.appsero-license-settings -->
299
 
307
  */
308
  public function license_form_submit( $form ) {
309
  if ( ! isset( $form['_nonce'], $form['_action'] ) ) {
310
+ $this->error = $this->client->__trans( 'Please add all information' );
311
+
312
  return;
313
  }
314
 
315
  if ( ! wp_verify_nonce( $form['_nonce'], $this->client->name ) ) {
316
+ $this->error = $this->client->__trans( "You don't have permission to manage license." );
317
+
318
  return;
319
  }
320
 
326
  case 'deactive':
327
  $this->deactive_client_license( $form );
328
  break;
329
+
330
+ case 'refresh':
331
+ $this->refresh_client_license( $form );
332
+ break;
333
  }
334
  }
335
 
337
  * Check license status on schedule
338
  */
339
  public function check_license_status() {
340
+ $license = $this->get_license();
341
 
342
  if ( isset( $license['key'] ) && ! empty( $license['key'] ) ) {
343
  $response = $this->check( $license['key'] );
363
  * Check this is a valid license
364
  */
365
  public function is_valid() {
366
+ if ( null !== $this->is_valid_license ) {
367
+ return $this->is_valid_license;
368
  }
369
 
370
+ $license = $this->get_license();
371
+
372
  if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
373
+ $this->is_valid_license = true;
374
  } else {
375
+ $this->is_valid_license = false;
376
  }
377
 
378
+ return $this->is_valid_license;
379
  }
380
 
381
  /**
382
  * Check this is a valid license
383
  */
384
  public function is_valid_by( $option, $value ) {
385
+ $license = $this->get_license();
386
 
387
  if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
388
  if ( isset( $license[ $option ] ) && $license[ $option ] == $value ) {
509
  .single-license-info p.occupied {
510
  color: #E40055;
511
  }
512
+ .appsero-license-right-form {
513
+ margin-left: auto;
514
+ }
515
+ .appsero-license-refresh-button {
516
+ padding: 6px 10px 4px 10px;
517
+ border: 1px solid #0082BF;
518
+ border-radius: 3px;
519
+ margin-left: auto;
520
+ background-color: #0082BF;
521
+ color: #fff;
522
+ cursor: pointer;
523
+ }
524
+ .appsero-license-refresh-button .dashicons {
525
+ color: #fff;
526
+ margin-left: 0;
527
+ }
528
  </style>
529
  <?php
530
  }
536
  ?>
537
  <div class="active-license-info">
538
  <div class="single-license-info">
539
+ <h3><?php $this->client->_etrans( 'Activations Remaining' ); ?></h3>
540
+ <?php if ( empty( $license['activation_limit'] ) ) { ?>
541
+ <p><?php $this->client->_etrans( 'Unlimited' ); ?></p>
542
+ <?php } else { ?>
543
  <p class="<?php echo $license['remaining'] ? '' : 'occupied'; ?>">
544
+ <?php printf( $this->client->__trans( '%1$d out of %2$d' ), $license['remaining'], $license['activation_limit'] ); ?>
545
  </p>
546
+ <?php } ?>
547
  </div>
548
  <div class="single-license-info">
549
+ <h3><?php $this->client->_etrans( 'Expires in' ); ?></h3>
550
  <?php
551
+ if ( false !== $license['expiry_days'] ) {
552
+ $occupied = $license['expiry_days'] > 21 ? '' : 'occupied';
553
  echo '<p class="' . $occupied . '">' . $license['expiry_days'] . ' days</p>';
554
  } else {
555
+ echo '<p>' . $this->client->__trans( 'Never' ) . '</p>';
556
+ } ?>
 
557
  </div>
558
  </div>
559
  <?php
563
  * Show license settings page notices
564
  */
565
  private function show_license_page_notices() {
566
+ if ( ! empty( $this->error ) ) {
567
+ ?>
568
  <div class="notice notice-error is-dismissible appsero-license-section">
569
  <p><?php echo $this->error; ?></p>
570
  </div>
571
  <?php
572
+ }
573
+
574
+ if ( ! empty( $this->success ) ) {
575
+ ?>
576
  <div class="notice notice-success is-dismissible appsero-license-section">
577
  <p><?php echo $this->success; ?></p>
578
  </div>
579
  <?php
580
+ }
581
+ echo '<br />';
582
  }
583
 
584
  /**
585
  * Card header
586
  */
587
+ private function show_license_page_card_header( $license ) {
588
  ?>
589
  <div class="appsero-license-title">
590
  <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">
592
  <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"/>
593
  <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"/>
594
  </svg>
595
+ <span><?php echo $this->client->__trans( 'Activate License' ); ?></span>
596
+
597
+ <?php if ( $license && $license['key'] ) : ?>
598
+ <form method="post" class="appsero-license-right-form" action="<?php $this->form_action_url(); ?>" novalidate="novalidate" spellcheck="false">
599
+ <input type="hidden" name="_action" value="refresh">
600
+ <input type="hidden" name="_nonce" value="<?php echo wp_create_nonce( $this->client->name ); ?>">
601
+ <button type="submit" name="submit" class="appsero-license-refresh-button">
602
+ <span class="dashicons dashicons-update"></span>
603
+ <?php echo $this->client->__trans( 'Refresh License' ); ?>
604
+ </button>
605
+ </form>
606
+ <?php endif; ?>
607
+
608
  </div>
609
  <?php
610
  }
614
  */
615
  private function active_client_license( $form ) {
616
  if ( empty( $form['license_key'] ) ) {
617
+ $this->error = $this->client->__trans( 'The license key field is required.' );
618
+
619
  return;
620
  }
621
 
622
  $license_key = sanitize_text_field( $form['license_key'] );
623
+ $response = $this->activate( $license_key );
624
 
625
  if ( ! $response['success'] ) {
626
+ $this->error = $response['error'] ? $response['error'] : $this->client->__trans( 'Unknown error occurred.' );
627
+
628
  return;
629
  }
630
 
641
 
642
  update_option( $this->option_key, $data, false );
643
 
644
+ $this->success = $this->client->__trans( 'License activated successfully.' );
645
  }
646
 
647
  /**
648
  * Deactive client license
649
  */
650
  private function deactive_client_license( $form ) {
651
+ $license = $this->get_license();
652
 
653
  if ( empty( $license['key'] ) ) {
654
+ $this->error = $this->client->__trans( 'License key not found.' );
655
+
656
  return;
657
  }
658
 
666
  update_option( $this->option_key, $data, false );
667
 
668
  if ( ! $response['success'] ) {
669
+ $this->error = $response['error'] ? $response['error'] : $this->client->__trans( 'Unknown error occurred.' );
670
+
671
+ return;
672
+ }
673
+
674
+ $this->success = $this->client->__trans( 'License deactivated successfully.' );
675
+ }
676
+
677
+ /**
678
+ * Refresh Client License
679
+ */
680
+ private function refresh_client_license( $form = null ) {
681
+ $license = $this->get_license();
682
+
683
+ if( !$license || ! isset( $license['key'] ) || empty( $license['key'] ) ) {
684
+ $this->error = $this->client->__trans( "License key not found" );
685
  return;
686
  }
687
 
688
+ $this->check_license_status();
689
+
690
+ $this->success = $this->client->__trans( 'License refreshed successfully.' );
691
  }
692
 
693
  /**
775
  /**
776
  * Form action URL
777
  */
778
+ private function form_action_url() {
779
+ $url = add_query_arg(
780
+ $_GET,
781
  admin_url( basename( $_SERVER['SCRIPT_NAME'] ) )
782
  );
783
+
784
+ echo apply_filters( 'appsero_client_license_form_action', $url );
785
  }
786
 
787
  /**
788
  * Get input license key
789
+ *
790
  * @param $action
791
+ *
792
  * @return $license
793
  */
794
  private function get_input_license_value( $action, $license ) {
806
 
807
  return '';
808
  }
 
809
  }
appsero/src/Updater.php CHANGED
@@ -70,18 +70,18 @@ class Updater {
70
  return $transient_data;
71
  }
72
 
73
- $version_info = $this->get_cached_version_info();
74
-
75
- if ( false === $version_info ) {
76
- $version_info = $this->get_project_latest_version();
77
- $this->set_cached_version_info( $version_info );
78
- }
79
 
80
  if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
81
 
 
 
 
82
  if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) {
83
- unset( $version_info->sections );
84
  $transient_data->response[ $this->client->basename ] = $version_info;
 
 
 
85
  }
86
 
87
  $transient_data->last_checked = time();
@@ -97,6 +97,12 @@ class Updater {
97
  * @return Object or Boolean
98
  */
99
  private function get_cached_version_info() {
 
 
 
 
 
 
100
 
101
  $value = get_transient( $this->cache_key );
102
 
@@ -137,8 +143,7 @@ class Updater {
137
  */
138
  private function get_project_latest_version() {
139
 
140
- $license_option_key = 'appsero_' . md5( $this->client->slug ) . '_manage_license';
141
- $license = get_option( $license_option_key, null );
142
 
143
  $params = array(
144
  'version' => $this->client->project_version,
@@ -196,14 +201,7 @@ class Updater {
196
  return $data;
197
  }
198
 
199
- $version_info = $this->get_cached_version_info();
200
-
201
- if ( false === $version_info ) {
202
- $version_info = $this->get_project_latest_version();
203
- $this->set_cached_version_info( $version_info );
204
- }
205
-
206
- return $version_info;
207
  }
208
 
209
  /**
@@ -224,17 +222,16 @@ class Updater {
224
  return $transient_data;
225
  }
226
 
227
- $version_info = $this->get_cached_version_info();
228
-
229
- if ( false === $version_info ) {
230
- $version_info = $this->get_project_latest_version();
231
- $this->set_cached_version_info( $version_info );
232
- }
233
 
234
  if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
235
 
 
236
  if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) {
237
  $transient_data->response[ $this->client->slug ] = (array) $version_info;
 
 
 
238
  }
239
 
240
  $transient_data->last_checked = time();
@@ -244,4 +241,18 @@ class Updater {
244
  return $transient_data;
245
  }
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
70
  return $transient_data;
71
  }
72
 
73
+ $version_info = $this->get_version_info();
 
 
 
 
 
74
 
75
  if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
76
 
77
+ unset( $version_info->sections );
78
+
79
+ // If new version available then set to `response`
80
  if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) {
 
81
  $transient_data->response[ $this->client->basename ] = $version_info;
82
+ } else {
83
+ // If new version is not available then set to `no_update`
84
+ $transient_data->no_update[ $this->client->basename ] = $version_info;
85
  }
86
 
87
  $transient_data->last_checked = time();
97
  * @return Object or Boolean
98
  */
99
  private function get_cached_version_info() {
100
+ global $pagenow;
101
+
102
+ // If updater page then fetch from API now
103
+ if ( 'update-core.php' == $pagenow ) {
104
+ return false; // Force to fetch data
105
+ }
106
 
107
  $value = get_transient( $this->cache_key );
108
 
143
  */
144
  private function get_project_latest_version() {
145
 
146
+ $license = $this->client->license()->get_license();
 
147
 
148
  $params = array(
149
  'version' => $this->client->project_version,
201
  return $data;
202
  }
203
 
204
+ return $this->get_version_info();
 
 
 
 
 
 
 
205
  }
206
 
207
  /**
222
  return $transient_data;
223
  }
224
 
225
+ $version_info = $this->get_version_info();
 
 
 
 
 
226
 
227
  if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
228
 
229
+ // If new version available then set to `response`
230
  if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) {
231
  $transient_data->response[ $this->client->slug ] = (array) $version_info;
232
+ } else {
233
+ // If new version is not available then set to `no_update`
234
+ $transient_data->no_update[ $this->client->slug ] = (array) $version_info;
235
  }
236
 
237
  $transient_data->last_checked = time();
241
  return $transient_data;
242
  }
243
 
244
+ /**
245
+ * Get version information
246
+ */
247
+ private function get_version_info() {
248
+ $version_info = $this->get_cached_version_info();
249
+
250
+ if ( false === $version_info ) {
251
+ $version_info = $this->get_project_latest_version();
252
+ $this->set_cached_version_info( $version_info );
253
+ }
254
+
255
+ return $version_info;
256
+ }
257
+
258
  }
wpvr.php CHANGED
@@ -16,7 +16,7 @@
16
  * Plugin Name: WP VR
17
  * Plugin URI: https://rextheme.com/wpvr/
18
  * Description: WP VR - 360 Panorama and virtual tour creator for WordPress is a customized panaroma & virtual builder tool for WordPress Website.
19
- * Version: 8.2.5
20
  * Author: Rextheme
21
  * Author URI: http://rextheme.com/
22
  * License: GPL-2.0+
@@ -37,7 +37,7 @@ require plugin_dir_path(__FILE__) . 'elementor/elementor.php';
37
  * Start at version 1.0.0 and use SemVer - https://semver.org
38
  * Rename this for your plugin and update it as you release new versions.
39
  */
40
- define('WPVR_VERSION', '8.2.5');
41
  define('WPVR_FILE', __FILE__);
42
  define("WPVR_PLUGIN_DIR_URL", plugin_dir_url(__FILE__));
43
  define("WPVR_PLUGIN_DIR_PATH", plugin_dir_path(__FILE__));
@@ -2484,4 +2484,4 @@ function general_admin_notice(){
2484
  }
2485
 
2486
  }
2487
- add_action('admin_notices', 'general_admin_notice');
16
  * Plugin Name: WP VR
17
  * Plugin URI: https://rextheme.com/wpvr/
18
  * Description: WP VR - 360 Panorama and virtual tour creator for WordPress is a customized panaroma & virtual builder tool for WordPress Website.
19
+ * Version: 8.2.6
20
  * Author: Rextheme
21
  * Author URI: http://rextheme.com/
22
  * License: GPL-2.0+
37
  * Start at version 1.0.0 and use SemVer - https://semver.org
38
  * Rename this for your plugin and update it as you release new versions.
39
  */
40
+ define('WPVR_VERSION', '8.2.6');
41
  define('WPVR_FILE', __FILE__);
42
  define("WPVR_PLUGIN_DIR_URL", plugin_dir_url(__FILE__));
43
  define("WPVR_PLUGIN_DIR_PATH", plugin_dir_path(__FILE__));
2484
  }
2485
 
2486
  }
2487
+ // add_action('admin_notices', 'general_admin_notice');