CTX Feed – WooCommerce Product Feed Manager Plugin - Version 3.1.41

Version Description

(2019-10-24) = * Dependency & compatibility check upon activation * Tested with latest WordPress & WooCommerce Release

Download this release

Release Info

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

Code changes from version 3.1.40 to 3.1.41

README.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: wahid0003
3
  Donate link: https://webappick.com
4
  Tags:woocommerce,google product feed,facebook product feed,woocommerce product feed,woocommerce,
5
  Requires at least: 3.6
6
- Tested Up To: 5.2
7
- Stable tag: 3.1.40
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -304,6 +304,10 @@ Using pro version:
304
 
305
  == Changelog ==
306
 
 
 
 
 
307
  = 3.1.40 (2019-10-21) =
308
  * Fix error on fetching invalid child product of group product.
309
  * Fix google taxonomy not being selected on edit page
3
  Donate link: https://webappick.com
4
  Tags:woocommerce,google product feed,facebook product feed,woocommerce product feed,woocommerce,
5
  Requires at least: 3.6
6
+ Tested Up To: 5.3
7
+ Stable tag: 3.1.41
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
304
 
305
  == Changelog ==
306
 
307
+ = 3.1.41 (2019-10-24) =
308
+ * Dependency & compatibility check upon activation
309
+ * Tested with latest WordPress & WooCommerce Release
310
+
311
  = 3.1.40 (2019-10-21) =
312
  * Fix error on fetching invalid child product of group product.
313
  * Fix google taxonomy not being selected on edit page
admin/class-woo-feed-admin.php CHANGED
@@ -39,8 +39,7 @@ class Woo_Feed_Admin
39
  * @param string $woo_feed The name of this plugin.
40
  * @param string $version The version of this plugin.
41
  */
