CTX Feed – WooCommerce Product Feed Manager Plugin - Version 3.6.19

Version Description

(2020-08-17) = * Tweak: WordPress 5.5 compatibility checked. * Tweak: API Library updated.

Download this release

Release Info

Developer wahid0003
Plugin Icon 128x128 CTX Feed – WooCommerce Product Feed Manager Plugin
Version 3.6.19
Comparing to
See all releases

Code changes from version 3.6.18 to 3.6.19

README.txt CHANGED
@@ -1,11 +1,11 @@
1
- === WooCommerce Product Feed for Google, Bing, eBay and Many More ===
2
  Contributors: wahid0003, webappick, mhamudul_hk, shuvo586
3
  Donate link: https://webappick.com
4
  Tags:product feed,woocommerce product feed,google shopping feed,google shopping, XML CSV TXT product feed
5
  Requires at least: 3.6
6
- Tested Up To: 5.4
7
  Requires PHP: 5.6
8
- Stable tag: 3.6.18
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -308,6 +308,10 @@ Using pro version:
308
 
309
  == Changelog ==
310
 
 
 
 
 
311
  = 3.6.18 (2020-08-15) =
312
  * Fix: Tax Class & Tax Status Product attribute added.
313
 
1
+ === WooCommerce Product Feed for Google, Bing, eBay and Many More ===
2
  Contributors: wahid0003, webappick, mhamudul_hk, shuvo586
3
  Donate link: https://webappick.com
4
  Tags:product feed,woocommerce product feed,google shopping feed,google shopping, XML CSV TXT product feed
5
  Requires at least: 3.6
6
+ Tested Up To: 5.5
7
  Requires PHP: 5.6
8
+ Stable tag: 3.6.19
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
308
 
309
  == Changelog ==
310
 
311
+ = 3.6.19 (2020-08-17) =
312
+ * Tweak: WordPress 5.5 compatibility checked.
313
+ * Tweak: API Library updated.
314
+
315
  = 3.6.18 (2020-08-15) =
316
  * Fix: Tax Class & Tax Status Product attribute added.
317
 
