CTX Feed – WooCommerce Product Feed Manager Plugin - Version 4.3.28

Version Description

(2021-02-07) = * Fixed: GTIN/MPN/EAN disabled hide inputs at edit product page.

Download this release

Release Info

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

Code changes from version 4.3.27 to 4.3.28

README.txt CHANGED
@@ -1,14 +1,11 @@
1
  === Product Feed for WooCommerce ===
2
  Contributors: wahid0003, webappick, mhamudul_hk, shuvo586, nayanchamp7
3
  Donate link: https://webappick.com
4
- Tags: product feed, woocommerce, google shopping, facebook catalog, bing shopping, Instagram, skroutz
5
- Bing Shopping, Buy, comparison shopping engines, comparison shopping websites, CSV product feed, Data Feed, e-commerce, eBay, facebook ads, Facebook Dynamic remarketing,
6
- Facebook feed, Facebook Product Feed, google, google adwords, Google feed, Google Merchant, Google Merchant Export, Google Merchant Feed, google merchant product feed, Google product feed export,
7
- Google Product Review feed, product variations, rakuteen, shopping, skroutz, TSV, TXT product feed, variations export, walmart, woocommerce, wooCommerce export, WooCommerce Feed, woocommerce product feed manager, woocommerce variations, XML product feed, Yandex
8
  Requires at least: 3.6
9
- Tested Up To: 5.6
10
  Requires PHP: 5.6
11
- Stable tag: 4.3.27
12
  License: GPLv2 or later
13
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
14
 
@@ -501,6 +498,9 @@ Using pro version:
501
 
502
  == Changelog ==
503
 
 
 
 
504
  = 4.3.27 (2021-02-03) =
505
  * Fixed: Input request issues fixed.
506
 
1
  === Product Feed for WooCommerce ===
2
  Contributors: wahid0003, webappick, mhamudul_hk, shuvo586, nayanchamp7
3
  Donate link: https://webappick.com
4
+ Tags: Product Feed, WooCommerce, Google Shopping, Google Merchant, Facebook Catalog, Bing Shopping, Instagram Shop, Skroutz Data Feed, xml feed, csv feed, txt feed, woocommerce product feed
 
 
 
5
  Requires at least: 3.6
6
+ Tested Up To: 5.6.1
7
  Requires PHP: 5.6
8
+ Stable tag: 4.3.28
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
498
 
499
  == Changelog ==
500
 
501
+ = 4.3.28 (2021-02-07) =
502
+ * Fixed: GTIN/MPN/EAN disabled hide inputs at edit product page.
503
+
504
  = 4.3.27 (2021-02-03) =
505
  * Fixed: Input request issues fixed.
506
 
admin/class-woo-feed-admin.php CHANGED
@@ -115,10 +115,6 @@ class Woo_Feed_Admin {
115
  wp_register_script( 'jquery-validate-additional-methods', plugin_dir_url( __FILE__ ) . 'js/additional-methods.min.js', array( 'jquery', 'jquery-validate' ), $this->version, false );
116
  wp_register_script( 'jquery-sortable', plugin_dir_url( __FILE__ ) . 'js/jquery-sortable' . $ext, array( 'jquery' ), $this->version, false );
117
 
118
- if ( ! wp_script_is( 'clipboard', 'registered' ) ) {
119
- wp_register_script( 'clipboard', plugin_dir_url( __FILE__ ) . 'js/clipboard.min.js', [], '2.0.4', false );
120
- }
121
-
122
  $feedScriptDependency = [
123
  'jquery',
124
  'clipboard',
115
  wp_register_script( 'jquery-validate-additional-methods', plugin_dir_url( __FILE__ ) . 'js/additional-methods.min.js', array( 'jquery', 'jquery-validate' ), $this->version, false );
116
  wp_register_script( 'jquery-sortable', plugin_dir_url( __FILE__ ) . 'js/jquery-sortable' . $ext, array( 'jquery' ), $this->version, false );
117
 
 
 
 
 
118
  $feedScriptDependency = [
119
  'jquery',
120
  'clipboard',
admin/partials/woo-feed-edit-filter.php CHANGED
@@ -67,7 +67,7 @@ if ( ! defined( 'ABSPATH' ) ) {
67
  </table>
68
  </td>
69
  </tr>
70
- <tr><td colspan="2"> <b style="font-size: large;"><a href="http://bit.ly/2KIwvTt"> &#8594; Premium version</a> of the plugin have lots to filtering option like:</b><br>
71
  <table class="table widefat fixed" style="border: 0">
72
  <tr>
73
  <td>1. Include/Exclude some specific products from feed by Product ID.</td>
@@ -88,7 +88,7 @@ if ( ! defined( 'ABSPATH' ) ) {
88
  <td>6. Custom Number format.</td>
89
  </tr>
90
  <tr>
91
- <td><b>Get &#8594;<a style="color: red;" href="http://bit.ly/2KIwvTt"> Woo Feed Pro</a></b></td>
92
  </tr>
93
  </table>
94
  </td>
67
  </table>
68
  </td>
69
  </tr>
70
+ <tr><td colspan="2"> <b style="font-size: large;"><a href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed"> &#8594; Premium version</a> of the plugin have lots to filtering option like:</b><br>
71
  <table class="table widefat fixed" style="border: 0">
72
  <tr>
73
  <td>1. Include/Exclude some specific products from feed by Product ID.</td>
88
  <td>6. Custom Number format.</td>
89
  </tr>
90
  <tr>
91
+ <td><b>Get &#8594;<a style="color: red;" href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed"> Woo Feed Pro</a></b></td>
92
  </tr>
93
  </table>
94
  </td>
admin/partials/woo-feed-pro-vs-free.php CHANGED
@@ -11,7 +11,7 @@
11
  * @version 1.0.2
12
  */
13
  if ( ! function_exists( 'add_action' ) ) die();
14
- // ### REF > utm parameters http://bit.ly/2KIwvTt
15
  $features = array(
16
  array(
17
  'thumb' => esc_url( WOO_FEED_PLUGIN_URL ) . 'admin/images/features/smart-filter-conditions.svg',
@@ -316,7 +316,7 @@ $testimonials = array(
316
  <div class="wrap wapk-admin wapk-feed-pro-upgrade">
317
  <div class="wapk-section wapk-feed-banner">
318
  <div class="wapk-banner">
319
- <a href="http://bit.ly/2KIwvTt" target="_blank">
320
  <img class="wapk-banner__graphics" src="<?php echo esc_url( WOO_FEED_PLUGIN_URL ); ?>admin/images/woo-feed-pro-banner.png" alt="<?php esc_attr_e( 'Upgrade to WooFeed Pro to unlock more powerful features.', 'woo-feed' ); ?>">
321
  </a>
322
  </div>
11
  * @version 1.0.2
12
  */
13
  if ( ! function_exists( 'add_action' ) ) die();
14
+
15
  $features = array(
16
  array(
17
  'thumb' => esc_url( WOO_FEED_PLUGIN_URL ) . 'admin/images/features/smart-filter-conditions.svg',
316
  <div class="wrap wapk-admin wapk-feed-pro-upgrade">
317
  <div class="wapk-section wapk-feed-banner">
318
  <div class="wapk-banner">
319
+ <a href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed" target="_blank">
320
  <img class="wapk-banner__graphics" src="<?php echo esc_url( WOO_FEED_PLUGIN_URL ); ?>admin/images/woo-feed-pro-banner.png" alt="<?php esc_attr_e( 'Upgrade to WooFeed Pro to unlock more powerful features.', 'woo-feed' ); ?>">
321
  </a>
322
  </div>
includes/classes/class-woo-feed-admin-message.php CHANGED
@@ -108,12 +108,12 @@ final class Woo_Feed_Message {
108
  <tr>
109
  <th>
110
  <div class="woo-feed-top-header">
111
- <a class="get-woo-feed-pro" href="http://bit.ly/2KIwvTt" target="_blank" aria-label="<?php esc_attr_e( 'Get Woo Feed Pro', 'woo-feed' ); ?>">
112
  <img src="<?php echo esc_url( WOO_FEED_PLUGIN_URL ); ?>admin/images/get-woo-feed-pro.svg" alt="<?php esc_attr_e( 'Get Woo Feed Pro', 'woo-feed' ); ?>">
113
  </a>
114
  <div class="woo-feed-top-buttons">
115
  <a class="woo-feed-doc-link" href="https://webappick.com/docs/woocommerce-product-feed/" target="_blank" ><span class="dashicons dashicons-book"></span> <?php esc_html_e( 'Documentation', 'woo-feed' ); ?></a>
116
- <a class="woo-feed-video-link" href="http://bit.ly/2u6giNz" target="_blank"><span class="dashicons dashicons-youtube"></span> <?php esc_html_e( 'Video Tutorials', 'woo-feed' ); ?></a>
117
  <a class="woo-feed-support-link" href="https://webappick.com/support/" target="_blank"><span class="dashicons dashicons-sos"></span> <?php esc_html_e( 'Get Support', 'woo-feed' ); ?></a>
118
  </div>
119
  </div>
108
  <tr>
109
  <th>
110
  <div class="woo-feed-top-header">
111
+ <a class="get-woo-feed-pro" href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed" target="_blank" aria-label="<?php esc_attr_e( 'Get Woo Feed Pro', 'woo-feed' ); ?>">
112
  <img src="<?php echo esc_url( WOO_FEED_PLUGIN_URL ); ?>admin/images/get-woo-feed-pro.svg" alt="<?php esc_attr_e( 'Get Woo Feed Pro', 'woo-feed' ); ?>">
113
  </a>
114
  <div class="woo-feed-top-buttons">
115
  <a class="woo-feed-doc-link" href="https://webappick.com/docs/woocommerce-product-feed/" target="_blank" ><span class="dashicons dashicons-book"></span> <?php esc_html_e( 'Documentation', 'woo-feed' ); ?></a>
116
+ <a class="woo-feed-video-link" href="https://youtube.com/playlist?list=PLapCcXJAoEenI-35wc6YnnsAAgoYRxDr7" target="_blank"><span class="dashicons dashicons-youtube"></span> <?php esc_html_e( 'Video Tutorials', 'woo-feed' ); ?></a>
117
  <a class="woo-feed-support-link" href="https://webappick.com/support/" target="_blank"><span class="dashicons dashicons-sos"></span> <?php esc_html_e( 'Get Support', 'woo-feed' ); ?></a>
118
  </div>
119
  </div>
includes/classes/class-woo-feed-webappick-api.php CHANGED
@@ -178,7 +178,7 @@ if ( ! class_exists( 'WooFeedWebAppickAPI' ) ) {
178
  $followUp = esc_html__( 'Please Follow the email and WebAppick Support Team will get back with you shortly.', 'woo-feed' );
179
  $response .= sprintf( '<p>%s %s %s</p>', $ticketSubmitted, $notification, $followUp );
180
  $docLink = sprintf( '<a class="button button-primary" href="https://webappick.helpscoutdocs.com/" target="_blank"><span class="dashicons dashicons-media-document" aria-hidden="true"></span> %s</a>', esc_html__( 'Documentation', 'woo-feed' ) );
181
- $vidLink = sprintf( '<a class="button button-primary" href="http://bit.ly/2u6giNz" target="_blank"><span class="dashicons dashicons-video-alt3" aria-hidden="true"></span> %s</a>', esc_html__( 'Video Tutorials', 'woo-feed' ) );
182
  $response .= sprintf( '<p>%s %s</p>', $docLink, $vidLink );
183
  $response .= '<br><br><br>';
184
  $toc = sprintf( '<a href="https://webappick.com/terms-and-conditions/" target="_blank">%s</a>', esc_html__( 'Terms & Conditions', 'woo-feed' ) );
@@ -294,7 +294,7 @@ if ( ! class_exists( 'WooFeedWebAppickAPI' ) ) {
294
  $installDate = get_option( 'woo-feed-free-activation-time' );
295
  $installDate = strtotime( '-16 days', $installDate );
296
  $pluginName = sprintf( '<b>%s</b>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
297
- $proLink = sprintf( '<b><a href="http://bit.ly/2KIwvTt" target="_blank">%s</a></b>', esc_html__( 'Premium', 'woo-feed' ) );
298
  $has_notice = false;
299
  $review_notice = (
300
  false === get_option( 'woo_feed_rating_notice_hidden' ) &&
178
  $followUp = esc_html__( 'Please Follow the email and WebAppick Support Team will get back with you shortly.', 'woo-feed' );
179
  $response .= sprintf( '<p>%s %s %s</p>', $ticketSubmitted, $notification, $followUp );
180
  $docLink = sprintf( '<a class="button button-primary" href="https://webappick.helpscoutdocs.com/" target="_blank"><span class="dashicons dashicons-media-document" aria-hidden="true"></span> %s</a>', esc_html__( 'Documentation', 'woo-feed' ) );
181
+ $vidLink = sprintf( '<a class="button button-primary" href="https://youtube.com/playlist?list=PLapCcXJAoEenI-35wc6YnnsAAgoYRxDr7" target="_blank"><span class="dashicons dashicons-video-alt3" aria-hidden="true"></span> %s</a>', esc_html__( 'Video Tutorials', 'woo-feed' ) );
182
  $response .= sprintf( '<p>%s %s</p>', $docLink, $vidLink );
183
  $response .= '<br><br><br>';
184
  $toc = sprintf( '<a href="https://webappick.com/terms-and-conditions/" target="_blank">%s</a>', esc_html__( 'Terms & Conditions', 'woo-feed' ) );
294
  $installDate = get_option( 'woo-feed-free-activation-time' );
295
  $installDate = strtotime( '-16 days', $installDate );
296
  $pluginName = sprintf( '<b>%s</b>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
297
+ $proLink = sprintf( '<b><a href="https://webappick.com/plugin/woocommerce-product-feed-pro/?utm_source=freePlugin&utm_medium=go_premium&utm_campaign=free_to_pro&utm_term=wooFeed" target="_blank">%s</a></b>', esc_html__( 'Premium', 'woo-feed' ) );
298
  $has_notice = false;
299
  $review_notice = (
300
  false === get_option( 'woo_feed_rating_notice_hidden' ) &&
includes/feeds/merchant_infos.php CHANGED
@@ -16,15 +16,14 @@ return array(
16
  'feed_file_type' => array( 'XML', 'CSV', 'TSV', 'XLS', 'TXT' ),
17
  ),
18
  'google' => array(
19
- 'link' => 'http://bit.ly/38kmDrl',
20
  'video' => 'https://youtu.be/PTUYgF7DwEo',
21
  'feed_file_type' => array( 'XML', 'CSV', 'TSV', 'XLS', 'TXT' ),
22
  'doc' => array(
23
- esc_html__( 'How to make google merchant feed?', 'woo-feed' ) => 'http://bit.ly/355q0jY',
24
- esc_html__( 'How to configure shipping info?', 'woo-feed' ) => 'http://bit.ly/2Rzr0sI',
25
- esc_html__( 'How to set price with tax?', 'woo-feed' ) => 'http://bit.ly/2PuzWga',
26
- esc_html__( 'How to solve micro data error?', 'woo-feed' ) => 'http://bit.ly/345nIQz',
27
- esc_html__( 'How to configure google product categories?', 'woo-feed' ) => 'http://bit.ly/2RFWRrP',
28
  ),
29
  ), // Google.
30
  'google_local' => array(
@@ -48,115 +47,113 @@ return array(
48
  'feed_file_type' => array( 'CSV' ),
49
  ),
50
  'facebook' => array(
51
- 'link' => 'http://bit.ly/2P5cA1V',
52
  'video' => 'https://youtu.be/Wo3V_nf_eUU',
53
  'feed_file_type' => array( 'XML', 'CSV','TXT' ),
54
  ), // Facebook.
55
  'pinterest' => array(
56
- 'link' => 'http://bit.ly/35h6YXG',
57
  'feed_file_type' => array( 'XML', 'CSV','TXT' ),
58
  'doc' => array(
59
- esc_html__( 'How to configure google product categories?', 'woo-feed' ) => 'http://bit.ly/2RFWRrP',
60
  ),
61
  ), // Pinterest.
62
  'pinterest_rss' => array(
63
- 'link' => 'http://bit.ly/35h6YXG',
64
  'feed_file_type' => array( 'XML' ),
65
  ), // Pinterest.
66
  'bing' => array(
67
- 'link' => 'http://bit.ly/33ZeuVS',
68
  'feed_file_type' => array( 'CSV', 'TSV', 'XLS', 'TXT'),
69
  ), // Bing.
70
  'pricespy' => array(
71
- 'link' => 'http://bit.ly/2t0rEFm',
72
  'feed_file_type' => array( 'TXT' ),
73
  ), // PriceSpy.
74
  'prisjakt' => array(
75
- 'link' => 'http://bit.ly/36iRT8a',
76
  'feed_file_type' => array( 'TXT' ),
77
  ), // Prisjakt.
78
  'idealo' => array(
79
- 'link' => 'http://bit.ly/2LDgJI0',
80
  'feed_file_type' => array( 'CSV', 'TXT' ),
81
  ), // Idealo.
82
  'yandex_csv' => array(
83
- 'link' => 'http://bit.ly/2t0tsy8',
84
  'feed_file_type' => array( 'CSV', 'TXT' ),
85
  ), // Yandex (CSV).
86
  'adroll' => array(
87
- 'link' => 'http://bit.ly/2qzPtmt',
88
  'feed_file_type' => array( 'XML', 'CSV' ),
89
  ), // adroll
90
  'adform' => array(
91
- 'link' => 'http://bit.ly/2s6yatQ',
92
  'feed_file_type' => array( 'XML', 'CSV' ),
93
  ), // adform
94
  'kelkoo' => array(
95
- 'link' => 'http://bit.ly/2RAcqkL',
96
  'feed_file_type' => array( 'XML', 'CSV' ),
97
  ), // Kelkoo.
98
  'shopmania' => array(
99
- 'link' => 'http://bit.ly/38pE2PA',
100
  'feed_file_type' => array( 'XML', 'CSV' ),
101
  ), // Shop Mania.
102
  'connexity' => array(
103
- 'link' => 'http://bit.ly/36lPaLw',
104
  'feed_file_type' => array( 'TXT' ),
105
  ), // Connexity.
106
  'twenga' => array(
107
- 'link' => 'http://bit.ly/2RwTIud',
108
  'feed_file_type' => array( 'XML', 'TXT' ),
109
  ), // Twenga.
110
  'fruugo' => array(
111
- 'link' => 'http://bit.ly/2Yxabjn',
112
  'feed_file_type' => array( 'XML', 'CSV' ),
113
  ), // Fruugo.
114
  'fruugo.au' => array(
115
- 'link' => 'http://bit.ly/2Yxabjn',
116
  'feed_file_type' => array( 'XML', 'CSV' ),
117
  ), // Fruugo Australia.
118
  'pricerunner' => array(
119
- 'link' => 'http://bit.ly/2Pznn3s',
120
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
121
  ), // Price Runner.
122
  'bonanza' => array(
123
- 'link' => 'http://bit.ly/2Rxi9aK',
124
  'feed_file_type' => array( 'CSV' ),
125
  ), // Bonanza
126
  'bol' => array(
127
- 'link' => 'http://bit.ly/2P3MUCu',
128
  'feed_file_type' => array( 'XML', 'CSV' ),
129
  ), // Bol.
130
  'wish' => array(
131
- 'link' => 'http://bit.ly/348iYtc',
132
  'feed_file_type' => array( 'CSV' ),
133
  ), // Wish.com.
134
  'myshopping.com.au' => array(
135
- 'link' => 'http://bit.ly/2E6jugI',
136
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
137
  ), // Myshopping.com.au.
138
  'skinflint.co.uk' => array(
139
- 'link' => 'http://bit.ly/2sg09qJ',
140
  'feed_file_type' => array( 'CSV' ),
141
  ), // SkinFlint.co.uk.
142
  'yahoo_nfa' => array(
143
- 'link' => 'http://bit.ly/2LCC58k',
144
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
145
  ), // Yahoo NFA.
146
  'comparer.be' => array(
147
- 'link' => 'http://bit.ly/38xz2sa',
148
  'feed_file_type' => array( 'XML', 'CSV' ),
149
  ), // Comparer.be.
150
  'rakuten.de' => array(
151
- 'link' => 'http://bit.ly/2YCDdym',
152
  'feed_file_type' => array( 'CSV', 'TXT' ),
153
  ), // rakuten.
154
  'avantlink' => array(
155
- 'link' => 'http://bit.ly/2PuExPv',
156
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
157
  ), // Avantlink
158
  'shareasale' => array(
159
- 'link' => 'http://bit.ly/36uT1pF',
160
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
161
  ), // ShareASale.
162
  'trovaprezzi' => array(
@@ -375,7 +372,6 @@ return array(
375
  'feed_file_type' => array( 'CSV' ),
376
  ),
377
  'shopee' => array(
378
- 'link' => 'https://webappick-assets.s3.amazonaws.com/feed_template/Shopee_mass_upload_29-06-2020_basic_template.xlsx.xls',
379
  'feed_file_type' => array( 'CSV' ),
380
  ),
381
  'zalando' => array(
16
  'feed_file_type' => array( 'XML', 'CSV', 'TSV', 'XLS', 'TXT' ),
17
  ),
18
  'google' => array(
19
+ 'link' => 'https://support.google.com/merchants/answer/7052112?hl=en',
20
  'video' => 'https://youtu.be/PTUYgF7DwEo',
21
  'feed_file_type' => array( 'XML', 'CSV', 'TSV', 'XLS', 'TXT' ),
22
  'doc' => array(
23
+ esc_html__( 'How to make google merchant feed?', 'woo-feed' ) => 'https://youtu.be/PTUYgF7DwEo',
24
+ esc_html__( 'How to configure shipping info?', 'woo-feed' ) => 'https://webappick.com/docs/woo-feed/merchants/how-to-configure-google-merchant-shipping-attribute/',
25
+ esc_html__( 'How to set price with tax?', 'woo-feed' ) => 'https://webappick.com/docs/woo-feed/product-attributes/how-to-include-include-value-added-tax-vat-in-my-prices/',
26
+ esc_html__( 'How to configure google product categories?', 'woo-feed' ) => 'https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/',
 
27
  ),
28
  ), // Google.
29
  'google_local' => array(
47
  'feed_file_type' => array( 'CSV' ),
48
  ),
49
  'facebook' => array(
50
+ 'link' => 'https://www.facebook.com/business/help/120325381656392?id=725943027795860',
51
  'video' => 'https://youtu.be/Wo3V_nf_eUU',
52
  'feed_file_type' => array( 'XML', 'CSV','TXT' ),
53
  ), // Facebook.
54
  'pinterest' => array(
55
+ 'link' => 'https://help.pinterest.com/en/business/article/before-you-get-started-with-catalogs',
56
  'feed_file_type' => array( 'XML', 'CSV','TXT' ),
57
  'doc' => array(
58
+ esc_html__( 'How to configure google product categories?', 'woo-feed' ) => 'https://webappick.com/docs/woo-feed/feed-configuration/how-to-map-store-category-with-merchant-category/',
59
  ),
60
  ), // Pinterest.
61
  'pinterest_rss' => array(
62
+ 'link' => 'https://help.pinterest.com/en/business/article/before-you-get-started-with-catalogs',
63
  'feed_file_type' => array( 'XML' ),
64
  ), // Pinterest.
65
  'bing' => array(
66
+ 'link' => 'https://help.ads.microsoft.com/apex/index/3/en/51084',
67
  'feed_file_type' => array( 'CSV', 'TSV', 'XLS', 'TXT'),
68
  ), // Bing.
69
  'pricespy' => array(
70
+ 'link' => 'https://pricespy.co.nz/info/register-and-feature-your-shop--i10',
71
  'feed_file_type' => array( 'TXT' ),
72
  ), // PriceSpy.
73
  'prisjakt' => array(
74
+ 'link' => 'https://www.prisjakt.nu/info/registrera-och-profilera-din-butik--i10',
75
  'feed_file_type' => array( 'TXT' ),
76
  ), // Prisjakt.
77
  'idealo' => array(
78
+ 'link' => 'https://connect.idealo.de/tam/UK_feed_specification.pdf',
79
  'feed_file_type' => array( 'CSV', 'TXT' ),
80
  ), // Idealo.
81
  'yandex_csv' => array(
82
+ 'link' => 'https://yandex.com/support/partnermarket/export/recommendation.html#csv',
83
  'feed_file_type' => array( 'CSV', 'TXT' ),
84
  ), // Yandex (CSV).
85
  'adroll' => array(
86
+ 'link' => 'https://help.adroll.com/hc/en-us/articles/216673657-Set-Up-Your-Product-Feed',
87
  'feed_file_type' => array( 'XML', 'CSV' ),
88
  ), // adroll
89
  'adform' => array(
90
+ 'link' => 'https://www.adformhelp.com/s/topic/0TO3W0000008PC5WAM/good-to-know',
91
  'feed_file_type' => array( 'XML', 'CSV' ),
92
  ), // adform
93
  'kelkoo' => array(
94
+ 'link' => 'https://developers.kelkoogroup.com/app/documentation/navigate/_publisher/feedServicePublic/_/_/MerchantFeeds#data-structure',
95
  'feed_file_type' => array( 'XML', 'CSV' ),
96
  ), // Kelkoo.
97
  'shopmania' => array(
98
+ 'link' => 'https://partner.shopmania.com/cp.help/datafeed-specifications',
99
  'feed_file_type' => array( 'XML', 'CSV' ),
100
  ), // Shop Mania.
101
  'connexity' => array(
102
+ 'link' => 'https://www.operationroi.com/wp-content/downloads/Connexity-Feed-Specs-09-2015.pdf',
103
  'feed_file_type' => array( 'TXT' ),
104
  ), // Connexity.
105
  'twenga' => array(
106
+ 'link' => 'https://support.twenga-solutions.com/hc/en-gb/articles/115014901088-Create-a-feed-to-import-your-catalog',
107
  'feed_file_type' => array( 'XML', 'TXT' ),
108
  ), // Twenga.
109
  'fruugo' => array(
110
+ 'link' => 'https://fruugo.atlassian.net/wiki/spaces/RR/pages/67608211/Field+Specification',
111
  'feed_file_type' => array( 'XML', 'CSV' ),
112
  ), // Fruugo.
113
  'fruugo.au' => array(
114
+ 'link' => 'https://fruugo.atlassian.net/wiki/spaces/RR/pages/67608211/Field+Specification',
115
  'feed_file_type' => array( 'XML', 'CSV' ),
116
  ), // Fruugo Australia.
117
  'pricerunner' => array(
118
+ 'link' => 'https://www.pricerunner.com/info/getting-started',
119
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
120
  ), // Price Runner.
121
  'bonanza' => array(
122
+ 'link' => 'https://support.bonanza.com/hc/en-us/articles/360000656491',
123
  'feed_file_type' => array( 'CSV' ),
124
  ), // Bonanza
125
  'bol' => array(
126
+ 'link' => 'https://partnerblog.bol.com/app/files/2018/02/Kolomnamen_productfeeds-2.2.pdf',
127
  'feed_file_type' => array( 'XML', 'CSV' ),
128
  ), // Bol.
129
  'wish' => array(
130
+ 'link' => 'https://merchant.wish.com/documentation/products',
131
  'feed_file_type' => array( 'CSV' ),
132
  ), // Wish.com.
133
  'myshopping.com.au' => array(
134
+ 'link' => 'https://merchant.myshopping.com.au/doc/Product_Feed_Specification.pdf',
135
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
136
  ), // Myshopping.com.au.
137
  'skinflint.co.uk' => array(
 
138
  'feed_file_type' => array( 'CSV' ),
139
  ), // SkinFlint.co.uk.
140
  'yahoo_nfa' => array(
 
141
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
142
  ), // Yahoo NFA.
143
  'comparer.be' => array(
144
+ 'link' => 'https://sc.vergelijk.nl/data/fr_FR/ignore/folders/annexe_3-directives_fichier.pdf',
145
  'feed_file_type' => array( 'XML', 'CSV' ),
146
  ), // Comparer.be.
147
  'rakuten.de' => array(
148
+ 'link' => 'https://rakutenadvertising.com/product-feed-specification/',
149
  'feed_file_type' => array( 'CSV', 'TXT' ),
150
  ), // rakuten.
151
  'avantlink' => array(
152
+ 'link' => 'https://support.avantlink.com/hc/en-us/articles/203883345-All-About-Datafeeds',
153
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
154
  ), // Avantlink
155
  'shareasale' => array(
156
+ 'link' => 'https://blog.shareasale.com/2013/07/18/how-to-create-a-product-datafeed/',
157
  'feed_file_type' => array( 'XML', 'CSV', 'TXT' ),
158
  ), // ShareASale.
159
  'trovaprezzi' => array(
372
  'feed_file_type' => array( 'CSV' ),
373
  ),
374
  'shopee' => array(
 
375
  'feed_file_type' => array( 'CSV' ),
376
  ),
377
  'zalando' => array(
includes/helper.php CHANGED
@@ -2678,42 +2678,44 @@ if ( ! function_exists( 'woo_feed_add_identifier_fields' ) ) {
2678
  * @since 3.7.8
2679
  */
2680
  function woo_feed_add_identifier_fields() {
2681
-
2682
- echo '<div class="options_group">';
2683
- echo sprintf( '<h4 class="%s" style="padding-left: 10px;">%s</h4>', esc_attr( 'woo-feed-option-title' ), esc_html( 'Unique Identifier - Woo Feed', 'woo-feed' ) );
2684
-
2685
- //GTIN input field
2686
- woocommerce_wp_text_input( array(
2687
- 'id' => 'woo_feed_gtin',
2688
- 'value' => get_post_meta( get_the_ID(), 'woo_feed_gtin', true ),
2689
- 'placeholder' => esc_html( 'Set product GTIN', 'woo-feed' ),
2690
- 'label' => esc_html( 'GTIN', 'woo-feed' ),
2691
- 'desc_tip' => true,
2692
- 'description' => esc_html( 'Set product GTIN code here.', 'woo-feed' ),
2693
- ) );
2694
-
2695
- //MPN input field
2696
- woocommerce_wp_text_input( array(
2697
- 'id' => 'woo_feed_mpn',
2698
- 'value' => get_post_meta( get_the_ID(), 'woo_feed_mpn', true ),
2699
- 'placeholder' => esc_html( 'Set product MPN', 'woo-feed' ),
2700
- 'label' => esc_html( 'MPN', 'woo-feed' ),
2701
- 'desc_tip' => true,
2702
- 'description' => esc_html( 'Set product MPN code here.', 'woo-feed' ),
2703
- ) );
2704
-
2705
- //EAN input field
2706
- woocommerce_wp_text_input( array(
2707
- 'id' => 'woo_feed_ean',
2708
- 'value' => get_post_meta( get_the_ID(), 'woo_feed_ean', true ),
2709
- 'placeholder' => esc_html( 'Set product EAN', 'woo-feed' ),
2710
- 'label' => esc_html( 'EAN', 'woo-feed' ),
2711
- 'desc_tip' => true,
2712
- 'description' => esc_html( 'Set product EAN code here.', 'woo-feed' ),
2713
- ) );
2714
-
2715
- echo '</div>';
2716
-
 
 
2717
  }
2718
  add_action( 'woocommerce_product_options_inventory_product_data', 'woo_feed_add_identifier_fields');
2719
  }
@@ -2766,64 +2768,66 @@ if ( ! function_exists( 'woo_feed_add_identifier_fields_for_variation' ) ) {
2766
  * @since 3.7.8
2767
  */
2768
  function woo_feed_add_identifier_fields_for_variation( $loop, $variation_data, $variation ) {
2769
-
2770
- echo '<div class="woo-feed-variation-options">';
2771
- echo sprintf( '<h4 class="%s">%s</h4>', esc_attr( 'woo-feed-variation-option-title' ), esc_html( 'Unique Identifier - Woo Feed', 'woo-feed' ) );
2772
- ?>
2773
- <style>
2774
- .woo-feed-variation-options {
2775
- border-top: 1px solid #ccc;
2776
- margin-top: 20px;
2777
- }
2778
- .woo-feed-variation-options h4 {
2779
- margin-bottom: 0;
2780
- }
2781
- .woo-feed-variation-options .form-field input[type="text"] {
2782
- width: 100%;
2783
- padding: 5px;
2784
- }
2785
- .woo-feed-variation-items {
2786
- display: flex;
2787
- flex-wrap: wrap;
2788
- }
2789
- .woo-feed-variation-items p {
2790
- width: 33.33%;
2791
- padding: 0 10px;
2792
- box-sizing: border-box;
2793
- }
2794
- .woo-feed-variation-items p:first-child,.woo-feed-variation-items p:last-child {
2795
- padding: 0;
2796
- }
2797
- </style>
2798
- <?php
2799
-
2800
- echo '<div class="woo-feed-variation-items">';
2801
- //GTIN variation input field
2802
- woocommerce_wp_text_input( array(
2803
- 'id' => "woo_feed_gtin_var[$variation->ID]",
2804
- 'value' => get_post_meta( $variation->ID, "woo_feed_gtin_var", true ),
2805
- 'placeholder' => esc_html( 'Set product GTIN', 'woo-feed' ),
2806
- 'label' => esc_html( 'GTIN', 'woo-feed' ),
2807
- ) );
2808
-
2809
- //MPN variation input field
2810
- woocommerce_wp_text_input( array(
2811
- 'id' => "woo_feed_mpn_var[$variation->ID]",
2812
- 'value' => get_post_meta( $variation->ID, 'woo_feed_mpn_var', true ),
2813
- 'placeholder' => esc_html( 'Set product MPN', 'woo-feed' ),
2814
- 'label' => esc_html( 'MPN', 'woo-feed' ),
2815
- ) );
2816
-
2817
- //EAN variation input field
2818
- woocommerce_wp_text_input( array(
2819
- 'id' => "woo_feed_ean_var[$variation->ID]",
2820
- 'value' => get_post_meta( $variation->ID, 'woo_feed_ean_var', true ),
2821
- 'placeholder' => esc_html( 'Set product EAN', 'woo-feed' ),
2822
- 'label' => esc_html( 'EAN', 'woo-feed' ),
2823
- ) );
2824
-
2825
- echo '</div></div>';
2826
-
 
 
2827
  }
2828
  add_action( 'woocommerce_product_after_variable_attributes', 'woo_feed_add_identifier_fields_for_variation', 10, 3 );
2829
  }
2678
  * @since 3.7.8
2679
  */
2680
  function woo_feed_add_identifier_fields() {
2681
+ $settings = woo_feed_get_options( 'all' );
2682
+
2683
+ if( isset($settings['disable_mpn']) && 'disable' !== $settings['disable_mpn'] ) {
2684
+ echo '<div class="options_group">';
2685
+ echo sprintf( '<h4 class="%s" style="padding-left: 10px;">%s</h4>', esc_attr( 'woo-feed-option-title' ), esc_html( 'Unique Identifier - Woo Feed', 'woo-feed' ) );
2686
+
2687
+ //GTIN input field
2688
+ woocommerce_wp_text_input( array(
2689
+ 'id' => 'woo_feed_gtin',
2690
+ 'value' => get_post_meta( get_the_ID(), 'woo_feed_gtin', true ),
2691
+ 'placeholder' => esc_html( 'Set product GTIN', 'woo-feed' ),
2692
+ 'label' => esc_html( 'GTIN', 'woo-feed' ),
2693
+ 'desc_tip' => true,
2694
+ 'description' => esc_html( 'Set product GTIN code here.', 'woo-feed' ),
2695
+ ) );
2696
+
2697
+ //MPN input field
2698
+ woocommerce_wp_text_input( array(
2699
+ 'id' => 'woo_feed_mpn',
2700
+ 'value' => get_post_meta( get_the_ID(), 'woo_feed_mpn', true ),
2701
+ 'placeholder' => esc_html( 'Set product MPN', 'woo-feed' ),
2702
+ 'label' => esc_html( 'MPN', 'woo-feed' ),
2703
+ 'desc_tip' => true,
2704
+ 'description' => esc_html( 'Set product MPN code here.', 'woo-feed' ),
2705
+ ) );
2706
+
2707
+ //EAN input field
2708
+ woocommerce_wp_text_input( array(
2709
+ 'id' => 'woo_feed_ean',
2710
+ 'value' => get_post_meta( get_the_ID(), 'woo_feed_ean', true ),
2711
+ 'placeholder' => esc_html( 'Set product EAN', 'woo-feed' ),
2712
+ 'label' => esc_html( 'EAN', 'woo-feed' ),
2713
+ 'desc_tip' => true,
2714
+ 'description' => esc_html( 'Set product EAN code here.', 'woo-feed' ),
2715
+ ) );
2716
+
2717
+ echo '</div>';
2718
+ }
2719
  }
2720
  add_action( 'woocommerce_product_options_inventory_product_data', 'woo_feed_add_identifier_fields');
2721
  }
2768
  * @since 3.7.8
2769
  */
2770
  function woo_feed_add_identifier_fields_for_variation( $loop, $variation_data, $variation ) {
2771
+ $settings = woo_feed_get_options( 'all' );
2772
+
2773
+ if( isset($settings['disable_mpn']) && 'disable' !== $settings['disable_mpn'] ) {
2774
+ echo '<div class="woo-feed-variation-options">';
2775
+ echo sprintf( '<h4 class="%s">%s</h4>', esc_attr( 'woo-feed-variation-option-title' ), esc_html( 'Unique Identifier - Woo Feed', 'woo-feed' ) );
2776
+ ?>
2777
+ <style>
2778
+ .woo-feed-variation-options {
2779
+ border-top: 1px solid #ccc;
2780
+ margin-top: 20px;
2781
+ }
2782
+ .woo-feed-variation-options h4 {
2783
+ margin-bottom: 0;
2784
+ }
2785
+ .woo-feed-variation-options .form-field input[type="text"] {
2786
+ width: 100%;
2787
+ padding: 5px;
2788
+ }
2789
+ .woo-feed-variation-items {
2790
+ display: flex;
2791
+ flex-wrap: wrap;
2792
+ }
2793
+ .woo-feed-variation-items p {
2794
+ width: 33.33%;
2795
+ padding: 0 10px;
2796
+ box-sizing: border-box;
2797
+ }
2798
+ .woo-feed-variation-items p:first-child,.woo-feed-variation-items p:last-child {
2799
+ padding: 0;
2800
+ }
2801
+ </style>
2802
+ <?php
2803
+
2804
+ echo '<div class="woo-feed-variation-items">';
2805
+ //GTIN variation input field
2806
+ woocommerce_wp_text_input( array(
2807
+ 'id' => "woo_feed_gtin_var[$variation->ID]",
2808
+ 'value' => get_post_meta( $variation->ID, "woo_feed_gtin_var", true ),
2809
+ 'placeholder' => esc_html( 'Set product GTIN', 'woo-feed' ),
2810
+ 'label' => esc_html( 'GTIN', 'woo-feed' ),
2811
+ ) );
2812
+
2813
+ //MPN variation input field
2814
+ woocommerce_wp_text_input( array(
2815
+ 'id' => "woo_feed_mpn_var[$variation->ID]",
2816
+ 'value' => get_post_meta( $variation->ID, 'woo_feed_mpn_var', true ),
2817
+ 'placeholder' => esc_html( 'Set product MPN', 'woo-feed' ),
2818
+ 'label' => esc_html( 'MPN', 'woo-feed' ),
2819
+ ) );
2820
+
2821
+ //EAN variation input field
2822
+ woocommerce_wp_text_input( array(
2823
+ 'id' => "woo_feed_ean_var[$variation->ID]",
2824
+ 'value' => get_post_meta( $variation->ID, 'woo_feed_ean_var', true ),
2825
+ 'placeholder' => esc_html( 'Set product EAN', 'woo-feed' ),
2826
+ 'label' => esc_html( 'EAN', 'woo-feed' ),
2827
+ ) );
2828
+
2829
+ echo '</div></div>';
2830
+ }
2831
  }
2832
  add_action( 'woocommerce_product_after_variable_attributes', 'woo_feed_add_identifier_fields_for_variation', 10, 3 );
2833
  }
libs/WebAppick/AppServices/Client.php CHANGED
@@ -193,18 +193,18 @@ class Client {
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.
@@ -213,34 +213,34 @@ class Client {
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.
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.
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.
libs/WebAppick/AppServices/License.php DELETED
@@ -1,1244 +0,0 @@
1
- <?php
2
- /**
3
- * WebAppick License Checker
4
- *
5
- * This class will check, active and deactivate license
6
- * @version 1.0.0
7
- * @package WebAppick
8
- * @subpackage AppServices
9
- */
10
-
11
- namespace WebAppick\AppServices;
12
-
13
- use WP_Theme;
14
-
15
- if ( ! defined( 'ABSPATH' ) ) {
16
- die();
17
- }
18
-
19
- /**
20
- * Class License
21
- */
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
103
- * @type int $expiry_day Number of day remaining before the license expires
104
- * }
105
- */
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
- */
127
- public function __construct( Client $client ) {
128
- $this->client = $client;
129
- $this->option_key = 'WebAppick_' . md5( $this->client->getSlug() ) . '_manage_license';
130
- $this->data_key = $this->client->getSlug() . '-license';
131
- $this->schedule_hook = $this->client->getSlug() . '_license_check_event';
132
- // load the license.
133
- $this->getLicense();
134
- add_action( 'init', [ $this, 'handle_license_page_form' ], 10 );
135
- }
136
-
137
- /**
138
- * Initialize License.
139
- *
140
- * @return void
141
- */
142
- public function init() {
143
- // check the validity and save the state.
144
- $this->is_valid();
145
- // Run hook to check license status daily.
146
- add_action( $this->schedule_hook, array( $this, 'check_license_status' ) );
147
- $this->currentUserCanManage = $this->menu_args['capability'];
148
- $this->isLicensePage = isset( $_GET['page'] ) && $_GET['page'] === $this->menu_args['menu_slug']; // phpcs:ignore
149
- add_action( 'plugin_action_links_' . $this->client->getBasename(), [ $this, 'plugin_action_links' ] );
150
- add_action( 'admin_notices', array( $this, '__admin_notices' ), 10 );
151
- // Activation/Deactivation hooks.
152
- $this->activation_deactivation();
153
- $this->didInit = true;
154
- }
155
-
156
- /**
157
- * Expose the License Key.
158
- *
159
- * @return void|string
160
- */
161
- public function get_key() {
162
- $this->getLicense();
163
- return $this->license['key'];
164
- }
165
-
166
- /**
167
- * Display Admin Notices.
168
- *
169
- * @return void
170
- */
171
- public function __admin_notices() {
172
- if ( ! current_user_can( $this->currentUserCanManage ) ) return;
173
- if ( defined( 'WP_HTTP_BLOCK_EXTERNAL' ) && WP_HTTP_BLOCK_EXTERNAL === true ) {
174
- $host = wp_parse_url( $this->__getLicenceAPI(), PHP_URL_HOST );
175
- if ( ! defined( 'WP_ACCESSIBLE_HOSTS' ) || ( defined( 'WP_ACCESSIBLE_HOSTS' ) && false === stristr( WP_ACCESSIBLE_HOSTS, $host ) ) ) {
176
- ?>
177
- <div class="notice notice-error">
178
- <p><?php
179
- printf(
180
- /* translators: 1: Warning in bold tag, 2: This plugin name, 3: API Host Name, 4: WP_ACCESSIBLE_HOSTS constant */
181
- esc_html__( '%1$s You\'re blocking external requests which means you won\'t be able to get %2$s updates. Please add %3$s to %4$s.', 'woo-feed' ),
182
- '<b>'. esc_html__( 'Warning!', 'woo-feed' ).'</b>',
183
- esc_html( $this->client->getName() ),
184
- '<strong>' . esc_html( $host ) . '</strong>',
185
- '<code>WP_ACCESSIBLE_HOSTS</code>'
186
- );
187
- ?></p>
188
- </div>
189
- <?php
190
- }
191
- }
192
- if ( ! $this->isLicensePage && ! $this->is_valid() ) {
193
- ?>
194
- <div class="notice notice-error">
195
- <p><?php
196
- printf(
197
- /* translators: 1: This plugin name, 2: Plugin/Theme, 3: Activation Page URL, 4: This Plugin Name */
198
- esc_html__( 'The %1$s API Key has not been activated, so the %2$s is inactive! %3$s to activate %4$s.', 'woo-feed' ),
199
- '<strong>' . esc_attr( $this->client->getName() ) . '</strong>',
200
- esc_attr( $this->client->getType() ),
201
- '<a href="' . esc_url( admin_url( 'admin.php?page=' . $this->menu_args['menu_slug'] ) ) . '">'. esc_html__( 'Click here', 'woo-feed' ) .'</a>',
202
- '<strong>' . esc_attr( $this->client->getName() ) . '</strong>'
203
- );
204
- ?></p>
205
- </div>
206
- <?php
207
- }
208
- if ( ! empty( $this->error ) ) {
209
- ?>
210
- <div class="notice notice-error is-dismissible">
211
- <p><?php echo $this->error; // phpcs:ignore xss ok ?></p>
212
- </div>
213
- <?php
214
- }
215
- if ( ! empty( $this->success ) ) {
216
- ?>
217
- <div class="notice notice-success is-dismissible">
218
- <p><?php echo $this->success; // phpcs:ignore xss ok ?></p>
219
- </div>
220
- <?php
221
- }
222
- }
223
-
224
- /**
225
- * Setup plugin action link to the license page.
226
- *
227
- * @param array $links plugin action links.
228
- * @return array
229
- */
230
- public function plugin_action_links( $links ) {
231
- if ( ! empty( $this->menu_args['menu_slug'] ) && ! empty( $this->menu_args['menu_title'] ) ) {
232
- /** @noinspection HtmlUnknownTarget */
233
- $links[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=' . $this->menu_args['menu_slug'] ) ), esc_html( $this->menu_args['menu_title'] ) );
234
- }
235
- return $links;
236
- }
237
-
238
- /**
239
- * Check license.
240
- *
241
- * @return array
242
- */
243
- public function check() {
244
- return $this->send_request( 'status', $this->license );
245
- }
246
-
247
- /**
248
- * Check Plugin Update.
249
- *
250
- * @return array
251
- */
252
- public function check_update() {
253
- return $this->send_request( 'update', $this->license );
254
- }
255
-
256
- /**
257
- * Get Plugin data.
258
- *
259
- * @return array {
260
- * Plugin Information
261
- * @type bool $success API response status
262
- * @type string $api_call_execution_time API Man (Rest Response) Execution Time
263
- * @type array $data {
264
- * Plugin Data ( API Man.)
265
- * @type array $package {
266
- * @type int $product_id API Man Product ID
267
- * }
268
- * @type array $info {
269
- * @type string $id Plugin Id
270
- * @type string $name Plugin Name
271
- * @type string $author Author Name
272
- * @type string $author_profile Author Profile URL
273
- * @type string $slug Plugin Slug
274
- * @type string $plugin Plugin main file path
275
- * @type string $new_version New Version String
276
- * @type string $url Plugin URL
277
- * @type string $package Plugin update download URL
278
- * @type string $icons Plugin Icons
279
- * @type string $banners Plugin Banners
280
- * @type string $banner_rtl RTL Version of Plugin Banners
281
- * @type string $upgrade_notice Upgrade Notice
282
- * @type string $requires Minimum WordPress Version
283
- * @type string $requires_php Minimum PHP Version
284
- * @type string $tested Tested upto WordPress Version
285
- * @type array $compatibility Compatibility information (API Man sends string)
286
- * @type array $contributors Plugin Contributors List (if available)
287
- * @type array $ratings Plugin Rating (if available)
288
- * @type float $num_ratings Plugin Rating (if available)
289
- * @type string $last_updated Last updated Date
290
- * @type string $homepage Plugin Home Page URL
291
- * @type array $sections {
292
- * Plugin Description Sections
293
- * @type string $description Plugin Description
294
- * @type string $changelog Change LOG
295
- * }
296
- * @type mixed $author_block_count
297
- * @type mixed $author_block_rating
298
- * }
299
- * }
300
- * }
301
- */
302
- public function get_information() {
303
- return $this->send_request( 'information', $this->license );
304
- }
305
-
306
- /**
307
- * Active a license.
308
- *
309
- * @param array $license license data.
310
- * @return array
311
- */
312
- public function activate( $license ) {
313
- return $this->send_request( 'activate', $license );
314
- }
315
-
316
- /**
317
- * Deactivate current license.
318
- *
319
- * @return array
320
- */
321
- public function deactivate() {
322
- return $this->send_request( 'deactivate', $this->license );
323
- }
324
-
325
- /**
326
- * Send common request.
327
- *
328
- * @param string $action request action.
329
- * @param array $license license data.
330
- *
331
- * @return array
332
- */
333
- protected function send_request( $action, $license = [] ) {
334
- // WC-AM Valid Actions and response data types.
335
- $actions = [
336
- 'activate' => 'json',
337
- 'deactivate' => 'json',
338
- 'status' => 'json',
339
- 'information' => 'json',
340
- 'update' => 'json',
341
- 'plugininformation' => 'serialize', // serialize option doesn't provide success status.
342
- 'pluginupdatecheck' => 'serialize',
343
- ];
344
- if ( ! in_array( $action, array_keys( $actions ) ) ) {
345
- return [
346
- 'success' => false,
347
- 'error' => esc_html__( 'Invalid Request Action.', 'woo-feed' ),
348
- ];
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.', 'woo-feed' ),
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
- ];
369
- $this->setAPI_URL();
370
- $response = $this->client->send_request( $params, '', true );
371
- $this->restoreAPI_URL();
372
- if ( ! is_wp_error( $response ) ) {
373
- $response = wp_remote_retrieve_body( $response );
374
- if ( 'json' == $actions[ $action ] ) {
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.', 'woo-feed' ),
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() {
416
- return 'https://webappick.com/?wc-api=wc-am-api';
417
- }
418
-
419
- /**
420
- * Filter api url for licensing api.
421
- *
422
- * @return void
423
- */
424
- private function setAPI_URL() {
425
- add_filter( $this->client->getSlug() . '_WebAppick_API_URL', [ $this, '__getLicenceAPI' ], 10 );
426
- }
427
-
428
- /**
429
- * Remove filter for changing wpi url.
430
- *
431
- * @see License::setAPI_URL()
432
- * @return void
433
- */
434
- private function restoreAPI_URL() {
435
- remove_filter( $this->client->getSlug() . '_WebAppick_API_URL', [ $this, '__getLicenceAPI' ], 10 );
436
- }
437
-
438
- /**
439
- * Add settings page for license.
440
- *
441
- * @param array $args settings for rendering the menu.
442
- *
443
- * @return void
444
- */
445
- public function add_settings_page( $args = array() ) {
446
- if ( $this->didInit ) {
447
- _doing_it_wrong( __METHOD__, sprintf( '<code>%s</code> Should be called before License::init()', __METHOD__ ), '1.0.1' );
448
- return;
449
- }
450
- $defaults = [
451
- 'type' => 'menu', // Can be: menu, options, submenu.
452
- 'page_title' => esc_html__( 'Manage License', 'woo-feed' ),
453
- 'menu_title' => esc_html__( 'Manage License', 'woo-feed' ),
454
- 'capability' => 'manage_options',
455
- 'menu_slug' => $this->client->getSlug() . '-manage-license',
456
- 'icon_url' => '',
457
- 'position' => null,
458
- 'parent_slug' => '',
459
- ];
460
- $this->menu_args = wp_parse_args( $args, $defaults );
461
- if ( ! in_array( $this->menu_args['type'], [ 'menu', 'options', 'submenu' ] ) ) {
462
- if ( empty( $this->menu_args['parent_slug'] ) ) {
463
- $this->menu_args['type'] = 'menu';
464
- }
465
- }
466
- if ( 'submenu' == $this->menu_args['type'] && empty( $this->menu_args['parent_slug'] ) ) {
467
- $this->menu_args['type'] = 'options';
468
- }
469
- add_action( 'admin_menu', array( $this, 'admin_menu' ), 999 );
470
- }
471
-
472
- /**
473
- * Admin Menu hook.
474
- *
475
- * @return void
476
- */
477
- public function admin_menu() {
478
- switch ( $this->menu_args['type'] ) {
479
- case 'submenu':
480
- $this->add_submenu_page();
481
- break;
482
- case 'options':
483
- $this->add_options_page();
484
- break;
485
- case 'menu':
486
- default:
487
- $this->add_menu_page();
488
- break;
489
- }
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', 'woo-feed' ); ?></h1>
504
- <hr class="wp-header-end">
505
- <?php do_action( 'before_webappick_' . $this->client->getSlug() . '_license_section' ); ?>
506
- <div class="webappick-license-settings webappick-license-section">
507
- <?php $this->show_license_page_card_header(); ?>
508
- <div class="webappick-license-details">
509
- <?php if ( 'activate' == $action ) { ?>
510
- <p><?php
511
- /* translators: %s: This Plugin Name */
512
- printf( esc_html__( 'Active %s by your license key to get professional support and automatic update from your WordPress dashboard.', 'woo-feed' ), '<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', 'woo-feed' ); ?></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', 'woo-feed' ); ?>"
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', 'woo-feed' ); ?></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', 'woo-feed' ); ?>"
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', 'woo-feed' ); ?></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', 'woo-feed' ); ?></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', 'woo-feed' ) : esc_html_e( 'Deactivate License', 'woo-feed' );
611
- ?></button>
612
- <a href="http://webappick.com/my-account/api-keys/" class="button button-primary button-hero" style="margin-left: 20px;font-size: 17px;line-height: 2.5;" target="_blank"><?php esc_html_e( 'Manage License', 'woo-feed' ); ?></a>
613
- </div>
614
- </form>
615
- <?php $this->show_active_license_info(); ?>
616
- </div>
617
- </div> <!-- /.webappick-license-settings -->
618
- <?php do_action( 'after_webappick_' . $this->client->getSlug() . '_license_section' ); ?>
619
- </div>
620
- <?php
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() {
642
- if ( isset( $_POST[ $this->data_key ], $_POST[ $this->data_key ]['_action'] ) ) {
643
- check_admin_referer( $this->data_key );
644
- switch ( $_POST[ $this->data_key ]['_action'] ) {
645
- case 'activate':
646
- $this->activate_client_license( array_map( 'sanitize_text_field', $_POST[ $this->data_key ] ) );
647
- break;
648
- case 'deactivate':
649
- $this->deactivate_client_license();
650
- break;
651
- default:
652
- break;
653
- }
654
- }
655
- }
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() {
664
- // get current license data.
665
- $license = $this->getLicense();
666
- if ( $license ) {
667
- // check license.
668
- $response = $this->check();
669
- if ( isset( $response['success'], $response['status_check'] ) && $response['success'] ) {
670
- // update license status.
671
- $license = wp_parse_args(
672
- [
673
- 'status' => 'active' == $response['status_check'] ? 'active' : 'inactive',
674
- 'remaining' => isset( $response['data'], $response['data']['activations_remaining'] ) ? $response['data']['activations_remaining'] : 0,
675
- 'activations' => isset( $response['data'], $response['data']['total_activations'] ) ? $response['data']['total_activations'] : 0,
676
- 'limit' => isset( $response['data'], $response['data']['total_activations_purchased'] ) ? $response['data']['total_activations_purchased'] : 0,
677
- 'unlimited' => isset( $response['data'], $response['data']['unlimited_activations'] ) ? $response['data']['unlimited_activations'] : false,
678
- 'expiry_date' => 0, // wc-am doesn't sent remaining date.
679
- ],
680
- $license
681
- );
682
- } else {
683
- // Don't reset the key.
684
- // keep it, if the user renew subscription update the status and reactivate the plugin.
685
- $license = wp_parse_args(
686
- [
687
- 'status' => 'inactive',
688
- 'remaining' => 0,
689
- 'activations' => 0,
690
- 'limit' => 0,
691
- 'unlimited' => false,
692
- 'expiry_date' => 0, // wc-am doesn't sent remaining date.
693
- ],
694
- $license
695
- );
696
- }
697
- // update the license state & and save in db.
698
- $this->setLicense( $license );
699
- }
700
- }
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;
725
- }
726
-
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
- */
752
- public function migrate_license_from_wc_am( $override = false ) {
753
- // phpcs:disable
754
- /*// WC AM data structure.
755
- [
756
- '_data' => [ 'api_key', 'activation_email', ], // api key & email
757
- '_product_id' => '', // product title or name
758
- '_instance' => '', // instance key unique id
759
- '_activated' => '', // activation status => Activated|Deactivated
760
- '_deactivate_checkbox' => '', // deactivation check box state > On|Off
761
- ];*/
762
- // phpcs:enable
763
- // check if already migrated || override.
764
- if ( 1 == get_option( $this->option_key . '_wc_am_migrated', false ) && ! $override ) {
765
- return false;
766
- }
767
- // is already migrated.
768
- // api manager data prefix.
769
- $wcAmPrefix = str_ireplace( array( ' ', '_', '&', '?' ), '_', strtolower( $this->client->getName() ) );
770
- $license = [
771
- 'key' => '',
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 );
799
- return true;
800
- }
801
-
802
- /**
803
- * Styles for licenses page.
804
- *
805
- * @return void
806
- */
807
- private function licenses_style() {
808
- ?>
809
- <!--suppress CssUnusedSymbol -->
810
- <style>
811
- .webappick-license-settings *{-webkit-box-sizing:border-box;box-sizing:border-box}
812
- .webappick-license-settings{margin-top:20px;background-color:#fff;-webkit-box-shadow:0 3px 10px rgba(16,16,16,.05);box-shadow:0 3px 10px rgba(16,16,16,.05)}
813
- .webappick-license-section{width:100%;min-height:1px;-webkit-box-sizing:border-box;box-sizing:border-box}
814
- .webappick-license-title{background-color:#f8fafb;border-bottom:2px solid #eaeaea;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 20px}
815
- .webappick-license-title svg{width:30px;height:30px;fill:#0082bf}
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}
834
- .license-input-fields button:focus{outline:0 none}
835
- .active-license-info{display:-webkit-box;display:-ms-flexbox;display:flex}
836
- .single-license-info{margin-right:40px}
837
- .single-license-info:last-child{margin-right:0}
838
- .single-license-info h3{font-size:15px;margin:0 0 12px 0;display:inline-block}
839
- .single-license-info p{margin:0 0 0 5px;font-size:15px;font-weight:500;display:inline-block}
840
- .single-license-info p.active{color:#047167}
841
- .single-license-info p.inactive{color:#e40055}
842
- </style>
843
- <?php
844
- }
845
-
846
- /**
847
- * Show active license information.
848
- *
849
- * @return void
850
- */
851
- private function show_active_license_info() {
852
- $status = ( isset( $this->license['status'] ) && 'active' === $this->license['status'] ) ? 'active' : 'inactive';
853
- $limit = isset( $this->license['limit'] ) ? $this->license['limit'] : 0;
854
- $activations = isset( $this->license['activations'] ) ? $this->license['activations'] : 0;
855
- $remaining = isset( $this->license['remaining'] ) ? $this->license['remaining'] : 0;
856
- $unlimited = isset( $this->license['unlimited'] ) ? $this->license['unlimited'] : false;
857
- ?>
858
- <div class="active-license-info">
859
- <div class="single-license-info">
860
- <h3><?php esc_html_e( 'Status:', 'woo-feed' ); ?></h3>
861
- <p class="<?php echo esc_attr( $status ); ?>"><?php 'active' == $status ? esc_html_e( 'Active', 'woo-feed' ) : esc_html_e( 'Inactive', 'woo-feed' ); ?></p>
862
- </div>
863
- <?php if ( false !== $unlimited ) { ?>
864
- <div class="single-license-info">
865
- <h3><?php esc_html_e( 'Activation Limit:', 'woo-feed' ); ?></h3>
866
- <p class="active"><?php esc_html_e( 'Unlimited', 'woo-feed' ); ?></p>
867
- </div>
868
- <div class="single-license-info">
869
- <h3><?php esc_html_e( 'Total Activation:', 'woo-feed' ); ?></h3>
870
- <p class="active"><?php echo esc_attr( $activations ); ?></p>
871
- </div>
872
- <?php } else { ?>
873
- <div class="single-license-info">
874
- <h3><?php esc_html_e( 'Activation Remaining:', 'woo-feed' ); ?></h3>
875
- <p class="<?php echo $remaining ? 'active' : 'inactive'; ?>"><?php
876
- if ( 'active' == $status ) {
877
- /* translators: 1: Remaining activation, 2: Total activation */
878
- printf( esc_html__( '%1$d out of %2$d', 'woo-feed' ), esc_attr( $remaining ), esc_attr( $limit ) );
879
- } else {
880
- esc_html_e( 'N/A', 'woo-feed' );
881
- }
882
- ?></p>
883
- </div>
884
- <?php } ?>
885
- <div class="single-license-info">
886
- <h3><?php esc_html_e( 'Automatic Update:', 'woo-feed' ); ?></h3>
887
- <p class="<?php echo esc_attr( $status ); ?>"><?php 'active' == $status ? esc_html_e( 'Enabled', 'woo-feed' ) : esc_html_e( 'Disabled', 'woo-feed' ); ?></p>
888
- </div>
889
- </div>
890
- <?php
891
- }
892
-
893
- /**
894
- * Card header.
895
- *
896
- * @return void
897
- */
898
- private function show_license_page_card_header() {
899
- ?>
900
- <div class="webappick-license-title">
901
- <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">
902
- <path d="m150 161.48c-8.613 0-15.598 6.982-15.598 15.598 0 5.776 3.149 10.807 7.817 13.505v17.341h15.562v-17.341c4.668-2.697 7.817-7.729 7.817-13.505 0-8.616-6.984-15.598-15.598-15.598z"/>
903
- <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"/>
904
- <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"/>
905
- </svg>
906
- <span><?php esc_html_e( 'Activate License', 'woo-feed' ); ?></span>
907
- </div>
908
- <?php
909
- }
910
-
911
- /**
912
- * Active client license.
913
- *
914
- * @param array $postData Sanitized Form $_POST Data.
915
- * @return void
916
- */
917
- private function activate_client_license( $postData ) {
918
- if ( empty( $postData['license_key'] ) ) {
919
- $this->error = esc_html__('The license key field is required.', 'woo-feed' );
920
- return;
921
- }
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'] ) {
929
- $check = $this->check(); // check api status.
930
- if ( $check['success'] && 'inactive' !== $check['status_check'] ) {
931
- $this->error = $deactivate['error'] ? $deactivate['error'] : esc_html__( 'Unknown error occurred.', 'woo-feed' );
932
- return;
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'] ) {
942
- $this->error = $response['error'] ? $response['error'] : esc_html__( 'Unknown error occurred.', 'woo-feed' );
943
- return;
944
- }
945
- // Don't reset the key.
946
- // keep it, if the user renew subscription update the status and reactivate the plugin.
947
- $license = array_merge(
948
- $license,
949
- [
950
- 'status' => isset( $response['activated'] ) && $response['activated'] ? 'active' : 'inactive',
951
- 'remaining' => isset( $response['data'], $response['data']['activations_remaining'] ) ? $response['data']['activations_remaining'] : 0,
952
- 'activations' => isset( $response['data'], $response['data']['total_activations'] ) ? $response['data']['total_activations'] : 0,
953
- 'limit' => isset( $response['data'], $response['data']['total_activations_purchased'] ) ? $response['data']['total_activations_purchased'] : 0,
954
- 'unlimited' => isset( $response['data'], $response['data']['unlimited_activations'] ) ? $response['data']['unlimited_activations'] : false,
955
- 'expiry_date' => 0, // wc-am doesn't sent remaining date.
956
- ]
957
- );
958
- $this->setLicense( $license );
959
- if ( ! $updateKey ) {
960
- $this->success = esc_html__( 'License activated successfully.', 'woo-feed' );
961
- } else {
962
- $this->success = esc_html__( 'License Updated successfully.', 'woo-feed' );
963
- }
964
- }
965
-
966
- /**
967
- * deactivate client license.
968
- *
969
- * @return void
970
- */
971
- private function deactivate_client_license() {
972
- if ( ! isset( $this->license['key'] ) || empty( $this->license['key'] ) ) {
973
- $this->error = esc_html__( 'License key not found.', 'woo-feed' );
974
- } else {
975
- $response = $this->deactivate();
976
- if ( ! $response['success'] ) {
977
- // check api status.
978
- $check = $this->check();
979
- if ( $check['success'] && 'inactive' !== $check['status_check'] ) {
980
- $this->error = $response['error'] ? $response['error'] : esc_html__( 'Unknown error occurred.', 'woo-feed' );
981
- }
982
- }
983
- }
984
- // keep the instance key for reference.
985
- $this->setLicense( [ 'instance' => $this->license['instance'] ] );
986
- $this->success = esc_html__( 'License deactivated successfully.', 'woo-feed' );
987
- }
988
-
989
- /**
990
- * Add license menu page.
991
- *
992
- * @return void
993
- */
994
- private function add_menu_page() {
995
- add_menu_page(
996
- esc_html( $this->menu_args['page_title'] ),
997
- esc_html( $this->menu_args['menu_title'] ),
998
- $this->menu_args['capability'],
999
- $this->menu_args['menu_slug'],
1000
- array( $this, 'menu_output' ),
1001
- $this->menu_args['icon_url'],
1002
- $this->menu_args['position']
1003
- );
1004
- }
1005
-
1006
- /**
1007
- * Add submenu page.
1008
- *
1009
- * @return void
1010
- */
1011
- private function add_submenu_page() {
1012
- add_submenu_page(
1013
- $this->menu_args['parent_slug'],
1014
- esc_html( $this->menu_args['page_title'] ),
1015
- esc_html( $this->menu_args['menu_title'] ),
1016
- $this->menu_args['capability'],
1017
- $this->menu_args['menu_slug'],
1018
- array( $this, 'menu_output' )
1019
- );
1020
- }
1021
-
1022
- /**
1023
- * Add submenu page.
1024
- *
1025
- * @return void
1026
- */
1027
- private function add_options_page() {
1028
- add_options_page(
1029
- esc_html( $this->menu_args['page_title'] ),
1030
- esc_html( $this->menu_args['menu_title'] ),
1031
- $this->menu_args['capability'],
1032
- $this->menu_args['menu_slug'],
1033
- array( $this, 'menu_output' )
1034
- );
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 ) ) {
1044
- wp_schedule_event( time(), 'daily', $this->schedule_hook );
1045
- wp_schedule_single_event( time() + 20, $this->schedule_hook );
1046
- }
1047
- }
1048
-
1049
- /**
1050
- * Clear any scheduled hook.
1051
- *
1052
- * @return void
1053
- */
1054
- public function clear_scheduler() {
1055
- wp_clear_scheduled_hook( $this->schedule_hook );
1056
- }
1057
-
1058
- /**
1059
- * Register Activation And Deactivation Hooks.
1060
- *
1061
- * @return void
1062
- */
1063
- private function activation_deactivation() {
1064
- switch ( $this->client->getType() ) {
1065
- case 'plugin':
1066
- register_activation_hook( $this->client->getBasename(), array( $this, 'schedule_cron_event' ) );
1067
- register_deactivation_hook( $this->client->getBasename(), array( $this, 'project_deactivation' ) );
1068
- add_action( 'activated_plugin', array( $this, 'redirect_to_license_page' ), 999, 2 );
1069
- break;
1070
- case 'theme':
1071
- add_action( 'switch_theme', array( $this, 'project_deactivation' ), 10 );
1072
- add_action( 'after_switch_theme', array( $this, 'schedule_cron_event' ), 10 );
1073
- add_action( 'after_switch_theme', array( $this, 'redirect_to_license_page' ), 999, 2 );
1074
- break;
1075
- }
1076
- }
1077
-
1078
- /**
1079
- * Project Deactivation Callback.
1080
- *
1081
- * @return void
1082
- */
1083
- public function project_deactivation() {
1084
- $this->clear_scheduler();
1085
- $this->getLicense();
1086
- $this->deactivate_client_license();
1087
- }
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() );
1103
- }
1104
- if ( 'theme' == $this->client->getType() ) {
1105
- $canRedirect = ( ! get_option( 'theme_switched_via_customizer' ) );
1106
- }
1107
- if ( $canRedirect ) {
1108
- wp_safe_redirect( admin_url( 'admin.php?page=' . $this->menu_args['menu_slug'] ) );
1109
- die();
1110
- }
1111
- }
1112
-
1113
- /**
1114
- * Form action URL.
1115
- *
1116
- * @return void
1117
- */
1118
- private function formActionUrl() {
1119
- global $plugin_page;
1120
- if( ! isset( $_SERVER['SCRIPT_NAME'], $plugin_page ) ) return; // phpcs:ignore
1121
- echo esc_url(
1122
- add_query_arg(
1123
- array( 'page' => sanitize_text_field( $plugin_page ) ), // phpcs:ignore
1124
- admin_url( basename( sanitize_text_field( $_SERVER['SCRIPT_NAME'] ) ) )
1125
- )
1126
- );
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
1135
- */
1136
- private function get_input_license_value( $action, $license ) {
1137
- // phpcs:disable
1138
- // if ( 'deactivate' != $action ) return '';
1139
- // $key_length = strlen( $license['key'] );
1140
- // return str_pad( substr( $license['key'], 0, $key_length / 2 ), $key_length, '*' );
1141
- // phpcs:enable
1142
- return isset( $license['key'] ) ? $license['key'] : '';
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() {
1158
- if ( null !== $this->license ) {
1159
- return $this->license;
1160
- }
1161
- $this->license = get_option( $this->option_key, false );
1162
- // initialize blank inactive license data.
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
- */
1184
- private function setLicense( $license = [] ) {
1185
- $this->license = $this->parse_license_data( $license );
1186
- // update in db.
1187
- return update_option( $this->option_key, $this->license, false );
1188
- }
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 );
1211
- $license = array();
1212
- // sanitize data.
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'] );
1220
- $license['unlimited'] = (bool) $data['unlimited'];
1221
- $license['expiry_date'] = absint( $data['expiry_date'] );
1222
- return $license;
1223
- }
1224
-
1225
- /**
1226
- * Generate a random Instance ID.
1227
- *
1228
- * @return string
1229
- */
1230
- private function generateInstanceId() {
1231
- $id = false;
1232
- if ( function_exists( 'wp_generate_password' ) ) {
1233
- $id = wp_generate_password( 12, false );
1234
- if ( 12 !== strlen( $id ) ) {
1235
- $id = false;
1236
- }
1237
- }
1238
- if ( ! $id ) {
1239
- $id = md5( uniqid( wp_rand( 100, 100000 ), true ) );
1240
- }
1241
- return $id;
1242
- }
1243
- }
1244
- // End of file License.php.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
libs/WebAppick/AppServices/Updater.php DELETED
@@ -1,265 +0,0 @@
1
- <?php
2
- /**
3
- * WebAppick Updater
4
- *
5
- * This class will show new updates project
6
- * @version 1.0.0
7
- * @package WebAppick
8
- * @subpackage AppServices
9
- */
10
-
11
- namespace WebAppick\AppServices;
12
-
13
- use stdClass;
14
-
15
- if ( ! defined( 'ABSPATH' ) ) {
16
- die();
17
- }
18
-
19
- /**
20
- * Class Updater
21
- * @package WebAppick\AppServices
22
- */
23
- class Updater {
24
-
25
- /**
26
- * WebAppick\AppServices\Client
27
- *
28
- * @var Client
29
- */
30
- protected $client;
31
-
32
- /**
33
- * Flag for checking if the init method is already called.
34
- * @var bool
35
- */
36
- private $didInit = false;
37
-
38
- /**
39
- * WebAppick\AppServices\License
40
- *
41
- * @var License
42
- */
43
- protected $license;
44
-
45
- /**
46
- * Cache Key for current App
47
- * @var string
48
- */
49
- private $cache_key;
50
-
51
- /**
52
- * Initialize the class
53
- *
54
- * @param Client $client The Client.
55
- * @param License $license The license.
56
- */
57
- public function __construct( Client $client, License $license ) {
58
- $this->client = $client;
59
- $this->license = $license;
60
- $this->cache_key = 'WebAppick_' . md5( $this->client->getSlug() ) . '_version_info';
61
- }
62
-
63
- /**
64
- * Initialize Updater
65
- *
66
- * @return void
67
- */
68
- public function init() {
69
- // Run hooks.
70
- if ( $this->client->getType() == 'plugin' ) {
71
- $this->run_plugin_hooks();
72
- } elseif ( $this->client->getType() == 'theme' ) {
73
- $this->run_theme_hooks();
74
- }
75
- $this->didInit = true;
76
- }
77
-
78
- /**
79
- * Set up WordPress filter to hooks to get update.
80
- *
81
- * @return void
82
- */
83
- private function run_plugin_hooks() {
84
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_plugin_update' ) );
85
- add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
86
- register_deactivation_hook( $this->client->getFile(), array( $this, 'delete_cached_version_info' ) );
87
- }
88
-
89
- /**
90
- * Set up WordPress filter to hooks to get update.
91
- *
92
- * @return void
93
- */
94
- private function run_theme_hooks() {
95
- add_filter( 'pre_set_site_transient_update_themes', array( $this, 'check_theme_update' ) );
96
- add_action( 'switch_theme', array( $this, 'delete_cached_version_info' ) );
97
- }
98
-
99
- /**
100
- * Check for Update for this specific project
101
- * @param object $transient_data plugin update transient data.
102
- * @return object
103
- */
104
- public function check_plugin_update( $transient_data ) {
105
- global $pagenow;
106
-
107
- if ( ! isset( $transient_data->checked ) || isset( $transient_data->checked ) && empty( $transient_data->checked ) ) {
108
- return $transient_data;
109
- }
110
- if ( ! is_object( $transient_data ) ) {
111
- $transient_data = new stdClass();
112
- }
113
- if ( 'plugins.php' == $pagenow && is_multisite() ) return $transient_data;
114
- if ( ! empty( $transient_data->response ) && ! empty( $transient_data->response[ $this->client->getBasename() ] ) ) {
115
- return $transient_data;
116
- }
117
- $project_info = $this->get_cached_version_info();
118
-
119
- if ( false === $project_info || ! is_object( $project_info ) ) {
120
- $project_info = $this->get_information();
121
- $this->set_cached_version_info( $project_info );
122
- }
123
- if ( false !== $project_info && is_object( $project_info ) && isset( $project_info->new_version ) ) {
124
- if ( version_compare( $this->client->getProjectVersion(), $project_info->new_version, '<' ) ) {
125
- unset( $project_info->sections );
126
- $transient_data->response[ $this->client->getBasename() ] = $project_info;
127
- }
128
- $transient_data->last_checked = time();
129
- $transient_data->checked[ $this->client->getBasename() ] = $this->client->getProjectVersion();
130
- }
131
- return $transient_data;
132
- }
133
-
134
- /**
135
- * Get version info from database
136
- *
137
- * @return object|bool
138
- */
139
- private function get_cached_version_info() {
140
- $info = get_transient( $this->cache_key );
141
- if ( ! $info && ! isset( $info->name ) ) {
142
- return false; // Cache is expired.
143
- }
144
- return $this->__children_to_array( $info, [ 'icons', 'banners', 'sections' ] );
145
- }
146
-
147
- /**
148
- * Set version info to database
149
- * @param string $value data (version info) to cache.
150
- * @return void
151
- */
152
- private function set_cached_version_info( $value ) {
153
- if ( ! $value ) return;
154
- set_transient( $this->cache_key, $value, 3 * HOUR_IN_SECONDS );
155
- }
156
-
157
- /**
158
- * Delete cached version info
159
- * @return bool
160
- */
161
- public function delete_cached_version_info() {
162
- return delete_transient( $this->cache_key );
163
- }
164
-
165
- /**
166
- * Get plugin info from WebAppick
167
- * @return bool|array
168
- */
169
- private function get_information() {
170
- $response = $this->license->check_update();
171
- if ( isset( $response['success'] ) && $response['success'] ) {
172
- $data = $response['data']['package'];
173
- $response = $this->license->get_information();
174
- if ( isset( $response['success'] ) && $response['success'] ) {
175
- $data = array_merge( $data, $response['data']['info'] );
176
- }
177
- if ( isset( $data['product_id'] ) ) {
178
- unset( $data['product_id'] );
179
- }
180
- /**
181
- * Filter API Response Data
182
- * @param array $data
183
- */
184
- $data = apply_filters( 'WebAppick_' . $this->client->getSlug() . '_plugin_api_info', $data );
185
- return $this->__children_to_array( (object) $data, [ 'icons', 'banners', 'sections', 'compatibility', 'ratings', 'contributors', 'screenshots', 'tags' ] );
186
- }
187
- return false;
188
- }
189
-
190
- /**
191
- * Updates information on the "View version x.x details" page with custom data.
192
- *
193
- * @param mixed $data Plugin info Data.
194
- * @param string $action Request Action.
195
- * @param object $args API Args.
196
- *
197
- * @return object $data
198
- */
199
- public function plugins_api_filter( $data, $action = '', $args = null ) {
200
- if ( 'plugin_information' != $action ) {
201
- return $data;
202
- }
203
- if ( ! isset( $args->slug ) || ( $args->slug != $this->client->getSlug() ) ) return $data;
204
- $project_info = $this->get_cached_version_info();
205
- if ( false === $project_info ) {
206
- $project_info = $this->get_information();
207
- $this->set_cached_version_info( $project_info );
208
- }
209
- return $project_info;
210
- }
211
-
212
- /**
213
- * Check theme update
214
- * @param object $transient_data Theme update transient data.
215
- * @return object
216
- */
217
- public function check_theme_update( $transient_data ) {
218
- global $pagenow;
219
- if ( ! is_object( $transient_data ) ) {
220
- $transient_data = new stdClass();
221
- }
222
- if ( 'themes.php' == $pagenow && is_multisite() ) return $transient_data;
223
- if ( ! empty( $transient_data->response ) && ! empty( $transient_data->response[ $this->client->getSlug() ] ) ) {
224
- return $transient_data;
225
- }
226
- $project_info = $this->get_cached_version_info();
227
- if ( false === $project_info ) {
228
- $project_info = $this->get_information();
229
- $this->set_cached_version_info( $project_info );
230
- }
231
- if ( false !== $project_info && is_object( $project_info ) && isset( $project_info->new_version ) ) {
232
- if ( version_compare( $this->client->getProjectVersion(), $project_info->new_version, '<' ) ) {
233
- $transient_data->response[ $this->client->getSlug() ] = (array) $project_info;
234
- }
235
- $transient_data->last_checked = time();
236
- $transient_data->checked[ $this->client->getSlug() ] = $this->client->getProjectVersion();
237
- }
238
- return $transient_data;
239
- }
240
-
241
- /**
242
- * Typecast child element to array or object
243
- * Utility method
244
- * @param array|object $input the array or object to convert/typecast.
245
- * @param array $children children array.
246
- *
247
- * @return array|object
248
- */
249
- private function __children_to_array( $input, $children = [] ) {
250
- if ( ! empty( $children ) && is_array( $children ) && ( is_object( $input ) || is_array( $input ) ) ) {
251
- $isObject = is_object( $input );
252
- foreach ( $children as $child ) {
253
- if ( call_user_func_array( $isObject ? 'property_exists' : 'array_key_exists', [ $input, $child ] ) ) {
254
- if ( $isObject ) {
255
- $input->{$child} = (array) $input->{$child};
256
- } else {
257
- $input[ $child ] = (array) $input->{$child};
258
- }
259
- }
260
- }
261
- }
262
- return $input;
263
- }
264
- }
265
- // End of file Updater.php.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
woo-feed.php CHANGED
@@ -10,7 +10,7 @@
10
  * Plugin Name: Product Feed for WooCommerce
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
- * Version: 4.3.27
14
  * Author: WebAppick
15
  * Author URI: https://webappick.com/
16
  * License: GPL v2
@@ -38,7 +38,7 @@ if ( ! defined( 'WOO_FEED_FREE_VERSION' ) ) {
38
  * @var string
39
  * @since 3.1.6
40
  */
41
- define( 'WOO_FEED_FREE_VERSION', '4.3.27' );
42
  }
43
 
44
  if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {
10
  * Plugin Name: Product Feed for WooCommerce
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
+ * Version: 4.3.28
14
  * Author: WebAppick
15
  * Author URI: https://webappick.com/
16
  * License: GPL v2
38
  * @var string
39
  * @since 3.1.6
40
  */
41
+ define( 'WOO_FEED_FREE_VERSION', '4.3.28' );
42
  }
43
 
44
  if ( ! defined( 'WOO_FEED_FREE_FILE' ) ) {