42
- public function __construct($woo_feed, $version)
43
- {
44
 
45
  $this->woo_feed = $woo_feed;
46
  $this->version = $version;
@@ -49,7 +48,7 @@ class Woo_Feed_Admin
49
 
50
  /**
51
  * Register the stylesheets for the admin area.
52
- *
53
  * @since 1.0.0
54
  */
55
  public function enqueue_styles( $hook ) {
@@ -81,7 +80,7 @@ class Woo_Feed_Admin
81
 
82
  /**
83
  * Register the JavaScript for the admin area.
84
- *
85
  * @since 1.0.0
86
  */
87
  public function enqueue_scripts( $hook ) {
@@ -121,6 +120,21 @@ class Woo_Feed_Admin
121
  wp_enqueue_script($this->woo_feed);
122
 
123
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
  /**
126
  * Register the Plugin's Admin Pages for the admin area.
39
  * @param string $woo_feed The name of this plugin.
40
  * @param string $version The version of this plugin.
41
  */
42
+ public function __construct($woo_feed, $version) {
 
43
 
44
  $this->woo_feed = $woo_feed;
45
  $this->version = $version;
48
 
49
  /**
50
  * Register the stylesheets for the admin area.
51
+ * @param string $hook
52
  * @since 1.0.0
53
  */
54
  public function enqueue_styles( $hook ) {
80
 
81
  /**
82
  * Register the JavaScript for the admin area.
83
+ * @param string $hook
84
  * @since 1.0.0
85
  */
86
  public function enqueue_scripts( $hook ) {
120
  wp_enqueue_script($this->woo_feed);
121
 
122
  }
123
+
124
+ /**
125
+ * Add Go to Pro and Documentation link
126
+ * @param array $links
127
+ * @return array
128
+ */
129
+ public function woo_feed_plugin_action_links( $links ) {
130
+
131
+ $links[] = '<a style="color: #389e38; font-weight: bold;" 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">' . __( 'Get Pro', 'woo-feed' ) . '</a>';
132
+ /** @noinspection HtmlUnknownTarget */
133
+ $links[] = sprintf( '<a style="color:#ce7304; font-weight: bold;" href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-docs' ) ), __( 'Docs', 'woo-feed' ) );
134
+ /** @noinspection HtmlUnknownTarget */
135
+ $links[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-settings' ) ), __( 'Settings', 'woo-feed' ) );
136
+ return $links;
137
+ }
138
 
139
  /**
140
  * Register the Plugin's Admin Pages for the admin area.
admin/css/woo-feed-admin.css CHANGED
@@ -400,54 +400,6 @@ input[class=woo_feed_status_input]:checked + label:before{
400
  font-size: large;
401
  }
402
 
403
- /*Plugin Deactivation popup*/
404
- /*noinspection SpellCheckingInspection */
405
- .wpf_deactive_plugin-modal {
406
- position: fixed;
407
- z-index: 99999;
408
- top: 0;
409
- right: 0;
410
- bottom: 0;
411
- left: 0;
412
- background: rgba(0,0,0,0.5);
413
- display: none;
414
- }
415
- /*noinspection SpellCheckingInspection */
416
- .wpf_deactive_plugin-modal.modal-active {
417
- display: block;
418
- }
419
- /*noinspection SpellCheckingInspection */
420
- .wpf_deactive_plugin-modal-wrap {
421
- width: 475px;
422
- position: relative;
423
- margin: 10% auto;
424
- background: #fff;
425
- }
426
- /*noinspection SpellCheckingInspection */
427
- .wpf_deactive_plugin-modal-header {
428
- border-bottom: 1px solid #eee;
429
- padding: 8px 20px;
430
- }
431
- /*noinspection SpellCheckingInspection */
432
- .wpf_deactive_plugin-modal-header h3 {
433
- line-height: 150%;
434
- margin: 0;
435
- }
436
- /*noinspection SpellCheckingInspection */
437
- .wpf_deactive_plugin-modal-body {
438
- padding: 5px 20px 20px 20px;
439
- }
440
- /*noinspection SpellCheckingInspection */
441
- .wpf_deactive_plugin-modal-body .reason-input {
442
- margin-top: 5px;
443
- margin-left: 20px;
444
- }
445
- /*noinspection SpellCheckingInspection */
446
- .wpf_deactive_plugin-modal-footer {
447
- border-top: 1px solid #eee;
448
- padding: 12px 20px;
449
- text-align: right;
450
- }
451
  /*noinspection SpellCheckingInspection */
452
  #wpbody-content.woofeed-body-content{
453
  overflow:visible!important;
400
  font-size: large;
401
  }
402
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
  /*noinspection SpellCheckingInspection */
404
  #wpbody-content.woofeed-body-content{
405
  overflow:visible!important;
admin/js/woo-feed-admin.js CHANGED
@@ -1,3 +1,4 @@
 
1
  ( function ($, window, document, opts) {
2
  "use strict";
3
  /**
@@ -71,6 +72,7 @@
71
  showTooltip( event.trigger, 'Copied!' );
72
  } );
73
  }
 
74
  var sliders = $('.wapk-slider');
75
  if( sliders.length ) {
76
  sliders.slick({
@@ -85,9 +87,7 @@
85
  }
86
  });
87
 
88
-
89
  $(function () {
90
-
91
  // noinspection ES6ConvertVarToLetConst
92
  var pageURL = $(location). attr("href");
93
  if(pageURL.indexOf('webappick-product-feed-for-woocommerce') >= 0 || pageURL.indexOf('woo_feed_manage_feed') >= 0) {
@@ -96,21 +96,27 @@
96
  }
97
 
98
  // Category Mapping (Auto Field Populate)
 
99
  $(".treegrid-parent").on('change keyup', function () {
 
100
  var val = $(this).val(), parent = $(this).attr('classval');
 
101
  $(".treegrid-parent-" + parent).val(val);
102
  });
103
  // Generate Feed Add Table Row
104
  $(document).on('click', '#wf_newRow', function () {
105
  $("#table-1 tbody tr:first").clone().find('input').val('').end().find("select:not('.wfnoempty')").val('').end().insertAfter("#table-1 tbody tr:last");
106
- $('.outputType').each(function (index, element) {
107
  //do stuff to each individually.
108
  $(this).attr('name', "output_type[" + index + "][]"); //sets the val to the index of the element, which, you know, is useless
109
  });
110
  });
111
  // XML Feed Wrapper
112
  $(document).on('change', '#feedType', function () {
113
- var type = $(this).val(), provider = $("#provider").val(), itemWrapper = $(".itemWrapper"), wf_csvtxt = $(".wf_csvtxt");
 
 
 
114
  if ( type === 'xml' ) {
115
  itemWrapper.show(); wf_csvtxt.hide();
116
  } else if ( type === 'csv' || type === 'txt' ) {
@@ -119,50 +125,55 @@
119
  itemWrapper.hide(); wf_csvtxt.hide();
120
  }
121
  if( type !== "" && helper.in_array( provider, ['google', 'facebook'] ) ) {
122
- $(".itemWrapper").hide();
123
  }
 
124
  if( provider === 'criteo' ) {
125
  itemWrapper.find('input[name="itemsWrapper"]').val("channel");
126
  itemWrapper.find('input[name="itemWrapper"]').val("item");
127
  }
128
  });
129
  // Tooltip only Text
 
130
  $('.wfmasterTooltip').hover(function () {
131
  // Hover over code
 
132
  var title = $(this).attr('wftitle');
 
133
  $(this).data('tipText', title).removeAttr('wftitle');
134
- $('<p class="wftooltip"></p>')
135
- .text(title)
136
- .appendTo('body')
137
- .fadeIn('slow');
138
  }, function () {
139
  // Hover out code
 
140
  $(this).attr('wftitle', $(this).data('tipText'));
 
141
  $('.wftooltip').remove();
142
  }).mousemove(function (e) {
143
- var mousex = e.pageX + 20; //Get X coordinates
144
- var mousey = e.pageY + 10; //Get Y coordinates
145
- $('.wftooltip')
146
- .css({top: mousey, left: mousex})
147
  });
148
  // Dynamic Attribute Add New Condition
149
  $(document).on('click', '#wf_newCon', function () {
150
  $("#table-1 tbody tr:first").show().clone().find('input').val('').end().insertAfter("#table-1 tbody tr:last");
 
151
  $(".fsrow:gt(5)").prop('disabled', false);
152
  $(".daRow:eq(0)").hide();
153
  });
154
  // Add New Condition for Filter
155
  $(document).on('click', '#wf_newFilter', function () {
156
  $("#table-filter tbody tr:eq(0)").show().clone().find('input').val('').end().find('select').val('').end().insertAfter("#table-filter tbody tr:last");
 
157
  $(".fsrow:gt(2)").prop('disabled', false);
158
  $(".daRow:eq(0)").hide();
159
  });
160
  // Attribute type selection
161
  $(document).on('change', '.attr_type', function () {
 
162
  var type = $(this).val(), row = $(this).closest('tr');
163
  row.find('.wf_attr').prop('required',false);
164
  row.find('.wf_default').prop('required',false);
165
- if (type == 'pattern') {
166
  row.find('.wf_attr').hide();
167
  row.find('.wf_attr').val('');
168
  row.find('.wf_default').show();
@@ -176,26 +187,28 @@
176
  });
177
  // Attribute type selection for dynamic attribute
178
  $(document).on('change', '.dType', function () {
 
179
  var type = $(this).val(), row = $(this).closest('tr');
180
- if (type == 'pattern') {
181
  row.find('.value_attribute').hide();
182
  row.find('.value_pattern').show();
183
- } else if (type == 'attribute') {
184
  row.find('.value_attribute').show();
185
  row.find('.value_pattern').hide();
186
- } else if (type == 'remove') {
187
  row.find('.value_attribute').hide();
188
  row.find('.value_pattern').hide();
189
  }
190
  });
191
  // Generate Feed Table Row Delete
192
- $(document).on('click', '.delRow', function (event) {
193
  $(this).closest('tr').remove();
194
  });
195
  //Expand output type
196
  $(document).on('click', '.expandType', function () {
 
197
  var row = $(this).closest('tr');
198
- $('.outputType').each(function (index, element) {
199
  //do stuff to each individually.
200
  $(this).attr('name', "output_type[" + index + "][]");
201
  });
@@ -205,8 +218,9 @@
205
  });
206
  //Contract output type
207
  $(document).on('click', '.contractType', function () {
 
208
  var row = $(this).closest('tr');
209
- $('.outputType').each(function (index, element) {
210
  //do stuff to each individually.
211
  $(this).attr('name', "output_type[" + index + "][]");
212
  });
@@ -216,7 +230,7 @@
216
  });
217
  // Generate Feed Form Submit
218
  $(".generateFeed").validate();
219
- $(document).on('submit', '#generateFeed', function (event) {
220
  $(".makeFeedResponse").html("<b style='color: darkblue;'><i class='dashicons dashicons-sos wpf_sos'></i> Processing...</b>");
221
  //event.preventDefault();
222
  // Feed Generating form validation
@@ -224,8 +238,9 @@
224
  if ($(this).valid()) {}
225
  });
226
  // Update Feed Form Submit
 
227
  $(".updatefeed").validate();
228
- $(document).on('submit', '#updatefeed', function (event) {
229
  $(".makeFeedResponse").html("<b style='color: darkblue;'><i class='dashicons dashicons-sos wpf_sos'></i> Processing...</b>");
230
  //event.preventDefault();
231
  // Feed Generating form validation
@@ -233,6 +248,7 @@
233
  if ($(this).valid()) {}
234
  });
235
  // helper functions
 
236
  var helper = {
237
  in_array: function( needle, haystack ) {
238
  try {
@@ -244,11 +260,12 @@
244
  selectize_render_item: function( data, escape ) {
245
  return '<div class="item webappick_selector">' + escape(data.text) + '</div>';
246
  },
247
- };
248
- // Feed Editor Table
249
- var feedEditor = {
250
  init: function(){
251
- // Initialize Table Sorting
 
 
252
  $('.sorted_table').sortablesd({
253
  containerSelector: 'table',
254
  itemPath: '> tbody',
@@ -256,7 +273,6 @@
256
  handle: 'i.wf_sortedtable',
257
  placeholder: '<tr class="placeholder"><td colspan="100"></td></tr>',
258
  });
259
- var $glCat = $('#googleTaxonomyId');
260
  if( $glCat.length ) {
261
  $glCat.selectize({
262
  render: {
@@ -270,9 +286,10 @@
270
  // Get Merchant View
271
  $("#provider").on('change', function ( event ) {
272
  event.preventDefault();
 
273
  var merchant = $(this).val(), feedType = $("#feedType"), feedForm = $("#providerPage"),
274
- marchants = ["pinterest", "fruugo", "fruugo.au", "vergelijk_comparer", "spartoo.fi", "avantlink"];
275
- if( helper.in_array( merchant, marchants ) ) {
276
  feedType.val("csv");
277
  feedType.find('option').not('[value="csv"]').disabled( true );
278
  feedType.find('option').not('[value="csv"]').disabled( true );
@@ -283,6 +300,7 @@
283
  feedType.trigger('change');
284
  feedForm.html("<h3>Loading...</h3>");
285
  // Get FeedForm For Selected Provider/Merchant
 
286
  $.post( opts.wpf_ajax_url, { _ajax_nonce: opts.nonce, action: "get_feed_merchant", merchant: merchant }, function (data) {
287
  feedForm.html(data); // insert server response
288
  feedEditor.init();
@@ -290,9 +308,10 @@
290
  });
291
  // Feed Active and Inactive status change via ajax
292
  $('.woo_feed_status_input').on('change',function(){
 
293
  var $feedName = $(this).val(), counter = ( $(this)[0].checked ) ? 1 : 0;
294
- $.post( opts.wpf_ajax_url, { _ajax_nonce: opts.nonce, action: "update_feed_status", feedName: $feedName, status: counter }, function (data) {
295
- } );
296
  });
297
  // Adding for Copy-to-Clipboard functionality in the settings page
298
  $("#woo_feed_settings_error_copy_clipboard_button").on('click', function() {
@@ -302,81 +321,18 @@
302
  else if (document.selection) {document.selection.empty();}
303
  });
304
  });
305
- // Plugin deactivation pop up
306
- $(function() {
307
- var modal = $( '#wpf_deactive_plugin-modal' ), deactivateLink = '';
308
- $( '#the-list' ).on('click', 'a.wpf-deactivate-link', function(e) {
309
- e.preventDefault();
310
- modal.addClass('modal-active');
311
- deactivateLink = $(this).attr('href');
312
- modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left');
313
- });
314
- modal
315
- .on('click', 'button.button-primary', function(e) {
316
- e.preventDefault();
317
- modal.removeClass('modal-active');
318
- }).on('click', 'input[type="radio"]', function () {
319
- var parent = $(this).parents('li:first');
320
- modal.find('.reason-input').remove();
321
- var inputType = parent.data('type'),
322
- inputPlaceholder = parent.data('placeholder'),
323
- reasonInputHtml = '<div class="reason-input">' + ( ( 'text' === inputType ) ? '<input type="text" size="40" />' : '<textarea rows="5" cols="45"></textarea>' ) + '</div>';
324
- if ( inputType !== '' ) {
325
- parent.append( $(reasonInputHtml) );
326
- parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
327
- }
328
- }).on('click', 'button.button-secondary', function(e) {
329
- e.preventDefault();
330
- var button = $(this);
331
- if ( button.hasClass('disabled') ) return;
332
- var $radio = $( 'input[type="radio"]:checked', modal ),
333
- $selected_reason = $radio.parents('li:first'),
334
- $input = $selected_reason.find('textarea, input[type="text"]');
335
- $.ajax({
336
- url: ajaxurl,
337
- type: 'POST',
338
- data: {
339
- action: 'woo-feed-submit-uninstall-reason',
340
- reason_id: ( 0 === $radio.length ) ? 'none' : $radio.val(),
341
- reason_info: ( 0 !== $input.length ) ? $input.val().trim() : ''
342
- },
343
- beforeSend: function() {
344
- button.addClass('disabled');
345
- button.text('Processing...');
346
- },
347
- complete: function() {
348
- window.location.href = deactivateLink;
349
- },
350
- error:function(data){}
351
- });
352
- }).on('click', '.dont-bother-me', function(e) {
353
- e.preventDefault();
354
- var button = $(this);
355
- if ( button.hasClass('disabled') ) return;
356
- $.ajax({
357
- url: ajaxurl,
358
- type: 'POST',
359
- data: {
360
- action: 'woo-feed-submit-uninstall-reason',
361
- reason_id: 'no-comment',
362
- reason_info: 'I rather wouldn\'t say'
363
- },
364
- beforeSend: function() {
365
- button.addClass("disabled");
366
- },
367
- complete: function() {
368
- window.location.href = deactivateLink;
369
- }
370
- });
371
- });
372
- });
373
  //Checking whether php ssh2 extension is added or not
 
374
  $(document).on('change', '.ftporsftp', function () {
375
- var server = $(this).val();
376
- if (server == 'sftp') {
377
- $('.ssh2_status').show();
378
- $('.ssh2_status').css('color','dodgerblue');
379
- $('.ssh2_status').text('Wait! Checking Extensions ...');
 
 
 
380
  $.ajax({
381
  url: opts.wpf_ajax_url,
382
  type: 'post',
@@ -387,27 +343,29 @@
387
  },
388
  success: function (response) {
389
  if (response.success) {
390
- if(response.data == 'exists') {
391
- $('.ssh2_status').hide();
392
  } else {
393
- $('.ssh2_status').show();
394
- $('.ssh2_status').css('color','red');
395
- $('.ssh2_status').text('Warning! Enable PHP ssh2 extension to use SFTP. Contact your server administrator.');
396
  }
397
  }
398
  }
399
  });
400
  }else{
401
- $('.ssh2_status').hide();
402
  }
403
  });
404
  $(document).on('click', '.woo-feed-review-notice ul li a', function (e) {
405
  e.preventDefault();
406
- let notice = $(this).attr('val');
407
- if(notice=="given"){
 
408
  window.open('https://wordpress.org/support/plugin/webappick-product-feed-for-woocommerce/reviews/?rate=5#new-post','_blank');
409
  }
410
  $( ".woo-feed-review-notice" ).slideUp( 200, "linear");
 
411
  $.ajax({
412
  url: opts.wpf_ajax_url,
413
  type: 'post',
@@ -417,6 +375,7 @@
417
  });
418
  $(document).on('click', '.woo-feed-wpml-notice .notice-dismiss', function (e) {
419
  e.preventDefault();
 
420
  $.ajax({
421
  url: opts.wpf_ajax_url,
422
  type: 'post',
1
+ // noinspection JSUnresolvedVariable,ES6ConvertVarToLetConst,SpellCheckingInspection
2
  ( function ($, window, document, opts) {
3
  "use strict";
4
  /**
72
  showTooltip( event.trigger, 'Copied!' );
73
  } );
74
  }
75
+ // noinspection ES6ConvertVarToLetConst
76
  var sliders = $('.wapk-slider');
77
  if( sliders.length ) {
78
  sliders.slick({
87
  }
88
  });
89
 
 
90
  $(function () {
 
91
  // noinspection ES6ConvertVarToLetConst
92
  var pageURL = $(location). attr("href");
93
  if(pageURL.indexOf('webappick-product-feed-for-woocommerce') >= 0 || pageURL.indexOf('woo_feed_manage_feed') >= 0) {
96
  }
97
 
98
  // Category Mapping (Auto Field Populate)
99
+ // noinspection ES6ConvertVarToLetConst,SpellCheckingInspection
100
  $(".treegrid-parent").on('change keyup', function () {
101
+ // noinspection ES6ConvertVarToLetConst,SpellCheckingInspection
102
  var val = $(this).val(), parent = $(this).attr('classval');
103
+ // noinspection SpellCheckingInspection
104
  $(".treegrid-parent-" + parent).val(val);
105
  });
106
  // Generate Feed Add Table Row
107
  $(document).on('click', '#wf_newRow', function () {
108
  $("#table-1 tbody tr:first").clone().find('input').val('').end().find("select:not('.wfnoempty')").val('').end().insertAfter("#table-1 tbody tr:last");
109
+ $('.outputType').each(function (index) {
110
  //do stuff to each individually.
111
  $(this).attr('name', "output_type[" + index + "][]"); //sets the val to the index of the element, which, you know, is useless
112
  });
113
  });
114
  // XML Feed Wrapper
115
  $(document).on('change', '#feedType', function () {
116
+ // noinspection ES6ConvertVarToLetConst,SpellCheckingInspection
117
+ var type = $(this).val(), provider = $("#provider").val(),
118
+ itemWrapper = $(".itemWrapper"),
119
+ wf_csvtxt = $(".wf_csvtxt");
120
  if ( type === 'xml' ) {
121
  itemWrapper.show(); wf_csvtxt.hide();
122
  } else if ( type === 'csv' || type === 'txt' ) {
125
  itemWrapper.hide(); wf_csvtxt.hide();
126
  }
127
  if( type !== "" && helper.in_array( provider, ['google', 'facebook'] ) ) {
128
+ itemWrapper.hide();
129
  }
130
+ // noinspection SpellCheckingInspection
131
  if( provider === 'criteo' ) {
132
  itemWrapper.find('input[name="itemsWrapper"]').val("channel");
133
  itemWrapper.find('input[name="itemWrapper"]').val("item");
134
  }
135
  });
136
  // Tooltip only Text
137
+ // noinspection SpellCheckingInspection
138
  $('.wfmasterTooltip').hover(function () {
139
  // Hover over code
140
+ // noinspection ES6ConvertVarToLetConst,SpellCheckingInspection
141
  var title = $(this).attr('wftitle');
142
+ // noinspection SpellCheckingInspection
143
  $(this).data('tipText', title).removeAttr('wftitle');
144
+ // noinspection SpellCheckingInspection
145
+ $('<p class="wftooltip"></p>').text(title).appendTo('body').fadeIn('slow');
 
 
146
  }, function () {
147
  // Hover out code
148
+ // noinspection SpellCheckingInspection
149
  $(this).attr('wftitle', $(this).data('tipText'));
150
+ // noinspection SpellCheckingInspection
151
  $('.wftooltip').remove();
152
  }).mousemove(function (e) {
153
+ // noinspection SpellCheckingInspection
154
+ $('.wftooltip').css({top: (e.pageY + 10), left: (e.pageX + 20) })
 
 
155
  });
156
  // Dynamic Attribute Add New Condition
157
  $(document).on('click', '#wf_newCon', function () {
158
  $("#table-1 tbody tr:first").show().clone().find('input').val('').end().insertAfter("#table-1 tbody tr:last");
159
+ // noinspection SpellCheckingInspection
160
  $(".fsrow:gt(5)").prop('disabled', false);
161
  $(".daRow:eq(0)").hide();
162
  });
163
  // Add New Condition for Filter
164
  $(document).on('click', '#wf_newFilter', function () {
165
  $("#table-filter tbody tr:eq(0)").show().clone().find('input').val('').end().find('select').val('').end().insertAfter("#table-filter tbody tr:last");
166
+ // noinspection SpellCheckingInspection
167
  $(".fsrow:gt(2)").prop('disabled', false);
168
  $(".daRow:eq(0)").hide();
169
  });
170
  // Attribute type selection
171
  $(document).on('change', '.attr_type', function () {
172
+ // noinspection ES6ConvertVarToLetConst
173
  var type = $(this).val(), row = $(this).closest('tr');
174
  row.find('.wf_attr').prop('required',false);
175
  row.find('.wf_default').prop('required',false);
176
+ if (type === 'pattern') {
177
  row.find('.wf_attr').hide();
178
  row.find('.wf_attr').val('');
179
  row.find('.wf_default').show();
187
  });
188
  // Attribute type selection for dynamic attribute
189
  $(document).on('change', '.dType', function () {
190
+ // noinspection ES6ConvertVarToLetConst
191
  var type = $(this).val(), row = $(this).closest('tr');
192
+ if (type === 'pattern') {
193
  row.find('.value_attribute').hide();
194
  row.find('.value_pattern').show();
195
+ } else if (type === 'attribute') {
196
  row.find('.value_attribute').show();
197
  row.find('.value_pattern').hide();
198
+ } else if (type === 'remove') {
199
  row.find('.value_attribute').hide();
200
  row.find('.value_pattern').hide();
201
  }
202
  });
203
  // Generate Feed Table Row Delete
204
+ $(document).on('click', '.delRow', function () {
205
  $(this).closest('tr').remove();
206
  });
207
  //Expand output type
208
  $(document).on('click', '.expandType', function () {
209
+ // noinspection ES6ConvertVarToLetConst
210
  var row = $(this).closest('tr');
211
+ $('.outputType').each(function (index) {
212
  //do stuff to each individually.
213
  $(this).attr('name', "output_type[" + index + "][]");
214
  });
218
  });
219
  //Contract output type
220
  $(document).on('click', '.contractType', function () {
221
+ // noinspection ES6ConvertVarToLetConst
222
  var row = $(this).closest('tr');
223
+ $('.outputType').each(function (index) {
224
  //do stuff to each individually.
225
  $(this).attr('name', "output_type[" + index + "][]");
226
  });
230
  });
231
  // Generate Feed Form Submit
232
  $(".generateFeed").validate();
233
+ $(document).on('submit', '#generateFeed', function () {
234
  $(".makeFeedResponse").html("<b style='color: darkblue;'><i class='dashicons dashicons-sos wpf_sos'></i> Processing...</b>");
235
  //event.preventDefault();
236
  // Feed Generating form validation
238
  if ($(this).valid()) {}
239
  });
240
  // Update Feed Form Submit
241
+ // noinspection SpellCheckingInspection
242
  $(".updatefeed").validate();
243
+ $(document).on('submit', '#updatefeed', function () {
244
  $(".makeFeedResponse").html("<b style='color: darkblue;'><i class='dashicons dashicons-sos wpf_sos'></i> Processing...</b>");
245
  //event.preventDefault();
246
  // Feed Generating form validation
248
  if ($(this).valid()) {}
249
  });
250
  // helper functions
251
+ // noinspection ES6ConvertVarToLetConst,SpellCheckingInspection
252
  var helper = {
253
  in_array: function( needle, haystack ) {
254
  try {
260
  selectize_render_item: function( data, escape ) {
261
  return '<div class="item webappick_selector">' + escape(data.text) + '</div>';
262
  },
263
+ },
264
+ feedEditor = { // Feed Editor Table
 
265
  init: function(){
266
+ // noinspection ES6ConvertVarToLetConst
267
+ var $glCat = $('#googleTaxonomyId');
268
+ // noinspection SpellCheckingInspection,JSUnresolvedFunction Initialize Table Sorting
269
  $('.sorted_table').sortablesd({
270
  containerSelector: 'table',
271
  itemPath: '> tbody',
273
  handle: 'i.wf_sortedtable',
274
  placeholder: '<tr class="placeholder"><td colspan="100"></td></tr>',
275
  });
 
276
  if( $glCat.length ) {
277
  $glCat.selectize({
278
  render: {
286
  // Get Merchant View
287
  $("#provider").on('change', function ( event ) {
288
  event.preventDefault();
289
+ // noinspection ES6ConvertVarToLetConst,SpellCheckingInspection
290
  var merchant = $(this).val(), feedType = $("#feedType"), feedForm = $("#providerPage"),
291
+ merchants = ["pinterest", "fruugo", "fruugo.au", "vergelijk_comparer", "spartoo.fi", "avantlink"];
292
+ if( helper.in_array( merchant, merchants ) ) {
293
  feedType.val("csv");
294
  feedType.find('option').not('[value="csv"]').disabled( true );
295
  feedType.find('option').not('[value="csv"]').disabled( true );
300
  feedType.trigger('change');
301
  feedForm.html("<h3>Loading...</h3>");
302
  // Get FeedForm For Selected Provider/Merchant
303
+ // noinspection JSUnresolvedVariable
304
  $.post( opts.wpf_ajax_url, { _ajax_nonce: opts.nonce, action: "get_feed_merchant", merchant: merchant }, function (data) {
305
  feedForm.html(data); // insert server response
306
  feedEditor.init();
308
  });
309
  // Feed Active and Inactive status change via ajax
310
  $('.woo_feed_status_input').on('change',function(){
311
+ // noinspection ES6ConvertVarToLetConst
312
  var $feedName = $(this).val(), counter = ( $(this)[0].checked ) ? 1 : 0;
313
+ // noinspection JSUnresolvedVariable
314
+ $.post( opts.wpf_ajax_url, { _ajax_nonce: opts.nonce, action: "update_feed_status", feedName: $feedName, status: counter }, function (data) {} );
315
  });
316
  // Adding for Copy-to-Clipboard functionality in the settings page
317
  $("#woo_feed_settings_error_copy_clipboard_button").on('click', function() {
321
  else if (document.selection) {document.selection.empty();}
322
  });
323
  });
324
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
  //Checking whether php ssh2 extension is added or not
326
+ // noinspection SpellCheckingInspection
327
  $(document).on('change', '.ftporsftp', function () {
328
+ // noinspection ES6ConvertVarToLetConst
329
+ var server = $(this).val(),
330
+ ssh2Status = $('.ssh2_status');
331
+ if (server === 'sftp') {
332
+ ssh2Status.show();
333
+ ssh2Status.css('color','dodgerblue');
334
+ ssh2Status.text('Wait! Checking Extensions ...');
335
+ // noinspection JSUnresolvedVariable
336
  $.ajax({
337
  url: opts.wpf_ajax_url,
338
  type: 'post',
343
  },
344
  success: function (response) {
345
  if (response.success) {
346
+ if(response.data === 'exists') {
347
+ ssh2Status.hide();
348
  } else {
349
+ ssh2Status.show();
350
+ ssh2Status.css('color','red');
351
+ ssh2Status.text('Warning! Enable PHP ssh2 extension to use SFTP. Contact your server administrator.');
352
  }
353
  }
354
  }
355
  });
356
  }else{
357
+ ssh2Status.hide();
358
  }
359
  });
360
  $(document).on('click', '.woo-feed-review-notice ul li a', function (e) {
361
  e.preventDefault();
362
+ // noinspection ES6ConvertVarToLetConst
363
+ var notice = $(this).attr('val');
364
+ if(notice === "given") {
365
  window.open('https://wordpress.org/support/plugin/webappick-product-feed-for-woocommerce/reviews/?rate=5#new-post','_blank');
366
  }
367
  $( ".woo-feed-review-notice" ).slideUp( 200, "linear");
368
+ // noinspection JSUnresolvedVariable
369
  $.ajax({
370
  url: opts.wpf_ajax_url,
371
  type: 'post',
375
  });
376
  $(document).on('click', '.woo-feed-wpml-notice .notice-dismiss', function (e) {
377
  e.preventDefault();
378
+ // noinspection JSUnresolvedVariable
379
  $.ajax({
380
  url: opts.wpf_ajax_url,
381
  type: 'post',
includes/class-woo-feed.php CHANGED
@@ -227,8 +227,7 @@ class Woo_Feed
227
  * @since 1.0.0
228
  * @access private
229
  */
230
- private function define_admin_hooks()
231
- {
232
 
233
  $plugin_admin = new Woo_Feed_Admin($this->get_woo_feed(), $this->get_version());
234
 
@@ -236,7 +235,7 @@ class Woo_Feed
236
  $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts');
237
  $this->loader->add_action('admin_menu', $plugin_admin, 'load_admin_pages');
238
  $this->loader->add_action( 'admin_page_access_denied', $plugin_admin, 'handle_old_menu_slugs' );
239
-
240
  }
241
 
242
  /**
227
  * @since 1.0.0
228
  * @access private
229
  */
230
+ private function define_admin_hooks() {
 
231
 
232
  $plugin_admin = new Woo_Feed_Admin($this->get_woo_feed(), $this->get_version());
233
 
235
  $this->loader->add_action('admin_enqueue_scripts', $plugin_admin, 'enqueue_scripts');
236
  $this->loader->add_action('admin_menu', $plugin_admin, 'load_admin_pages');
237
  $this->loader->add_action( 'admin_page_access_denied', $plugin_admin, 'handle_old_menu_slugs' );
238
+ $this->loader->add_filter( 'plugin_action_links_' . WOO_FEED_PLUGIN_BASE_NAME, $plugin_admin, 'woo_feed_plugin_action_links' );
239
  }
240
 
241
  /**
includes/classes/class-woo-feed-dropdown.php CHANGED
@@ -49,7 +49,7 @@ class Woo_Feed_Dropdown
49
  */
50
  public function googleTaxonomy( $selected = "" ) {
51
  # Get All Google Taxonomies
52
- $fileName = WOO_FEED_Admin_Path . "/partials/templates/google_taxonomy.txt";
53
  $customTaxonomyFile = fopen($fileName, "r");
54
  $str = "";
55
  if( ! empty( $selected ) ) {
49
  */
50
  public function googleTaxonomy( $selected = "" ) {
51
  # Get All Google Taxonomies
52
+ $fileName = WOO_FEED_ADMIN_PATH . "/partials/templates/google_taxonomy.txt";
53
  $customTaxonomyFile = fopen($fileName, "r");
54
  $str = "";
55
  if( ! empty( $selected ) ) {
includes/classes/class-woo-feed-tracker.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * WooCommerce Product Feed Plugin Uses Tracker
4
+ * Uses Webappick Insights for tracking
5
+ * @since 3.1.41
6
+ * @version 1.0.0
7
+ */
8
+ if( ! defined( 'ABSPATH' ) ) die();
9
+ /**
10
+ * Class WooFeedTracker
11
+ */
12
+ final class WooFeedTracker {
13
+ /**
14
+ * @var WebAppick\Insights
15
+ */
16
+ public $insights = null;
17
+
18
+ /**
19
+ * Class constructor
20
+ *
21
+ * @return void
22
+ * @since 1.0.0
23
+ *
24
+ */
25
+ public function __construct() {
26
+ if ( ! class_exists( 'WebAppick\Client' ) ) {
27
+ /** @noinspection PhpIncludeInspection */
28
+ require_once WOO_FEED_LIBS_PATH . 'WebAppick/Client.php';
29
+ }
30
+
31
+ $client = new WebAppick\Client( '4e68acba-cbdc-476b-b4bf-eab176ac6a16', 'WooCommerce Product Feed', WOO_FEED_FREE_FILE );
32
+
33
+ $this->insights = $client->insights();
34
+ // Hide tracker notice until tracking server gets ready...
35
+ // Tracker will not send data until user click Allow (optIn)
36
+ $this->insights->hide_notice();
37
+ /**
38
+ * @TODO count products by type
39
+ * @see wc_get_product_types();
40
+ */
41
+ $this->insights->add_extra( [
42
+ 'products' => $this->insights->get_post_count( 'product' ),
43
+ ] );
44
+ $this->insights->init_plugin();
45
+ add_filter( 'WebAppick_endpoint', array( $this, 'uninstallStatEndPoint' ) );
46
+ }
47
+
48
+ /**
49
+ * Tracker API EndPoint
50
+ * @return string
51
+ */
52
+ public function uninstallStatEndPoint() {
53
+ return 'https://track.webappick.com/api/receive-uninstall-tracking';
54
+ }
55
+
56
+ /**
57
+ * Get number of orders
58
+ *
59
+ * @return integer
60
+ */
61
+ protected function get_order_count() {
62
+ global $wpdb;
63
+
64
+ return (int) $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts WHERE post_type = 'shop_order' and post_status IN ('wc-completed', 'wc-processing', 'wc-on-hold', 'wc-refunded');" );
65
+ }
66
+
67
+ }
68
+ // End of file class-woo-feed-tracker.php
includes/helper.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Helper Functions
4
+ * @package WooFeed
5
+ * @subpackage WooFeed_Helper_Functions
6
+ * @version 1.0.0
7
+ * @since WooFeed 3.1.40
8
+ * @author KD <mhamudul.hk@gmail.com>
9
+ * @copyright WebAppick
10
+ */
11
+ if( ! defined( 'ABSPATH' ) ) die(); // Silence...
12
+ if( ! function_exists( 'wooFeed_is_plugin_active' ) ) {
13
+ /**
14
+ * Determines whether a plugin is active.
15
+ * @since 3.1.41
16
+ * @see is_plugin_active()
17
+ * @param string $plugin Path to the plugin file relative to the plugins directory.
18
+ * @return bool True, if in the active plugins list. False, not in the list.
19
+ */
20
+ function wooFeed_is_plugin_active( $plugin ) {
21
+ if( !function_exists('is_plugin_active') ) include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
22
+ return is_plugin_active( $plugin );
23
+ }
24
+ }
25
+ if( ! function_exists( 'wooFeed_is_plugin_inactive' ) ) {
26
+ /**
27
+ * Determines whether the plugin is inactive.
28
+ * @since 3.1.41
29
+ * @see wooFeed_is_plugin_inactive()
30
+ *
31
+ * @param string $plugin Path to the plugin file relative to the plugins directory.
32
+ * @return bool True if inactive. False if active.
33
+ */
34
+ function wooFeed_is_plugin_inactive( $plugin ) {
35
+ return ! wooFeed_is_plugin_active( $plugin );
36
+ }
37
+ }
38
+ if( ! function_exists( 'wooFeed_deactivate_plugins' ) ) {
39
+ /**
40
+ * Deactivate a single plugin or multiple plugins.
41
+ * Wrapper for core deactivate_plugins() function
42
+ * @see deactivate_plugins()
43
+ * @param string|array $plugins Single plugin or list of plugins to deactivate.
44
+ * @param bool $silent Prevent calling deactivation hooks. Default is false.
45
+ * @param mixed $network_wide Whether to deactivate the plugin for all sites in the network.
46
+ * @return void
47
+ */
48
+ function wooFeed_deactivate_plugins( $plugins, $silent = false, $network_wide = null ) {
49
+ if ( ! function_exists( 'deactivate_plugins' ) ) require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
50
+ deactivate_plugins( $plugins, $silent, $network_wide );
51
+ }
52
+ }
53
+ if( ! function_exists( 'wooFeed_is_supported_php' ) ) {
54
+ /**
55
+ * Check if server php version meet minimum requirement
56
+ * @since 3.1.41
57
+ * @return bool
58
+ */
59
+ function wooFeed_is_supported_php(){
60
+ // PHP version need to be => WOO_FEED_MIN_PHP_VERSION
61
+ return ! version_compare( PHP_VERSION, WOO_FEED_MIN_PHP_VERSION, '<' );
62
+ }
63
+ }
64
+ if( ! function_exists( 'wooFeed_check_WC' ) ) {
65
+ function wooFeed_check_WC(){
66
+ return class_exists( 'WooCommerce', false );
67
+ }
68
+ }
69
+ if( ! function_exists( 'wooFeed_Admin_Notices' ) ) {
70
+ /**
71
+ * Display Admin Messages
72
+ * @hooked admin_notices
73
+ * @since 3.1.41
74
+ * @return void
75
+ */
76
+ function wooFeed_Admin_Notices(){
77
+ //@TODO Refactor this function with admin message class
78
+ // WC Missing Notice..
79
+ if ( ! wooFeed_check_WC() ) {
80
+ $plugin_url = self_admin_url( 'plugin-install.php?s=woocommerce&tab=search&type=term' );
81
+ /** @noinspection HtmlUnknownTarget */
82
+ $plugin_url = sprintf( '<a href="%s">%s</a>', $plugin_url, esc_html__( 'WooCommerce', 'woocommerce' ) );
83
+ $plugin_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce Product Feed', 'woo-feed' ) );
84
+ $wc_name = sprintf( '<code>%s</code>', esc_html__( 'WooCommerce', 'woocommerce' ) );
85
+ $message = sprintf( esc_html__( '%s requires %s to be installed and active. You can installed/activate %s here.', 'woo-feed' ), $plugin_name, $wc_name, $plugin_url );
86
+ printf( '<div class="error"><p><strong>%1$s</strong></p></div>', $message );
87
+ }
88
+ }
89
+ }
90
+ // End of file helper.php
libs/WebAppick/Client.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WebAppick;
3
+ use WP_Error;
4
+
5
+ /**
6
+ * This Package is based on WebAppick project by weDevs
7
+ * @see https://github.com/WebAppick/client
8
+ * @license MIT
9
+ */
10
+ /**
11
+ * Class Client
12
+ * @package WebAppick
13
+ */
14
+ class Client {
15
+
16
+ /**
17
+ * The client version
18
+ * @var string
19
+ */
20
+ public $version = '1.0.0';
21
+
22
+ /**
23
+ * Hash identifier of the plugin
24
+ * @var string
25
+ */
26
+ public $hash;
27
+
28
+ /**
29
+ * Name of the plugin
30
+ * @var string
31
+ */
32
+ public $name;
33
+
34
+ /**
35
+ * The plugin/theme file path
36
+ * @example .../wp-content/plugins/test-slug/test-slug.php
37
+ *
38
+ * @var string
39
+ */
40
+ public $file;
41
+
42
+ /**
43
+ * Main plugin file
44
+ * @example test-slug/test-slug.php
45
+ * @var string
46
+ */
47
+ public $basename;
48
+
49
+ /**
50
+ * Slug of the plugin
51
+ * @example test-slug
52
+ *
53
+ * @var string
54
+ */
55
+ public $slug;
56
+
57
+ /**
58
+ * The project version
59
+ *
60
+ * @var string
61
+ */
62
+ public $project_version;
63
+
64
+ /**
65
+ * The project type
66
+ *
67
+ * @var string
68
+ */
69
+ public $type;
70
+
71
+ /**
72
+ * Initialize the class
73
+ *
74
+ * @param string $hash hash of the plugin
75
+ * @param string $name readable name of the plugin
76
+ * @param string $file main plugin file path
77
+ */
78
+ public function __construct( $hash, $name, $file ) {
79
+ $this->hash = $hash;
80
+ $this->name = $name;
81
+ $this->file = $file;
82
+
83
+ $this->set_basename_and_slug();
84
+ }
85
+
86
+ /**
87
+ * Initialize insights class
88
+ *
89
+ * @return Insights
90
+ */
91
+ public function insights() {
92
+
93
+ if ( ! class_exists( __NAMESPACE__ . '\Insights') ) {
94
+ require_once __DIR__ . '/Insights.php';
95
+ }
96
+
97
+ return new Insights( $this );
98
+ }
99
+
100
+ /**
101
+ * Initialize plugin/theme updater
102
+ *
103
+ * @return Updater
104
+ */
105
+ public function updater() {
106
+ if ( ! class_exists( __NAMESPACE__ . '\Updater') ) {
107
+ require_once __DIR__ . '/Updater.php';
108
+ }
109
+ return new Updater( $this );
110
+ }
111
+
112
+ /**
113
+ * Initialize license checker
114
+ *
115
+ * @return License
116
+ */
117
+ public function license() {
118
+
119
+ if ( ! class_exists( __NAMESPACE__ . '\License') ) {
120
+ require_once __DIR__ . '/License.php';
121
+ }
122
+
123
+ return new License( $this );
124
+ }
125
+
126
+ /**
127
+ * API Endpoint
128
+ *
129
+ * @return string
130
+ */
131
+ public function endpoint() {
132
+ $endpoint = apply_filters( 'WebAppick_endpoint', 'https://tracking.WebAppick.com/v1' );
133
+ return trailingslashit( $endpoint );
134
+ }
135
+
136
+ /**
137
+ * Set project basename, slug and version
138
+ *
139
+ * @return void
140
+ */
141
+ protected function set_basename_and_slug() {
142
+
143
+ if( strpos( $this->file, WP_CONTENT_DIR . '/themes/' ) === false ) {
144
+
145
+ $this->basename = plugin_basename( $this->file );
146
+ /** @noinspection SpellCheckingInspection, PhpUnusedLocalVariableInspection */
147
+ list( $this->slug, $mainfile ) = explode( '/', $this->basename );
148
+ if( ! function_exists( 'get_plugin_data' ) ) require_once ABSPATH . 'wp-admin/includes/plugin.php';
149
+ $plugin_data = get_plugin_data( $this->file );
150
+ $this->project_version = $plugin_data['Version'];
151
+ $this->type = 'plugin';
152
+ } else {
153
+ $this->basename = str_replace( WP_CONTENT_DIR . '/themes/', '', $this->file );
154
+ /** @noinspection SpellCheckingInspection, PhpUnusedLocalVariableInspection */
155
+ list( $this->slug, $mainfile) = explode( '/', $this->basename );
156
+ $theme = wp_get_theme( $this->slug );
157
+ $this->project_version = $theme->version;
158
+ $this->type = 'theme';
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Client UserAgent String
164
+ * @return string
165
+ */
166
+ private function __user_agent() {
167
+ return 'WebAppick/' . md5( esc_url( home_url() ) ) . ';';
168
+ }
169
+
170
+ /**
171
+ * Send request to remote endpoint
172
+ *
173
+ * @param array $params
174
+ * @param string $route
175
+ * @param bool $blocking
176
+ * @return array|WP_Error Array of results including HTTP headers or WP_Error if the request failed.
177
+ */
178
+ public function send_request( $params, $route = '', $blocking = false ) {
179
+ $url = $this->endpoint() . $route;
180
+
181
+ $headers = array(
182
+ 'user-agent' => $this->__user_agent(),
183
+ 'Accept' => 'application/json',
184
+ );
185
+ // @TODO escape API URL
186
+ $response = wp_remote_post( $url, array(
187
+ 'method' => 'POST',
188
+ 'timeout' => 45,
189
+ 'redirection' => 5,
190
+ 'httpversion' => '1.0',
191
+ 'blocking' => $blocking,
192
+ 'headers' => $headers,
193
+ 'body' => array_merge( $params, array( 'client' => $this->version ) ),
194
+ 'cookies' => array()
195
+ ) );
196
+ return $response;
197
+ }
198
+
199
+ }
200
+ // End of file Insights.php
libs/WebAppick/Insights.php ADDED
@@ -0,0 +1,881 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WebAppick;
3
+ use WP_Theme;
4
+ use WP_User;
5
+
6
+ /**
7
+ * WebAppick Insights
8
+ *
9
+ * This is a tracker class to track plugin usage based on if the customer has opted in.
10
+ * No personal information is being tracked by this class, only general settings, active plugins, environment details
11
+ * and admin email.
12
+ */
13
+ class Insights {
14
+
15
+ /**
16
+ * The notice text
17
+ *
18
+ * @var string
19
+ */
20
+ public $notice;
21
+
22
+ /**
23
+ * Wheather to the notice or not
24
+ *
25
+ * @var boolean
26
+ */
27
+ protected $show_notice = true;
28
+
29
+ /**
30
+ * If extra data needs to be sent
31
+ *
32
+ * @var array
33
+ */
34
+ protected $extra_data = array();
35
+
36
+ /**
37
+ * WebAppick\Client
38
+ *
39
+ * @var Client
40
+ */
41
+ protected $client;
42
+
43
+ /**
44
+ * Initialize the class
45
+ *
46
+ * @param Client $client
47
+ * @param string $name
48
+ * @param string $file
49
+ */
50
+ public function __construct( $client, $name = null, $file = null ) {
51
+
52
+ if ( is_string( $client ) && ! empty( $name ) && ! empty( $file ) ) {
53
+ $client = new Client( $client, $name, $file );
54
+ }
55
+
56
+ if ( is_object( $client ) && is_a( $client, 'WebAppick\Client' ) ) {
57
+ $this->client = $client;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Don't show the notice
63
+ *
64
+ * @return Insights
65
+ */
66
+ public function hide_notice() {
67
+ $this->show_notice = false;
68
+ return $this;
69
+ }
70
+
71
+ /**
72
+ * Add extra data if needed
73
+ *
74
+ * @param array $data
75
+ *
76
+ * @return Insights
77
+ */
78
+ public function add_extra( $data = array() ) {
79
+ $this->extra_data = $data;
80
+
81
+ return $this;
82
+ }
83
+
84
+ /**
85
+ * Set custom notice text
86
+ *
87
+ * @param string $text
88
+ *
89
+ * @return Insights
90
+ */
91
+ public function notice( $text ) {
92
+ $this->notice = $text;
93
+
94
+ return $this;
95
+ }
96
+
97
+ /**
98
+ * Initialize insights
99
+ *
100
+ * @return void
101
+ */
102
+ public function init() {
103
+ if ( $this->client->type == 'plugin' ) {
104
+ $this->init_plugin();
105
+ } else if ( $this->client->type == 'theme' ) {
106
+ $this->init_theme();
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Initialize theme hooks
112
+ *
113
+ * @return void
114
+ */
115
+ public function init_theme() {
116
+ $this->init_common();
117
+
118
+ add_action( 'switch_theme', array( $this, 'deactivation_cleanup' ) );
119
+ add_action( 'switch_theme', array( $this, 'theme_deactivated' ), 12, 3 );
120
+ }
121
+
122
+ /**
123
+ * Initialize plugin hooks
124
+ *
125
+ * @return void
126
+ */
127
+ public function init_plugin() {
128
+ // plugin deactivate popup
129
+ if ( ! $this->__is_local_server() ) {
130
+ add_action( 'plugin_action_links_' . $this->client->basename, array( $this, 'plugin_action_links' ) );
131
+ add_action( 'admin_footer', array( $this, 'deactivate_scripts' ) );
132
+ }
133
+
134
+ $this->init_common();
135
+
136
+ register_activation_hook( $this->client->file, array( $this, 'activate_plugin' ) );
137
+ register_deactivation_hook( $this->client->file, array( $this, 'deactivation_cleanup' ) );
138
+ }
139
+
140
+ /**
141
+ * Initialize common hooks
142
+ *
143
+ * @return void
144
+ */
145
+ protected function init_common() {
146
+ if ( $this->show_notice ) {
147
+ // tracking notice
148
+ add_action( 'admin_notices', array( $this, 'admin_notice' ) );
149
+ }
150
+ add_action( 'admin_init', array( $this, 'handle_optIn_optOut' ) );
151
+ add_action( 'removable_query_args', array( $this, 'add_removable_query_args' ), 10, 1 );
152
+ // uninstall reason
153
+ add_action( 'wp_ajax_' . $this->client->slug . '_submit-uninstall-reason', array( $this, 'uninstall_reason_submission' ) );
154
+ // cron events
155
+ add_action( 'cron_schedules', array( $this, 'add_weekly_schedule' ) );
156
+ add_action( $this->client->slug . '_tracker_send_event', array( $this, 'send_tracking_data' ) );
157
+ // add_action( 'admin_init', array( $this, 'send_tracking_data' ) ); // test
158
+ }
159
+
160
+ /**
161
+ * Send tracking data to WebAppick server
162
+ *
163
+ * @param boolean $override
164
+ *
165
+ * @return void
166
+ */
167
+ public function send_tracking_data( $override = false ) {
168
+ // skip on AJAX Requests
169
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) return;
170
+ if ( ! $this->__tracking_allowed() && ! $override ) return;
171
+ // Send a maximum of once per week
172
+ $last_send = $this->__get_last_send();
173
+ if ( $last_send && $last_send > strtotime( '-1 week' ) ) return;
174
+ $this->client->send_request( $this->get_tracking_data(), 'track' );
175
+ update_option( $this->client->slug . '_tracking_last_send', time() );
176
+ }
177
+
178
+ /**
179
+ * Get the tracking data points
180
+ *
181
+ * @return array
182
+ */
183
+ protected function get_tracking_data() {
184
+ $all_plugins = $this->__get_all_plugins();
185
+ $admin_user = $this->__get_admin();
186
+ $data = array(
187
+ 'version' => $this->client->project_version,
188
+ 'url' => esc_url( home_url() ),
189
+ 'site' => $this->__get_site_name(),
190
+ 'admin_email' => get_option( 'admin_email' ) . ',' . $admin_user->user_email,
191
+ 'first_name' => $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name,
192
+ 'last_name' => $admin_user->last_name,
193
+ 'hash' => $this->client->hash,
194
+ 'server' => $this->__get_server_info(),
195
+ 'wp' => $this->__get_wp_info(),
196
+ 'users' => $this->__get_user_counts(),
197
+ 'active_plugins' => count( $all_plugins['active_plugins'] ),
198
+ 'inactive_plugins' => count( $all_plugins['inactive_plugins'] ),
199
+ 'ip_address' => $this->__get_user_ip_address(),
200
+ 'theme' => get_stylesheet(),
201
+ );
202
+ // for child classes
203
+ if ( $extra = $this->get_extra_data() ) {
204
+ $data['extra'] = $extra;
205
+ }
206
+ return apply_filters( $this->client->slug . '_tracker_data', $data );
207
+ }
208
+
209
+ /**
210
+ * If a child class wants to send extra data
211
+ *
212
+ * @return mixed
213
+ */
214
+ protected function get_extra_data() {
215
+ return $this->extra_data;
216
+ }
217
+
218
+ /**
219
+ * Explain the user which data we collect
220
+ *
221
+ * @return array
222
+ */
223
+ protected function data_we_collect() {
224
+ $data = array(
225
+ esc_html__( 'Server environment details (php, mysql, server, WordPress versions)', 'webappick' ),
226
+ esc_html__( 'Number of users in your site', 'webappick' ),
227
+ esc_html__( 'Number of products in your site', 'webappick' ),
228
+ esc_html__( 'Site language', 'webappick' ),
229
+ esc_html__( 'Number of active and inactive plugins', 'webappick' ),
230
+ esc_html__( 'Site name and url', 'webappick' ),
231
+ esc_html__( 'Your name and email address', 'webappick' ),
232
+ );
233
+ return $data;
234
+ }
235
+
236
+ /**
237
+ * Get Site SuperAdmin
238
+ * Returns Empty WP_User instance if fails
239
+ * @return WP_User
240
+ */
241
+ private function __get_admin() {
242
+ $admins = get_users( array(
243
+ 'role' => 'administrator',
244
+ 'orderby' => 'ID',
245
+ 'order' => 'ASC',
246
+ 'number' => 1,
247
+ 'paged' => 1,
248
+ ) );
249
+ return ( is_array( $admins ) && ! empty( $admins ) ) ? $admins[0] : new WP_User();
250
+ }
251
+
252
+ /**
253
+ * Check if the user has opted into tracking
254
+ *
255
+ * @return bool
256
+ */
257
+ private function __tracking_allowed() {
258
+ return 'yes' == get_option( $this->client->slug . '_allow_tracking', 'no' );
259
+ }
260
+
261
+ /**
262
+ * Get the last time a tracking was sent
263
+ *
264
+ * @return false|string
265
+ */
266
+ private function __get_last_send() {
267
+ return get_option( $this->client->slug . '_tracking_last_send', false );
268
+ }
269
+
270
+ /**
271
+ * Check if the notice has been dismissed or enabled
272
+ *
273
+ * @return boolean
274
+ */
275
+ private function __notice_dismissed() {
276
+ $hide_notice = get_option( $this->client->slug . '_tracking_notice', 'no' );
277
+ if ( 'hide' == $hide_notice ) return true;
278
+ return false;
279
+ }
280
+
281
+ /**
282
+ * Check if the current server is localhost
283
+ *
284
+ * @return boolean
285
+ */
286
+ private function __is_local_server() {
287
+ return apply_filters( 'WebAppick_is_local', in_array( $_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1' ) ) );
288
+ }
289
+
290
+ /**
291
+ * Schedule the event weekly
292
+ *
293
+ * @return void
294
+ */
295
+ private function __schedule_event() {
296
+ wp_schedule_event( time(), 'weekly', $this->client->slug . '_tracker_send_event' );
297
+ wp_schedule_event( time(), 'daily', $this->client->slug . '_license_check_event' );
298
+ }
299
+
300
+ /**
301
+ * Clear any scheduled hook
302
+ *
303
+ * @return void
304
+ */
305
+ private function __clear_schedule_event() {
306
+ wp_clear_scheduled_hook( $this->client->slug . '_tracker_send_event' );
307
+ wp_clear_scheduled_hook( $this->client->slug . '_license_check_event' );
308
+ }
309
+
310
+ /**
311
+ * Display the admin notice to users that have not opted-in or out
312
+ *
313
+ * @return void
314
+ */
315
+ public function admin_notice() {
316
+ if ( $this->__notice_dismissed() ) return;
317
+
318
+ if ( $this->__tracking_allowed() ) return;
319
+ if ( ! current_user_can( 'manage_options' ) ) return;
320
+
321
+ // don't show tracking if a local server
322
+ if ( ! $this->__is_local_server() ) {
323
+ $optOutUrl = add_query_arg( $this->client->slug . '_tracker_optOut', 'true' );
324
+ $optInUrl = add_query_arg( $this->client->slug . '_tracker_optIn', 'true' );
325
+
326
+ if ( empty( $this->notice ) ) {
327
+ $notice = sprintf( esc_html__( 'Want to help make %1$s even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.', 'webappick' ), '<strong>'.$this->client->name.'</strong>' );
328
+ } else {
329
+ $notice = $this->notice;
330
+ }
331
+
332
+ $notice .= ' (<a class="' . $this->client->slug . '-insights-data-we-collect" href="#">' . esc_html__( 'what we collect', 'webappick' ) . '</a>)';
333
+ $notice .= '<p class="description" style="display:none;">' . implode( ', ', $this->data_we_collect() ) . '. '. esc_html__( 'No sensitive data is tracked.', 'webappick' ) .'</p>';
334
+ echo '<div class="updated"><p>';
335
+ echo $notice;
336
+ echo '</p><p class="submit">';
337
+ echo '&nbsp;<a href="' . esc_url( $optOutUrl ) . '" class="button button-secondary">' . esc_html__( 'No thanks', 'webappick' ) . '</a>';
338
+ echo '&nbsp;<a href="' . esc_url( $optInUrl ) . '" class="button button-primary">' . esc_html__( 'Allow', 'webappick' ) . '</a>';
339
+ echo '</p></div>';
340
+ echo "<script type='text/javascript'>jQuery('." . $this->client->slug . "-insights-data-we-collect').on('click', function(e) {
341
+ e.preventDefault();
342
+ jQuery(this).parents('.updated').find('p.description').slideToggle('fast');
343
+ });</script>";
344
+ }
345
+ }
346
+
347
+ /**
348
+ * handle the optIn/optOut
349
+ *
350
+ * @return void
351
+ */
352
+ public function handle_optIn_optOut() {
353
+
354
+ if( isset( $_GET[ $this->client->slug . '_tracker_optIn' ] ) && $_GET[ $this->client->slug . '_tracker_optIn' ] == 'true' ) {
355
+ $this->optIn();
356
+ wp_redirect( remove_query_arg( $this->client->slug . '_tracker_optIn' ) );
357
+ exit;
358
+ }
359
+ if ( isset( $_GET[ $this->client->slug . '_tracker_optOut' ] ) && $_GET[ $this->client->slug . '_tracker_optOut' ] == 'true' ) {
360
+ $this->optOut();
361
+ wp_redirect( remove_query_arg( $this->client->slug . '_tracker_optOut' ) );
362
+ exit;
363
+ }
364
+ }
365
+
366
+ /**
367
+ * Add query vars to removable query args array
368
+ * @param array $removable_query_args
369
+ * @return array
370
+ */
371
+ public function add_removable_query_args( $removable_query_args ) {
372
+ return array_merge( $removable_query_args, array($this->client->slug . '_tracker_optIn', $this->client->slug . '_tracker_optOut' ) );
373
+ }
374
+
375
+ /**
376
+ * Tracking optIn
377
+ *
378
+ * @return void
379
+ */
380
+ public function optIn() {
381
+ update_option( $this->client->slug . '_allow_tracking', 'yes' );
382
+ update_option( $this->client->slug . '_tracking_notice', 'hide' );
383
+
384
+ $this->__clear_schedule_event();
385
+ $this->__schedule_event();
386
+ $this->send_tracking_data();
387
+ }
388
+
389
+ /**
390
+ * optOut from tracking
391
+ *
392
+ * @return void
393
+ */
394
+ public function optOut() {
395
+ update_option( $this->client->slug . '_allow_tracking', 'no' );
396
+ update_option( $this->client->slug . '_tracking_notice', 'hide' );
397
+ $this->__clear_schedule_event();
398
+ }
399
+
400
+ /**
401
+ * Get the number of post counts
402
+ *
403
+ * @param string $post_type
404
+ *
405
+ * @return integer
406
+ */
407
+ public function get_post_count( $post_type ) {
408
+ global $wpdb;
409
+ return (int) $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts WHERE post_type = '$post_type' and post_status = 'publish'");
410
+ }
411
+
412
+ /**
413
+ * Get server related info.
414
+ *
415
+ * @return array
416
+ */
417
+ private function __get_server_info() {
418
+ global $wpdb;
419
+ $server_data = array(
420
+ 'software' => ( isset( $_SERVER['SERVER_SOFTWARE'] ) && ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) ? $_SERVER['SERVER_SOFTWARE'] : 'N/A',
421
+ 'php_version' => ( function_exists( 'phpversion' ) ) ? phpversion() : 'N/A',
422
+ 'mysql_version' => $wpdb->db_version(),
423
+ 'php_max_upload_size' => size_format( wp_max_upload_size() ),
424
+ 'php_default_timezone' => date_default_timezone_get(),
425
+ 'php_soap' => class_exists( 'SoapClient' ) ? 'Yes' : 'No',
426
+ 'php_fsockopen' => function_exists( 'fsockopen' ) ? 'Yes' : 'No',
427
+ 'php_curl' => function_exists( 'curl_init' ) ? 'Yes' : 'No',
428
+ 'php_ftp' => function_exists( 'ftp_connect' ) ? 'Yes' : 'No',
429
+ 'php_sftp' => function_exists( 'ssh2_connect' ) ? 'Yes' : 'No',
430
+ );
431
+ return $server_data;
432
+ }
433
+
434
+ /**
435
+ * Get WordPress related data.
436
+ *
437
+ * @return array
438
+ */
439
+ private function __get_wp_info() {
440
+ $wp_data = array(
441
+ 'memory_limit' => WP_MEMORY_LIMIT,
442
+ 'debug_mode' => ( defined('WP_DEBUG') && WP_DEBUG ) ? 'Yes' : 'No',
443
+ 'locale' => get_locale(),
444
+ 'version' => get_bloginfo( 'version' ),
445
+ 'multisite' => is_multisite() ? 'Yes' : 'No',
446
+ );
447
+ return $wp_data;
448
+ }
449
+
450
+ /**
451
+ * Get the list of active and inactive plugins
452
+ * @return array
453
+ */
454
+ private function __get_all_plugins() {
455
+ if( ! function_exists( 'get_plugins' ) ) {
456
+ include ABSPATH . '/wp-admin/includes/plugin.php';
457
+ }
458
+ $plugins = get_plugins();
459
+ $active_plugins = array();
460
+ $active_plugins_keys = get_option( 'active_plugins', array() );
461
+ foreach ( $plugins as $k => $v ) {
462
+ // Take care of formatting the data how we want it.
463
+ $formatted = array(
464
+ 'name' => strip_tags( $v['Name'] ),
465
+ 'version' => isset( $v['Version'] ) ? strip_tags( $v['Version'] ) : 'N/A',
466
+ 'author' => isset( $v['Author'] ) ? strip_tags( $v['Author'] ) : 'N/A',
467
+ 'network' => isset( $v['Network'] ) ? strip_tags( $v['Network'] ) : 'N/A',
468
+ 'plugin_uri' => isset( $v['PluginURI'] ) ? strip_tags( $v['PluginURI'] ) : 'N/A',
469
+ );
470
+ if ( in_array( $k, $active_plugins_keys ) ) {
471
+ unset( $plugins[$k] ); // Remove active plugins from list so we can show active and inactive separately
472
+ $active_plugins[$k] = $formatted;
473
+ } else {
474
+ $plugins[$k] = $formatted;
475
+ }
476
+ }
477
+ return array( 'active_plugins' => $active_plugins, 'inactive_plugins' => $plugins );
478
+ }
479
+
480
+ /**
481
+ * Get user totals based on user role.
482
+ *
483
+ * @return array
484
+ */
485
+ public function __get_user_counts() {
486
+ $user_count = array();
487
+ $user_count_data = count_users();
488
+ $user_count['total'] = $user_count_data['total_users'];
489
+ // Get user count based on user role
490
+ foreach ( $user_count_data['avail_roles'] as $role => $count ) {
491
+ $user_count[ $role ] = $count;
492
+ }
493
+ return $user_count;
494
+ }
495
+
496
+ /**
497
+ * Add weekly cron schedule
498
+ *
499
+ * @param array $schedules
500
+ *
501
+ * @return array
502
+ */
503
+ public function add_weekly_schedule( $schedules ) {
504
+ $schedules['weekly'] = array(
505
+ 'interval' => DAY_IN_SECONDS * 7,
506
+ 'display' => __( 'Once Weekly', 'webappick' )
507
+ );
508
+ return $schedules;
509
+ }
510
+
511
+ /**
512
+ * Plugin activation hook
513
+ *
514
+ * @return void
515
+ */
516
+ public function activate_plugin() {
517
+ $allowed = get_option( $this->client->slug . '_allow_tracking', 'no' );
518
+ // if it wasn't allowed before, do nothing
519
+ if ( 'yes' !== $allowed ) return;
520
+ // re-schedule and delete the last sent time so we could force send again
521
+ wp_schedule_event( time(), 'weekly', $this->client->slug . '_tracker_send_event' );
522
+ delete_option( $this->client->slug . '_tracking_last_send' );
523
+ $this->send_tracking_data( true );
524
+ }
525
+
526
+ /**
527
+ * Clear our options upon deactivation
528
+ *
529
+ * @return void
530
+ */
531
+ public function deactivation_cleanup() {
532
+ $this->__clear_schedule_event();
533
+
534
+ if ( 'theme' == $this->client->type ) {
535
+ delete_option( $this->client->slug . '_tracking_last_send' );
536
+ delete_option( $this->client->slug . '_allow_tracking' );
537
+ }
538
+
539
+ delete_option( $this->client->slug . '_tracking_notice' );
540
+ }
541
+
542
+ /**
543
+ * Hook into action links and modify the deactivate link
544
+ *
545
+ * @param array $links
546
+ *
547
+ * @return array
548
+ */
549
+ public function plugin_action_links( $links ) {
550
+
551
+ if ( array_key_exists( 'deactivate', $links ) ) {
552
+ $links['deactivate'] = str_replace( '<a', '<a class="' . $this->client->slug . '-deactivate-link"', $links['deactivate'] );
553
+ }
554
+
555
+ return $links;
556
+ }
557
+
558
+ /**
559
+ * Deactivation reasons
560
+ * @return array
561
+ */
562
+ private function __get_uninstall_reasons() {
563
+
564
+ $reasons = array(
565
+
566
+ array(
567
+ 'id' => 'could-not-understand',
568
+ 'text' => esc_html__( 'I couldn\'t understand how to make it work', 'webappick' ),
569
+ 'type' => 'textarea',
570
+ 'placeholder' => esc_html__( 'Would you like us to assist you?', 'webappick' ),
571
+ ),
572
+ array(
573
+ 'id' => 'found-better-plugin',
574
+ 'text' => esc_html__( 'I found a better plugin', 'webappick' ),
575
+ 'type' => 'text',
576
+ 'placeholder' => esc_html__( 'Which plugin?', 'webappick' ),
577
+ ),
578
+ array(
579
+ 'id' => 'not-have-that-feature',
580
+ 'text' => esc_html__( 'The plugin is great, but I need specific feature that you don\'t support', 'webappick' ),
581
+ 'type' => 'textarea',
582
+ 'placeholder' => esc_html__( 'Could you tell us more about that feature?', 'webappick' ),
583
+ ),
584
+ array(
585
+ 'id' => 'is-not-working',
586
+ 'text' => esc_html__( 'The plugin is not working', 'webappick' ),
587
+ 'type' => 'textarea',
588
+ 'placeholder' => esc_html__( 'Could you tell us a bit more whats not working?', 'webappick' ),
589
+ ),
590
+ array(
591
+ 'id' => 'looking-for-other',
592
+ 'text' => esc_html__( 'It\'s not what I was looking for', 'webappick' ),
593
+ 'type' => '',
594
+ 'placeholder' => '',
595
+ ),
596
+ array(
597
+ 'id' => 'did-not-work-as-expected',
598
+ 'text' => esc_html__( 'The plugin didn\'t work as expected', 'webappick' ),
599
+ 'type' => 'textarea',
600
+ 'placeholder' => esc_html__( 'What did you expect?', 'webappick' ),
601
+ ),
602
+ array(
603
+ 'id' => 'other',
604
+ 'text' => esc_html__( 'Other', 'webappick' ),
605
+ 'type' => 'textarea',
606
+ 'placeholder' => esc_html__( 'Could you tell us a bit more?', 'webappick' ),
607
+ ),
608
+ );
609
+
610
+ return $reasons;
611
+ }
612
+
613
+ /**
614
+ * Plugin deactivation uninstall reason submission
615
+ *
616
+ * @return void
617
+ */
618
+ public function uninstall_reason_submission() {
619
+
620
+ if ( ! isset( $_POST['reason_id'] ) ) wp_send_json_error();
621
+
622
+ $current_user = wp_get_current_user();
623
+ global $wpdb;
624
+ /**
625
+ * @TODO remove old data variable after server upgrade
626
+ $data = array(
627
+ 'hash' => $this->client->hash,
628
+ 'reason_id' => sanitize_text_field( $_POST['reason_id'] ),
629
+ 'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( stripslashes( $_REQUEST['reason_info'] ) ) : '',
630
+ 'site' => $this->__get_site_name(),
631
+ 'url' => esc_url( home_url() ),
632
+ 'admin_email' => get_option( 'admin_email' ),
633
+ 'user_email' => $current_user->user_email,
634
+ 'first_name' => $current_user->first_name,
635
+ 'last_name' => $current_user->last_name,
636
+ 'server' => $this->__get_server_info(),
637
+ 'wp' => $this->__get_wp_info(),
638
+ 'ip_address' => $this->__get_user_ip_address(),
639
+ 'version' => $this->client->project_version,
640
+ );*/
641
+ $data = array(
642
+ 'reason_id' => sanitize_text_field( $_POST['reason_id'] ), // WPCS: CSRF ok, Input var ok.
643
+ 'plugin' => "Woo Feed Free",
644
+ 'url' => home_url(),
645
+ 'user_email' => $current_user->data->user_email,
646
+ 'user_name' => $current_user->data->display_name,
647
+ 'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( stripslashes( $_REQUEST['reason_info'] ) ) : '',
648
+ 'software' => $_SERVER['SERVER_SOFTWARE'],
649
+ 'php_version' => phpversion(),
650
+ 'mysql_version' => $wpdb->db_version(),
651
+ 'wp_version' => get_bloginfo( 'version' ),
652
+ 'locale' => get_locale(),
653
+ 'multisite' => is_multisite() ? 'Yes' : 'No'
654
+ );
655
+ // Add extra data
656
+ if ( $extra = $this->get_extra_data() ) {
657
+ $data['extra'] = $extra;
658
+ }
659
+ $this->client->send_request( $data, '' );
660
+ wp_send_json_success();
661
+ }
662
+
663
+ /**
664
+ * Handle the plugin deactivation feedback
665
+ *
666
+ * @return void
667
+ */
668
+ public function deactivate_scripts() {
669
+ global $pagenow;
670
+
671
+ if ( 'plugins.php' != $pagenow ) {
672
+ return;
673
+ }
674
+
675
+ $reasons = $this->__get_uninstall_reasons();
676
+ ?>
677
+
678
+ <div class="wapk-dr-modal" id="<?php echo $this->client->slug; ?>-wapk-dr-modal">
679
+ <div class="wapk-dr-modal-wrap">
680
+ <div class="wapk-dr-modal-header">
681
+ <h3><?php _e( 'If you have a moment, please let us know why you are deactivating:', 'domain' ); ?></h3>
682
+ </div>
683
+
684
+ <div class="wapk-dr-modal-body">
685
+ <ul class="reasons">
686
+ <?php foreach ($reasons as $reason) { ?>
687
+ <li data-type="<?php echo esc_attr( $reason['type'] ); ?>" data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>">
688
+ <label><input type="radio" name="selected-reason" value="<?php echo $reason['id']; ?>"> <?php echo $reason['text']; ?></label>
689
+ </li>
690
+ <?php } ?>
691
+ </ul>
692
+ </div>
693
+
694
+ <div class="wapk-dr-modal-footer">
695
+ <a href="#" class="dont-bother-me"><?php _e( 'I rather wouldn\'t say', 'domain' ); ?></a>
696
+ <button class="button-secondary"><?php _e( 'Submit & Deactivate', 'domain' ); ?></button>
697
+ <button class="button-primary"><?php _e( 'Cancel', 'domain' ); ?></button>
698
+ </div>
699
+ </div>
700
+ </div>
701
+
702
+ <!--suppress CssUnusedSymbol -->
703
+ <style type="text/css">
704
+ .wapk-dr-modal {
705
+ position: fixed;
706
+ z-index: 99999;
707
+ top: 0;
708
+ right: 0;
709
+ bottom: 0;
710
+ left: 0;
711
+ background: rgba(0,0,0,0.5);
712
+ display: none;
713
+ }
714
+
715
+ .wapk-dr-modal.modal-active {
716
+ display: block;
717
+ }
718
+
719
+ .wapk-dr-modal-wrap {
720
+ width: 475px;
721
+ position: relative;
722
+ margin: 10% auto;
723
+ background: #fff;
724
+ }
725
+
726
+ .wapk-dr-modal-header {
727
+ border-bottom: 1px solid #eee;
728
+ padding: 8px 20px;
729
+ }
730
+
731
+ .wapk-dr-modal-header h3 {
732
+ line-height: 150%;
733
+ margin: 0;
734
+ }
735
+
736
+ .wapk-dr-modal-body {
737
+ padding: 5px 20px 20px 20px;
738
+ }
739
+
740
+ .wapk-dr-modal-body .reason-input {
741
+ margin-top: 5px;
742
+ margin-left: 20px;
743
+ }
744
+ .wapk-dr-modal-footer {
745
+ border-top: 1px solid #eee;
746
+ padding: 12px 20px;
747
+ text-align: right;
748
+ }
749
+ </style>
750
+
751
+ <!--suppress JSUnresolvedVariable, ES6ConvertVarToLetConst -->
752
+ <script type="text/javascript">
753
+ (function($) {
754
+ $(function() {
755
+ /**
756
+ * Ajax Helper For Submitting Deactivation Reasons
757
+ * @param {Object} data
758
+ * @param {*|jQuery|HTMLElement} buttonElem
759
+ * @param {String} redirectTo
760
+ * @returns {*|jQuery}
761
+ * @private
762
+ */
763
+ function _ajax( data, buttonElem, redirectTo ) {
764
+ if ( buttonElem.hasClass('disabled') ) return;
765
+ return $.ajax( {
766
+ url: ajaxurl,
767
+ type: 'POST',
768
+ data: $.fn.extend( {}, data, { action: '<?php echo $this->client->slug; ?>_submit-uninstall-reason' } ),
769
+ beforeSend: function() {
770
+ buttonElem.addClass("disabled");
771
+ buttonElem.text('Processing...');
772
+ },
773
+ always: function() {
774
+ window.location.href = redirectTo;
775
+ } // not only on complete...!
776
+ } );
777
+ }
778
+ var modal = $( '#<?php echo $this->client->slug; ?>-wapk-dr-modal' ), deactivateLink = '';
779
+ $( '#the-list' ).on('click', 'a.<?php echo $this->client->slug; ?>-deactivate-link', function(e) {
780
+ e.preventDefault();
781
+ modal.addClass('modal-active');
782
+ deactivateLink = $(this).attr('href');
783
+ modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left');
784
+ });
785
+ modal.on('click', 'button.button-primary', function(e) {
786
+ e.preventDefault();
787
+ modal.removeClass('modal-active');
788
+ }).on('click', 'input[type="radio"]', function () {
789
+ modal.find('.reason-input').remove();
790
+ var parent = $(this).parents('li:first'),
791
+ inputType = parent.data('type'),
792
+ inputPlaceholder = parent.data('placeholder'),
793
+ reasonInputHtml = '<div class="reason-input">' + ( ( 'text' === inputType ) ? '<input type="text" size="40" />' : '<textarea rows="5" cols="45"></textarea>' ) + '</div>';
794
+ if ( inputType !== '' ) {
795
+ parent.append( $(reasonInputHtml) );
796
+ parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
797
+ }
798
+ }).on('click', '.dont-bother-me', function(e) {
799
+ e.preventDefault();
800
+ _ajax( { reason_id: 'no-comment', reason_info: 'I rather wouldn\'t say' }, $(this), deactivateLink );
801
+ }).on('click', 'button.button-secondary', function(e) {
802
+ e.preventDefault();
803
+ var $radio = $( 'input[type="radio"]:checked', modal ),
804
+ $selected_reason = $radio.parents('li:first'),
805
+ $input = $selected_reason.find('textarea, input[type="text"]');
806
+ _ajax( {
807
+ reason_id: ( 0 === $radio.length ) ? 'none' : $radio.val(),
808
+ reason_info: ( 0 !== $input.length ) ? $input.val().trim() : ''
809
+ }, $(this), deactivateLink );
810
+ });
811
+ });
812
+ }(jQuery));
813
+ </script>
814
+ <?php
815
+ }
816
+
817
+ /**
818
+ * Run after theme deactivated
819
+ * @param string $new_name
820
+ * @param WP_Theme $new_theme
821
+ * @param WP_Theme $old_theme
822
+ * @return void
823
+ */
824
+ public function theme_deactivated( $new_name, $new_theme, $old_theme ) {
825
+ // Make sure this is WebAppick theme
826
+ if( $old_theme->get_template() == $this->client->slug ) {
827
+ $current_user = wp_get_current_user();
828
+ /** @noinspection PhpUndefinedFieldInspection */
829
+ $data = array(
830
+ 'hash' => $this->client->hash,
831
+ 'reason_id' => 'none',
832
+ 'reason_info' => json_encode( [
833
+ 'new_theme' => [
834
+ 'name' => $new_name,
835
+ 'version' => $new_theme->version,
836
+ 'parent_theme' => $new_name->parent_theme,
837
+ 'author' => $new_name->parent_theme,
838
+ ]
839
+ ] ),
840
+ 'site' => $this->__get_site_name(),
841
+ 'url' => esc_url( home_url() ),
842
+ 'admin_email' => get_option( 'admin_email' ),
843
+ 'user_email' => $current_user->user_email,
844
+ 'first_name' => $current_user->first_name,
845
+ 'last_name' => $current_user->last_name,
846
+ 'server' => $this->__get_server_info(),
847
+ 'wp' => $this->__get_wp_info(),
848
+ 'ip_address' => $this->__get_user_ip_address(),
849
+ 'version' => $this->client->project_version,
850
+ );
851
+ $this->client->send_request( $data, 'deactivate' );
852
+ }
853
+ }
854
+
855
+ /**
856
+ * Get user IP Address
857
+ * @return string
858
+ */
859
+ private function __get_user_ip_address() {
860
+ $response = wp_remote_get( 'https://icanhazip.com/' );
861
+ if( is_wp_error( $response ) ) return '';
862
+ $ip = trim( wp_remote_retrieve_body( $response ) );
863
+ if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) return '';
864
+ return $ip;
865
+ }
866
+
867
+ /**
868
+ * Get site name
869
+ * @return string
870
+ */
871
+ private function __get_site_name() {
872
+ $site_name = get_bloginfo( 'name' );
873
+ if ( empty( $site_name ) ) {
874
+ $site_name = get_bloginfo( 'description' );
875
+ $site_name = wp_trim_words( $site_name, 3, '' );
876
+ }
877
+ if ( empty( $site_name ) ) $site_name = get_bloginfo( 'url' );
878
+ return $site_name;
879
+ }
880
+ }
881
+ // End of file Insights.php
libs/WebAppick/License.php ADDED
@@ -0,0 +1,343 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WebAppick;
3
+ /**
4
+ * WebAppick License Checker
5
+ *
6
+ * This class will check, active and deactive license
7
+ */
8
+ class License {
9
+
10
+ /**
11
+ * Client
12
+ *
13
+ * @var object
14
+ */
15
+ protected $client;
16
+
17
+ /**
18
+ * Arguments of create menu
19
+ *
20
+ * @var array
21
+ */
22
+ protected $menu_args;
23
+
24
+ /**
25
+ * `option_name` of `wp_options` table
26
+ *
27
+ * @var string
28
+ */
29
+ protected $option_key;
30
+
31
+ /**
32
+ * Error message of HTTP request
33
+ *
34
+ * @var string
35
+ */
36
+ protected $error;
37
+
38
+ /**
39
+ * Success message on form submit
40
+ *
41
+ * @var string
42
+ */
43
+ protected $success;
44
+
45
+ /**
46
+ * Set value for valid license
47
+ *
48
+ * @var boolean
49
+ */
50
+ private $is_valid_license = null;
51
+
52
+ /**
53
+ * Initialize the class
54
+ *
55
+ * @param Client
56
+ */
57
+ public function __construct( Client $client ) {
58
+ $this->client = $client;
59
+
60
+ $this->option_key = 'WebAppick_' . md5( $this->client->slug ) . '_licenses';
61
+ }
62
+
63
+ /**
64
+ * Check license
65
+ * @param string $license_key
66
+ * @return boolean
67
+ */
68
+ public function check( $license_key ) {
69
+ $route = 'public/license/' . $this->client->hash . '/check';
70
+
71
+ return $this->send_request( $license_key, $route );
72
+ }
73
+
74
+ /**
75
+ * Active a license
76
+ *
77
+ * @return boolean
78
+ */
79
+ public function activate( $license_key ) {
80
+ $route = 'public/license/' . $this->client->hash . '/activate';
81
+
82
+ return $this->send_request( $license_key, $route );
83
+ }
84
+
85
+ /**
86
+ * Deactivate a license
87
+ *
88
+ * @return array
89
+ */
90
+ public function deactivate( $license_key ) {
91
+ $route = 'public/license/' . $this->client->hash . '/deactivate';
92
+ return $this->send_request( $license_key, $route );
93
+ }
94
+
95
+ /**
96
+ * Send common request
97
+ *
98
+ * @param $license_key
99
+ * @param $route
100
+ *
101
+ * @return array
102
+ */
103
+ protected function send_request( $license_key, $route ) {
104
+ $params = array(
105
+ 'license_key' => $license_key,
106
+ 'url' => esc_url( home_url() ),
107
+ );
108
+ $response = $this->client->send_request( $params, $route, true );
109
+
110
+ if ( is_wp_error( $response ) ) {
111
+ return array(
112
+ 'success' => false,
113
+ 'error' => $response->get_error_message()
114
+ );
115
+ }
116
+
117
+ $response = json_decode( wp_remote_retrieve_body( $response ), true );
118
+
119
+ if ( empty( $response ) || isset( $response['exception'] )) {
120
+ return array(
121
+ 'success' => false,
122
+ 'error' => 'Unknown error occurred, Please try again.'
123
+ );
124
+ }
125
+
126
+ if ( isset( $response['errors'] ) && isset( $response['errors']['license_key'] ) ) {
127
+ $response = array(
128
+ 'success' => false,
129
+ 'error' => $response['errors']['license_key'][0]
130
+ );
131
+ }
132
+
133
+ return $response;
134
+ }
135
+
136
+ /**
137
+ * Add settings page for license
138
+ *
139
+ * @param array $args
140
+ *
141
+ * @return void
142
+ */
143
+ public function add_settings_page( $args = array() ) {
144
+ $defaults = array(
145
+ 'type' => 'menu', // Can be: menu, options, submenu
146
+ 'page_title' => 'Manage License',
147
+ 'menu_title' => 'Manage License',
148
+ 'capability' => 'manage_options',
149
+ 'menu_slug' => 'manage-license',
150
+ 'icon_url' => '',
151
+ 'position' => null,
152
+ 'parent_slug' => '',
153
+ );
154
+
155
+ $this->menu_args = wp_parse_args( $args, $defaults );
156
+
157
+ add_action( 'admin_menu', array( $this, 'admin_menu' ) );
158
+
159
+ add_action( $this->client->slug . '_license_check_event', array( $this, 'check_license_status' ) );
160
+ }
161
+
162
+ /**
163
+ * Admin Menu hook
164
+ *
165
+ * @return void
166
+ */
167
+ public function admin_menu() {
168
+ $add_page = 'add_' . $this->menu_args['type'] . '_page';
169
+
170
+ switch ( $this->menu_args['type'] ) {
171
+ case 'menu':
172
+ $add_page(
173
+ $this->menu_args['page_title'],
174
+ $this->menu_args['menu_title'],
175
+ $this->menu_args['capability'],
176
+ $this->menu_args['menu_slug'],
177
+ array( $this, 'menu_output' ),
178
+ $this->menu_args['icon_url'],
179
+ $this->menu_args['position']
180
+ );
181
+ break;
182
+
183
+ case 'submenu':
184
+ $add_page(
185
+ $this->menu_args['parent_slug'],
186
+ $this->menu_args['page_title'],
187
+ $this->menu_args['menu_title'],
188
+ $this->menu_args['capability'],
189
+ $this->menu_args['menu_slug'],
190
+ array( $this, 'menu_output' )
191
+ );
192
+ break;
193
+
194
+ case 'options':
195
+ $add_page(
196
+ $this->menu_args['page_title'],
197
+ $this->menu_args['menu_title'],
198
+ $this->menu_args['capability'],
199
+ $this->menu_args['menu_slug'],
200
+ array( $this, 'menu_output' )
201
+ );
202
+ break;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * License menu output
208
+ */
209
+ public function menu_output() {
210
+
211
+ if ( isset( $_POST['submit'] ) ) {
212
+ $this->license_page_form( $_POST );
213
+ }
214
+
215
+ $license = get_option( $this->option_key, null );
216
+ $action = ( $license && isset( $license['status'] ) && 'activate' == $license['status'] ) ? 'Deactive' : 'Active';
217
+ ?>
218
+
219
+ <div class="wrap">
220
+ <h1><?php echo $this->menu_args['menu_title']; ?></h1>
221
+
222
+ <?php if ( ! empty( $this->error ) ) : ?>
223
+ <div class="notice notice-error is-dismissible" style="max-width: 745px;">
224
+ <p><?php echo $this->error; ?></p>
225
+ </div>
226
+ <?php endif; ?>
227
+
228
+ <?php if ( ! empty( $this->success ) ) : ?>
229
+ <div class="notice notice-success is-dismissible" style="max-width: 745px;">
230
+ <p><?php echo $this->success; ?></p>
231
+ </div>
232
+ <?php endif; ?>
233
+
234
+ <br />
235
+
236
+ <div class="widget open" style="max-width: 800px; margin: 0;">
237
+ <div class="widget-top">
238
+ <div class="widget-title"><h3>License Settings</h3></div>
239
+ </div>
240
+ <div class="widget-inside" style="display: block; padding: 5px 15px;">
241
+ <form method="post" action="<?php echo home_url( $_SERVER['REQUEST_URI'] ); ?>" novalidate="novalidate">
242
+ <table class="form-table">
243
+ <tbody>
244
+ <tr>
245
+ <th scope="row">
246
+ <label>License key</label>
247
+ </th>
248
+ <td>
249
+ <input type="text" class="regular-text code" value="<?php echo $license['key']; ?>"
250
+ placeholder="Enter your license key" name="license_key"
251
+ <?php echo ( 'Deactive' == $action ) ? 'readonly="readonly"' : ''; ?> />
252
+ </td>
253
+ </tr>
254
+ </tbody>
255
+ </table>
256
+ <input type="hidden" name="_action" value="<?php echo $action; ?>">
257
+ <p>
258
+ <button type="submit" name="submit" class="button button-primary"><?php echo $action; ?></button>
259
+ </p>
260
+ </form>
261
+ </div>
262
+ </div> <!-- /.widget -->
263
+ </div>
264
+
265
+ <?php
266
+ }
267
+
268
+ /**
269
+ * License form submit
270
+ */
271
+ private function license_page_form( $form ) {
272
+ if ( $form['_action'] == 'Active' ) {
273
+ $response = $this->activate( $form['license_key'] );
274
+
275
+ if ( ! empty( $response['success'] ) ) {
276
+ $data = array(
277
+ 'key' => $form['license_key'],
278
+ 'status' => 'activate',
279
+ );
280
+ update_option( $this->option_key, $data, false );
281
+ $this->success = 'License activated successfully.';
282
+ }
283
+ } else if ( $form['_action'] == 'Deactive' ) {
284
+ $response = $this->deactivate( $form['license_key'] );
285
+
286
+ if ( ! empty( $response['success'] ) ) {
287
+ $this->success = 'License deactivated successfully.';
288
+ }
289
+
290
+ $data = array(
291
+ 'key' => '',
292
+ 'status' => 'deactivate',
293
+ );
294
+
295
+ update_option( $this->option_key, $data, false );
296
+ }
297
+
298
+ if ( isset( $response['error'] ) && ! empty( $response['error'] ) ) {
299
+ $this->error = $response['error'];
300
+ }
301
+
302
+ // var_export( $response );
303
+ }
304
+
305
+ /**
306
+ * Check license status on schedule
307
+ */
308
+ public function check_license_status() {
309
+ $license = get_option( $this->option_key, null );
310
+
311
+ if ( isset( $license['key'] ) && ! empty( $license['key'] ) ) {
312
+ $response = $this->check( $license['key'] );
313
+
314
+ if ( isset( $response['success'] ) && $response['success'] ) {
315
+ $license['status'] = 'activate';
316
+ } else {
317
+ $license['status'] = 'deactivate';
318
+ }
319
+
320
+ update_option( $this->option_key, $license, false );
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Check this is a valid license
326
+ */
327
+ public function is_valid() {
328
+ if ( null !== $this->is_valid_license ) {
329
+ return $this->is_valid_license;
330
+ }
331
+
332
+ $license = get_option( $this->option_key, null );
333
+ if ( ! empty( $license['key'] ) && isset( $license['status'] ) && $license['status'] == 'activate' ) {
334
+ $this->is_valid_license = true;
335
+ } else {
336
+ $this->is_valid_license = false;
337
+ }
338
+
339
+ return $this->is_valid_license;
340
+ }
341
+
342
+ }
343
+ // End of file License.php
libs/WebAppick/Updater.php ADDED
@@ -0,0 +1,250 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WebAppick;
3
+ /**
4
+ * WebAppick Updater
5
+ *
6
+ * This class will show new updates project
7
+ */
8
+ class Updater {
9
+
10
+ /**
11
+ * WebAppick\Client
12
+ *
13
+ * @var Client
14
+ */
15
+ protected $client;
16
+
17
+ /**
18
+ * Initialize the class
19
+ *
20
+ * @param Client
21
+ */
22
+ public function __construct( Client $client ) {
23
+
24
+ $this->client = $client;
25
+ $this->cache_key = 'WebAppick_' . md5( $this->client->slug ) . '_version_info';
26
+
27
+ // Run hooks.
28
+ if ( $this->client->type == 'plugin' ) {
29
+ $this->run_plugin_hooks();
30
+ } elseif ( $this->client->type == 'theme' ) {
31
+ $this->run_theme_hooks();
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Set up WordPress filter to hooks to get update.
37
+ *
38
+ * @return void
39
+ */
40
+ public function run_plugin_hooks() {
41
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_plugin_update' ) );
42
+ add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
43
+ }
44
+
45
+ /**
46
+ * Set up WordPress filter to hooks to get update.
47
+ *
48
+ * @return void
49
+ */
50
+ public function run_theme_hooks() {
51
+ add_filter( 'pre_set_site_transient_update_themes', array( $this, 'check_theme_update' ) );
52
+ }
53
+
54
+ /**
55
+ * Check for Update for this specific project
56
+ * @param object $transient_data
57
+ * @return object
58
+ */
59
+ public function check_plugin_update( $transient_data ) {
60
+ global $pagenow;
61
+
62
+ if ( ! is_object( $transient_data ) ) {
63
+ $transient_data = new \stdClass;
64
+ }
65
+
66
+ if ( 'plugins.php' == $pagenow && is_multisite() ) {
67
+ return $transient_data;
68
+ }
69
+
70
+ if ( ! empty( $transient_data->response ) && ! empty( $transient_data->response[ $this->client->basename ] ) ) {
71
+ return $transient_data;
72
+ }
73
+
74
+ $version_info = $this->get_cached_version_info();
75
+
76
+ if ( false === $version_info ) {
77
+ $version_info = $this->get_project_latest_version();
78
+ $this->set_cached_version_info( $version_info );
79
+ }
80
+
81
+ if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
82
+
83
+ if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) {
84
+ unset( $version_info->sections );
85
+ $transient_data->response[ $this->client->basename ] = $version_info;
86
+ }
87
+
88
+ $transient_data->last_checked = time();
89
+ $transient_data->checked[ $this->client->basename ] = $this->client->project_version;
90
+ }
91
+
92
+ return $transient_data;
93
+ }
94
+
95
+ /**
96
+ * Get version info from database
97
+ *
98
+ * @return object|bool
99
+ */
100
+ private function get_cached_version_info() {
101
+
102
+ $value = get_transient( $this->cache_key );
103
+
104
+ if( ! $value && ! isset( $value->name ) ) {
105
+ return false; // Cache is expired
106
+ }
107
+
108
+ // We need to turn the icons into an array
109
+ if ( isset( $value->icons ) ) {
110
+ $value->icons = (array) $value->icons;
111
+ }
112
+
113
+ // We need to turn the banners into an array
114
+ if ( isset( $value->banners ) ) {
115
+ $value->banners = (array) $value->banners;
116
+ }
117
+
118
+ if ( isset( $value->sections ) ) {
119
+ $value->sections = (array) $value->sections;
120
+ }
121
+
122
+ return $value;
123
+ }
124
+
125
+ /**
126
+ * Set version info to database
127
+ * @param string $value
128
+ * @return void
129
+ */
130
+ private function set_cached_version_info( $value ) {
131
+ if ( ! $value ) {
132
+ return;
133
+ }
134
+ set_transient( $this->cache_key, $value, 3 * HOUR_IN_SECONDS );
135
+ }
136
+
137
+ /**
138
+ * Get plugin info from WebAppick
139
+ */
140
+ private function get_project_latest_version() {
141
+
142
+ $license_option_key = 'WebAppick_' . md5( $this->client->slug ) . '_manage_license';
143
+ $license = get_option( $license_option_key, null );
144
+
145
+ $params = array(
146
+ 'version' => $this->client->project_version,
147
+ 'name' => $this->client->name,
148
+ 'slug' => $this->client->slug,
149
+ 'basename' => $this->client->basename,
150
+ 'license_key' => ! empty( $license ) && isset( $license['key'] ) ? $license['key'] : '',
151
+ );
152
+
153
+ $route = 'update/' . $this->client->hash . '/check';
154
+
155
+ $response = $this->client->send_request( $params, $route, true );
156
+
157
+ if ( is_wp_error( $response ) ) {
158
+ return false;
159
+ }
160
+
161
+ $response = json_decode( wp_remote_retrieve_body( $response ) );
162
+
163
+ if ( ! isset( $response->slug ) ) {
164
+ return false;
165
+ }
166
+
167
+ if ( isset( $response->icons ) ) {
168
+ $response->icons = (array) $response->icons;
169
+ }
170
+
171
+ if ( isset( $response->banners ) ) {
172
+ $response->banners = (array) $response->banners;
173
+ }
174
+
175
+ if ( isset( $response->sections ) ) {
176
+ $response->sections = (array) $response->sections;
177
+ }
178
+
179
+ return $response;
180
+ }
181
+
182
+ /**
183
+ * Updates information on the "View version x.x details" page with custom data.
184
+ *
185
+ * @param mixed $data
186
+ * @param string $action
187
+ * @param object $args
188
+ *
189
+ * @return object $data
190
+ */
191
+ public function plugins_api_filter( $data, $action = '', $args = null ) {
192
+
193
+ if ( $action != 'plugin_information' ) {
194
+ return $data;
195
+ }
196
+
197
+ if ( ! isset( $args->slug ) || ( $args->slug != $this->client->slug ) ) {
198
+ return $data;
199
+ }
200
+
201
+ $version_info = $this->get_cached_version_info();
202
+
203
+ if ( false === $version_info ) {
204
+ $version_info = $this->get_project_latest_version();
205
+ $this->set_cached_version_info( $version_info );
206
+ }
207
+
208
+ return $version_info;
209
+ }
210
+
211
+ /**
212
+ * Check theme upate
213
+ */
214
+ public function check_theme_update( $transient_data ) {
215
+ global $pagenow;
216
+
217
+ if ( ! is_object( $transient_data ) ) {
218
+ $transient_data = new \stdClass;
219
+ }
220
+
221
+ if ( 'themes.php' == $pagenow && is_multisite() ) {
222
+ return $transient_data;
223
+ }
224
+
225
+ if ( ! empty( $transient_data->response ) && ! empty( $transient_data->response[ $this->client->slug ] ) ) {
226
+ return $transient_data;
227
+ }
228
+
229
+ $version_info = $this->get_cached_version_info();
230
+
231
+ if ( false === $version_info ) {
232
+ $version_info = $this->get_project_latest_version();
233
+ $this->set_cached_version_info( $version_info );
234
+ }
235
+
236
+ if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
237
+
238
+ if ( version_compare( $this->client->project_version, $version_info->new_version, '<' ) ) {
239
+ $transient_data->response[ $this->client->slug ] = (array) $version_info;
240
+ }
241
+
242
+ $transient_data->last_checked = time();
243
+ $transient_data->checked[ $this->client->slug ] = $this->client->project_version;
244
+ }
245
+
246
+ return $transient_data;
247
+ }
248
+
249
+ }
250
+ // End of file Updater.php
libs/WebAppick/index.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php // Silence is golden
libs/index.php ADDED
@@ -0,0 +1 @@
 
1
+ <?php // Silence is golden
woo-feed.php CHANGED
@@ -15,7 +15,7 @@
15
  * Plugin Name: WooCommerce Product Feed
16
  * Plugin URI: https://webappick.com/
17
  * Description: This plugin generate WooCommerce product feed for Shopping Engines like Google Shopping,Facebook Product Feed,eBay,Amazon,Idealo and many more..
18
- * Version: 3.1.40
19
  * Author: WebAppick
20
  * Author URI: https://webappick.com/
21
  * License: GPL v2
@@ -23,50 +23,109 @@
23
  * Text Domain: woo-feed
24
  * Domain Path: /languages
25
  * WC requires at least: 2.6
26
- * WC tested up to: 3.6
27
  *
28
  */
29
-
30
  // Exit if accessed directly
31
  if (!defined('ABSPATH')) die();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
  /**
34
- * Plugin Version
35
- * @var string
36
  */
37
- define( 'WOO_FEED_VERSION', '3.1.40' );
38
 
39
  /**
40
- * Plugin Path with trailing slash
41
- * @var string
42
  */
43
- define( 'WOO_FEED_Path', plugin_dir_path( __FILE__ ) );
44
- /**
45
- * Plugin Directory URL
46
- * @var string
47
- * @since 3.1.37
48
- */
49
- define( 'WOO_FEED_PLUGIN_URL', trailingslashit( plugin_dir_url(__FILE__) ) );
50
- /**
51
- * Admin File Path with trailing slash
52
- * @var string
53
- */
54
- define( 'WOO_FEED_Admin_Path', WOO_FEED_Path . 'admin/' );
55
 
56
  if( ! class_exists( 'Woo_Feed' ) ) {
57
  /**
58
  * The core plugin class that is used to define internationalization,
59
  * admin-specific hooks, and public-facing site hooks.
60
  */
61
- require plugin_dir_path(__FILE__) . 'includes/class-woo-feed.php';
62
  }
 
63
  if( ! function_exists( 'activate_woo_feed' ) ) {
64
  /**
65
  * The code that runs during plugin activation.
66
  * This action is documented in includes/class-woo-feed-activator.php
 
67
  */
68
  function activate_woo_feed() {
69
- require plugin_dir_path(__FILE__) . 'includes/class-woo-feed-activator.php';
 
 
 
 
 
 
 
 
 
70
  Woo_Feed_Activator::activate();
71
  }
72
  register_activation_hook(__FILE__, 'activate_woo_feed');
@@ -77,7 +136,7 @@ if( ! function_exists( 'deactivate_woo_feed' ) ) {
77
  * This action is documented in includes/class-woo-feed-deactivator.php
78
  */
79
  function deactivate_woo_feed() {
80
- require plugin_dir_path(__FILE__) . 'includes/class-woo-feed-deactivator.php';
81
  Woo_Feed_Deactivator::deactivate();
82
  }
83
  register_deactivation_hook(__FILE__, 'deactivate_woo_feed');
@@ -94,7 +153,13 @@ if( ! function_exists( 'run_woo_feed' ) ) {
94
  */
95
  function run_woo_feed() {
96
  $plugin = new Woo_Feed();
97
- $plugin->run();
 
 
 
 
 
 
98
  }
99
  run_woo_feed();
100
  }
@@ -126,14 +191,12 @@ if( ! function_exists( 'feed_merchant_view' ) ) {
126
  /** @noinspection PhpUnusedLocalVariableInspection */
127
  $merchant = $provider = sanitize_text_field($_POST['merchant']);
128
  if(strpos($merchant,'amazon')!==false){
129
- include plugin_dir_path(__FILE__) . "admin/partials/templates/amazon_add-feed.php";
130
- }
131
- else if($merchant == 'smartly.io')
132
- {
133
- include plugin_dir_path(__FILE__) . "admin/partials/templates/google_add-feed.php";
134
- }
135
- else{
136
- include plugin_dir_path(__FILE__) . "admin/partials/templates/". $merchant . "_add-feed.php";
137
  }
138
  die();
139
  }
@@ -142,9 +205,11 @@ if( ! function_exists( 'feed_merchant_view' ) ) {
142
  if( ! function_exists( 'woo_feed_add_update' ) ) {
143
  /**
144
  * Update Feed Information
 
 
 
145
  */
146
- function woo_feed_add_update($info = "", $name = "")
147
- {
148
  set_time_limit(0);
149
  if (count($info) && isset($info['provider'])) {
150
  # GEt Post data
@@ -254,7 +319,6 @@ if( ! function_exists( 'woo_feed_add_update' ) ) {
254
  }
255
  }
256
  }
257
-
258
  return false;
259
  }
260
  }
@@ -618,8 +682,7 @@ if( ! function_exists( 'woo_feed_save_feed_file' ) ) {
618
  $tempFiles['footerFile'] =$path . "/" . "wf_store_feed_footer_info_".$fileName . "." . $type;
619
 
620
  woo_feed_unlink_tempFiles($tempFiles);
621
-
622
- $update = update_option('wf_feed_' . $fileName, serialize($feedInfo));
623
  if ($saveFile) {
624
 
625
  # FTP File Upload Info
@@ -795,10 +858,10 @@ if( ! function_exists( 'woo_feed_generate_feed' ) ) {
795
  wp_schedule_event(time(), 'woo_feed_corn', 'woo_feed_update_single_feed',$arg);
796
 
797
 
798
- require plugin_dir_path(__FILE__) . 'admin/partials/woo-feed-manage-list.php';
799
  } else {
800
  echo "<div class='notice notice-warning is-dismissible'><p>" . __("You are awesome for using <b>WooCommerce Product Feed</b>. Free version works great for up to <b>2000 products including variations.</b>", 'woo-feed') . "</p></div>";
801
- require plugin_dir_path(__FILE__) . 'admin/partials/woo-feed-admin-display.php';
802
  }
803
  }
804
  }
@@ -833,7 +896,7 @@ if( ! function_exists( 'woo_feed_manage_feed' ) ) {
833
  # Store Config
834
  update_option( $fileName, $_POST );
835
 
836
- require plugin_dir_path(__FILE__) . 'admin/partials/woo-feed-manage-list.php';
837
  wp_die();
838
  }
839
 
@@ -885,14 +948,18 @@ if( ! function_exists( 'woo_feed_manage_feed' ) ) {
885
  $fname = sanitize_text_field( $_GET['feed'] );
886
  $feedInfo = unserialize( get_option( $fname ) );
887
  $feedId = $wpdb->get_row( $wpdb->prepare( "SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT 1", $fname ) );
888
- if( $feedId ) $feedId = $feedId->option_id;
 
 
 
889
  $provider = strtolower( $feedInfo['feedrules']['provider'] );
 
890
  $feedRules = $feedInfo['feedrules'];
891
  //$provider == "custom" ||$provider == "twenga" || $provider == "pricespy" || $provider == "prisjakt" || $provider == "amazon" || $provider == "adwords"
892
  if ( in_array( $provider, $merchants ) ) {
893
- require plugin_dir_path(__FILE__) . "admin/partials/templates/custom_edit-feed.php";
894
  } else {
895
- require plugin_dir_path(__FILE__) . "admin/partials/woo-feed-edit-template.php";
896
  }
897
  }
898
  } else {
@@ -905,7 +972,7 @@ if( ! function_exists( 'woo_feed_manage_feed' ) ) {
905
  }
906
  }
907
 
908
- require plugin_dir_path(__FILE__) . 'admin/partials/woo-feed-manage-list.php';
909
  }
910
  }
911
  }
@@ -929,7 +996,7 @@ if( ! function_exists( 'woo_feed_pro_vs_free' ) ) {
929
  * Difference between free and premium plugin
930
  */
931
  function woo_feed_pro_vs_free(){
932
- require plugin_dir_path(__FILE__) . 'admin/partials/woo-feed-pro-vs-free.php';
933
  }
934
  }
935
  if( ! function_exists( 'woo_feed_config_feed' ) ) {
@@ -939,17 +1006,13 @@ if( ! function_exists( 'woo_feed_config_feed' ) ) {
939
  function woo_feed_config_feed(){
940
  if(isset($_POST['wa_woo_feed_config'])) {
941
  update_option("woo_feed_per_batch",sanitize_text_field($_POST['limit']));
942
- if(isset($_POST['enable_error_debugging']))
943
- {
944
  update_option("woo_feed_enable_error_debugging", sanitize_text_field($_POST['enable_error_debugging']));
945
- }
946
- else
947
- {
948
  update_option("woo_feed_enable_error_debugging", "off");
949
  }
950
  }
951
-
952
- require plugin_dir_path(__FILE__) . 'admin/partials/woo-feed-config.php';
953
  }
954
  }
955
  if( ! function_exists( 'woo_feed_getFeedInfoForCronUpdate' ) ) {
@@ -988,10 +1051,10 @@ if( ! function_exists( 'woo_feed_update_feed_status' ) ) {
988
  $feedInfo['status'] = $_POST['status'];
989
  $data = array('status' => true);
990
  update_option($_POST['feedName'],serialize($feedInfo));
991
- return wp_send_json_success($data);
992
  }else{
993
  $data = array('status' => false);
994
- return wp_send_json_error($data);
995
  }
996
  wp_die();
997
  }
@@ -1046,179 +1109,10 @@ if( ! function_exists( 'woo_feed_cron_update_single_feed' ) ) {
1046
  }
1047
  add_action('woo_feed_update_single_feed', 'woo_feed_cron_update_single_feed');
1048
  }
1049
- if( ! function_exists( 'woo_feed_plugin_action_links' ) ) {
1050
- /**
1051
- * Add Go to Pro and Documentation link
1052
- * @param array $links
1053
- * @return array
1054
- */
1055
- function woo_feed_plugin_action_links( $links ) {
1056
- if ( array_key_exists( 'deactivate', $links ) ) {
1057
- $links['deactivate'] = str_replace( '<a', '<a class="wpf-deactivate-link"', $links['deactivate'] );
1058
- }
1059
- $links[] = '<a style="color: #389e38; font-weight: bold;" 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">' . __( 'Get Pro', 'woo-feed' ) . '</a>';
1060
- /** @noinspection HtmlUnknownTarget */
1061
- $links[] = sprintf( '<a style="color:#ce7304; font-weight: bold;" href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-docs' ) ), __( 'Docs', 'woo-feed' ) );
1062
- /** @noinspection HtmlUnknownTarget */
1063
- $links[] = sprintf( '<a href="%s">%s</a>', esc_url( admin_url( 'admin.php?page=webappick-feed-settings' ) ), __( 'Settings', 'woo-feed' ) );
1064
- return $links;
1065
- }
1066
- add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'woo_feed_plugin_action_links' );
1067
- }
1068
- if( ! function_exists( 'woo_feed_get_uninstall_reasons' ) ) {
1069
- // uninstall reason
1070
- function woo_feed_get_uninstall_reasons() {
1071
-
1072
- $reasons = array(
1073
- array(
1074
- 'id' => 'could-not-understand',
1075
- 'text' => 'I couldn\'t understand how to make it work',
1076
- 'type' => 'textarea',
1077
- 'placeholder' => 'Would you like us to assist you?'
1078
- ),
1079
- array(
1080
- 'id' => 'found-better-plugin',
1081
- 'text' => 'I found a better plugin',
1082
- 'type' => 'text',
1083
- 'placeholder' => 'Which plugin?'
1084
- ),
1085
- array(
1086
- 'id' => 'not-have-that-feature',
1087
- 'text' => 'The plugin is great, but I need specific feature that you don\'t support',
1088
- 'type' => 'textarea',
1089
- 'placeholder' => 'Could you tell us more about that feature?'
1090
- ),
1091
- array(
1092
- 'id' => 'is-not-working',
1093
- 'text' => 'The plugin is not working',
1094
- 'type' => 'textarea',
1095
- 'placeholder' => 'Could you tell us a bit more whats not working?'
1096
- ),
1097
- array(
1098
- 'id' => 'looking-for-other',
1099
- 'text' => 'It\'s not what I was looking for',
1100
- 'type' => '',
1101
- 'placeholder' => ''
1102
- ),
1103
- array(
1104
- 'id' => 'did-not-work-as-expected',
1105
- 'text' => 'The plugin didn\'t work as expected',
1106
- 'type' => 'textarea',
1107
- 'placeholder' => 'What did you expect?'
1108
- ),
1109
- array(
1110
- 'id' => 'other',
1111
- 'text' => 'Other',
1112
- 'type' => 'textarea',
1113
- 'placeholder' => 'Could you tell us a bit more?'
1114
- ),
1115
- );
1116
-
1117
- return $reasons;
1118
- }
1119
- }
1120
- if( ! function_exists( 'woo_feed_uninstall_reason_submission' ) ) {
1121
- /**
1122
- * Plugin deactivation uninstall reason submission
1123
- *
1124
- * @return void
1125
- */
1126
- function woo_feed_uninstall_reason_submission(){
1127
- global $wpdb;
1128
-
1129
- if ( ! isset( $_POST['reason_id'] ) ) { // WPCS: CSRF ok, Input var ok.
1130
- wp_send_json_error();
1131
- }
1132
-
1133
- $CurUser = new WP_User(get_current_user_id());
1134
-
1135
- $data = array(
1136
- 'reason_id' => sanitize_text_field( $_POST['reason_id'] ), // WPCS: CSRF ok, Input var ok.
1137
- 'plugin' => "Woo Feed Free",
1138
- 'url' => home_url(),
1139
- 'user_email' => $CurUser->data->user_email,
1140
- 'user_name' => $CurUser->data->display_name,
1141
- 'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( stripslashes( $_REQUEST['reason_info'] ) ) : '',
1142
- 'software' => $_SERVER['SERVER_SOFTWARE'],
1143
- 'php_version' => phpversion(),
1144
- 'mysql_version' => $wpdb->db_version(),
1145
- 'wp_version' => get_bloginfo( 'version' ),
1146
- 'locale' => get_locale(),
1147
- 'multisite' => is_multisite() ? 'Yes' : 'No'
1148
- );
1149
-
1150
-
1151
- woo_feed_send_request( $data, 'uninstall_reason' );
1152
- wp_send_json_success();
1153
-
1154
- }
1155
- add_action( 'wp_ajax_woo-feed-submit-uninstall-reason', 'woo_feed_uninstall_reason_submission' );
1156
- }
1157
- if( ! function_exists( 'woo_feed_send_request' ) ) {
1158
- function woo_feed_send_request( $params, $route ) {
1159
- $api_url = "https://track.webappick.com/api/receive-uninstall-tracking";
1160
- return wp_remote_post($api_url, array(
1161
- 'method' => 'POST',
1162
- 'timeout' => 45,
1163
- 'redirection' => 5,
1164
- 'httpversion' => '1.0',
1165
- 'blocking' => false,
1166
- 'headers' => array( 'user-agent' => 'Webappick/' . md5( esc_url( home_url() ) ) . ';' ),
1167
- 'body' => $params,
1168
- 'cookies' => array()
1169
- )
1170
- );
1171
-
1172
- }
1173
- }
1174
- if( ! function_exists( 'woo_feed_deactivate_scripts' ) ) {
1175
- /**
1176
- * Handle the plugin deactivation feedback
1177
- *
1178
- * @return void
1179
- */
1180
- function woo_feed_deactivate_scripts() {
1181
-
1182
- global $pagenow;
1183
-
1184
- if ( 'plugins.php' != $pagenow ) {
1185
- return;
1186
- }
1187
-
1188
- $reasons = woo_feed_get_uninstall_reasons();
1189
- ?>
1190
- <!--pop up modal-->
1191
- <div class="wpf_deactive_plugin-modal" id="wpf_deactive_plugin-modal">
1192
- <div class="wpf_deactive_plugin-modal-wrap">
1193
- <div class="wpf_deactive_plugin-modal-header">
1194
- <h3><?php _e( 'If you have a moment, please let us know why you are deactivating:', 'woo-feed' ); ?></h3>
1195
- </div>
1196
-
1197
- <div class="wpf_deactive_plugin-modal-body">
1198
- <ul class="reasons">
1199
- <?php foreach ($reasons as $reason) { ?>
1200
- <li data-type="<?php echo esc_attr( $reason['type'] ); ?>" data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>">
1201
- <label><input type="radio" name="selected-reason" value="<?php echo $reason['id']; ?>"> <?php echo $reason['text']; ?></label>
1202
- </li>
1203
- <?php } ?>
1204
- </ul>
1205
- </div>
1206
-
1207
- <div class="wpf_deactive_plugin-modal-footer">
1208
- <a href="#" class="dont-bother-me"><?php _e( 'I rather wouldn\'t say', 'Woo Feed' ); ?></a>
1209
- <button class="button-secondary"><?php _e( 'Submit & Deactivate', 'Woo Feed' ); ?></button>
1210
- <button class="button-primary"><?php _e( 'Cancel', 'Woo Feed' ); ?></button>
1211
- </div>
1212
- </div>
1213
- </div>
1214
-
1215
- <?php
1216
- }
1217
- add_action( 'admin_footer', 'woo_feed_deactivate_scripts' );
1218
- }
1219
  if( ! function_exists( 'woo_feed_get_ssh2_status' ) ) {
1220
  function woo_feed_get_ssh2_status() {
1221
  check_ajax_referer( 'wpf_feed_nonce' );
 
1222
  $php_extension = get_loaded_extensions();
1223
  if(extension_loaded ( 'ssh2' )) {
1224
  wp_send_json_success('exists');
15
  * Plugin Name: WooCommerce Product Feed
16
  * Plugin URI: https://webappick.com/
17
  * Description: This plugin generate WooCommerce product feed for Shopping Engines like Google Shopping,Facebook Product Feed,eBay,Amazon,Idealo and many more..
18
+ * Version: 3.1.41
19
  * Author: WebAppick
20
  * Author URI: https://webappick.com/
21
  * License: GPL v2
23
  * Text Domain: woo-feed
24
  * Domain Path: /languages
25
  * WC requires at least: 2.6
26
+ * WC tested up to: 3.7.1
27
  *
28
  */
 
29
  // Exit if accessed directly
30
  if (!defined('ABSPATH')) die();
31
+ // Constants
32
+ if( ! defined( 'WOO_FEED_VERSION' ) ) {
33
+ /**
34
+ * Plugin Version
35
+ * @var string
36
+ */
37
+ define( 'WOO_FEED_VERSION', '3.1.41' );
38
+ }
39
+ if( ! defined( 'WOO_FEED_FREE_FILE') ) {
40
+ /**
41
+ * Plugin Base File
42
+ * @since 3.1.41
43
+ * @var string
44
+ */
45
+ define( 'WOO_FEED_FREE_FILE', __FILE__ );
46
+ }
47
+ if( ! defined( 'WOO_FEED_PATH' ) ) {
48
+ /**
49
+ * Plugin Path with trailing slash
50
+ * @var string dirname( __FILE__ )
51
+ */
52
+ /** @define "WOO_FEED_PATH" "./" */
53
+ define( 'WOO_FEED_PATH', plugin_dir_path( __FILE__ ) );
54
+ }
55
+ if( ! defined( 'WOO_FEED_ADMIN_PATH' ) ) {
56
+ /**
57
+ * Admin File Path with trailing slash
58
+ * @var string
59
+ */
60
+ define( 'WOO_FEED_ADMIN_PATH', WOO_FEED_PATH . 'admin/' );
61
+ }
62
+ if( ! defined( 'WOO_FEED_LIBS_PATH' ) ) {
63
+ /**
64
+ * Admin File Path with trailing slash
65
+ * @var string
66
+ */
67
+ define( 'WOO_FEED_LIBS_PATH', WOO_FEED_PATH . 'libs/' );
68
+ }
69
+ if( ! defined( 'WOO_FEED_PLUGIN_URL' ) ) {
70
+ /**
71
+ * Plugin Directory URL
72
+ * @var string
73
+ * @since 3.1.37
74
+ */
75
+ define( 'WOO_FEED_PLUGIN_URL', trailingslashit( plugin_dir_url(__FILE__) ) );
76
+ }
77
+ if( ! defined( 'WOO_FEED_MIN_PHP_VERSION' ) ) {
78
+ /**
79
+ * Minimum PHP Version Supported
80
+ * @var string
81
+ * @since 3.1.41
82
+ */
83
+ define( 'WOO_FEED_MIN_PHP_VERSION', '5.6.20' );
84
+ }
85
+ if( ! defined( 'WOO_FEED_PLUGIN_BASE_NAME' ) ) {
86
+ /**
87
+ * Plugin Base name..
88
+ * @var string
89
+ * @since 3.1.41
90
+ */
91
+ define( 'WOO_FEED_PLUGIN_BASE_NAME', plugin_basename(__FILE__) );
92
+ }
93
 
94
  /**
95
+ * Load Helper functions
 
96
  */
97
+ require_once WOO_FEED_PATH . 'includes/helper.php';
98
 
99
  /**
100
+ * Load Uses Tracker
 
101
  */
102
+ require_once WOO_FEED_PATH . 'includes/classes/class-woo-feed-tracker.php';
 
 
 
 
 
 
 
 
 
 
 
103
 
104
  if( ! class_exists( 'Woo_Feed' ) ) {
105
  /**
106
  * The core plugin class that is used to define internationalization,
107
  * admin-specific hooks, and public-facing site hooks.
108
  */
109
+ require_once WOO_FEED_PATH . 'includes/class-woo-feed.php';
110
  }
111
+
112
  if( ! function_exists( 'activate_woo_feed' ) ) {
113
  /**
114
  * The code that runs during plugin activation.
115
  * This action is documented in includes/class-woo-feed-activator.php
116
+ * @return void
117
  */
118
  function activate_woo_feed() {
119
+ // bail if unsupported php version
120
+ if( ! wooFeed_is_supported_php() ) {
121
+ echo '<div class="notice error"><p>'. sprintf( __( 'The Minimum PHP Version Requirement for <b>WooCommerce Product Feed</b> is %s. You are Running PHP %s', 'woo-feed' ), WOO_FEED_MIN_PHP_VERSION, phpversion() ) .'</p></div>';
122
+ die();
123
+ }
124
+ if( wooFeed_is_plugin_active( "webappick-product-feed-for-woocommerce/woo-feed.php" ) ) {
125
+ echo '<div class="notice error"><p>'. __( 'Please deactivate the <b>WooCommerce Product Feed Pro</b> version to activate free version again.', 'woo-feed' ) .'</p></div>';
126
+ die();
127
+ }
128
+ require_once WOO_FEED_PATH . 'includes/class-woo-feed-activator.php';
129
  Woo_Feed_Activator::activate();
130
  }
131
  register_activation_hook(__FILE__, 'activate_woo_feed');
136
  * This action is documented in includes/class-woo-feed-deactivator.php
137
  */
138
  function deactivate_woo_feed() {
139
+ require_once WOO_FEED_PATH . 'includes/class-woo-feed-deactivator.php';
140
  Woo_Feed_Deactivator::deactivate();
141
  }
142
  register_deactivation_hook(__FILE__, 'deactivate_woo_feed');
153
  */
154
  function run_woo_feed() {
155
  $plugin = new Woo_Feed();
156
+ /**
157
+ * Ensure Feed Plugin runs only if WooCommerce loaded (installed and activated)
158
+ * @since 3.1.41
159
+ */
160
+ add_action( 'woocommerce_loaded', array( $plugin, 'run' ) );
161
+ add_action( 'admin_notices', 'wooFeed_Admin_Notices' );
162
+ new WooFeedTracker();
163
  }
164
  run_woo_feed();
165
  }
191
  /** @noinspection PhpUnusedLocalVariableInspection */
192
  $merchant = $provider = sanitize_text_field($_POST['merchant']);
193
  if(strpos($merchant,'amazon')!==false){
194
+ include WOO_FEED_ADMIN_PATH . "partials/templates/amazon_add-feed.php";
195
+ } else if( $merchant == 'smartly.io' ) {
196
+ include WOO_FEED_ADMIN_PATH . "partials/templates/google_add-feed.php";
197
+ } else{
198
+ /** @noinspection PhpIncludeInspection */
199
+ include WOO_FEED_ADMIN_PATH . "partials/templates/" . $merchant . "_add-feed.php";
 
 
200
  }
201
  die();
202
  }
205
  if( ! function_exists( 'woo_feed_add_update' ) ) {
206
  /**
207
  * Update Feed Information
208
+ * @param array $info
209
+ * @param string $name
210
+ * @return string|bool
211
  */
212
+ function woo_feed_add_update($info = array(), $name = "") {
 
213
  set_time_limit(0);
214
  if (count($info) && isset($info['provider'])) {
215
  # GEt Post data
319
  }
320
  }
321
  }
 
322
  return false;
323
  }
324
  }
682
  $tempFiles['footerFile'] =$path . "/" . "wf_store_feed_footer_info_".$fileName . "." . $type;
683
 
684
  woo_feed_unlink_tempFiles($tempFiles);
685
+ update_option('wf_feed_' . $fileName, serialize($feedInfo));
 
686
  if ($saveFile) {
687
 
688
  # FTP File Upload Info
858
  wp_schedule_event(time(), 'woo_feed_corn', 'woo_feed_update_single_feed',$arg);
859
 
860
 
861
+ require WOO_FEED_ADMIN_PATH . "partials/woo-feed-manage-list.php";
862
  } else {
863
  echo "<div class='notice notice-warning is-dismissible'><p>" . __("You are awesome for using <b>WooCommerce Product Feed</b>. Free version works great for up to <b>2000 products including variations.</b>", 'woo-feed') . "</p></div>";
864
+ require WOO_FEED_ADMIN_PATH . "partials/woo-feed-admin-display.php";
865
  }
866
  }
867
  }
896
  # Store Config
897
  update_option( $fileName, $_POST );
898
 
899
+ require WOO_FEED_ADMIN_PATH . "partials/woo-feed-manage-list.php";
900
  wp_die();
901
  }
902
 
948
  $fname = sanitize_text_field( $_GET['feed'] );
949
  $feedInfo = unserialize( get_option( $fname ) );
950
  $feedId = $wpdb->get_row( $wpdb->prepare( "SELECT option_id FROM $wpdb->options WHERE option_name = %s LIMIT 1", $fname ) );
951
+ if( $feedId ) {
952
+ /** @noinspection PhpUnusedLocalVariableInspection */
953
+ $feedId = $feedId->option_id;
954
+ }
955
  $provider = strtolower( $feedInfo['feedrules']['provider'] );
956
+ /** @noinspection PhpUnusedLocalVariableInspection */
957
  $feedRules = $feedInfo['feedrules'];
958
  //$provider == "custom" ||$provider == "twenga" || $provider == "pricespy" || $provider == "prisjakt" || $provider == "amazon" || $provider == "adwords"
959
  if ( in_array( $provider, $merchants ) ) {
960
+ require WOO_FEED_ADMIN_PATH . "partials/templates/custom_edit-feed.php";
961
  } else {
962
+ require WOO_FEED_ADMIN_PATH . "partials/woo-feed-edit-template.php";
963
  }
964
  }
965
  } else {
972
  }
973
  }
974
 
975
+ require WOO_FEED_ADMIN_PATH . "partials/woo-feed-manage-list.php";
976
  }
977
  }
978
  }
996
  * Difference between free and premium plugin
997
  */
998
  function woo_feed_pro_vs_free(){
999
+ require WOO_FEED_ADMIN_PATH . "partials/woo-feed-pro-vs-free.php";
1000
  }
1001
  }
1002
  if( ! function_exists( 'woo_feed_config_feed' ) ) {
1006
  function woo_feed_config_feed(){
1007
  if(isset($_POST['wa_woo_feed_config'])) {
1008
  update_option("woo_feed_per_batch",sanitize_text_field($_POST['limit']));
1009
+ if(isset($_POST['enable_error_debugging'])) {
 
1010
  update_option("woo_feed_enable_error_debugging", sanitize_text_field($_POST['enable_error_debugging']));
1011
+ } else {
 
 
1012
  update_option("woo_feed_enable_error_debugging", "off");
1013
  }
1014
  }
1015
+ require WOO_FEED_ADMIN_PATH . "partials/woo-feed-config.php";
 
1016
  }
1017
  }
1018
  if( ! function_exists( 'woo_feed_getFeedInfoForCronUpdate' ) ) {
1051
  $feedInfo['status'] = $_POST['status'];
1052
  $data = array('status' => true);
1053
  update_option($_POST['feedName'],serialize($feedInfo));
1054
+ wp_send_json_success($data);
1055
  }else{
1056
  $data = array('status' => false);
1057
+ wp_send_json_error($data);
1058
  }
1059
  wp_die();
1060
  }
1109
  }
1110
  add_action('woo_feed_update_single_feed', 'woo_feed_cron_update_single_feed');
1111
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1112
  if( ! function_exists( 'woo_feed_get_ssh2_status' ) ) {
1113
  function woo_feed_get_ssh2_status() {
1114
  check_ajax_referer( 'wpf_feed_nonce' );
1115
+ /** @noinspection PhpUnusedLocalVariableInspection */
1116
  $php_extension = get_loaded_extensions();
1117
  if(extension_loaded ( 'ssh2' )) {
1118
  wp_send_json_success('exists');