libs/WebAppick/AppServices/Client.php CHANGED
@@ -23,67 +23,73 @@ if ( ! defined( 'ABSPATH' ) ) {
23
  class Client {
24
 
25
  /**
26
- * The client version
 
27
  * @var string
28
  */
29
- protected $clientVersion = '1.0.0';
30
 
31
  /**
32
- * API EndPoint
 
33
  * @var string
34
  */
35
  protected $API_EndPoint = 'https://track.webappick.com/api/';
36
 
37
  /**
38
- * API Version
 
39
  * @var string
40
  */
41
  protected $apiVersion = 'v1';
42
 
43
  /**
44
- * Hash identifier of the Plugin/Theme
 
45
  * @var string
46
  */
47
  protected $hash;
48
 
49
  /**
50
- * Name of the Plugin/Theme
 
51
  * @var string
52
  */
53
  protected $name;
54
 
55
  /**
56
- * The Plugin/Theme file path
57
- * @example .../wp-content/Plugin/test-slug/test-slug.php
58
  *
59
  * @var string
60
  */
61
  protected $file;
62
 
63
  /**
64
- * Main Plugin/Theme file
65
- * @example test-slug/test-slug.php
 
66
  * @var string
67
  */
68
  protected $basename;
69
 
70
  /**
71
- * Slug of the Plugin/Theme
72
- * @example test-slug
73
  *
74
  * @var string
75
  */
76
  protected $slug;
77
 
78
  /**
79
- * The project version
80
  *
81
  * @var string
82
  */
83
  protected $project_version;
84
 
85
  /**
86
- * The project type
87
  *
88
  * @var string
89
  */
@@ -91,82 +97,155 @@ class Client {
91
 
92
  /**
93
  * Store Product (unique) id for current Product
94
- * Required by WooCommerce API Manager > 2.0
 
95
  * @var bool|int
96
  */
97
- protected $ProjectId;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
  /**
100
- * Initialize the class
101
  *
102
- * @param string $hash hash of the Plugin/Theme.
103
- * @param string $name readable name of the Plugin/Theme.
104
- * @param string $file main Plugin/Theme file path.
105
- * @param string $ProjectId Store Product id for pro product.
106
  */
107
- public function __construct( $hash, $name, $file, $ProjectId = null ) {
 
 
 
 
 
 
 
 
 
 
 
 
108
  $this->hash = $hash;
109
  $this->name = $name;
110
  $this->file = $file;
111
- $this->ProjectId = ! empty( $ProjectId ) ? (int) $ProjectId : false;
112
  $this->set_basename_and_slug();
113
  }
114
 
115
  /**
116
- * Initialize insights class
117
  *
118
  * @return Insights
119
  */
120
  public function insights() {
 
 
 
121
 
122
  if ( ! class_exists( __NAMESPACE__ . '\Insights' ) ) {
123
  require_once __DIR__ . '/Insights.php';
124
  }
 
125
 
126
- return new Insights( $this );
127
  }
128
 
129
  /**
130
- * Initialize Promotions class
 
131
  * @return Promotions
132
  */
133
  public function promotions() {
 
 
 
134
  if ( ! class_exists( __NAMESPACE__ . '\Promotions' ) ) {
135
  require_once __DIR__ . '/Promotions.php';
136
  }
137
- return new Promotions( $this );
 
 
138
  }
139
 
140
  /**
141
- * Initialize Plugin/Theme updater
142
- * @param License $license The license class.
143
- * @return Updater
144
  */
145
- public function updater( License $license ) {
146
- if ( ! class_exists( __NAMESPACE__ . '\Updater') ) {
147
- require_once __DIR__ . '/Updater.php';
148
  }
149
- return new Updater( $this, $license );
 
 
 
 
 
 
150
  }
151
 
152
  /**
153
- * Initialize license checker
154
  *
155
- * @return License
 
 
156
  */
157
- public function license() {
 
 
 
158
 
159
- if ( ! class_exists( __NAMESPACE__ . '\License') ) {
160
- require_once __DIR__ . '/License.php';
 
 
 
 
 
 
 
 
 
 
 
 
161
  }
162
 
163
- return new License( $this );
 
 
 
 
 
164
  }
165
 
166
  /**
167
- * API Endpoint
168
  *
169
- * @param string $route route to send the request.
170
  *
171
  * @return string
172
  */
@@ -203,7 +282,7 @@ class Client {
203
  }
204
 
205
  /**
206
- * Set project basename, slug and version
207
  *
208
  * @return void
209
  */
@@ -229,7 +308,8 @@ class Client {
229
  }
230
 
231
  /**
232
- * Client UserAgent String
 
233
  * @return string
234
  */
235
  private function __user_agent() {
@@ -237,7 +317,7 @@ class Client {
237
  }
238
 
239
  /**
240
- * Send request to remote endpoint
241
  *
242
  * @param array $params Parameters/Data that being sent.
243
  * @param string $route Route to send the request to.
@@ -253,7 +333,8 @@ class Client {
253
  );
254
 
255
  /**
256
- * before request to api server
 
257
  * @since 1.0.2
258
  * @param array $params
259
  * @param string $route
@@ -264,7 +345,7 @@ class Client {
264
  do_action( $this->getSlug() . '_before_request', $params, $route, $headers, $this->clientVersion, $url );
265
  if ( ! empty( $route ) ) {
266
  /**
267
- * before request to api server to route
268
  * @since 1.0.2
269
  * @param array $params
270
  * @param string $route
@@ -276,7 +357,8 @@ class Client {
276
  }
277
  /**
278
  * Request Blocking mode.
279
- * Set it to true for debugging the response with after request action
 
280
  * @since 1.0.2
281
  * @param bool $blocking
282
  */
@@ -295,7 +377,8 @@ class Client {
295
  ]
296
  );
297
  /**
298
- * after request to api server
 
299
  * @since 1.0.2
300
  * @param array $response
301
  * @param string $route
@@ -303,7 +386,8 @@ class Client {
303
  do_action( $this->getSlug() . '_after_request', $response, $route );
304
  if ( ! empty( $route ) ) {
305
  /**
306
- * after request to api server to route
 
307
  * @since 1.0.2
308
  * @param array $response
309
  * @param string $route
@@ -316,7 +400,8 @@ class Client {
316
  //===> Getters.
317
 
318
  /**
319
- * Get Version of this client
 
320
  * @return string
321
  */
322
  public function getClientVersion() {
@@ -324,7 +409,8 @@ class Client {
324
  }
325
 
326
  /**
327
- * Get API URI
 
328
  * @return string
329
  */
330
  public function getApi() {
@@ -332,7 +418,8 @@ class Client {
332
  }
333
 
334
  /**
335
- * Get API Version using by this client
 
336
  * @return string
337
  */
338
  public function getApiVersion() {
@@ -340,7 +427,8 @@ class Client {
340
  }
341
 
342
  /**
343
- * Get Hash of current Plugin/Theme
 
344
  * @return string
345
  */
346
  public function getHash() {
@@ -348,7 +436,8 @@ class Client {
348
  }
349
 
350
  /**
351
- * Get Plugin/Theme Name
 
352
  * @return string
353
  */
354
  public function getName() {
@@ -356,15 +445,17 @@ class Client {
356
  }
357
 
358
  /**
359
- * Store Product ID
 
360
  * @return bool|int
361
  */
362
- public function getProjectId() {
363
- return $this->ProjectId;
364
  }
365
 
366
  /**
367
- * Get Plugin/Theme file
 
368
  * @return string
369
  */
370
  public function getFile() {
@@ -372,7 +463,8 @@ class Client {
372
  }
373
 
374
  /**
375
- * Get Plugin/Theme base name
 
376
  * @return string
377
  */
378
  public function getBasename() {
@@ -380,7 +472,8 @@ class Client {
380
  }
381
 
382
  /**
383
- * Get Plugin/Theme Slug
 
384
  * @return string
385
  */
386
  public function getSlug() {
@@ -388,7 +481,8 @@ class Client {
388
  }
389
 
390
  /**
391
- * Get Plugin/Theme Project Version
 
392
  * @return string
393
  */
394
  public function getProjectVersion() {
@@ -396,7 +490,8 @@ class Client {
396
  }
397
 
398
  /**
399
- * Get Project Type Plugin/Theme
 
400
  * @return string
401
  */
402
  public function getType() {
23
  class Client {
24
 
25
  /**
26
+ * The client version.
27
+ *
28
  * @var string
29
  */
30
+ protected $clientVersion = '1.0.3';
31
 
32
  /**
33
+ * API EndPoint.
34
+ *
35
  * @var string
36
  */
37
  protected $API_EndPoint = 'https://track.webappick.com/api/';
38
 
39
  /**
40
+ * API Version.
41
+ *
42
  * @var string
43
  */
44
  protected $apiVersion = 'v1';
45
 
46
  /**
47
+ * Hash identifier of the Plugin/Theme.
48
+ *
49
  * @var string
50
  */
51
  protected $hash;
52
 
53
  /**
54
+ * Name of the Plugin/Theme.
55
+ *
56
  * @var string
57
  */
58
  protected $name;
59
 
60
  /**
61
+ * The Plugin/Theme file path.
62
+ * Example .../wp-content/Plugin/test-slug/test-slug.php.
63
  *
64
  * @var string
65
  */
66
  protected $file;
67
 
68
  /**
69
+ * Main Plugin/Theme file.
70
+ * Example: test-slug/test-slug.php.
71
+ *
72
  * @var string
73
  */
74
  protected $basename;
75
 
76
  /**
77
+ * Slug of the Plugin/Theme.
78
+ * Example: test-slug.
79
  *
80
  * @var string
81
  */
82
  protected $slug;
83
 
84
  /**
85
+ * The project version.
86
  *
87
  * @var string
88
  */
89
  protected $project_version;
90
 
91
  /**
92
+ * The project type.
93
  *
94
  * @var string
95
  */
97
 
98
  /**
99
  * Store Product (unique) id for current Product
100
+ * Required by WooCommerce API Manager > 2.0.
101
+ *
102
  * @var bool|int
103
  */
104
+ protected $product_id;
105
+
106
+ /**
107
+ * Instance of Insights class.
108
+ *
109
+ * @since 1.0.3
110
+ * @var Insights
111
+ */
112
+ private $insights;
113
+
114
+ /**
115
+ * Instance of Promotions class.
116
+ *
117
+ * @since 1.0.3
118
+ * @var Promotions
119
+ */
120
+ private $promotions;
121
+
122
+ /**
123
+ * Instance of License class.
124
+ *
125
+ * @since 1.0.3
126
+ * @var License
127
+ */
128
+ private $license;
129
 
130
  /**
131
+ * Instance of Updater class.
132
  *
133
+ * @since 1.0.3
134
+ * @var Updater
 
 
135
  */
136
+ private $updater;
137
+
138
+ /**
139
+ * Initialize the class.
140
+ *
141
+ * @param string $hash hash of the Plugin/Theme.
142
+ * @param string $name readable name of the Plugin/Theme.
143
+ * @param string $file main Plugin/Theme file path.
144
+ * @param string $product_id Store Product id for pro product.
145
+ * If null license page will show field for product id input.
146
+ * @return void
147
+ */
148
+ public function __construct( $hash, $name, $file, $product_id = null ) {
149
  $this->hash = $hash;
150
  $this->name = $name;
151
  $this->file = $file;
152
+ $this->product_id = ! empty( $product_id ) ? (int) $product_id : false;
153
  $this->set_basename_and_slug();
154
  }
155
 
156
  /**
157
+ * Initialize insights class.
158
  *
159
  * @return Insights
160
  */
161
  public function insights() {
162
+ if ( ! is_null( $this->insights ) ) {
163
+ return $this->insights;
164
+ }
165
 
166
  if ( ! class_exists( __NAMESPACE__ . '\Insights' ) ) {
167
  require_once __DIR__ . '/Insights.php';
168
  }
169
+ $this->insights = new Insights( $this );
170
 
171
+ return $this->insights;
172
  }
173
 
174
  /**
175
+ * Initialize Promotions class.
176
+ *
177
  * @return Promotions
178
  */
179
  public function promotions() {
180
+ if ( ! is_null( $this->promotions ) ) {
181
+ return $this->promotions;
182
+ }
183
  if ( ! class_exists( __NAMESPACE__ . '\Promotions' ) ) {
184
  require_once __DIR__ . '/Promotions.php';
185
  }
186
+ $this->promotions = new Promotions( $this );
187
+
188
+ return $this->promotions;
189
  }
190
 
191
  /**
192
+ * Initialize license checker.
193
+ *
194
+ * @return License
195
  */
196
+ public function license() {
197
+ if ( ! is_null( $this->license ) ) {
198
+ return $this->license;
199
  }
200
+
201
+ if ( ! class_exists( __NAMESPACE__ . '\License') ) {
202
+ require_once __DIR__ . '/License.php';
203
+ }
204
+ $this->license = new License( $this );
205
+
206
+ return $this->license;
207
  }
208
 
209
  /**
210
+ * Initialize Plugin/Theme updater.
211
  *
212
+ * @since 1.0.3 $license param is removed.
213
+ *
214
+ * @return Updater
215
  */
216
+ public function updater() {
217
+ if ( ! is_null( $this->updater ) ) {
218
+ return $this->updater;
219
+ }
220
 
221
+ // check for deprecated argument.
222
+ if ( func_num_args() > 0 ) {
223
+ _deprecated_argument( __METHOD__, '1.0.3', '$license param is deprecated.' );
224
+ }
225
+
226
+ // check if license instance is created.
227
+ if ( is_null( $this->license ) ) {
228
+ _doing_it_wrong( __METHOD__, esc_html(
229
+ sprintf(
230
+ 'Updater needs License instance to be created before it. Please call %s first.',
231
+ __CLASS__ . '::license'
232
+ )
233
+ ), '1.0.3' );
234
+ return;
235
  }
236
 
237
+ if ( ! class_exists( __NAMESPACE__ . '\Updater') ) {
238
+ require_once __DIR__ . '/Updater.php';
239
+ }
240
+ $this->updater = new Updater( $this, $this->license );
241
+
242
+ return $this->updater;
243
  }
244
 
245
  /**
246
+ * API Endpoint.
247
  *
248
+ * @param string $route route to send the request.
249
  *
250
  * @return string
251
  */
282
  }
283
 
284
  /**
285
+ * Set project basename, slug and version.
286
  *
287
  * @return void
288
  */
308
  }
309
 
310
  /**
311
+ * Client UserAgent String.
312
+ *
313
  * @return string
314
  */
315
  private function __user_agent() {
317
  }
318
 
319
  /**
320
+ * Send request to remote endpoint.
321
  *
322
  * @param array $params Parameters/Data that being sent.
323
  * @param string $route Route to send the request to.
333
  );
334
 
335
  /**
336
+ * before request to api server.
337
+ *
338
  * @since 1.0.2
339
  * @param array $params
340
  * @param string $route
345
  do_action( $this->getSlug() . '_before_request', $params, $route, $headers, $this->clientVersion, $url );
346
  if ( ! empty( $route ) ) {
347
  /**
348
+ * before request to api server to route.
349
  * @since 1.0.2
350
  * @param array $params
351
  * @param string $route
357
  }
358
  /**
359
  * Request Blocking mode.
360
+ * Set it to true for debugging the response with after request action.
361
+ *
362
  * @since 1.0.2
363
  * @param bool $blocking
364
  */
377
  ]
378
  );
379
  /**
380
+ * After request to api server.
381
+ *
382
  * @since 1.0.2
383
  * @param array $response
384
  * @param string $route
386
  do_action( $this->getSlug() . '_after_request', $response, $route );
387
  if ( ! empty( $route ) ) {
388
  /**
389
+ * After request to api server to route.
390
+ *
391
  * @since 1.0.2
392
  * @param array $response
393
  * @param string $route
400
  //===> Getters.
401
 
402
  /**
403
+ * Get Version of this client.
404
+ *
405
  * @return string
406
  */
407
  public function getClientVersion() {
409
  }
410
 
411
  /**
412
+ * Get API URI.
413
+ *
414
  * @return string
415
  */
416
  public function getApi() {
418
  }
419
 
420
  /**
421
+ * Get API Version using by this client.
422
+ *
423
  * @return string
424
  */
425
  public function getApiVersion() {
427
  }
428
 
429
  /**
430
+ * Get Hash of current Plugin/Theme.
431
+ *
432
  * @return string
433
  */
434
  public function getHash() {
436
  }
437
 
438
  /**
439
+ * Get Plugin/Theme Name.
440
+ *
441
  * @return string
442
  */
443
  public function getName() {
445
  }
446
 
447
  /**
448
+ * Store Product ID.
449
+ *
450
  * @return bool|int
451
  */
452
+ public function getProductId() {
453
+ return $this->product_id;
454
  }
455
 
456
  /**
457
+ * Get Plugin/Theme file.
458
+ *
459
  * @return string
460
  */
461
  public function getFile() {
463
  }
464
 
465
  /**
466
+ * Get Plugin/Theme base name.
467
+ *
468
  * @return string
469
  */
470
  public function getBasename() {
472
  }
473
 
474
  /**
475
+ * Get Plugin/Theme Slug.
476
+ *
477
  * @return string
478
  */
479
  public function getSlug() {
481
  }
482
 
483
  /**
484
+ * Get Plugin/Theme Project Version.
485
+ *
486
  * @return string
487
  */
488
  public function getProjectVersion() {
490
  }
491
 
492
  /**
493
+ * Get Project Type Plugin/Theme.
494
+ *
495
  * @return string
496
  */
497
  public function getType() {
libs/WebAppick/AppServices/Insights.php CHANGED
@@ -400,7 +400,7 @@ class Insights {
400
  *
401
  * @return boolean
402
  */
403
- private function __is_local_server() {
404
  // phpcs:disable
405
  return apply_filters( 'WebAppick_is_local', in_array( $_SERVER['REMOTE_ADDR'], [ '127.0.0.1', '::1' ] ) );
406
  // phpcs:enable
@@ -436,7 +436,7 @@ class Insights {
436
  if ( $this->__notice_dismissed() ) {
437
  return;
438
  }
439
-
440
  if ( $this->is_tracking_allowed() ) {
441
  return;
442
  }
@@ -507,7 +507,6 @@ class Insights {
507
  * @return void
508
  */
509
  public function handle_optIn_optOut() {
510
-
511
  if ( isset( $_REQUEST['_wpnonce'] ) && ( isset( $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) || isset( $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) ) ) {
512
  check_admin_referer( $this->client->getSlug() . '_insight_action' );
513
  if ( isset( $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) && 'true' == $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) {
@@ -516,7 +515,7 @@ class Insights {
516
  exit;
517
  }
518
  if ( isset( $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) && 'true' == $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) {
519
- $this->optOut();
520
  wp_safe_redirect( remove_query_arg( $this->client->getSlug() . '_tracker_optOut' ) );
521
  exit;
522
  }
400
  *
401
  * @return boolean
402
  */
403
+ public function __is_local_server() {
404
  // phpcs:disable
405
  return apply_filters( 'WebAppick_is_local', in_array( $_SERVER['REMOTE_ADDR'], [ '127.0.0.1', '::1' ] ) );
406
  // phpcs:enable
436
  if ( $this->__notice_dismissed() ) {
437
  return;
438
  }
439
+
440
  if ( $this->is_tracking_allowed() ) {
441
  return;
442
  }
507
  * @return void
508
  */
509
  public function handle_optIn_optOut() {
 
510
  if ( isset( $_REQUEST['_wpnonce'] ) && ( isset( $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) || isset( $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) ) ) {
511
  check_admin_referer( $this->client->getSlug() . '_insight_action' );
512
  if ( isset( $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) && 'true' == $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) {
515
  exit;
516
  }
517
  if ( isset( $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) && 'true' == $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) {
518
+ $this->optOut();
519
  wp_safe_redirect( remove_query_arg( $this->client->getSlug() . '_tracker_optOut' ) );
520
  exit;
521
  }
libs/WebAppick/AppServices/License.php CHANGED
@@ -10,6 +10,8 @@
10
 
11
  namespace WebAppick\AppServices;
12
 
 
 
13
  if ( ! defined( 'ABSPATH' ) ) {
14
  die();
15
  }
@@ -20,64 +22,81 @@ if ( ! defined( 'ABSPATH' ) ) {
20
  class License {
21
 
22
  /**
23
- * WebAppick\AppServices\Client
24
  *
25
  * @var Client
26
  */
27
  protected $client;
28
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  /**
30
  * Flag for checking if the init method is already called.
 
31
  * @var bool
32
  */
33
  private $didInit = false;
34
 
35
  /**
36
- * Arguments of create menu
37
  *
38
  * @var array
39
  */
40
  protected $menu_args;
41
 
42
  /**
43
- * `option_name` of `wp_options` table
44
  *
45
  * @var string
46
  */
47
  protected $option_key;
48
 
49
  /**
50
- * Error message of HTTP request
51
  *
52
  * @var string
53
  */
54
  protected $error;
55
 
56
  /**
57
- * Success message on form submit
58
  *
59
  * @var string
60
  */
61
  protected $success;
62
 
63
  /**
64
- * Corn schedule hook name
65
  *
66
  * @var string
67
  */
68
  protected $schedule_hook;
69
 
70
  /**
71
- * Set value for valid license
72
  *
73
  * @var boolean
74
  */
75
  private $is_valid_license = null;
 
76
  /**
77
- * The license data
 
78
  * @var array {
79
  * Optional. License Data.
80
  * @type string $key The License Key
 
 
81
  * @type string $status Activation Status
82
  * @type int $remaining Remaining Activation
83
  * @type int $activation_limit Number of activation allowed for the license key
@@ -87,19 +106,21 @@ class License {
87
  protected $license;
88
 
89
  /**
90
- * Current User Permission for managing License
 
91
  * @var bool
92
  */
93
  protected $currentUserCanManage = false;
94
 
95
  /**
96
- * Is Current Page is the license manage page
 
97
  * @var bool
98
  */
99
  protected $isLicensePage = false;
100
 
101
  /**
102
- * Initialize the class
103
  *
104
  * @param Client $client The Client.
105
  */
@@ -114,7 +135,7 @@ class License {
114
  }
115
 
116
  /**
117
- * Initialize License
118
  *
119
  * @return void
120
  */
@@ -133,7 +154,8 @@ class License {
133
  }
134
 
135
  /**
136
- * Expose the License Key
 
137
  * @return void|string
138
  */
139
  public function get_key() {
@@ -142,7 +164,8 @@ class License {
142
  }
143
 
144
  /**
145
- * Display Admin Notices
 
146
  * @return void
147
  */
148
  public function __admin_notices() {
@@ -199,7 +222,8 @@ class License {
199
  }
200
 
201
  /**
202
- * Setup plugin action link to the license page
 
203
  * @param array $links plugin action links.
204
  * @return array
205
  */
@@ -212,7 +236,8 @@ class License {
212
  }
213
 
214
  /**
215
- * Check license
 
216
  * @return array
217
  */
218
  public function check() {
@@ -220,7 +245,8 @@ class License {
220
  }
221
 
222
  /**
223
- * Check Plugin Update
 
224
  * @return array
225
  */
226
  public function check_update() {
@@ -228,7 +254,8 @@ class License {
228
  }
229
 
230
  /**
231
- * Get Plugin data
 
232
  * @return array {
233
  * Plugin Information
234
  * @type bool $success API response status
@@ -277,7 +304,8 @@ class License {
277
  }
278
 
279
  /**
280
- * Active a license
 
281
  * @param array $license license data.
282
  * @return array
283
  */
@@ -286,7 +314,8 @@ class License {
286
  }
287
 
288
  /**
289
- * Deactivate current license
 
290
  * @return array
291
  */
292
  public function deactivate() {
@@ -294,7 +323,7 @@ class License {
294
  }
295
 
296
  /**
297
- * Send common request
298
  *
299
  * @param string $action request action.
300
  * @param array $license license data.
@@ -320,24 +349,20 @@ class License {
320
  }
321
  // parse license data
322
  $license = wp_parse_args( $license, $this->getLicense() );
323
- if ( empty( $license['key'] ) || empty( $license['instance'] ) ) {
 
324
  return [
325
  'success' => false,
326
  'error' => esc_html__( 'Invalid/Empty License Data.', 'webappick' ),
327
  ];
328
  }
329
- if ( empty( $this->client->getProjectId() ) && empty( $this->client->getName() ) ) {
330
- return [
331
- 'success' => false,
332
- 'error' => esc_html__( 'A valid project name/id is required.', 'webappick' ),
333
- ];
334
- }
335
  $params = [
336
  'object' => str_ireplace( array( 'http://', 'https://' ), '', home_url() ),
337
  'api_key' => $license['key'],
338
  'version' => $this->client->getProjectVersion(),
339
  'instance' => $license['instance'],
340
- 'product_id' => $this->client->getName(),
341
  'plugin_name' => $this->client->getBasename(),
342
  'wc_am_action' => $action,
343
  ];
@@ -350,33 +375,41 @@ class License {
350
  $response = json_decode( $response, true );
351
  } else {
352
  $response = maybe_unserialize( $response );
353
- // @TODO check wc-am error ..
354
- return $response;
 
 
 
 
 
 
 
 
 
355
  }
356
- if ( empty( $response ) || ! isset( $response['success'] ) ) {
357
  return [
358
  'success' => false,
359
- 'error' => esc_html__( 'Unknown error occurred, Please try again.', 'webappick' ),
360
- ];
361
- }
362
- if ( ! $response['success'] ) {
363
- $response = [
364
- 'success' => false,
365
- 'error' => isset( $response['error'] ) ? sanitize_text_field( $response['error'] ) : esc_html__( 'Unknown error occurred in API server.', 'webappick' ),
366
  'code' => isset( $response['code'] ) ? sanitize_text_field( $response['code'] ) : 'UNKNOWN',
 
367
  ];
368
  }
 
369
  return $response;
370
  } else {
371
  return [
372
  'success' => false,
373
  'error' => $response->get_error_message(),
 
 
374
  ];
375
  }
376
  }
377
 
378
  /**
379
- * License API URL
 
380
  * @return string
381
  */
382
  public function __getLicenceAPI() {
@@ -384,7 +417,8 @@ class License {
384
  }
385
 
386
  /**
387
- * Filter api url for licensing api
 
388
  * @return void
389
  */
390
  private function setAPI_URL() {
@@ -392,7 +426,8 @@ class License {
392
  }
393
 
394
  /**
395
- * Remove filter for changing wpi url
 
396
  * @see License::setAPI_URL()
397
  * @return void
398
  */
@@ -401,7 +436,7 @@ class License {
401
  }
402
 
403
  /**
404
- * Add settings page for license
405
  *
406
  * @param array $args settings for rendering the menu.
407
  *
@@ -435,7 +470,7 @@ class License {
435
  }
436
 
437
  /**
438
- * Admin Menu hook
439
  *
440
  * @return void
441
  */
@@ -455,11 +490,14 @@ class License {
455
  }
456
 
457
  /**
458
- * License menu output
 
 
459
  */
460
  public function menu_output() {
461
  $this->licenses_style();
462
  $action = ( isset( $this->license['status'] ) && 'active' == $this->license['status'] ) ? 'deactivate' : 'activate';
 
463
  ?>
464
  <div class="wrap webappick-license-settings-wrapper">
465
  <h1 class="wp-heading-inline"><?php esc_html_e( 'License Settings', 'webappick' ); ?></h1>
@@ -474,21 +512,100 @@ class License {
474
  printf( esc_html__( 'Active %s by your license key to get professional support and automatic update from your WordPress dashboard.', 'webappick' ), '<strong>' . esc_html( $this->client->getName() ) . '</strong>' );
475
  ?></p>
476
  <?php } ?>
477
- <form method="post" action="<?php $this->formActionUrl(); ?>" novalidate="novalidate" spellcheck="false" autocomplete="off">
478
  <?php wp_nonce_field( $this->data_key ); ?>
479
  <input type="hidden" name="<?php echo esc_attr( $this->data_key ); ?>[_action]" value="<?php echo esc_attr( $action ); ?>">
480
  <div class="license-input-fields">
481
- <div class="license-input-key">
482
- <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">
483
- <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"/>
484
- </svg>
485
- <label for="license_key" class="screen-reader-text"><?php esc_html_e( 'License Key', 'webappick' ); ?></label>
486
- <input class="regular-text" id="license_key" type="text"
487
- value="<?php echo esc_attr( $this->get_input_license_value( $action, $this->license ) ); ?>"
488
- placeholder="<?php esc_attr_e( 'Enter your license key to activate', 'webappick' ); ?>"
489
- name="<?php echo esc_attr( $this->data_key ); ?>[license_key]"<?php readonly( ( 'deactivate' == $action ), true, true ); ?>
490
- autocomplete="off">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491
  </div>
 
492
  <button type="submit" name="<?php echo esc_attr( $this->data_key); ?>[submit]" class="<?php printf( '%s-button', esc_attr( $action ) );?>"><?php
493
  'activate' == $action ? esc_html_e( 'Activate License', 'webappick' ) : esc_html_e( 'Deactivate License', 'webappick' );
494
  ?></button>
@@ -504,7 +621,21 @@ class License {
504
  }
505
 
506
  /**
507
- * License form submit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
  * @return void
509
  */
510
  public function handle_license_page_form() {
@@ -525,7 +656,8 @@ class License {
525
 
526
  /**
527
  * Check license status on schedule.
528
- * Check and update license status on db
 
529
  * @return void
530
  */
531
  public function check_license_status() {
@@ -569,15 +701,24 @@ class License {
569
 
570
  /**
571
  * Check this is a valid license.
 
 
 
 
 
572
  * @return bool
573
  */
574
- public function is_valid() {
575
  if ( null !== $this->is_valid_license ) {
576
  return $this->is_valid_license;
577
  }
 
578
  // load the license if already not loaded.
579
- $this->getLicense();
580
- if ( isset( $this->license['status'] ) && 'active' == $this->license['status'] ) {
 
 
 
581
  $this->is_valid_license = true;
582
  } else {
583
  $this->is_valid_license = false;
@@ -586,8 +727,25 @@ class License {
586
  return $this->is_valid_license;
587
  }
588
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
  /**
590
  * Read WooCommerce API Manager Data, Convert to new license format and save in db.
 
591
  * @param bool $override override current settings.
592
  * @return bool
593
  */
@@ -614,21 +772,27 @@ class License {
614
  'status' => 'deactivate', // activate.
615
  'instance' => '', // max len 190.
616
  ];
 
617
  // get key.
618
  $data = get_option( $wcAmPrefix . '_data', false );
619
  if ( $data && isset( $data['api_key'] ) ) {
620
  $license['key'] = $data['api_key'];
621
  }
622
- // instance id.
623
- $data = get_option( $wcAmPrefix . '_instance', false );
624
- if ( $data ) {
625
- $license['instance'] = $data;
 
 
626
  }
 
 
627
  // activation status.
628
  $data = get_option( $wcAmPrefix . '_activated', false );
629
  if ( $data ) {
630
  $license['status'] = strtolower( $data ) === 'activated' ? 'active' : 'inactive'; // Deactivated.
631
  }
 
632
  $this->setLicense( $license );
633
  $this->check_license_status();
634
  update_option( $this->option_key . '_wc_am_migrated', 1, false );
@@ -636,7 +800,9 @@ class License {
636
  }
637
 
638
  /**
639
- * Styles for licenses page
 
 
640
  */
641
  private function licenses_style() {
642
  ?>
@@ -650,10 +816,18 @@ class License {
650
  .webappick-license-title span{font-size:17px;color:#444;margin-left:10px}
651
  .webappick-license-details{padding:20px}
652
  .webappick-license-details p{font-size:15px;margin:0 0 20px 0}
653
- .license-input-key{position:relative;-webkit-box-flex:0;-ms-flex:0 0 72%;flex:0 0 72%;max-width:72%}
654
- .license-input-key input{background-color:#f9f9f9;padding:10px 15px 10px 48px;border:1px solid #e8e5e5;border-radius:3px;height:45px;font-size:16px;color:#71777d;width:100%;-webkit-box-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent}
655
- .license-input-key input:focus{outline:0 none;border:1px solid #e8e5e5;-webkit-box-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent}
656
- .license-input-key svg{width:22px;height:22px;fill:#0082bf;position:absolute;left:14px;top:13px}
 
 
 
 
 
 
 
 
657
  .license-input-fields{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;margin:20px 0;max-width:850px;width:100%}
658
  .license-input-fields button{margin-left:20px;color:#fff;font-size:17px;padding:8px;height:46px;background-color:#0082bf;border-radius:3px;cursor:pointer;-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%;border:1px solid #0082bf}
659
  .license-input-fields button.deactivate-button{background-color:#e40055;border-color:#e40055}
@@ -670,7 +844,8 @@ class License {
670
  }
671
 
672
  /**
673
- * Show active license information
 
674
  * @return void
675
  */
676
  private function show_active_license_info() {
@@ -716,7 +891,8 @@ class License {
716
  }
717
 
718
  /**
719
- * Card header
 
720
  * @return void
721
  */
722
  private function show_license_page_card_header() {
@@ -733,7 +909,8 @@ class License {
733
  }
734
 
735
  /**
736
- * Active client license
 
737
  * @param array $postData Sanitized Form $_POST Data.
738
  * @return void
739
  */
@@ -745,7 +922,7 @@ class License {
745
 
746
  $license = (array) $this->getLicense();
747
  // check if it's a change request.
748
- $updateKey = ( isset( $this->license['key'] ) && $postData['license_key'] === $this->license['key'] ) ? true : false;
749
  if ( $updateKey ) {
750
  $deactivate = $this->deactivate(); // deactivate first.
751
  if ( ! $deactivate['success'] ) {
@@ -756,7 +933,9 @@ class License {
756
  }
757
  }
758
  }
 
759
  $license['key'] = $postData['license_key'];
 
760
  if ( empty( $license['instance'] ) ) $license['instance'] = $this->generateInstanceId();
761
  $response = $this->activate( $license );
762
  if ( ! $response['success'] ) {
@@ -786,6 +965,7 @@ class License {
786
 
787
  /**
788
  * deactivate client license.
 
789
  * @return void
790
  */
791
  private function deactivate_client_license() {
@@ -808,6 +988,7 @@ class License {
808
 
809
  /**
810
  * Add license menu page.
 
811
  * @return void
812
  */
813
  private function add_menu_page() {
@@ -824,6 +1005,7 @@ class License {
824
 
825
  /**
826
  * Add submenu page.
 
827
  * @return void
828
  */
829
  private function add_submenu_page() {
@@ -839,6 +1021,7 @@ class License {
839
 
840
  /**
841
  * Add submenu page.
 
842
  * @return void
843
  */
844
  private function add_options_page() {
@@ -852,7 +1035,9 @@ class License {
852
  }
853
 
854
  /**
855
- * Schedule daily license checker event
 
 
856
  */
857
  public function schedule_cron_event() {
858
  if ( ! wp_next_scheduled( $this->schedule_hook ) ) {
@@ -863,6 +1048,7 @@ class License {
863
 
864
  /**
865
  * Clear any scheduled hook.
 
866
  * @return void
867
  */
868
  public function clear_scheduler() {
@@ -871,6 +1057,7 @@ class License {
871
 
872
  /**
873
  * Register Activation And Deactivation Hooks.
 
874
  * @return void
875
  */
876
  private function activation_deactivation() {
@@ -890,6 +1077,7 @@ class License {
890
 
891
  /**
892
  * Project Deactivation Callback.
 
893
  * @return void
894
  */
895
  public function project_deactivation() {
@@ -900,12 +1088,15 @@ class License {
900
 
901
  /**
902
  * Redirect to the license activation page after plugin/theme is activated.
903
- * @TODO make option for the plugin/theme (which is using this lib) can alter this method with their custom function.
904
- * @param string $param1 Plugin: base file|Theme: old theme name.
905
- * @param bool|WP_Theme $param2 Plugin: network wide activation status|Theme: WP_Theme instance of the old theme.
 
 
 
906
  * @return void
907
  */
908
- public function redirect_to_license_page( $param1, $param2 ) {
909
  $canRedirect = false;
910
  if ( 'plugin' == $this->client->getType() ) {
911
  $canRedirect = ( $param1 == $this->client->getBasename() );
@@ -920,7 +1111,8 @@ class License {
920
  }
921
 
922
  /**
923
- * Form action URL
 
924
  * @return void
925
  */
926
  private function formActionUrl() {
@@ -935,7 +1127,8 @@ class License {
935
  }
936
 
937
  /**
938
- * Get input license key
 
939
  * @param string $action current license action.
940
  * @param array $license license data.
941
  * @return string
@@ -950,14 +1143,15 @@ class License {
950
  }
951
 
952
  /**
953
- * get Plugin/Theme License
 
954
  * @return array {
955
  * Optional. License Data.
956
- * @type string $key The License Key
957
- * @type string $status Activation Status
958
- * @type int $remaining Remaining Activation
959
- * @type int $activation_limit Number of activation allowed for the license key
960
- * @type int $expiry_day Number of day remaining before the license expires
961
  * }
962
  */
963
  private function getLicense() {
@@ -969,19 +1163,21 @@ class License {
969
  if ( false === $this->license ) {
970
  $this->setLicense();
971
  }
 
972
  return $this->license;
973
  }
974
 
975
  /**
976
- * Update License Data
977
- * call this method without license data will deactivate the license (set empty data)
 
978
  * @param array $license {
979
  * Optional. License Data.
980
- * @type string $key The License Key
981
- * @type string $status Activation Status
982
- * @type int $remaining Remaining Activation
983
- * @type int $activation_limit Number of activation allowed for the license key
984
- * @type int $expiry_day Number of day remaining before the license expires
985
  * }
986
  * @return bool False if value was not updated and true if value was updated.
987
  */
@@ -993,20 +1189,22 @@ class License {
993
 
994
  /**
995
  * Parse License data.
 
996
  * @param array $data license data.
997
  *
998
  * @return array
999
  */
1000
  private function parse_license_data( $data = [] ) {
1001
  $defaults = [
1002
- 'key' => '', // license key.
1003
- 'status' => 'inactive', // current status.
1004
- 'instance' => '', // instance unique id.
1005
- 'remaining' => 0, // remaining activation.
1006
- 'activations' => 0, // total activation.
1007
- 'limit' => 0, // activation limit.
1008
- 'unlimited' => false, // is unlimited activation.
1009
- 'expiry_date' => 0, // expires set this to a unix timestamp.
 
1010
  ];
1011
  // parse
1012
  $data = wp_parse_args( $data, $defaults );
@@ -1015,6 +1213,7 @@ class License {
1015
  $license['key'] = sanitize_text_field( $data['key'] );
1016
  $license['status'] = strtolower( $data['status'] ) === 'active' ? 'active' : 'inactive';
1017
  $license['instance'] = sanitize_text_field( $data['instance'] );
 
1018
  $license['remaining'] = absint( $data['remaining'] );
1019
  $license['activations'] = absint( $data['activations'] );
1020
  $license['limit'] = absint( $data['limit'] );
@@ -1024,7 +1223,8 @@ class License {
1024
  }
1025
 
1026
  /**
1027
- * Generate a random Instance ID
 
1028
  * @return string
1029
  */
1030
  private function generateInstanceId() {
@@ -1041,4 +1241,4 @@ class License {
1041
  return $id;
1042
  }
1043
  }
1044
- // End of file License.php.
10
 
11
  namespace WebAppick\AppServices;
12
 
13
+ use WP_Theme;
14
+
15
  if ( ! defined( 'ABSPATH' ) ) {
16
  die();
17
  }
22
  class License {
23
 
24
  /**
25
+ * WebAppick\AppServices\Client.
26
  *
27
  * @var Client
28
  */
29
  protected $client;
30
 
31
+ /**
32
+ * Unique string for handling post data array for a instance.
33
+ * @var string
34
+ */
35
+ protected $data_key;
36
+
37
+ /**
38
+ * List of product id and associated label for rendering product id input dropdown.
39
+ * @var array
40
+ */
41
+ private $product_data = [];
42
+
43
  /**
44
  * Flag for checking if the init method is already called.
45
+ *
46
  * @var bool
47
  */
48
  private $didInit = false;
49
 
50
  /**
51
+ * Arguments of create menu.
52
  *
53
  * @var array
54
  */
55
  protected $menu_args;
56
 
57
  /**
58
+ * `option_name` of `wp_options` table.
59
  *
60
  * @var string
61
  */
62
  protected $option_key;
63
 
64
  /**
65
+ * Error message of HTTP request.
66
  *
67
  * @var string
68
  */
69
  protected $error;
70
 
71
  /**
72
+ * Success message on form submit.
73
  *
74
  * @var string
75
  */
76
  protected $success;
77
 
78
  /**
79
+ * Corn schedule hook name.
80
  *
81
  * @var string
82
  */
83
  protected $schedule_hook;
84
 
85
  /**
86
+ * Set value for valid license.
87
  *
88
  * @var boolean
89
  */
90
  private $is_valid_license = null;
91
+
92
  /**
93
+ * The license data.
94
+ *
95
  * @var array {
96
  * Optional. License Data.
97
  * @type string $key The License Key
98
+ * @type string $instance Unique instance id
99
+ * @type string $product_id Product (wc-store) variation id
100
  * @type string $status Activation Status
101
  * @type int $remaining Remaining Activation
102
  * @type int $activation_limit Number of activation allowed for the license key
106
  protected $license;
107
 
108
  /**
109
+ * Current User Permission for managing License.
110
+ *
111
  * @var bool
112
  */
113
  protected $currentUserCanManage = false;
114
 
115
  /**
116
+ * Is Current Page is the license manage page.
117
+ *
118
  * @var bool
119
  */
120
  protected $isLicensePage = false;
121
 
122
  /**
123
+ * Initialize the class.
124
  *
125
  * @param Client $client The Client.
126
  */
135
  }
136
 
137
  /**
138
+ * Initialize License.
139
  *
140
  * @return void
141
  */
154
  }
155
 
156
  /**
157
+ * Expose the License Key.
158
+ *
159
  * @return void|string
160
  */
161
  public function get_key() {
164
  }
165
 
166
  /**
167
+ * Display Admin Notices.
168
+ *
169
  * @return void
170
  */
171
  public function __admin_notices() {
222
  }
223
 
224
  /**
225
+ * Setup plugin action link to the license page.
226
+ *
227
  * @param array $links plugin action links.
228
  * @return array
229
  */
236
  }
237
 
238
  /**
239
+ * Check license.
240
+ *
241
  * @return array
242
  */
243
  public function check() {
245
  }
246
 
247
  /**
248
+ * Check Plugin Update.
249
+ *
250
  * @return array
251
  */
252
  public function check_update() {
254
  }
255
 
256
  /**
257
+ * Get Plugin data.
258
+ *
259
  * @return array {
260
  * Plugin Information
261
  * @type bool $success API response status
304
  }
305
 
306
  /**
307
+ * Active a license.
308
+ *
309
  * @param array $license license data.
310
  * @return array
311
  */
314
  }
315
 
316
  /**
317
+ * Deactivate current license.
318
+ *
319
  * @return array
320
  */
321
  public function deactivate() {
323
  }
324
 
325
  /**
326
+ * Send common request.
327
  *
328
  * @param string $action request action.
329
  * @param array $license license data.
349
  }
350
  // parse license data
351
  $license = wp_parse_args( $license, $this->getLicense() );
352
+ // validate license data.
353
+ if ( ! $this->validate_license_data( $license ) ) {
354
  return [
355
  'success' => false,
356
  'error' => esc_html__( 'Invalid/Empty License Data.', 'webappick' ),
357
  ];
358
  }
359
+
 
 
 
 
 
360
  $params = [
361
  'object' => str_ireplace( array( 'http://', 'https://' ), '', home_url() ),
362
  'api_key' => $license['key'],
363
  'version' => $this->client->getProjectVersion(),
364
  'instance' => $license['instance'],
365
+ 'product_id' => $license['product_id'],
366
  'plugin_name' => $this->client->getBasename(),
367
  'wc_am_action' => $action,
368
  ];
375
  $response = json_decode( $response, true );
376
  } else {
377
  $response = maybe_unserialize( $response );
378
+ if( is_string( $response ) && 0 === strpos( $response, '{' ) ) {
379
+ // WC-AM returns error with json.
380
+ $response = json_decode( $response, true );
381
+ } else {
382
+ return [
383
+ 'success' => true,
384
+ 'data' => (array) $response,
385
+ // for sanity.
386
+ 'api_call_execution_time' => '',
387
+ ];
388
+ }
389
  }
390
+ if ( empty( $response ) || ! isset( $response['success'] ) || ( isset( $response['success'] ) && ! $response['success'] ) ) {
391
  return [
392
  'success' => false,
393
+ 'error' => isset( $response['error'] ) ? sanitize_text_field( $response['error'] ) : esc_html__( 'Unknown error occurred, Please try again.', 'webappick' ),
 
 
 
 
 
 
394
  'code' => isset( $response['code'] ) ? sanitize_text_field( $response['code'] ) : 'UNKNOWN',
395
+ 'data' => isset( $response['data'] ) ? sanitize_text_field( $response['data'] ) : '',
396
  ];
397
  }
398
+
399
  return $response;
400
  } else {
401
  return [
402
  'success' => false,
403
  'error' => $response->get_error_message(),
404
+ 'code' => $response->get_error_code(),
405
+ 'data' => $response->get_error_data( $response->get_error_code() ),
406
  ];
407
  }
408
  }
409
 
410
  /**
411
+ * License API URL.
412
+ *
413
  * @return string
414
  */
415
  public function __getLicenceAPI() {
417
  }
418
 
419
  /**
420
+ * Filter api url for licensing api.
421
+ *
422
  * @return void
423
  */
424
  private function setAPI_URL() {
426
  }
427
 
428
  /**
429
+ * Remove filter for changing wpi url.
430
+ *
431
  * @see License::setAPI_URL()
432
  * @return void
433
  */
436
  }
437
 
438
  /**
439
+ * Add settings page for license.
440
  *
441
  * @param array $args settings for rendering the menu.
442
  *
470
  }
471
 
472
  /**
473
+ * Admin Menu hook.
474
  *
475
  * @return void
476
  */
490
  }
491
 
492
  /**
493
+ * License menu output.
494
+ *
495
+ * @return void
496
  */
497
  public function menu_output() {
498
  $this->licenses_style();
499
  $action = ( isset( $this->license['status'] ) && 'active' == $this->license['status'] ) ? 'deactivate' : 'activate';
500
+ $need_prod_id = empty( $this->client->getProductId() );
501
  ?>
502
  <div class="wrap webappick-license-settings-wrapper">
503
  <h1 class="wp-heading-inline"><?php esc_html_e( 'License Settings', 'webappick' ); ?></h1>
512
  printf( esc_html__( 'Active %s by your license key to get professional support and automatic update from your WordPress dashboard.', 'webappick' ), '<strong>' . esc_html( $this->client->getName() ) . '</strong>' );
513
  ?></p>
514
  <?php } ?>
515
+ <form method="post" action="<?php $this->formActionUrl(); ?>" spellcheck="false" autocomplete="off">
516
  <?php wp_nonce_field( $this->data_key ); ?>
517
  <input type="hidden" name="<?php echo esc_attr( $this->data_key ); ?>[_action]" value="<?php echo esc_attr( $action ); ?>">
518
  <div class="license-input-fields">
519
+ <div class="input-group">
520
+ <div class="license-input code<?php echo $need_prod_id ? ' has-product-id' : '' ?>">
521
+ <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">
522
+ <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"/>
523
+ </svg>
524
+ <label for="license_key" class="screen-reader-text"><?php esc_html_e( 'License Key', 'webappick' ); ?></label>
525
+ <input class="regular-text" id="license_key" type="text"
526
+ value="<?php echo esc_attr( $this->get_input_license_value( $action, $this->license ) ); ?>"
527
+ placeholder="<?php esc_attr_e( 'Enter your license key to activate', 'webappick' ); ?>"
528
+ name="<?php echo esc_attr( $this->data_key ); ?>[license_key]"<?php readonly( ( 'deactivate' == $action ), true, true ); ?>
529
+ autocomplete="off" required>
530
+ </div>
531
+ <?php if( ! $need_prod_id ) { ?>
532
+ <input type="hidden" name="<?php echo esc_attr( $this->data_key ); ?>[product_id]" value="<?php echo esc_attr( $this->client->getProductId() ); ?>">
533
+ <?php } else {
534
+ if ( empty( $this->product_data ) ) {
535
+ ?>
536
+ <div class="license-input product-id">
537
+ <svg enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg">
538
+ <g>
539
+ <path d="m30 30h53.857v-30h-83.857v83.857h30z"/><path d="m428.143 0v30h53.857v53.857h30v-83.857z"/>
540
+ <path d="m30 428.143h-30v83.857h83.857v-30h-53.857z"/>
541
+ <path d="m482 482h-53.857v30h83.857v-83.857h-30z"/>
542
+ <path d="m68.857 236.571h167.714v-167.714h-167.714zm30-137.714h107.714v107.714h-107.714z"/>
543
+ <path d="m443.143 275.429h-167.714v167.714h167.714zm-137.714 30h107.714v38.857h-68.856v68.856h-38.857v-107.713zm68.857 107.714v-38.856h38.856v38.856z"/>
544
+ <path d="m206.571 344.286h-38.857v-68.857h-98.857v167.714h167.714v-152.714h-30zm0 68.857h-107.714v-107.714h38.857v68.857h68.857z"/>
545
+ <path d="m137.714 137.714h30v30h-30z"/>
546
+ <path d="m305.429 98.857h38.857v68.856h68.856v38.857h-137.705v30h167.705v-167.713h-167.713v98.643h30zm68.857 0h38.856v38.856h-38.856z"/>
547
+ </g>
548
+ </svg>
549
+ <label for="product_id" class="screen-reader-text"><?php esc_html_e( 'Product ID', 'webappick' ); ?></label>
550
+ <input class="regular-text" id="product_id" type="text"
551
+ value="<?php echo esc_attr( $this->license['product_id'] ); ?>"
552
+ placeholder="<?php esc_attr_e( 'Product ID', 'webappick' ); ?>"
553
+ name="<?php echo esc_attr( $this->data_key ); ?>[product_id]"<?php readonly( ( 'deactivate' == $action ), true, true ); ?>
554
+ autocomplete="off" required>
555
+ </div>
556
+ <!-- /.product-id-input -->
557
+ <?php
558
+ } else {
559
+ ?>
560
+ <div class="license-input product-id">
561
+ <svg enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg">
562
+ <g>
563
+ <path d="m30 30h53.857v-30h-83.857v83.857h30z"/><path d="m428.143 0v30h53.857v53.857h30v-83.857z"/>
564
+ <path d="m30 428.143h-30v83.857h83.857v-30h-53.857z"/>
565
+ <path d="m482 482h-53.857v30h83.857v-83.857h-30z"/>
566
+ <path d="m68.857 236.571h167.714v-167.714h-167.714zm30-137.714h107.714v107.714h-107.714z"/>
567
+ <path d="m443.143 275.429h-167.714v167.714h167.714zm-137.714 30h107.714v38.857h-68.856v68.856h-38.857v-107.713zm68.857 107.714v-38.856h38.856v38.856z"/>
568
+ <path d="m206.571 344.286h-38.857v-68.857h-98.857v167.714h167.714v-152.714h-30zm0 68.857h-107.714v-107.714h38.857v68.857h68.857z"/>
569
+ <path d="m137.714 137.714h30v30h-30z"/>
570
+ <path d="m305.429 98.857h38.857v68.856h68.856v38.857h-137.705v30h167.705v-167.713h-167.713v98.643h30zm68.857 0h38.856v38.856h-38.856z"/>
571
+ </g>
572
+ </svg>
573
+ <label for="product_id" class="screen-reader-text"><?php esc_html_e( 'Select License Type', 'webappick' ); ?></label>
574
+ <input type="hidden" name="<?php echo esc_attr( $this->data_key ); ?>[product_id]" value="<?php echo esc_attr( $this->client->getName() ); ?>">
575
+ <select class="regular-text" id="product_id" name="<?php echo esc_attr( $this->data_key ); ?>[product_id]" <?php readonly( ( 'deactivate' == $action ), true ); ?><?php disabled( ( 'deactivate' == $action ), true ); ?>>
576
+ <option value="" disabled selected><?php esc_html_e( 'Select A License Type', 'webappick' ); ?></option>
577
+ <?php
578
+ foreach ( $this->product_data as $id => $item ) {
579
+ if( is_array( $item ) && isset( $item['label'], $item['products'] ) && is_array( $item['products'] ) ) {
580
+ echo '<optgroup label="' . esc_html( $item['label'] ) . '">';
581
+ $item['products'] = array_unique( $item['products'] );
582
+ foreach ( $item['products'] as $k => $label ) {
583
+ printf(
584
+ '<option value="%s"%s>%s</option>',
585
+ esc_attr( $k ),
586
+ selected( $k, $this->license['product_id'], false ),
587
+ esc_html( $label )
588
+ );
589
+ }
590
+ echo '</optgroup>';
591
+ } else {
592
+ printf(
593
+ '<option value="%s"%s>%s</option>',
594
+ esc_attr( $id ),
595
+ selected( $id, $this->license['product_id'], false ),
596
+ esc_html( $item )
597
+ );
598
+ }
599
+ }
600
+ ?>
601
+ </select>
602
+ </div>
603
+ <!-- /.product-id-input -->
604
+ <?php
605
+ }
606
+ } ?>
607
  </div>
608
+ <!-- /.input-group -->
609
  <button type="submit" name="<?php echo esc_attr( $this->data_key); ?>[submit]" class="<?php printf( '%s-button', esc_attr( $action ) );?>"><?php
610
  'activate' == $action ? esc_html_e( 'Activate License', 'webappick' ) : esc_html_e( 'Deactivate License', 'webappick' );
611
  ?></button>
621
  }
622
 
623
  /**
624
+ * Set Product ID Data for dropdown.
625
+ *
626
+ * @param int[] $data Product id => label information for variable product. So user can select from the dropdown.
627
+ *
628
+ * @return void
629
+ */
630
+ public function set_product_data( $data = [] ) {
631
+ if ( ! empty( $data ) ) {
632
+ $this->product_data = $data;
633
+ }
634
+ }
635
+
636
+ /**
637
+ * License form submit.
638
+ *
639
  * @return void
640
  */
641
  public function handle_license_page_form() {
656
 
657
  /**
658
  * Check license status on schedule.
659
+ * Check and update license status on db.
660
+ *
661
  * @return void
662
  */
663
  public function check_license_status() {
701
 
702
  /**
703
  * Check this is a valid license.
704
+ *
705
+ * @param array $license Optional. A license instance to check.
706
+ * Default blank.
707
+ * If blank it will test against license from database..
708
+ *
709
  * @return bool
710
  */
711
+ public function is_valid( $license = [] ) {
712
  if ( null !== $this->is_valid_license ) {
713
  return $this->is_valid_license;
714
  }
715
+
716
  // load the license if already not loaded.
717
+ if ( empty( $license ) ) {
718
+ $license = $this->getLicense();
719
+ }
720
+
721
+ if ( isset( $license['key'], $license['instance'], $license['product_id'], $license['status'] ) && 'active' == $license['status'] ) {
722
  $this->is_valid_license = true;
723
  } else {
724
  $this->is_valid_license = false;
727
  return $this->is_valid_license;
728
  }
729
 
730
+ /**
731
+ * Validate license data for request.
732
+ *
733
+ * @param array $license license data.
734
+ *
735
+ * @return bool
736
+ */
737
+ public function validate_license_data( $license = [] ) {
738
+ $license = $this->parse_license_data( $license );
739
+ return (
740
+ ! empty( $license['key'] ) &&
741
+ ! empty( $license['instance'] ) &&
742
+ ! empty( $license['product_id'] )
743
+ );
744
+ }
745
+
746
  /**
747
  * Read WooCommerce API Manager Data, Convert to new license format and save in db.
748
+ *
749
  * @param bool $override override current settings.
750
  * @return bool
751
  */
772
  'status' => 'deactivate', // activate.
773
  'instance' => '', // max len 190.
774
  ];
775
+
776
  // get key.
777
  $data = get_option( $wcAmPrefix . '_data', false );
778
  if ( $data && isset( $data['api_key'] ) ) {
779
  $license['key'] = $data['api_key'];
780
  }
781
+ if ( $data && isset( $data['product_id'] ) ) {
782
+ $license['product_id'] = $data['product_id'];
783
+ }
784
+ // id found?.
785
+ if ( ! isset( $license['product_id'] ) ) {
786
+ $license['product_id'] = get_option( $wcAmPrefix . '_product_id', '' );
787
  }
788
+ // instance id.
789
+ $license['instance'] = get_option( $wcAmPrefix . '_instance', '' );
790
  // activation status.
791
  $data = get_option( $wcAmPrefix . '_activated', false );
792
  if ( $data ) {
793
  $license['status'] = strtolower( $data ) === 'activated' ? 'active' : 'inactive'; // Deactivated.
794
  }
795
+ // save license.
796
  $this->setLicense( $license );
797
  $this->check_license_status();
798
  update_option( $this->option_key . '_wc_am_migrated', 1, false );
800
  }
801
 
802
  /**
803
+ * Styles for licenses page.
804
+ *
805
+ * @return void
806
  */
807
  private function licenses_style() {
808
  ?>
816
  .webappick-license-title span{font-size:17px;color:#444;margin-left:10px}
817
  .webappick-license-details{padding:20px}
818
  .webappick-license-details p{font-size:15px;margin:0 0 20px 0}
819
+ .input-group{position:relative;-webkit-box-flex:0;-ms-flex:0 0 72%;flex:0 0 72%;max-width:72%}
820
+ .input-group input,
821
+ .input-group select{background-color:#f9f9f9;padding:10px 15px 10px 38px;border:1px solid #e8e5e5;border-radius:3px;height:45px;font-size:14px;line-height:1;color:#71777d;width:100%;-webkit-box-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent}
822
+ .input-group input[readonly],
823
+ .input-group select[readonly]{cursor:default}
824
+ .input-group input:focus,
825
+ .input-group select:focus{outline:0 none;border:1px solid #e8e5e5;-webkit-box-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent}
826
+ .input-group .license-input{position:relative;display:block;float:left;padding:0 2px}
827
+ .input-group svg{width:22px;height:22px;fill:#0082bf;position:absolute;left:14px;top:13px;z-index: 99}
828
+ .input-group .license-input.code{width:100%}
829
+ .input-group .license-input.code.has-product-id{width:calc(100% - 210px)}
830
+ .input-group .license-input.product-id{width:210px}
831
  .license-input-fields{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;margin:20px 0;max-width:850px;width:100%}
832
  .license-input-fields button{margin-left:20px;color:#fff;font-size:17px;padding:8px;height:46px;background-color:#0082bf;border-radius:3px;cursor:pointer;-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%;border:1px solid #0082bf}
833
  .license-input-fields button.deactivate-button{background-color:#e40055;border-color:#e40055}
844
  }
845
 
846
  /**
847
+ * Show active license information.
848
+ *
849
  * @return void
850
  */
851
  private function show_active_license_info() {
891
  }
892
 
893
  /**
894
+ * Card header.
895
+ *
896
  * @return void
897
  */
898
  private function show_license_page_card_header() {
909
  }
910
 
911
  /**
912
+ * Active client license.
913
+ *
914
  * @param array $postData Sanitized Form $_POST Data.
915
  * @return void
916
  */
922
 
923
  $license = (array) $this->getLicense();
924
  // check if it's a change request.
925
+ $updateKey = ( $this->validate_license_data( $license ) ) ? true : false;
926
  if ( $updateKey ) {
927
  $deactivate = $this->deactivate(); // deactivate first.
928
  if ( ! $deactivate['success'] ) {
933
  }
934
  }
935
  }
936
+ // set new license info.
937
  $license['key'] = $postData['license_key'];
938
+ $license['product_id'] = $postData['product_id'];
939
  if ( empty( $license['instance'] ) ) $license['instance'] = $this->generateInstanceId();
940
  $response = $this->activate( $license );
941
  if ( ! $response['success'] ) {
965
 
966
  /**
967
  * deactivate client license.
968
+ *
969
  * @return void
970
  */
971
  private function deactivate_client_license() {
988
 
989
  /**
990
  * Add license menu page.
991
+ *
992
  * @return void
993
  */
994
  private function add_menu_page() {
1005
 
1006
  /**
1007
  * Add submenu page.
1008
+ *
1009
  * @return void
1010
  */
1011
  private function add_submenu_page() {
1021
 
1022
  /**
1023
  * Add submenu page.
1024
+ *
1025
  * @return void
1026
  */
1027
  private function add_options_page() {
1035
  }
1036
 
1037
  /**
1038
+ * Schedule daily license checker event.
1039
+ *
1040
+ * @return void
1041
  */
1042
  public function schedule_cron_event() {
1043
  if ( ! wp_next_scheduled( $this->schedule_hook ) ) {
1048
 
1049
  /**
1050
  * Clear any scheduled hook.
1051
+ *
1052
  * @return void
1053
  */
1054
  public function clear_scheduler() {
1057
 
1058
  /**
1059
  * Register Activation And Deactivation Hooks.
1060
+ *
1061
  * @return void
1062
  */
1063
  private function activation_deactivation() {
1077
 
1078
  /**
1079
  * Project Deactivation Callback.
1080
+ *
1081
  * @return void
1082
  */
1083
  public function project_deactivation() {
1088
 
1089
  /**
1090
  * Redirect to the license activation page after plugin/theme is activated.
1091
+ *
1092
+ * @TODO make option for the plugin/theme (which is using this lib) can alter this method with their custom function.
1093
+ *
1094
+ * @param string $param1 Plugin: base file|Theme: old theme name.
1095
+ * @param bool|WP_Theme $param2 Plugin: network wide activation status|Theme: WP_Theme instance of the old theme.
1096
+ *
1097
  * @return void
1098
  */
1099
+ public function redirect_to_license_page( $param1, $param2 = null ) {
1100
  $canRedirect = false;
1101
  if ( 'plugin' == $this->client->getType() ) {
1102
  $canRedirect = ( $param1 == $this->client->getBasename() );
1111
  }
1112
 
1113
  /**
1114
+ * Form action URL.
1115
+ *
1116
  * @return void
1117
  */
1118
  private function formActionUrl() {
1127
  }
1128
 
1129
  /**
1130
+ * Get input license key.
1131
+ *
1132
  * @param string $action current license action.
1133
  * @param array $license license data.
1134
  * @return string
1143
  }
1144
 
1145
  /**
1146
+ * Get Plugin/Theme License.
1147
+ *
1148
  * @return array {
1149
  * Optional. License Data.
1150
+ * @type string $key The License Key.
1151
+ * @type string $status Activation Status.
1152
+ * @type int $remaining Remaining Activation.
1153
+ * @type int $activation_limit Number of activation allowed for the license key.
1154
+ * @type int $expiry_day Number of day remaining before the license expires.
1155
  * }
1156
  */
1157
  private function getLicense() {
1163
  if ( false === $this->license ) {
1164
  $this->setLicense();
1165
  }
1166
+ $this->license = $this->parse_license_data( $this->license );
1167
  return $this->license;
1168
  }
1169
 
1170
  /**
1171
+ * Update License Data.
1172
+ * Call this method without license data will deactivate the license (set empty data).
1173
+ *
1174
  * @param array $license {
1175
  * Optional. License Data.
1176
+ * @type string $key The License Key.
1177
+ * @type string $status Activation Status.
1178
+ * @type int $remaining Remaining Activation.
1179
+ * @type int $activation_limit Number of activation allowed for the license key.
1180
+ * @type int $expiry_day Number of day remaining before the license expires.
1181
  * }
1182
  * @return bool False if value was not updated and true if value was updated.
1183
  */
1189
 
1190
  /**
1191
  * Parse License data.
1192
+ *
1193
  * @param array $data license data.
1194
  *
1195
  * @return array
1196
  */
1197
  private function parse_license_data( $data = [] ) {
1198
  $defaults = [
1199
+ 'key' => '', // license key.
1200
+ 'status' => 'inactive', // current status.
1201
+ 'instance' => '', // instance unique id.
1202
+ 'product_id' => !empty( $this->client->getProductId() ) ? $this->client->getProductId() : $this->client->getName(), // product id.
1203
+ 'remaining' => 0, // remaining activation.
1204
+ 'activations' => 0, // total activation.
1205
+ 'limit' => 0, // activation limit.
1206
+ 'unlimited' => false, // is unlimited activation.
1207
+ 'expiry_date' => 0, // expires set this to a unix timestamp.
1208
  ];
1209
  // parse
1210
  $data = wp_parse_args( $data, $defaults );
1213
  $license['key'] = sanitize_text_field( $data['key'] );
1214
  $license['status'] = strtolower( $data['status'] ) === 'active' ? 'active' : 'inactive';
1215
  $license['instance'] = sanitize_text_field( $data['instance'] );
1216
+ $license['product_id'] = sanitize_text_field( $data['product_id'] );
1217
  $license['remaining'] = absint( $data['remaining'] );
1218
  $license['activations'] = absint( $data['activations'] );
1219
  $license['limit'] = absint( $data['limit'] );
1223
  }
1224
 
1225
  /**
1226
+ * Generate a random Instance ID.
1227
+ *
1228
  * @return string
1229
  */
1230
  private function generateInstanceId() {
1241
  return $id;
1242
  }
1243
  }
1244
+ // End of file License.php.
woo-feed.php CHANGED
@@ -11,7 +11,7 @@
11
  * Plugin URI: https://webappick.com/
12
  * Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
13
  *
14
- * Version: 3.6.18
15
  * Author: WebAppick
16
  * Author URI: https://webappick.com/
17
  * License: GPL v2
@@ -21,7 +21,7 @@
21
  *
22
  * WP Requirement & Test
23
  * Requires at least: 4.4
24
- * Tested up to: 5.4
25
  * Requires PHP: 5.6
26
  *
27
  * WC Requirement & Test
@@ -39,7 +39,7 @@ if ( ! defined( 'WOO_FEED_FREE_VERSION' ) ) {
39
  * @var string
40
  * @since 3.1.6
41
  */
42
- define( 'WOO_FEED_FREE_VERSION', '3.6.18' );
43
  }
44
 
45
  if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {
11
  * Plugin URI: https://webappick.com/
12
  * Description: Easily generate woocommerce product feed for any marketing channel like Google Shopping(Merchant), Facebook Remarketing, Bing, eBay & more. Support 100+ Merchants.
13
  *
14
+ * Version: 3.6.19
15
  * Author: WebAppick
16
  * Author URI: https://webappick.com/
17
  * License: GPL v2
21
  *
22
  * WP Requirement & Test
23
  * Requires at least: 4.4
24
+ * Tested up to: 5.5
25
  * Requires PHP: 5.6
26
  *
27
  * WC Requirement & Test
39
  * @var string
40
  * @since 3.1.6
41
  */
42
+ define( 'WOO_FEED_FREE_VERSION', '3.6.19' );
43
  }
44
 
45
  if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {