WooLentor – Elementor WooCommerce Builder Addons, Variation Swatches Addons, Gutenberg WooCommerce Product block, grid, slider, templates, widgets, Quick View, Wishlist, Products Compare, Product Filter – All in One Solution - Version 2.1.7

Version Description

Download this release

Release Info

Developer devitemsllc
Plugin Icon 128x128 WooLentor – Elementor WooCommerce Builder Addons, Variation Swatches Addons, Gutenberg WooCommerce Product block, grid, slider, templates, widgets, Quick View, Wishlist, Products Compare, Product Filter – All in One Solution
Version 2.1.7
Comparing to
See all releases

Code changes from version 2.1.6 to 2.1.7

Files changed (92) hide show
  1. assets/css/woolentor-widgets.css +14 -6
  2. classes/class.assest_management.php +9 -0
  3. classes/class.widgets_control.php +9 -2
  4. includes/addons/product_flash_sale.php +1262 -0
  5. includes/admin/admin-init.php +17 -6
  6. includes/admin/assets/css/woolentor-admin.css +4 -0
  7. includes/admin/assets/js/woolentor-admin.js +3 -1
  8. includes/admin/include/admin_field-manager.php +6 -4
  9. includes/admin/include/admin_fields.php +96 -42
  10. includes/admin/include/class.extension-manager.php +0 -10
  11. includes/admin/include/settings_field_manager_default.php +796 -0
  12. includes/custom-metabox.php +90 -30
  13. includes/helper-function.php +26 -23
  14. includes/modules/class.module-manager.php +33 -2
  15. includes/modules/compare/assets/css/admin.css +142 -0
  16. includes/modules/compare/assets/css/frontend.css +395 -0
  17. includes/modules/compare/assets/css/frontend.min.css +1 -0
  18. includes/modules/compare/assets/images/extensions/email-candy-pro.png +0 -0
  19. includes/modules/compare/assets/images/extensions/hashbar-pro.png +0 -0
  20. includes/modules/compare/assets/images/extensions/htmega-pro.png +0 -0
  21. includes/modules/compare/assets/images/extensions/just-tables-pro.png +0 -0
  22. includes/modules/compare/assets/images/extensions/multicurrencypro.png +0 -0
  23. includes/modules/compare/assets/images/extensions/whols-pro.png +0 -0
  24. includes/modules/compare/assets/images/extensions/woolentor-addons-pro.png +0 -0
  25. includes/modules/compare/assets/images/icon.svg +22 -0
  26. includes/modules/compare/assets/images/loading.svg +14 -0
  27. includes/modules/compare/assets/js/admin.js +100 -0
  28. includes/modules/compare/assets/js/frontend.js +122 -0
  29. includes/modules/compare/assets/js/frontend.min.js +1 -0
  30. includes/modules/compare/includes/classes/Admin.php +34 -0
  31. includes/modules/compare/includes/classes/Admin/Admin_Fields.php +652 -0
  32. includes/modules/compare/includes/classes/Admin/Dashboard.php +112 -0
  33. includes/modules/compare/includes/classes/Ajax.php +57 -0
  34. includes/modules/compare/includes/classes/Assets.php +248 -0
  35. includes/modules/compare/includes/classes/Frontend.php +40 -0
  36. includes/modules/compare/includes/classes/Frontend/Manage_Compare.php +669 -0
  37. includes/modules/compare/includes/classes/Frontend/Shortcode.php +164 -0
  38. includes/modules/compare/includes/classes/Installer.php +39 -0
  39. includes/modules/compare/includes/helper-functions.php +167 -0
  40. includes/modules/compare/includes/templates/evercompare-button-add.php +1 -0
  41. includes/modules/compare/includes/templates/evercompare-table.php +47 -0
  42. includes/modules/compare/init.php +144 -0
  43. includes/modules/flash-sale/assets/css/flash-sale.css +534 -39
  44. includes/modules/flash-sale/assets/js/flash-sale.js +110 -11
  45. includes/modules/flash-sale/assets/js/moment-timezone-with-data.js +0 -1
  46. includes/modules/flash-sale/assets/js/moment.min.js +0 -1
  47. includes/modules/flash-sale/class.flash-sale.php +297 -108
  48. includes/modules/shopify-like-checkout/class.shopify-like-checkout.php +1 -1
  49. includes/modules/wishlist/assets/css/admin.css +135 -0
  50. includes/modules/wishlist/assets/css/frontend.css +457 -0
  51. includes/modules/wishlist/assets/images/extensions/email-candy-pro.png +0 -0
  52. includes/modules/wishlist/assets/images/extensions/hashbar-pro.png +0 -0
  53. includes/modules/wishlist/assets/images/extensions/htmega-pro.png +0 -0
  54. includes/modules/wishlist/assets/images/extensions/just-tables-pro.png +0 -0
  55. includes/modules/wishlist/assets/images/extensions/multicurrencypro.png +0 -0
  56. includes/modules/wishlist/assets/images/extensions/whols-pro.png +0 -0
  57. includes/modules/wishlist/assets/images/extensions/woolentor-addons-pro.png +0 -0
  58. includes/modules/wishlist/assets/images/icon.svg +29 -0
  59. includes/modules/wishlist/assets/images/loading.svg +14 -0
  60. includes/modules/wishlist/assets/images/remove.svg +1 -0
  61. includes/modules/wishlist/assets/images/social-icon/email.svg +1 -0
  62. includes/modules/wishlist/assets/images/social-icon/facebook.svg +1 -0
  63. includes/modules/wishlist/assets/images/social-icon/linkedin.svg +1 -0
  64. includes/modules/wishlist/assets/images/social-icon/odnoklassniki.svg +1 -0
  65. includes/modules/wishlist/assets/images/social-icon/pinterest.svg +1 -0
  66. includes/modules/wishlist/assets/images/social-icon/reddit.svg +1 -0
  67. includes/modules/wishlist/assets/images/social-icon/telegram.svg +1 -0
  68. includes/modules/wishlist/assets/images/social-icon/twitter.svg +1 -0
  69. includes/modules/wishlist/assets/images/social-icon/vk.svg +18 -0
  70. includes/modules/wishlist/assets/images/social-icon/whatsapp.svg +22 -0
  71. includes/modules/wishlist/assets/js/admin.js +58 -0
  72. includes/modules/wishlist/assets/js/frontend.js +313 -0
  73. includes/modules/wishlist/includes/classes/Admin.php +34 -0
  74. includes/modules/wishlist/includes/classes/Admin/Admin_Fields.php +582 -0
  75. includes/modules/wishlist/includes/classes/Admin/Dashboard.php +118 -0
  76. includes/modules/wishlist/includes/classes/Admin/Settings_Api.php +792 -0
  77. includes/modules/wishlist/includes/classes/Ajax.php +155 -0
  78. includes/modules/wishlist/includes/classes/Assets.php +206 -0
  79. includes/modules/wishlist/includes/classes/Frontend.php +39 -0
  80. includes/modules/wishlist/includes/classes/Frontend/Manage_Wishlist.php +601 -0
  81. includes/modules/wishlist/includes/classes/Frontend/Shortcode.php +196 -0
  82. includes/modules/wishlist/includes/classes/Installer.php +82 -0
  83. includes/modules/wishlist/includes/classes/Manage_Data.php +236 -0
  84. includes/modules/wishlist/includes/helper-functions.php +190 -0
  85. includes/modules/wishlist/includes/templates/wishsuite-button-add.php +1 -0
  86. includes/modules/wishlist/includes/templates/wishsuite-button-exist.php +1 -0
  87. includes/modules/wishlist/includes/templates/wishsuite-social-share.php +92 -0
  88. includes/modules/wishlist/includes/templates/wishsuite-table.php +52 -0
  89. includes/modules/wishlist/init.php +146 -0
  90. languages/woolentor.pot +161 -149
  91. readme.txt +13 -2
  92. woolentor_addons_elementor.php +3 -3
assets/css/woolentor-widgets.css CHANGED
@@ -399,8 +399,13 @@ li.woolentor-cart .button:before {
399
  position: relative;
400
  overflow: hidden;
401
  }
402
- .woolentor-product-same-height.ht-products .ht-product .ht-product-inner{
403
- height: 100%;
 
 
 
 
 
404
  }
405
  .woolentor-product-same-height.ht-products.product-slider .slick-list,.woolentor-product-same-height.ht-products.product-slider .slick-track,.woolentor-product-same-height.ht-products.product-slider .ht-product{
406
  height: 100% !important;
@@ -762,7 +767,7 @@ li.woolentor-cart .button:before {
762
  display: none !important;
763
  }
764
 
765
- .ht-products .ht-product .ht-product-inner .ht-product-action ul li a .ht-product-action-tooltip,span.woolentor-tip, .wishsuite-button.wishlist span.wishsuite-btn-text {
766
  position: absolute;
767
  left: 100%;
768
  top: 50%;
@@ -785,7 +790,7 @@ li.woolentor-cart .button:before {
785
  transition: all 0.5s ease;
786
  z-index: 99;
787
  }
788
- .wishsuite-button.wishlist span.wishsuite-btn-text{
789
  margin-right: -10px;
790
  -webkit-transform: translateY(-65%);
791
  -ms-transform: translateY(-65%);
@@ -4048,6 +4053,9 @@ h2.wl_filter_title {
4048
  text-decoration: none;
4049
  cursor: pointer;
4050
  }
 
 
 
4051
 
4052
  .wl_single-product-item {
4053
  margin-top: 30px;
@@ -4083,13 +4091,13 @@ h2.wl_filter_title {
4083
 
4084
  @media only screen and (max-width: 767px) {
4085
  .wl_single-product-item .product-thumbnail {
4086
- height: 235px;
4087
  }
4088
  }
4089
 
4090
  @media only screen and (max-width: 575px) {
4091
  .wl_single-product-item .product-thumbnail {
4092
- height: 270px;
4093
  }
4094
  }
4095
 
399
  position: relative;
400
  overflow: hidden;
401
  }
402
+ .woolentor-product-same-height.ht-products .ht-product .ht-product-inner {
403
+ height: 100%;
404
+ display: flex;
405
+ flex-direction: column;
406
+ }
407
+ .woolentor-product-same-height.ht-products .ht-product .ht-product-content {
408
+ flex: 1 0;
409
  }
410
  .woolentor-product-same-height.ht-products.product-slider .slick-list,.woolentor-product-same-height.ht-products.product-slider .slick-track,.woolentor-product-same-height.ht-products.product-slider .ht-product{
411
  height: 100% !important;
767
  display: none !important;
768
  }
769
 
770
+ .ht-products .ht-product .ht-product-inner .ht-product-action ul li a .ht-product-action-tooltip,span.woolentor-tip,[class*="elementor-widget-woolentor"]:not(.elementor-widget-woolentor-product-archive-addons) .wishsuite-button.wishlist span.wishsuite-btn-text {
771
  position: absolute;
772
  left: 100%;
773
  top: 50%;
790
  transition: all 0.5s ease;
791
  z-index: 99;
792
  }
793
+ [class*="elementor-widget-woolentor"]:not(.elementor-widget-woolentor-product-archive-addons) .wishsuite-button.wishlist span.wishsuite-btn-text{
794
  margin-right: -10px;
795
  -webkit-transform: translateY(-65%);
796
  -ms-transform: translateY(-65%);
4053
  text-decoration: none;
4054
  cursor: pointer;
4055
  }
4056
+ .wl_single-product-item a.htcompare-btn{
4057
+ justify-content: center;
4058
+ }
4059
 
4060
  .wl_single-product-item {
4061
  margin-top: 30px;
4091
 
4092
  @media only screen and (max-width: 767px) {
4093
  .wl_single-product-item .product-thumbnail {
4094
+ height: auto;
4095
  }
4096
  }
4097
 
4098
  @media only screen and (max-width: 575px) {
4099
  .wl_single-product-item .product-thumbnail {
4100
+ height: auto;
4101
  }
4102
  }
4103
 
classes/class.assest_management.php CHANGED
@@ -111,6 +111,10 @@ class Assets_Management{
111
  'src' => WOOLENTOR_ADDONS_PL_URL . 'assets/addons/ajax-search/css/ajax-search.css',
112
  'version' => WOOLENTOR_VERSION
113
  ],
 
 
 
 
114
 
115
  'woolentor-admin' => [
116
  'src' => WOOLENTOR_ADDONS_PL_URL . 'includes/admin/assets/css/woolentor-admin.css',
@@ -226,6 +230,11 @@ class Assets_Management{
226
  'version' => WOOLENTOR_VERSION,
227
  'deps' => [ 'jquery','wc-checkout' ]
228
  ],
 
 
 
 
 
229
 
230
 
231
  'woolentor-admin-main' =>[
111
  'src' => WOOLENTOR_ADDONS_PL_URL . 'assets/addons/ajax-search/css/ajax-search.css',
112
  'version' => WOOLENTOR_VERSION
113
  ],
114
+ 'woolentor-flash-sale-module' => [
115
+ 'src' => WOOLENTOR_ADDONS_PL_URL . 'includes/modules/flash-sale/assets/css/flash-sale.css',
116
+ 'version' => WOOLENTOR_VERSION,
117
+ ],
118
 
119
  'woolentor-admin' => [
120
  'src' => WOOLENTOR_ADDONS_PL_URL . 'includes/admin/assets/css/woolentor-admin.css',
230
  'version' => WOOLENTOR_VERSION,
231
  'deps' => [ 'jquery','wc-checkout' ]
232
  ],
233
+ 'woolentor-flash-sale-module' => [
234
+ 'src' => WOOLENTOR_ADDONS_PL_URL . 'includes/modules/flash-sale/assets/js/flash-sale.js',
235
+ 'version' => WOOLENTOR_VERSION,
236
+ 'deps' => [ 'jquery', 'countdown-min' ]
237
+ ],
238
 
239
 
240
  'woolentor-admin-main' =>[
classes/class.widgets_control.php CHANGED
@@ -345,14 +345,21 @@ class Widgets_Control{
345
 
346
  ];
347
 
348
- if( is_plugin_active('wishsuite/wishsuite.php') ){
 
 
 
 
 
 
 
349
  $widget_list['common']['wb_wishsuite_table'] = [
350
  'title' => esc_html__('WishSuite Table','woolentor'),
351
  'is_pro' => false,
352
  ];
353
  }
354
 
355
- if( is_plugin_active('ever-compare/ever-compare.php') ){
356
  $widget_list['common']['wb_ever_compare_table'] = [
357
  'title' => esc_html__('EverCompare','woolentor'),
358
  'is_pro' => false,
345
 
346
  ];
347
 
348
+ if( woolentor_get_option('enable', 'woolentor_flash_sale_settings') == 'on' ){
349
+ $widget_list['common']['product_flash_sale'] = [
350
+ 'title' => esc_html__('WL: Product Flash Sale','woolentor'),
351
+ 'is_pro' => false,
352
+ ];
353
+ }
354
+
355
+ if( class_exists('WishSuite_Base') || class_exists('Woolentor_WishSuite_Base') ){
356
  $widget_list['common']['wb_wishsuite_table'] = [
357
  'title' => esc_html__('WishSuite Table','woolentor'),
358
  'is_pro' => false,
359
  ];
360
  }
361
 
362
+ if( class_exists('Ever_Compare') || class_exists('Woolentor_Ever_Compare') ){
363
  $widget_list['common']['wb_ever_compare_table'] = [
364
  'title' => esc_html__('EverCompare','woolentor'),
365
  'is_pro' => false,
includes/addons/product_flash_sale.php ADDED
@@ -0,0 +1,1262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Elementor;
3
+
4
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
5
+
6
+ class Woolentor_Product_Flash_Sale_Widget extends Widget_Base {
7
+
8
+ public function get_name() {
9
+ return 'woolentor-flash-sale-product';
10
+ }
11
+
12
+ public function get_title() {
13
+ return __( 'WL: Product Flash Sale', 'woolentor' );
14
+ }
15
+
16
+ public function get_icon() {
17
+ return 'eicon-cart-light';
18
+ }
19
+
20
+ public function get_categories() {
21
+ return [ 'woolentor-addons' ];
22
+ }
23
+
24
+ public function get_style_depends(){
25
+ return [
26
+ 'htflexboxgrid',
27
+ 'font-awesome',
28
+ 'simple-line-icons',
29
+ 'woolentor-flash-sale-module',
30
+ ];
31
+ }
32
+
33
+ public function get_script_depends() {
34
+ return [
35
+ 'woolentor-flash-sale-module',
36
+ ];
37
+ }
38
+
39
+ public function get_keywords(){
40
+ return ['flash','product','sale','flash sale'];
41
+ }
42
+
43
+ public function get_deal_options(){
44
+ $deals = woolentor_get_option('deals', 'woolentor_flash_sale_settings');
45
+
46
+ $deal_options = array_map(function($item){
47
+
48
+ return !empty($item['title']) ? $item['title'] : __('Unnamed Deal', 'woolentor');
49
+
50
+ }, $deals);
51
+
52
+ return $deal_options;
53
+ }
54
+
55
+ protected function register_controls() {
56
+ // General settings
57
+ $this->start_controls_section(
58
+ 'woolentor-products-general-setting',
59
+ [
60
+ 'label' => esc_html__( 'General Settings', 'woolentor' ),
61
+ ]
62
+ );
63
+
64
+ $this->add_control(
65
+ 'deal',
66
+ [
67
+ 'label' => esc_html__( 'Select Deal', 'woolentor' ),
68
+ 'type' => Controls_Manager::SELECT,
69
+ 'options' => $this->get_deal_options(),
70
+ 'default' => '0',
71
+ ]
72
+ );
73
+
74
+ $this->add_control(
75
+ 'woolentor_product_grid_products_count',
76
+ [
77
+ 'label' => __( 'Product Limit', 'woolentor' ),
78
+ 'type' => Controls_Manager::NUMBER,
79
+ 'default' => 9,
80
+ 'step' => 1,
81
+ ]
82
+ );
83
+
84
+ $this->add_control(
85
+ 'woolentor_product_grid_column',
86
+ [
87
+ 'label' => esc_html__( 'Columns', 'woolentor' ),
88
+ 'type' => Controls_Manager::SELECT,
89
+ 'default' => '3',
90
+ 'options' => [
91
+ '1' => esc_html__( '1', 'woolentor' ),
92
+ '2' => esc_html__( '2', 'woolentor' ),
93
+ '3' => esc_html__( '3', 'woolentor' ),
94
+ '4' => esc_html__( '4', 'woolentor' ),
95
+ '5' => esc_html__( '5', 'woolentor' ),
96
+ '6' => esc_html__( '6', 'woolentor' ),
97
+ ],
98
+ ]
99
+ );
100
+
101
+ $this->add_control(
102
+ 'woolentor_custom_order',
103
+ [
104
+ 'label' => esc_html__( 'Custom Order', 'woolentor' ),
105
+ 'type' => Controls_Manager::SWITCHER,
106
+ 'return_value' => 'yes',
107
+ 'default' => 'no',
108
+ ]
109
+ );
110
+
111
+ $this->add_control(
112
+ 'orderby',
113
+ [
114
+ 'label' => esc_html__( 'Order by', 'woolentor' ),
115
+ 'type' => Controls_Manager::SELECT,
116
+ 'default' => 'none',
117
+ 'options' => [
118
+ 'none' => esc_html__('None','woolentor'),
119
+ 'ID' => esc_html__('ID','woolentor'),
120
+ 'date' => esc_html__('Date','woolentor'),
121
+ 'name' => esc_html__('Name','woolentor'),
122
+ 'title' => esc_html__('Title','woolentor'),
123
+ 'comment_count' => esc_html__('Comment count','woolentor'),
124
+ 'rand' => esc_html__('Random','woolentor'),
125
+ ],
126
+ 'condition' => [
127
+ 'woolentor_custom_order' => 'yes',
128
+ ]
129
+ ]
130
+ );
131
+
132
+ $this->add_control(
133
+ 'order',
134
+ [
135
+ 'label' => esc_html__( 'Order', 'woolentor' ),
136
+ 'type' => Controls_Manager::SELECT,
137
+ 'default' => 'DESC',
138
+ 'options' => [
139
+ 'DESC' => esc_html__('Descending','woolentor'),
140
+ 'ASC' => esc_html__('Ascending','woolentor'),
141
+ ],
142
+ 'condition' => [
143
+ 'woolentor_custom_order' => 'yes',
144
+ ]
145
+ ]
146
+ );
147
+
148
+ $this->end_controls_section();
149
+
150
+ // Countdown settings
151
+ $this->start_controls_section(
152
+ 'woolentor-products-countdown-setting',
153
+ [
154
+ 'label' => esc_html__( 'Countdown', 'woolentor' ),
155
+ ]
156
+ );
157
+ $this->add_control(
158
+ 'show_countdown',
159
+ [
160
+ 'label' => __( 'Show Countdown Timer', 'woolentor' ),
161
+ 'type' => Controls_Manager::SWITCHER,
162
+ 'label_on' => __( 'Show', 'woolentor' ),
163
+ 'label_off' => __( 'Hide', 'woolentor' ),
164
+ 'return_value' => 'yes',
165
+ 'default' => 'yes',
166
+ ]
167
+ );
168
+
169
+ $this->add_control(
170
+ 'countdown_style',
171
+ [
172
+ 'label' => __( 'Countdown Style', 'woolentor' ),
173
+ 'type' => Controls_Manager::SELECT,
174
+ 'default' => '1',
175
+ 'options' => [
176
+ '1' => __( 'Style One', 'woolentor' ),
177
+ '2' => __( 'Style Two', 'woolentor' ),
178
+ ],
179
+ 'condition' =>[
180
+ 'show_countdown' => 'yes',
181
+ ]
182
+ ]
183
+ );
184
+
185
+ $this->add_control(
186
+ 'countdown_position',
187
+ [
188
+ 'label' => __( 'Position', 'woolentor' ),
189
+ 'type' => Controls_Manager::CHOOSE,
190
+ 'options' => [
191
+ 'content_top' => [
192
+ 'title' => __( 'Content Top', 'woolentor' ),
193
+ 'icon' => 'eicon-v-align-top',
194
+ ],
195
+ 'content_bottom' => [
196
+ 'title' => __( 'Content Bottom', 'woolentor' ),
197
+ 'icon' => 'eicon-v-align-bottom',
198
+ ],
199
+ 'left' => [
200
+ 'title' => __( 'Thumbnail Left', 'woolentor' ),
201
+ 'icon' => 'eicon-h-align-left',
202
+ ],
203
+ 'right' => [
204
+ 'title' => __( 'Thumbnail Right', 'woolentor' ),
205
+ 'icon' => 'eicon-h-align-right',
206
+ ],
207
+ 'bottom' => [
208
+ 'title' => __( 'Thumbnail Bottom', 'woolentor' ),
209
+ 'icon' => 'eicon-v-align-bottom',
210
+ ],
211
+ ],
212
+ 'default' => 'content_top',
213
+ 'toggle' => false,
214
+ 'label_block' => true,
215
+ 'condition' =>[
216
+ 'show_countdown' => 'yes',
217
+ ]
218
+ ]
219
+ );
220
+
221
+ $this->add_control(
222
+ 'countdown_title',
223
+ [
224
+ 'label' => __( 'Countdown Title', 'woolentor' ),
225
+ 'type' => Controls_Manager::TEXT,
226
+ 'label_block' => true,
227
+ 'description' => __( 'HTML tags are allowed.', 'woolentor' ),
228
+ 'default' => woolentor_get_option('countdown_timer_title', 'woolentor_flash_sale_settings'),
229
+ 'condition' => [
230
+ 'show_countdown' => 'yes',
231
+ 'countdown_position' => array('content_top', 'content_bottom')
232
+ ]
233
+ ]
234
+ );
235
+
236
+ $this->add_control(
237
+ 'custom_labels',
238
+ [
239
+ 'label' => __( 'Custom Label', 'woolentor' ),
240
+ 'type' => Controls_Manager::SWITCHER,
241
+ 'return_value' => 'yes',
242
+ 'condition' => [
243
+ 'show_countdown' => 'yes',
244
+ ]
245
+ ]
246
+ );
247
+
248
+ $this->add_control(
249
+ 'customlabel_days',
250
+ [
251
+ 'label' => __( 'Days', 'woolentor' ),
252
+ 'type' => Controls_Manager::TEXT,
253
+ 'placeholder' => __( 'Days', 'woolentor' ),
254
+ 'condition' => [
255
+ 'custom_labels!' => '',
256
+ 'show_countdown' => 'yes',
257
+ ]
258
+ ]
259
+ );
260
+
261
+ $this->add_control(
262
+ 'customlabel_hours',
263
+ [
264
+ 'label' => __( 'Hours', 'woolentor' ),
265
+ 'type' => Controls_Manager::TEXT,
266
+ 'placeholder' => __( 'Hours', 'woolentor' ),
267
+ 'condition' => [
268
+ 'custom_labels!' => '',
269
+ 'show_countdown' => 'yes',
270
+ ]
271
+ ]
272
+ );
273
+
274
+ $this->add_control(
275
+ 'customlabel_minutes',
276
+ [
277
+ 'label' => __( 'Minutes', 'woolentor' ),
278
+ 'type' => Controls_Manager::TEXT,
279
+ 'placeholder' => __( 'Minutes', 'woolentor' ),
280
+ 'condition' => [
281
+ 'custom_labels!' => '',
282
+ 'show_countdown' => 'yes',
283
+ ]
284
+ ]
285
+ );
286
+
287
+ $this->add_control(
288
+ 'customlabel_seconds',
289
+ [
290
+ 'label' => __( 'Seconds', 'woolentor' ),
291
+ 'type' => Controls_Manager::TEXT,
292
+ 'placeholder' => __( 'Seconds', 'woolentor' ),
293
+ 'condition' => [
294
+ 'custom_labels!' => '',
295
+ 'show_countdown' => 'yes',
296
+ ]
297
+ ]
298
+ );
299
+ $this->end_controls_section();
300
+
301
+ // Stock Progress Settings
302
+ $this->start_controls_section(
303
+ 'woolentor-products-stockprogress-setting',
304
+ [
305
+ 'label' => esc_html__( 'Stock Progress Bar', 'woolentor' ),
306
+ ]
307
+ );
308
+
309
+ $this->add_control(
310
+ 'show_stock_progress',
311
+ [
312
+ 'label' => __( 'Show Stock Progress Bar', 'woolentor' ),
313
+ 'type' => Controls_Manager::SWITCHER,
314
+ 'label_on' => __( 'Show', 'woolentor' ),
315
+ 'label_off' => __( 'Hide', 'woolentor' ),
316
+ 'return_value' => 'yes',
317
+ 'default' => 'yes',
318
+ ]
319
+ );
320
+
321
+ $this->add_control(
322
+ 'show_stock_progress_notice',
323
+ [
324
+ 'raw' => esc_html__( 'Product must have both "Manage stock" and "Initial number in stock" set from the "Inventory" tab to display the stock progress indicator."' , 'woolentor' ),
325
+ 'type' => Controls_Manager::RAW_HTML,
326
+ 'content_classes' => 'elementor-descriptor elementor-panel-alert elementor-panel-alert-info',
327
+ 'condition' => [
328
+ 'show_stock_progress' => 'yes',
329
+ ]
330
+ ],
331
+ );
332
+
333
+ $this->add_control(
334
+ 'sold_custom_text',
335
+ [
336
+ 'label' => __( 'Sold Custom Text', 'woolentor' ),
337
+ 'type' => Controls_Manager::TEXT,
338
+ 'placeholder' => __( 'Sold:', 'woolentor' ),
339
+ 'label_block' => true,
340
+ 'condition' => [
341
+ 'show_stock_progress' => 'yes',
342
+ ]
343
+ ]
344
+ );
345
+
346
+ $this->add_control(
347
+ 'available_custom_text',
348
+ [
349
+ 'label' => __( 'Available Custom Text', 'woolentor' ),
350
+ 'type' => Controls_Manager::TEXT,
351
+ 'placeholder' => __( 'Available:', 'woolentor' ),
352
+ 'label_block' => true,
353
+ 'condition' => [
354
+ 'show_stock_progress' => 'yes',
355
+ ]
356
+ ]
357
+ );
358
+
359
+ $this->end_controls_section();
360
+
361
+ // Styling
362
+ $this->start_controls_section(
363
+ 'styling_section_tab',
364
+ [
365
+ 'label' => __( 'General Style', 'woolentor' ),
366
+ 'tab' => Controls_Manager::TAB_STYLE,
367
+ ]
368
+ );
369
+ $this->add_responsive_control(
370
+ 'product_inner_margin',
371
+ [
372
+ 'label' => __( 'Margin', 'woolentor' ),
373
+ 'type' => Controls_Manager::DIMENSIONS,
374
+ 'size_units' => [ 'px', '%', 'em' ],
375
+ 'selectors' => [
376
+ '{{WRAPPER}} .woolentor-flash-product' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
377
+ ],
378
+ ]
379
+ );
380
+
381
+ $this->add_responsive_control(
382
+ 'product_inner_padding',
383
+ [
384
+ 'label' => __( 'Padding', 'woolentor' ),
385
+ 'type' => Controls_Manager::DIMENSIONS,
386
+ 'size_units' => [ 'px', '%', 'em' ],
387
+ 'selectors' => [
388
+ '{{WRAPPER}} .woolentor-flash-product' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
389
+ ],
390
+ ]
391
+ );
392
+
393
+ // Product Title
394
+ $this->add_control(
395
+ 'product_title_heading',
396
+ [
397
+ 'label' => __( 'Product Title', 'woolentor' ),
398
+ 'type' => Controls_Manager::HEADING,
399
+ 'separator' => 'before',
400
+ ]
401
+ );
402
+
403
+ $this->add_control(
404
+ 'product_title_color',
405
+ [
406
+ 'label' => __( 'Title Color', 'woolentor' ),
407
+ 'type' => Controls_Manager::COLOR,
408
+ 'default' => '',
409
+ 'selectors' => [
410
+ '{{WRAPPER}} .woolentor-flash-product .woolentor-flash-product-title a' => 'color: {{VALUE}};',
411
+ ],
412
+ 'separator' => 'before',
413
+ ]
414
+ );
415
+
416
+ $this->add_group_control(
417
+ Group_Control_Typography::get_type(),
418
+ [
419
+ 'name' => 'product_title_typography',
420
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product .woolentor-flash-product-title a',
421
+ ]
422
+ );
423
+
424
+ $this->add_control(
425
+ 'product_title_hover_color',
426
+ [
427
+ 'label' => __( 'Title Hover Color', 'woolentor' ),
428
+ 'type' => Controls_Manager::COLOR,
429
+ 'default' => '#0A3ACA',
430
+ 'selectors' => [
431
+ '{{WRAPPER}} .woolentor-flash-product .woolentor-flash-product-title a:hover' => 'color: {{VALUE}};',
432
+ ],
433
+ ]
434
+ );
435
+
436
+ $this->add_responsive_control(
437
+ 'product_title_margin',
438
+ [
439
+ 'label' => __( 'Margin', 'woolentor' ),
440
+ 'type' => Controls_Manager::DIMENSIONS,
441
+ 'size_units' => [ 'px', '%', 'em' ],
442
+ 'selectors' => [
443
+ '{{WRAPPER}} .woolentor-flash-product .woolentor-flash-product-title' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
444
+ ],
445
+ ]
446
+ );
447
+
448
+ // Product Price
449
+ $this->add_control(
450
+ 'product_price_heading',
451
+ [
452
+ 'label' => __( 'Product Price', 'woolentor' ),
453
+ 'type' => Controls_Manager::HEADING,
454
+ 'separator' => 'before',
455
+ ]
456
+ );
457
+
458
+ $this->add_responsive_control(
459
+ 'product_price_margin',
460
+ [
461
+ 'label' => __( 'Margin', 'woolentor' ),
462
+ 'type' => Controls_Manager::DIMENSIONS,
463
+ 'size_units' => [ 'px', '%', 'em' ],
464
+ 'separator' => 'before',
465
+ 'selectors' => [
466
+ '{{WRAPPER}} .woolentor-flash-product-price' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
467
+ ],
468
+ ]
469
+ );
470
+
471
+ $this->add_control(
472
+ 'product_sale_price_color',
473
+ [
474
+ 'label' => __( 'Sale Price Color', 'woolentor' ),
475
+ 'type' => Controls_Manager::COLOR,
476
+ 'default' => '#000',
477
+ 'selectors' => [
478
+ '{{WRAPPER}} .woolentor-flash-product-price,{{WRAPPER}} .woolentor-flash-product-price ins' => 'color: {{VALUE}};',
479
+ ],
480
+ ]
481
+ );
482
+
483
+ $this->add_group_control(
484
+ Group_Control_Typography::get_type(),
485
+ [
486
+ 'name' => 'product_sale_price_typography',
487
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-price,{{WRAPPER}} .woolentor-flash-product-price ins',
488
+ ]
489
+ );
490
+
491
+ $this->add_control(
492
+ 'product_regular_price_color',
493
+ [
494
+ 'label' => __( 'Regular Price Color', 'woolentor' ),
495
+ 'type' => Controls_Manager::COLOR,
496
+ 'default' => '#666666',
497
+ 'selectors' => [
498
+ '{{WRAPPER}} .woolentor-flash-product-price del' => 'color: {{VALUE}};',
499
+ ],
500
+ ]
501
+ );
502
+
503
+ $this->add_group_control(
504
+ Group_Control_Typography::get_type(),
505
+ [
506
+ 'name' => 'product_regular_price_typography',
507
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-price del',
508
+ ]
509
+ );
510
+
511
+ // Rating
512
+ $this->add_control(
513
+ 'product_rating_heading',
514
+ [
515
+ 'label' => __( 'Product Rating', 'woolentor' ),
516
+ 'type' => Controls_Manager::HEADING,
517
+ 'separator' => 'before',
518
+ ]
519
+ );
520
+
521
+ $this->add_control(
522
+ 'product_rating_icon_color',
523
+ [
524
+ 'label' => __( 'Icon Color', 'woolentor' ),
525
+ 'type' => Controls_Manager::COLOR,
526
+ 'separator' => 'before',
527
+ 'default' => '#ecb804',
528
+ 'selectors' => [
529
+ '{{WRAPPER}} .woolentor-flash-product-rating i' => 'color: {{VALUE}};',
530
+ ],
531
+ ]
532
+ );
533
+
534
+ $this->add_control(
535
+ 'product_rating_icon_size',
536
+ [
537
+ 'label' => __( 'Icon Size', 'woolentor' ),
538
+ 'type' => Controls_Manager::SLIDER,
539
+ 'size_units' => [ 'px' ],
540
+ 'range' => [
541
+ 'px' => [
542
+ 'min' => 10,
543
+ 'max' => 100,
544
+ 'step' => 5,
545
+ ],
546
+ ],
547
+ 'default' => [
548
+ 'unit' => 'px',
549
+ 'size' => 16,
550
+ ],
551
+ 'selectors' => [
552
+ '{{WRAPPER}} .woolentor-flash-product-rating i' => 'font-size: {{SIZE}}{{UNIT}};',
553
+ ],
554
+ ]
555
+ );
556
+
557
+ $this->add_control(
558
+ 'product_rating_number_color',
559
+ [
560
+ 'label' => __( 'Number Color', 'woolentor' ),
561
+ 'type' => Controls_Manager::COLOR,
562
+ 'default' => '#000000',
563
+ 'selectors' => [
564
+ '{{WRAPPER}} .woolentor-flash-product-rating span' => 'color: {{VALUE}};',
565
+ ],
566
+ ]
567
+ );
568
+
569
+ $this->add_group_control(
570
+ Group_Control_Typography::get_type(),
571
+ [
572
+ 'name' => 'product_rating_number_typography',
573
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-rating span',
574
+ ]
575
+ );
576
+
577
+ $this->add_control(
578
+ 'product_info_others_heading',
579
+ [
580
+ 'label' => __( 'Others', 'woolentor' ),
581
+ 'type' => Controls_Manager::HEADING,
582
+ 'separator' => 'before',
583
+ ]
584
+ );
585
+
586
+ $this->add_control(
587
+ 'product_info_separator_color',
588
+ [
589
+ 'label' => __( 'Separator Border Color', 'woolentor' ),
590
+ 'type' => Controls_Manager::COLOR,
591
+ 'selectors' => [
592
+ '{{WRAPPER}} .woolentor-flash-product-offer-timer,{{WRAPPER}} .woolentor-flash-product-offer-pos-c-bottom .woolentor-flash-product-offer-timer' => 'border-color: {{VALUE}};',
593
+ ],
594
+ ]
595
+ );
596
+
597
+ $this->add_control(
598
+ 'product_info_out_of_stock_color',
599
+ [
600
+ 'label' => __( '"Out of stock" Text Color', 'woolentor' ),
601
+ 'type' => Controls_Manager::COLOR,
602
+ 'selectors' => [
603
+ '{{WRAPPER}} .woolentor-flash-product-image span' => 'color: {{VALUE}};',
604
+ ],
605
+ 'default' => '#ffffff'
606
+ ]
607
+ );
608
+
609
+ $this->add_control(
610
+ 'product_info_out_of_stock_bg_color',
611
+ [
612
+ 'label' => __( '"Out of stock" BG Color', 'woolentor' ),
613
+ 'type' => Controls_Manager::COLOR,
614
+ 'selectors' => [
615
+ '{{WRAPPER}} .woolentor-flash-product-image span' => 'background-color: {{VALUE}};',
616
+ ],
617
+ 'default' => '#f05b64'
618
+ ]
619
+ );
620
+
621
+
622
+ $this->end_controls_section(); // General
623
+
624
+ // Style Action Button tab section
625
+ $this->start_controls_section(
626
+ 'product_action_button_style_section',
627
+ [
628
+ 'label' => __( 'Action Button Style', 'woolentor' ),
629
+ 'tab' => Controls_Manager::TAB_STYLE,
630
+ ]
631
+ );
632
+
633
+ $this->start_controls_tabs('product_action_button_style_tabs');
634
+
635
+ // Normal
636
+ $this->start_controls_tab(
637
+ 'product_action_button_style_normal_tab',
638
+ [
639
+ 'label' => __( 'Normal', 'woolentor' ),
640
+ ]
641
+ );
642
+
643
+ $this->add_control(
644
+ 'product_action_button_normal_bg_color',
645
+ [
646
+ 'label' => esc_html__( 'Button Background', 'woolentor' ),
647
+ 'type' => Controls_Manager::HEADING,
648
+ ]
649
+ );
650
+
651
+ $this->add_group_control(
652
+ Group_Control_Background::get_type(),
653
+ [
654
+ 'name' => 'product_action_button_normal_background_color',
655
+ 'label' => __( 'Button Background', 'woolentor' ),
656
+ 'types' => [ 'classic', 'gradient' ],
657
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-action a',
658
+ ]
659
+ );
660
+
661
+ $this->add_control(
662
+ 'product_action_button_normal_icon_color',
663
+ [
664
+ 'label' => esc_html__( 'Button Icon Color', 'woolentor' ),
665
+ 'type' => Controls_Manager::HEADING,
666
+ ]
667
+ );
668
+
669
+ $this->add_control(
670
+ 'product_action_button_normal_color',
671
+ [
672
+ 'label' => __( 'Button Icon Color', 'woolentor' ),
673
+ 'type' => Controls_Manager::COLOR,
674
+ 'default' => '#ffffff',
675
+ 'selectors' => [
676
+ '{{WRAPPER}} .woolentor-flash-product-action i' => 'color: {{VALUE}};',
677
+ '{{WRAPPER}} .woolentor-flash-product-action svg' => 'color: {{VALUE}};',
678
+ ],
679
+ ]
680
+ );
681
+
682
+ $this->add_control(
683
+ 'product_action_button_border',
684
+ [
685
+ 'label' => esc_html__( 'Button Border', 'woolentor' ),
686
+ 'type' => Controls_Manager::HEADING,
687
+ ]
688
+ );
689
+
690
+ $this->add_responsive_control(
691
+ 'product_action_button_border_radius',
692
+ [
693
+ 'label' => __( 'Border Radius', 'woolentor' ),
694
+ 'type' => Controls_Manager::DIMENSIONS,
695
+ 'size_units' => [ 'px', '%', 'em' ],
696
+ 'selectors' => [
697
+ '{{WRAPPER}} .woolentor-flash-product-action a' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
698
+ ],
699
+ ]
700
+ );
701
+
702
+ $this->end_controls_tab();
703
+
704
+
705
+ // Hover
706
+ $this->start_controls_tab(
707
+ 'product_action_button_style_hover_tab',
708
+ [
709
+ 'label' => __( 'Hover', 'woolentor' ),
710
+ ]
711
+ );
712
+
713
+ $this->add_control(
714
+ 'product_action_button_hover_color',
715
+ [
716
+ 'label' => __( 'Button Hover Icon Color', 'woolentor' ),
717
+ 'type' => Controls_Manager::COLOR,
718
+ 'default' => '#ffffff' ,
719
+ 'selectors' => [
720
+ '{{WRAPPER}} .woolentor-flash-product-action a:hover i' => 'color: {{VALUE}};',
721
+ '{{WRAPPER}} .woolentor-flash-product-action a:hover svg' => 'color: {{VALUE}};',
722
+ ],
723
+ ]
724
+ );
725
+
726
+ $this->add_group_control(
727
+ Group_Control_Background::get_type(),
728
+ [
729
+ 'name' => 'product_action_button_hover_background_color',
730
+ 'label' => __( 'Button Hover Background Color', 'woolentor' ),
731
+ 'types' => [ 'classic', 'gradient' ],
732
+ 'default' => '#DC9A0E',
733
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-action a:hover',
734
+ ]
735
+ );
736
+
737
+ $this->end_controls_tab(); // Hover tab
738
+
739
+ $this->end_controls_tabs(); // Normal and Hover tabs
740
+
741
+ $this->end_controls_section(); // Action buttons
742
+
743
+ // Style Countdown tab section
744
+ $this->start_controls_section(
745
+ 'product_counter_style_section',
746
+ [
747
+ 'label' => __( 'Counter Style', 'woolentor' ),
748
+ 'tab' => Controls_Manager::TAB_STYLE,
749
+ 'condition' => [
750
+ 'show_countdown' => 'yes',
751
+ ]
752
+ ]
753
+ );
754
+ // Countdown title
755
+ $this->add_control(
756
+ 'product_counter_heading',
757
+ [
758
+ 'label' => __( 'Title', 'woolentor' ),
759
+ 'type' => Controls_Manager::HEADING,
760
+ 'separator' => 'before',
761
+ ]
762
+ );
763
+
764
+ $this->add_group_control(
765
+ Group_Control_Typography::get_type(),
766
+ [
767
+ 'name' => 'product_counter_title_typography',
768
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-offer-timer-text',
769
+ ]
770
+ );
771
+
772
+ $this->add_control(
773
+ 'product_ccounter_title_color',
774
+ [
775
+ 'label' => __( 'Color', 'woolentor' ),
776
+ 'type' => Controls_Manager::COLOR,
777
+ 'default' => '',
778
+ 'selectors' => [
779
+ '{{WRAPPER}} .woolentor-flash-product-offer-timer-text' => 'color: {{VALUE}};',
780
+ ],
781
+ ]
782
+ );
783
+
784
+ $this->add_responsive_control(
785
+ 'product_ccounter_title_margin',
786
+ [
787
+ 'label' => __( 'Margin', 'woolentor' ),
788
+ 'type' => Controls_Manager::DIMENSIONS,
789
+ 'size_units' => [ 'px', '%', 'em' ],
790
+ 'selectors' => [
791
+ '{{WRAPPER}} .woolentor-flash-product-offer-timer-text' => 'margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
792
+ ],
793
+ ]
794
+ );
795
+
796
+ // Counter items
797
+ $this->add_control(
798
+ 'product_counter_items_heading',
799
+ [
800
+ 'label' => __( 'Counter Item', 'woolentor' ),
801
+ 'type' => Controls_Manager::HEADING,
802
+ 'separator' => 'before',
803
+ ]
804
+ );
805
+
806
+ $this->add_control(
807
+ 'product_counter_number_color',
808
+ [
809
+ 'label' => __( 'Number Color', 'woolentor' ),
810
+ 'type' => Controls_Manager::COLOR,
811
+ 'default' => '',
812
+ 'selectors' => [
813
+ '{{WRAPPER}} .woolentor-flash-product-offer-timer .woolentor-count' => 'color: {{VALUE}};',
814
+ ],
815
+ 'separator' => 'before',
816
+ ]
817
+ );
818
+
819
+ $this->add_group_control(
820
+ Group_Control_Typography::get_type(),
821
+ [
822
+ 'name' => 'product_counter_number_typography',
823
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-offer-timer .woolentor-count',
824
+ ]
825
+ );
826
+
827
+ $this->add_group_control(
828
+ Group_Control_Background::get_type(),
829
+ [
830
+ 'name' => 'product_counter_background_color',
831
+ 'label' => __( 'Counter Background', 'woolentor' ),
832
+ 'types' => [ 'classic', 'gradient' ],
833
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-offer-timer .woolentor-count',
834
+ ]
835
+ );
836
+
837
+ // Counter Label
838
+ $this->add_control(
839
+ 'product_counter_label_heading',
840
+ [
841
+ 'label' => __( 'Counter Label', 'woolentor' ),
842
+ 'type' => Controls_Manager::HEADING,
843
+ 'separator' => 'before',
844
+ ]
845
+ );
846
+
847
+ $this->add_control(
848
+ 'product_counter_label_color',
849
+ [
850
+ 'label' => __( 'Label Color', 'woolentor' ),
851
+ 'type' => Controls_Manager::COLOR,
852
+ 'default' => '',
853
+ 'selectors' => [
854
+ '{{WRAPPER}} .woolentor-flash-product-offer-timer .woolentor-label' => 'color: {{VALUE}};',
855
+ ],
856
+ 'separator' => 'before',
857
+ ]
858
+ );
859
+
860
+ $this->add_group_control(
861
+ Group_Control_Typography::get_type(),
862
+ [
863
+ 'name' => 'product_counter_label_typography',
864
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-offer-timer .woolentor-label',
865
+ ]
866
+ );
867
+
868
+ $this->end_controls_section(); // Counter
869
+
870
+ $this->start_controls_section(
871
+ 'product_stock_progress_style_section',
872
+ [
873
+ 'label' => __( 'Stock Progress Style', 'woolentor' ),
874
+ 'tab' => Controls_Manager::TAB_STYLE,
875
+ 'condition' => [
876
+ 'show_stock_progress' => 'yes',
877
+ ]
878
+ ]
879
+ );
880
+
881
+ $this->add_control(
882
+ 'product_stock_progress_bar_color',
883
+ [
884
+ 'label' => __( 'Color', 'woolentor' ),
885
+ 'separator' => 'before',
886
+ 'type' => Controls_Manager::COLOR,
887
+ 'selectors' => [
888
+ '{{WRAPPER}} .woolentor-flash-product-progress-sold' => 'background-color: {{VALUE}};',
889
+ ],
890
+ ]
891
+ );
892
+
893
+ $this->add_group_control(
894
+ Group_Control_Background::get_type(),
895
+ [
896
+ 'name' => 'product_stock_progress_bar_bg_color',
897
+ 'label' => __( 'Background', 'woolentor' ),
898
+ 'types' => [ 'classic', 'gradient' ],
899
+ 'selector' => '{{WRAPPER}} .woolentor-flash-product-progress-total',
900
+ ]
901
+ );
902
+
903
+ $this->add_control(
904
+ 'product_stock_progress_bar_sold_label_color',
905
+ [
906
+ 'label' => __( 'Sold Label Color', 'woolentor' ),
907
+ 'type' => Controls_Manager::COLOR,
908
+ 'selectors' => [
909
+ '{{WRAPPER}} .woolentor-flash-product-progress-label span:first-child' => 'color: {{VALUE}};',
910
+ ],
911
+ ]
912
+ );
913
+
914
+ $this->add_control(
915
+ 'product_stock_progress_bar_Available_label_color',
916
+ [
917
+ 'label' => __( 'Available Number Color', 'woolentor' ),
918
+ 'type' => Controls_Manager::COLOR,
919
+ 'selectors' => [
920
+ '{{WRAPPER}} .woolentor-flash-product-progress-label span:last-child' => 'color: {{VALUE}};',
921
+ ],
922
+ ]
923
+ );
924
+
925
+ $this->add_control(
926
+ 'product_stock_progress_bar_height',
927
+ [
928
+ 'label' => __( 'Height', 'woolentor' ),
929
+ 'type' => Controls_Manager::SLIDER,
930
+ 'size_units' => [ 'px', 'em' ],
931
+ 'range' => [
932
+ 'px' => [
933
+ 'min' => 5,
934
+ 'max' => 100,
935
+ 'step' => 5,
936
+ ],
937
+ 'em' => [
938
+ 'min' => 1,
939
+ 'max' => 5,
940
+ 'step' => 1,
941
+ ],
942
+ ],
943
+ 'default' => [
944
+ 'unit' => 'px',
945
+ 'size' => 10,
946
+ ],
947
+ 'selectors' => [
948
+ '{{WRAPPER}} .woolentor-flash-product-progress-total' => 'height: {{SIZE}}{{UNIT}};',
949
+ ],
950
+ ]
951
+ );
952
+
953
+ $this->add_control(
954
+ 'product_stock_progress_bar_border_radius',
955
+ [
956
+ 'label' => __( 'Border Radius', 'woolentor' ),
957
+ 'type' => Controls_Manager::SLIDER,
958
+ 'size_units' => [ 'px', 'em' ],
959
+ 'range' => [
960
+ 'px' => [
961
+ 'min' => 0,
962
+ 'max' => 100,
963
+ 'step' => 5,
964
+ ],
965
+ 'em' => [
966
+ 'min' => 0,
967
+ 'max' => 5,
968
+ 'step' => 1,
969
+ ],
970
+ ],
971
+ 'default' => [
972
+ 'unit' => 'px',
973
+ 'size' => 10,
974
+ ],
975
+ 'selectors' => [
976
+ '{{WRAPPER}} .woolentor-flash-product-progress-total,{{WRAPPER}} .woolentor-flash-product-progress-sold' => 'border-radius: {{SIZE}}{{UNIT}};',
977
+ ],
978
+ ]
979
+ );
980
+
981
+ $this->end_controls_section(); // Stock progress
982
+ }
983
+
984
+ protected function render( $instance = [] ) {
985
+
986
+ $settings = $this->get_settings_for_display();
987
+
988
+ // Calculate Column
989
+ $columns = $settings['woolentor_product_grid_column'];
990
+ $collumval = 'ht-product ht-col-lg-4 ht-col-md-6 ht-col-sm-6 ht-col-xs-12 mb-30 product';
991
+ if( $columns !='' ){
992
+ if( $columns == 5 ){
993
+ $collumval = 'ht-product cus-col-5 ht-col-md-6 ht-col-sm-6 ht-col-xs-12 mb-30 product';
994
+ }else{
995
+ $colwidth = round( 12 / $columns );
996
+ $collumval = 'ht-product ht-col-lg-'.$colwidth.' ht-col-md-6 ht-col-sm-6 ht-col-xs-12 mb-30 product';
997
+ }
998
+ }
999
+
1000
+ // Countdown
1001
+ $show_countdown = $settings['show_countdown'];
1002
+ $countdown_style = $settings['countdown_style'];
1003
+ $countdown_style = $countdown_style == '2' ? 'flip' : 'default';
1004
+ $countdown_position = $settings['countdown_position'] ? $settings['countdown_position'] : 'content_top';
1005
+ $countdown_position_class = array(
1006
+ 'left' => 'woolentor-flash-product-offer-pos-t-left',
1007
+ 'right' => 'woolentor-flash-product-offer-pos-t-right',
1008
+ 'bottom' => 'woolentor-flash-product-offer-pos-t-bottom',
1009
+ 'content_top' => '',
1010
+ 'content_bottom' => 'woolentor-flash-product-offer-pos-c-bottom',
1011
+ );
1012
+ $countdown_title = $settings['countdown_title'];
1013
+ $data_customlavel = [];
1014
+ if( $show_countdown == 'yes' ){
1015
+ $data_customlavel['daytxt'] = ! empty( $settings['customlabel_days'] ) ? $settings['customlabel_days'] : __('Days', 'woolentor');
1016
+ $data_customlavel['hourtxt'] = ! empty( $settings['customlabel_hours'] ) ? $settings['customlabel_hours'] : __('Hours', 'woolentor');
1017
+ $data_customlavel['minutestxt'] = ! empty( $settings['customlabel_minutes'] ) ? $settings['customlabel_minutes'] : __('Min', 'woolentor');
1018
+ $data_customlavel['secondstxt'] = ! empty( $settings['customlabel_seconds'] ) ? $settings['customlabel_seconds'] : __('Sec', 'woolentor');
1019
+ }
1020
+
1021
+ // Stock Progress bar
1022
+ $show_stock_progress = $settings['show_stock_progress'];
1023
+ $sold_custom_text = $settings['sold_custom_text'] ? $settings['sold_custom_text'] : __('Sold:', 'woolentor');
1024
+ $available_custom_text = $settings['available_custom_text'] ? $settings['available_custom_text'] : __('Available:', 'woolentor');
1025
+
1026
+ // Get deal
1027
+ $selected_deal = $settings['deal'];
1028
+ $deals = woolentor_get_option('deals', 'woolentor_flash_sale_settings');
1029
+ $deal = !empty($deals[$selected_deal]) ? $deals[$selected_deal] : array();
1030
+
1031
+ // Query Argument
1032
+ $per_page = $settings['woolentor_product_grid_products_count'];
1033
+ $custom_order_ck = $settings['woolentor_custom_order'];
1034
+ $orderby = $settings['orderby'];
1035
+ $order = $settings['order'];
1036
+
1037
+ $query_args = array(
1038
+ 'post_type' => 'product',
1039
+ 'post_status' => 'publish',
1040
+ 'ignore_sticky_posts' => 1,
1041
+ 'posts_per_page' => $per_page,
1042
+ );
1043
+
1044
+ // Custom Order
1045
+ if( $custom_order_ck == 'yes' ){
1046
+ $query_args['orderby'] = $orderby;
1047
+ $query_args['order'] = $order;
1048
+ }
1049
+
1050
+ $apply_on_all_products = !empty($deal['apply_on_all_products']) ? $deal['apply_on_all_products'] : 'off';
1051
+ $include_categories = !empty($deal['categories']) ? $deal['categories'] : array();
1052
+ $include_products = !empty($deal['products']) ? $deal['products'] : array();
1053
+ $exclude_products = !empty($deal['exclude_products']) ? $deal['exclude_products'] : array();
1054
+ $product_ids = array();
1055
+
1056
+ // Prepare product ids
1057
+ if( $apply_on_all_products != 'on' ){
1058
+
1059
+ if( $include_categories ){
1060
+ $query_1 = new \WP_Query( array(
1061
+ 'post_type' => 'product',
1062
+ 'post_status' => 'publish',
1063
+ 'fields' => 'ids',
1064
+ 'tax_query' => array(
1065
+ array(
1066
+ 'taxonomy' => 'product_cat',
1067
+ 'field' => 'term_id',
1068
+ 'terms' => $include_categories,
1069
+ ),
1070
+ // grouped and variable product is not supported right now
1071
+ 'relation' => 'AND',
1072
+ array(
1073
+ 'taxonomy' => 'product_type',
1074
+ 'field' => 'slug',
1075
+ 'terms' => array('simple', 'external'),
1076
+ ),
1077
+ ),
1078
+
1079
+ ));
1080
+
1081
+ $product_ids = $query_1->posts;
1082
+ }
1083
+
1084
+ if( $include_products ){
1085
+ $product_ids = array_merge($product_ids, $include_products);
1086
+ }
1087
+
1088
+ if( $exclude_products ){
1089
+ $product_ids = array_intersect($product_ids, $exclude_products);
1090
+ }
1091
+
1092
+ } elseif( $exclude_products ){
1093
+ $query_args['post__not_in'] = $exclude_products;
1094
+ }
1095
+
1096
+ $found_products = false;
1097
+ $deal_status = !empty($deal['status']) ? $deal['status'] : 'off';
1098
+ if( $deal_status == 'on' && \Woolentor_Flash_Sale::user_validity($deal) && \Woolentor_Flash_Sale::datetime_validity($deal) ){
1099
+ if( $apply_on_all_products == 'on' ){
1100
+ $found_products = true;
1101
+ } elseif( $product_ids ){
1102
+ $found_products = true;
1103
+ $query_args['post__in'] = $product_ids;
1104
+ }
1105
+ }
1106
+
1107
+ if( $found_products ):
1108
+ ?>
1109
+ <div class="ht-products woocommerce ht-row">
1110
+
1111
+ <?php
1112
+ $products = new \WP_Query( $query_args );
1113
+ if( $products->have_posts() ):
1114
+
1115
+ // Countdown remaining time
1116
+ $remaining_time = \Woolentor_Flash_Sale::get_remaining_time($deal);
1117
+
1118
+ while( $products->have_posts() ): $products->the_post();
1119
+ global $product;
1120
+ $product_id = $product->get_id();
1121
+ $ajax_add_to_cart_class = $product->is_purchasable() && $product->is_in_stock() ? ' add_to_cart_button' : '';
1122
+ $ajax_add_to_cart_class .= $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock() ? ' ajax_add_to_cart' : '';
1123
+ ?>
1124
+
1125
+ <!--Product Start-->
1126
+ <div class="<?php echo esc_attr($collumval); ?>">
1127
+ <div class="woolentor-flash-product <?php echo esc_attr($countdown_position_class[$countdown_position]) ?>">
1128
+
1129
+ <div class="woolentor-flash-product-thumb">
1130
+ <a href="<?php the_permalink(); ?>">
1131
+ <div class="woolentor-flash-product-image">
1132
+ <?php
1133
+ woolentor_sale_flash();
1134
+ woocommerce_template_loop_product_thumbnail();
1135
+ ?>
1136
+ </div>
1137
+ </a>
1138
+
1139
+ <?php if($show_countdown == 'yes'): ?>
1140
+ <div class="woolentor-countdown woolentor-countdown-<?php echo esc_attr($countdown_style); ?>" data-countdown="<?php echo esc_attr( $remaining_time ) ?>" data-customlavel='<?php echo wp_json_encode( $data_customlavel ) ?>'></div>
1141
+ <?php endif; ?>
1142
+
1143
+
1144
+ <ul class="woolentor-flash-product-action">
1145
+ <li><a href="<?php echo $product->add_to_cart_url() ?>" data-quantity="1" class="woolentor-flash-product-action-btn <?php echo esc_attr($ajax_add_to_cart_class); ?>" data-product_id="<?php echo esc_attr($product_id); ?>"><i class="fa fa-shopping-cart"></i></a></li>
1146
+
1147
+ <?php
1148
+ if( true === woolentor_has_wishlist_plugin() ){
1149
+ echo '<li>'.woolentor_add_to_wishlist_button('<i class="fa fa-heart"></i>','<i class="fa fa-heart"></i>').'</li>';
1150
+ }
1151
+ ?>
1152
+
1153
+ <?php
1154
+ if( function_exists('woolentor_compare_button') && true === woolentor_exist_compare_plugin() ){
1155
+ echo '<li>';
1156
+ woolentor_compare_button(
1157
+ array(
1158
+ 'style'=>2,
1159
+ 'btn_text'=>'<i class="fas fa-exchange-alt"></i>',
1160
+ 'btn_added_txt'=>'<i class="fas fa-exchange-alt"></i>'
1161
+ )
1162
+ );
1163
+ echo '</li>';
1164
+ }
1165
+ ?>
1166
+
1167
+ <li>
1168
+ <a href="javascript:void(0);" class="woolentor-flash-product-action-btn woolentorquickview" data-quick-id="<?php echo esc_attr($product_id);?>" >
1169
+ <i class="fa fa-eye"></i>
1170
+ </a>
1171
+ </li>
1172
+ </ul>
1173
+ </div>
1174
+
1175
+ <div class="woolentor-flash-product-content">
1176
+
1177
+ <?php if($show_countdown == 'yes'): ?>
1178
+ <div class="woolentor-flash-product-offer-timer">
1179
+
1180
+ <?php if($countdown_title): ?>
1181
+ <p class="woolentor-flash-product-offer-timer-text"><?php echo wp_kses_post($countdown_title) ?></p>
1182
+ <?php endif; ?>
1183
+
1184
+
1185
+ <div class="woolentor-countdown woolentor-countdown-<?php echo esc_attr($countdown_style); ?>" data-countdown="<?php echo esc_attr( $remaining_time ) ?>" data-customlavel='<?php echo wp_json_encode( $data_customlavel ) ?>'></div>
1186
+ </div>
1187
+ <?php endif; ?>
1188
+
1189
+ <?php
1190
+ $manage_stock = get_post_meta( $product_id, '_manage_stock', true );
1191
+ $initial_stock = get_post_meta( $product_id, 'woolentor_total_stock_quantity', true );
1192
+
1193
+ if($show_stock_progress == 'yes' && $manage_stock == 'yes' && $initial_stock):
1194
+ $current_stock = get_post_meta( $product_id, '_stock', true );
1195
+ $total_sold = $initial_stock > $current_stock ? $initial_stock - $current_stock : 0;
1196
+ $percentage = $total_sold > 0 ? round( $total_sold / $initial_stock * 100 ) : 0;
1197
+
1198
+ if($current_stock >= 0):
1199
+ ?>
1200
+ <div class="woolentor-flash-product-progress">
1201
+ <div class="woolentor-flash-product-progress-total">
1202
+ <div class="woolentor-flash-product-progress-sold" style="width: <?php echo esc_attr($percentage) ?>%;"></div>
1203
+ </div>
1204
+ <div class="woolentor-flash-product-progress-label"><span><?php echo esc_html($sold_custom_text) ?> <?php echo esc_html($total_sold) ?></span><span><?php echo esc_html($available_custom_text) ?> <?php echo esc_html($current_stock); ?></span></div>
1205
+ </div>
1206
+ <?php endif; ?>
1207
+
1208
+ <?php elseif($show_stock_progress && $manage_stock == 'yes' && !$initial_stock): ?>
1209
+ <div class="woolentor-flash-product-progress woolentor-stock-message">
1210
+ <span><?php echo esc_html__( 'To show the stock progress bar. Set the initial stock amount from', 'woolentor' ) ?></span> <a href="<?php echo esc_url(get_edit_post_link( $product_id )) ?>" target="_blank"><b> <?php echo esc_html__( 'Here', 'woolentor' ); ?></b></a>
1211
+ </div>
1212
+ <?php endif; ?>
1213
+
1214
+ <h3 class="woolentor-flash-product-title"><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>
1215
+
1216
+ <?php
1217
+ $has_rating_class = $product->get_average_rating() ? '' : 'woolentor-product-has-no-rating';
1218
+ ?>
1219
+ <div class="woolentor-flash-product-price-rating <?php echo esc_attr($has_rating_class) ?>">
1220
+ <div class="woolentor-flash-product-price">
1221
+ <?php
1222
+ if( $product->get_type() != 'variable' ){
1223
+
1224
+ echo '<div class="price">' .wc_format_sale_price( wc_get_price_to_display( $product ), \Woolentor_Flash_Sale::get_calculated_price($product_id, $deal) ) . $product->get_price_suffix() . '</div>';
1225
+
1226
+ } elseif($product->get_type() == 'variable') {
1227
+ $price_min_o = wc_get_price_to_display( $product, [ 'price' => $product->get_variation_regular_price( 'min' ) ] );
1228
+ $price_min = \Woolentor_Flash_Sale::get_calculated_price($product_id, $deal, $price_min_o);
1229
+ $price_max_o = wc_get_price_to_display( $product, [ 'price' => $product->get_variation_regular_price( 'max' ) ] );
1230
+ $price_max = \Woolentor_Flash_Sale::get_calculated_price($product_id, $deal, $price_max_o);
1231
+ $price_html = wc_format_price_range( $price_min, $price_max );
1232
+
1233
+ if($price_min == $price_max){
1234
+ echo '<div class="price">' .wc_format_sale_price( $price_max_o, $price_max) . $product->get_price_suffix() . '</div>';
1235
+ } else{
1236
+ echo '<div class="price">' .wp_kses_post($price_html) . '</div>';
1237
+ }
1238
+ }
1239
+ ?>
1240
+ </div>
1241
+
1242
+ <?php if($product->get_average_rating()): ?>
1243
+ <div class="woolentor-flash-product-rating"><i class="eicon-star"></i> <span><?php echo esc_html($product->get_average_rating()); ?></span></div>
1244
+ <?php endif; ?>
1245
+ </div>
1246
+
1247
+ </div>
1248
+
1249
+ </div>
1250
+ </div> <!-- /.product -->
1251
+ <?php endwhile; wp_reset_query(); wp_reset_postdata(); endif; ?>
1252
+
1253
+ </div> <!-- /.ht-products -->
1254
+ <?php
1255
+ else:
1256
+ echo '<strong>' . __( 'Unfortunately, no products were found in the deal you selected.', 'woolentor' ) . '</strong>';
1257
+ endif; // $product_ids
1258
+ }
1259
+
1260
+ }
1261
+
1262
+ Plugin::instance()->widgets_manager->register_widget_type( new Woolentor_Product_Flash_Sale_Widget() );
includes/admin/admin-init.php CHANGED
@@ -290,14 +290,29 @@ class Woolentor_Admin_Init{
290
  $subaction = ( !empty( $_POST['subaction'] ) ? sanitize_text_field( $_POST['subaction'] ) : '' );
291
  $section = ( !empty( $_POST['section'] ) ? sanitize_text_field( $_POST['section'] ) : '' );
292
  $fileds = ( !empty( $_POST['fileds'] ) ? woolentor_clean( $_POST['fileds'] ) : '' );
 
293
 
294
  if( empty( $section ) || empty( $fileds ) ){
295
  return;
296
  }
297
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
298
  $response_content = $message = $element_keys = $field_html = '';
299
  if( $subaction === 'get_data' ){
300
- foreach( $fileds as $key => $field ){
301
  ob_start();
302
  Woolentor_Admin_Fields_Manager::instance()->add_field( $field, $section );
303
  $field_html .= ob_get_clean();
@@ -305,16 +320,12 @@ class Woolentor_Admin_Init{
305
  $message = esc_html__( 'Data Fetch successfully!', 'woolentor' );
306
  $response_content = $field_html;
307
 
308
- $element_keys = array_map( function( $field ){
309
- return $field['name'];
310
- }, $fileds );
311
-
312
  }
313
 
314
  wp_send_json_success([
315
  'message' => $message,
316
  'content' => $response_content,
317
- 'fields' => wp_json_encode( $element_keys )
318
  ]);
319
 
320
  }
290
  $subaction = ( !empty( $_POST['subaction'] ) ? sanitize_text_field( $_POST['subaction'] ) : '' );
291
  $section = ( !empty( $_POST['section'] ) ? sanitize_text_field( $_POST['section'] ) : '' );
292
  $fileds = ( !empty( $_POST['fileds'] ) ? woolentor_clean( $_POST['fileds'] ) : '' );
293
+ $fieldname = ( !empty( $_POST['fieldname'] ) ? sanitize_text_field( $_POST['fieldname'] ) : '' );
294
 
295
  if( empty( $section ) || empty( $fileds ) ){
296
  return;
297
  }
298
 
299
+ $module_fields = Woolentor_Admin_Fields::instance()->fields()['woolentor_others_tabs']['modules'];
300
+ $section_fields = [];
301
+ foreach ( $module_fields as $module ) {
302
+ if( isset( $module['section'] ) && $module['section'] === $section ){
303
+ $section_fields = $module['setting_fields'];
304
+ break;
305
+ }else{
306
+ if( isset( $module['name'] ) && $module['name'] === $fieldname ){
307
+ $section_fields = $module['setting_fields'];
308
+ break;
309
+ }
310
+ }
311
+ }
312
+
313
  $response_content = $message = $element_keys = $field_html = '';
314
  if( $subaction === 'get_data' ){
315
+ foreach( $section_fields as $key => $field ){
316
  ob_start();
317
  Woolentor_Admin_Fields_Manager::instance()->add_field( $field, $section );
318
  $field_html .= ob_get_clean();
320
  $message = esc_html__( 'Data Fetch successfully!', 'woolentor' );
321
  $response_content = $field_html;
322
 
 
 
 
 
323
  }
324
 
325
  wp_send_json_success([
326
  'message' => $message,
327
  'content' => $response_content,
328
+ 'fields' => wp_json_encode( $fileds )
329
  ]);
330
 
331
  }
includes/admin/assets/css/woolentor-admin.css CHANGED
@@ -1852,6 +1852,10 @@
1852
  .woolentor-module-setting-popup-content .woolentor-admin-option{
1853
  padding: 20px 5px 20px 0;
1854
  }
 
 
 
 
1855
  .woolentor-module-setting-popup-content .woolentor-admin-option:not(.woolentor-action-field-left){
1856
  display: block;
1857
  }
1852
  .woolentor-module-setting-popup-content .woolentor-admin-option{
1853
  padding: 20px 5px 20px 0;
1854
  }
1855
+ .woolentor-repeater-item-add + .woolentor-admin-option {
1856
+ border-top: 1px solid #EAEAEA;
1857
+ margin-top: 20px;
1858
+ }
1859
  .woolentor-module-setting-popup-content .woolentor-admin-option:not(.woolentor-action-field-left){
1860
  display: block;
1861
  }
includes/admin/assets/js/woolentor-admin.js CHANGED
@@ -190,6 +190,7 @@
190
  var $this = $(this),
191
  $section = $this.data('section'),
192
  $fields = $this.data('fields'),
 
193
  content = null,
194
  modulewrapper = wp.template( 'woolentormodule' );
195
 
@@ -200,6 +201,7 @@
200
  nonce : WOOLENTOR_ADMIN.nonce,
201
  section : $section,
202
  fileds : $fields,
 
203
  action : 'woolentor_module_data',
204
  subaction : 'get_data',
205
  },
@@ -421,7 +423,7 @@
421
  $itemCount = $('.woolentor-option-repeater-item:not(.woolentor-repeater-hidden)').length;
422
 
423
  $hidden.attr('data-id', $itemCount );
424
- $('.woolentor-option-repeater-item-area .woolentor-option-repeater-item').siblings().removeClass('woolentor_active_repeater');
425
  $hidden.removeClass('woolentor-repeater-hidden').addClass('woolentor_active_repeater');
426
  $hidden.insertAfter( '.woolentor-option-repeater-item-area div.woolentor-option-repeater-item:last' );
427
 
190
  var $this = $(this),
191
  $section = $this.data('section'),
192
  $fields = $this.data('fields'),
193
+ $fieldname = $this.data('fieldname') ? $this.data('fieldname') : '',
194
  content = null,
195
  modulewrapper = wp.template( 'woolentormodule' );
196
 
201
  nonce : WOOLENTOR_ADMIN.nonce,
202
  section : $section,
203
  fileds : $fields,
204
+ fieldname : $fieldname,
205
  action : 'woolentor_module_data',
206
  subaction : 'get_data',
207
  },
423
  $itemCount = $('.woolentor-option-repeater-item:not(.woolentor-repeater-hidden)').length;
424
 
425
  $hidden.attr('data-id', $itemCount );
426
+ $('.woolentor-option-repeater-item-area .woolentor-option-repeater-item').removeClass('woolentor_active_repeater');
427
  $hidden.removeClass('woolentor-repeater-hidden').addClass('woolentor_active_repeater');
428
  $hidden.insertAfter( '.woolentor-option-repeater-item-area div.woolentor-option-repeater-item:last' );
429
 
includes/admin/include/admin_field-manager.php CHANGED
@@ -225,7 +225,8 @@ class Woolentor_Admin_Fields_Manager {
225
 
226
  $setting_fields = '';
227
  if( !empty( $args['additional_info']['setting_fields'] ) ){
228
- $setting_fields = wp_json_encode( $args['additional_info']['setting_fields'] );
 
229
  }
230
 
231
  $html = '<div class="woolentor-admin-switch-block woolentor-module-field '.esc_attr( $args['class'] ).'">';
@@ -338,7 +339,8 @@ class Woolentor_Admin_Fields_Manager {
338
 
339
  $setting_fields = '';
340
  if( !empty( $args['additional_info']['setting_fields'] ) ){
341
- $setting_fields = wp_json_encode( $args['additional_info']['setting_fields'] );
 
342
  }
343
  $visibility = 'woolentor-visibility-none';
344
  if( ( $args['additional_info']['require_settings'] === true ) && ( $value === 'on' ) ){
@@ -355,7 +357,7 @@ class Woolentor_Admin_Fields_Manager {
355
  $html .= '</div>';
356
  $html .= '</div>';
357
  $html .= '<div class="woolentor-admin-switch-block-actions" '.$data_atr.'>';
358
- $html .= !empty( $args['additional_info']['require_settings'] ) ? '<a href="#" class="woolentor-admin-switch-block-setting '.$visibility.'" data-section="'.$args['section'].'" data-fields=\'' .$setting_fields. '\'><i class="wli wli-cog-light"></i></a>' : '';
359
  $html .= '<div class="woolentor-admin-switch" '.$switch_id.'>';
360
  $html .= sprintf( '<input type="checkbox" class="checkbox" id="woolentor_field_%1$s[%2$s]" name="%2$s" value="on" %3$s/>', $args['section'], $args['id'], $checked );
361
  $html .= sprintf( '<label for="woolentor_field_%1$s[%2$s]"><span class="woolentor-admin-switch-label on">%3$s</span><span class="woolentor-admin-switch-label off">%4$s</span><span class="woolentor-admin-switch-indicator"></span></label>', $args['section'], $args['id'], 'on', 'off' );
@@ -577,7 +579,7 @@ class Woolentor_Admin_Fields_Manager {
577
  $html .= '</div>';
578
  $html .= '<div class="woolentor-admin-option-action" '.$data_atr.'>';
579
  $html .= '<div class="woolentor-admin-select">';
580
- $html .= sprintf( '<select multiple="multiple" class="%1$s" name="%2$s[]" id="%1$s[%2$s]" %3$s>', $args['section'], $args['id'], $disabled );
581
  foreach ( $args['options'] as $key => $label ) {
582
  $selected = '';
583
  if( !empty( $value ) ){
225
 
226
  $setting_fields = '';
227
  if( !empty( $args['additional_info']['setting_fields'] ) ){
228
+ // $setting_fields = wp_json_encode( $args['additional_info']['setting_fields'] );
229
+ $setting_fields = wp_json_encode( array_column( $args['additional_info']['setting_fields'], 'name' ) );
230
  }
231
 
232
  $html = '<div class="woolentor-admin-switch-block woolentor-module-field '.esc_attr( $args['class'] ).'">';
339
 
340
  $setting_fields = '';
341
  if( !empty( $args['additional_info']['setting_fields'] ) ){
342
+ // $setting_fields = wp_json_encode( $args['additional_info']['setting_fields'] );
343
+ $setting_fields = wp_json_encode( array_column( $args['additional_info']['setting_fields'], 'name' ) );
344
  }
345
  $visibility = 'woolentor-visibility-none';
346
  if( ( $args['additional_info']['require_settings'] === true ) && ( $value === 'on' ) ){
357
  $html .= '</div>';
358
  $html .= '</div>';
359
  $html .= '<div class="woolentor-admin-switch-block-actions" '.$data_atr.'>';
360
+ $html .= !empty( $args['additional_info']['require_settings'] ) ? '<a href="#" class="woolentor-admin-switch-block-setting '.$visibility.'" data-section="'.$args['section'].'" data-fieldname="'.$args['id'].'" data-fields=\'' .$setting_fields. '\'><i class="wli wli-cog-light"></i></a>' : '';
361
  $html .= '<div class="woolentor-admin-switch" '.$switch_id.'>';
362
  $html .= sprintf( '<input type="checkbox" class="checkbox" id="woolentor_field_%1$s[%2$s]" name="%2$s" value="on" %3$s/>', $args['section'], $args['id'], $checked );
363
  $html .= sprintf( '<label for="woolentor_field_%1$s[%2$s]"><span class="woolentor-admin-switch-label on">%3$s</span><span class="woolentor-admin-switch-label off">%4$s</span><span class="woolentor-admin-switch-indicator"></span></label>', $args['section'], $args['id'], 'on', 'off' );
579
  $html .= '</div>';
580
  $html .= '<div class="woolentor-admin-option-action" '.$data_atr.'>';
581
  $html .= '<div class="woolentor-admin-select">';
582
+ $html .= sprintf( '<select multiple="multiple" class="%1$s" name="%2$s[]" %3$s>', $args['section'], $args['id'], $disabled );
583
  foreach ( $args['options'] as $key => $label ) {
584
  $selected = '';
585
  if( !empty( $value ) ){
includes/admin/include/admin_fields.php CHANGED
@@ -1373,49 +1373,9 @@ class Woolentor_Admin_Fields {
1373
  'class' => 'woolentor-action-field-left'
1374
  ),
1375
 
1376
- array(
1377
- 'name' => 'override_sale_price',
1378
- 'label' => esc_html__( 'Override Sale Price', 'woolentor' ),
1379
- 'type' => 'checkbox',
1380
- 'default' => 'off',
1381
- 'class' => 'woolentor-action-field-left'
1382
- ),
1383
-
1384
- array(
1385
- 'name' => 'enable_countdown_on_product_details_page',
1386
- 'label' => esc_html__( 'Show Countdown On Product Details Page', 'woolentor' ),
1387
- 'type' => 'checkbox',
1388
- 'default' => 'on',
1389
- 'class' => 'woolentor-action-field-left'
1390
- ),
1391
-
1392
- array(
1393
- 'name' => 'countdown_position',
1394
- 'label' => esc_html__( 'Countdown Position', 'woolentor' ),
1395
- 'type' => 'select',
1396
- 'options' => array(
1397
- 'woocommerce_before_add_to_cart_form' => esc_html__('Add to cart - Before', 'woolentor'),
1398
- 'woocommerce_after_add_to_cart_form' => esc_html__('Add to cart - After', 'woolentor'),
1399
- 'woocommerce_product_meta_start' => esc_html__('Product meta - Before', 'woolentor'),
1400
- 'woocommerce_product_meta_end' => esc_html__('Product meta - After', 'woolentor'),
1401
- 'woocommerce_single_product_summary' => esc_html__('Product summary - Before', 'woolentor'),
1402
- 'woocommerce_after_single_product_summary' => esc_html__('Product summary - After', 'woolentor'),
1403
- ),
1404
- 'class' => 'woolentor-action-field-left'
1405
- ),
1406
-
1407
- array(
1408
- 'name' => 'countdown_timer_title',
1409
- 'label' => esc_html__( 'Countdown Timer Title', 'woolentor' ),
1410
- 'type' => 'text',
1411
- 'default' => esc_html__('Hurry Up! Offer ends in', 'woolentor'),
1412
- 'class' => 'woolentor-action-field-left'
1413
- ),
1414
-
1415
  array(
1416
  'name' => 'deals',
1417
  'label' => esc_html__( 'Sale Events', 'woolentor' ),
1418
- 'desc' => esc_html__( 'Repeater field description', 'woolentor' ),
1419
  'type' => 'repeater',
1420
  'title_field' => 'title',
1421
  'fields' => [
@@ -1490,6 +1450,7 @@ class Woolentor_Admin_Fields {
1490
  'name' => 'discount_type',
1491
  'label' => esc_html__( 'Discount Type', 'woolentor' ),
1492
  'type' => 'select',
 
1493
  'options' => array(
1494
  'fixed_discount' => esc_html__( 'Fixed Discount', 'woolentor' ),
1495
  'percentage_discount' => esc_html__( 'Percentage Discount', 'woolentor' ),
@@ -1518,10 +1479,83 @@ class Woolentor_Admin_Fields {
1518
 
1519
  ]
1520
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1521
 
1522
  )
1523
 
1524
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1525
 
1526
  array(
1527
  'name' => 'ajaxsearch',
@@ -1558,6 +1592,16 @@ class Woolentor_Admin_Fields {
1558
  'require_settings' => true,
1559
  'is_pro' => true
1560
  ),
 
 
 
 
 
 
 
 
 
 
1561
 
1562
  array(
1563
  'name' => 'single_product_sticky_add_to_cartp',
@@ -1852,8 +1896,18 @@ class Woolentor_Admin_Fields {
1852
 
1853
  }
1854
 
 
 
 
 
 
 
 
 
 
 
1855
  // Wishsuite Addons
1856
- if( is_plugin_active('wishsuite/wishsuite.php') ){
1857
  $settings_fields['woolentor_elements_tabs'][] = [
1858
  'name' => 'wb_wishsuite_table',
1859
  'label' => esc_html__( 'WishSuite Table', 'woolentor' ),
@@ -1863,7 +1917,7 @@ class Woolentor_Admin_Fields {
1863
  }
1864
 
1865
  // Ever Compare Addons
1866
- if( is_plugin_active('ever-compare/ever-compare.php') ){
1867
  $settings_fields['woolentor_elements_tabs'][] = [
1868
  'name' => 'wb_ever_compare_table',
1869
  'label' => esc_html__( 'Ever Compare', 'woolentor' ),
1373
  'class' => 'woolentor-action-field-left'
1374
  ),
1375
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1376
  array(
1377
  'name' => 'deals',
1378
  'label' => esc_html__( 'Sale Events', 'woolentor' ),
 
1379
  'type' => 'repeater',
1380
  'title_field' => 'title',
1381
  'fields' => [
1450
  'name' => 'discount_type',
1451
  'label' => esc_html__( 'Discount Type', 'woolentor' ),
1452
  'type' => 'select',
1453
+ 'default' => 'percentage_discount',
1454
  'options' => array(
1455
  'fixed_discount' => esc_html__( 'Fixed Discount', 'woolentor' ),
1456
  'percentage_discount' => esc_html__( 'Percentage Discount', 'woolentor' ),
1479
 
1480
  ]
1481
  ),
1482
+
1483
+ array(
1484
+ 'name' => 'manage_price_label',
1485
+ 'label' => esc_html__( 'Manage Price Label', 'woolentor' ),
1486
+ 'desc' => esc_html__( 'Manage how you want the price labels to appear, or leave it blank to display only the flash-sale price without any labels. Available placeholders: {original_price}, {flash_sale_price}', 'woolentor' ),
1487
+ 'type' => 'text',
1488
+ 'class' => 'woolentor-action-field-left',
1489
+ ),
1490
+
1491
+ array(
1492
+ 'name' => 'override_sale_price',
1493
+ 'label' => esc_html__( 'Override Sale Price', 'woolentor' ),
1494
+ 'type' => 'checkbox',
1495
+ 'default' => 'off',
1496
+ 'class' => 'woolentor-action-field-left'
1497
+ ),
1498
+
1499
+ array(
1500
+ 'name' => 'enable_countdown_on_product_details_page',
1501
+ 'label' => esc_html__( 'Show Countdown On Product Details Page', 'woolentor' ),
1502
+ 'type' => 'checkbox',
1503
+ 'default' => 'on',
1504
+ 'class' => 'woolentor-action-field-left'
1505
+ ),
1506
+
1507
+ array(
1508
+ 'name' => 'countdown_style',
1509
+ 'label' => esc_html__( 'Countdown Style', 'woolentor' ),
1510
+ 'type' => 'select',
1511
+ 'options' => array(
1512
+ '1' => esc_html__('Style One', 'woolentor'),
1513
+ '2' => esc_html__('Style Two', 'woolentor'),
1514
+ ),
1515
+ 'default' => '2',
1516
+ 'class' => 'woolentor-action-field-left'
1517
+ ),
1518
+
1519
+ array(
1520
+ 'name' => 'countdown_position',
1521
+ 'label' => esc_html__( 'Countdown Position', 'woolentor' ),
1522
+ 'type' => 'select',
1523
+ 'options' => array(
1524
+ 'woocommerce_before_add_to_cart_form' => esc_html__('Add to cart - Before', 'woolentor'),
1525
+ 'woocommerce_after_add_to_cart_form' => esc_html__('Add to cart - After', 'woolentor'),
1526
+ 'woocommerce_product_meta_start' => esc_html__('Product meta - Before', 'woolentor'),
1527
+ 'woocommerce_product_meta_end' => esc_html__('Product meta - After', 'woolentor'),
1528
+ 'woocommerce_single_product_summary' => esc_html__('Product summary - Before', 'woolentor'),
1529
+ 'woocommerce_after_single_product_summary' => esc_html__('Product summary - After', 'woolentor'),
1530
+ ),
1531
+ 'class' => 'woolentor-action-field-left'
1532
+ ),
1533
+
1534
+ array(
1535
+ 'name' => 'countdown_timer_title',
1536
+ 'label' => esc_html__( 'Countdown Timer Title', 'woolentor' ),
1537
+ 'type' => 'text',
1538
+ 'default' => esc_html__('Hurry Up! Offer ends in', 'woolentor'),
1539
+ 'class' => 'woolentor-action-field-left'
1540
+ ),
1541
 
1542
  )
1543
 
1544
  ),
1545
+
1546
+ array(
1547
+ 'name' => 'wishlist',
1548
+ 'label' => esc_html__( 'Wishlist', 'woolentor' ),
1549
+ 'type' => 'element',
1550
+ 'default' => 'off',
1551
+ ),
1552
+
1553
+ array(
1554
+ 'name' => 'compare',
1555
+ 'label' => esc_html__( 'Compare', 'woolentor' ),
1556
+ 'type' => 'element',
1557
+ 'default' => 'off',
1558
+ ),
1559
 
1560
  array(
1561
  'name' => 'ajaxsearch',
1592
  'require_settings' => true,
1593
  'is_pro' => true
1594
  ),
1595
+
1596
+ array(
1597
+ 'name' => 'gtm_conversion_trackingp',
1598
+ 'label' => esc_html__( 'GTM Conversion Tracking', 'woolentor' ),
1599
+ 'desc' => esc_html__( 'GTM Conversion Tracking Module', 'woolentor' ),
1600
+ 'type' => 'module',
1601
+ 'default'=> 'off',
1602
+ 'require_settings' => true,
1603
+ 'is_pro' => true
1604
+ ),
1605
 
1606
  array(
1607
  'name' => 'single_product_sticky_add_to_cartp',
1896
 
1897
  }
1898
 
1899
+ // FlashSale Addons
1900
+ if( woolentor_get_option('enable', 'woolentor_flash_sale_settings') == 'on' ){
1901
+ $settings_fields['woolentor_elements_tabs'][] = [
1902
+ 'name' => 'product_flash_sale',
1903
+ 'label' => esc_html__( 'WL: Product Flash Sale', 'woolentor' ),
1904
+ 'type' => 'element',
1905
+ 'default' => 'on'
1906
+ ];
1907
+ }
1908
+
1909
  // Wishsuite Addons
1910
+ if( class_exists('WishSuite_Base') || class_exists('Woolentor_WishSuite_Base') ){
1911
  $settings_fields['woolentor_elements_tabs'][] = [
1912
  'name' => 'wb_wishsuite_table',
1913
  'label' => esc_html__( 'WishSuite Table', 'woolentor' ),
1917
  }
1918
 
1919
  // Ever Compare Addons
1920
+ if( class_exists('Ever_Compare') || class_exists('Woolentor_Ever_Compare') ){
1921
  $settings_fields['woolentor_elements_tabs'][] = [
1922
  'name' => 'wb_ever_compare_table',
1923
  'label' => esc_html__( 'Ever Compare', 'woolentor' ),
includes/admin/include/class.extension-manager.php CHANGED
@@ -60,16 +60,6 @@ class Woolentor_Extension_Manager{
60
 
61
  'free' => array(
62
 
63
- array(
64
- 'slug' => 'wishsuite',
65
- 'location' => 'wishsuite.php',
66
- 'name' => esc_html__( 'WishSuite', 'woolentor' )
67
- ),
68
- array(
69
- 'slug' => 'ever-compare',
70
- 'location' => 'ever-compare.php',
71
- 'name' => esc_html__( 'EverCompare', 'woolentor' )
72
- ),
73
  array(
74
  'slug' => 'swatchly',
75
  'location' => 'swatchly.php',
60
 
61
  'free' => array(
62
 
 
 
 
 
 
 
 
 
 
 
63
  array(
64
  'slug' => 'swatchly',
65
  'location' => 'swatchly.php',
includes/admin/include/settings_field_manager_default.php ADDED
@@ -0,0 +1,796 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Settings Api class
4
+ */
5
+ class WooLentor_Settings_Field_Manager_Default {
6
+
7
+ /**
8
+ * settings sections array
9
+ *
10
+ * @var array
11
+ */
12
+ protected $settings_sections = array();
13
+
14
+ /**
15
+ * Settings fields array
16
+ *
17
+ * @var array
18
+ */
19
+ protected $settings_fields = array();
20
+
21
+ public function __construct() {
22
+ add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
23
+ }
24
+
25
+ /**
26
+ * Enqueue scripts and styles
27
+ */
28
+ function admin_enqueue_scripts() {
29
+ wp_enqueue_style( 'wp-color-picker' );
30
+ wp_enqueue_media();
31
+ wp_enqueue_script( 'wp-color-picker' );
32
+ wp_enqueue_script( 'jquery-ui-sortable' );
33
+ wp_enqueue_script( 'jquery' );
34
+ }
35
+
36
+ /**
37
+ * Set settings sections
38
+ *
39
+ * @param array $sections setting sections array
40
+ */
41
+ function set_sections( $sections ) {
42
+ $this->settings_sections = $sections;
43
+
44
+ return $this;
45
+ }
46
+
47
+ /**
48
+ * Add a single section
49
+ *
50
+ * @param array $section
51
+ */
52
+ function add_section( $section ) {
53
+ $this->settings_sections[] = $section;
54
+
55
+ return $this;
56
+ }
57
+
58
+ /**
59
+ * Set settings fields
60
+ *
61
+ * @param array $fields settings fields array
62
+ */
63
+ function set_fields( $fields ) {
64
+ $this->settings_fields = $fields;
65
+
66
+ return $this;
67
+ }
68
+
69
+ function add_field( $section, $field ) {
70
+ $defaults = array(
71
+ 'name' => '',
72
+ 'label' => '',
73
+ 'desc' => '',
74
+ 'type' => 'text'
75
+ );
76
+
77
+ $arg = wp_parse_args( $field, $defaults );
78
+ $this->settings_fields[$section][] = $arg;
79
+
80
+ return $this;
81
+ }
82
+
83
+ /**
84
+ * Initialize and registers the settings sections and fileds to WordPress
85
+ *
86
+ * Usually this should be called at `admin_init` hook.
87
+ *
88
+ * This function gets the initiated settings sections and fields. Then
89
+ * registers them to WordPress and ready for use.
90
+ */
91
+ function admin_init() {
92
+
93
+ //register settings sections
94
+ foreach ( $this->settings_sections as $section ) {
95
+ if ( false == get_option( $section['id'] ) ) {
96
+ add_option( $section['id'] );
97
+ }
98
+
99
+ if ( isset($section['desc']) && !empty($section['desc']) ) {
100
+ $section['desc'] = '<div class="inside">' . $section['desc'] . '</div>';
101
+ $callback = create_function('', 'echo "' . str_replace( '"', '\"', $section['desc'] ) . '";');
102
+ } else if ( isset( $section['callback'] ) ) {
103
+ $callback = $section['callback'];
104
+ } else {
105
+ $callback = null;
106
+ }
107
+
108
+ // Tab section title
109
+ if( isset( $section['section_title'] ) && !empty( $section['section_title'] ) ){
110
+ $section['title'] = $section['section_title'];
111
+ }else{
112
+ $section['title'] = '';
113
+ }
114
+
115
+ add_settings_section( $section['id'], $section['title'], $callback, $section['id'] );
116
+ }
117
+
118
+ //register settings fields
119
+ foreach ( $this->settings_fields as $section => $field ) {
120
+ foreach ( $field as $option ) {
121
+
122
+ $name = $option['name'];
123
+ $type = isset( $option['type'] ) ? $option['type'] : 'text';
124
+ $label = isset( $option['label'] ) ? $option['label'] : '';
125
+ $callback = isset( $option['callback'] ) ? $option['callback'] : array( $this, 'callback_' . $type );
126
+
127
+ $args = array(
128
+ 'id' => $name,
129
+ 'class' => isset( $option['class'] ) ? $option['class'] : $name,
130
+ 'label_for' => "{$section}[{$name}]",
131
+ 'desc' => isset( $option['desc'] ) ? $option['desc'] : '',
132
+ 'name' => $label,
133
+ 'section' => $section,
134
+ 'size' => isset( $option['size'] ) ? $option['size'] : null,
135
+ 'options' => isset( $option['options'] ) ? $option['options'] : '',
136
+ 'std' => isset( $option['default'] ) ? $option['default'] : '',
137
+ 'sanitize_callback' => isset( $option['sanitize_callback'] ) ? $option['sanitize_callback'] : '',
138
+ 'type' => $type,
139
+ 'placeholder' => isset( $option['placeholder'] ) ? $option['placeholder'] : '',
140
+ 'min' => isset( $option['min'] ) ? $option['min'] : '',
141
+ 'max' => isset( $option['max'] ) ? $option['max'] : '',
142
+ 'step' => isset( $option['step'] ) ? $option['step'] : '',
143
+ 'headding' => isset( $option['headding'] ) ? $option['headding'] : '',
144
+ );
145
+
146
+ add_settings_field( "{$section}[{$name}]", $label, $callback, $section, $section, $args );
147
+ }
148
+ }
149
+
150
+ // creates our settings in the options table
151
+ foreach ( $this->settings_sections as $section ) {
152
+ register_setting( $section['id'], $section['id'], array( $this, 'sanitize_options' ) );
153
+ }
154
+ }
155
+
156
+ /**
157
+ * Get field description for display
158
+ *
159
+ * @param array $args settings field args
160
+ */
161
+ public function get_field_description( $args ) {
162
+ if ( ! empty( $args['desc'] ) ) {
163
+ $desc = sprintf( '<p class="description">%s</p>', $args['desc'] );
164
+ } else {
165
+ $desc = '';
166
+ }
167
+ return $desc;
168
+ }
169
+
170
+ /**
171
+ * Get Title for display
172
+ *
173
+ * @param array $args settings field args
174
+ */
175
+ public function callback_title( $args ) {
176
+ $headding = isset( $args['headding'] ) ? $args['headding'] : '';
177
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
178
+ $html = sprintf( '<h2 class="element_section_title %1$s-title">%2$s</h2>', $size, $headding );
179
+ echo $html;
180
+ }
181
+
182
+ /**
183
+ * Displays a text field for a settings field
184
+ *
185
+ * @param array $args settings field args
186
+ */
187
+ function callback_text( $args ) {
188
+
189
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
190
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
191
+ $type = isset( $args['type'] ) ? $args['type'] : 'text';
192
+ $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="' . $args['placeholder'] . '"';
193
+
194
+ $html = sprintf( '<input type="%1$s" class="%2$s-text" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s"%6$s/>', $type, $size, $args['section'], $args['id'], $value, $placeholder );
195
+ $html .= $this->get_field_description( $args );
196
+
197
+ echo $html;
198
+ }
199
+
200
+ /**
201
+ * Displays a multitextbox for a settings field
202
+ *
203
+ * @param array $args settings field args
204
+ */
205
+ function callback_multitext( $args ) {
206
+
207
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
208
+ $html = '<fieldset>';
209
+ foreach ( $args['options'] as $key => $label ) {
210
+ $new_value = isset( $value[$key] ) ? $value[$key] : '';
211
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
212
+ $html .= sprintf( '<input type="text" class="multitextbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%4$s" />', $args['section'], $args['id'], $key, $new_value );
213
+ $html .= sprintf( ' %1$s</label><br>', $label );
214
+ }
215
+
216
+ $html .= $this->get_field_description( $args );
217
+ $html .= '</fieldset>';
218
+
219
+ echo $html;
220
+ }
221
+
222
+ /**
223
+ * Displays a url field for a settings field
224
+ *
225
+ * @param array $args settings field args
226
+ */
227
+ function callback_url( $args ) {
228
+ $this->callback_text( $args );
229
+ }
230
+
231
+ /**
232
+ * Displays a number field for a settings field
233
+ *
234
+ * @param array $args settings field args
235
+ */
236
+ function callback_number( $args ) {
237
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
238
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
239
+ $type = isset( $args['type'] ) ? $args['type'] : 'number';
240
+ $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="' . $args['placeholder'] . '"';
241
+ $min = ( $args['min'] == '' ) ? '' : ' min="' . $args['min'] . '"';
242
+ $max = ( $args['max'] == '' ) ? '' : ' max="' . $args['max'] . '"';
243
+ $step = ( $args['step'] == '' ) ? '' : ' step="' . $args['step'] . '"';
244
+
245
+ $html = sprintf( '<input type="%1$s" class="%2$s-number" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s"%6$s%7$s%8$s%9$s/>', $type, $size, $args['section'], $args['id'], $value, $placeholder, $min, $max, $step );
246
+ $html .= $this->get_field_description( $args );
247
+
248
+ echo $html;
249
+ }
250
+
251
+ /**
252
+ * Displays a checkbox for a settings field
253
+ *
254
+ * @param array $args settings field args
255
+ */
256
+ function callback_checkbox( $args ) {
257
+
258
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
259
+
260
+ $html = '<fieldset class="htoptions_element_checkbox">';
261
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" />', $args['section'], $args['id'] );
262
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="htoptions_sp_%1$s[%2$s]" name="%1$s[%2$s]" value="on" %3$s />', $args['section'], $args['id'], checked( $value, 'on', false ) );
263
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s]">%3$s</label>', $args['section'], $args['id'], $args['desc'] );
264
+ $html .= sprintf( '<div class="htoption_checkbox_desc" id="htoptions_sp_%1$s[%2$s]">%3$s</div>', $args['section'], $args['id'], $args['desc'] );
265
+ $html .= '</fieldset>';
266
+
267
+ echo $html;
268
+ }
269
+
270
+ /**
271
+ * Displays a multicheckbox for a settings field
272
+ *
273
+ * @param array $args settings field args
274
+ */
275
+ function callback_multicheck( $args ) {
276
+
277
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
278
+ $html = '<fieldset>';
279
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="" />', $args['section'], $args['id'] );
280
+ foreach ( $args['options'] as $key => $label ) {
281
+ $checked = isset( $value[$key] ) ? $value[$key] : '0';
282
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
283
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $checked, $key, false ) );
284
+ $html .= sprintf( '%1$s</label><br>', $label );
285
+ }
286
+
287
+ $html .= $this->get_field_description( $args );
288
+ $html .= '</fieldset>';
289
+
290
+ echo $html;
291
+ }
292
+
293
+ /**
294
+ * Displays a multicheckbox for a settings field
295
+ *
296
+ * @param array $args settings field args
297
+ */
298
+ function callback_multicheckshort( $args ) {
299
+
300
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
301
+
302
+ $field_options = array_merge( $value, $args['options'] );
303
+
304
+ $html = '<fieldset><input type="checkbox" class="htoption-shortable-checkall">'.esc_html__( 'Check All', 'htoptions' ).'<ul class="htoption_shortable">';
305
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="" />', $args['section'], $args['id'] );
306
+
307
+ foreach ( $field_options as $key => $label ) {
308
+ $checked = array_key_exists( $key, $value ) ? $key : '0';
309
+ $html .= sprintf( '<li><label for="htoptions_sp_%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
310
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $checked, $key, false ) );
311
+ $html .= sprintf( '%1$s</label></li>', $label );
312
+ }
313
+
314
+ $html .= '</ul>'.$this->get_field_description( $args ).'</fieldset>';
315
+
316
+ echo $html;
317
+ }
318
+
319
+ /**
320
+ * Displays a radio button for a settings field
321
+ *
322
+ * @param array $args settings field args
323
+ */
324
+ function callback_radio( $args ) {
325
+
326
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
327
+ $html = '<fieldset>';
328
+
329
+ foreach ( $args['options'] as $key => $label ) {
330
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
331
+ $html .= sprintf( '<input type="radio" class="radio" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $value, $key, false ) );
332
+ $html .= sprintf( '%1$s</label><br>', $label );
333
+ }
334
+
335
+ $html .= $this->get_field_description( $args );
336
+ $html .= '</fieldset>';
337
+
338
+ echo $html;
339
+ }
340
+
341
+ /**
342
+ * Displays a selectbox for a settings field
343
+ *
344
+ * @param array $args settings field args
345
+ */
346
+ function callback_select( $args ) {
347
+
348
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
349
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
350
+ $html = sprintf( '<select class="%1$s" name="%2$s[%3$s]" id="%2$s[%3$s]">', $size, $args['section'], $args['id'] );
351
+
352
+ foreach ( $args['options'] as $key => $label ) {
353
+ $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $value, $key, false ), $label );
354
+ }
355
+
356
+ $html .= sprintf( '</select>' );
357
+ $html .= $this->get_field_description( $args );
358
+
359
+ echo $html;
360
+ }
361
+
362
+ /**
363
+ * Displays a multiselect for a settings field
364
+ *
365
+ * @param array $args settings field args
366
+ */
367
+ function callback_multiselect( $args ) {
368
+
369
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
370
+ $html = sprintf( '<select multiple="multiple" class="%1$s" name="%1$s[%2$s][]" id="%1$s[%2$s]">', $args['section'], $args['id'] );
371
+ foreach ( $args['options'] as $key => $label ) {
372
+ $selected = '';
373
+ if( !empty( $value ) ){
374
+ $selected = in_array( $key, $value ) ? $key : '';
375
+ }
376
+ $html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', $key, selected( $selected, $key, false ), $label );
377
+ }
378
+ $html .= sprintf( '</select>' );
379
+ $html .= $this->get_field_description( $args );
380
+
381
+ echo $html;
382
+ }
383
+
384
+ /**
385
+ * Displays a textarea for a settings field
386
+ *
387
+ * @param array $args settings field args
388
+ */
389
+ function callback_textarea( $args ) {
390
+
391
+ $value = esc_textarea( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
392
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
393
+ $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="'.$args['placeholder'].'"';
394
+
395
+ $html = sprintf( '<textarea rows="5" cols="55" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]"%4$s>%5$s</textarea>', $size, $args['section'], $args['id'], $placeholder, $value );
396
+ $html .= $this->get_field_description( $args );
397
+
398
+ echo $html;
399
+ }
400
+
401
+ /**
402
+ * Displays the html for a settings field
403
+ *
404
+ * @param array $args settings field args
405
+ * @return string
406
+ */
407
+ function callback_html( $args ) {
408
+ echo $this->get_field_description( $args );
409
+ }
410
+
411
+ /**
412
+ * Displays a rich text textarea for a settings field
413
+ *
414
+ * @param array $args settings field args
415
+ */
416
+ function callback_wysiwyg( $args ) {
417
+
418
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
419
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : '500px';
420
+
421
+ echo '<div style="max-width: ' . $size . ';">';
422
+
423
+ $editor_settings = array(
424
+ 'teeny' => true,
425
+ 'textarea_name' => $args['section'] . '[' . $args['id'] . ']',
426
+ 'textarea_rows' => 10
427
+ );
428
+
429
+ if ( isset( $args['options'] ) && is_array( $args['options'] ) ) {
430
+ $editor_settings = array_merge( $editor_settings, $args['options'] );
431
+ }
432
+
433
+ wp_editor( $value, $args['section'] . '-' . $args['id'], $editor_settings );
434
+
435
+ echo '</div>';
436
+
437
+ echo $this->get_field_description( $args );
438
+ }
439
+
440
+ /**
441
+ * Displays a file upload field for a settings field
442
+ *
443
+ * @param array $args settings field args
444
+ */
445
+ function callback_file( $args ) {
446
+
447
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
448
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
449
+ $id = $args['section'] . '[' . $args['id'] . ']';
450
+ $label = isset( $args['options']['button_label'] ) ? $args['options']['button_label'] : __( 'Choose File' );
451
+
452
+ $html = sprintf( '<input type="text" class="%1$s-text htoption-url" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
453
+ $html .= '<input type="button" class="button htoption-browse" value="' . $label . '" />';
454
+ $html .= $this->get_field_description( $args );
455
+
456
+ echo $html;
457
+ }
458
+
459
+ /**
460
+ * Displays a file upload field for a settings field
461
+ *
462
+ * @param array $args settings field args
463
+ */
464
+ function callback_image_upload( $args ) {
465
+
466
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
467
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
468
+ $id = $args['section'] . '[' . $args['id'] . ']';
469
+ $label = isset( $args['options']['button_label'] ) ? $args['options']['button_label'] : __( 'Choose File' );
470
+ $remove_label = isset( $args['options']['button_remove_label'] ) ? $args['options']['button_remove_label'] : __( 'Remove' );
471
+
472
+ $save_file = ( $value != '' ) ? '<div class="htoption_seleted_image"><img src="'.esc_url( $value ).'" alt="'.esc_attr( $label ).'" /></div>' : '';
473
+
474
+ $html = '<div class="htoption_display">'.$save_file.'</div>';
475
+ $html .= sprintf( '<input type="hidden" class="%1$s-text htoption-url" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
476
+ $html .= '<input type="button" class="button htoption-browse" value="' . $label . '" />';
477
+ $html .= '<input type="button" class="button htoption-remove" value="' . $remove_label . '" />';
478
+
479
+ $html .= $this->get_field_description( $args );
480
+
481
+ echo $html;
482
+ }
483
+
484
+ /**
485
+ * Displays a password field for a settings field
486
+ *
487
+ * @param array $args settings field args
488
+ */
489
+ function callback_password( $args ) {
490
+
491
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
492
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
493
+
494
+ $html = sprintf( '<input type="password" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
495
+ $html .= $this->get_field_description( $args );
496
+
497
+ echo $html;
498
+ }
499
+
500
+ /**
501
+ * Displays a color picker field for a settings field
502
+ *
503
+ * @param array $args settings field args
504
+ */
505
+ function callback_color( $args ) {
506
+
507
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
508
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
509
+
510
+ $html = sprintf( '<input type="text" class="%1$s-text wp-color-picker-field" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s" data-default-color="%5$s" />', $size, $args['section'], $args['id'], $value, $args['std'] );
511
+ $html .= $this->get_field_description( $args );
512
+
513
+ echo $html;
514
+ }
515
+
516
+ /**
517
+ * Displays a DIMENSIONS for a settings field
518
+ *
519
+ * @param array $args settings field args
520
+ */
521
+ function callback_dimensions( $args ) {
522
+
523
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
524
+ $html = '<fieldset><ul class="htoption_dimensions">';
525
+ foreach ( $args['options'] as $key => $label ) {
526
+ $new_value = isset( $value[$key] ) ? $value[$key] : '';
527
+ $html .= '<li>';
528
+
529
+ if( 'unit' === $key ){
530
+ $html .= sprintf( '<input type="text" class="dimensionsbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%4$s" />', $args['section'], $args['id'], $key, $new_value );
531
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">%4$s</label>', $args['section'], $args['id'], $key, $label );
532
+ }else{
533
+ $html .= sprintf( '<input type="number" class="dimensionsbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%4$s" />', $args['section'], $args['id'], $key, $new_value );
534
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">%4$s</label>', $args['section'], $args['id'], $key, $label );
535
+ }
536
+
537
+ $html .= '</li>';
538
+ }
539
+
540
+ $html .= '</ul>'.$this->get_field_description( $args ).'</fieldset>';
541
+
542
+ echo $html;
543
+ }
544
+
545
+
546
+ /**
547
+ * Displays a select box for creating the pages select box
548
+ *
549
+ * @param array $args settings field args
550
+ */
551
+ function callback_pages( $args ) {
552
+
553
+ $dropdown_args = array(
554
+ 'selected' => esc_attr($this->get_option($args['id'], $args['section'], $args['std'] ) ),
555
+ 'name' => $args['section'] . '[' . $args['id'] . ']',
556
+ 'id' => $args['section'] . '[' . $args['id'] . ']',
557
+ 'echo' => 0
558
+ );
559
+ $html = wp_dropdown_pages( $dropdown_args );
560
+ echo $html;
561
+ }
562
+
563
+ /**
564
+ * Sanitize callback for Settings API
565
+ *
566
+ * @return mixed
567
+ */
568
+ function sanitize_options( $options ) {
569
+
570
+ if ( !$options ) {
571
+ return $options;
572
+ }
573
+
574
+ foreach( $options as $option_slug => $option_value ) {
575
+ $sanitize_callback = $this->get_sanitize_callback( $option_slug );
576
+
577
+ // If callback is set, call it
578
+ if ( $sanitize_callback ) {
579
+ $options[ $option_slug ] = call_user_func( $sanitize_callback, $option_value );
580
+ continue;
581
+ }
582
+ }
583
+
584
+ return $options;
585
+ }
586
+
587
+ /**
588
+ * Get sanitization callback for given option slug
589
+ *
590
+ * @param string $slug option slug
591
+ *
592
+ * @return mixed string or bool false
593
+ */
594
+ function get_sanitize_callback( $slug = '' ) {
595
+ if ( empty( $slug ) ) {
596
+ return false;
597
+ }
598
+
599
+ // Iterate over registered fields and see if we can find proper callback
600
+ foreach( $this->settings_fields as $section => $options ) {
601
+ foreach ( $options as $option ) {
602
+ if ( $option['name'] != $slug ) {
603
+ continue;
604
+ }
605
+
606
+ // Return the callback name
607
+ return isset( $option['sanitize_callback'] ) && is_callable( $option['sanitize_callback'] ) ? $option['sanitize_callback'] : false;
608
+ }
609
+ }
610
+
611
+ return false;
612
+ }
613
+
614
+ /**
615
+ * Get the value of a settings field
616
+ *
617
+ * @param string $option settings field name
618
+ * @param string $section the section name this field belongs to
619
+ * @param string $default default text if it's not found
620
+ * @return string
621
+ */
622
+ function get_option( $option, $section, $default = '' ) {
623
+
624
+ $options = get_option( $section );
625
+
626
+ if ( isset( $options[$option] ) ) {
627
+ return $options[$option];
628
+ }
629
+
630
+ return $default;
631
+ }
632
+
633
+ /**
634
+ * Show navigations as tab
635
+ *
636
+ * Shows all the settings section labels as tab
637
+ */
638
+ function show_navigation() {
639
+ $html = '<h2 class="nav-tab-wrapper">';
640
+
641
+ $count = count( $this->settings_sections );
642
+
643
+ // don't show the navigation if only one section exists
644
+ if ( $count === 1 ) {
645
+ return;
646
+ }
647
+
648
+ foreach ( $this->settings_sections as $tab ) {
649
+ $html .= sprintf( '<a href="#%1$s" class="nav-tab" id="%1$s-tab">%2$s</a>', $tab['id'], $tab['title'] );
650
+ }
651
+
652
+ $html .= '</h2>';
653
+
654
+ echo $html;
655
+ }
656
+
657
+ /**
658
+ * Show the section settings forms
659
+ *
660
+ * This function displays every sections in a different form
661
+ */
662
+ function show_forms() {
663
+ ?>
664
+ <div class="metabox-holder">
665
+ <?php foreach ( $this->settings_sections as $form ) { ?>
666
+ <div id="<?php echo $form['id']; ?>" class="group" style="display: none;">
667
+ <form method="post" action="options.php">
668
+ <?php
669
+ do_action( 'wsa_form_top_' . $form['id'], $form );
670
+ settings_fields( $form['id'] );
671
+ do_settings_sections( $form['id'] );
672
+ do_action( 'wsa_form_bottom_' . $form['id'], $form );
673
+ if ( isset( $this->settings_fields[ $form['id'] ] ) ):
674
+ ?>
675
+ <div class="wl-submit-button" style="padding-left: 10px">
676
+ <?php submit_button(); ?>
677
+ </div>
678
+ <?php endif; ?>
679
+ </form>
680
+ </div>
681
+ <?php } ?>
682
+ </div>
683
+ <?php
684
+ $this->script();
685
+ }
686
+
687
+ /**
688
+ * Tabbable JavaScript codes & Initiate Color Picker
689
+ *
690
+ * This code uses localstorage for displaying active tabs
691
+ */
692
+ function script() {
693
+ ?>
694
+ <script>
695
+ jQuery(document).ready(function($) {
696
+ //Initiate Color Picker
697
+ $('.wp-color-picker-field').wpColorPicker();
698
+ $(".proelement .wp-picker-container button").attr("disabled", true);
699
+
700
+ // Switches option sections
701
+ $('.group').hide();
702
+ var activetab = '';
703
+ if (typeof(localStorage) != 'undefined' ) {
704
+ activetab = localStorage.getItem("activetab");
705
+ }
706
+
707
+ //if url has section id as hash then set it as active or override the current local storage value
708
+ if(window.location.hash){
709
+ activetab = window.location.hash;
710
+ if (typeof(localStorage) != 'undefined' ) {
711
+ localStorage.setItem("activetab", activetab);
712
+ }
713
+ }
714
+
715
+ if (activetab != '' && $(activetab).length ) {
716
+ $(activetab).fadeIn();
717
+ } else {
718
+ $('.group:first').fadeIn();
719
+ }
720
+ $('.group .collapsed').each(function(){
721
+ $(this).find('input:checked').parent().parent().parent().nextAll().each(
722
+ function(){
723
+ if ($(this).hasClass('last')) {
724
+ $(this).removeClass('hidden');
725
+ return false;
726
+ }
727
+ $(this).filter('.hidden').removeClass('hidden');
728
+ });
729
+ });
730
+
731
+ if (activetab != '' && $(activetab + '-tab').length ) {
732
+ $(activetab + '-tab').addClass('nav-tab-active');
733
+ }
734
+ else {
735
+ $('.nav-tab-wrapper a:first').addClass('nav-tab-active');
736
+ }
737
+ $('.nav-tab-wrapper a').click(function(evt) {
738
+ $('.nav-tab-wrapper a').removeClass('nav-tab-active');
739
+ $(this).addClass('nav-tab-active').blur();
740
+ var clicked_group = $(this).attr('href');
741
+ if (typeof(localStorage) != 'undefined' ) {
742
+ localStorage.setItem("activetab", $(this).attr('href'));
743
+ }
744
+ $('.group').hide();
745
+ $(clicked_group).fadeIn();
746
+ evt.preventDefault();
747
+ });
748
+
749
+ $('.htoption-browse').on('click', function (event) {
750
+ event.preventDefault();
751
+
752
+ var self = $(this);
753
+
754
+ // Create the media frame.
755
+ var file_frame = wp.media.frames.file_frame = wp.media({
756
+ title: self.data('uploader_title'),
757
+ button: {
758
+ text: self.data('uploader_button_text'),
759
+ },
760
+ multiple: false
761
+ });
762
+
763
+ file_frame.on('select', function () {
764
+ attachment = file_frame.state().get('selection').first().toJSON();
765
+ self.prev('.htoption-url').val(attachment.url).change();
766
+ self.siblings('.htoption_display').html('<div class="htoption_seleted_image"><img src="'+attachment.url+'" alt="'+attachment.caption+'" /></div>');
767
+ });
768
+
769
+ // Finally, open the modal
770
+ file_frame.open();
771
+
772
+ });
773
+
774
+ // Remove Media Button
775
+ $('.htoption-remove').on('click', function (event) {
776
+ event.preventDefault();
777
+ var self = $(this);
778
+ self.siblings('.htoption-url').val('').change();
779
+ self.siblings('.htoption_display').html('');
780
+ });
781
+
782
+
783
+ // Shortable field select all
784
+ $(".htoption-shortable-checkall").click(function () {
785
+ $( this ).siblings('.htoption_shortable').find('input:checkbox').not( this ).prop( 'checked', this.checked );
786
+ });
787
+
788
+ // Initiate shortable Field
789
+ $( ".htoption_shortable" ).sortable();
790
+
791
+ });
792
+ </script>
793
+ <?php
794
+ }
795
+
796
+ }
includes/custom-metabox.php CHANGED
@@ -1,42 +1,102 @@
1
- <?php
 
2
 
3
- // add extra metabox tab to woocommerce
4
- if( !function_exists('woolentor_add_wc_extra_metabox_tab')){
5
- function woolentor_add_wc_extra_metabox_tab($tabs){
6
- $woolentor_tab = array(
7
- 'label' => __( 'Product Badge', 'woolentor' ),
8
- 'target' => 'woolentor_product_data',
9
- 'class' => '',
10
- 'priority' => 80,
11
- );
12
- $tabs['woolentor_product_badge'] = $woolentor_tab;
13
- return $tabs;
14
  }
15
- add_filter( 'woocommerce_product_data_tabs', 'woolentor_add_wc_extra_metabox_tab' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
18
  // add metabox to general tab
19
- if( !function_exists('woolentor_add_metabox_to_general_tab')){
20
- function woolentor_add_metabox_to_general_tab(){
21
- echo '<div id="woolentor_product_data" class="panel woocommerce_options_panel hidden">';
22
- woocommerce_wp_text_input( array(
23
- 'id' => '_saleflash_text',
24
- 'label' => __( 'Custom Product Badge Text', 'woolentor' ),
25
- 'placeholder' => __( 'New', 'woolentor' ),
26
- 'description' => __( 'Enter your preferred Sale badge text. Ex: New / Free etc (Only for Universal layout addon)', 'woolentor' ),
27
- 'desc_tip' => true
28
- ) );
29
- echo '</div>';
30
- }
31
- add_action( 'woocommerce_product_data_panels', 'woolentor_add_metabox_to_general_tab' );
32
  }
 
33
  // Update data
34
- if( !function_exists('woolentor_save_metabox_of_general_tab') ){
35
- function woolentor_save_metabox_of_general_tab( $post_id ){
 
 
 
 
 
 
 
36
  $saleflash_text = wp_kses_post( stripslashes( $_POST['_saleflash_text'] ) );
37
  update_post_meta( $post_id, '_saleflash_text', $saleflash_text);
 
 
 
 
38
  }
39
- add_action( 'woocommerce_process_product_meta', 'woolentor_save_metabox_of_general_tab');
40
  }
41
 
42
- ?>
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
 
4
+ class Woolentor_Free_Custom_Meta_Fields{
5
+
6
+ private static $_instance = null;
7
+
8
+ /**
9
+ * Get Instance
10
+ */
11
+ public static function get_instance(){
12
+ if( is_null( self::$_instance ) ){
13
+ self::$_instance = new self();
 
14
  }
15
+ return self::$_instance;
16
+ }
17
+
18
+ /**
19
+ * Constructor
20
+ */
21
+ public function __construct(){
22
+
23
+ // Add Field in inventory tab
24
+ add_action( 'woocommerce_product_options_inventory_product_data', [ $this, 'add_extra_field_in_inventory_tab' ] );
25
+
26
+ // Custom Product tab
27
+ add_filter( 'woocommerce_product_data_tabs', [ $this, 'product_woolentor_tab' ], 10, 1 );
28
+ add_action( 'woocommerce_product_data_panels', [ $this, 'product_woolentor_data_panel' ], 99 );
29
+ add_action( 'woocommerce_process_product_meta', [ $this, 'save_woolenor_product_meta' ] );
30
+
31
+ }
32
+
33
+ /**
34
+ * add_extra_field_in_inventory_tab Custom field add in inventory tab
35
+ *
36
+ * @return void
37
+ */
38
+ public function add_extra_field_in_inventory_tab(){
39
+
40
+ // Stock progress bar extra field
41
+ echo '<div class="options_group">';
42
+ woocommerce_wp_text_input(
43
+ array(
44
+ 'id' => 'woolentor_total_stock_quantity',
45
+ 'label' => __( 'Initial number in stock', 'woolentor' ),
46
+ 'desc_tip' => 'true',
47
+ 'description' => __( 'Required for stock progress bar', 'woolentor' ),
48
+ 'type' => 'text',
49
+ )
50
+ );
51
+ echo '</div>';
52
+
53
+ }
54
+
55
+ // add extra metabox tab to woocommerce
56
+ public function product_woolentor_tab( $tabs ){
57
+ $woolentor_tab = array(
58
+ 'label' => __( 'Product Badge', 'woolentor' ),
59
+ 'target' => 'woolentor_product_data',
60
+ 'class' => '',
61
+ 'priority' => 80,
62
+ );
63
+ $tabs['woolentor_product_badge'] = $woolentor_tab;
64
+ return $tabs;
65
  }
66
 
67
  // add metabox to general tab
68
+ public function product_woolentor_data_panel(){
69
+ echo '<div id="woolentor_product_data" class="panel woocommerce_options_panel hidden">';
70
+ woocommerce_wp_text_input( array(
71
+ 'id' => '_saleflash_text',
72
+ 'label' => __( 'Custom Product Badge Text', 'woolentor' ),
73
+ 'placeholder' => __( 'New', 'woolentor' ),
74
+ 'description' => __( 'Enter your preferred Sale badge text. Ex: New / Free etc (Only for Universal layout addon)', 'woolentor' ),
75
+ 'desc_tip' => true
76
+ ) );
77
+ echo '</div>';
 
 
 
78
  }
79
+
80
  // Update data
81
+ public function save_woolenor_product_meta( $post_id ){
82
+
83
+ if( wp_verify_nonce( sanitize_key( $_POST['woocommerce_meta_nonce'] ), 'woocommerce_save_data' ) ){
84
+
85
+ // Quantity field
86
+ $stock_quantity = !empty( $_POST['woolentor_total_stock_quantity'] ) ? wc_clean( $_POST['woolentor_total_stock_quantity'] ) : '';
87
+ update_post_meta( $post_id, 'woolentor_total_stock_quantity', $stock_quantity );
88
+
89
+ // Sale Flash
90
  $saleflash_text = wp_kses_post( stripslashes( $_POST['_saleflash_text'] ) );
91
  update_post_meta( $post_id, '_saleflash_text', $saleflash_text);
92
+
93
+ }else{
94
+ delete_post_meta( $post_id, 'woolentor_total_stock_quantity' );
95
+ delete_post_meta( $post_id, '_saleflash_text' );
96
  }
97
+
98
  }
99
 
100
+
101
+ }
102
+ Woolentor_Free_Custom_Meta_Fields::get_instance();
includes/helper-function.php CHANGED
@@ -3,6 +3,14 @@
3
  // Exit if accessed directly
4
  if( ! defined( 'ABSPATH' ) ) exit();
5
 
 
 
 
 
 
 
 
 
6
  /**
7
  * Elementor Version check
8
  * Return boolean value
@@ -747,13 +755,19 @@ if( class_exists('WooCommerce') ){
747
  * [woolentor_pro_get_taxonomies]
748
  * @return [array] product texonomies
749
  */
750
- function woolentor_get_taxonomies( $object = 'product' ) {
751
  $all_taxonomies = get_object_taxonomies( $object );
752
  $taxonomies_list = [];
753
  foreach ( $all_taxonomies as $taxonomy_data ) {
754
  $taxonomy = get_taxonomy( $taxonomy_data );
755
- if( $taxonomy->show_ui ) {
756
- $taxonomies_list[ $taxonomy_data ] = $taxonomy->label;
 
 
 
 
 
 
757
  }
758
  }
759
  return $taxonomies_list;
@@ -786,7 +800,7 @@ function woolentor_order_by_opts() {
786
  * @return [bool]
787
  */
788
  function woolentor_exist_compare_plugin(){
789
- if( class_exists('Ever_Compare') ){
790
  return true;
791
  }elseif( class_exists('YITH_Woocompare') ){
792
  return true;
@@ -812,7 +826,7 @@ function woolentor_compare_button( $button_arg = array() ){
812
  $button_text = !empty( $button_arg['btn_text'] ) ? $button_arg['btn_text'] : esc_html__('Add to Compare','woolentor');
813
  $button_added_text = !empty( $button_arg['btn_added_txt'] ) ? $button_arg['btn_added_txt'] : esc_html__( 'Product Added','woolentor' );
814
 
815
- if( class_exists('Ever_Compare') ){
816
  $comp_link = \EverCompare\Frontend\Manage_Compare::instance()->get_compare_page_url();
817
  echo '<a title="'.esc_attr( $button_title ).'" href="'.esc_url( $comp_link ).'" class="htcompare-btn woolentor-compare" data-added-text="'.esc_attr( $button_added_text ).'" data-product_id="'.esc_attr( $product_id ).'">'.$button_text.'</a>';
818
 
@@ -840,7 +854,7 @@ function woolentor_compare_button( $button_arg = array() ){
840
  * @return [bool]
841
  */
842
  function woolentor_has_wishlist_plugin(){
843
- if( class_exists('WishSuite_Base') ){
844
  return true;
845
  }elseif( class_exists('YITH_WCWL') ){
846
  return true;
@@ -865,29 +879,18 @@ function woolentor_add_to_wishlist_button( $normalicon = '<i class="fa fa-heart-
865
 
866
  $output = '';
867
 
868
- if( class_exists('WishSuite_Base') ){
869
 
870
- $button_text = wishsuite_get_option( 'button_text','wishsuite_settings_tabs', 'Wishlist' );
871
- $button_added_text = wishsuite_get_option( 'added_button_text','wishsuite_settings_tabs', 'Product Added' );
872
- $button_exist_text = wishsuite_get_option( 'exist_button_text','wishsuite_settings_tabs', 'Product already added' );
873
-
874
- $button_text = $normalicon.'<span class="wishsuite-btn-text">'.$button_text.'</span>';
875
- $button_added_text = $addedicon.'<span class="wishsuite-btn-text">'.$button_added_text.'</span>';
876
- $button_exist_text = $addedicon.'<span class="wishsuite-btn-text">'.$button_exist_text.'</span>';
877
-
878
- $button_class = 'wishsuite-btn wishsuite-button wishlist'.( $tooltip == 'yes' ? '' : ' wltooltip_no' );
879
 
880
  $button_args = [
881
- 'btn_class' => $button_class,
882
- 'btn_text' => $button_text,
883
- 'btn_added_text' => $button_added_text,
884
- 'btn_exist_text' => $button_exist_text,
885
  ];
886
 
887
  add_filter( 'wishsuite_button_arg', function( $button_arg ) use ( $button_args ) {
888
-
889
- $button_arg['button_class'] = $button_args['btn_class'];
890
-
891
  return $button_arg;
892
  }, 90, 1 );
893
 
3
  // Exit if accessed directly
4
  if( ! defined( 'ABSPATH' ) ) exit();
5
 
6
+ /**
7
+ * [woolentor_is_woocommerce]
8
+ * @return [boolean]
9
+ */
10
+ function woolentor_is_woocommerce() {
11
+ return class_exists( 'WooCommerce' );
12
+ }
13
+
14
  /**
15
  * Elementor Version check
16
  * Return boolean value
755
  * [woolentor_pro_get_taxonomies]
756
  * @return [array] product texonomies
757
  */
758
+ function woolentor_get_taxonomies( $object = 'product', $skip_terms = false ) {
759
  $all_taxonomies = get_object_taxonomies( $object );
760
  $taxonomies_list = [];
761
  foreach ( $all_taxonomies as $taxonomy_data ) {
762
  $taxonomy = get_taxonomy( $taxonomy_data );
763
+ if( $skip_terms === true ){
764
+ if( ( $taxonomy->show_ui ) && ( 'pa_' !== substr( $taxonomy_data, 0, 3 ) ) ) {
765
+ $taxonomies_list[ $taxonomy_data ] = $taxonomy->label;
766
+ }
767
+ }else{
768
+ if( $taxonomy->show_ui ) {
769
+ $taxonomies_list[ $taxonomy_data ] = $taxonomy->label;
770
+ }
771
  }
772
  }
773
  return $taxonomies_list;
800
  * @return [bool]
801
  */
802
  function woolentor_exist_compare_plugin(){
803
+ if( class_exists('Ever_Compare') || class_exists('Woolentor_Ever_Compare') ){
804
  return true;
805
  }elseif( class_exists('YITH_Woocompare') ){
806
  return true;
826
  $button_text = !empty( $button_arg['btn_text'] ) ? $button_arg['btn_text'] : esc_html__('Add to Compare','woolentor');
827
  $button_added_text = !empty( $button_arg['btn_added_txt'] ) ? $button_arg['btn_added_txt'] : esc_html__( 'Product Added','woolentor' );
828
 
829
+ if( class_exists('Ever_Compare') || class_exists('Woolentor_Ever_Compare') ){
830
  $comp_link = \EverCompare\Frontend\Manage_Compare::instance()->get_compare_page_url();
831
  echo '<a title="'.esc_attr( $button_title ).'" href="'.esc_url( $comp_link ).'" class="htcompare-btn woolentor-compare" data-added-text="'.esc_attr( $button_added_text ).'" data-product_id="'.esc_attr( $product_id ).'">'.$button_text.'</a>';
832
 
854
  * @return [bool]
855
  */
856
  function woolentor_has_wishlist_plugin(){
857
+ if( class_exists('WishSuite_Base') || class_exists('Woolentor_WishSuite_Base') ){
858
  return true;
859
  }elseif( class_exists('YITH_WCWL') ){
860
  return true;
879
 
880
  $output = '';
881
 
882
+ if( class_exists('WishSuite_Base') || class_exists('Woolentor_WishSuite_Base') ){
883
 
884
+ $button_class = ' wishlist'.( $tooltip == 'yes' ? '' : ' wltooltip_no' );
 
 
 
 
 
 
 
 
885
 
886
  $button_args = [
887
+ 'btn_class' => $button_class
 
 
 
888
  ];
889
 
890
  add_filter( 'wishsuite_button_arg', function( $button_arg ) use ( $button_args ) {
891
+ if( strpos( $button_arg['button_class'], 'wishlist' ) == false ){
892
+ $button_arg['button_class'] .= $button_args['btn_class'];
893
+ }
894
  return $button_arg;
895
  }, 90, 1 );
896
 
includes/modules/class.module-manager.php CHANGED
@@ -27,15 +27,31 @@ class Woolentor_Module_Manager{
27
  * @return [void]
28
  */
29
  public function include_file(){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  // Shopify Style Checkout page
32
  if( woolentor_get_option( 'enable', 'woolentor_shopify_checkout_settings', 'off' ) == 'on' ){
33
- require( WOOLENTOR_ADDONS_PL_PATH .'includes/modules/shopify-like-checkout/class.shopify-like-checkout.php' );
34
  }
35
 
36
  // Flash Sale
37
  if( woolentor_get_option( 'enable', 'woolentor_flash_sale_settings', 'off' ) == 'on' ){
38
- require( WOOLENTOR_ADDONS_PL_PATH .'includes/modules/flash-sale/class.flash-sale.php' );
39
  }
40
 
41
  if( is_plugin_active('woolentor-addons-pro/woolentor_addons_pro.php') ){
@@ -50,10 +66,25 @@ class Woolentor_Module_Manager{
50
  require_once( WOOLENTOR_ADDONS_PL_PATH_PRO .'includes/modules/pre-orders/pre-orders.php' );
51
  }
52
 
 
 
 
 
 
53
  }
54
 
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
57
 
58
  }
59
 
27
  * @return [void]
28
  */
29
  public function include_file(){
30
+
31
+ // Wishlist
32
+ if( woolentor_get_option( 'wishlist', 'woolentor_others_tabs', 'off' ) == 'on' ){
33
+ $this->deactivate( 'wishsuite/wishsuite.php' );
34
+ if( ! class_exists('WishSuite_Base') ){
35
+ require_once( WOOLENTOR_ADDONS_PL_PATH .'includes/modules/wishlist/init.php' );
36
+ }
37
+ }
38
+
39
+ // Compare
40
+ if( woolentor_get_option( 'compare', 'woolentor_others_tabs', 'off' ) == 'on' ){
41
+ $this->deactivate( 'ever-compare/ever-compare.php' );
42
+ if( ! class_exists('Ever_Compare') ){
43
+ require_once( WOOLENTOR_ADDONS_PL_PATH .'includes/modules/compare/init.php' );
44
+ }
45
+ }
46
 
47
  // Shopify Style Checkout page
48
  if( woolentor_get_option( 'enable', 'woolentor_shopify_checkout_settings', 'off' ) == 'on' ){
49
+ require_once( WOOLENTOR_ADDONS_PL_PATH .'includes/modules/shopify-like-checkout/class.shopify-like-checkout.php' );
50
  }
51
 
52
  // Flash Sale
53
  if( woolentor_get_option( 'enable', 'woolentor_flash_sale_settings', 'off' ) == 'on' ){
54
+ require_once( WOOLENTOR_ADDONS_PL_PATH .'includes/modules/flash-sale/class.flash-sale.php' );
55
  }
56
 
57
  if( is_plugin_active('woolentor-addons-pro/woolentor_addons_pro.php') ){
66
  require_once( WOOLENTOR_ADDONS_PL_PATH_PRO .'includes/modules/pre-orders/pre-orders.php' );
67
  }
68
 
69
+ // GTM Conversion tracking
70
+ if( ( woolentor_get_option( 'enable', 'woolentor_gtm_convertion_tracking_settings', 'off' ) == 'on' ) ){
71
+ require_once( WOOLENTOR_ADDONS_PL_PATH_PRO .'includes/modules/gtm-conversion-tracking/gtm-conversion-tracking.php' );
72
+ }
73
+
74
  }
75
 
76
  }
77
 
78
+ /**
79
+ * [deactivate] Deactivated
80
+ * @return [void]
81
+ */
82
+ public function deactivate( $slug ){
83
+ if( is_plugin_active( $slug ) ){
84
+ return deactivate_plugins( $slug );
85
+ }
86
+ }
87
+
88
 
89
  }
90
 
includes/modules/compare/assets/css/admin.css ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ tr.element_section_title_area {
2
+ background: #ffff;
3
+ }
4
+ h2.element_section_title.margin_0 {
5
+ margin: 0;
6
+ }
7
+
8
+ tr.element_section_title_area[class*="message-"] h2{
9
+ font-size: 12px;
10
+ font-weight: 400;
11
+ }
12
+ tr.element_section_title_area[class*="message-"]{
13
+ border: 1px solid #c3c4c7;
14
+ border-left-width: 4px;
15
+ box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
16
+ }
17
+ tr.element_section_title_area.message-info{
18
+ border-left-color: #17a2b8
19
+ }
20
+
21
+ .form-table tr.element_section_title_area[class*="message-"] td {
22
+ padding: 0 10px;
23
+ }
24
+
25
+ /* Check box */
26
+ .htoptions_element_checkbox label {
27
+ padding: 2px;
28
+ width: 43px;
29
+ height: 15px;
30
+ background-color: #2c3e50;
31
+ border-radius: 60px;
32
+ -webkit-transition: background 0.2s;
33
+ transition: background 0.2s;
34
+ position: relative;
35
+ text-indent: -99999px;
36
+ }
37
+ .htoptions_element_checkbox label::before {
38
+ content: "";
39
+ position: absolute;
40
+ top: 2px;
41
+ left: 2px;
42
+ bottom: 2px;
43
+ right: 2px;
44
+ background-color: #ffffff;
45
+ border-radius: 10px;
46
+ -webkit-transition: background 0.2s;
47
+ transition: background 0.2s;
48
+ }
49
+ .htoptions_element_checkbox label::after {
50
+ content: "";
51
+ position: absolute;
52
+ top: 3px;
53
+ left: 3px;
54
+ bottom: 3px;
55
+ width: 18px;
56
+ background-color: #2c3e50;
57
+ border-radius: 10px;
58
+ -webkit-transition: margin 0.2s, background 0.2s;
59
+ transition: margin 0.2s, background 0.2s;
60
+ }
61
+ .htoptions_element_checkbox input {
62
+ opacity: 0;
63
+ width: 0;
64
+ height: 0;
65
+ position: absolute;
66
+ }
67
+ .htoptions_element_checkbox input:disabled{
68
+ opacity: 0;
69
+ }
70
+ .htoptions_element_checkbox input:checked + label {
71
+ background-color: #22b9ff;
72
+ }
73
+ .htoptions_element_checkbox input:checked + label::after {
74
+ background-color: #22b9ff;
75
+ margin-left: 23px;
76
+ }
77
+
78
+ .button.htoption-remove {
79
+ margin-left: 10px;
80
+ }
81
+ .htoption_display {
82
+ max-width: 120px;
83
+ }
84
+ .htoption_seleted_image{
85
+ border: 1px solid #ddd;
86
+ margin-bottom: 10px;
87
+ }
88
+ .htoption_display img{
89
+ width: 100%;
90
+ }
91
+
92
+ ul.htoption_shortable li {
93
+ position: relative;
94
+ box-shadow: 0 0px 4px rgb(0 0 0 / 10%);
95
+ padding: 8px 0 7px 25px;
96
+ }
97
+ ul.htoption_shortable li:before {
98
+ position: absolute;
99
+ content: "::";
100
+ left: 9px;
101
+ top: 4px;
102
+ font-size: 22px;
103
+ }
104
+ ul.htoption_shortable li.ui-sortable-helper{
105
+ background: #fff;
106
+ border: 1px dashed #ccc;
107
+ }
108
+
109
+ /* Dimensions Field */
110
+ .htoption_dimensions li {
111
+ float: left;
112
+ width: 75px;
113
+ }
114
+ .htoption_dimensions li input {
115
+ display: block;
116
+ text-align: center;
117
+ width: 100%;
118
+ border-color: #d5dadf;
119
+ height: 30px;
120
+ border-left: none;
121
+ border-radius: 0;
122
+ padding: 4px 4px 4px 0;
123
+ }
124
+ .htoption_dimensions li input:focus{
125
+ outline: none;
126
+ box-shadow: none;
127
+ border:1px solid #007cba !important;
128
+ }
129
+ .htoption_dimensions li:first-child input {
130
+ border-left: 1px solid #d5dadf;
131
+ border-radius: 3px 0 0 3px;
132
+ }
133
+ .htoption_dimensions li:last-child input {
134
+ border-right: 1px solid #d5dadf;
135
+ border-radius: 0 3px 3px 0;
136
+ }
137
+ .htoption_dimensions li label {
138
+ display: block !important;
139
+ text-align: center;
140
+ font-size: 13px;
141
+ text-transform: uppercase;
142
+ }
includes/modules/compare/assets/css/frontend.css ADDED
@@ -0,0 +1,395 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Button Style */
2
+ .products a.htcompare-shop-top_thumbnail{
3
+ position: absolute !important;
4
+ top: 0;
5
+ left: 8px !important;
6
+ z-index: 9;
7
+ }
8
+ .htcompare-btn {
9
+ display: inline-flex !important;
10
+ align-items: center;
11
+ position: relative !important;
12
+ }
13
+ .htcompare-btn svg {
14
+ fill: currentColor;
15
+ transition: all 200ms ease-out;
16
+ width: 15px;
17
+ height: 15px;
18
+ margin-right: 5px;
19
+ }
20
+
21
+ .htcompare-btn svg .ever-compare-check,.htcompare-btn.added svg .ever-compare-refresh{
22
+ opacity: 0;
23
+ }
24
+ .htcompare-btn.added svg .ever-compare-check{
25
+ opacity: 1;
26
+ }
27
+
28
+ .htcompare-btn.loading svg .ever-compare-refresh {
29
+ animation:loading 500ms 0ms infinite normal linear;
30
+ transform-origin: center;
31
+ }
32
+ @keyframes loading {
33
+ from {transform: rotate(0deg);}
34
+ to {transform: rotate(360deg);}
35
+ }
36
+
37
+ .htcompare-btn.loading::after,a.htcompare-btn.added::after,.ever-compare-loader{
38
+ display: none;
39
+ }
40
+ .htcompare-btn.loading .ever-compare-loader{
41
+ display: block;
42
+ }
43
+
44
+ .htcompare-btn-text {
45
+ display: flex;
46
+ align-items: center;
47
+ }
48
+ .ever-compare-btn-image{
49
+ width: 25px;
50
+ margin-right: 5px;
51
+ display: inline-block;
52
+ }
53
+ .ever-compare-btn-image img{
54
+ width: 100% !important;
55
+ margin: 0 !important;
56
+ }
57
+
58
+ a.htcompare-btn.loading,a.htcompare-cart-button.loading{
59
+ opacity: .25;
60
+ /*padding-right: 2.618em;*/
61
+ position: relative;
62
+ }
63
+
64
+ /* Common table Style */
65
+ .htcompare-row {
66
+ display: -webkit-box;
67
+ display: -ms-flexbox;
68
+ display: flex;
69
+ -webkit-box-orient: horizontal;
70
+ -webkit-box-direction: normal;
71
+ -ms-flex-direction: row;
72
+ flex-direction: row;
73
+ -ms-flex-wrap: nowrap;
74
+ flex-wrap: nowrap;
75
+ }
76
+ .htcompare-col {
77
+ display: -webkit-box;
78
+ display: -ms-flexbox;
79
+ display: flex;
80
+ -webkit-box-orient: vertical;
81
+ -webkit-box-direction: normal;
82
+ -ms-flex-direction: column;
83
+ flex-direction: column;
84
+ -webkit-box-pack: center;
85
+ -ms-flex-pack: center;
86
+ justify-content: center;
87
+ padding: 15px;
88
+ word-break: break-word;
89
+ }
90
+ .htcompare-row:nth-child(2n) .htcompare-col {
91
+ background-color: #F7F7F7;
92
+ }
93
+ .htcompare-col {
94
+ border-right: 1px solid #ddd;
95
+ }
96
+ .htcolumn-value {
97
+ -webkit-box-flex: 0;
98
+ -ms-flex: 0 1 26%;
99
+ flex: 0 1 26%;
100
+ -webkit-box-align: center;
101
+ -ms-flex-align: center;
102
+ align-items: center;
103
+ text-align: center;
104
+ }
105
+ .compare-data-primary .htcolumn-value {
106
+ -webkit-box-pack: start;
107
+ -ms-flex-pack: start;
108
+ justify-content: flex-start;
109
+ padding-top: 0;
110
+ border-top: 1px solid #ddd;
111
+ }
112
+ .htcolumn-field-name {
113
+ -webkit-box-flex: 0;
114
+ -ms-flex: 0 0 20%;
115
+ flex: 0 0 20%;
116
+ color: #2d2a2a;
117
+ text-transform: uppercase;
118
+ font-weight: 600;
119
+ font-size: 16px;
120
+ }
121
+ .htcompare-remove{
122
+ position: relative;
123
+ display: inline-block;
124
+ padding: 10px;
125
+ margin-left: -5px;
126
+ }
127
+ .htcompare-remove:focus{
128
+ outline: none;
129
+ }
130
+ .htcompare-remove::after, .htcompare-remove::before {
131
+ content: " ";
132
+ position: absolute;
133
+ top: 50%;
134
+ display: inline-block;
135
+ width: 15px;
136
+ height: 2px;
137
+ background-color: #2d2a2a;
138
+ right: 0;
139
+ -webkit-transform: rotate(45deg);
140
+ transform: rotate(45deg);
141
+ }
142
+ .htcompare-remove::after{
143
+ -webkit-transform: rotate(-45deg);
144
+ transform: rotate(-45deg);
145
+ }
146
+ .htcompare-remove:hover::after,.htcompare-remove:hover::before{
147
+ background: #EC1E1E;
148
+ }
149
+ .htcompare-product-image{
150
+ display: block;
151
+ }
152
+ .htcompare-return-to-shop .button{
153
+ display: inline-block;
154
+ }
155
+ .htcompare-empty-page-text,.htcompare-return-to-shop{
156
+ text-align: center;
157
+ }
158
+ .htcompare-empty-page-text {
159
+ margin-bottom: 10px;
160
+ }
161
+
162
+ .htcompare-table{
163
+ position: relative;
164
+ }
165
+ .htcompare-table.loading:before{
166
+ position: absolute;
167
+ content:"";
168
+ top: 0;
169
+ right: 0;
170
+ bottom: 0;
171
+ left: 0;
172
+ z-index: 1;
173
+ background-color: rgba(255,255,255,.6);
174
+ }
175
+ .htcompare-table .htcompare-table-loader {
176
+ border: 8px solid #f3f3f3;
177
+ border-radius: 50%;
178
+ border-top: 8px solid #3498db;
179
+ width: 50px;
180
+ height: 50px;
181
+ -webkit-animation: htcomspin 1s linear infinite;
182
+ animation: htcomspin 1s linear infinite;
183
+ position: absolute;
184
+ top: 50%;
185
+ left: 50%;
186
+ z-index: 1;
187
+ transform: translate(-30px, -25px);
188
+ display: none;
189
+ }
190
+
191
+ .htcompare-table.loading .htcompare-table-loader{
192
+ display: block;
193
+ }
194
+
195
+ .compare-data-description .htcolumn-value p:last-child,.compare-data-availability .htcolumn-value p:last-child,.ever-compare-message-error p{
196
+ margin-bottom: 0;
197
+ }
198
+
199
+ .ever-compare-message-error {
200
+ border: 1px solid #dc3545;
201
+ border-left-width: 4px;
202
+ box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
203
+ padding: 4px 10px;
204
+ margin-bottom: 10px;
205
+ }
206
+ .compare-data-primary.htcompare-row .htcompare-col {
207
+ background-color: transparent !important;
208
+ }
209
+
210
+ /* Safari */
211
+ @-webkit-keyframes htcomspin {
212
+ 0% { -webkit-transform: rotate(0deg); }
213
+ 100% { -webkit-transform: rotate(360deg); }
214
+ }
215
+
216
+ @keyframes htcomspin {
217
+ 0% { transform: rotate(0deg); }
218
+ 100% { transform: rotate(360deg); }
219
+ }
220
+
221
+ /* Popup Style */
222
+ a.htcompare-cart-button.loading::after{
223
+ font-family: WooCommerce;
224
+ content: '\e01c';
225
+ vertical-align: top;
226
+ -webkit-font-smoothing: antialiased;
227
+ font-weight: 400;
228
+ position: absolute;
229
+ top: auto;
230
+ right: 1em;
231
+ animation: spin 2s linear infinite;
232
+ }
233
+ a.htcompare-cart-button.added::after{
234
+ font-family: WooCommerce;
235
+ content: '\e017';
236
+ margin-left: .53em;
237
+ vertical-align: bottom;
238
+ }
239
+
240
+ .htcompare-popup{
241
+ display: none;
242
+ position: fixed;
243
+ z-index: 9999;
244
+ top: 0;
245
+ left: 0;
246
+ visibility: hidden;
247
+ overflow: hidden;
248
+ opacity: 0;
249
+ width: 100%;
250
+ height: 100%;
251
+ padding-right: 17px;
252
+ -webkit-transition: all 0.25s cubic-bezier(0.645, 0.045, 0.355, 1);
253
+ -o-transition: all 0.25s cubic-bezier(0.645, 0.045, 0.355, 1);
254
+ transition: all 0.25s cubic-bezier(0.645, 0.045, 0.355, 1);
255
+ background-color: rgba(0, 0, 0, 0.5);
256
+
257
+ }
258
+ .logged-in.admin-bar .htcompare-popup{top: 15px;}
259
+ .htcompare-popup.open{
260
+ display: -webkit-box;
261
+ display: -webkit-flex;
262
+ display: -ms-flexbox;
263
+ display: flex;
264
+ opacity: 1;
265
+ visibility: visible;
266
+ }
267
+ .htcompare-popup .htcompare-popup-content-area {
268
+ width: calc(100% - 30px);
269
+ max-width: 1500px;
270
+ margin: auto;
271
+ padding: 30px;
272
+ background: #fff;
273
+ position: relative;
274
+ }
275
+ .htcompare-popup .htcompare-popup-content-area .htcompare-table{
276
+ max-height: 750px;
277
+ overflow-y: auto;
278
+ }
279
+ .htcompare-popup-close {
280
+ position: absolute;
281
+ width: 25px;
282
+ height: 25px;
283
+ background: #fff;
284
+ right: -10px;
285
+ top: -10px;
286
+ border-radius: 100%;
287
+ cursor: pointer;
288
+ }
289
+ .htcompare-popup-close::after, .htcompare-popup-close::before{
290
+ content: " ";
291
+ position: absolute;
292
+ top: 50%;
293
+ display: inline-block;
294
+ width: 15px;
295
+ height: 2px;
296
+ background-color: #2d2a2a;
297
+ right: 5px;
298
+ -webkit-transform: rotate(45deg);
299
+ transform: rotate(45deg);
300
+ }
301
+ .htcompare-popup-close::after {
302
+ -webkit-transform: rotate(-45deg);
303
+ transform: rotate(-45deg);
304
+ }
305
+ .htcompare-popup-close:hover::after,.htcompare-popup-close:hover::before{
306
+ background: #EC1E1E;
307
+ }
308
+
309
+ /*Share Link button*/
310
+ .ever-compare-shareable-link {
311
+ margin-top: 10px;
312
+ }
313
+ .ever-compare-shareable-link.right {
314
+ text-align: right;
315
+ }
316
+ .ever-compare-shareable-link.left {
317
+ text-align: left;
318
+ }
319
+ .ever-compare-shareable-link.center {
320
+ text-align: center;
321
+ }
322
+
323
+
324
+ /* Normal :1366px. */
325
+ @media (min-width: 1200px) and (max-width: 1400px) {
326
+
327
+ }
328
+
329
+ /* Normal desktop :992px. */
330
+ @media (min-width: 992px) and (max-width: 1200px) {
331
+ .htcompare-table {
332
+ overflow-x: auto;
333
+ -webkit-overflow-scrolling: touch;
334
+ }
335
+ }
336
+
337
+ @media (min-width: 768px) and (max-width: 1024px) {
338
+ .htcompare-table {
339
+ overflow-x: auto;
340
+ -webkit-overflow-scrolling: touch;
341
+ }
342
+ .htcompare-col {
343
+ -webkit-box-flex: 0;
344
+ -ms-flex: 0 0 33.33333%;
345
+ flex: 0 0 33.33333%;
346
+ }
347
+ }
348
+
349
+ /* Tablet desktop :768px. */
350
+ @media (min-width: 768px) and (max-width: 991px) {
351
+
352
+ }
353
+
354
+ /* small mobile :320px. */
355
+ @media (max-width: 767px) {
356
+ .htcompare-table {
357
+ overflow-x: auto;
358
+ -webkit-overflow-scrolling: touch;
359
+ }
360
+ .htcompare-col {
361
+ -webkit-box-flex: 1;
362
+ -ms-flex: 1 0 50%;
363
+ flex: 1 0 50%;
364
+ }
365
+ .htcolumn-field-name{
366
+ display: none;
367
+ }
368
+
369
+ .htcompare-row:nth-child(2n) .htcompare-col {
370
+ background-color: transparent;
371
+ }
372
+
373
+ .htcolumn-value::before {
374
+ content: attr(data-title);
375
+ display: block;
376
+ background-color: #F7F7F7;
377
+ margin-top: -15px;
378
+ margin-bottom: 15px;
379
+ padding: 5px 0;
380
+ width: 100%;
381
+ color: #2d2a2a;
382
+ text-transform: uppercase;
383
+ font-weight: 600;
384
+ font-size: 14px;
385
+ }
386
+ .compare-data-primary .htcolumn-value::before{
387
+ display: none;
388
+ }
389
+
390
+ }
391
+
392
+ /* Large Mobile :480px. */
393
+ @media only screen and (min-width: 480px) and (max-width: 767px) {
394
+
395
+ }
includes/modules/compare/assets/css/frontend.min.css ADDED
@@ -0,0 +1 @@
 
1
+ .products a.htcompare-shop-top_thumbnail{position:absolute!important;top:0;left:8px!important;z-index:9}.htcompare-btn{display:inline-flex!important;align-items:center;position:relative!important}.htcompare-btn svg{fill:currentColor;transition:all .2s ease-out;width:15px;height:15px;margin-right:5px}.htcompare-btn svg .ever-compare-check,.htcompare-btn.added svg .ever-compare-refresh{opacity:0}.htcompare-btn.added svg .ever-compare-check{opacity:1}.htcompare-btn.loading svg .ever-compare-refresh{animation:loading .5s 0s infinite normal linear;transform-origin:center}@keyframes loading{from{transform:rotate(0)}to{transform:rotate(360deg)}}.ever-compare-loader,.htcompare-btn.loading::after,a.htcompare-btn.added::after{display:none}.htcompare-btn.loading .ever-compare-loader{display:block}.htcompare-btn-text{display:flex;align-items:center}.ever-compare-btn-image{width:25px;margin-right:5px;display:inline-block}.ever-compare-btn-image img{width:100%!important;margin:0!important}a.htcompare-btn.loading,a.htcompare-cart-button.loading{opacity:.25;/*padding-right:2.618em;*/position:relative}.htcompare-row{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.htcompare-col{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding:15px;word-break:break-word}.htcompare-row:nth-child(2n) .htcompare-col{background-color:#f7f7f7}.htcompare-col{border-right:1px solid #ddd}.htcolumn-value{-webkit-box-flex:0;-ms-flex:0 1 26%;flex:0 1 26%;-webkit-box-align:center;-ms-flex-align:center;align-items:center;text-align:center}.compare-data-primary .htcolumn-value{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start;padding-top:0;border-top:1px solid #ddd}.htcolumn-field-name{-webkit-box-flex:0;-ms-flex:0 0 20%;flex:0 0 20%;color:#2d2a2a;text-transform:uppercase;font-weight:600;font-size:16px}.htcompare-remove{position:relative;display:inline-block;padding:10px;margin-left:-5px}.htcompare-remove:focus{outline:0}.htcompare-remove::after,.htcompare-remove::before{content:" ";position:absolute;top:50%;display:inline-block;width:15px;height:2px;background-color:#2d2a2a;right:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.htcompare-remove::after{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.htcompare-remove:hover::after,.htcompare-remove:hover::before{background:#ec1e1e}.htcompare-product-image{display:block}.htcompare-return-to-shop .button{display:inline-block}.htcompare-empty-page-text,.htcompare-return-to-shop{text-align:center}.htcompare-empty-page-text{margin-bottom:10px}.htcompare-table{position:relative}.htcompare-table.loading:before{position:absolute;content:"";top:0;right:0;bottom:0;left:0;z-index:1;background-color:rgba(255,255,255,.6)}.htcompare-table .htcompare-table-loader{border:8px solid #f3f3f3;border-radius:50%;border-top:8px solid #3498db;width:50px;height:50px;-webkit-animation:htcomspin 1s linear infinite;animation:htcomspin 1s linear infinite;position:absolute;top:50%;left:50%;z-index:1;transform:translate(-30px,-25px);display:none}.htcompare-table.loading .htcompare-table-loader{display:block}.compare-data-availability .htcolumn-value p:last-child,.compare-data-description .htcolumn-value p:last-child,.ever-compare-message-error p{margin-bottom:0}.ever-compare-message-error{border:1px solid #dc3545;border-left-width:4px;box-shadow:0 1px 1px rgb(0 0 0 / 4%);padding:4px 10px;margin-bottom:10px}.compare-data-primary.htcompare-row .htcompare-col{background-color:transparent!important}@-webkit-keyframes htcomspin{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(360deg)}}@keyframes htcomspin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}a.htcompare-cart-button.loading::after{font-family:WooCommerce;content:'\e01c';vertical-align:top;-webkit-font-smoothing:antialiased;font-weight:400;position:absolute;top:auto;right:1em;animation:spin 2s linear infinite}a.htcompare-cart-button.added::after{font-family:WooCommerce;content:'\e017';margin-left:.53em;vertical-align:bottom}.htcompare-popup{display:none;position:fixed;z-index:9999;top:0;left:0;visibility:hidden;overflow:hidden;opacity:0;width:100%;height:100%;padding-right:17px;-webkit-transition:all .25s cubic-bezier(.645,.045,.355,1);-o-transition:all .25s cubic-bezier(.645,.045,.355,1);transition:all .25s cubic-bezier(.645,.045,.355,1);background-color:rgba(0,0,0,.5)}.logged-in.admin-bar .htcompare-popup{top: 15px;}.htcompare-popup.open{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;opacity:1;visibility:visible}.htcompare-popup .htcompare-popup-content-area{width:calc(100% - 30px);max-width:1500px;margin:auto;padding:30px;background:#fff;position:relative}.htcompare-popup .htcompare-popup-content-area .htcompare-table{max-height:750px;overflow-y:auto}.htcompare-popup-close{position:absolute;width:25px;height:25px;background:#fff;right:-10px;top:-10px;border-radius:100%;cursor:pointer}.htcompare-popup-close::after,.htcompare-popup-close::before{content:" ";position:absolute;top:50%;display:inline-block;width:15px;height:2px;background-color:#2d2a2a;right:5px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.htcompare-popup-close::after{-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.htcompare-popup-close:hover::after,.htcompare-popup-close:hover::before{background:#ec1e1e}.ever-compare-shareable-link{margin-top:10px}.ever-compare-shareable-link.right{text-align:right}.ever-compare-shareable-link.left{text-align:left}.ever-compare-shareable-link.center{text-align:center}@media (min-width:992px) and (max-width:1200px){.htcompare-table{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (min-width:768px) and (max-width:1024px){.htcompare-table{overflow-x:auto;-webkit-overflow-scrolling:touch}.htcompare-col{-webkit-box-flex:0;-ms-flex:0 0 33.33333%;flex:0 0 33.33333%}}@media (max-width:767px){.htcompare-table{overflow-x:auto;-webkit-overflow-scrolling:touch}.htcompare-col{-webkit-box-flex:1;-ms-flex:1 0 50%;flex:1 0 50%}.htcolumn-field-name{display:none}.htcompare-row:nth-child(2n) .htcompare-col{background-color:transparent}.htcolumn-value::before{content:attr(data-title);display:block;background-color:#f7f7f7;margin-top:-15px;margin-bottom:15px;padding:5px 0;width:100%;color:#2d2a2a;text-transform:uppercase;font-weight:600;font-size:14px}.compare-data-primary .htcolumn-value::before{display:none}}
includes/modules/compare/assets/images/extensions/email-candy-pro.png ADDED
Binary file
includes/modules/compare/assets/images/extensions/hashbar-pro.png ADDED
Binary file
includes/modules/compare/assets/images/extensions/htmega-pro.png ADDED
Binary file
includes/modules/compare/assets/images/extensions/just-tables-pro.png ADDED
Binary file
includes/modules/compare/assets/images/extensions/multicurrencypro.png ADDED
Binary file
includes/modules/compare/assets/images/extensions/whols-pro.png ADDED
Binary file
includes/modules/compare/assets/images/extensions/woolentor-addons-pro.png ADDED
Binary file
includes/modules/compare/assets/images/icon.svg ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 471.701 471.701">
2
+ <g class="ever-compare-refresh">
3
+ <path d="M409.6,0c-9.426,0-17.067,7.641-17.067,17.067v62.344C304.667-5.656,164.478-3.386,79.411,84.479
4
+ c-40.09,41.409-62.455,96.818-62.344,154.454c0,9.426,7.641,17.067,17.067,17.067S51.2,248.359,51.2,238.933
5
+ c0.021-103.682,84.088-187.717,187.771-187.696c52.657,0.01,102.888,22.135,138.442,60.976l-75.605,25.207
6
+ c-8.954,2.979-13.799,12.652-10.82,21.606s12.652,13.799,21.606,10.82l102.4-34.133c6.99-2.328,11.697-8.88,11.674-16.247v-102.4
7
+ C426.667,7.641,419.026,0,409.6,0z"/>
8
+ <path d="M443.733,221.867c-9.426,0-17.067,7.641-17.067,17.067c-0.021,103.682-84.088,187.717-187.771,187.696
9
+ c-52.657-0.01-102.888-22.135-138.442-60.976l75.605-25.207c8.954-2.979,13.799-12.652,10.82-21.606
10
+ c-2.979-8.954-12.652-13.799-21.606-10.82l-102.4,34.133c-6.99,2.328-11.697,8.88-11.674,16.247v102.4
11
+ c0,9.426,7.641,17.067,17.067,17.067s17.067-7.641,17.067-17.067v-62.345c87.866,85.067,228.056,82.798,313.122-5.068
12
+ c40.09-41.409,62.455-96.818,62.344-154.454C460.8,229.508,453.159,221.867,443.733,221.867z"/>
13
+ </g>
14
+ <g class="ever-compare-check">
15
+ <path d="M238.933,0C106.974,0,0,106.974,0,238.933s106.974,238.933,238.933,238.933s238.933-106.974,238.933-238.933
16
+ C477.726,107.033,370.834,0.141,238.933,0z M238.933,443.733c-113.108,0-204.8-91.692-204.8-204.8s91.692-204.8,204.8-204.8
17
+ s204.8,91.692,204.8,204.8C443.611,351.991,351.991,443.611,238.933,443.733z"/>
18
+ <path d="M370.046,141.534c-6.614-6.388-17.099-6.388-23.712,0v0L187.733,300.134l-56.201-56.201
19
+ c-6.548-6.78-17.353-6.967-24.132-0.419c-6.78,6.548-6.967,17.353-0.419,24.132c0.137,0.142,0.277,0.282,0.419,0.419
20
+ l68.267,68.267c6.664,6.663,17.468,6.663,24.132,0l170.667-170.667C377.014,158.886,376.826,148.082,370.046,141.534z"/>
21
+ </g>
22
+ </svg>
includes/modules/compare/assets/images/loading.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 471.701 471.701">
2
+ <g class="ever-compare-refresh">
3
+ <path d="M409.6,0c-9.426,0-17.067,7.641-17.067,17.067v62.344C304.667-5.656,164.478-3.386,79.411,84.479
4
+ c-40.09,41.409-62.455,96.818-62.344,154.454c0,9.426,7.641,17.067,17.067,17.067S51.2,248.359,51.2,238.933
5
+ c0.021-103.682,84.088-187.717,187.771-187.696c52.657,0.01,102.888,22.135,138.442,60.976l-75.605,25.207
6
+ c-8.954,2.979-13.799,12.652-10.82,21.606s12.652,13.799,21.606,10.82l102.4-34.133c6.99-2.328,11.697-8.88,11.674-16.247v-102.4
7
+ C426.667,7.641,419.026,0,409.6,0z"/>
8
+ <path d="M443.733,221.867c-9.426,0-17.067,7.641-17.067,17.067c-0.021,103.682-84.088,187.717-187.771,187.696
9
+ c-52.657-0.01-102.888-22.135-138.442-60.976l75.605-25.207c8.954-2.979,13.799-12.652,10.82-21.606
10
+ c-2.979-8.954-12.652-13.799-21.606-10.82l-102.4,34.133c-6.99,2.328-11.697,8.88-11.674,16.247v102.4
11
+ c0,9.426,7.641,17.067,17.067,17.067s17.067-7.641,17.067-17.067v-62.345c87.866,85.067,228.056,82.798,313.122-5.068
12
+ c40.09-41.409,62.455-96.818,62.344-154.454C460.8,229.508,453.159,221.867,443.733,221.867z"/>
13
+ </g>
14
+ </svg>
includes/modules/compare/assets/js/admin.js ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($){
2
+ "use strict";
3
+
4
+ var EverCompareAdmin = {
5
+
6
+ /**
7
+ * [init]
8
+ * @return @return {[void]} Initial Function
9
+ */
10
+ init: function(){
11
+ this.MenuActive();
12
+
13
+ /**
14
+ * For save value
15
+ */
16
+ this.HideShowField( '.depend_shop_btn_position_use_shortcode', evercompare.option_data['shop_btn_position'], 'use_shortcode' );
17
+ this.HideShowField( '.depend_shop_btn_position_custom_hook', evercompare.option_data['shop_btn_position'], 'custom_position' );
18
+
19
+ this.HideShowField( '.depend_product_btn_position_use_shortcode', evercompare.option_data['product_btn_position'], 'use_shortcode' );
20
+ this.HideShowField( '.depend_product_btn_position_custom_hook', evercompare.option_data['product_btn_position'], 'custom_position' );
21
+
22
+ this.HideShowField( '.depend_button_icon_type_custom', evercompare.option_data['button_icon_type'], 'custom' );
23
+ this.HideShowField( '.depend_added_button_icon_type_custom', evercompare.option_data['added_button_icon_type'], 'custom' );
24
+
25
+ this.HideShowField( '.depend_enable_shareable_link', evercompare.option_data['enable_shareable_link'], 'on' );
26
+
27
+ this.HideShowField( '.depend_button_custom_style', evercompare.option_data['button_style'], 'custom' );
28
+ this.HideShowField( '.depend_table_custom_style', evercompare.option_data['table_style'], 'custom' );
29
+
30
+ /**
31
+ * After Change
32
+ */
33
+ this.ConditionField( '.shop_btn_position select', '.depend_shop_btn_position_use_shortcode', 'use_shortcode' );
34
+ this.ConditionField( '.shop_btn_position select', '.depend_shop_btn_position_custom_hook', 'custom_position' );
35
+
36
+ this.ConditionField( '.product_btn_position select', '.depend_product_btn_position_use_shortcode', 'use_shortcode' );
37
+ this.ConditionField( '.product_btn_position select', '.depend_product_btn_position_custom_hook', 'custom_position' );
38
+
39
+ this.ConditionField( '.button_icon_type select', '.depend_button_icon_type_custom', 'custom' );
40
+ this.ConditionField( '.added_button_icon_type select', '.depend_added_button_icon_type_custom', 'custom' );
41
+
42
+ this.ConditionField( '.enable_shareable_link .checkbox', '.depend_enable_shareable_link', 'on', 'radio' );
43
+
44
+ this.ConditionField( '.button_style select', '.depend_button_custom_style', 'custom' );
45
+ this.ConditionField( '.table_style select', '.depend_table_custom_style', 'custom' );
46
+
47
+ },
48
+
49
+ /**
50
+ * [MenuActive] Active first menu item
51
+ */
52
+ MenuActive: function(){
53
+ if ( typeof evercompare.is_settings != "undefined" && evercompare.is_settings == 1 ){
54
+ $('.toplevel_page_evercompare .wp-first-item').addClass('current');
55
+ }
56
+ },
57
+
58
+ /**
59
+ * [ConditionField]
60
+ * @param {[String]} controller
61
+ * @param {[String]} field
62
+ * @param {[String]} condition_value
63
+ * @param {String} fieldtype
64
+ */
65
+ ConditionField: function( controller, field, condition_value, fieldtype = 'select' ){
66
+ $( controller ).on('change',function(){
67
+ var change_value = '';
68
+ if( fieldtype === 'radio' ){
69
+ if( $(this).is(":checked") ){
70
+ change_value = $(this).val();
71
+ }
72
+ }else{
73
+ change_value = $(this).val();
74
+ }
75
+ EverCompareAdmin.HideShowField( field, change_value, condition_value );
76
+ });
77
+
78
+ },
79
+
80
+ /**
81
+ * [HideShowField]
82
+ * @param {[String]} field
83
+ * @param {[String]} current_value
84
+ * @param {[String]} condition_value
85
+ */
86
+ HideShowField: function( field, current_value, condition_value ){
87
+ if( current_value === condition_value ){
88
+ $( field ).show();
89
+ }else{
90
+ $( field ).hide();
91
+ }
92
+ },
93
+
94
+ };
95
+
96
+ $( document ).ready( function() {
97
+ EverCompareAdmin.init();
98
+ });
99
+
100
+ })(jQuery);
includes/modules/compare/assets/js/frontend.js ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($){
2
+ "use strict";
3
+
4
+ var $body = $('body'),
5
+ $popup = $('.htcompare-popup');
6
+
7
+ // Add product in compare table
8
+ $body.on('click', 'a.htcompare-btn', function (e) {
9
+ var $this = $(this),
10
+ id = $this.data('product_id'),
11
+ addedText = $this.data('added-text');
12
+
13
+ if( evercompare.popup === 'yes' ){
14
+ e.preventDefault();
15
+ if ( $this.hasClass('added') ) {
16
+ $body.find('.htcompare-popup').addClass('open');
17
+ return true;
18
+ }
19
+ }else{
20
+ if ( $this.hasClass('added') ) return true;
21
+ }
22
+
23
+ e.preventDefault();
24
+
25
+ $this.addClass('loading');
26
+
27
+ $.ajax({
28
+ url: evercompare.ajaxurl,
29
+ data: {
30
+ action: 'ever_compare_add_to_compare',
31
+ id: id,
32
+ },
33
+ dataType: 'json',
34
+ method: 'GET',
35
+ success: function ( response ) {
36
+ if ( response.table ) {
37
+ updateCompareData( response );
38
+ $popup.addClass('open');
39
+ } else {
40
+ console.log( 'Something wrong loading compare data' );
41
+ }
42
+ },
43
+ error: function ( data ) {
44
+ console.log('Something wrong with AJAX response.');
45
+ },
46
+ complete: function () {
47
+ $this.removeClass('loading').addClass('added');
48
+ $this.html('<span class="htcompare-btn-text">'+addedText+'</span>');
49
+ },
50
+ });
51
+
52
+ });
53
+
54
+ // Remove data from compare table
55
+ $body.on('click', 'a.htcompare-remove', function (e) {
56
+ var $table = $('.htcompare-table');
57
+
58
+ e.preventDefault();
59
+ var $this = $(this),
60
+ id = $this.data('product_id');
61
+
62
+ $table.addClass('loading');
63
+ $this.addClass('loading');
64
+
65
+ jQuery.ajax({
66
+ url: evercompare.ajaxurl,
67
+ data: {
68
+ action: 'ever_compare_remove_from_compare',
69
+ id: id,
70
+ },
71
+ dataType: 'json',
72
+ method: 'GET',
73
+ success: function (response) {
74
+ if (response.table) {
75
+ updateCompareData(response);
76
+ } else {
77
+ console.log( 'Something wrong loading compare data' );
78
+ }
79
+ },
80
+ error: function (data) {
81
+ console.log('Something wrong with AJAX response.');
82
+ },
83
+ complete: function () {
84
+ $table.removeClass('loading');
85
+ $this.addClass('loading');
86
+ },
87
+ });
88
+
89
+ });
90
+
91
+ // Update table HTML
92
+ function updateCompareData( data ) {
93
+ if ( $('.htcompare-table').length > 0 ) {
94
+ $('.htcompare-table').replaceWith( data.table );
95
+ $('.evercompare-copy-link').on('click',function(e){
96
+ evercompareCopyToClipboard( $(this).closest('.ever-compare-shareable-link').find('.evercompare-share-link') , this );
97
+ });
98
+ }
99
+ }
100
+
101
+ // Close popup
102
+ $body.on('click','.htcompare-popup-close', function(e){
103
+ $popup.removeClass('open');
104
+ });
105
+
106
+ // Copy Shareable link
107
+ $('.evercompare-copy-link').on('click',function(e){
108
+ evercompareCopyToClipboard( $(this).closest('.ever-compare-shareable-link').find('.evercompare-share-link') , this );
109
+ });
110
+ function evercompareCopyToClipboard( element, button ) {
111
+ var $tempdata = $("<input>");
112
+ $("body").append($tempdata);
113
+ $tempdata.val($(element).text()).select();
114
+ document.execCommand("copy");
115
+ $tempdata.remove();
116
+ $(button).text( $(button).data('copytext') );
117
+ setTimeout(function() {
118
+ $( button ).text( $(button).data('btntext') );
119
+ }, 1000);
120
+ }
121
+
122
+ })(jQuery);
includes/modules/compare/assets/js/frontend.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){"use strict";var a=e("body"),o=e(".htcompare-popup");function t(a){e(".htcompare-table").length>0&&(e(".htcompare-table").replaceWith(a.table),e(".evercompare-copy-link").on("click",function(a){n(e(this).closest(".ever-compare-shareable-link").find(".evercompare-share-link"),this)}))}function n(a,o){var t=e("<input>");e("body").append(t),t.val(e(a).text()).select(),document.execCommand("copy"),t.remove(),e(o).text(e(o).data("copytext")),setTimeout(function(){e(o).text(e(o).data("btntext"))},1e3)}a.on("click","a.htcompare-btn",function(n){var r=e(this),c=r.data("product_id"),s=r.data("added-text");if("yes"===evercompare.popup){if(n.preventDefault(),r.hasClass("added"))return a.find(".htcompare-popup").addClass("open"),!0}else if(r.hasClass("added"))return!0;n.preventDefault(),r.addClass("loading"),e.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_add_to_compare",id:c},dataType:"json",method:"GET",success:function(e){e.table?(t(e),o.addClass("open")):console.log("Something wrong loading compare data")},error:function(e){console.log("Something wrong with AJAX response.")},complete:function(){r.removeClass("loading").addClass("added"),r.html('<span class="htcompare-btn-text">'+s+"</span>")}})}),a.on("click","a.htcompare-remove",function(a){var o=e(".htcompare-table");a.preventDefault();var n=e(this),r=n.data("product_id");o.addClass("loading"),n.addClass("loading"),jQuery.ajax({url:evercompare.ajaxurl,data:{action:"ever_compare_remove_from_compare",id:r},dataType:"json",method:"GET",success:function(e){e.table?t(e):console.log("Something wrong loading compare data")},error:function(e){console.log("Something wrong with AJAX response.")},complete:function(){o.removeClass("loading"),n.addClass("loading")}})}),a.on("click",".htcompare-popup-close",function(e){o.removeClass("open")}),e(".evercompare-copy-link").on("click",function(a){n(e(this).closest(".ever-compare-shareable-link").find(".evercompare-share-link"),this)})}(jQuery);
includes/modules/compare/includes/classes/Admin.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare;
3
+
4
+ /**
5
+ * Admin handlers class
6
+ */
7
+ class Admin {
8
+
9
+ /**
10
+ * [$_instance]
11
+ * @var null
12
+ */
13
+ private static $_instance = null;
14
+
15
+ /**
16
+ * [instance] Initializes a singleton instance
17
+ * @return [Admin]
18
+ */
19
+ public static function instance() {
20
+ if ( is_null( self::$_instance ) ) {
21
+ self::$_instance = new self();
22
+ }
23
+ return self::$_instance;
24
+ }
25
+
26
+ /**
27
+ * Initialize the class
28
+ */
29
+ private function __construct() {
30
+ require_once( __DIR__. '/Admin/Dashboard.php' );
31
+ Admin\Dashboard::instance();
32
+ }
33
+
34
+ }
includes/modules/compare/includes/classes/Admin/Admin_Fields.php ADDED
@@ -0,0 +1,652 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare\Admin;
3
+ /**
4
+ * Admin Page Fields handlers class
5
+ */
6
+ class Admin_Fields {
7
+
8
+ private $settings_api;
9
+
10
+ /**
11
+ * [$_instance]
12
+ * @var null
13
+ */
14
+ private static $_instance = null;
15
+
16
+ /**
17
+ * [instance] Initializes a singleton instance
18
+ * @return [Admin]
19
+ */
20
+ public static function instance() {
21
+ if ( is_null( self::$_instance ) ) {
22
+ self::$_instance = new self();
23
+ }
24
+ return self::$_instance;
25
+ }
26
+
27
+ function __construct() {
28
+ require_once( WOOLENTOR_ADDONS_PL_PATH .'includes/admin/include/settings_field_manager_default.php' );
29
+ $this->settings_api = new \WooLentor_Settings_Field_Manager_Default();
30
+ add_action( 'admin_init', [ $this, 'admin_init' ] );
31
+ }
32
+
33
+ public function admin_init() {
34
+
35
+ //set the settings
36
+ $this->settings_api->set_sections( $this->get_settings_sections() );
37
+ $this->settings_api->set_fields( $this->fields_settings() );
38
+
39
+ //initialize settings
40
+ $this->settings_api->admin_init();
41
+ }
42
+
43
+ // Options page Section register
44
+ public function get_settings_sections() {
45
+ $sections = array(
46
+
47
+ array(
48
+ 'id' => 'ever_compare_settings_tabs',
49
+ 'title' => esc_html__( 'Button Settings', 'ever-compare' ),
50
+ ),
51
+
52
+ array(
53
+ 'id' => 'ever_compare_table_settings_tabs',
54
+ 'title' => esc_html__( 'Table Settings', 'ever-compare' )
55
+ ),
56
+ array(
57
+ 'id' => 'ever_compare_style_tabs',
58
+ 'title' => esc_html__( 'Style Settings', 'ever-compare' ),
59
+ )
60
+
61
+ );
62
+ return $sections;
63
+ }
64
+
65
+ // Options page field register
66
+ protected function fields_settings() {
67
+
68
+ $settings_fields = array(
69
+
70
+ 'ever_compare_settings_tabs' => array(
71
+
72
+ array(
73
+ 'name' => 'btn_show_shoppage',
74
+ 'label' => __( 'Show button in product list page', 'ever-compare' ),
75
+ 'desc' => __( 'Show compare button in product list page.', 'ever-compare' ),
76
+ 'type' => 'checkbox',
77
+ 'default' => 'off',
78
+ ),
79
+
80
+ array(
81
+ 'name' => 'btn_show_productpage',
82
+ 'label' => __( 'Show button in single product page', 'ever-compare' ),
83
+ 'desc' => __( 'Show compare button in single product page.', 'ever-compare' ),
84
+ 'type' => 'checkbox',
85
+ 'default' => 'on',
86
+ ),
87
+
88
+ array(
89
+ 'name' => 'shop_btn_position',
90
+ 'label' => __( 'Shop page button position', 'ever-compare' ),
91
+ 'desc' => __( 'You can manage compare button position in product list page.', 'ever-compare' ),
92
+ 'type' => 'select',
93
+ 'default' => 'after_cart_btn',
94
+ 'options' => [
95
+ 'before_cart_btn' => __( 'Before Add To Cart', 'ever-compare' ),
96
+ 'after_cart_btn' => __( 'After Add To Cart', 'ever-compare' ),
97
+ 'top_thumbnail' => __( 'Top On Image', 'ever-compare' ),
98
+ 'use_shortcode' => __( 'Use Shortcode', 'ever-compare' ),
99
+ 'custom_position' => __( 'Custom Position', 'ever-compare' ),
100
+ ],
101
+ ),
102
+
103
+ array(
104
+ 'name' => 'shop_use_shortcode_message',
105
+ 'headding'=> wp_kses_post('<code>[evercompare_button]</code> Use this shortcode into your theme/child theme to place the compare button.'),
106
+ 'type' => 'title',
107
+ 'size' => 'margin_0 regular',
108
+ 'class' => 'depend_shop_btn_position_use_shortcode element_section_title_area message-info',
109
+ ),
110
+
111
+ array(
112
+ 'name' => 'shop_custom_hook_message',
113
+ 'headding'=> esc_html__( 'Some themes remove the above positions. In that case, custom position is useful. Here you can place the custom/default hook name & priority to inject & adjust the compare button for the product loop.', 'ever-compare' ),
114
+ 'type' => 'title',
115
+ 'size' => 'margin_0 regular',
116
+ 'class' => 'depend_shop_btn_position_custom_hook element_section_title_area message-info',
117
+ ),
118
+
119
+ array(
120
+ 'name' => 'shop_custom_hook_name',
121
+ 'label' => __( 'Hook name', 'ever-compare' ),
122
+ 'desc' => __( 'e.g: woocommerce_after_shop_loop_item_title', 'ever-compare' ),
123
+ 'type' => 'text',
124
+ 'class' => 'depend_shop_btn_position_custom_hook'
125
+ ),
126
+
127
+ array(
128
+ 'name' => 'shop_custom_hook_priority',
129
+ 'label' => __( 'Hook priority', 'ever-compare' ),
130
+ 'desc' => __( 'Default: 10', 'ever-compare' ),
131
+ 'type' => 'text',
132
+ 'class' => 'depend_shop_btn_position_custom_hook'
133
+ ),
134
+
135
+ array(
136
+ 'name' => 'product_btn_position',
137
+ 'label' => __( 'Product page button position', 'ever-compare' ),
138
+ 'desc' => __( 'You can manage compare button position in single product page.', 'ever-compare' ),
139
+ 'type' => 'select',
140
+ 'default' => 'after_cart_btn',
141
+ 'options' => [
142
+ 'before_cart_btn' => __( 'Before Add To Cart', 'ever-compare' ),
143
+ 'after_cart_btn' => __( 'After Add To Cart', 'ever-compare' ),
144
+ 'after_thumbnail' => __( 'After Image', 'ever-compare' ),
145
+ 'after_summary' => __( 'After Summary', 'ever-compare' ),
146
+ 'use_shortcode' => __( 'Use Shortcode', 'ever-compare' ),
147
+ 'custom_position' => __( 'Custom Position', 'ever-compare' ),
148
+ ],
149
+ ),
150
+
151
+ array(
152
+ 'name' => 'product_use_shortcode_message',
153
+ 'headding'=> wp_kses_post('<code>[evercompare_button]</code> Use this shortcode into your theme/child theme to place the compare button.'),
154
+ 'type' => 'title',
155
+ 'size' => 'margin_0 regular',
156
+ 'class' => 'depend_product_btn_position_use_shortcode element_section_title_area message-info',
157
+ ),
158
+
159
+ array(
160
+ 'name' => 'product_custom_hook_message',
161
+ 'headding'=> esc_html__( 'Some themes remove the above positions. In that case, custom position is useful. Here you can place the custom/default hook name & priority to inject & adjust the compare button for the single product page.', 'ever-compare' ),
162
+ 'type' => 'title',
163
+ 'size' => 'margin_0 regular',
164
+ 'class' => 'depend_product_btn_position_custom_hook element_section_title_area message-info',
165
+ ),
166
+
167
+ array(
168
+ 'name' => 'product_custom_hook_name',
169
+ 'label' => __( 'Hook name', 'ever-compare' ),
170
+ 'desc' => __( 'e.g: woocommerce_after_single_product_summary', 'ever-compare' ),
171
+ 'type' => 'text',
172
+ 'class' => 'depend_product_btn_position_custom_hook'
173
+ ),
174
+
175
+ array(
176
+ 'name' => 'product_custom_hook_priority',
177
+ 'label' => __( 'Hook priority', 'ever-compare' ),
178
+ 'desc' => __( 'Default: 10', 'ever-compare' ),
179
+ 'type' => 'text',
180
+ 'class' => 'depend_product_btn_position_custom_hook'
181
+ ),
182
+
183
+ array(
184
+ 'name' => 'open_popup',
185
+ 'label' => __( 'Open popup', 'ever-compare' ),
186
+ 'type' => 'checkbox',
187
+ 'default' => 'on',
188
+ 'desc' => __( 'You can manage the popup window from here.', 'ever-compare' ),
189
+ ),
190
+
191
+ array(
192
+ 'name' => 'button_text',
193
+ 'label' => __( 'Button text', 'ever-compare' ),
194
+ 'desc' => __( 'Enter your compare button text.', 'ever-compare' ),
195
+ 'type' => 'text',
196
+ 'default' => __( 'Compare', 'ever-compare' ),
197
+ 'placeholder' => __( 'Compare', 'ever-compare' ),
198
+ ),
199
+
200
+ array(
201
+ 'name' => 'added_button_text',
202
+ 'label' => __( 'Added button text', 'ever-compare' ),
203
+ 'desc' => __( 'Enter your compare added button text.', 'ever-compare' ),
204
+ 'type' => 'text',
205
+ 'default' => __( 'Added', 'ever-compare' ),
206
+ 'placeholder' => __( 'Added', 'ever-compare' ),
207
+ ),
208
+
209
+ array(
210
+ 'name' => 'button_icon_type',
211
+ 'label' => esc_html__( 'Button icon type', 'ever-compare' ),
212
+ 'desc' => esc_html__( 'Choose an icon type for the compare button from here.', 'ever-compare' ),
213
+ 'type' => 'select',
214
+ 'default' => 'default',
215
+ 'options' => [
216
+ 'none' => esc_html__( 'None', 'ever-compare' ),
217
+ 'default' => esc_html__( 'Default', 'ever-compare' ),
218
+ 'custom' => esc_html__( 'Custom', 'ever-compare' ),
219
+ ]
220
+ ),
221
+
222
+ array(
223
+ 'name' => 'button_custom_icon',
224
+ 'label' => esc_html__( 'Button custom icon', 'ever-compare' ),
225
+ 'type' => 'image_upload',
226
+ 'options' => [
227
+ 'button_label' => esc_html__( 'Upload', 'ever-compare' ),
228
+ 'button_remove_label' => esc_html__( 'Remove', 'ever-compare' ),
229
+ ],
230
+ 'desc' => esc_html__( 'Upload you custom icon from here.', 'ever-compare' ),
231
+ 'class' => 'depend_button_icon_type_custom',
232
+ ),
233
+
234
+ array(
235
+ 'name' => 'added_button_icon_type',
236
+ 'label' => __( 'Added button icon type', 'ever-compare' ),
237
+ 'desc' => __( 'Choose an icon for the compare button from here.', 'ever-compare' ),
238
+ 'type' => 'select',
239
+ 'default' => 'default',
240
+ 'options' => [
241
+ 'none' => esc_html__( 'None', 'ever-compare' ),
242
+ 'default' => esc_html__( 'Default', 'ever-compare' ),
243
+ 'custom' => esc_html__( 'Custom', 'ever-compare' ),
244
+ ]
245
+ ),
246
+
247
+ array(
248
+ 'name' => 'added_button_custom_icon',
249
+ 'label' => __( 'Added button custom icon', 'ever-compare' ),
250
+ 'type' => 'image_upload',
251
+ 'options' => [
252
+ 'button_label' => esc_html__( 'Upload', 'ever-compare' ),
253
+ 'button_remove_label' => esc_html__( 'Remove', 'ever-compare' ),
254
+ ],
255
+ 'class' => 'depend_added_button_icon_type_custom',
256
+ ),
257
+
258
+ ),
259
+
260
+ 'ever_compare_table_settings_tabs' => array(
261
+
262
+ array(
263
+ 'name' => 'compare_page',
264
+ 'label' => __( 'Compare page', 'ever-compare' ),
265
+ 'desc' => wp_kses_post('Select a compare page for compare table. It should contain the shortcode <code>[evercompare_table]</code>'),
266
+ 'type' => 'select',
267
+ 'default' => '0',
268
+ 'options' => ever_compare_get_post_list()
269
+ ),
270
+
271
+ array(
272
+ 'name' => 'enable_shareable_link',
273
+ 'label' => __( 'Enable shareable link', 'ever-compare' ),
274
+ 'type' => 'checkbox',
275
+ 'default' => 'off',
276
+ 'desc' => __( 'If you enable this you can easily share your compare page link with specific products.', 'ever-compare' ),
277
+ ),
278
+
279
+ array(
280
+ 'name' => 'linkshare_btn_pos',
281
+ 'label' => __( 'Share link button position', 'ever-compare' ),
282
+ 'type' => 'select',
283
+ 'default' => 'right',
284
+ 'options' => [
285
+ 'left' => __('Left','ever-compare'),
286
+ 'center' => __('Center','ever-compare'),
287
+ 'right' => __('Right','ever-compare')
288
+ ],
289
+ 'class' => 'depend_enable_shareable_link'
290
+ ),
291
+
292
+ array(
293
+ 'name' => 'shareable_link_button_text',
294
+ 'label' => __( 'Share link button text', 'ever-compare' ),
295
+ 'placeholder' => __( 'Copy shareable link', 'ever-compare' ),
296
+ 'type' => 'text',
297
+ 'class' => 'depend_enable_shareable_link'
298
+ ),
299
+
300
+ array(
301
+ 'name' => 'shareable_link_after_button_text',
302
+ 'label' => __( 'Text to show after link is copied', 'ever-compare' ),
303
+ 'placeholder' => __( 'Copied', 'ever-compare' ),
304
+ 'type' => 'text',
305
+ 'class' => 'depend_enable_shareable_link'
306
+ ),
307
+
308
+ array(
309
+ 'name' => 'limit',
310
+ 'label' => esc_html__( 'Limit', 'quickswish' ),
311
+ 'desc' => esc_html__( 'You can manage your maximum compare quantity from here.', 'quickswish' ),
312
+ 'type' => 'number',
313
+ 'min' => 1,
314
+ 'max' => 1500,
315
+ 'step' => 1,
316
+ 'default' => 10,
317
+ 'sanitize_callback' => 'floatval',
318
+ ),
319
+
320
+ array(
321
+ 'name' => 'show_fields',
322
+ 'label' => __('Show fields in table', 'ever-compare'),
323
+ 'desc' => __('Choose which fields should be presented on the product compare page with table.', 'ever-compare'),
324
+ 'type' => 'multicheckshort',
325
+ 'options' => ever_compare_get_available_attributes(),
326
+ 'default' => [
327
+ 'title' => esc_html__( 'title', 'ever-compare' ),
328
+ 'ratting' => esc_html__( 'ratting', 'ever-compare' ),
329
+ 'price' => esc_html__( 'price', 'ever-compare' ),
330
+ 'add_to_cart' => esc_html__( 'add_to_cart', 'ever-compare' ),
331
+ 'description' => esc_html__( 'description', 'ever-compare' ),
332
+ 'availability' => esc_html__( 'availability', 'ever-compare' ),
333
+ 'sku' => esc_html__( 'sku', 'ever-compare' ),
334
+ 'weight' => esc_html__( 'weight', 'ever-compare' ),
335
+ 'dimensions' => esc_html__( 'dimensions', 'ever-compare' ),
336
+ ],
337
+ ),
338
+
339
+ array(
340
+ 'name' => 'table_heading_section_title',
341
+ 'headding'=> esc_html__( 'Custom heading', 'ever-compare' ),
342
+ 'type' => 'title',
343
+ 'size' => 'margin_0 regular',
344
+ 'class' => 'element_section_title_area',
345
+ ),
346
+
347
+ array(
348
+ 'name' => 'table_heading',
349
+ 'label' => __( 'Fields heading text', 'ever-compare' ),
350
+ 'desc' => __( 'You can change heading text from here.', 'ever-compare' ),
351
+ 'type' => 'multitext',
352
+ 'options' => ever_compare_table_heading()
353
+ ),
354
+
355
+ array(
356
+ 'name' => 'reached_max_limit_message',
357
+ 'label' => __('Reached maximum limit message', 'ever-compare'),
358
+ 'desc' => __('You can manage message for maximum product added in the compare table.', 'ever-compare'),
359
+ 'type' => 'textarea'
360
+ ),
361
+
362
+ array(
363
+ 'name' => 'empty_table_text',
364
+ 'label' => __('Empty compare page text', 'ever-compare'),
365
+ 'desc' => __('Text will be displayed if user don\'t add any products to compare', 'ever-compare'),
366
+ 'type' => 'textarea'
367
+ ),
368
+
369
+ array(
370
+ 'name' => 'shop_button_text',
371
+ 'label' => __( 'Return to shop button text', 'ever-compare' ),
372
+ 'desc' => __( 'Enter your return to shop button text.', 'ever-compare' ),
373
+ 'type' => 'text',
374
+ 'default' => __( 'Return to shop', 'ever-compare' ),
375
+ 'placeholder' => __( 'Return to shop', 'ever-compare' ),
376
+ ),
377
+
378
+ array(
379
+ 'name' => 'image_size',
380
+ 'label' => __( 'Image size', 'ever-compare' ),
381
+ 'desc' => __( 'Enter your required image size.', 'ever-compare' ),
382
+ 'type' => 'multitext',
383
+ 'options' =>[
384
+ 'width' => esc_html__( 'Width', 'ever-compare' ),
385
+ 'height' => esc_html__( 'Height', 'ever-compare' ),
386
+ ],
387
+ 'default' => [
388
+ 'width' => 300,
389
+ 'height' => 300,
390
+ ],
391
+ ),
392
+
393
+ array(
394
+ 'name' => 'hard_crop',
395
+ 'label' => __( 'Image Hard Crop', 'ever-compare' ),
396
+ 'type' => 'checkbox',
397
+ 'default' => 'on',
398
+ ),
399
+
400
+ ),
401
+
402
+ 'ever_compare_style_tabs' => array(
403
+
404
+ array(
405
+ 'name' => 'button_style',
406
+ 'label' => esc_html__( 'Button style', 'ever-compare' ),
407
+ 'desc' => esc_html__( 'Choose a style for the compare button from here.', 'ever-compare' ),
408
+ 'type' => 'select',
409
+ 'default' => 'theme',
410
+ 'options' => [
411
+ 'default' => esc_html__( 'Default', 'ever-compare' ),
412
+ 'theme' => esc_html__( 'Theme', 'ever-compare' ),
413
+ 'custom' => esc_html__( 'Custom', 'ever-compare' ),
414
+ ]
415
+ ),
416
+
417
+ array(
418
+ 'name' => 'table_style',
419
+ 'label' => esc_html__( 'Table style', 'ever-compare' ),
420
+ 'desc' => esc_html__( 'Choose a table style from here.', 'ever-compare' ),
421
+ 'type' => 'select',
422
+ 'default' => 'default',
423
+ 'options' => [
424
+ 'default' => esc_html__( 'Default', 'ever-compare' ),
425
+ 'custom' => esc_html__( 'Custom', 'ever-compare' ),
426
+ ]
427
+ ),
428
+
429
+ array(
430
+ 'name' => 'button_custom_style_area_title',
431
+ 'headding'=> esc_html__( 'Button custom style', 'ever-compare' ),
432
+ 'type' => 'title',
433
+ 'size' => 'margin_0 regular',
434
+ 'class' => 'depend_button_custom_style element_section_title_area',
435
+ ),
436
+
437
+ array(
438
+ 'name' => 'button_color',
439
+ 'label' => esc_html__( 'Color', 'ever-compare' ),
440
+ 'desc' => wp_kses_post( 'Set the color of the button.', 'ever-compare' ),
441
+ 'type' => 'color',
442
+ 'class' => 'depend_button_custom_style',
443
+ ),
444
+
445
+ array(
446
+ 'name' => 'button_hover_color',
447
+ 'label' => esc_html__( 'Hover Color', 'ever-compare' ),
448
+ 'desc' => wp_kses_post( 'Set the hover color of the button.', 'ever-compare' ),
449
+ 'type' => 'color',
450
+ 'class' => 'depend_button_custom_style',
451
+ ),
452
+
453
+ array(
454
+ 'name' => 'background_color',
455
+ 'label' => esc_html__( 'Background Color', 'ever-compare' ),
456
+ 'desc' => wp_kses_post( 'Set the background color of the button.', 'ever-compare' ),
457
+ 'type' => 'color',
458
+ 'class' => 'depend_button_custom_style',
459
+ ),
460
+
461
+ array(
462
+ 'name' => 'hover_background_color',
463
+ 'label' => esc_html__( 'Hover Background Color', 'ever-compare' ),
464
+ 'desc' => wp_kses_post( 'Set the hover background color of the button.', 'ever-compare' ),
465
+ 'type' => 'color',
466
+ 'class' => 'depend_button_custom_style',
467
+ ),
468
+
469
+ array(
470
+ 'name' => 'button_custom_padding',
471
+ 'label' => __( 'Padding', 'ever-compare' ),
472
+ 'type' => 'dimensions',
473
+ 'options' => [
474
+ 'top' => esc_html__( 'Top', 'ever-compare' ),
475
+ 'right' => esc_html__( 'Right', 'ever-compare' ),
476
+ 'bottom'=> esc_html__( 'Bottom', 'ever-compare' ),
477
+ 'left' => esc_html__( 'Left', 'ever-compare' ),
478
+ 'unit' => esc_html__( 'Unit', 'ever-compare' ),
479
+ ],
480
+ 'class' => 'depend_button_custom_style',
481
+ ),
482
+
483
+ array(
484
+ 'name' => 'button_custom_margin',
485
+ 'label' => __( 'Margin', 'ever-compare' ),
486
+ 'type' => 'dimensions',
487
+ 'options' => [
488
+ 'top' => esc_html__( 'Top', 'ever-compare' ),
489
+ 'right' => esc_html__( 'Right', 'ever-compare' ),
490
+ 'bottom'=> esc_html__( 'Bottom', 'ever-compare' ),
491
+ 'left' => esc_html__( 'Left', 'ever-compare' ),
492
+ 'unit' => esc_html__( 'Unit', 'ever-compare' ),
493
+ ],
494
+ 'class' => 'depend_button_custom_style',
495
+ ),
496
+
497
+ array(
498
+ 'name' => 'button_custom_border',
499
+ 'label' => __( 'Border width', 'ever-compare' ),
500
+ 'type' => 'dimensions',
501
+ 'options' => [
502
+ 'top' => esc_html__( 'Top', 'ever-compare' ),
503
+ 'right' => esc_html__( 'Right', 'ever-compare' ),
504
+ 'bottom'=> esc_html__( 'Bottom', 'ever-compare' ),
505
+ 'left' => esc_html__( 'Left', 'ever-compare' ),
506
+ 'unit' => esc_html__( 'Unit', 'ever-compare' ),
507
+ ],
508
+ 'class' => 'depend_button_custom_style',
509
+ ),
510
+ array(
511
+ 'name' => 'button_custom_border_color',
512
+ 'label' => esc_html__( 'Border Color', 'ever-compare' ),
513
+ 'desc' => wp_kses_post( 'Set the button color of the button.', 'ever-compare' ),
514
+ 'type' => 'color',
515
+ 'class' => 'depend_button_custom_style',
516
+ ),
517
+
518
+ array(
519
+ 'name' => 'button_custom_border_radius',
520
+ 'label' => __( 'Border Radius', 'ever-compare' ),
521
+ 'type' => 'dimensions',
522
+ 'options' => [
523
+ 'top' => esc_html__( 'Top', 'ever-compare' ),
524
+ 'right' => esc_html__( 'Right', 'ever-compare' ),
525
+ 'bottom'=> esc_html__( 'Bottom', 'ever-compare' ),
526
+ 'left' => esc_html__( 'Left', 'ever-compare' ),
527
+ 'unit' => esc_html__( 'Unit', 'ever-compare' ),
528
+ ],
529
+ 'class' => 'depend_button_custom_style',
530
+ ),
531
+
532
+ array(
533
+ 'name' => 'table_custom_style_area_title',
534
+ 'headding'=> esc_html__( 'Table custom style', 'ever-compare' ),
535
+ 'type' => 'title',
536
+ 'size' => 'margin_0 regular',
537
+ 'class' => 'depend_table_custom_style element_section_title_area',
538
+ ),
539
+
540
+ array(
541
+ 'name' => 'table_border_color',
542
+ 'label' => esc_html__( 'Border color', 'ever-compare' ),
543
+ 'desc' => wp_kses_post( 'Set the border color of the table.', 'ever-compare' ),
544
+ 'type' => 'color',
545
+ 'class' => 'depend_table_custom_style',
546
+ ),
547
+
548
+ array(
549
+ 'name' => 'table_column_padding',
550
+ 'label' => __( 'Column Padding', 'ever-compare' ),
551
+ 'type' => 'dimensions',
552
+ 'options' => [
553
+ 'top' => esc_html__( 'Top', 'ever-compare' ),
554
+ 'right' => esc_html__( 'Right', 'ever-compare' ),
555
+ 'bottom'=> esc_html__( 'Bottom', 'ever-compare' ),
556
+ 'left' => esc_html__( 'Left', 'ever-compare' ),
557
+ 'unit' => esc_html__( 'Unit', 'ever-compare' ),
558
+ ],
559
+ 'class' => 'depend_table_custom_style',
560
+ ),
561
+
562
+ array(
563
+ 'name' => 'table_event_color',
564
+ 'label' => esc_html__( 'Column background color (Event)', 'ever-compare' ),
565
+ 'desc' => wp_kses_post( 'Set the background color of the table event column.', 'ever-compare' ),
566
+ 'type' => 'color',
567
+ 'class' => 'depend_table_custom_style',
568
+ ),
569
+
570
+ array(
571
+ 'name' => 'table_odd_color',
572
+ 'label' => esc_html__( 'Column background color (Odd)', 'ever-compare' ),
573
+ 'desc' => wp_kses_post( 'Set the background color of the table odd column.', 'ever-compare' ),
574
+ 'type' => 'color',
575
+ 'class' => 'depend_table_custom_style',
576
+ ),
577
+
578
+ array(
579
+ 'name' => 'table_heading_event_color',
580
+ 'label' => esc_html__( 'Heading color (Event)', 'ever-compare' ),
581
+ 'desc' => wp_kses_post( 'Set the heading color of the table event column.', 'ever-compare' ),
582
+ 'type' => 'color',
583
+ 'class' => 'depend_table_custom_style',
584
+ ),
585
+
586
+ array(
587
+ 'name' => 'table_heading_odd_color',
588
+ 'label' => esc_html__( 'Heading color (Odd)', 'ever-compare' ),
589
+ 'desc' => wp_kses_post( 'Set the heading color of the table odd column.', 'ever-compare' ),
590
+ 'type' => 'color',
591
+ 'class' => 'depend_table_custom_style',
592
+ ),
593
+
594
+ array(
595
+ 'name' => 'table_content_event_color',
596
+ 'label' => esc_html__( 'Content color (Event)', 'ever-compare' ),
597
+ 'desc' => wp_kses_post( 'Set the content color of the table event column.', 'ever-compare' ),
598
+ 'type' => 'color',
599
+ 'class' => 'depend_table_custom_style',
600
+ ),
601
+
602
+ array(
603
+ 'name' => 'table_content_odd_color',
604
+ 'label' => esc_html__( 'Content color (Odd)', 'ever-compare' ),
605
+ 'desc' => wp_kses_post( 'Set the content color of the table odd column.', 'ever-compare' ),
606
+ 'type' => 'color',
607
+ 'class' => 'depend_table_custom_style',
608
+ ),
609
+
610
+ array(
611
+ 'name' => 'table_content_link_color',
612
+ 'label' => esc_html__( 'Content link color', 'ever-compare' ),
613
+ 'desc' => wp_kses_post( 'Set the content link color of the table.', 'ever-compare' ),
614
+ 'type' => 'color',
615
+ 'class' => 'depend_table_custom_style',
616
+ ),
617
+
618
+ array(
619
+ 'name' => 'table_content_link_hover_color',
620
+ 'label' => esc_html__( 'Content link hover color', 'ever-compare' ),
621
+ 'desc' => wp_kses_post( 'Set the content link hover color of the table.', 'ever-compare' ),
622
+ 'type' => 'color',
623
+ 'class' => 'depend_table_custom_style',
624
+ ),
625
+
626
+ ),
627
+
628
+ );
629
+
630
+ return $settings_fields;
631
+ }
632
+
633
+ public function plugin_page() {
634
+ echo '<div class="wrap">';
635
+ echo '<h2>'.esc_html__( 'Compare Settings','ever-compare' ).'</h2>';
636
+ $this->save_message();
637
+ $this->settings_api->show_navigation();
638
+ $this->settings_api->show_forms();
639
+ echo '</div>';
640
+ }
641
+
642
+ public function save_message() {
643
+ if( isset( $_GET['settings-updated'] ) ) {
644
+ ?>
645
+ <div class="updated notice is-dismissible">
646
+ <p><strong><?php esc_html_e('Successfully Settings Saved.', 'ever-compare') ?></strong></p>
647
+ </div>
648
+ <?php
649
+ }
650
+ }
651
+
652
+ }
includes/modules/compare/includes/classes/Admin/Dashboard.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare\Admin;
3
+ /**
4
+ * Dashboard handlers class
5
+ */
6
+ class Dashboard {
7
+
8
+ /**
9
+ * Parent Menu Page Slug
10
+ */
11
+ const MENU_PAGE_SLUG = 'evercompare';
12
+
13
+ /**
14
+ * [$admin_menu_hook] Parent Menu Hook
15
+ * @var string
16
+ */
17
+ static $admin_menu_hook = '';
18
+
19
+ /**
20
+ * [$_instance]
21
+ * @var null
22
+ */
23
+ private static $_instance = null;
24
+
25
+ /**
26
+ * [instance] Initializes a singleton instance
27
+ * @return [Admin]
28
+ */
29
+ public static function instance() {
30
+ if ( is_null( self::$_instance ) ) {
31
+ self::$_instance = new self();
32
+ }
33
+ return self::$_instance;
34
+ }
35
+
36
+ /**
37
+ * Initialize the class
38
+ */
39
+ private function __construct() {
40
+ require_once( __DIR__. '/Admin_Fields.php' );
41
+
42
+ Admin_Fields::instance();
43
+
44
+ add_action( 'admin_menu', [ $this, 'add_menu' ], 220 );
45
+
46
+ // Add a post display state for special EverCompare page.
47
+ add_filter( 'display_post_states', [ $this, 'add_display_post_states' ], 10, 2 );
48
+
49
+
50
+ }
51
+
52
+ /**
53
+ * [add_menu] Admin Menu
54
+ */
55
+ public function add_menu(){
56
+
57
+ self::$admin_menu_hook = add_submenu_page(
58
+ 'woolentor_page',
59
+ esc_html__( 'Compare', 'woolentor' ),
60
+ esc_html__( 'Compare', 'woolentor' ),
61
+ 'manage_options',
62
+ self::MENU_PAGE_SLUG,
63
+ [ $this,'dashboard' ],
64
+ );
65
+
66
+ add_action( 'load-' . self::$admin_menu_hook, [ $this, 'init_hooks'] );
67
+
68
+
69
+ }
70
+
71
+ /**
72
+ * Initialize our hooks for the admin page
73
+ *
74
+ * @return void
75
+ */
76
+ public function init_hooks() {
77
+ add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
78
+ }
79
+
80
+ /**
81
+ * [enqueue_scripts] Add Scripts Base Menu Slug
82
+ * @param [string] $hook
83
+ * @return [void]
84
+ */
85
+ public function enqueue_scripts() {
86
+ wp_enqueue_style( 'evercompare-admin' );
87
+ wp_enqueue_script( 'evercompare-admin' );
88
+ }
89
+
90
+ /**
91
+ * [dashboard] Dashboard plugin page
92
+ * @return [HTML]
93
+ */
94
+ public function dashboard(){
95
+ Admin_Fields::instance()->plugin_page();
96
+ }
97
+
98
+ /**
99
+ * Add a post display state for special WishSuite page in the page list table.
100
+ *
101
+ * @param array $post_states An array of post display states.
102
+ * @param WP_Post $post The current post object.
103
+ */
104
+ public function add_display_post_states( $post_states, $post ){
105
+ if ( (int)woolentor_get_option( 'compare_page', 'ever_compare_table_settings_tabs' ) === $post->ID ) {
106
+ $post_states['evercompare_page_for_compare_table'] = __( 'EverCompare', 'ever-compare' );
107
+ }
108
+ return $post_states;
109
+ }
110
+
111
+
112
+ }
includes/modules/compare/includes/classes/Ajax.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare;
3
+ /**
4
+ * Ajax handlers class
5
+ */
6
+ class Ajax {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [instance] Initializes a singleton instance
16
+ * @return [Ajax]
17
+ */
18
+ public static function instance() {
19
+ if ( is_null( self::$_instance ) ) {
20
+ self::$_instance = new self();
21
+ }
22
+ return self::$_instance;
23
+ }
24
+
25
+ /**
26
+ * Initialize the class
27
+ */
28
+ private function __construct() {
29
+
30
+ // Add Ajax Callback
31
+ add_action( 'wp_ajax_ever_compare_add_to_compare', [ $this, 'add_to_compare' ] );
32
+ add_action( 'wp_ajax_nopriv_ever_compare_add_to_compare', [ $this, 'add_to_compare' ] );
33
+
34
+ // Remove Ajax Callback
35
+ add_action( 'wp_ajax_ever_compare_remove_from_compare', [ $this, 'remove_from_compare' ] );
36
+ add_action( 'wp_ajax_nopriv_ever_compare_remove_from_compare', [ $this,'remove_from_compare' ] );
37
+
38
+ }
39
+
40
+ /**
41
+ * [add_to_compare] Product add ajax callback
42
+ */
43
+ public function add_to_compare(){
44
+ $id = sanitize_text_field( $_GET['id'] );
45
+ \EverCompare\Frontend\Manage_Compare::instance()->add_to_compare( $id );
46
+ }
47
+
48
+ /**
49
+ * [remove_from_compare] Product delete ajax callback
50
+ * @return [void]
51
+ */
52
+ public function remove_from_compare(){
53
+ $id = sanitize_text_field( $_GET['id'] );
54
+ \EverCompare\Frontend\Manage_Compare::instance()->remove_from_compare( $id );
55
+ }
56
+
57
+ }
includes/modules/compare/includes/classes/Assets.php ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare;
3
+ /**
4
+ * Assets handlers class
5
+ */
6
+ class Assets {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [$suffix]
16
+ * @var [string]
17
+ */
18
+ public $suffix = '';
19
+
20
+ /**
21
+ * [instance] Initializes a singleton instance
22
+ * @return [Base]
23
+ */
24
+ public static function instance() {
25
+ if ( is_null( self::$_instance ) ) {
26
+ self::$_instance = new self();
27
+ }
28
+ return self::$_instance;
29
+ }
30
+
31
+ /**
32
+ * Class constructor
33
+ */
34
+ private function __construct() {
35
+ $this->suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
36
+ add_action( 'wp_enqueue_scripts', [ $this, 'register_assets' ] );
37
+ add_action( 'admin_enqueue_scripts', [ $this, 'register_assets' ] );
38
+ }
39
+
40
+ /**
41
+ * All available scripts
42
+ *
43
+ * @return array
44
+ */
45
+ public function get_scripts() {
46
+
47
+ $script_list = [
48
+ 'evercompare-admin' => [
49
+ 'src' => EVERCOMPARE_ASSETS . '/js/admin.js',
50
+ 'version' => WOOLENTOR_VERSION,
51
+ 'deps' => [ 'jquery' ]
52
+ ],
53
+ 'evercompare-frontend' => [
54
+ 'src' => EVERCOMPARE_ASSETS . '/js/frontend'.$this->suffix.'.js',
55
+ 'version' => WOOLENTOR_VERSION,
56
+ 'deps' => [ 'jquery' ]
57
+ ],
58
+ ];
59
+
60
+ return $script_list;
61
+
62
+ }
63
+
64
+ /**
65
+ * All available styles
66
+ *
67
+ * @return array
68
+ */
69
+ public function get_styles() {
70
+
71
+ $style_list = [
72
+ 'evercompare-admin' => [
73
+ 'src' => EVERCOMPARE_ASSETS . '/css/admin.css',
74
+ 'version' => WOOLENTOR_VERSION,
75
+ ],
76
+ 'evercompare-frontend' => [
77
+ 'src' => EVERCOMPARE_ASSETS . '/css/frontend'.$this->suffix.'.css',
78
+ 'version' => WOOLENTOR_VERSION,
79
+ ],
80
+ ];
81
+
82
+ return $style_list;
83
+
84
+ }
85
+
86
+ /**
87
+ * Register scripts and styles
88
+ *
89
+ * @return void
90
+ */
91
+ public function register_assets() {
92
+ $scripts = $this->get_scripts();
93
+ $styles = $this->get_styles();
94
+
95
+ foreach ( $scripts as $handle => $script ) {
96
+ $deps = isset( $script['deps'] ) ? $script['deps'] : false;
97
+
98
+ wp_register_script( $handle, $script['src'], $deps, $script['version'], true );
99
+ }
100
+
101
+ foreach ( $styles as $handle => $style ) {
102
+ $deps = isset( $style['deps'] ) ? $style['deps'] : false;
103
+
104
+ wp_register_style( $handle, $style['src'], $deps, $style['version'] );
105
+ }
106
+
107
+ // Inline CSS
108
+ wp_add_inline_style( 'evercompare-frontend', $this->inline_style() );
109
+
110
+ // Frontend Localize data
111
+ $option_data = array();
112
+ $localize_data = array(
113
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
114
+ 'popup' => ( woolentor_get_option( 'open_popup', 'ever_compare_settings_tabs', 'on' ) === 'on' ) ? 'yes' : 'no',
115
+ 'option_data' => $option_data,
116
+ );
117
+
118
+ // Admin Localize data
119
+ $setting_page = 0;
120
+ if( isset( $_GET['page'] ) && $_GET['page'] == 'evercompare' ){
121
+ $setting_page = 1;
122
+ }
123
+ $admin_option_data = array(
124
+ 'shop_btn_position' => woolentor_get_option( 'shop_btn_position','ever_compare_settings_tabs','after_cart_btn' ),
125
+ 'product_btn_position' => woolentor_get_option( 'product_btn_position','ever_compare_settings_tabs','after_cart_btn' ),
126
+ 'button_icon_type' => woolentor_get_option( 'button_icon_type','ever_compare_settings_tabs','none' ),
127
+ 'added_button_icon_type'=> woolentor_get_option( 'added_button_icon_type','ever_compare_settings_tabs','none' ),
128
+ 'enable_shareable_link' => woolentor_get_option( 'enable_shareable_link','ever_compare_table_settings_tabs','off' ),
129
+ 'button_style' => woolentor_get_option( 'button_style','ever_compare_style_tabs','theme' ),
130
+ 'table_style' => woolentor_get_option( 'table_style','ever_compare_style_tabs','default' ),
131
+ );
132
+ $admin_localize_data = array(
133
+ 'is_settings'=> $setting_page,
134
+ 'option_data'=> $admin_option_data,
135
+ );
136
+ wp_localize_script( 'evercompare-frontend', 'evercompare', $localize_data );
137
+ wp_localize_script( 'evercompare-admin', 'evercompare', $admin_localize_data );
138
+
139
+ }
140
+
141
+ /**
142
+ * [inline_style]
143
+ * @return [CSS String]
144
+ */
145
+ public function inline_style(){
146
+
147
+ $inline_css = '';
148
+
149
+ // Button Custom Style
150
+ if( 'custom' === woolentor_get_option( 'button_style', 'ever_compare_style_tabs', 'theme' ) ){
151
+
152
+ $btn_padding = ever_compare_dimensions( 'button_custom_padding','ever_compare_style_tabs','padding' );
153
+ $btn_margin = ever_compare_dimensions( 'button_custom_margin','ever_compare_style_tabs','margin' );
154
+ $btn_border_radius = ever_compare_dimensions( 'button_custom_border_radius','ever_compare_style_tabs','border-radius' );
155
+ $btn_border_width = ever_compare_dimensions( 'button_custom_border','ever_compare_style_tabs','border-width' );
156
+ $btn_border_style = !empty( $btn_border_width ) ? 'border-style:solid;' : '';
157
+
158
+ $btn_border_color = ever_compare_generate_css('button_custom_border_color','ever_compare_style_tabs','border-color');
159
+ $btn_color = ever_compare_generate_css('button_color','ever_compare_style_tabs','color');
160
+ $btn_bg_color = ever_compare_generate_css('background_color','ever_compare_style_tabs','background-color');
161
+
162
+ // Hover
163
+ $btn_hover_color = ever_compare_generate_css('button_hover_color','ever_compare_style_tabs','color');
164
+ $btn_hover_bg_color = ever_compare_generate_css('hover_background_color','ever_compare_style_tabs','background-color');
165
+
166
+ $inline_css .= "
167
+ .htcompare-btn{
168
+ {$btn_padding}
169
+ {$btn_margin}
170
+ {$btn_color}
171
+ {$btn_bg_color}
172
+ {$btn_border_width}
173
+ {$btn_border_style}
174
+ {$btn_border_color}
175
+ {$btn_border_radius}
176
+ }
177
+ .htcompare-btn:hover{
178
+ {$btn_hover_color}
179
+ {$btn_hover_bg_color}
180
+ }
181
+ ";
182
+
183
+ }
184
+
185
+ // Table style
186
+ if( 'custom' === woolentor_get_option( 'table_style', 'ever_compare_style_tabs', 'default' ) ){
187
+
188
+ $border_color = ever_compare_generate_css('table_border_color','ever_compare_style_tabs','border-color');
189
+ $column_padding = ever_compare_dimensions( 'table_column_padding','ever_compare_style_tabs','padding' );
190
+
191
+ $event_bg_color = ever_compare_generate_css('table_event_color','ever_compare_style_tabs','background-color');
192
+ $odd_bg_color = ever_compare_generate_css('table_odd_color','ever_compare_style_tabs','background-color');
193
+
194
+ $event_heading_color = ever_compare_generate_css('table_heading_event_color','ever_compare_style_tabs','color');
195
+ $odd_heading_color = ever_compare_generate_css('table_heading_odd_color','ever_compare_style_tabs','color');
196
+
197
+ $event_content_color = ever_compare_generate_css('table_content_event_color','ever_compare_style_tabs','color');
198
+ $odd_content_color = ever_compare_generate_css('table_content_odd_color','ever_compare_style_tabs','color');
199
+
200
+ $link_color = ever_compare_generate_css('table_content_link_color','ever_compare_style_tabs','color');
201
+ $link_hover_color = ever_compare_generate_css('table_content_link_hover_color','ever_compare_style_tabs','color');
202
+
203
+ $inline_css .= "
204
+ .htcompare-col,.compare-data-primary .htcolumn-value{
205
+ {$border_color}
206
+ }
207
+ .htcompare-col{
208
+ {$column_padding}
209
+ }
210
+
211
+ .htcompare-row:nth-child(2n) .htcompare-col{
212
+ {$event_bg_color}
213
+ }
214
+ .htcompare-row:nth-child(2n+1) .htcompare-col{
215
+ {$odd_bg_color}
216
+ }
217
+
218
+ .htcompare-row:nth-child(2n) .htcompare-col.htcolumn-field-name{
219
+ {$event_heading_color}
220
+ }
221
+ .htcompare-row:nth-child(2n+1) .htcompare-col.htcolumn-field-name{
222
+ {$odd_heading_color}
223
+ }
224
+
225
+ .htcompare-row:nth-child(2n) .htcompare-col.htcolumn-value{
226
+ {$event_content_color}
227
+ }
228
+ .htcompare-row:nth-child(2n+1) .htcompare-col.htcolumn-value{
229
+ {$odd_content_color}
230
+ }
231
+
232
+ .htcompare-row .htcompare-col.htcolumn-value a{
233
+ {$link_color}
234
+ }
235
+ .htcompare-row .htcompare-col.htcolumn-value a:hover{
236
+ {$link_hover_color}
237
+ }
238
+
239
+ ";
240
+
241
+ }
242
+
243
+ return $inline_css;
244
+
245
+ }
246
+
247
+
248
+ }
includes/modules/compare/includes/classes/Frontend.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare;
3
+
4
+ /**
5
+ * Frontend handlers class
6
+ */
7
+ class Frontend {
8
+
9
+ /**
10
+ * [$_instance]
11
+ * @var null
12
+ */
13
+ private static $_instance = null;
14
+
15
+ /**
16
+ * [instance] Initializes a singleton instance
17
+ * @return [Base]
18
+ */
19
+ public static function instance() {
20
+ if ( is_null( self::$_instance ) ) {
21
+ self::$_instance = new self();
22
+ }
23
+ return self::$_instance;
24
+ }
25
+
26
+ /**
27
+ * Initialize the class
28
+ */
29
+ private function __construct() {
30
+ $this->includes();
31
+ Frontend\Manage_Compare::instance();
32
+ Frontend\Shortcode::instance();
33
+ }
34
+
35
+ public function includes(){
36
+ require_once( __DIR__. '/Frontend/Manage_Compare.php' );
37
+ require_once __DIR__ . '/Frontend/Shortcode.php';
38
+ }
39
+
40
+ }
includes/modules/compare/includes/classes/Frontend/Manage_Compare.php ADDED
@@ -0,0 +1,669 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare\Frontend;
3
+ /**
4
+ * Button handlers class
5
+ */
6
+ class Manage_Compare {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [$reached_max_limit]
16
+ * @var boolean
17
+ */
18
+ public $reached_max_limit = false;
19
+
20
+ /**
21
+ * [instance] Initializes a singleton instance
22
+ * @return [Compare_Button]
23
+ */
24
+ public static function instance() {
25
+ if ( is_null( self::$_instance ) ) {
26
+ self::$_instance = new self();
27
+ }
28
+ return self::$_instance;
29
+ }
30
+
31
+ /**
32
+ * Initialize the class
33
+ */
34
+ private function __construct() {
35
+ add_action( 'init', [ $this, 'button_manager' ] );
36
+ add_action( 'ever_compare_before_table', [ $this, 'reached_max_limit_message' ], 1 );
37
+ add_action( 'ever_compare_after_table', [ $this, 'shareable_link' ], 1 );
38
+ }
39
+
40
+ /**
41
+ * [compare_button]
42
+ * @return [void]
43
+ */
44
+ public function button_print(){
45
+ echo do_shortcode( '[evercompare_button]' );
46
+ }
47
+
48
+ /**
49
+ * [button_manager] Button Manager
50
+ * @return [void]
51
+ */
52
+ public function button_manager(){
53
+
54
+ $enable_btn = woolentor_get_option( 'btn_show_shoppage', 'ever_compare_settings_tabs', 'off' );
55
+ $product_enable_btn = woolentor_get_option( 'btn_show_productpage', 'ever_compare_settings_tabs', 'on' );
56
+
57
+ $shop_page_btn_position = woolentor_get_option( 'shop_btn_position', 'ever_compare_settings_tabs', 'after_cart_btn' );
58
+ $product_page_btn_position = woolentor_get_option( 'product_btn_position', 'ever_compare_settings_tabs', 'after_cart_btn' );
59
+
60
+
61
+ // Shop Button Position
62
+ if( $shop_page_btn_position != 'use_shortcode' && $enable_btn == 'on' ){
63
+ switch ( $shop_page_btn_position ) {
64
+
65
+ case 'before_cart_btn':
66
+ add_action( 'woocommerce_after_shop_loop_item', [ $this, 'button_print' ], 7 );
67
+ break;
68
+
69
+ case 'top_thumbnail':
70
+ add_action( 'woocommerce_before_shop_loop_item', [ $this, 'button_print' ], 5 );
71
+ break;
72
+
73
+ case 'custom_position':
74
+ $hook_name = woolentor_get_option( 'shop_custom_hook_name', 'ever_compare_settings_tabs', '' );
75
+ $priority = woolentor_get_option( 'shop_custom_hook_priority', 'ever_compare_settings_tabs', 10 );
76
+ if( !empty( $hook_name ) ){
77
+ add_action( $hook_name, [ $this, 'button_print' ], $priority );
78
+ }
79
+ break;
80
+
81
+ default:
82
+ add_action( 'woocommerce_after_shop_loop_item', [ $this, 'button_print' ], 20 );
83
+ break;
84
+
85
+ }
86
+ }
87
+
88
+ // Product Page Button Position
89
+ if( $product_page_btn_position != 'use_shortcode' && $product_enable_btn == 'on' ){
90
+ switch ( $product_page_btn_position ) {
91
+
92
+ case 'before_cart_btn':
93
+ add_action( 'woocommerce_before_add_to_cart_button', [ $this, 'button_print' ], 20 );
94
+ break;
95
+
96
+ case 'after_thumbnail':
97
+ add_action( 'woocommerce_product_thumbnails', [ $this, 'button_print' ], 21 );
98
+ break;
99
+
100
+ case 'after_summary':
101
+ add_action( 'woocommerce_after_single_product_summary', [ $this, 'button_print' ], 11 );
102
+ break;
103
+
104
+ case 'custom_position':
105
+ $hook_name = woolentor_get_option( 'product_custom_hook_name', 'ever_compare_settings_tabs', '' );
106
+ $priority = woolentor_get_option( 'product_custom_hook_priority', 'ever_compare_settings_tabs', 10 );
107
+ if( !empty( $hook_name ) ){
108
+ add_action( $hook_name, [ $this, 'button_print' ], $priority );
109
+ }
110
+ break;
111
+
112
+ default:
113
+ add_action( 'woocommerce_single_product_summary', [ $this, 'button_print' ], 31 );
114
+ break;
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Popup HTML Render
120
+ */
121
+ if( woolentor_get_option( 'open_popup', 'ever_compare_settings_tabs', 'on' ) === 'on' ){
122
+ add_action( 'wp_footer', [ $this, 'pop_up_html' ] );
123
+ }
124
+
125
+ /**
126
+ * Manage maximum product added message
127
+ */
128
+ if( isset( $_COOKIE[ 'ever_compare_max_limit' ] ) && $_COOKIE[ 'ever_compare_max_limit' ] == 'yes' ) {
129
+ setcookie( 'ever_compare_max_limit', 'no', 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
130
+ $this->reached_max_limit = true;
131
+ }
132
+
133
+
134
+ }
135
+
136
+ /**
137
+ * [button_html] Button HTML
138
+ * @param [type] $atts
139
+ * @return [HTML]
140
+ */
141
+ public function button_html( $atts ) {
142
+ $button_attr = apply_filters( 'evercompare_button_arg', $atts );
143
+ return ever_compare_get_template( 'evercompare-button-'.$atts['template_name'].'.php', $button_attr, false );
144
+ }
145
+
146
+ /**
147
+ * [table_html] Wishlist table HTML
148
+ * @return [HTML]
149
+ */
150
+ public function table_html( $atts ) {
151
+ $table_attr = apply_filters( 'evercompare_table_arg', $atts );
152
+ return ever_compare_get_template( 'evercompare-table.php', $table_attr, false );
153
+ }
154
+
155
+ /**
156
+ * [pop_up_html]
157
+ * @return [void]
158
+ */
159
+ public function pop_up_html(){
160
+ echo '<div class="htcompare-popup"><div class="htcompare-popup-content-area"><span class="htcompare-popup-close">&nbsp;</span>'.do_shortcode( '[evercompare_table]' ).'</div></div>';
161
+ }
162
+
163
+ /**
164
+ * [reached_max_limit_message]
165
+ * @return [void]
166
+ */
167
+ public function reached_max_limit_message(){
168
+ if( ! $this->reached_max_limit ) {
169
+ return;
170
+ }
171
+
172
+ $message = !empty( woolentor_get_option('reached_max_limit_message','ever_compare_table_settings_tabs') ) ? woolentor_get_option('reached_max_limit_message','ever_compare_table_settings_tabs') : esc_html__( 'You are already added the maximum number of products.', 'ever-compare' );
173
+ echo '<div class="ever-compare-message-error"><p>'. wp_kses_post( $message ).'</p></div>';
174
+
175
+ }
176
+
177
+ /**
178
+ * [shareable_link]
179
+ * @return [void]
180
+ */
181
+ public function shareable_link(){
182
+
183
+ $shareable_link = woolentor_get_option( 'enable_shareable_link','ever_compare_table_settings_tabs','off' );
184
+ if ( $shareable_link !== 'on' ) {
185
+ return;
186
+ }
187
+
188
+ $ids = $this->get_compared_products();
189
+
190
+ if ( isset( $_GET['evcompare'] ) ) {
191
+ $query_perametter_ids = sanitize_text_field( $_GET['evcompare'] );
192
+ if( !empty( $query_perametter_ids ) ){
193
+ $ids = explode( ',', $query_perametter_ids );
194
+ }
195
+ }
196
+
197
+ $buttonText = woolentor_get_option( 'shareable_link_button_text','ever_compare_table_settings_tabs','Copy shareable link' ) ? woolentor_get_option( 'shareable_link_button_text','ever_compare_table_settings_tabs','Copy shareable link' ) : esc_html__( 'Copy shareable link', 'ever-compare' );
198
+ $aftercopy_buttonText = woolentor_get_option( 'shareable_link_after_button_text','ever_compare_table_settings_tabs','Copied' ) ? woolentor_get_option( 'shareable_link_after_button_text','ever_compare_table_settings_tabs','Copied' ) : esc_html__( 'Copied', 'ever-compare' );
199
+ $button_pos = woolentor_get_option( 'linkshare_btn_pos','ever_compare_table_settings_tabs','right' );
200
+
201
+ $idsString = is_array( $ids ) ? implode( ',', $ids ) : '';
202
+ $shareablelink = $this->get_compare_page_url() . '?evcompare='.$idsString;
203
+ ?>
204
+ <div class="ever-compare-shareable-link <?php echo esc_attr( $button_pos );?>">
205
+ <button class="evercompare-copy-link" data-copytext="<?php echo esc_attr( $aftercopy_buttonText ); ?>" data-btntext="<?php echo esc_attr( $buttonText ); ?>"><?php echo $buttonText; ?></button>
206
+ <p style="display: none;" class="evercompare-share-link"><?php echo $shareablelink; ?></p>
207
+ </div>
208
+ <?php
209
+
210
+ }
211
+
212
+ /**
213
+ * [add_to_compare] Ajax callable function
214
+ */
215
+ public function add_to_compare( $id ) {
216
+
217
+ $cookie_name = $this->get_cookie_name();
218
+
219
+ if ( $this->is_product_in_compare( $id ) ) {
220
+ $this->compare_json_response();
221
+ }
222
+
223
+ $products = $this->get_compared_products();
224
+
225
+ // Reached Maximum Limit
226
+ if( $this->reached_max_limit() ) {
227
+ setcookie( 'ever_compare_max_limit', 'yes', 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
228
+ $this->compare_json_response();
229
+ }
230
+
231
+ $products[] = $id;
232
+
233
+ setcookie( $cookie_name, json_encode( $products ), 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
234
+
235
+ $_COOKIE[$cookie_name] = json_encode( $products );
236
+
237
+ $this->compare_json_response();
238
+
239
+ }
240
+
241
+ /**
242
+ * [reached_max_limit]
243
+ * @return [bool]
244
+ */
245
+ public function reached_max_limit(){
246
+
247
+ $products = $this->get_compared_products();
248
+ $max_limit = intval( woolentor_get_option( 'limit','ever_compare_table_settings_tabs', 10 ) );
249
+
250
+ if( $max_limit && count( $products ) >= $max_limit ) {
251
+ $this->reached_max_limit = true;
252
+ } else {
253
+ $this->reached_max_limit = false;
254
+ }
255
+
256
+ return $this->reached_max_limit;
257
+ }
258
+
259
+ /**
260
+ * [remove_from_compare] Ajax callable function
261
+ * @return [json]
262
+ */
263
+ public function remove_from_compare( $id ) {
264
+
265
+ $cookie_name = $this->get_cookie_name();
266
+
267
+ if ( ! $this->is_product_in_compare( $id ) ) {
268
+ $this->compare_json_response();
269
+ }
270
+
271
+ $products = $this->get_compared_products();
272
+
273
+ foreach ( $products as $prod_key => $product_id ) {
274
+ if ( intval( $id ) == $product_id ) {
275
+ unset( $products[ $prod_key ] );
276
+ $this->reached_max_limit = false;
277
+ }
278
+ }
279
+
280
+ if ( empty( $products ) ) {
281
+ setcookie( $cookie_name, false, 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
282
+ $_COOKIE[$cookie_name] = false;
283
+ } else {
284
+ setcookie( $cookie_name, json_encode( $products ), 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
285
+ $_COOKIE[$cookie_name] = json_encode( $products );
286
+ }
287
+
288
+ $this->compare_json_response();
289
+ }
290
+
291
+ /**
292
+ * [get_response_html ] Compare product table HTML
293
+ * @return [html]
294
+ */
295
+ public function get_response_html(){
296
+
297
+ $products = $this->get_compared_products_data();
298
+ $fields = $this->get_compare_fields();
299
+
300
+ $empty_compare_text = woolentor_get_option('empty_table_text','ever_compare_table_settings_tabs');
301
+ $return_shop_button = woolentor_get_option('shop_button_text','ever_compare_table_settings_tabs','Return to shop');
302
+
303
+ $custom_heading = !empty( woolentor_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) ) ? woolentor_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) : array();
304
+
305
+ $default_atts = array(
306
+ 'evercompare' => self::instance(),
307
+ 'products' => $products,
308
+ 'fields' => $fields,
309
+ 'heading_txt' => $custom_heading,
310
+ 'return_shop_button' => $return_shop_button,
311
+ 'empty_compare_text' => $empty_compare_text,
312
+ );
313
+ $table_attr = apply_filters( 'evercompare_response_html_args', $default_atts );
314
+
315
+ ever_compare_get_template( 'evercompare-table.php', $table_attr );
316
+
317
+ }
318
+
319
+ /**
320
+ * [get_compared_products_data] generate compared products data
321
+ * @return [array] product list
322
+ */
323
+ public function get_compared_products_data() {
324
+ $ids = $this->get_compared_products();
325
+
326
+ // For shareable link
327
+ $shareable_link = woolentor_get_option('enable_shareable_link','ever_compare_table_settings_tabs','off');
328
+ if ( ( $shareable_link === 'on' ) && isset( $_GET['evcompare'] ) ) {
329
+ $query_perametter_ids = sanitize_text_field( $_GET['evcompare'] );
330
+ if( !empty( $query_perametter_ids ) ){
331
+ $ids = explode( ',', $query_perametter_ids );
332
+ }
333
+ }
334
+
335
+ if ( empty( $ids ) ) {
336
+ return array();
337
+ }
338
+
339
+ $args = array(
340
+ 'include' => $ids,
341
+ );
342
+
343
+ $products = wc_get_products( $args );
344
+
345
+ $products_data = array();
346
+
347
+ $fields = $this->get_compare_fields();
348
+
349
+ $fields = array_filter( $fields, function( $field ) {
350
+ return 'pa_' === substr( $field, 0, 3 );
351
+ }, ARRAY_FILTER_USE_KEY );
352
+
353
+ $data_none = '-';
354
+
355
+ foreach ( $products as $product ) {
356
+
357
+ $rating_count = $product->get_rating_count();
358
+ $average = $product->get_average_rating();
359
+
360
+ $products_data[ $product->get_id() ] = array(
361
+ 'primary' => array(
362
+ 'image' => $product->get_image() ? $product->get_image('ever-compare-image') : $data_none,
363
+ ),
364
+ 'id' => $product->get_id(),
365
+ 'title' => $product->get_title() ? $product->get_title() : $data_none,
366
+ 'image_id' => $product->get_image_id(),
367
+ 'permalink' => $product->get_permalink(),
368
+ 'price' => $product->get_price_html() ? $product->get_price_html() : $data_none,
369
+ 'rating' => wc_get_rating_html( $average, $rating_count ),
370
+ 'add_to_cart' => $this->add_to_cart_html( $product ) ? $this->add_to_cart_html( $product ) :$data_none,
371
+ 'dimensions' => wc_format_dimensions( $product->get_dimensions( false ) ),
372
+ 'description' => $product->get_short_description() ? $product->get_short_description() : $data_none,
373
+ 'weight' => $product->get_weight() ? $product->get_weight() : $data_none,
374
+ 'sku' => $product->get_sku() ? $product->get_sku() : $data_none,
375
+ 'availability' => $this->availability_html( $product ),
376
+ );
377
+
378
+ foreach ( $fields as $field_id => $field_name ) {
379
+ if ( taxonomy_exists( $field_id ) ) {
380
+ $products_data[ $product->get_id() ][ $field_id ] = array();
381
+ $terms = get_the_terms( $product->get_id(), $field_id );
382
+ if ( ! empty( $terms ) ) {
383
+ foreach ( $terms as $term ) {
384
+ $term = sanitize_term( $term, $field_id );
385
+ $products_data[ $product->get_id() ][ $field_id ][] = $term->name;
386
+ }
387
+ } else {
388
+ $products_data[ $product->get_id() ][ $field_id ][] = '-';
389
+ }
390
+ $products_data[ $product->get_id() ][ $field_id ] = implode( ', ', $products_data[ $product->get_id() ][ $field_id ] );
391
+ }
392
+ }
393
+ }
394
+
395
+ return $products_data;
396
+ }
397
+
398
+ /**
399
+ * [get_compare_fields] Table field list
400
+ * @return [array] Table Field list
401
+ */
402
+ public function get_compare_fields() {
403
+ $fields = array(
404
+ 'primary' => ''
405
+ );
406
+
407
+ $default_show = array(
408
+ 'title' => esc_html__( 'title', 'ever-compare' ),
409
+ 'ratting' => esc_html__( 'ratting', 'ever-compare' ),
410
+ 'price' => esc_html__( 'price', 'ever-compare' ),
411
+ 'add_to_cart' => esc_html__( 'add_to_cart', 'ever-compare' ),
412
+ 'description' => esc_html__( 'description', 'ever-compare' ),
413
+ 'availability' => esc_html__( 'availability', 'ever-compare' ),
414
+ 'sku' => esc_html__( 'sku', 'ever-compare' ),
415
+ 'weight' => esc_html__( 'weight', 'ever-compare' ),
416
+ 'dimensions' => esc_html__( 'dimensions', 'ever-compare' ),
417
+ );
418
+
419
+ $fields_settings = !empty( woolentor_get_option( 'show_fields', 'ever_compare_table_settings_tabs' ) ) ? woolentor_get_option( 'show_fields', 'ever_compare_table_settings_tabs' ) : array();
420
+
421
+ if ( isset( $fields_settings ) && count( $fields_settings ) > 1 ) {
422
+ $fields = $fields + $fields_settings;
423
+ }else{
424
+ $fields = $fields + $default_show;
425
+ }
426
+
427
+ return $fields;
428
+ }
429
+
430
+ /**
431
+ * [is_products_have_field]
432
+ * @param [string] $field_id
433
+ * @param [object] $products
434
+ * @return boolean
435
+ */
436
+ public function is_products_have_field( $field_id, $products ) {
437
+ foreach ( $products as $product_id => $product ) {
438
+ if ( isset( $product[ $field_id ] ) && ( ! empty( $product[ $field_id ] ) && '-' !== $product[ $field_id ] && 'N/A' !== $product[ $field_id ] ) ) {
439
+ return true;
440
+ }
441
+ }
442
+ return false;
443
+ }
444
+
445
+ /**
446
+ * [compare_display_field]
447
+ * @param [string] $field_id
448
+ * @param [array] $product
449
+ * @return [html]
450
+ */
451
+ public function compare_display_field( $field_id, $product ) {
452
+
453
+ $type = $field_id;
454
+
455
+ if ( 'pa_' === substr( $field_id, 0, 3 ) ) {
456
+ $type = 'attribute';
457
+ }
458
+
459
+ switch ( $type ) {
460
+ case 'primary':
461
+ ?>
462
+ <div class="htcompare-primary-content-area">
463
+ <a href="#" class="htcompare-remove" data-product_id="<?php echo esc_attr( $product['id'] ); ?>">&nbsp;</a>
464
+ <a href="<?php echo get_permalink( $product['id'] ); ?>" class="htcompare-product-image">
465
+ <?php echo $product['primary']['image']; ?>
466
+ </a>
467
+ </div>
468
+ <?php
469
+ break;
470
+
471
+ case 'title':
472
+ echo '<a href="'.get_permalink( $product['id'] ).'" class="htcompare-product-title">'.$product[ $field_id ].'</a>';
473
+ break;
474
+
475
+ case 'ratting':
476
+ echo '<span class="htcompare-product-ratting">'.wp_kses_post( $product[ $field_id ] ).'</span>';
477
+ break;
478
+
479
+ case 'price':
480
+ echo '<div class="htcompare-product-price">'.wp_kses_post( $product[ $field_id ] ).'</div>';
481
+ break;
482
+
483
+ case 'add_to_cart':
484
+ echo apply_filters( 'htcompare_add_to_cart_btn', $product[ $field_id ] );
485
+ break;
486
+
487
+ case 'attribute':
488
+ echo wp_kses_post( $product[ $field_id ] );
489
+ break;
490
+
491
+ case 'weight':
492
+ if ( $product[ $field_id ] ) {
493
+ $unit = $product[ $field_id ] !== '-' ? get_option( 'woocommerce_weight_unit' ) : '';
494
+ echo wc_format_localized_decimal( $product[ $field_id ] ) . ' ' . esc_attr( $unit );
495
+ }
496
+ break;
497
+
498
+ case 'description':
499
+ echo apply_filters( 'woocommerce_short_description', $product[ $field_id ] );
500
+ break;
501
+
502
+ default:
503
+ echo wp_kses_post( $product[ $field_id ] );
504
+ break;
505
+ }
506
+ }
507
+
508
+ /**
509
+ * [add_to_cart_html] Generate Cart button
510
+ * @param [object] $product
511
+ */
512
+ public function add_to_cart_html( $product ) {
513
+ if ( ! $product ) return;
514
+
515
+ $defaults = array(
516
+ 'quantity' => 1,
517
+ 'class' => implode( ' ', array_filter( array(
518
+ 'htcompare-cart-button button',
519
+ 'product_type_' . $product->get_type(),
520
+ $product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
521
+ $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock() ? 'ajax_add_to_cart' : '',
522
+ ) ) ),
523
+ 'attributes' => array(
524
+ 'data-product_id' => $product->get_id(),
525
+ 'data-product_sku' => $product->get_sku(),
526
+ 'aria-label' => $product->add_to_cart_description(),
527
+ 'rel' => 'nofollow',
528
+ ),
529
+ );
530
+
531
+ $args = apply_filters( 'woocommerce_loop_add_to_cart_args', $defaults, $product );
532
+
533
+ if ( isset( $args['attributes']['aria-label'] ) ) {
534
+ $args['attributes']['aria-label'] = strip_tags( $args['attributes']['aria-label'] );
535
+ }
536
+
537
+ return apply_filters( 'woocommerce_loop_add_to_cart_link',
538
+ sprintf( '<a href="%s" data-quantity="%s" class="%s add-to-cart-loop" %s><span>%s</span></a>',
539
+ esc_url( $product->add_to_cart_url() ),
540
+ esc_attr( isset( $args['quantity'] ) ? $args['quantity'] : 1 ),
541
+ esc_attr( isset( $args['class'] ) ? $args['class'] : 'button' ),
542
+ isset( $args['attributes'] ) ? wc_implode_html_attributes( $args['attributes'] ) : '',
543
+ esc_html( $product->add_to_cart_text() )
544
+ ),
545
+ $product, $args );
546
+ }
547
+
548
+ /**
549
+ * [availability_html]
550
+ * @param [object] $product
551
+ * @return [html]
552
+ */
553
+ public function availability_html( $product ) {
554
+ $html = '';
555
+ $availability = $product->get_availability();
556
+
557
+ if( empty( $availability['availability'] ) ) {
558
+ $availability['availability'] = __( 'In stock', 'woocommerce' );
559
+ }
560
+
561
+ if ( ! empty( $availability['availability'] ) ) {
562
+ ob_start();
563
+
564
+ wc_get_template( 'single-product/stock.php', array(
565
+ 'product' => $product,
566
+ 'class' => $availability['class'],
567
+ 'availability' => $availability['availability'],
568
+ ) );
569
+
570
+ $html = ob_get_clean();
571
+ }
572
+
573
+ return apply_filters( 'woocommerce_get_stock_html', $html, $product );
574
+ }
575
+
576
+ /**
577
+ * [compare_cookie_name] Get Compare cookie name
578
+ * @return [string]
579
+ */
580
+ public function get_cookie_name() {
581
+ $name = 'ever_compare_compare_list';
582
+ if ( is_multisite() ){
583
+ $name .= '_' . get_current_blog_id();
584
+ }
585
+ return $name;
586
+ }
587
+
588
+ /**
589
+ * [is_product_in_compare]
590
+ * @param [int] $id product id
591
+ * @return [array] product id list
592
+ */
593
+ public function is_product_in_compare( $id ) {
594
+ $list = $this->get_compared_products();
595
+ return in_array( $id, $list, true );
596
+ }
597
+
598
+ /**
599
+ * [get_compared_products]
600
+ * @return [json]
601
+ */
602
+ public function get_compared_products() {
603
+ $cookie_name = $this->get_cookie_name();
604
+ return isset( $_COOKIE[ $cookie_name ] ) ? json_decode( wp_unslash( $_COOKIE[ $cookie_name ] ), true ) : array();
605
+ }
606
+
607
+ /**
608
+ * [compare_json_response]
609
+ * @return [json] product json
610
+ */
611
+ public function compare_json_response() {
612
+ $count = 0;
613
+ $products = $this->get_compared_products();
614
+
615
+ ob_start();
616
+
617
+ $this->get_response_html();
618
+
619
+ $table_html = ob_get_clean();
620
+
621
+ if ( is_array( $products ) ) {
622
+ $count = count( $products );
623
+ }
624
+
625
+ wp_send_json( array(
626
+ 'count' => $count,
627
+ 'table' => $table_html,
628
+ ) );
629
+
630
+ }
631
+
632
+ /**
633
+ * [get_compare_page_url] Compare Page Link
634
+ * @return [URL]
635
+ */
636
+ public function get_compare_page_url() {
637
+ $page_id = woolentor_get_option( 'compare_page', 'ever_compare_table_settings_tabs' );
638
+ return get_permalink( $page_id );
639
+ }
640
+
641
+ /**
642
+ * [field_name]
643
+ * @param [string] $field
644
+ * @return [string]
645
+ */
646
+ public function field_name( $field = '', $custom = false ){
647
+
648
+ if( empty( $field ) ){
649
+ return;
650
+ }
651
+
652
+ if( $custom === true ){
653
+ return $field;
654
+ }
655
+
656
+ $default = ever_compare_get_default_fields();
657
+
658
+ $str = substr( $field, 0, 3 );
659
+ if( 'pa_' === $str ){
660
+ $field_name = wc_attribute_label( $field );
661
+ }else{
662
+ $field_name = $default[$field];
663
+ }
664
+ return $field_name;
665
+
666
+ }
667
+
668
+
669
+ }
includes/modules/compare/includes/classes/Frontend/Shortcode.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare\Frontend;
3
+ /**
4
+ * Shortcode handler class
5
+ */
6
+ class Shortcode {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [instance] Initializes a singleton instance
16
+ * @return [Base]
17
+ */
18
+ public static function instance() {
19
+ if ( is_null( self::$_instance ) ) {
20
+ self::$_instance = new self();
21
+ }
22
+ return self::$_instance;
23
+ }
24
+
25
+ /**
26
+ * Initializes the class
27
+ */
28
+ function __construct() {
29
+ add_shortcode( 'evercompare_button', [ $this, 'button_shortcode' ] );
30
+ add_shortcode( 'evercompare_table', [ $this, 'table_shortcode' ] );
31
+ }
32
+
33
+ /**
34
+ * [button_shortcode] Compare Button Shortcode callable function
35
+ * @param [type] $atts
36
+ * @param string $content
37
+ * @return [HTML]
38
+ */
39
+ public function button_shortcode( $atts, $content = '' ){
40
+
41
+ wp_enqueue_style( 'evercompare-frontend' );
42
+ wp_enqueue_script( 'evercompare-frontend' );
43
+
44
+ global $product;
45
+
46
+ // Fetch option data
47
+ $button_text = woolentor_get_option( 'button_text','ever_compare_settings_tabs', 'Compare' );
48
+ $button_added_text = woolentor_get_option( 'added_button_text','ever_compare_settings_tabs', 'Added' );
49
+
50
+ $shop_page_btn_position = woolentor_get_option( 'shop_btn_position', 'ever_compare_settings_tabs', 'after_cart_btn' );
51
+ $product_page_btn_position = woolentor_get_option( 'product_btn_position', 'ever_compare_settings_tabs', 'after_cart_btn' );
52
+ $button_style = woolentor_get_option( 'button_style', 'ever_compare_style_tabs', 'theme' );
53
+
54
+ $button_class = array(
55
+ 'htcompare-btn',
56
+ 'htcompare-btn-style-'.$button_style,
57
+ 'htcompare-shop-'.$shop_page_btn_position,
58
+ 'htcompare-product-'.$product_page_btn_position,
59
+ );
60
+
61
+ if( $button_style === 'theme' ){
62
+ $button_class[] = 'button';
63
+ }
64
+
65
+ $button_icon = $this->get_icon();
66
+ $added_button_icon = $this->get_icon('added_');
67
+
68
+ if( !empty( $button_text ) ){
69
+ $button_text = '<span class="evercompare-btn-text">'.$button_text.'</span>';
70
+ }
71
+
72
+ if( !empty( $button_added_text ) ){
73
+ $button_added_text = '<span class="evercompare-btn-text">'.$button_added_text.'</span>';
74
+ }
75
+
76
+ // Shortcode atts
77
+ $default_atts = array(
78
+ 'product_id' => $product->get_id(),
79
+ 'button_url' => Manage_Compare::instance()->get_compare_page_url(),
80
+ 'button_class' => implode(' ', $button_class ),
81
+ 'button_text' => $button_icon.$button_text,
82
+ 'button_added_text' => $added_button_icon.$button_added_text,
83
+ 'template_name' => 'add',
84
+ );
85
+
86
+ $atts = shortcode_atts( $default_atts, $atts, $content );
87
+ return Manage_Compare::instance()->button_html( $atts );
88
+
89
+ }
90
+
91
+ /**
92
+ * [table_shortcode] Compare table shortcode callable function
93
+ * @param [type] $atts
94
+ * @param string $content
95
+ * @return [HTML]
96
+ */
97
+ public function table_shortcode( $atts, $content = '' ){
98
+
99
+ wp_enqueue_style( 'evercompare-frontend' );
100
+ wp_enqueue_script( 'evercompare-frontend' );
101
+
102
+ /* Fetch From option data */
103
+ $empty_compare_text = woolentor_get_option('empty_table_text','ever_compare_table_settings_tabs');
104
+ $return_shop_button = woolentor_get_option('shop_button_text','ever_compare_table_settings_tabs','Return to shop');
105
+
106
+ /* Product and Field */
107
+ $products = Manage_Compare::instance()->get_compared_products_data();
108
+ $fields = Manage_Compare::instance()->get_compare_fields();
109
+
110
+ $custom_heading = !empty( woolentor_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) ) ? woolentor_get_option( 'table_heading', 'ever_compare_table_settings_tabs' ) : array();
111
+
112
+ $default_atts = array(
113
+ 'evercompare' => Manage_Compare::instance(),
114
+ 'products' => $products,
115
+ 'fields' => $fields,
116
+ 'return_shop_button'=> $return_shop_button,
117
+ 'heading_txt' => $custom_heading,
118
+ 'empty_compare_text'=> $empty_compare_text,
119
+ );
120
+
121
+ $atts = shortcode_atts( $default_atts, $atts, $content );
122
+ return Manage_Compare::instance()->table_html( $atts );
123
+
124
+ }
125
+
126
+ /**
127
+ * [get_icon]
128
+ * @param string $type
129
+ * @return [HTML]
130
+ */
131
+ public function get_icon( $type = '' ){
132
+
133
+ $arrContextOptions = [
134
+ 'ssl' => [
135
+ 'verify_peer' => false,
136
+ 'verify_peer_name' => false,
137
+ ]
138
+ ];
139
+
140
+ $default_icon = file_get_contents( EVERCOMPARE_ASSETS .'/images/icon.svg', false, stream_context_create($arrContextOptions) );
141
+ $default_loader = '<span class="ever-compare-loader">'.file_get_contents( EVERCOMPARE_ASSETS .'/images/loading.svg', false, stream_context_create($arrContextOptions) ).'</span>';
142
+
143
+ $button_text = ( $type === 'added' ) ? woolentor_get_option( 'added_button_text','ever_compare_settings_tabs', 'Added' ) : woolentor_get_option( 'button_text','ever_compare_settings_tabs', 'Compare' );
144
+
145
+ $button_icon_type = woolentor_get_option( $type.'button_icon_type', 'ever_compare_settings_tabs', 'default' );
146
+
147
+ if( $button_icon_type === 'custom' ){
148
+ $button_icon = woolentor_get_option( $type.'button_custom_icon','ever_compare_settings_tabs', '' );
149
+ }elseif( $button_icon_type === 'default' ){
150
+ return $default_icon;
151
+ }else{
152
+ $button_icon = '';
153
+ }
154
+
155
+ if( !empty( $button_icon ) ){
156
+ $button_icon = '<span class="ever-compare-btn-image"><img src="'.esc_url( $button_icon ).'" alt="'.esc_attr( $button_text ).'"></span>';
157
+ }
158
+
159
+ return $default_loader.$button_icon;
160
+
161
+ }
162
+
163
+
164
+ }
includes/modules/compare/includes/classes/Installer.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace EverCompare;
3
+ /**
4
+ * Installer class
5
+ */
6
+ class Installer {
7
+
8
+ /**
9
+ * Run the installer
10
+ *
11
+ * @return void
12
+ */
13
+ public function run() {
14
+ $this->create_page();
15
+ }
16
+
17
+ /**
18
+ * [create_page] Create page
19
+ * @return [void]
20
+ */
21
+ private function create_page() {
22
+ if ( function_exists( 'WC' ) ) {
23
+ if ( !function_exists( 'wc_create_page' ) ) {
24
+ require_once WC_ABSPATH . '/includes/admin/wc-admin-functions.php';
25
+ }
26
+ $create_page_id = wc_create_page(
27
+ sanitize_title_with_dashes( _x( 'evercompare', 'page_slug', 'ever-compare' ) ),
28
+ '',
29
+ __( 'EverCompare', 'ever-compare' ),
30
+ '<!-- wp:shortcode -->[evercompare_table]<!-- /wp:shortcode -->'
31
+ );
32
+ if( $create_page_id ){
33
+ woolentor_update_option( 'ever_compare_table_settings_tabs','compare_page', $create_page_id );
34
+ }
35
+ }
36
+ }
37
+
38
+
39
+ }
includes/modules/compare/includes/helper-functions.php ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Get Post List
4
+ * return array
5
+ */
6
+ function ever_compare_get_post_list( $post_type = 'page' ){
7
+ $options = array();
8
+ $options['0'] = __('Select','ever-compare');
9
+ $perpage = -1;
10
+ $all_post = array( 'posts_per_page' => $perpage, 'post_type'=> $post_type );
11
+ $post_terms = get_posts( $all_post );
12
+ if ( ! empty( $post_terms ) && ! is_wp_error( $post_terms ) ){
13
+ foreach ( $post_terms as $term ) {
14
+ $options[ $term->ID ] = $term->post_title;
15
+ }
16
+ return $options;
17
+ }
18
+ }
19
+
20
+ /**
21
+ * [ever_compare_locate_template]
22
+ * @param [string] $tmp_name Template name
23
+ * @return [Template path]
24
+ */
25
+ function ever_compare_locate_template( $tmp_name ) {
26
+
27
+ $woo_tmp_base = function_exists('WC') ? WC()->template_path() : '';
28
+
29
+ $woo_tmp_path = $woo_tmp_base . $tmp_name; //active theme directory/woocommerce/
30
+ $theme_tmp_path = '/' . $tmp_name; //active theme root directory
31
+ $plugin_tmp_path = EVERCOMPARE_DIR . 'includes/templates/' . $tmp_name;
32
+
33
+ $located = locate_template( [ $woo_tmp_path, $theme_tmp_path ] );
34
+
35
+ if ( ! $located && file_exists( $plugin_tmp_path ) ) {
36
+ return apply_filters( 'evercompare_locate_template', $plugin_tmp_path, $tmp_name );
37
+ }
38
+
39
+ return apply_filters( 'evercompare_locate_template', $located, $tmp_name );
40
+ }
41
+
42
+ /**
43
+ * [ever_compare_get_template]
44
+ * @param [string] $tmp_name Template name
45
+ * @param [array] $args template argument array
46
+ * @param boolean $echo
47
+ * @return [void]
48
+ */
49
+ function ever_compare_get_template( $tmp_name = '', $args = null, $echo = true ) {
50
+ $located = ever_compare_locate_template( $tmp_name );
51
+
52
+ if ( $args && is_array( $args ) ) {
53
+ extract( $args );
54
+ }
55
+
56
+ if ( $echo !== true ) { ob_start(); }
57
+
58
+ // include file located.
59
+ include( $located );
60
+
61
+ if ( $echo !== true ) { return ob_get_clean(); }
62
+
63
+ }
64
+
65
+
66
+ /**
67
+ * Get default fields List
68
+ * return array
69
+ */
70
+ function ever_compare_get_default_fields(){
71
+ $fields = array(
72
+ 'title' => esc_html__( 'Title', 'ever-compare' ),
73
+ 'ratting' => esc_html__( 'Ratting', 'ever-compare' ),
74
+ 'price' => esc_html__( 'Price', 'ever-compare' ),
75
+ 'add_to_cart' => esc_html__( 'Add To Cart', 'ever-compare' ),
76
+ 'description' => esc_html__( 'Description', 'ever-compare' ),
77
+ 'availability' => esc_html__( 'Availability', 'ever-compare' ),
78
+ 'sku' => esc_html__( 'Sku', 'ever-compare' ),
79
+ 'weight' => esc_html__( 'Weight', 'ever-compare' ),
80
+ 'dimensions' => esc_html__( 'Dimensions', 'ever-compare' ),
81
+ );
82
+ return apply_filters( 'ever_compare_default_fields', $fields );
83
+ }
84
+
85
+ /**
86
+ * Get Fields List
87
+ * return array
88
+ */
89
+ function ever_compare_get_available_attributes() {
90
+ $attribute_list = array();
91
+
92
+ if( function_exists( 'wc_get_attribute_taxonomies' ) ) {
93
+ $attribute_list = wc_get_attribute_taxonomies();
94
+ }
95
+
96
+ $fields = ever_compare_get_default_fields();
97
+
98
+ if ( count( $attribute_list ) > 0 ) {
99
+ foreach ( $attribute_list as $attribute ) {
100
+ $fields[ 'pa_' . $attribute->attribute_name ] = $attribute->attribute_label;
101
+ }
102
+ }
103
+
104
+ return $fields;
105
+ }
106
+
107
+ /**
108
+ * [ever_compare_table_active_heading]
109
+ * @return [array]
110
+ */
111
+ function ever_compare_table_active_heading(){
112
+ $active_heading = !empty( woolentor_get_option( 'show_fields', 'ever_compare_table_settings_tabs' ) ) ? woolentor_get_option( 'show_fields', 'ever_compare_table_settings_tabs' ) : array();
113
+ return $active_heading;
114
+ }
115
+
116
+ /**
117
+ * [ever_compare_table_heading]
118
+ * @return [array]
119
+ */
120
+ function ever_compare_table_heading(){
121
+ $new_list = array();
122
+ $field_list = count( ever_compare_table_active_heading() ) > 0 ? ever_compare_table_active_heading() : ever_compare_get_default_fields();
123
+ foreach ( $field_list as $key => $value ) {
124
+ $new_list[$key] = \EverCompare\Frontend\Manage_Compare::instance()->field_name( $key );
125
+ }
126
+ return $new_list;
127
+ }
128
+
129
+ /**
130
+ * [ever_compare_dimensions]
131
+ * @param [string] $key
132
+ * @param [string] $tab
133
+ * @return [String | Bool]
134
+ */
135
+ function ever_compare_dimensions( $key, $tab, $css_attr ){
136
+ $dimensions = !empty( woolentor_get_option( $key, $tab ) ) ? woolentor_get_option( $key, $tab ) : array();
137
+ if( !empty( $dimensions['top'] ) || !empty( $dimensions['right'] ) || !empty( $dimensions['bottom'] ) || !empty( $dimensions['left'] ) ){
138
+
139
+ $unit = ( empty( $dimensions['unit'] ) ? 'px' : $dimensions['unit'] );
140
+ $top = ( !empty( $dimensions['top'] ) ? $dimensions['top'] : 0 );
141
+ $right = ( !empty( $dimensions['right'] ) ? $dimensions['right'] : 0 );
142
+ $bottom = ( !empty( $dimensions['bottom'] ) ? $dimensions['bottom'] : 0 );
143
+ $left = ( !empty( $dimensions['left'] ) ? $dimensions['left'] : 0 );
144
+
145
+ $css_attr .= ":{$top}{$unit} {$right}{$unit} {$bottom}{$unit} {$left}{$unit}";
146
+ return $css_attr.';';
147
+
148
+ }else{
149
+ return false;
150
+ }
151
+ }
152
+
153
+ /**
154
+ * [ever_compare_generate_css]
155
+ * @return [String | Bool]
156
+ */
157
+ function ever_compare_generate_css( $key, $tab, $css_attr, $unit = '' ){
158
+ $field_value = !empty( woolentor_get_option( $key, $tab ) ) ? woolentor_get_option( $key, $tab ) : '';
159
+
160
+ if( !empty( $field_value ) ){
161
+ $css_attr .= ":{$field_value}{$unit}";
162
+ return $css_attr.';';
163
+ }else{
164
+ return false;
165
+ }
166
+
167
+ }
includes/modules/compare/includes/templates/evercompare-button-add.php ADDED
@@ -0,0 +1 @@
 
1
+ <span class="htcompare-button-area"><a href="<?php echo esc_url( $button_url ); ?>" class="<?php echo $button_class; ?>" data-added-text="<?php echo esc_attr__( $button_added_text, 'ever-compare'); ?>" data-product_id="<?php echo esc_attr( $product_id ); ?>"><?php echo $button_text; ?></a></span>
includes/modules/compare/includes/templates/evercompare-table.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="htcompare-table">
2
+ <?php
3
+ do_action( 'ever_compare_before_table' );
4
+
5
+ if ( ! empty( $products ) ) {
6
+ array_unshift( $products, array() );
7
+ foreach ( $fields as $field_id => $field ) {
8
+ if ( ! $evercompare->is_products_have_field( $field_id, $products ) ) {
9
+ continue;
10
+ }
11
+
12
+ // Generate Filed name
13
+ $name = $evercompare->field_name( $field );
14
+ if( array_key_exists( $field_id, $heading_txt ) && !empty( $heading_txt[$field_id] ) ){
15
+ $name = $evercompare->field_name( $heading_txt[$field_id], true );
16
+ }
17
+
18
+ ?>
19
+ <div class="htcompare-row compare-data-<?php echo esc_attr( $field_id ); ?>">
20
+ <?php foreach ( $products as $product_id => $product ) : ?>
21
+ <?php if ( ! empty( $product ) ) : ?>
22
+ <div class="htcompare-col htcolumn-value" data-title="<?php echo esc_attr( $name ); ?>">
23
+ <?php $evercompare->compare_display_field( $field_id, $product ); ?>
24
+ </div>
25
+ <?php else: ?>
26
+ <div class="htcompare-col htcolumn-field-name">
27
+ <?php echo esc_html( $name ); ?>
28
+ </div>
29
+ <?php endif; ?>
30
+ <?php endforeach ?>
31
+ </div>
32
+ <?php
33
+ }
34
+ echo '<div class="htcompare-table-loader"></div>';
35
+ } else {
36
+ if ( $empty_compare_text ){
37
+ echo '<div class="htcompare-empty-page-text">'.wp_kses_post( $empty_compare_text ).'</div>';
38
+ }
39
+
40
+ if( $return_shop_button ){
41
+ echo '<div class="htcompare-return-to-shop"><a href="'.esc_url( wc_get_page_permalink( 'shop' ) ).'" class="button">'.esc_html__( $return_shop_button, 'ever-compare' ).'</a></div>';
42
+ }
43
+ }
44
+
45
+ do_action( 'ever_compare_after_table' );
46
+ ?>
47
+ </div>
includes/modules/compare/init.php ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
+
4
+ /**
5
+ * Plugin Main Class
6
+ */
7
+ final class Woolentor_Ever_Compare{
8
+
9
+ /**
10
+ * [$_instance]
11
+ * @var null
12
+ */
13
+ private static $_instance = null;
14
+
15
+ /**
16
+ * [instance] Initializes a singleton instance
17
+ * @return [Base]
18
+ */
19
+ public static function instance() {
20
+ if ( is_null( self::$_instance ) ) {
21
+ self::$_instance = new self();
22
+ }
23
+ return self::$_instance;
24
+ }
25
+
26
+ /**
27
+ * [__construct] Class Constructor
28
+ */
29
+ private function __construct(){
30
+
31
+ $this->define_constants();
32
+ $this->includes();
33
+ if( get_option('woolentor_compare_status', 'no') === 'no' ){
34
+ $this->activate();
35
+ update_option( 'woolentor_compare_status','yes' );
36
+ }
37
+ $this->init_plugin();
38
+
39
+ }
40
+
41
+ /**
42
+ * Define the required plugin constants
43
+ *
44
+ * @return void
45
+ */
46
+ public function define_constants() {
47
+ define( 'EVERCOMPARE_FILE', __FILE__ );
48
+ define( 'EVERCOMPARE_DIR', plugin_dir_path( EVERCOMPARE_FILE ) );
49
+ define( 'EVERCOMPARE_URL', plugins_url( '', EVERCOMPARE_FILE ) );
50
+ define( 'EVERCOMPARE_ASSETS', EVERCOMPARE_URL . '/assets' );
51
+ }
52
+
53
+ /**
54
+ * [includes] Load file
55
+ * @return [void]
56
+ */
57
+ public function includes(){
58
+ require_once(__DIR__ . '/includes/classes/Installer.php');
59
+ require_once(__DIR__ . '/includes/helper-functions.php');
60
+ require_once(__DIR__ . '/includes/classes/Assets.php');
61
+ require_once(__DIR__ . '/includes/classes/Admin.php');
62
+ require_once(__DIR__ . '/includes/classes/Frontend.php');
63
+ require_once(__DIR__ . '/includes/classes/Ajax.php');
64
+ }
65
+
66
+ /**
67
+ * Initialize the plugin
68
+ *
69
+ * @return void
70
+ */
71
+ public function init_plugin() {
72
+
73
+ EverCompare\Assets::instance();
74
+
75
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
76
+ EverCompare\Ajax::instance();
77
+ }
78
+
79
+ if ( is_admin() ) {
80
+ EverCompare\Admin::instance();
81
+ }
82
+ EverCompare\Frontend::instance();
83
+
84
+ // add image size
85
+ $this->set_image_size();
86
+
87
+ // let's filter the woocommerce image size
88
+ add_filter( 'woocommerce_get_image_size_ever-compare-image', [ $this, 'wc_image_filter_size' ], 10, 1 );
89
+
90
+ }
91
+
92
+ /**
93
+ * Do stuff upon plugin activation
94
+ *
95
+ * @return void
96
+ */
97
+ public function activate() {
98
+ $installer = new EverCompare\Installer();
99
+ $installer->run();
100
+ }
101
+
102
+ /**
103
+ * [set_image_size] Set Image Size
104
+ */
105
+ public function set_image_size(){
106
+
107
+ $image_dimention = woolentor_get_option( 'image_size', 'ever_compare_table_settings_tabs', array( 'width'=>300, 'height'=>300 ) );
108
+ if( isset( $image_dimention ) && is_array( $image_dimention ) ){
109
+ $hard_crop = !empty( woolentor_get_option( 'hard_crop', 'ever_compare_table_settings_tabs' ) ) ? true : false;
110
+ add_image_size( 'ever-compare-image', $image_dimention['width'], $image_dimention['height'], $hard_crop );
111
+ }
112
+
113
+ }
114
+
115
+ /**
116
+ * [wc_image_filter_size]
117
+ * @return [array]
118
+ */
119
+ public function wc_image_filter_size(){
120
+
121
+ $image_dimention = woolentor_get_option( 'image_size', 'ever_compare_table_settings_tabs', array('width'=>300,'height'=>300) );
122
+ $hard_crop = !empty( woolentor_get_option( 'hard_crop', 'ever_compare_table_settings_tabs' ) ) ? true : false;
123
+
124
+ if( isset( $image_dimention ) && is_array( $image_dimention ) ){
125
+ return array(
126
+ 'width' => isset( $image_dimention['width'] ) ? absint( $image_dimention['width'] ) : 300,
127
+ 'height' => isset( $image_dimention['height'] ) ? absint( $image_dimention['height'] ) : 300,
128
+ 'crop' => isset( $hard_crop ) ? 1 : 0,
129
+ );
130
+ }
131
+
132
+ }
133
+
134
+ }
135
+
136
+ /**
137
+ * Initializes the main plugin
138
+ *
139
+ * @return Woolentor_Ever_Compare
140
+ */
141
+ function woolentor_ever_compare() {
142
+ return Woolentor_Ever_Compare::instance();
143
+ }
144
+ woolentor_ever_compare();
includes/modules/flash-sale/assets/css/flash-sale.css CHANGED
@@ -1,45 +1,540 @@
1
- /*Countdown*/
2
- .ht-saleflash-countdown-wrap{
3
- margin-bottom: 15px;
4
- }
5
- .ht-saleflash-countdown-wrap .ht-product-countdown {
6
- display: -webkit-box;
7
- display: -webkit-flex;
8
- display: -ms-flexbox;
9
- display: flex;
10
- margin-left: -2px;
11
  }
12
-
13
- .ht-saleflash-countdown-wrap.ht-align--center .ht-product-countdown {
14
- margin: auto;
15
- justify-content: center;
 
 
 
 
16
  }
17
-
18
- .ht-saleflash-countdown-wrap.ht-align--center{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  text-align: center;
20
- }
21
-
22
- .ht-saleflash-countdown-wrap .ht-saleflash-countdown-title{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  font-weight: 500;
24
- }
25
-
26
- .ht-saleflash-countdown-wrap .ht-product-countdown .cd-single {
27
- padding: 2px;
28
- min-width: 60px;
29
- }
30
-
31
- .ht-saleflash-countdown-wrap .ht-product-countdown .cd-single .cd-single-inner {
32
  text-align: center;
33
- border: 1px solid;
34
- }
35
-
36
- .ht-saleflash-countdown-wrap .ht-product-countdown .cd-single .cd-single-inner h3 {
37
- font-size: 15px;
38
- font-weight: 700;
39
- margin: 2px 0 2px;
40
- }
41
-
42
- .ht-saleflash-countdown-wrap .ht-product-countdown .cd-single .cd-single-inner p {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  font-size: 12px;
44
- margin: 0 0 2px;
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Cart page */
2
+ .woocommerce dt.variation-woolentor_cart_flash_sale_label{
3
+ display: none !important;
 
 
 
 
 
 
 
4
  }
5
+ .woolentor-flashsale-label{
6
+ font-size: 12px;
7
+ padding: 3px 5px;
8
+ border-radius: 3px;
9
+ border: 1px dashed red;
10
+ margin-top: 3px;
11
+ display: inline-block;
12
+ line-height: 1;
13
  }
14
+ /*Product Flash Sale Start */
15
+ .woolentor-flash-product {
16
+ border-radius: 5px;
17
+ background-color: #FAFAFA;
18
+ }
19
+ .woolentor-flash-product-thumb {
20
+ position: relative;
21
+ display: block;
22
+ padding: 10px;
23
+ padding-bottom: 0;
24
+ }
25
+ .woolentor-flash-product-thumb .woolentor-countdown {
26
+ position: absolute;
27
+ z-index: 99;
28
+ bottom: 0;
29
+ left: 10px;
30
+ display: none;
31
+ width: calc(100% - 20px);
32
+ padding: 10px;
33
+ background-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.25) 100%);
34
+ }
35
+ .woolentor-flash-product-thumb .woolentor-flash-product-action {
36
+ position: absolute;
37
+ top: 50%;
38
+ right: 10px;
39
+ left: 10px;
40
+ display: flex;
41
+ visibility: hidden;
42
+ margin-top: 20px;
43
+ padding: 0;
44
+ transform: translateY(-50%);
45
+ opacity: 0;
46
+ background-color: transparent;
47
+ }
48
+ @media only screen and (max-width: 767px) {
49
+ .woolentor-flash-product-thumb .woolentor-flash-product-action {
50
+ display: none;
51
+ }
52
+ }
53
+ .woolentor-flash-product-image {
54
+ display: flex;
55
+ overflow: hidden;
56
+ transition: all 0.3s ease 0s;
57
+ border-radius: 5px;
58
+ }
59
+ .woolentor-flash-product-image img {
60
+ width: 100%;
61
+ }
62
+ .woolentor-flash-product-content {
63
+ position: relative;
64
+ display: flex;
65
+ flex-direction: column;
66
+ padding: 20px;
67
+ }
68
+ .woolentor-flash-product-offer-timer {
69
+ margin: 0 -20px 20px;
70
+ padding: 0 20px 20px;
71
+ border-bottom: 1px solid #E5E5E5;
72
+ }
73
+ .woolentor-flash-product-offer-timer-text {
74
+ font-size: 14px;
75
+ margin-bottom: 15px;
76
  text-align: center;
77
+ color: #000000;
78
+ }
79
+ .woolentor-flash-product-progress {
80
+ display: flex;
81
+ flex-direction: column;
82
+ margin-bottom: 20px;
83
+ }
84
+ .woolentor-flash-product-progress-total {
85
+ width: 100%;
86
+ height: 10px;
87
+ border-radius: 10px;
88
+ background-color: #B6FAFF;
89
+ }
90
+ .woolentor-flash-product-progress-sold {
91
+ height: 100%;
92
+ border-radius: 10px;
93
+ background-color: #32C1CD;
94
+ }
95
+ .woolentor-flash-product-progress-label,
96
+ .woolentor-flash-product .woolentor-stock-message {
97
+ font-size: 13px;
98
+ line-height: 1.538;
99
+ display: flex;
100
+ justify-content: space-between;
101
+ margin-top: 5px;
102
+ }
103
+ .woolentor-flash-product .woolentor-stock-message{
104
+ display: inline-block;
105
+ text-align: center;
106
+ }
107
+ .woolentor-flash-product-title,
108
+ .woolentor-flash-product-title a {
109
+ font-size: 18px;
110
  font-weight: 500;
111
+ line-height: 1.444;
112
+ max-width: 260px;
113
+ margin: 0 auto 15px;
 
 
 
 
 
114
  text-align: center;
115
+ }
116
+ .woolentor-flash-product-title a {
117
+ transition: all 0.3s ease 0s;
118
+ text-decoration: none;
119
+ color: #000000;
120
+ }
121
+ .woolentor-flash-product-title a:hover {
122
+ text-decoration: underline;
123
+ }
124
+ .woolentor-flash-product-price-rating {
125
+ display: flex;
126
+ align-items: center;
127
+ flex-wrap: wrap;
128
+ justify-content: space-between;
129
+ }
130
+ .woolentor-flash-product-price-rating i{
131
+ color: #ecb804;
132
+ }
133
+ .woolentor-flash-product-price .price {
134
+ display: flex;
135
+ align-items: center;
136
+ color: #000000;
137
+ gap: 10px;
138
+ }
139
+ .woolentor-flash-product-price span {
140
+ line-height: 1;
141
+ }
142
+ .woolentor-flash-product-price .price{
143
+ font-size: 24px;
144
+ font-weight: 500;
145
+ }
146
+ .woolentor-flash-product-price .price ins{
147
+ margin-left: 0;
148
+ order: 0;
149
+ }
150
+ .woolentor-flash-product-price .price del {
151
+ font-size: 16px;
152
+ text-decoration: line-through;
153
+ color: #666666;
154
+ margin-left: 0;
155
+ order: 1;
156
+ }
157
+ .woolentor-flash-product-rating {
158
+ font-size: 16px;
159
+ font-weight: 500;
160
+ line-height: 1;
161
+ display: flex;
162
+ align-items: center;
163
+ gap: 5px;
164
+ }
165
+ .woolentor-flash-product-price-rating.woolentor-product-has-no-rating{
166
+ justify-content: center;
167
+ }
168
+ .woolentor-flash-product-rating span {
169
+ transform: translateY(1px);
170
+ }
171
+ .woolentor-flash-product-action {
172
+ z-index: 111;
173
+ display: none;
174
+ justify-content: center;
175
+ order: 12;
176
+ padding-top: 20px;
177
+ transition: all 0.3s ease 0s;
178
+ gap: 5px;
179
+ margin: 0;
180
+ padding: 0;
181
+ list-style: none;
182
+ }
183
+ @media only screen and (max-width: 767px) {
184
+ .woolentor-flash-product-action {
185
+ display: flex;
186
+ }
187
+ }
188
+ .woolentor-flash-product-action-btn.added{
189
+ display: none;
190
+ }
191
+ .woolentor-flash-product-action .yith-wcwl-add-to-wishlist i{
192
+ margin: 0;
193
+ }
194
+ .woolentor-flash-product-action a,
195
+ .woolentor-flash-product-action .added_to_cart {
196
+ font-size: 16px;
197
+ display: flex;
198
+ align-items: center;
199
+ justify-content: center;
200
+ width: 50px;
201
+ height: 50px;
202
+ transition: all 0.3s ease 0s;
203
+ text-decoration: none;
204
+ color: #FFFFFF;
205
+ border-radius: 50%;
206
+ background-color: #272626;
207
+ position: relative;
208
+ }
209
+ @media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
210
+ .woolentor-flash-product-action-btn {
211
+ font-size: 14px;
212
+ width: 40px;
213
+ height: 40px;
214
+ }
215
+ }
216
+ @media only screen and (max-width: 575px) {
217
+ .woolentor-flash-product-action-btn {
218
+ font-size: 16px;
219
+ width: 50px;
220
+ height: 50px;
221
+ }
222
+ }
223
+ .woolentor-flash-product-action a:hover {
224
+ color: #FFFFFF;
225
+ background-color: #DC9A0E;
226
+ }
227
+ .woolentor-flash-product:hover .woolentor-flash-product-action {
228
+ visibility: visible;
229
+ margin-top: 0;
230
+ opacity: 1;
231
+ }
232
+ /*Action buttons adjustment*/
233
+ .woolentor-flash-product-action a.added_to_cart.wc-forward {
234
+ text-indent: -9999px;
235
+ position: relative;
236
+ text-align: center;
237
+ }
238
+ .woolentor-flash-product-action-btn.loading{
239
+ position: relative;
240
+ }
241
+ .woolentor-flash-product-action-btn.loading i{
242
+ display: none;
243
+ }
244
+ .woolentor-flash-product-action a.added_to_cart.wc-forward:after {
245
+ position: absolute;
246
+ text-indent: 0;
247
+ content: "\e017";
248
+ font-family: WooCommerce;
249
+ left: 0;
250
+ right: 0;
251
+ font-size: 18px;
252
+ margin: 0;
253
+ top: 50%;
254
+ transform: translateY(-50%);
255
+ }
256
+ .woolentor-flash-product-action-btn.loading::after{
257
+ font-family: WooCommerce;
258
+ content: '\e01c';
259
+ vertical-align: top;
260
+ -webkit-font-smoothing: antialiased;
261
+ font-weight: 400;
262
+ position: absolute;
263
+ top: auto;
264
+ right: 1em;
265
+ animation: spin 2s linear infinite;
266
+ }
267
+ .woolentor-flash-product-action .woolentor-compare.compare::before{
268
+ align-items: center;
269
+ line-height: unset;
270
+ }
271
+ .woolentor-flash-product-action .woolentor-compare.added i::before{
272
+ content: "\f00c";
273
+ }
274
+
275
+ .woolentor-flash-product-offer-pos-c-bottom .woolentor-flash-product-offer-timer {
276
+ order: 11;
277
+ margin-top: 20px;
278
+ margin-bottom: 0;
279
+ padding-top: 20px;
280
+ padding-bottom: 0;
281
+ border-top: 1px solid #E5E5E5;
282
+ border-bottom: 0;
283
+ }
284
+ .woolentor-flash-product-offer-pos-t-bottom .woolentor-flash-product-offer-timer {
285
+ display: none;
286
+ }
287
+ .woolentor-flash-product-offer-pos-t-bottom .woolentor-flash-product-thumb .woolentor-countdown {
288
+ display: flex;
289
+ }
290
+ .woolentor-flash-product-offer-pos-t-left .woolentor-flash-product-offer-timer {
291
+ display: none;
292
+ }
293
+ .woolentor-flash-product-offer-pos-t-left .woolentor-flash-product-thumb .woolentor-countdown {
294
+ top: 10px;
295
+ display: flex;
296
+ flex-direction: column;
297
+ width: auto;
298
+ background-image: linear-gradient(to left, transparent 0%, rgba(0, 0, 0, 0.25) 100%);
299
+ }
300
+ .woolentor-flash-product-offer-pos-t-right .woolentor-flash-product-offer-timer {
301
+ display: none;
302
+ }
303
+ .woolentor-flash-product-offer-pos-t-right .woolentor-flash-product-thumb .woolentor-countdown {
304
+ top: 10px;
305
+ right: 10px;
306
+ left: auto;
307
+ display: flex;
308
+ flex-direction: column;
309
+ width: auto;
310
+ background-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.25) 100%);
311
+ }
312
+
313
+ .woolentor-countdown-flip{
314
+ display: flex;
315
+ flex-wrap: wrap;
316
+ justify-content: space-between;
317
+ width: 100%;
318
+ height: auto;
319
+ border-radius: 5px;
320
+ }
321
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner {
322
+ position: relative;
323
+ display: block;
324
+ width: 60px;
325
+ height: 50px;
326
+ transform: translateZ(0);
327
+ transform: translate3d(0, 0, 0);
328
+ text-align: center;
329
+ border-radius: 5px;
330
+ -webkit-backface-visibility: hidden;
331
+ backface-visibility: hidden;
332
+ perspective: 479px;
333
+ }
334
+ @media only screen and (min-width: 992px) and (max-width: 1199px) {
335
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner {
336
+ width: 52px;
337
+ height: 36px;
338
+ }
339
+ }
340
+ @media only screen and (min-width: 768px) and (max-width: 991px) {
341
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner {
342
+ height: 46px;
343
+ }
344
+ }
345
+ @media only screen and (max-width: 767px) {
346
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner {
347
+ width: 40px;
348
+ height: 28px;
349
+ }
350
+ }
351
+ @media only screen and (max-width: 575px) {
352
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner {
353
+ width: 60px;
354
+ height: 46px;
355
+ }
356
+ }
357
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count {
358
+ font-size: 36px;
359
+ line-height: 50px;
360
+ position: absolute;
361
+ top: 0;
362
+ display: flex;
363
+ overflow: hidden;
364
+ justify-content: center;
365
+ width: 100%;
366
+ transform: translateZ(0);
367
+ color: #FFFFFF;
368
+ background-color: #272626;
369
+ transform-style: flat;
370
+ }
371
+ @media only screen and (min-width: 992px) and (max-width: 1199px) {
372
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count {
373
+ font-size: 24px;
374
+ line-height: 36px;
375
+ }
376
+ }
377
+ @media only screen and (min-width: 768px) and (max-width: 991px) {
378
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count {
379
+ line-height: 46px;
380
+ }
381
+ }
382
+ @media only screen and (max-width: 767px) {
383
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count {
384
+ font-size: 20px;
385
+ line-height: 28px;
386
+ }
387
+ }
388
+ @media only screen and (max-width: 575px) {
389
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count {
390
+ font-size: 36px;
391
+ line-height: 50px;
392
+ }
393
+ }
394
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count.woolentor-top {
395
+ height: 50%;
396
+ transform-origin: 50% 100%;
397
+ border-radius: 5px 5px 0 0;
398
+ }
399
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count.woolentor-top.woolentor-curr {
400
+ z-index: 3;
401
+ transform: rotateX(0deg);
402
+ }
403
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count.woolentor-bottom {
404
+ line-height: 0;
405
+ top: 50%;
406
+ height: 50%;
407
+ transform-origin: 50% 0;
408
+ border-top: 1px solid #FFFFFF;
409
+ border-radius: 0 0 5px 5px;
410
+ }
411
+ .woolentor-countdown-flip .woolentor-time .woolentor-time-inner .woolentor-count.woolentor-bottom.woolentor-next {
412
+ z-index: 2;
413
+ transform: rotateX(90deg);
414
+ }
415
+ .woolentor-countdown-flip .woolentor-time.woolentor-flip .woolentor-time-inner .woolentor-count.woolentor-top.woolentor-curr {
416
+ transition: all 250ms ease-in-out;
417
+ transform: rotateX(-90deg);
418
+ }
419
+ .woolentor-countdown-flip .woolentor-time.woolentor-flip .woolentor-time-inner .woolentor-count.woolentor-bottom.woolentor-next {
420
+ transition: all 250ms ease-in-out 250ms;
421
+ transform: rotateX(0deg);
422
+ }
423
+ .woolentor-countdown-flip .woolentor-time .woolentor-label {
424
+ font-family: "Montserrat", sans-serif;
425
  font-size: 12px;
426
+ font-weight: 600;
427
+ line-height: 1.25;
428
+ display: block;
429
+ width: 100%;
430
+ margin-top: 8px;
431
+ text-align: center;
432
+ }
433
+ @media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
434
+ .woolentor-countdown-flip .woolentor-time .woolentor-label {
435
+ margin-top: 4px;
436
+ }
437
+ }
438
+
439
+ .woolentor-countdown-default {
440
+ display: flex;
441
+ flex-wrap: wrap;
442
+ justify-content: space-between;
443
+ width: 100%;
444
+ border-radius: 5px;
445
+ }
446
+ .woolentor-countdown-default .woolentor-time .woolentor-count {
447
+ font-size: 36px;
448
+ line-height: 50px;
449
+ display: flex;
450
+ justify-content: center;
451
+ width: 60px;
452
+ color: #FFFFFF;
453
+ border-radius: 5px;
454
+ background-color: #272626;
455
+ }
456
+ @media only screen and (min-width: 992px) and (max-width: 1199px) {
457
+ .woolentor-countdown-default .woolentor-time .woolentor-count {
458
+ font-size: 24px;
459
+ line-height: 36px;
460
+ width: 52px;
461
+ }
462
+ }
463
+ @media only screen and (min-width: 768px) and (max-width: 991px) {
464
+ .woolentor-countdown-default .woolentor-time .woolentor-count {
465
+ line-height: 46px;
466
+ }
467
+ }
468
+ @media only screen and (max-width: 767px) {
469
+ .woolentor-countdown-default .woolentor-time .woolentor-count {
470
+ font-size: 20px;
471
+ line-height: 28px;
472
+ width: 40px;
473
+ }
474
+ }
475
+ @media only screen and (max-width: 575px) {
476
+ .woolentor-countdown-default .woolentor-time .woolentor-count {
477
+ font-size: 36px;
478
+ line-height: 46px;
479
+ width: 60px;
480
+ }
481
+ }
482
+ .woolentor-countdown-default .woolentor-time .woolentor-label {
483
+ font-family: "Montserrat", sans-serif;
484
+ font-size: 12px;
485
+ font-weight: 600;
486
+ line-height: 1.25;
487
+ display: block;
488
+ width: 100%;
489
+ margin-top: 8px;
490
+ text-align: center;
491
+ }
492
+ @media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
493
+ .woolentor-countdown-default .woolentor-time .woolentor-label {
494
+ margin-top: 4px;
495
+ }
496
+ }
497
+
498
+ /*Sale flash*/
499
+ .woolentor-flash-product-image span {
500
+ display: none;
501
+ background-color: #23252a;
502
+ border-radius: 3px;
503
+ color: #fff;
504
+ font-size: 14px;
505
+ font-weight: 500;
506
+ right: 15px;
507
+ top: 15px;
508
+ line-height: 1 !important;
509
+ min-height: inherit !important;
510
+ min-width: inherit !important;
511
+ padding: 5px 10px;
512
+ position: absolute;
513
+ }
514
+ .woolentor-flash-product-image span.ht-stockout{
515
+ display: inline-block;
516
+ background-color: #f05b64;
517
+ color: #fff;
518
+ }
519
+
520
+ /*Single product*/
521
+ .single-product .woolentor-flash-product-countdown{
522
+ margin-bottom: 20px;
523
+ }
524
+ .single-product .woolentor-flash-product-countdown .woolentor-countdown{
525
+ justify-content: initial;
526
+ }
527
+ .single-product .woolentor-flash-product-offer-timer-text{
528
+ text-align: left;
529
+ margin-bottom: 10px;
530
+ display: inline-block;
531
+ background-color: #272626;
532
+ color: #fff;
533
+ padding: 2px 15px;
534
+ border-radius: 5px;
535
+ margin-bottom: 10px;
536
+ }
537
+ .single-product .woolentor-flash-product-countdown .woolentor-time{
538
+ margin-right: 10px;
539
+ }
540
+ /* Product Flash Sale End */
includes/modules/flash-sale/assets/js/flash-sale.js CHANGED
@@ -1,20 +1,119 @@
1
  ;(function($){
2
  "use strict";
3
 
4
- $(document).ready(function(){
5
-
6
- // show countdown based on server timzone
7
- var finalTime, daysTime, hours, minutes, second;
8
- $('.ht-product-countdown').each(function() {
9
- var $this = $(this),
10
- finalDate = $(this).data('countdown'),
11
- customlavel = $(this).data('customlavel');
12
-
13
- $this.countdown(finalDate, function(event) {
14
- $this.html(event.strftime('<div class="cd-single"><div class="cd-single-inner"><h3>%D</h3><p>'+customlavel.daytxt+'</p></div></div><div class="cd-single"><div class="cd-single-inner"><h3>%H</h3><p>'+customlavel.hourtxt+'</p></div></div><div class="cd-single"><div class="cd-single-inner"><h3>%M</h3><p>'+customlavel.minutestxt+'</p></div></div><div class="cd-single"><div class="cd-single-inner"><h3>%S</h3><p>'+customlavel.secondstxt+'</p></div></div>'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
 
 
 
 
 
 
18
  });
19
 
20
  })(jQuery);
1
  ;(function($){
2
  "use strict";
3
 
4
+ // Flash sale countdown
5
+ function FlashSaleCountDownFlip($this, $time) {;
6
+ var customlavel = $this.data('customlavel');
7
+ var labels = [customlavel.daytxt, customlavel.hourtxt, customlavel.minutestxt, customlavel.secondstxt],
8
+ template = function(label, curr, next) {
9
+ return (
10
+ `<div class="woolentor-time woolentor-${label.toLowerCase()}">
11
+ <div class="woolentor-time-inner">
12
+ <span class="woolentor-count woolentor-curr woolentor-top">${curr}</span>
13
+ <span class="woolentor-count woolentor-next woolentor-top">${next}</span>
14
+ <span class="woolentor-count woolentor-next woolentor-bottom">${next}</span>
15
+ <span class="woolentor-count woolentor-curr woolentor-bottom">${curr}</span>
16
+ </div>
17
+ <span class="woolentor-label">${label.length < 6 ? label : label.substr(0, 3)}</span>
18
+ </div>`
19
+ )
20
+ },
21
+ currDate = '00:00:00:00',
22
+ nextDate = '00:00:00:00',
23
+ parser = /([0-9]{2})/gi;
24
+ // Parse countdown string to an object
25
+ function strfobj(str) {
26
+ var parsed = str.match(parser),
27
+ obj = {};
28
+ labels.forEach(function(label, i) {
29
+ obj[label] = parsed[i]
30
+ });
31
+ return obj;
32
+ }
33
+ // Return the time components that diffs
34
+ function diff(obj1, obj2) {
35
+ var diff = [];
36
+ labels.forEach(function(key) {
37
+ if (obj1[key] !== obj2[key]) {
38
+ diff.push(key);
39
+ }
40
  });
41
+ return diff;
42
+ }
43
+ // Build the layout
44
+ var initData = strfobj(currDate);
45
+ labels.forEach(function(label, i) {
46
+ $this.append(template(label, initData[label], initData[label]));
47
+ });
48
+ // Starts the countdown);
49
+ $this.countdown($time, function(event) {
50
+ var newDate = event.strftime('%D:%H:%M:%S'),
51
+ data;
52
+ if (newDate !== nextDate) {
53
+ currDate = nextDate;
54
+ nextDate = newDate;
55
+ // Setup the data
56
+ data = {
57
+ 'curr': strfobj(currDate),
58
+ 'next': strfobj(nextDate)
59
+ };
60
+ // Apply the new values to each node that changed
61
+ diff(data.curr, data.next).forEach(function(label) {
62
+ var selector = '.%s'.replace(/%s/, `woolentor-${label.toLowerCase()}`),
63
+ $node = $this.find(selector);
64
+ // Update the node
65
+ $node.removeClass('woolentor-flip');
66
+ $node.find('.woolentor-curr').text(data.curr[label]);
67
+ $node.find('.woolentor-next').text(data.next[label]);
68
+ // Wait for a repaint to then flip
69
+ setTimeout(function() {
70
+ $node.addClass('woolentor-flip');
71
+ })
72
+ });
73
+ }
74
  });
75
+ }
76
+
77
+ function flashsalecountdownhandler(){
78
+ $('.woolentor-countdown-flip').each(function() {
79
+ var $this = $(this),
80
+ endDate = $this.data('countdown'),
81
+ remainingTimeMillisecond = endDate * 1000, //multiply by 1000 because javascript timestamps are in ms;
82
+ currentTime = new Date();
83
+
84
+ endDate = new Date( currentTime.getTime() + remainingTimeMillisecond );
85
+
86
+ FlashSaleCountDownFlip($this, endDate);
87
+ });
88
+
89
+ $('.woolentor-countdown-default').each(function() {
90
+ var $this = $(this),
91
+ endDate = $this.data('countdown'),
92
+ remainingTimeMillisecond = endDate * 1000, //multiply by 1000 because javascript timestamps are in ms
93
+ customlavel = $(this).data('customlavel'),
94
+ currentTime = new Date(),
95
+ $template = `<div class="woolentor-time woolentor-days"><span class="woolentor-count">%D</span><span class="woolentor-label">${customlavel.daytxt}</span></div><div class="woolentor-time woolentor-hours"><span class="woolentor-count">%H</span><span class="woolentor-label">${customlavel.hourtxt}</span></div><div class="woolentor-time woolentor-mins"><span class="woolentor-count">%M</span><span class="woolentor-label">${customlavel.minutestxt}</span></div><div class="woolentor-time woolentor-secs"><span class="woolentor-count">%S</span><span class="woolentor-label">${customlavel.secondstxt}</span></div>`;
96
+
97
+ endDate = new Date( currentTime.getTime() + remainingTimeMillisecond );
98
+
99
+ $this.countdown(endDate, function(event) {
100
+ $this.html(event.strftime($template));
101
+ });
102
+ });
103
+ }
104
+
105
+ $(document).ready(function(){
106
+
107
+ flashsalecountdownhandler();
108
+
109
+ });
110
 
111
+ // For elementor editor
112
+ var flashsalecountdownhandler_elem = function countdownhandler_elem(){
113
+ flashsalecountdownhandler();
114
+ }
115
+ $(window).on('elementor/frontend/init', function () {
116
+ elementorFrontend.hooks.addAction( 'frontend/element_ready/woolentor-flash-sale-product.default', flashsalecountdownhandler_elem);
117
  });
118
 
119
  })(jQuery);
includes/modules/flash-sale/assets/js/moment-timezone-with-data.js DELETED
@@ -1 +0,0 @@
1
- !function(a,i){"use strict";"object"==typeof module&&module.exports?module.exports=i(require("moment")):"function"==typeof define&&define.amd?define(["moment"],i):i(a.moment)}(this,function(c){"use strict";void 0===c.version&&c.default&&(c=c.default);var i,A={},n={},t={},s={},u={};c&&"string"==typeof c.version||N("Moment Timezone requires Moment.js. See https://momentjs.com/timezone/docs/#/use-it/browser/");var a=c.version.split("."),e=+a[0],r=+a[1];function m(a){return 96<a?a-87:64<a?a-29:a-48}function o(a){var i=0,e=a.split("."),r=e[0],o=e[1]||"",c=1,A=0,n=1;for(45===a.charCodeAt(0)&&(n=-(i=1));i<r.length;i++)A=60*A+m(r.charCodeAt(i));for(i=0;i<o.length;i++)c/=60,A+=m(o.charCodeAt(i))*c;return A*n}function f(a){for(var i=0;i<a.length;i++)a[i]=o(a[i])}function l(a,i){var e,r=[];for(e=0;e<i.length;e++)r[e]=a[i[e]];return r}function p(a){var i=a.split("|"),e=i[2].split(" "),r=i[3].split(""),o=i[4].split(" ");return f(e),f(r),f(o),function(a,i){for(var e=0;e<i;e++)a[e]=Math.round((a[e-1]||0)+6e4*a[e]);a[i-1]=1/0}(o,r.length),{name:i[0],abbrs:l(i[1].split(" "),r),offsets:l(e,r),untils:o,population:0|i[5]}}function M(a){a&&this._set(p(a))}function d(a,i){this.name=a,this.zones=i}function b(a){var i=a.toTimeString(),e=i.match(/\([a-z ]+\)/i);"GMT"===(e=e&&e[0]?(e=e[0].match(/[A-Z]/g))?e.join(""):void 0:(e=i.match(/[A-Z]{3,5}/g))?e[0]:void 0)&&(e=void 0),this.at=+a,this.abbr=e,this.offset=a.getTimezoneOffset()}function h(a){this.zone=a,this.offsetScore=0,this.abbrScore=0}function E(a,i){for(var e,r;r=6e4*((i.at-a.at)/12e4|0);)(e=new b(new Date(a.at+r))).offset===a.offset?a=e:i=e;return a}function g(a,i){return a.offsetScore!==i.offsetScore?a.offsetScore-i.offsetScore:a.abbrScore!==i.abbrScore?a.abbrScore-i.abbrScore:a.zone.population!==i.zone.population?i.zone.population-a.zone.population:i.zone.name.localeCompare(a.zone.name)}function z(a,i){var e,r;for(f(i),e=0;e<i.length;e++)r=i[e],u[r]=u[r]||{},u[r][a]=!0}function P(){try{var a=Intl.DateTimeFormat().resolvedOptions().timeZone;if(a&&3<a.length){var i=s[T(a)];if(i)return i;N("Moment Timezone found "+a+" from the Intl api, but did not have that data loaded.")}}catch(a){}var e,r,o,c=function(){var a,i,e,r=(new Date).getFullYear()-2,o=new b(new Date(r,0,1)),c=[o];for(e=1;e<48;e++)(i=new b(new Date(r,e,1))).offset!==o.offset&&(a=E(o,i),c.push(a),c.push(new b(new Date(a.at+6e4)))),o=i;for(e=0;e<4;e++)c.push(new b(new Date(r+e,0,1))),c.push(new b(new Date(r+e,6,1)));return c}(),A=c.length,n=function(a){var i,e,r,o=a.length,c={},A=[];for(i=0;i<o;i++)for(e in r=u[a[i].offset]||{})r.hasOwnProperty(e)&&(c[e]=!0);for(i in c)c.hasOwnProperty(i)&&A.push(s[i]);return A}(c),t=[];for(r=0;r<n.length;r++){for(e=new h(_(n[r]),A),o=0;o<A;o++)e.scoreOffsetAt(c[o]);t.push(e)}return t.sort(g),0<t.length?t[0].zone.name:void 0}function T(a){return(a||"").toLowerCase().replace(/\//g,"_")}function S(a){var i,e,r,o;for("string"==typeof a&&(a=[a]),i=0;i<a.length;i++)o=T(e=(r=a[i].split("|"))[0]),A[o]=a[i],s[o]=e,z(o,r[2].split(" "))}function _(a,i){a=T(a);var e,r=A[a];return r instanceof M?r:"string"==typeof r?(r=new M(r),A[a]=r):n[a]&&i!==_&&(e=_(n[a],_))?((r=A[a]=new M)._set(e),r.name=s[a],r):null}function k(a){var i,e,r,o;for("string"==typeof a&&(a=[a]),i=0;i<a.length;i++)r=T((e=a[i].split("|"))[0]),o=T(e[1]),n[r]=o,s[r]=e[0],n[o]=r,s[o]=e[1]}function C(a){S(a.zones),k(a.links),function(a){var i,e,r,o;if(a&&a.length)for(i=0;i<a.length;i++)e=(o=a[i].split("|"))[0].toUpperCase(),r=o[1].split(" "),t[e]=new d(e,r)}(a.countries),G.dataVersion=a.version}function B(a){var i="X"===a._f||"x"===a._f;return!(!a._a||void 0!==a._tzm||i)}function N(a){"undefined"!=typeof console&&"function"==typeof console.error&&console.error(a)}function G(a){var i=Array.prototype.slice.call(arguments,0,-1),e=arguments[arguments.length-1],r=_(e),o=c.utc.apply(null,i);return r&&!c.isMoment(a)&&B(o)&&o.add(r.parse(o),"minutes"),o.tz(e),o}(e<2||2==e&&r<6)&&N("Moment Timezone requires Moment.js >= 2.6.0. You are using Moment.js "+c.version+". See momentjs.com"),M.prototype={_set:function(a){this.name=a.name,this.abbrs=a.abbrs,this.untils=a.untils,this.offsets=a.offsets,this.population=a.population},_index:function(a){var i,e=+a,r=this.untils;for(i=0;i<r.length;i++)if(e<r[i])return i},countries:function(){var i=this.name;return Object.keys(t).filter(function(a){return-1!==t[a].zones.indexOf(i)})},parse:function(a){var i,e,r,o,c=+a,A=this.offsets,n=this.untils,t=n.length-1;for(o=0;o<t;o++)if(i=A[o],e=A[o+1],r=A[o?o-1:o],i<e&&G.moveAmbiguousForward?i=e:r<i&&G.moveInvalidForward&&(i=r),c<n[o]-6e4*i)return A[o];return A[t]},abbr:function(a){return this.abbrs[this._index(a)]},offset:function(a){return N("zone.offset has been deprecated in favor of zone.utcOffset"),this.offsets[this._index(a)]},utcOffset:function(a){return this.offsets[this._index(a)]}},h.prototype.scoreOffsetAt=function(a){this.offsetScore+=Math.abs(this.zone.utcOffset(a.at)-a.offset),this.zone.abbr(a.at).replace(/[^A-Z]/g,"")!==a.abbr&&this.abbrScore++},G.version="0.5.34",G.dataVersion="",G._zones=A,G._links=n,G._names=s,G._countries=t,G.add=S,G.link=k,G.load=C,G.zone=_,G.zoneExists=function a(i){return a.didShowError||(a.didShowError=!0,N("moment.tz.zoneExists('"+i+"') has been deprecated in favor of !moment.tz.zone('"+i+"')")),!!_(i)},G.guess=function(a){return i&&!a||(i=P()),i},G.names=function(){var a,i=[];for(a in s)s.hasOwnProperty(a)&&(A[a]||A[n[a]])&&s[a]&&i.push(s[a]);return i.sort()},G.Zone=M,G.unpack=p,G.unpackBase60=o,G.needsOffset=B,G.moveInvalidForward=!0,G.moveAmbiguousForward=!1,G.countries=function(){return Object.keys(t)},G.zonesForCountry=function(a,i){if(!(a=function(a){return a=a.toUpperCase(),t[a]||null}(a)))return null;var e=a.zones.sort();return i?e.map(function(a){return{name:a,offset:_(a).utcOffset(new Date)}}):e};var y,L=c.fn;function O(a){return function(){return this._z?this._z.abbr(this):a.call(this)}}function D(a){return function(){return this._z=null,a.apply(this,arguments)}}c.tz=G,c.defaultZone=null,c.updateOffset=function(a,i){var e,r=c.defaultZone;if(void 0===a._z&&(r&&B(a)&&!a._isUTC&&(a._d=c.utc(a._a)._d,a.utc().add(r.parse(a),"minutes")),a._z=r),a._z)if(e=a._z.utcOffset(a),Math.abs(e)<16&&(e/=60),void 0!==a.utcOffset){var o=a._z;a.utcOffset(-e,i),a._z=o}else a.zone(e,i)},L.tz=function(a,i){if(a){if("string"!=typeof a)throw new Error("Time zone name must be a string, got "+a+" ["+typeof a+"]");return this._z=_(a),this._z?c.updateOffset(this,i):N("Moment Timezone has no data for "+a+". See http://momentjs.com/timezone/docs/#/data-loading/."),this}if(this._z)return this._z.name},L.zoneName=O(L.zoneName),L.zoneAbbr=O(L.zoneAbbr),L.utc=D(L.utc),L.local=D(L.local),L.utcOffset=(y=L.utcOffset,function(){return 0<arguments.length&&(this._z=null),y.apply(this,arguments)}),c.tz.setDefault=function(a){return(e<2||2==e&&r<9)&&N("Moment Timezone setDefault() requires Moment.js >= 2.9.0. You are using Moment.js "+c.version+"."),c.defaultZone=a?_(a):null,c};var v=c.momentProperties;return"[object Array]"===Object.prototype.toString.call(v)?(v.push("_z"),v.push("_a")):v&&(v._z=null),C({version:"2021e",zones:["Africa/Abidjan|GMT|0|0||48e5","Africa/Nairobi|EAT|-30|0||47e5","Africa/Algiers|CET|-10|0||26e5","Africa/Lagos|WAT|-10|0||17e6","Africa/Maputo|CAT|-20|0||26e5","Africa/Cairo|EET EEST|-20 -30|01010|1M2m0 gL0 e10 mn0|15e6","Africa/Casablanca|+00 +01|0 -10|010101010101010101010101010101010101|1H3C0 wM0 co0 go0 1o00 s00 dA0 vc0 11A0 A00 e00 y00 11A0 uM0 e00 Dc0 11A0 s00 e00 IM0 WM0 mo0 gM0 LA0 WM0 jA0 e00 28M0 e00 2600 gM0 2600 e00 2600 gM0|32e5","Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|11e6","Africa/Johannesburg|SAST|-20|0||84e5","Africa/Juba|EAT CAT|-30 -20|01|24nx0|","Africa/Khartoum|EAT CAT|-30 -20|01|1Usl0|51e5","Africa/Sao_Tome|GMT WAT|0 -10|010|1UQN0 2q00|","Africa/Tripoli|EET CET CEST|-20 -10 -20|0120|1IlA0 TA0 1o00|11e5","Africa/Windhoek|CAT WAT|-20 -10|0101010101010|1GQo0 11B0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|32e4","America/Adak|HST HDT|a0 90|01010101010101010101010|1GIc0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|326","America/Anchorage|AKST AKDT|90 80|01010101010101010101010|1GIb0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|30e4","America/Santo_Domingo|AST|40|0||29e5","America/Araguaina|-03 -02|30 20|010|1IdD0 Lz0|14e4","America/Fortaleza|-03|30|0||34e5","America/Asuncion|-03 -04|30 40|01010101010101010101010|1GTf0 1cN0 17b0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0 19X0 1ip0 17b0 1ip0 17b0 1ip0 19X0 1fB0 19X0 1fB0|28e5","America/Panama|EST|50|0||15e5","America/Mexico_City|CST CDT|60 50|01010101010101010101010|1GQw0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|20e6","America/Bahia|-02 -03|20 30|01|1GCq0|27e5","America/Managua|CST|60|0||22e5","America/La_Paz|-04|40|0||19e5","America/Lima|-05|50|0||11e6","America/Denver|MST MDT|70 60|01010101010101010101010|1GI90 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|26e5","America/Campo_Grande|-03 -04|30 40|0101010101010101|1GCr0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|77e4","America/Cancun|CST CDT EST|60 50 50|01010102|1GQw0 1nX0 14p0 1lb0 14p0 1lb0 Dd0|63e4","America/Caracas|-0430 -04|4u 40|01|1QMT0|29e5","America/Chicago|CST CDT|60 50|01010101010101010101010|1GI80 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|92e5","America/Chihuahua|MST MDT|70 60|01010101010101010101010|1GQx0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0 11B0 1nX0 14p0 1lb0 14p0 1lb0 14p0 1nX0 11B0 1nX0|81e4","America/Phoenix|MST|70|0||42e5","America/Whitehorse|PST PDT MST|80 70 70|0101010101010101012|1GIa0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1z90|23e3","America/New_York|EST EDT|50 40|01010101010101010101010|1GI70 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|21e6","America/Rio_Branco|-04 -05|40 50|01|1KLE0|31e4","America/Los_Angeles|PST PDT|80 70|01010101010101010101010|1GIa0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|15e6","America/Fort_Nelson|PST PDT MST|80 70 70|01010102|1GIa0 1zb0 Op0 1zb0 Op0 1zb0 Op0|39e2","America/Halifax|AST ADT|40 30|01010101010101010101010|1GI60 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|39e4","America/Godthab|-03 -02|30 20|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|17e3","America/Grand_Turk|EST EDT AST|50 40 40|010101021010101010|1GI70 1zb0 Op0 1zb0 Op0 1zb0 Op0 7jA0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|37e2","America/Havana|CST CDT|50 40|01010101010101010101010|1GQt0 1qM0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Oo0 1zc0 Rc0 1zc0 Oo0 1zc0|21e5","America/Metlakatla|PST AKST AKDT|80 90 80|01212120121212121|1PAa0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 uM0 jB0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|14e2","America/Miquelon|-03 -02|30 20|01010101010101010101010|1GI50 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|61e2","America/Montevideo|-02 -03|20 30|01010101|1GI40 1o10 11z0 1o10 11z0 1o10 11z0|17e5","America/Noronha|-02|20|0||30e2","America/Port-au-Prince|EST EDT|50 40|010101010101010101010|1GI70 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 3iN0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|23e5","Antarctica/Palmer|-03 -04|30 40|010101010|1H3D0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0|40","America/Santiago|-03 -04|30 40|010101010101010101010|1H3D0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|62e5","America/Sao_Paulo|-02 -03|20 30|0101010101010101|1GCq0 1zd0 Lz0 1C10 Lz0 1C10 On0 1zd0 On0 1zd0 On0 1zd0 On0 1HB0 FX0|20e6","Atlantic/Azores|-01 +00|10 0|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|25e4","America/St_Johns|NST NDT|3u 2u|01010101010101010101010|1GI5u 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Op0 1zb0 Rd0 1zb0 Op0 1zb0|11e4","Antarctica/Casey|+11 +08|-b0 -80|010101010|1GAF0 blz0 3m10 1o30 14k0 1kr0 12l0 1o01|10","Antarctica/Davis|+05 +07|-50 -70|01|1GAI0|70","Pacific/Port_Moresby|+10|-a0|0||25e4","Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1GQg0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|40e5","Asia/Tashkent|+05|-50|0||23e5","Pacific/Auckland|NZDT NZST|-d0 -c0|01010101010101010101010|1GQe0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00|14e5","Asia/Baghdad|+03|-30|0||66e5","Antarctica/Troll|+00 +02|0 -20|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|40","Asia/Dhaka|+06|-60|0||16e6","Asia/Amman|EET EEST|-20 -30|010101010101010101010|1GPy0 4bX0 Dd0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 LA0 1C00|25e5","Asia/Kamchatka|+12|-c0|0||18e4","Asia/Baku|+04 +05|-40 -50|010101010|1GNA0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00|27e5","Asia/Bangkok|+07|-70|0||15e6","Asia/Barnaul|+07 +06|-70 -60|010|1N7v0 3rd0|","Asia/Beirut|EET EEST|-20 -30|01010101010101010101010|1GNy0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0|22e5","Asia/Kuala_Lumpur|+08|-80|0||71e5","Asia/Kolkata|IST|-5u|0||15e6","Asia/Chita|+10 +08 +09|-a0 -80 -90|012|1N7s0 3re0|33e4","Asia/Ulaanbaatar|+08 +09|-80 -90|01010|1O8G0 1cJ0 1cP0 1cJ0|12e5","Asia/Shanghai|CST|-80|0||23e6","Asia/Colombo|+0530|-5u|0||22e5","Asia/Damascus|EET EEST|-20 -30|01010101010101010101010|1GPy0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0 1qL0 WN0 1qL0 WN0 1qL0|26e5","Asia/Dili|+09|-90|0||19e4","Asia/Dubai|+04|-40|0||39e5","Asia/Famagusta|EET EEST +03|-20 -30 -30|0101010101201010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 15U0 2Ks0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|","Asia/Gaza|EET EEST|-20 -30|01010101010101010101010|1GPy0 1a00 1fA0 1cL0 1cN0 1nX0 1210 1nA0 1210 1qL0 WN0 1qL0 WN0 1qL0 11c0 1on0 11B0 1o00 11A0 1qo0 Xc0 1qo0|18e5","Asia/Hong_Kong|HKT|-80|0||73e5","Asia/Hovd|+07 +08|-70 -80|01010|1O8H0 1cJ0 1cP0 1cJ0|81e3","Asia/Irkutsk|+09 +08|-90 -80|01|1N7t0|60e4","Europe/Istanbul|EET EEST +03|-20 -30 -30|01010101012|1GNB0 1qM0 11A0 1o00 1200 1nA0 11A0 1tA0 U00 15w0|13e6","Asia/Jakarta|WIB|-70|0||31e6","Asia/Jayapura|WIT|-90|0||26e4","Asia/Jerusalem|IST IDT|-20 -30|01010101010101010101010|1GPA0 1aL0 1eN0 1oL0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0 W10 1rz0 10N0 1oL0 10N0 1oL0 10N0 1rz0 W10 1rz0|81e4","Asia/Kabul|+0430|-4u|0||46e5","Asia/Karachi|PKT|-50|0||24e6","Asia/Kathmandu|+0545|-5J|0||12e5","Asia/Yakutsk|+10 +09|-a0 -90|01|1N7s0|28e4","Asia/Krasnoyarsk|+08 +07|-80 -70|01|1N7u0|10e5","Asia/Magadan|+12 +10 +11|-c0 -a0 -b0|012|1N7q0 3Cq0|95e3","Asia/Makassar|WITA|-80|0||15e5","Asia/Manila|PST|-80|0||24e6","Europe/Athens|EET EEST|-20 -30|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|35e5","Asia/Novosibirsk|+07 +06|-70 -60|010|1N7v0 4eN0|15e5","Asia/Omsk|+07 +06|-70 -60|01|1N7v0|12e5","Asia/Pyongyang|KST KST|-90 -8u|010|1P4D0 6BA0|29e5","Asia/Qyzylorda|+06 +05|-60 -50|01|1Xei0|73e4","Asia/Rangoon|+0630|-6u|0||48e5","Asia/Sakhalin|+11 +10|-b0 -a0|010|1N7r0 3rd0|58e4","Asia/Seoul|KST|-90|0||23e6","Asia/Srednekolymsk|+12 +11|-c0 -b0|01|1N7q0|35e2","Asia/Tehran|+0330 +0430|-3u -4u|01010101010101010101010|1GLUu 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0 1cp0 1dz0 1cp0 1dz0 1cN0 1dz0 1cp0 1dz0|14e6","Asia/Tokyo|JST|-90|0||38e6","Asia/Tomsk|+07 +06|-70 -60|010|1N7v0 3Qp0|10e5","Asia/Vladivostok|+11 +10|-b0 -a0|01|1N7r0|60e4","Asia/Yekaterinburg|+06 +05|-60 -50|01|1N7w0|14e5","Europe/Lisbon|WET WEST|0 -10|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|27e5","Atlantic/Cape_Verde|-01|10|0||50e4","Australia/Adelaide|ACDT ACST|-au -9u|01010101010101010101010|1GQgu 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|11e5","Australia/Brisbane|AEST|-a0|0||20e5","Australia/Darwin|ACST|-9u|0||12e4","Australia/Eucla|+0845|-8J|0||368","Australia/Lord_Howe|+11 +1030|-b0 -au|01010101010101010101010|1GQf0 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1fAu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu 1cLu 1cMu|347","Australia/Perth|AWST|-80|0||18e5","Pacific/Easter|-05 -06|50 60|010101010101010101010|1H3D0 Op0 1zb0 Rd0 1wn0 Rd0 46n0 Ap0 1Nb0 Ap0 1Nb0 Ap0 1zb0 11B0 1nX0 11B0 1nX0 11B0 1nX0 11B0|30e2","Europe/Dublin|GMT IST|0 -10|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|12e5","Etc/GMT-1|+01|-10|0||","Pacific/Guadalcanal|+11|-b0|0||11e4","Pacific/Fakaofo|+13|-d0|0||483","Pacific/Kiritimati|+14|-e0|0||51e2","Etc/GMT-2|+02|-20|0||","Pacific/Tahiti|-10|a0|0||18e4","Pacific/Niue|-11|b0|0||12e2","Etc/GMT+12|-12|c0|0||","Pacific/Galapagos|-06|60|0||25e3","Etc/GMT+7|-07|70|0||","Pacific/Pitcairn|-08|80|0||56","Pacific/Gambier|-09|90|0||125","Etc/UTC|UTC|0|0||","Europe/Ulyanovsk|+04 +03|-40 -30|010|1N7y0 3rd0|13e5","Europe/London|GMT BST|0 -10|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|10e6","Europe/Chisinau|EET EEST|-20 -30|01010101010101010101010|1GNA0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|67e4","Europe/Kaliningrad|+03 EET|-30 -20|01|1N7z0|44e4","Europe/Kirov|+04 +03|-40 -30|01|1N7y0|48e4","Europe/Moscow|MSK MSK|-40 -30|01|1N7y0|16e6","Europe/Saratov|+04 +03|-40 -30|010|1N7y0 5810|","Europe/Simferopol|EET EEST MSK MSK|-20 -30 -40 -30|0101023|1GNB0 1qM0 11A0 1o00 11z0 1nW0|33e4","Europe/Volgograd|+04 +03|-40 -30|0101|1N7y0 9Jd0 5gn0|10e5","Pacific/Honolulu|HST|a0|0||37e4","MET|MET MEST|-10 -20|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|","Pacific/Chatham|+1345 +1245|-dJ -cJ|01010101010101010101010|1GQe0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00|600","Pacific/Apia|+14 +13|-e0 -d0|01010101010101010101|1GQe0 1cM0 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1a00 1fA0 1cM0 1fA0 1a00 1fA0 1a00 1fA0|37e3","Pacific/Bougainville|+10 +11|-a0 -b0|01|1NwE0|18e4","Pacific/Fiji|+13 +12|-d0 -c0|010101010101010101010|1Goe0 1Nc0 Ao0 1Q00 xz0 1SN0 uM0 1SM0 uM0 1VA0 s00 1VA0 s00 1VA0 s00 20o0 pc0 2hc0 bc0 4q00|88e4","Pacific/Guam|ChST|-a0|0||17e4","Pacific/Marquesas|-0930|9u|0||86e2","Pacific/Pago_Pago|SST|b0|0||37e2","Pacific/Norfolk|+1130 +11 +12|-bu -b0 -c0|012121212|1PoCu 9Jcu 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|25e4","Pacific/Tongatapu|+13 +14|-d0 -e0|010|1S4d0 s00|75e3"],links:["Africa/Abidjan|Africa/Accra","Africa/Abidjan|Africa/Bamako","Africa/Abidjan|Africa/Banjul","Africa/Abidjan|Africa/Bissau","Africa/Abidjan|Africa/Conakry","Africa/Abidjan|Africa/Dakar","Africa/Abidjan|Africa/Freetown","Africa/Abidjan|Africa/Lome","Africa/Abidjan|Africa/Monrovia","Africa/Abidjan|Africa/Nouakchott","Africa/Abidjan|Africa/Ouagadougou","Africa/Abidjan|Africa/Timbuktu","Africa/Abidjan|America/Danmarkshavn","Africa/Abidjan|Atlantic/Reykjavik","Africa/Abidjan|Atlantic/St_Helena","Africa/Abidjan|Etc/GMT","Africa/Abidjan|Etc/GMT+0","Africa/Abidjan|Etc/GMT-0","Africa/Abidjan|Etc/GMT0","Africa/Abidjan|Etc/Greenwich","Africa/Abidjan|GMT","Africa/Abidjan|GMT+0","Africa/Abidjan|GMT-0","Africa/Abidjan|GMT0","Africa/Abidjan|Greenwich","Africa/Abidjan|Iceland","Africa/Algiers|Africa/Tunis","Africa/Cairo|Egypt","Africa/Casablanca|Africa/El_Aaiun","Africa/Johannesburg|Africa/Maseru","Africa/Johannesburg|Africa/Mbabane","Africa/Lagos|Africa/Bangui","Africa/Lagos|Africa/Brazzaville","Africa/Lagos|Africa/Douala","Africa/Lagos|Africa/Kinshasa","Africa/Lagos|Africa/Libreville","Africa/Lagos|Africa/Luanda","Africa/Lagos|Africa/Malabo","Africa/Lagos|Africa/Ndjamena","Africa/Lagos|Africa/Niamey","Africa/Lagos|Africa/Porto-Novo","Africa/Maputo|Africa/Blantyre","Africa/Maputo|Africa/Bujumbura","Africa/Maputo|Africa/Gaborone","Africa/Maputo|Africa/Harare","Africa/Maputo|Africa/Kigali","Africa/Maputo|Africa/Lubumbashi","Africa/Maputo|Africa/Lusaka","Africa/Nairobi|Africa/Addis_Ababa","Africa/Nairobi|Africa/Asmara","Africa/Nairobi|Africa/Asmera","Africa/Nairobi|Africa/Dar_es_Salaam","Africa/Nairobi|Africa/Djibouti","Africa/Nairobi|Africa/Kampala","Africa/Nairobi|Africa/Mogadishu","Africa/Nairobi|Indian/Antananarivo","Africa/Nairobi|Indian/Comoro","Africa/Nairobi|Indian/Mayotte","Africa/Tripoli|Libya","America/Adak|America/Atka","America/Adak|US/Aleutian","America/Anchorage|America/Juneau","America/Anchorage|America/Nome","America/Anchorage|America/Sitka","America/Anchorage|America/Yakutat","America/Anchorage|US/Alaska","America/Campo_Grande|America/Cuiaba","America/Chicago|America/Indiana/Knox","America/Chicago|America/Indiana/Tell_City","America/Chicago|America/Knox_IN","America/Chicago|America/Matamoros","America/Chicago|America/Menominee","America/Chicago|America/North_Dakota/Beulah","America/Chicago|America/North_Dakota/Center","America/Chicago|America/North_Dakota/New_Salem","America/Chicago|America/Rainy_River","America/Chicago|America/Rankin_Inlet","America/Chicago|America/Resolute","America/Chicago|America/Winnipeg","America/Chicago|CST6CDT","America/Chicago|Canada/Central","America/Chicago|US/Central","America/Chicago|US/Indiana-Starke","America/Chihuahua|America/Mazatlan","America/Chihuahua|Mexico/BajaSur","America/Denver|America/Boise","America/Denver|America/Cambridge_Bay","America/Denver|America/Edmonton","America/Denver|America/Inuvik","America/Denver|America/Ojinaga","America/Denver|America/Shiprock","America/Denver|America/Yellowknife","America/Denver|Canada/Mountain","America/Denver|MST7MDT","America/Denver|Navajo","America/Denver|US/Mountain","America/Fortaleza|America/Argentina/Buenos_Aires","America/Fortaleza|America/Argentina/Catamarca","America/Fortaleza|America/Argentina/ComodRivadavia","America/Fortaleza|America/Argentina/Cordoba","America/Fortaleza|America/Argentina/Jujuy","America/Fortaleza|America/Argentina/La_Rioja","America/Fortaleza|America/Argentina/Mendoza","America/Fortaleza|America/Argentina/Rio_Gallegos","America/Fortaleza|America/Argentina/Salta","America/Fortaleza|America/Argentina/San_Juan","America/Fortaleza|America/Argentina/San_Luis","America/Fortaleza|America/Argentina/Tucuman","America/Fortaleza|America/Argentina/Ushuaia","America/Fortaleza|America/Belem","America/Fortaleza|America/Buenos_Aires","America/Fortaleza|America/Catamarca","America/Fortaleza|America/Cayenne","America/Fortaleza|America/Cordoba","America/Fortaleza|America/Jujuy","America/Fortaleza|America/Maceio","America/Fortaleza|America/Mendoza","America/Fortaleza|America/Paramaribo","America/Fortaleza|America/Recife","America/Fortaleza|America/Rosario","America/Fortaleza|America/Santarem","America/Fortaleza|Antarctica/Rothera","America/Fortaleza|Atlantic/Stanley","America/Fortaleza|Etc/GMT+3","America/Godthab|America/Nuuk","America/Halifax|America/Glace_Bay","America/Halifax|America/Goose_Bay","America/Halifax|America/Moncton","America/Halifax|America/Thule","America/Halifax|Atlantic/Bermuda","America/Halifax|Canada/Atlantic","America/Havana|Cuba","America/La_Paz|America/Boa_Vista","America/La_Paz|America/Guyana","America/La_Paz|America/Manaus","America/La_Paz|America/Porto_Velho","America/La_Paz|Brazil/West","America/La_Paz|Etc/GMT+4","America/Lima|America/Bogota","America/Lima|America/Guayaquil","America/Lima|Etc/GMT+5","America/Los_Angeles|America/Ensenada","America/Los_Angeles|America/Santa_Isabel","America/Los_Angeles|America/Tijuana","America/Los_Angeles|America/Vancouver","America/Los_Angeles|Canada/Pacific","America/Los_Angeles|Mexico/BajaNorte","America/Los_Angeles|PST8PDT","America/Los_Angeles|US/Pacific","America/Managua|America/Belize","America/Managua|America/Costa_Rica","America/Managua|America/El_Salvador","America/Managua|America/Guatemala","America/Managua|America/Regina","America/Managua|America/Swift_Current","America/Managua|America/Tegucigalpa","America/Managua|Canada/Saskatchewan","America/Mexico_City|America/Bahia_Banderas","America/Mexico_City|America/Merida","America/Mexico_City|America/Monterrey","America/Mexico_City|Mexico/General","America/New_York|America/Detroit","America/New_York|America/Fort_Wayne","America/New_York|America/Indiana/Indianapolis","America/New_York|America/Indiana/Marengo","America/New_York|America/Indiana/Petersburg","America/New_York|America/Indiana/Vevay","America/New_York|America/Indiana/Vincennes","America/New_York|America/Indiana/Winamac","America/New_York|America/Indianapolis","America/New_York|America/Iqaluit","America/New_York|America/Kentucky/Louisville","America/New_York|America/Kentucky/Monticello","America/New_York|America/Louisville","America/New_York|America/Montreal","America/New_York|America/Nassau","America/New_York|America/Nipigon","America/New_York|America/Pangnirtung","America/New_York|America/Thunder_Bay","America/New_York|America/Toronto","America/New_York|Canada/Eastern","America/New_York|EST5EDT","America/New_York|US/East-Indiana","America/New_York|US/Eastern","America/New_York|US/Michigan","America/Noronha|Atlantic/South_Georgia","America/Noronha|Brazil/DeNoronha","America/Noronha|Etc/GMT+2","America/Panama|America/Atikokan","America/Panama|America/Cayman","America/Panama|America/Coral_Harbour","America/Panama|America/Jamaica","America/Panama|EST","America/Panama|Jamaica","America/Phoenix|America/Creston","America/Phoenix|America/Dawson_Creek","America/Phoenix|America/Hermosillo","America/Phoenix|MST","America/Phoenix|US/Arizona","America/Rio_Branco|America/Eirunepe","America/Rio_Branco|America/Porto_Acre","America/Rio_Branco|Brazil/Acre","America/Santiago|Chile/Continental","America/Santo_Domingo|America/Anguilla","America/Santo_Domingo|America/Antigua","America/Santo_Domingo|America/Aruba","America/Santo_Domingo|America/Barbados","America/Santo_Domingo|America/Blanc-Sablon","America/Santo_Domingo|America/Curacao","America/Santo_Domingo|America/Dominica","America/Santo_Domingo|America/Grenada","America/Santo_Domingo|America/Guadeloupe","America/Santo_Domingo|America/Kralendijk","America/Santo_Domingo|America/Lower_Princes","America/Santo_Domingo|America/Marigot","America/Santo_Domingo|America/Martinique","America/Santo_Domingo|America/Montserrat","America/Santo_Domingo|America/Port_of_Spain","America/Santo_Domingo|America/Puerto_Rico","America/Santo_Domingo|America/St_Barthelemy","America/Santo_Domingo|America/St_Kitts","America/Santo_Domingo|America/St_Lucia","America/Santo_Domingo|America/St_Thomas","America/Santo_Domingo|America/St_Vincent","America/Santo_Domingo|America/Tortola","America/Santo_Domingo|America/Virgin","America/Sao_Paulo|Brazil/East","America/St_Johns|Canada/Newfoundland","America/Whitehorse|America/Dawson","America/Whitehorse|Canada/Yukon","Antarctica/Palmer|America/Punta_Arenas","Asia/Baghdad|Antarctica/Syowa","Asia/Baghdad|Asia/Aden","Asia/Baghdad|Asia/Bahrain","Asia/Baghdad|Asia/Kuwait","Asia/Baghdad|Asia/Qatar","Asia/Baghdad|Asia/Riyadh","Asia/Baghdad|Etc/GMT-3","Asia/Baghdad|Europe/Minsk","Asia/Bangkok|Asia/Ho_Chi_Minh","Asia/Bangkok|Asia/Novokuznetsk","Asia/Bangkok|Asia/Phnom_Penh","Asia/Bangkok|Asia/Saigon","Asia/Bangkok|Asia/Vientiane","Asia/Bangkok|Etc/GMT-7","Asia/Bangkok|Indian/Christmas","Asia/Dhaka|Antarctica/Vostok","Asia/Dhaka|Asia/Almaty","Asia/Dhaka|Asia/Bishkek","Asia/Dhaka|Asia/Dacca","Asia/Dhaka|Asia/Kashgar","Asia/Dhaka|Asia/Qostanay","Asia/Dhaka|Asia/Thimbu","Asia/Dhaka|Asia/Thimphu","Asia/Dhaka|Asia/Urumqi","Asia/Dhaka|Etc/GMT-6","Asia/Dhaka|Indian/Chagos","Asia/Dili|Etc/GMT-9","Asia/Dili|Pacific/Palau","Asia/Dubai|Asia/Muscat","Asia/Dubai|Asia/Tbilisi","Asia/Dubai|Asia/Yerevan","Asia/Dubai|Etc/GMT-4","Asia/Dubai|Europe/Samara","Asia/Dubai|Indian/Mahe","Asia/Dubai|Indian/Mauritius","Asia/Dubai|Indian/Reunion","Asia/Gaza|Asia/Hebron","Asia/Hong_Kong|Hongkong","Asia/Jakarta|Asia/Pontianak","Asia/Jerusalem|Asia/Tel_Aviv","Asia/Jerusalem|Israel","Asia/Kamchatka|Asia/Anadyr","Asia/Kamchatka|Etc/GMT-12","Asia/Kamchatka|Kwajalein","Asia/Kamchatka|Pacific/Funafuti","Asia/Kamchatka|Pacific/Kwajalein","Asia/Kamchatka|Pacific/Majuro","Asia/Kamchatka|Pacific/Nauru","Asia/Kamchatka|Pacific/Tarawa","Asia/Kamchatka|Pacific/Wake","Asia/Kamchatka|Pacific/Wallis","Asia/Kathmandu|Asia/Katmandu","Asia/Kolkata|Asia/Calcutta","Asia/Kuala_Lumpur|Asia/Brunei","Asia/Kuala_Lumpur|Asia/Kuching","Asia/Kuala_Lumpur|Asia/Singapore","Asia/Kuala_Lumpur|Etc/GMT-8","Asia/Kuala_Lumpur|Singapore","Asia/Makassar|Asia/Ujung_Pandang","Asia/Rangoon|Asia/Yangon","Asia/Rangoon|Indian/Cocos","Asia/Seoul|ROK","Asia/Shanghai|Asia/Chongqing","Asia/Shanghai|Asia/Chungking","Asia/Shanghai|Asia/Harbin","Asia/Shanghai|Asia/Macao","Asia/Shanghai|Asia/Macau","Asia/Shanghai|Asia/Taipei","Asia/Shanghai|PRC","Asia/Shanghai|ROC","Asia/Tashkent|Antarctica/Mawson","Asia/Tashkent|Asia/Aqtau","Asia/Tashkent|Asia/Aqtobe","Asia/Tashkent|Asia/Ashgabat","Asia/Tashkent|Asia/Ashkhabad","Asia/Tashkent|Asia/Atyrau","Asia/Tashkent|Asia/Dushanbe","Asia/Tashkent|Asia/Oral","Asia/Tashkent|Asia/Samarkand","Asia/Tashkent|Etc/GMT-5","Asia/Tashkent|Indian/Kerguelen","Asia/Tashkent|Indian/Maldives","Asia/Tehran|Iran","Asia/Tokyo|Japan","Asia/Ulaanbaatar|Asia/Choibalsan","Asia/Ulaanbaatar|Asia/Ulan_Bator","Asia/Vladivostok|Asia/Ust-Nera","Asia/Yakutsk|Asia/Khandyga","Atlantic/Azores|America/Scoresbysund","Atlantic/Cape_Verde|Etc/GMT+1","Australia/Adelaide|Australia/Broken_Hill","Australia/Adelaide|Australia/South","Australia/Adelaide|Australia/Yancowinna","Australia/Brisbane|Australia/Lindeman","Australia/Brisbane|Australia/Queensland","Australia/Darwin|Australia/North","Australia/Lord_Howe|Australia/LHI","Australia/Perth|Australia/West","Australia/Sydney|Antarctica/Macquarie","Australia/Sydney|Australia/ACT","Australia/Sydney|Australia/Canberra","Australia/Sydney|Australia/Currie","Australia/Sydney|Australia/Hobart","Australia/Sydney|Australia/Melbourne","Australia/Sydney|Australia/NSW","Australia/Sydney|Australia/Tasmania","Australia/Sydney|Australia/Victoria","Etc/UTC|Etc/UCT","Etc/UTC|Etc/Universal","Etc/UTC|Etc/Zulu","Etc/UTC|UCT","Etc/UTC|UTC","Etc/UTC|Universal","Etc/UTC|Zulu","Europe/Athens|Asia/Nicosia","Europe/Athens|EET","Europe/Athens|Europe/Bucharest","Europe/Athens|Europe/Helsinki","Europe/Athens|Europe/Kiev","Europe/Athens|Europe/Mariehamn","Europe/Athens|Europe/Nicosia","Europe/Athens|Europe/Riga","Europe/Athens|Europe/Sofia","Europe/Athens|Europe/Tallinn","Europe/Athens|Europe/Uzhgorod","Europe/Athens|Europe/Vilnius","Europe/Athens|Europe/Zaporozhye","Europe/Chisinau|Europe/Tiraspol","Europe/Dublin|Eire","Europe/Istanbul|Asia/Istanbul","Europe/Istanbul|Turkey","Europe/Lisbon|Atlantic/Canary","Europe/Lisbon|Atlantic/Faeroe","Europe/Lisbon|Atlantic/Faroe","Europe/Lisbon|Atlantic/Madeira","Europe/Lisbon|Portugal","Europe/Lisbon|WET","Europe/London|Europe/Belfast","Europe/London|Europe/Guernsey","Europe/London|Europe/Isle_of_Man","Europe/London|Europe/Jersey","Europe/London|GB","Europe/London|GB-Eire","Europe/Moscow|W-SU","Europe/Paris|Africa/Ceuta","Europe/Paris|Arctic/Longyearbyen","Europe/Paris|Atlantic/Jan_Mayen","Europe/Paris|CET","Europe/Paris|Europe/Amsterdam","Europe/Paris|Europe/Andorra","Europe/Paris|Europe/Belgrade","Europe/Paris|Europe/Berlin","Europe/Paris|Europe/Bratislava","Europe/Paris|Europe/Brussels","Europe/Paris|Europe/Budapest","Europe/Paris|Europe/Busingen","Europe/Paris|Europe/Copenhagen","Europe/Paris|Europe/Gibraltar","Europe/Paris|Europe/Ljubljana","Europe/Paris|Europe/Luxembourg","Europe/Paris|Europe/Madrid","Europe/Paris|Europe/Malta","Europe/Paris|Europe/Monaco","Europe/Paris|Europe/Oslo","Europe/Paris|Europe/Podgorica","Europe/Paris|Europe/Prague","Europe/Paris|Europe/Rome","Europe/Paris|Europe/San_Marino","Europe/Paris|Europe/Sarajevo","Europe/Paris|Europe/Skopje","Europe/Paris|Europe/Stockholm","Europe/Paris|Europe/Tirane","Europe/Paris|Europe/Vaduz","Europe/Paris|Europe/Vatican","Europe/Paris|Europe/Vienna","Europe/Paris|Europe/Warsaw","Europe/Paris|Europe/Zagreb","Europe/Paris|Europe/Zurich","Europe/Paris|Poland","Europe/Ulyanovsk|Europe/Astrakhan","Pacific/Auckland|Antarctica/McMurdo","Pacific/Auckland|Antarctica/South_Pole","Pacific/Auckland|NZ","Pacific/Chatham|NZ-CHAT","Pacific/Easter|Chile/EasterIsland","Pacific/Fakaofo|Etc/GMT-13","Pacific/Fakaofo|Pacific/Enderbury","Pacific/Fakaofo|Pacific/Kanton","Pacific/Galapagos|Etc/GMT+6","Pacific/Gambier|Etc/GMT+9","Pacific/Guadalcanal|Etc/GMT-11","Pacific/Guadalcanal|Pacific/Efate","Pacific/Guadalcanal|Pacific/Kosrae","Pacific/Guadalcanal|Pacific/Noumea","Pacific/Guadalcanal|Pacific/Pohnpei","Pacific/Guadalcanal|Pacific/Ponape","Pacific/Guam|Pacific/Saipan","Pacific/Honolulu|HST","Pacific/Honolulu|Pacific/Johnston","Pacific/Honolulu|US/Hawaii","Pacific/Kiritimati|Etc/GMT-14","Pacific/Niue|Etc/GMT+11","Pacific/Pago_Pago|Pacific/Midway","Pacific/Pago_Pago|Pacific/Samoa","Pacific/Pago_Pago|US/Samoa","Pacific/Pitcairn|Etc/GMT+8","Pacific/Port_Moresby|Antarctica/DumontDUrville","Pacific/Port_Moresby|Etc/GMT-10","Pacific/Port_Moresby|Pacific/Chuuk","Pacific/Port_Moresby|Pacific/Truk","Pacific/Port_Moresby|Pacific/Yap","Pacific/Tahiti|Etc/GMT+10","Pacific/Tahiti|Pacific/Rarotonga"],countries:["AD|Europe/Andorra","AE|Asia/Dubai","AF|Asia/Kabul","AG|America/Port_of_Spain America/Antigua","AI|America/Port_of_Spain America/Anguilla","AL|Europe/Tirane","AM|Asia/Yerevan","AO|Africa/Lagos Africa/Luanda","AQ|Antarctica/Casey Antarctica/Davis Antarctica/DumontDUrville Antarctica/Mawson Antarctica/Palmer Antarctica/Rothera Antarctica/Syowa Antarctica/Troll Antarctica/Vostok Pacific/Auckland Antarctica/McMurdo","AR|America/Argentina/Buenos_Aires America/Argentina/Cordoba America/Argentina/Salta America/Argentina/Jujuy America/Argentina/Tucuman America/Argentina/Catamarca America/Argentina/La_Rioja America/Argentina/San_Juan America/Argentina/Mendoza America/Argentina/San_Luis America/Argentina/Rio_Gallegos America/Argentina/Ushuaia","AS|Pacific/Pago_Pago","AT|Europe/Vienna","AU|Australia/Lord_Howe Antarctica/Macquarie Australia/Hobart Australia/Melbourne Australia/Sydney Australia/Broken_Hill Australia/Brisbane Australia/Lindeman Australia/Adelaide Australia/Darwin Australia/Perth Australia/Eucla","AW|America/Curacao America/Aruba","AX|Europe/Helsinki Europe/Mariehamn","AZ|Asia/Baku","BA|Europe/Belgrade Europe/Sarajevo","BB|America/Barbados","BD|Asia/Dhaka","BE|Europe/Brussels","BF|Africa/Abidjan Africa/Ouagadougou","BG|Europe/Sofia","BH|Asia/Qatar Asia/Bahrain","BI|Africa/Maputo Africa/Bujumbura","BJ|Africa/Lagos Africa/Porto-Novo","BL|America/Port_of_Spain America/St_Barthelemy","BM|Atlantic/Bermuda","BN|Asia/Brunei","BO|America/La_Paz","BQ|America/Curacao America/Kralendijk","BR|America/Noronha America/Belem America/Fortaleza America/Recife America/Araguaina America/Maceio America/Bahia America/Sao_Paulo America/Campo_Grande America/Cuiaba America/Santarem America/Porto_Velho America/Boa_Vista America/Manaus America/Eirunepe America/Rio_Branco","BS|America/Nassau","BT|Asia/Thimphu","BW|Africa/Maputo Africa/Gaborone","BY|Europe/Minsk","BZ|America/Belize","CA|America/St_Johns America/Halifax America/Glace_Bay America/Moncton America/Goose_Bay America/Blanc-Sablon America/Toronto America/Nipigon America/Thunder_Bay America/Iqaluit America/Pangnirtung America/Atikokan America/Winnipeg America/Rainy_River America/Resolute America/Rankin_Inlet America/Regina America/Swift_Current America/Edmonton America/Cambridge_Bay America/Yellowknife America/Inuvik America/Creston America/Dawson_Creek America/Fort_Nelson America/Whitehorse America/Dawson America/Vancouver","CC|Indian/Cocos","CD|Africa/Maputo Africa/Lagos Africa/Kinshasa Africa/Lubumbashi","CF|Africa/Lagos Africa/Bangui","CG|Africa/Lagos Africa/Brazzaville","CH|Europe/Zurich","CI|Africa/Abidjan","CK|Pacific/Rarotonga","CL|America/Santiago America/Punta_Arenas Pacific/Easter","CM|Africa/Lagos Africa/Douala","CN|Asia/Shanghai Asia/Urumqi","CO|America/Bogota","CR|America/Costa_Rica","CU|America/Havana","CV|Atlantic/Cape_Verde","CW|America/Curacao","CX|Indian/Christmas","CY|Asia/Nicosia Asia/Famagusta","CZ|Europe/Prague","DE|Europe/Zurich Europe/Berlin Europe/Busingen","DJ|Africa/Nairobi Africa/Djibouti","DK|Europe/Copenhagen","DM|America/Port_of_Spain America/Dominica","DO|America/Santo_Domingo","DZ|Africa/Algiers","EC|America/Guayaquil Pacific/Galapagos","EE|Europe/Tallinn","EG|Africa/Cairo","EH|Africa/El_Aaiun","ER|Africa/Nairobi Africa/Asmara","ES|Europe/Madrid Africa/Ceuta Atlantic/Canary","ET|Africa/Nairobi Africa/Addis_Ababa","FI|Europe/Helsinki","FJ|Pacific/Fiji","FK|Atlantic/Stanley","FM|Pacific/Chuuk Pacific/Pohnpei Pacific/Kosrae","FO|Atlantic/Faroe","FR|Europe/Paris","GA|Africa/Lagos Africa/Libreville","GB|Europe/London","GD|America/Port_of_Spain America/Grenada","GE|Asia/Tbilisi","GF|America/Cayenne","GG|Europe/London Europe/Guernsey","GH|Africa/Accra","GI|Europe/Gibraltar","GL|America/Nuuk America/Danmarkshavn America/Scoresbysund America/Thule","GM|Africa/Abidjan Africa/Banjul","GN|Africa/Abidjan Africa/Conakry","GP|America/Port_of_Spain America/Guadeloupe","GQ|Africa/Lagos Africa/Malabo","GR|Europe/Athens","GS|Atlantic/South_Georgia","GT|America/Guatemala","GU|Pacific/Guam","GW|Africa/Bissau","GY|America/Guyana","HK|Asia/Hong_Kong","HN|America/Tegucigalpa","HR|Europe/Belgrade Europe/Zagreb","HT|America/Port-au-Prince","HU|Europe/Budapest","ID|Asia/Jakarta Asia/Pontianak Asia/Makassar Asia/Jayapura","IE|Europe/Dublin","IL|Asia/Jerusalem","IM|Europe/London Europe/Isle_of_Man","IN|Asia/Kolkata","IO|Indian/Chagos","IQ|Asia/Baghdad","IR|Asia/Tehran","IS|Atlantic/Reykjavik","IT|Europe/Rome","JE|Europe/London Europe/Jersey","JM|America/Jamaica","JO|Asia/Amman","JP|Asia/Tokyo","KE|Africa/Nairobi","KG|Asia/Bishkek","KH|Asia/Bangkok Asia/Phnom_Penh","KI|Pacific/Tarawa Pacific/Enderbury Pacific/Kiritimati","KM|Africa/Nairobi Indian/Comoro","KN|America/Port_of_Spain America/St_Kitts","KP|Asia/Pyongyang","KR|Asia/Seoul","KW|Asia/Riyadh Asia/Kuwait","KY|America/Panama America/Cayman","KZ|Asia/Almaty Asia/Qyzylorda Asia/Qostanay Asia/Aqtobe Asia/Aqtau Asia/Atyrau Asia/Oral","LA|Asia/Bangkok Asia/Vientiane","LB|Asia/Beirut","LC|America/Port_of_Spain America/St_Lucia","LI|Europe/Zurich Europe/Vaduz","LK|Asia/Colombo","LR|Africa/Monrovia","LS|Africa/Johannesburg Africa/Maseru","LT|Europe/Vilnius","LU|Europe/Luxembourg","LV|Europe/Riga","LY|Africa/Tripoli","MA|Africa/Casablanca","MC|Europe/Monaco","MD|Europe/Chisinau","ME|Europe/Belgrade Europe/Podgorica","MF|America/Port_of_Spain America/Marigot","MG|Africa/Nairobi Indian/Antananarivo","MH|Pacific/Majuro Pacific/Kwajalein","MK|Europe/Belgrade Europe/Skopje","ML|Africa/Abidjan Africa/Bamako","MM|Asia/Yangon","MN|Asia/Ulaanbaatar Asia/Hovd Asia/Choibalsan","MO|Asia/Macau","MP|Pacific/Guam Pacific/Saipan","MQ|America/Martinique","MR|Africa/Abidjan Africa/Nouakchott","MS|America/Port_of_Spain America/Montserrat","MT|Europe/Malta","MU|Indian/Mauritius","MV|Indian/Maldives","MW|Africa/Maputo Africa/Blantyre","MX|America/Mexico_City America/Cancun America/Merida America/Monterrey America/Matamoros America/Mazatlan America/Chihuahua America/Ojinaga America/Hermosillo America/Tijuana America/Bahia_Banderas","MY|Asia/Kuala_Lumpur Asia/Kuching","MZ|Africa/Maputo","NA|Africa/Windhoek","NC|Pacific/Noumea","NE|Africa/Lagos Africa/Niamey","NF|Pacific/Norfolk","NG|Africa/Lagos","NI|America/Managua","NL|Europe/Amsterdam","NO|Europe/Oslo","NP|Asia/Kathmandu","NR|Pacific/Nauru","NU|Pacific/Niue","NZ|Pacific/Auckland Pacific/Chatham","OM|Asia/Dubai Asia/Muscat","PA|America/Panama","PE|America/Lima","PF|Pacific/Tahiti Pacific/Marquesas Pacific/Gambier","PG|Pacific/Port_Moresby Pacific/Bougainville","PH|Asia/Manila","PK|Asia/Karachi","PL|Europe/Warsaw","PM|America/Miquelon","PN|Pacific/Pitcairn","PR|America/Puerto_Rico","PS|Asia/Gaza Asia/Hebron","PT|Europe/Lisbon Atlantic/Madeira Atlantic/Azores","PW|Pacific/Palau","PY|America/Asuncion","QA|Asia/Qatar","RE|Indian/Reunion","RO|Europe/Bucharest","RS|Europe/Belgrade","RU|Europe/Kaliningrad Europe/Moscow Europe/Simferopol Europe/Kirov Europe/Volgograd Europe/Astrakhan Europe/Saratov Europe/Ulyanovsk Europe/Samara Asia/Yekaterinburg Asia/Omsk Asia/Novosibirsk Asia/Barnaul Asia/Tomsk Asia/Novokuznetsk Asia/Krasnoyarsk Asia/Irkutsk Asia/Chita Asia/Yakutsk Asia/Khandyga Asia/Vladivostok Asia/Ust-Nera Asia/Magadan Asia/Sakhalin Asia/Srednekolymsk Asia/Kamchatka Asia/Anadyr","RW|Africa/Maputo Africa/Kigali","SA|Asia/Riyadh","SB|Pacific/Guadalcanal","SC|Indian/Mahe","SD|Africa/Khartoum","SE|Europe/Stockholm","SG|Asia/Singapore","SH|Africa/Abidjan Atlantic/St_Helena","SI|Europe/Belgrade Europe/Ljubljana","SJ|Europe/Oslo Arctic/Longyearbyen","SK|Europe/Prague Europe/Bratislava","SL|Africa/Abidjan Africa/Freetown","SM|Europe/Rome Europe/San_Marino","SN|Africa/Abidjan Africa/Dakar","SO|Africa/Nairobi Africa/Mogadishu","SR|America/Paramaribo","SS|Africa/Juba","ST|Africa/Sao_Tome","SV|America/El_Salvador","SX|America/Curacao America/Lower_Princes","SY|Asia/Damascus","SZ|Africa/Johannesburg Africa/Mbabane","TC|America/Grand_Turk","TD|Africa/Ndjamena","TF|Indian/Reunion Indian/Kerguelen","TG|Africa/Abidjan Africa/Lome","TH|Asia/Bangkok","TJ|Asia/Dushanbe","TK|Pacific/Fakaofo","TL|Asia/Dili","TM|Asia/Ashgabat","TN|Africa/Tunis","TO|Pacific/Tongatapu","TR|Europe/Istanbul","TT|America/Port_of_Spain","TV|Pacific/Funafuti","TW|Asia/Taipei","TZ|Africa/Nairobi Africa/Dar_es_Salaam","UA|Europe/Simferopol Europe/Kiev Europe/Uzhgorod Europe/Zaporozhye","UG|Africa/Nairobi Africa/Kampala","UM|Pacific/Pago_Pago Pacific/Wake Pacific/Honolulu Pacific/Midway","US|America/New_York America/Detroit America/Kentucky/Louisville America/Kentucky/Monticello America/Indiana/Indianapolis America/Indiana/Vincennes America/Indiana/Winamac America/Indiana/Marengo America/Indiana/Petersburg America/Indiana/Vevay America/Chicago America/Indiana/Tell_City America/Indiana/Knox America/Menominee America/North_Dakota/Center America/North_Dakota/New_Salem America/North_Dakota/Beulah America/Denver America/Boise America/Phoenix America/Los_Angeles America/Anchorage America/Juneau America/Sitka America/Metlakatla America/Yakutat America/Nome America/Adak Pacific/Honolulu","UY|America/Montevideo","UZ|Asia/Samarkand Asia/Tashkent","VA|Europe/Rome Europe/Vatican","VC|America/Port_of_Spain America/St_Vincent","VE|America/Caracas","VG|America/Port_of_Spain America/Tortola","VI|America/Port_of_Spain America/St_Thomas","VN|Asia/Bangkok Asia/Ho_Chi_Minh","VU|Pacific/Efate","WF|Pacific/Wallis","WS|Pacific/Apia","YE|Asia/Riyadh Asia/Aden","YT|Africa/Nairobi Indian/Mayotte","ZA|Africa/Johannesburg","ZM|Africa/Maputo Africa/Lusaka","ZW|Africa/Maputo Africa/Harare"]}),c});
 
includes/modules/flash-sale/assets/js/moment.min.js DELETED
@@ -1 +0,0 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.moment=t()}(this,function(){"use strict";var e,i;function f(){return e.apply(null,arguments)}function o(e){return e instanceof Array||"[object Array]"===Object.prototype.toString.call(e)}function u(e){return null!=e&&"[object Object]"===Object.prototype.toString.call(e)}function m(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function l(e){if(Object.getOwnPropertyNames)return 0===Object.getOwnPropertyNames(e).length;for(var t in e)if(m(e,t))return;return 1}function r(e){return void 0===e}function h(e){return"number"==typeof e||"[object Number]"===Object.prototype.toString.call(e)}function a(e){return e instanceof Date||"[object Date]"===Object.prototype.toString.call(e)}function d(e,t){for(var n=[],s=0;s<e.length;++s)n.push(t(e[s],s));return n}function c(e,t){for(var n in t)m(t,n)&&(e[n]=t[n]);return m(t,"toString")&&(e.toString=t.toString),m(t,"valueOf")&&(e.valueOf=t.valueOf),e}function _(e,t,n,s){return xt(e,t,n,s,!0).utc()}function y(e){return null==e._pf&&(e._pf={empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidEra:null,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],era:null,meridiem:null,rfc2822:!1,weekdayMismatch:!1}),e._pf}function g(e){if(null==e._isValid){var t=y(e),n=i.call(t.parsedDateParts,function(e){return null!=e}),s=!isNaN(e._d.getTime())&&t.overflow<0&&!t.empty&&!t.invalidEra&&!t.invalidMonth&&!t.invalidWeekday&&!t.weekdayMismatch&&!t.nullInput&&!t.invalidFormat&&!t.userInvalidated&&(!t.meridiem||t.meridiem&&n);if(e._strict&&(s=s&&0===t.charsLeftOver&&0===t.unusedTokens.length&&void 0===t.bigHour),null!=Object.isFrozen&&Object.isFrozen(e))return s;e._isValid=s}return e._isValid}function w(e){var t=_(NaN);return null!=e?c(y(t),e):y(t).userInvalidated=!0,t}i=Array.prototype.some?Array.prototype.some:function(e){for(var t=Object(this),n=t.length>>>0,s=0;s<n;s++)if(s in t&&e.call(this,t[s],s,t))return!0;return!1};var p=f.momentProperties=[],t=!1;function v(e,t){var n,s,i;if(r(t._isAMomentObject)||(e._isAMomentObject=t._isAMomentObject),r(t._i)||(e._i=t._i),r(t._f)||(e._f=t._f),r(t._l)||(e._l=t._l),r(t._strict)||(e._strict=t._strict),r(t._tzm)||(e._tzm=t._tzm),r(t._isUTC)||(e._isUTC=t._isUTC),r(t._offset)||(e._offset=t._offset),r(t._pf)||(e._pf=y(t)),r(t._locale)||(e._locale=t._locale),0<p.length)for(n=0;n<p.length;n++)r(i=t[s=p[n]])||(e[s]=i);return e}function k(e){v(this,e),this._d=new Date(null!=e._d?e._d.getTime():NaN),this.isValid()||(this._d=new Date(NaN)),!1===t&&(t=!0,f.updateOffset(this),t=!1)}function M(e){return e instanceof k||null!=e&&null!=e._isAMomentObject}function D(e){!1===f.suppressDeprecationWarnings&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+e)}function n(i,r){var a=!0;return c(function(){if(null!=f.deprecationHandler&&f.deprecationHandler(null,i),a){for(var e,t,n=[],s=0;s<arguments.length;s++){if(e="","object"==typeof arguments[s]){for(t in e+="\n["+s+"] ",arguments[0])m(arguments[0],t)&&(e+=t+": "+arguments[0][t]+", ");e=e.slice(0,-2)}else e=arguments[s];n.push(e)}D(i+"\nArguments: "+Array.prototype.slice.call(n).join("")+"\n"+(new Error).stack),a=!1}return r.apply(this,arguments)},r)}var s,S={};function Y(e,t){null!=f.deprecationHandler&&f.deprecationHandler(e,t),S[e]||(D(t),S[e]=!0)}function O(e){return"undefined"!=typeof Function&&e instanceof Function||"[object Function]"===Object.prototype.toString.call(e)}function b(e,t){var n,s=c({},e);for(n in t)m(t,n)&&(u(e[n])&&u(t[n])?(s[n]={},c(s[n],e[n]),c(s[n],t[n])):null!=t[n]?s[n]=t[n]:delete s[n]);for(n in e)m(e,n)&&!m(t,n)&&u(e[n])&&(s[n]=c({},s[n]));return s}function x(e){null!=e&&this.set(e)}f.suppressDeprecationWarnings=!1,f.deprecationHandler=null,s=Object.keys?Object.keys:function(e){var t,n=[];for(t in e)m(e,t)&&n.push(t);return n};function T(e,t,n){var s=""+Math.abs(e),i=t-s.length;return(0<=e?n?"+":"":"-")+Math.pow(10,Math.max(0,i)).toString().substr(1)+s}var N=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,P=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,R={},W={};function C(e,t,n,s){var i="string"==typeof s?function(){return this[s]()}:s;e&&(W[e]=i),t&&(W[t[0]]=function(){return T(i.apply(this,arguments),t[1],t[2])}),n&&(W[n]=function(){return this.localeData().ordinal(i.apply(this,arguments),e)})}function U(e,t){return e.isValid()?(t=H(t,e.localeData()),R[t]=R[t]||function(s){for(var e,i=s.match(N),t=0,r=i.length;t<r;t++)W[i[t]]?i[t]=W[i[t]]:i[t]=(e=i[t]).match(/\[[\s\S]/)?e.replace(/^\[|\]$/g,""):e.replace(/\\/g,"");return function(e){for(var t="",n=0;n<r;n++)t+=O(i[n])?i[n].call(e,s):i[n];return t}}(t),R[t](e)):e.localeData().invalidDate()}function H(e,t){var n=5;function s(e){return t.longDateFormat(e)||e}for(P.lastIndex=0;0<=n&&P.test(e);)e=e.replace(P,s),P.lastIndex=0,--n;return e}var F={};function L(e,t){var n=e.toLowerCase();F[n]=F[n+"s"]=F[t]=e}function V(e){return"string"==typeof e?F[e]||F[e.toLowerCase()]:void 0}function G(e){var t,n,s={};for(n in e)m(e,n)&&(t=V(n))&&(s[t]=e[n]);return s}var E={};function A(e,t){E[e]=t}function j(e){return e%4==0&&e%100!=0||e%400==0}function I(e){return e<0?Math.ceil(e)||0:Math.floor(e)}function Z(e){var t=+e,n=0;return 0!=t&&isFinite(t)&&(n=I(t)),n}function z(t,n){return function(e){return null!=e?(q(this,t,e),f.updateOffset(this,n),this):$(this,t)}}function $(e,t){return e.isValid()?e._d["get"+(e._isUTC?"UTC":"")+t]():NaN}function q(e,t,n){e.isValid()&&!isNaN(n)&&("FullYear"===t&&j(e.year())&&1===e.month()&&29===e.date()?(n=Z(n),e._d["set"+(e._isUTC?"UTC":"")+t](n,e.month(),xe(n,e.month()))):e._d["set"+(e._isUTC?"UTC":"")+t](n))}var B,J=/\d/,Q=/\d\d/,X=/\d{3}/,K=/\d{4}/,ee=/[+-]?\d{6}/,te=/\d\d?/,ne=/\d\d\d\d?/,se=/\d\d\d\d\d\d?/,ie=/\d{1,3}/,re=/\d{1,4}/,ae=/[+-]?\d{1,6}/,oe=/\d+/,ue=/[+-]?\d+/,le=/Z|[+-]\d\d:?\d\d/gi,he=/Z|[+-]\d\d(?::?\d\d)?/gi,de=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i;function ce(e,n,s){B[e]=O(n)?n:function(e,t){return e&&s?s:n}}function fe(e,t){return m(B,e)?B[e](t._strict,t._locale):new RegExp(me(e.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(e,t,n,s,i){return t||n||s||i})))}function me(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}B={};var _e={};function ye(e,n){var t,s=n;for("string"==typeof e&&(e=[e]),h(n)&&(s=function(e,t){t[n]=Z(e)}),t=0;t<e.length;t++)_e[e[t]]=s}function ge(e,i){ye(e,function(e,t,n,s){n._w=n._w||{},i(e,n._w,n,s)})}var we,pe=0,ve=1,ke=2,Me=3,De=4,Se=5,Ye=6,Oe=7,be=8;function xe(e,t){if(isNaN(e)||isNaN(t))return NaN;var n,s=(t%(n=12)+n)%n;return e+=(t-s)/12,1==s?j(e)?29:28:31-s%7%2}we=Array.prototype.indexOf?Array.prototype.indexOf:function(e){for(var t=0;t<this.length;++t)if(this[t]===e)return t;return-1},C("M",["MM",2],"Mo",function(){return this.month()+1}),C("MMM",0,0,function(e){return this.localeData().monthsShort(this,e)}),C("MMMM",0,0,function(e){return this.localeData().months(this,e)}),L("month","M"),A("month",8),ce("M",te),ce("MM",te,Q),ce("MMM",function(e,t){return t.monthsShortRegex(e)}),ce("MMMM",function(e,t){return t.monthsRegex(e)}),ye(["M","MM"],function(e,t){t[ve]=Z(e)-1}),ye(["MMM","MMMM"],function(e,t,n,s){var i=n._locale.monthsParse(e,s,n._strict);null!=i?t[ve]=i:y(n).invalidMonth=e});var Te="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Ne="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Pe=/D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/,Re=de,We=de;function Ce(e,t){var n;if(!e.isValid())return e;if("string"==typeof t)if(/^\d+$/.test(t))t=Z(t);else if(!h(t=e.localeData().monthsParse(t)))return e;return n=Math.min(e.date(),xe(e.year(),t)),e._d["set"+(e._isUTC?"UTC":"")+"Month"](t,n),e}function Ue(e){return null!=e?(Ce(this,e),f.updateOffset(this,!0),this):$(this,"Month")}function He(){function e(e,t){return t.length-e.length}for(var t,n=[],s=[],i=[],r=0;r<12;r++)t=_([2e3,r]),n.push(this.monthsShort(t,"")),s.push(this.months(t,"")),i.push(this.months(t,"")),i.push(this.monthsShort(t,""));for(n.sort(e),s.sort(e),i.sort(e),r=0;r<12;r++)n[r]=me(n[r]),s[r]=me(s[r]);for(r=0;r<24;r++)i[r]=me(i[r]);this._monthsRegex=new RegExp("^("+i.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+n.join("|")+")","i")}function Fe(e){return j(e)?366:365}C("Y",0,0,function(){var e=this.year();return e<=9999?T(e,4):"+"+e}),C(0,["YY",2],0,function(){return this.year()%100}),C(0,["YYYY",4],0,"year"),C(0,["YYYYY",5],0,"year"),C(0,["YYYYYY",6,!0],0,"year"),L("year","y"),A("year",1),ce("Y",ue),ce("YY",te,Q),ce("YYYY",re,K),ce("YYYYY",ae,ee),ce("YYYYYY",ae,ee),ye(["YYYYY","YYYYYY"],pe),ye("YYYY",function(e,t){t[pe]=2===e.length?f.parseTwoDigitYear(e):Z(e)}),ye("YY",function(e,t){t[pe]=f.parseTwoDigitYear(e)}),ye("Y",function(e,t){t[pe]=parseInt(e,10)}),f.parseTwoDigitYear=function(e){return Z(e)+(68<Z(e)?1900:2e3)};var Le=z("FullYear",!0);function Ve(e){var t,n;return e<100&&0<=e?((n=Array.prototype.slice.call(arguments))[0]=e+400,t=new Date(Date.UTC.apply(null,n)),isFinite(t.getUTCFullYear())&&t.setUTCFullYear(e)):t=new Date(Date.UTC.apply(null,arguments)),t}function Ge(e,t,n){var s=7+t-n;return s-(7+Ve(e,0,s).getUTCDay()-t)%7-1}function Ee(e,t,n,s,i){var r,a=1+7*(t-1)+(7+n-s)%7+Ge(e,s,i),o=a<=0?Fe(r=e-1)+a:a>Fe(e)?(r=e+1,a-Fe(e)):(r=e,a);return{year:r,dayOfYear:o}}function Ae(e,t,n){var s,i,r=Ge(e.year(),t,n),a=Math.floor((e.dayOfYear()-r-1)/7)+1;return a<1?s=a+je(i=e.year()-1,t,n):a>je(e.year(),t,n)?(s=a-je(e.year(),t,n),i=e.year()+1):(i=e.year(),s=a),{week:s,year:i}}function je(e,t,n){var s=Ge(e,t,n),i=Ge(e+1,t,n);return(Fe(e)-s+i)/7}C("w",["ww",2],"wo","week"),C("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),A("week",5),A("isoWeek",5),ce("w",te),ce("ww",te,Q),ce("W",te),ce("WW",te,Q),ge(["w","ww","W","WW"],function(e,t,n,s){t[s.substr(0,1)]=Z(e)});function Ie(e,t){return e.slice(t,7).concat(e.slice(0,t))}C("d",0,"do","day"),C("dd",0,0,function(e){return this.localeData().weekdaysMin(this,e)}),C("ddd",0,0,function(e){return this.localeData().weekdaysShort(this,e)}),C("dddd",0,0,function(e){return this.localeData().weekdays(this,e)}),C("e",0,0,"weekday"),C("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),A("day",11),A("weekday",11),A("isoWeekday",11),ce("d",te),ce("e",te),ce("E",te),ce("dd",function(e,t){return t.weekdaysMinRegex(e)}),ce("ddd",function(e,t){return t.weekdaysShortRegex(e)}),ce("dddd",function(e,t){return t.weekdaysRegex(e)}),ge(["dd","ddd","dddd"],function(e,t,n,s){var i=n._locale.weekdaysParse(e,s,n._strict);null!=i?t.d=i:y(n).invalidWeekday=e}),ge(["d","e","E"],function(e,t,n,s){t[s]=Z(e)});var Ze="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),ze="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),$e="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),qe=de,Be=de,Je=de;function Qe(){function e(e,t){return t.length-e.length}for(var t,n,s,i,r=[],a=[],o=[],u=[],l=0;l<7;l++)t=_([2e3,1]).day(l),n=me(this.weekdaysMin(t,"")),s=me(this.weekdaysShort(t,"")),i=me(this.weekdays(t,"")),r.push(n),a.push(s),o.push(i),u.push(n),u.push(s),u.push(i);r.sort(e),a.sort(e),o.sort(e),u.sort(e),this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+o.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+a.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+r.join("|")+")","i")}function Xe(){return this.hours()%12||12}function Ke(e,t){C(e,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),t)})}function et(e,t){return t._meridiemParse}C("H",["HH",2],0,"hour"),C("h",["hh",2],0,Xe),C("k",["kk",2],0,function(){return this.hours()||24}),C("hmm",0,0,function(){return""+Xe.apply(this)+T(this.minutes(),2)}),C("hmmss",0,0,function(){return""+Xe.apply(this)+T(this.minutes(),2)+T(this.seconds(),2)}),C("Hmm",0,0,function(){return""+this.hours()+T(this.minutes(),2)}),C("Hmmss",0,0,function(){return""+this.hours()+T(this.minutes(),2)+T(this.seconds(),2)}),Ke("a",!0),Ke("A",!1),L("hour","h"),A("hour",13),ce("a",et),ce("A",et),ce("H",te),ce("h",te),ce("k",te),ce("HH",te,Q),ce("hh",te,Q),ce("kk",te,Q),ce("hmm",ne),ce("hmmss",se),ce("Hmm",ne),ce("Hmmss",se),ye(["H","HH"],Me),ye(["k","kk"],function(e,t,n){var s=Z(e);t[Me]=24===s?0:s}),ye(["a","A"],function(e,t,n){n._isPm=n._locale.isPM(e),n._meridiem=e}),ye(["h","hh"],function(e,t,n){t[Me]=Z(e),y(n).bigHour=!0}),ye("hmm",function(e,t,n){var s=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s)),y(n).bigHour=!0}),ye("hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s,2)),t[Se]=Z(e.substr(i)),y(n).bigHour=!0}),ye("Hmm",function(e,t,n){var s=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s))}),ye("Hmmss",function(e,t,n){var s=e.length-4,i=e.length-2;t[Me]=Z(e.substr(0,s)),t[De]=Z(e.substr(s,2)),t[Se]=Z(e.substr(i))});var tt=z("Hours",!0);var nt,st={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",w:"a week",ww:"%d weeks",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Te,monthsShort:Ne,week:{dow:0,doy:6},weekdays:Ze,weekdaysMin:$e,weekdaysShort:ze,meridiemParse:/[ap]\.?m?\.?/i},it={},rt={};function at(e){return e?e.toLowerCase().replace("_","-"):e}function ot(e){for(var t,n,s,i,r=0;r<e.length;){for(t=(i=at(e[r]).split("-")).length,n=(n=at(e[r+1]))?n.split("-"):null;0<t;){if(s=ut(i.slice(0,t).join("-")))return s;if(n&&n.length>=t&&function(e,t){for(var n=Math.min(e.length,t.length),s=0;s<n;s+=1)if(e[s]!==t[s])return s;return n}(i,n)>=t-1)break;t--}r++}return nt}function ut(t){var e;if(void 0===it[t]&&"undefined"!=typeof module&&module&&module.exports)try{e=nt._abbr,require("./locale/"+t),lt(e)}catch(e){it[t]=null}return it[t]}function lt(e,t){var n;return e&&((n=r(t)?dt(e):ht(e,t))?nt=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+e+" not found. Did you forget to load it?")),nt._abbr}function ht(e,t){if(null===t)return delete it[e],null;var n,s=st;if(t.abbr=e,null!=it[e])Y("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),s=it[e]._config;else if(null!=t.parentLocale)if(null!=it[t.parentLocale])s=it[t.parentLocale]._config;else{if(null==(n=ut(t.parentLocale)))return rt[t.parentLocale]||(rt[t.parentLocale]=[]),rt[t.parentLocale].push({name:e,config:t}),null;s=n._config}return it[e]=new x(b(s,t)),rt[e]&&rt[e].forEach(function(e){ht(e.name,e.config)}),lt(e),it[e]}function dt(e){var t;if(e&&e._locale&&e._locale._abbr&&(e=e._locale._abbr),!e)return nt;if(!o(e)){if(t=ut(e))return t;e=[e]}return ot(e)}function ct(e){var t,n=e._a;return n&&-2===y(e).overflow&&(t=n[ve]<0||11<n[ve]?ve:n[ke]<1||n[ke]>xe(n[pe],n[ve])?ke:n[Me]<0||24<n[Me]||24===n[Me]&&(0!==n[De]||0!==n[Se]||0!==n[Ye])?Me:n[De]<0||59<n[De]?De:n[Se]<0||59<n[Se]?Se:n[Ye]<0||999<n[Ye]?Ye:-1,y(e)._overflowDayOfYear&&(t<pe||ke<t)&&(t=ke),y(e)._overflowWeeks&&-1===t&&(t=Oe),y(e)._overflowWeekday&&-1===t&&(t=be),y(e).overflow=t),e}var ft=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,mt=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_t=/Z|[+-]\d\d(?::?\d\d)?/,yt=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/],["YYYYMM",/\d{6}/,!1],["YYYY",/\d{4}/,!1]],gt=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],wt=/^\/?Date\((-?\d+)/i,pt=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/,vt={UT:0,GMT:0,EDT:-240,EST:-300,CDT:-300,CST:-360,MDT:-360,MST:-420,PDT:-420,PST:-480};function kt(e){var t,n,s,i,r,a,o=e._i,u=ft.exec(o)||mt.exec(o);if(u){for(y(e).iso=!0,t=0,n=yt.length;t<n;t++)if(yt[t][1].exec(u[1])){i=yt[t][0],s=!1!==yt[t][2];break}if(null==i)return void(e._isValid=!1);if(u[3]){for(t=0,n=gt.length;t<n;t++)if(gt[t][1].exec(u[3])){r=(u[2]||" ")+gt[t][0];break}if(null==r)return void(e._isValid=!1)}if(!s&&null!=r)return void(e._isValid=!1);if(u[4]){if(!_t.exec(u[4]))return void(e._isValid=!1);a="Z"}e._f=i+(r||"")+(a||""),Ot(e)}else e._isValid=!1}function Mt(e,t,n,s,i,r){var a=[function(e){var t=parseInt(e,10);{if(t<=49)return 2e3+t;if(t<=999)return 1900+t}return t}(e),Ne.indexOf(t),parseInt(n,10),parseInt(s,10),parseInt(i,10)];return r&&a.push(parseInt(r,10)),a}function Dt(e){var t,n,s,i,r=pt.exec(e._i.replace(/\([^)]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").replace(/^\s\s*/,"").replace(/\s\s*$/,""));if(r){if(t=Mt(r[4],r[3],r[2],r[5],r[6],r[7]),n=r[1],s=t,i=e,n&&ze.indexOf(n)!==new Date(s[0],s[1],s[2]).getDay()&&(y(i).weekdayMismatch=!0,!void(i._isValid=!1)))return;e._a=t,e._tzm=function(e,t,n){if(e)return vt[e];if(t)return 0;var s=parseInt(n,10),i=s%100;return 60*((s-i)/100)+i}(r[8],r[9],r[10]),e._d=Ve.apply(null,e._a),e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),y(e).rfc2822=!0}else e._isValid=!1}function St(e,t,n){return null!=e?e:null!=t?t:n}function Yt(e){var t,n,s,i,r,a,o,u=[];if(!e._d){for(a=e,o=new Date(f.now()),s=a._useUTC?[o.getUTCFullYear(),o.getUTCMonth(),o.getUTCDate()]:[o.getFullYear(),o.getMonth(),o.getDate()],e._w&&null==e._a[ke]&&null==e._a[ve]&&function(e){var t,n,s,i,r,a,o,u,l;null!=(t=e._w).GG||null!=t.W||null!=t.E?(r=1,a=4,n=St(t.GG,e._a[pe],Ae(Tt(),1,4).year),s=St(t.W,1),((i=St(t.E,1))<1||7<i)&&(u=!0)):(r=e._locale._week.dow,a=e._locale._week.doy,l=Ae(Tt(),r,a),n=St(t.gg,e._a[pe],l.year),s=St(t.w,l.week),null!=t.d?((i=t.d)<0||6<i)&&(u=!0):null!=t.e?(i=t.e+r,(t.e<0||6<t.e)&&(u=!0)):i=r);s<1||s>je(n,r,a)?y(e)._overflowWeeks=!0:null!=u?y(e)._overflowWeekday=!0:(o=Ee(n,s,i,r,a),e._a[pe]=o.year,e._dayOfYear=o.dayOfYear)}(e),null!=e._dayOfYear&&(r=St(e._a[pe],s[pe]),(e._dayOfYear>Fe(r)||0===e._dayOfYear)&&(y(e)._overflowDayOfYear=!0),n=Ve(r,0,e._dayOfYear),e._a[ve]=n.getUTCMonth(),e._a[ke]=n.getUTCDate()),t=0;t<3&&null==e._a[t];++t)e._a[t]=u[t]=s[t];for(;t<7;t++)e._a[t]=u[t]=null==e._a[t]?2===t?1:0:e._a[t];24===e._a[Me]&&0===e._a[De]&&0===e._a[Se]&&0===e._a[Ye]&&(e._nextDay=!0,e._a[Me]=0),e._d=(e._useUTC?Ve:function(e,t,n,s,i,r,a){var o;return e<100&&0<=e?(o=new Date(e+400,t,n,s,i,r,a),isFinite(o.getFullYear())&&o.setFullYear(e)):o=new Date(e,t,n,s,i,r,a),o}).apply(null,u),i=e._useUTC?e._d.getUTCDay():e._d.getDay(),null!=e._tzm&&e._d.setUTCMinutes(e._d.getUTCMinutes()-e._tzm),e._nextDay&&(e._a[Me]=24),e._w&&void 0!==e._w.d&&e._w.d!==i&&(y(e).weekdayMismatch=!0)}}function Ot(e){if(e._f!==f.ISO_8601)if(e._f!==f.RFC_2822){e._a=[],y(e).empty=!0;for(var t,n,s,i,r,a,o,u=""+e._i,l=u.length,h=0,d=H(e._f,e._locale).match(N)||[],c=0;c<d.length;c++)n=d[c],(t=(u.match(fe(n,e))||[])[0])&&(0<(s=u.substr(0,u.indexOf(t))).length&&y(e).unusedInput.push(s),u=u.slice(u.indexOf(t)+t.length),h+=t.length),W[n]?(t?y(e).empty=!1:y(e).unusedTokens.push(n),r=n,o=e,null!=(a=t)&&m(_e,r)&&_e[r](a,o._a,o,r)):e._strict&&!t&&y(e).unusedTokens.push(n);y(e).charsLeftOver=l-h,0<u.length&&y(e).unusedInput.push(u),e._a[Me]<=12&&!0===y(e).bigHour&&0<e._a[Me]&&(y(e).bigHour=void 0),y(e).parsedDateParts=e._a.slice(0),y(e).meridiem=e._meridiem,e._a[Me]=function(e,t,n){var s;if(null==n)return t;return null!=e.meridiemHour?e.meridiemHour(t,n):(null!=e.isPM&&((s=e.isPM(n))&&t<12&&(t+=12),s||12!==t||(t=0)),t)}(e._locale,e._a[Me],e._meridiem),null!==(i=y(e).era)&&(e._a[pe]=e._locale.erasConvertYear(i,e._a[pe])),Yt(e),ct(e)}else Dt(e);else kt(e)}function bt(e){var t,n,s=e._i,i=e._f;return e._locale=e._locale||dt(e._l),null===s||void 0===i&&""===s?w({nullInput:!0}):("string"==typeof s&&(e._i=s=e._locale.preparse(s)),M(s)?new k(ct(s)):(a(s)?e._d=s:o(i)?function(e){var t,n,s,i,r,a,o=!1;if(0===e._f.length)return y(e).invalidFormat=!0,e._d=new Date(NaN);for(i=0;i<e._f.length;i++)r=0,a=!1,t=v({},e),null!=e._useUTC&&(t._useUTC=e._useUTC),t._f=e._f[i],Ot(t),g(t)&&(a=!0),r+=y(t).charsLeftOver,r+=10*y(t).unusedTokens.length,y(t).score=r,o?r<s&&(s=r,n=t):(null==s||r<s||a)&&(s=r,n=t,a&&(o=!0));c(e,n||t)}(e):i?Ot(e):r(n=(t=e)._i)?t._d=new Date(f.now()):a(n)?t._d=new Date(n.valueOf()):"string"==typeof n?function(e){var t=wt.exec(e._i);null===t?(kt(e),!1===e._isValid&&(delete e._isValid,Dt(e),!1===e._isValid&&(delete e._isValid,e._strict?e._isValid=!1:f.createFromInputFallback(e)))):e._d=new Date(+t[1])}(t):o(n)?(t._a=d(n.slice(0),function(e){return parseInt(e,10)}),Yt(t)):u(n)?function(e){var t,n;e._d||(n=void 0===(t=G(e._i)).day?t.date:t.day,e._a=d([t.year,t.month,n,t.hour,t.minute,t.second,t.millisecond],function(e){return e&&parseInt(e,10)}),Yt(e))}(t):h(n)?t._d=new Date(n):f.createFromInputFallback(t),g(e)||(e._d=null),e))}function xt(e,t,n,s,i){var r,a={};return!0!==t&&!1!==t||(s=t,t=void 0),!0!==n&&!1!==n||(s=n,n=void 0),(u(e)&&l(e)||o(e)&&0===e.length)&&(e=void 0),a._isAMomentObject=!0,a._useUTC=a._isUTC=i,a._l=n,a._i=e,a._f=t,a._strict=s,(r=new k(ct(bt(a))))._nextDay&&(r.add(1,"d"),r._nextDay=void 0),r}function Tt(e,t,n,s){return xt(e,t,n,s,!1)}f.createFromInputFallback=n("value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.",function(e){e._d=new Date(e._i+(e._useUTC?" UTC":""))}),f.ISO_8601=function(){},f.RFC_2822=function(){};var Nt=n("moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?e<this?this:e:w()}),Pt=n("moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/",function(){var e=Tt.apply(null,arguments);return this.isValid()&&e.isValid()?this<e?this:e:w()});function Rt(e,t){var n,s;if(1===t.length&&o(t[0])&&(t=t[0]),!t.length)return Tt();for(n=t[0],s=1;s<t.length;++s)t[s].isValid()&&!t[s][e](n)||(n=t[s]);return n}var Wt=["year","quarter","month","week","day","hour","minute","second","millisecond"];function Ct(e){var t=G(e),n=t.year||0,s=t.quarter||0,i=t.month||0,r=t.week||t.isoWeek||0,a=t.day||0,o=t.hour||0,u=t.minute||0,l=t.second||0,h=t.millisecond||0;this._isValid=function(e){var t,n,s=!1;for(t in e)if(m(e,t)&&(-1===we.call(Wt,t)||null!=e[t]&&isNaN(e[t])))return!1;for(n=0;n<Wt.length;++n)if(e[Wt[n]]){if(s)return!1;parseFloat(e[Wt[n]])!==Z(e[Wt[n]])&&(s=!0)}return!0}(t),this._milliseconds=+h+1e3*l+6e4*u+1e3*o*60*60,this._days=+a+7*r,this._months=+i+3*s+12*n,this._data={},this._locale=dt(),this._bubble()}function Ut(e){return e instanceof Ct}function Ht(e){return e<0?-1*Math.round(-1*e):Math.round(e)}function Ft(e,n){C(e,0,0,function(){var e=this.utcOffset(),t="+";return e<0&&(e=-e,t="-"),t+T(~~(e/60),2)+n+T(~~e%60,2)})}Ft("Z",":"),Ft("ZZ",""),ce("Z",he),ce("ZZ",he),ye(["Z","ZZ"],function(e,t,n){n._useUTC=!0,n._tzm=Vt(he,e)});var Lt=/([\+\-]|\d\d)/gi;function Vt(e,t){var n,s,i=(t||"").match(e);return null===i?null:0===(s=60*(n=((i[i.length-1]||[])+"").match(Lt)||["-",0,0])[1]+Z(n[2]))?0:"+"===n[0]?s:-s}function Gt(e,t){var n,s;return t._isUTC?(n=t.clone(),s=(M(e)||a(e)?e.valueOf():Tt(e).valueOf())-n.valueOf(),n._d.setTime(n._d.valueOf()+s),f.updateOffset(n,!1),n):Tt(e).local()}function Et(e){return-Math.round(e._d.getTimezoneOffset())}function At(){return!!this.isValid()&&(this._isUTC&&0===this._offset)}f.updateOffset=function(){};var jt=/^(-|\+)?(?:(\d*)[. ])?(\d+):(\d+)(?::(\d+)(\.\d*)?)?$/,It=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/;function Zt(e,t){var n,s,i,r=e,a=null;return Ut(e)?r={ms:e._milliseconds,d:e._days,M:e._months}:h(e)||!isNaN(+e)?(r={},t?r[t]=+e:r.milliseconds=+e):(a=jt.exec(e))?(n="-"===a[1]?-1:1,r={y:0,d:Z(a[ke])*n,h:Z(a[Me])*n,m:Z(a[De])*n,s:Z(a[Se])*n,ms:Z(Ht(1e3*a[Ye]))*n}):(a=It.exec(e))?(n="-"===a[1]?-1:1,r={y:zt(a[2],n),M:zt(a[3],n),w:zt(a[4],n),d:zt(a[5],n),h:zt(a[6],n),m:zt(a[7],n),s:zt(a[8],n)}):null==r?r={}:"object"==typeof r&&("from"in r||"to"in r)&&(i=function(e,t){var n;if(!e.isValid()||!t.isValid())return{milliseconds:0,months:0};t=Gt(t,e),e.isBefore(t)?n=$t(e,t):((n=$t(t,e)).milliseconds=-n.milliseconds,n.months=-n.months);return n}(Tt(r.from),Tt(r.to)),(r={}).ms=i.milliseconds,r.M=i.months),s=new Ct(r),Ut(e)&&m(e,"_locale")&&(s._locale=e._locale),Ut(e)&&m(e,"_isValid")&&(s._isValid=e._isValid),s}function zt(e,t){var n=e&&parseFloat(e.replace(",","."));return(isNaN(n)?0:n)*t}function $t(e,t){var n={};return n.months=t.month()-e.month()+12*(t.year()-e.year()),e.clone().add(n.months,"M").isAfter(t)&&--n.months,n.milliseconds=t-e.clone().add(n.months,"M"),n}function qt(s,i){return function(e,t){var n;return null===t||isNaN(+t)||(Y(i,"moment()."+i+"(period, number) is deprecated. Please use moment()."+i+"(number, period). See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info."),n=e,e=t,t=n),Bt(this,Zt(e,t),s),this}}function Bt(e,t,n,s){var i=t._milliseconds,r=Ht(t._days),a=Ht(t._months);e.isValid()&&(s=null==s||s,a&&Ce(e,$(e,"Month")+a*n),r&&q(e,"Date",$(e,"Date")+r*n),i&&e._d.setTime(e._d.valueOf()+i*n),s&&f.updateOffset(e,r||a))}Zt.fn=Ct.prototype,Zt.invalid=function(){return Zt(NaN)};var Jt=qt(1,"add"),Qt=qt(-1,"subtract");function Xt(e){return"string"==typeof e||e instanceof String}function Kt(e){return M(e)||a(e)||Xt(e)||h(e)||function(t){var e=o(t),n=!1;e&&(n=0===t.filter(function(e){return!h(e)&&Xt(t)}).length);return e&&n}(e)||function(e){var t,n,s=u(e)&&!l(e),i=!1,r=["years","year","y","months","month","M","days","day","d","dates","date","D","hours","hour","h","minutes","minute","m","seconds","second","s","milliseconds","millisecond","ms"];for(t=0;t<r.length;t+=1)n=r[t],i=i||m(e,n);return s&&i}(e)||null==e}function en(e,t){if(e.date()<t.date())return-en(t,e);var n=12*(t.year()-e.year())+(t.month()-e.month()),s=e.clone().add(n,"months"),i=t-s<0?(t-s)/(s-e.clone().add(n-1,"months")):(t-s)/(e.clone().add(1+n,"months")-s);return-(n+i)||0}function tn(e){var t;return void 0===e?this._locale._abbr:(null!=(t=dt(e))&&(this._locale=t),this)}f.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",f.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var nn=n("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(e){return void 0===e?this.localeData():this.locale(e)});function sn(){return this._locale}var rn=126227808e5;function an(e,t){return(e%t+t)%t}function on(e,t,n){return e<100&&0<=e?new Date(e+400,t,n)-rn:new Date(e,t,n).valueOf()}function un(e,t,n){return e<100&&0<=e?Date.UTC(e+400,t,n)-rn:Date.UTC(e,t,n)}function ln(e,t){return t.erasAbbrRegex(e)}function hn(){for(var e=[],t=[],n=[],s=[],i=this.eras(),r=0,a=i.length;r<a;++r)t.push(me(i[r].name)),e.push(me(i[r].abbr)),n.push(me(i[r].narrow)),s.push(me(i[r].name)),s.push(me(i[r].abbr)),s.push(me(i[r].narrow));this._erasRegex=new RegExp("^("+s.join("|")+")","i"),this._erasNameRegex=new RegExp("^("+t.join("|")+")","i"),this._erasAbbrRegex=new RegExp("^("+e.join("|")+")","i"),this._erasNarrowRegex=new RegExp("^("+n.join("|")+")","i")}function dn(e,t){C(0,[e,e.length],0,t)}function cn(e,t,n,s,i){var r;return null==e?Ae(this,s,i).year:((r=je(e,s,i))<t&&(t=r),function(e,t,n,s,i){var r=Ee(e,t,n,s,i),a=Ve(r.year,0,r.dayOfYear);return this.year(a.getUTCFullYear()),this.month(a.getUTCMonth()),this.date(a.getUTCDate()),this}.call(this,e,t,n,s,i))}C("N",0,0,"eraAbbr"),C("NN",0,0,"eraAbbr"),C("NNN",0,0,"eraAbbr"),C("NNNN",0,0,"eraName"),C("NNNNN",0,0,"eraNarrow"),C("y",["y",1],"yo","eraYear"),C("y",["yy",2],0,"eraYear"),C("y",["yyy",3],0,"eraYear"),C("y",["yyyy",4],0,"eraYear"),ce("N",ln),ce("NN",ln),ce("NNN",ln),ce("NNNN",function(e,t){return t.erasNameRegex(e)}),ce("NNNNN",function(e,t){return t.erasNarrowRegex(e)}),ye(["N","NN","NNN","NNNN","NNNNN"],function(e,t,n,s){var i=n._locale.erasParse(e,s,n._strict);i?y(n).era=i:y(n).invalidEra=e}),ce("y",oe),ce("yy",oe),ce("yyy",oe),ce("yyyy",oe),ce("yo",function(e,t){return t._eraYearOrdinalRegex||oe}),ye(["y","yy","yyy","yyyy"],pe),ye(["yo"],function(e,t,n,s){var i;n._locale._eraYearOrdinalRegex&&(i=e.match(n._locale._eraYearOrdinalRegex)),n._locale.eraYearOrdinalParse?t[pe]=n._locale.eraYearOrdinalParse(e,i):t[pe]=parseInt(e,10)}),C(0,["gg",2],0,function(){return this.weekYear()%100}),C(0,["GG",2],0,function(){return this.isoWeekYear()%100}),dn("gggg","weekYear"),dn("ggggg","weekYear"),dn("GGGG","isoWeekYear"),dn("GGGGG","isoWeekYear"),L("weekYear","gg"),L("isoWeekYear","GG"),A("weekYear",1),A("isoWeekYear",1),ce("G",ue),ce("g",ue),ce("GG",te,Q),ce("gg",te,Q),ce("GGGG",re,K),ce("gggg",re,K),ce("GGGGG",ae,ee),ce("ggggg",ae,ee),ge(["gggg","ggggg","GGGG","GGGGG"],function(e,t,n,s){t[s.substr(0,2)]=Z(e)}),ge(["gg","GG"],function(e,t,n,s){t[s]=f.parseTwoDigitYear(e)}),C("Q",0,"Qo","quarter"),L("quarter","Q"),A("quarter",7),ce("Q",J),ye("Q",function(e,t){t[ve]=3*(Z(e)-1)}),C("D",["DD",2],"Do","date"),L("date","D"),A("date",9),ce("D",te),ce("DD",te,Q),ce("Do",function(e,t){return e?t._dayOfMonthOrdinalParse||t._ordinalParse:t._dayOfMonthOrdinalParseLenient}),ye(["D","DD"],ke),ye("Do",function(e,t){t[ke]=Z(e.match(te)[0])});var fn=z("Date",!0);C("DDD",["DDDD",3],"DDDo","dayOfYear"),L("dayOfYear","DDD"),A("dayOfYear",4),ce("DDD",ie),ce("DDDD",X),ye(["DDD","DDDD"],function(e,t,n){n._dayOfYear=Z(e)}),C("m",["mm",2],0,"minute"),L("minute","m"),A("minute",14),ce("m",te),ce("mm",te,Q),ye(["m","mm"],De);var mn=z("Minutes",!1);C("s",["ss",2],0,"second"),L("second","s"),A("second",15),ce("s",te),ce("ss",te,Q),ye(["s","ss"],Se);var _n,yn,gn=z("Seconds",!1);for(C("S",0,0,function(){return~~(this.millisecond()/100)}),C(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),C(0,["SSS",3],0,"millisecond"),C(0,["SSSS",4],0,function(){return 10*this.millisecond()}),C(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),C(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),C(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),C(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),C(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),L("millisecond","ms"),A("millisecond",16),ce("S",ie,J),ce("SS",ie,Q),ce("SSS",ie,X),_n="SSSS";_n.length<=9;_n+="S")ce(_n,oe);function wn(e,t){t[Ye]=Z(1e3*("0."+e))}for(_n="S";_n.length<=9;_n+="S")ye(_n,wn);yn=z("Milliseconds",!1),C("z",0,0,"zoneAbbr"),C("zz",0,0,"zoneName");var pn=k.prototype;function vn(e){return e}pn.add=Jt,pn.calendar=function(e,t){1===arguments.length&&(arguments[0]?Kt(arguments[0])?(e=arguments[0],t=void 0):function(e){for(var t=u(e)&&!l(e),n=!1,s=["sameDay","nextDay","lastDay","nextWeek","lastWeek","sameElse"],i=0;i<s.length;i+=1)n=n||m(e,s[i]);return t&&n}(arguments[0])&&(t=arguments[0],e=void 0):t=e=void 0);var n=e||Tt(),s=Gt(n,this).startOf("day"),i=f.calendarFormat(this,s)||"sameElse",r=t&&(O(t[i])?t[i].call(this,n):t[i]);return this.format(r||this.localeData().calendar(i,this,Tt(n)))},pn.clone=function(){return new k(this)},pn.diff=function(e,t,n){var s,i,r;if(!this.isValid())return NaN;if(!(s=Gt(e,this)).isValid())return NaN;switch(i=6e4*(s.utcOffset()-this.utcOffset()),t=V(t)){case"year":r=en(this,s)/12;break;case"month":r=en(this,s);break;case"quarter":r=en(this,s)/3;break;case"second":r=(this-s)/1e3;break;case"minute":r=(this-s)/6e4;break;case"hour":r=(this-s)/36e5;break;case"day":r=(this-s-i)/864e5;break;case"week":r=(this-s-i)/6048e5;break;default:r=this-s}return n?r:I(r)},pn.endOf=function(e){var t,n;if(void 0===(e=V(e))||"millisecond"===e||!this.isValid())return this;switch(n=this._isUTC?un:on,e){case"year":t=n(this.year()+1,0,1)-1;break;case"quarter":t=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":t=n(this.year(),this.month()+1,1)-1;break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":t=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":t=this._d.valueOf(),t+=36e5-an(t+(this._isUTC?0:6e4*this.utcOffset()),36e5)-1;break;case"minute":t=this._d.valueOf(),t+=6e4-an(t,6e4)-1;break;case"second":t=this._d.valueOf(),t+=1e3-an(t,1e3)-1;break}return this._d.setTime(t),f.updateOffset(this,!0),this},pn.format=function(e){e=e||(this.isUtc()?f.defaultFormatUtc:f.defaultFormat);var t=U(this,e);return this.localeData().postformat(t)},pn.from=function(e,t){return this.isValid()&&(M(e)&&e.isValid()||Tt(e).isValid())?Zt({to:this,from:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},pn.fromNow=function(e){return this.from(Tt(),e)},pn.to=function(e,t){return this.isValid()&&(M(e)&&e.isValid()||Tt(e).isValid())?Zt({from:this,to:e}).locale(this.locale()).humanize(!t):this.localeData().invalidDate()},pn.toNow=function(e){return this.to(Tt(),e)},pn.get=function(e){return O(this[e=V(e)])?this[e]():this},pn.invalidAt=function(){return y(this).overflow},pn.isAfter=function(e,t){var n=M(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=V(t)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()<this.clone().startOf(t).valueOf())},pn.isBefore=function(e,t){var n=M(e)?e:Tt(e);return!(!this.isValid()||!n.isValid())&&("millisecond"===(t=V(t)||"millisecond")?this.valueOf()<n.valueOf():this.clone().endOf(t).valueOf()<n.valueOf())},pn.isBetween=function(e,t,n,s){var i=M(e)?e:Tt(e),r=M(t)?t:Tt(t);return!!(this.isValid()&&i.isValid()&&r.isValid())&&(("("===(s=s||"()")[0]?this.isAfter(i,n):!this.isBefore(i,n))&&(")"===s[1]?this.isBefore(r,n):!this.isAfter(r,n)))},pn.isSame=function(e,t){var n,s=M(e)?e:Tt(e);return!(!this.isValid()||!s.isValid())&&("millisecond"===(t=V(t)||"millisecond")?this.valueOf()===s.valueOf():(n=s.valueOf(),this.clone().startOf(t).valueOf()<=n&&n<=this.clone().endOf(t).valueOf()))},pn.isSameOrAfter=function(e,t){return this.isSame(e,t)||this.isAfter(e,t)},pn.isSameOrBefore=function(e,t){return this.isSame(e,t)||this.isBefore(e,t)},pn.isValid=function(){return g(this)},pn.lang=nn,pn.locale=tn,pn.localeData=sn,pn.max=Pt,pn.min=Nt,pn.parsingFlags=function(){return c({},y(this))},pn.set=function(e,t){if("object"==typeof e)for(var n=function(e){var t,n=[];for(t in e)m(e,t)&&n.push({unit:t,priority:E[t]});return n.sort(function(e,t){return e.priority-t.priority}),n}(e=G(e)),s=0;s<n.length;s++)this[n[s].unit](e[n[s].unit]);else if(O(this[e=V(e)]))return this[e](t);return this},pn.startOf=function(e){var t,n;if(void 0===(e=V(e))||"millisecond"===e||!this.isValid())return this;switch(n=this._isUTC?un:on,e){case"year":t=n(this.year(),0,1);break;case"quarter":t=n(this.year(),this.month()-this.month()%3,1);break;case"month":t=n(this.year(),this.month(),1);break;case"week":t=n(this.year(),this.month(),this.date()-this.weekday());break;case"isoWeek":t=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1));break;case"day":case"date":t=n(this.year(),this.month(),this.date());break;case"hour":t=this._d.valueOf(),t-=an(t+(this._isUTC?0:6e4*this.utcOffset()),36e5);break;case"minute":t=this._d.valueOf(),t-=an(t,6e4);break;case"second":t=this._d.valueOf(),t-=an(t,1e3);break}return this._d.setTime(t),f.updateOffset(this,!0),this},pn.subtract=Qt,pn.toArray=function(){var e=this;return[e.year(),e.month(),e.date(),e.hour(),e.minute(),e.second(),e.millisecond()]},pn.toObject=function(){var e=this;return{years:e.year(),months:e.month(),date:e.date(),hours:e.hours(),minutes:e.minutes(),seconds:e.seconds(),milliseconds:e.milliseconds()}},pn.toDate=function(){return new Date(this.valueOf())},pn.toISOString=function(e){if(!this.isValid())return null;var t=!0!==e,n=t?this.clone().utc():this;return n.year()<0||9999<n.year()?U(n,t?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):O(Date.prototype.toISOString)?t?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",U(n,"Z")):U(n,t?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},pn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var e,t,n,s="moment",i="";return this.isLocal()||(s=0===this.utcOffset()?"moment.utc":"moment.parseZone",i="Z"),e="["+s+'("]',t=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",n=i+'[")]',this.format(e+t+"-MM-DD[T]HH:mm:ss.SSS"+n)},"undefined"!=typeof Symbol&&null!=Symbol.for&&(pn[Symbol.for("nodejs.util.inspect.custom")]=function(){return"Moment<"+this.format()+">"}),pn.toJSON=function(){return this.isValid()?this.toISOString():null},pn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},pn.unix=function(){return Math.floor(this.valueOf()/1e3)},pn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},pn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},pn.eraName=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].name;if(t[n].until<=e&&e<=t[n].since)return t[n].name}return""},pn.eraNarrow=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].narrow;if(t[n].until<=e&&e<=t[n].since)return t[n].narrow}return""},pn.eraAbbr=function(){for(var e,t=this.localeData().eras(),n=0,s=t.length;n<s;++n){if(e=this.clone().startOf("day").valueOf(),t[n].since<=e&&e<=t[n].until)return t[n].abbr;if(t[n].until<=e&&e<=t[n].since)return t[n].abbr}return""},pn.eraYear=function(){for(var e,t,n=this.localeData().eras(),s=0,i=n.length;s<i;++s)if(e=n[s].since<=n[s].until?1:-1,t=this.clone().startOf("day").valueOf(),n[s].since<=t&&t<=n[s].until||n[s].until<=t&&t<=n[s].since)return(this.year()-f(n[s].since).year())*e+n[s].offset;return this.year()},pn.year=Le,pn.isLeapYear=function(){return j(this.year())},pn.weekYear=function(e){return cn.call(this,e,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},pn.isoWeekYear=function(e){return cn.call(this,e,this.isoWeek(),this.isoWeekday(),1,4)},pn.quarter=pn.quarters=function(e){return null==e?Math.ceil((this.month()+1)/3):this.month(3*(e-1)+this.month()%3)},pn.month=Ue,pn.daysInMonth=function(){return xe(this.year(),this.month())},pn.week=pn.weeks=function(e){var t=this.localeData().week(this);return null==e?t:this.add(7*(e-t),"d")},pn.isoWeek=pn.isoWeeks=function(e){var t=Ae(this,1,4).week;return null==e?t:this.add(7*(e-t),"d")},pn.weeksInYear=function(){var e=this.localeData()._week;return je(this.year(),e.dow,e.doy)},pn.weeksInWeekYear=function(){var e=this.localeData()._week;return je(this.weekYear(),e.dow,e.doy)},pn.isoWeeksInYear=function(){return je(this.year(),1,4)},pn.isoWeeksInISOWeekYear=function(){return je(this.isoWeekYear(),1,4)},pn.date=fn,pn.day=pn.days=function(e){if(!this.isValid())return null!=e?this:NaN;var t,n,s=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=e?(t=e,n=this.localeData(),e="string"!=typeof t?t:isNaN(t)?"number"==typeof(t=n.weekdaysParse(t))?t:null:parseInt(t,10),this.add(e-s,"d")):s},pn.weekday=function(e){if(!this.isValid())return null!=e?this:NaN;var t=(this.day()+7-this.localeData()._week.dow)%7;return null==e?t:this.add(e-t,"d")},pn.isoWeekday=function(e){if(!this.isValid())return null!=e?this:NaN;if(null==e)return this.day()||7;var t,n,s=(t=e,n=this.localeData(),"string"==typeof t?n.weekdaysParse(t)%7||7:isNaN(t)?null:t);return this.day(this.day()%7?s:s-7)},pn.dayOfYear=function(e){var t=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==e?t:this.add(e-t,"d")},pn.hour=pn.hours=tt,pn.minute=pn.minutes=mn,pn.second=pn.seconds=gn,pn.millisecond=pn.milliseconds=yn,pn.utcOffset=function(e,t,n){var s,i=this._offset||0;if(!this.isValid())return null!=e?this:NaN;if(null==e)return this._isUTC?i:Et(this);if("string"==typeof e){if(null===(e=Vt(he,e)))return this}else Math.abs(e)<16&&!n&&(e*=60);return!this._isUTC&&t&&(s=Et(this)),this._offset=e,this._isUTC=!0,null!=s&&this.add(s,"m"),i!==e&&(!t||this._changeInProgress?Bt(this,Zt(e-i,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,f.updateOffset(this,!0),this._changeInProgress=null)),this},pn.utc=function(e){return this.utcOffset(0,e)},pn.local=function(e){return this._isUTC&&(this.utcOffset(0,e),this._isUTC=!1,e&&this.subtract(Et(this),"m")),this},pn.parseZone=function(){var e;return null!=this._tzm?this.utcOffset(this._tzm,!1,!0):"string"==typeof this._i&&(null!=(e=Vt(le,this._i))?this.utcOffset(e):this.utcOffset(0,!0)),this},pn.hasAlignedHourOffset=function(e){return!!this.isValid()&&(e=e?Tt(e).utcOffset():0,(this.utcOffset()-e)%60==0)},pn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},pn.isLocal=function(){return!!this.isValid()&&!this._isUTC},pn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},pn.isUtc=At,pn.isUTC=At,pn.zoneAbbr=function(){return this._isUTC?"UTC":""},pn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},pn.dates=n("dates accessor is deprecated. Use date instead.",fn),pn.months=n("months accessor is deprecated. Use month instead",Ue),pn.years=n("years accessor is deprecated. Use year instead",Le),pn.zone=n("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",function(e,t){return null!=e?("string"!=typeof e&&(e=-e),this.utcOffset(e,t),this):-this.utcOffset()}),pn.isDSTShifted=n("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",function(){if(!r(this._isDSTShifted))return this._isDSTShifted;var e,t={};return v(t,this),(t=bt(t))._a?(e=(t._isUTC?_:Tt)(t._a),this._isDSTShifted=this.isValid()&&0<function(e,t,n){for(var s=Math.min(e.length,t.length),i=Math.abs(e.length-t.length),r=0,a=0;a<s;a++)(n&&e[a]!==t[a]||!n&&Z(e[a])!==Z(t[a]))&&r++;return r+i}(t._a,e.toArray())):this._isDSTShifted=!1,this._isDSTShifted});var kn=x.prototype;function Mn(e,t,n,s){var i=dt(),r=_().set(s,t);return i[n](r,e)}function Dn(e,t,n){if(h(e)&&(t=e,e=void 0),e=e||"",null!=t)return Mn(e,t,n,"month");for(var s=[],i=0;i<12;i++)s[i]=Mn(e,i,n,"month");return s}function Sn(e,t,n,s){t=("boolean"==typeof e?h(t)&&(n=t,t=void 0):(t=e,e=!1,h(n=t)&&(n=t,t=void 0)),t||"");var i,r=dt(),a=e?r._week.dow:0,o=[];if(null!=n)return Mn(t,(n+a)%7,s,"day");for(i=0;i<7;i++)o[i]=Mn(t,(i+a)%7,s,"day");return o}kn.calendar=function(e,t,n){var s=this._calendar[e]||this._calendar.sameElse;return O(s)?s.call(t,n):s},kn.longDateFormat=function(e){var t=this._longDateFormat[e],n=this._longDateFormat[e.toUpperCase()];return t||!n?t:(this._longDateFormat[e]=n.match(N).map(function(e){return"MMMM"===e||"MM"===e||"DD"===e||"dddd"===e?e.slice(1):e}).join(""),this._longDateFormat[e])},kn.invalidDate=function(){return this._invalidDate},kn.ordinal=function(e){return this._ordinal.replace("%d",e)},kn.preparse=vn,kn.postformat=vn,kn.relativeTime=function(e,t,n,s){var i=this._relativeTime[n];return O(i)?i(e,t,n,s):i.replace(/%d/i,e)},kn.pastFuture=function(e,t){var n=this._relativeTime[0<e?"future":"past"];return O(n)?n(t):n.replace(/%s/i,t)},kn.set=function(e){var t,n;for(n in e)m(e,n)&&(O(t=e[n])?this[n]=t:this["_"+n]=t);this._config=e,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},kn.eras=function(e,t){for(var n,s=this._eras||dt("en")._eras,i=0,r=s.length;i<r;++i){switch(typeof s[i].since){case"string":n=f(s[i].since).startOf("day"),s[i].since=n.valueOf();break}switch(typeof s[i].until){case"undefined":s[i].until=1/0;break;case"string":n=f(s[i].until).startOf("day").valueOf(),s[i].until=n.valueOf();break}}return s},kn.erasParse=function(e,t,n){var s,i,r,a,o,u=this.eras();for(e=e.toUpperCase(),s=0,i=u.length;s<i;++s)if(r=u[s].name.toUpperCase(),a=u[s].abbr.toUpperCase(),o=u[s].narrow.toUpperCase(),n)switch(t){case"N":case"NN":case"NNN":if(a===e)return u[s];break;case"NNNN":if(r===e)return u[s];break;case"NNNNN":if(o===e)return u[s];break}else if(0<=[r,a,o].indexOf(e))return u[s]},kn.erasConvertYear=function(e,t){var n=e.since<=e.until?1:-1;return void 0===t?f(e.since).year():f(e.since).year()+(t-e.offset)*n},kn.erasAbbrRegex=function(e){return m(this,"_erasAbbrRegex")||hn.call(this),e?this._erasAbbrRegex:this._erasRegex},kn.erasNameRegex=function(e){return m(this,"_erasNameRegex")||hn.call(this),e?this._erasNameRegex:this._erasRegex},kn.erasNarrowRegex=function(e){return m(this,"_erasNarrowRegex")||hn.call(this),e?this._erasNarrowRegex:this._erasRegex},kn.months=function(e,t){return e?o(this._months)?this._months[e.month()]:this._months[(this._months.isFormat||Pe).test(t)?"format":"standalone"][e.month()]:o(this._months)?this._months:this._months.standalone},kn.monthsShort=function(e,t){return e?o(this._monthsShort)?this._monthsShort[e.month()]:this._monthsShort[Pe.test(t)?"format":"standalone"][e.month()]:o(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},kn.monthsParse=function(e,t,n){var s,i,r;if(this._monthsParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],s=0;s<12;++s)r=_([2e3,s]),this._shortMonthsParse[s]=this.monthsShort(r,"").toLocaleLowerCase(),this._longMonthsParse[s]=this.months(r,"").toLocaleLowerCase();return n?"MMM"===t?-1!==(i=we.call(this._shortMonthsParse,a))?i:null:-1!==(i=we.call(this._longMonthsParse,a))?i:null:"MMM"===t?-1!==(i=we.call(this._shortMonthsParse,a))||-1!==(i=we.call(this._longMonthsParse,a))?i:null:-1!==(i=we.call(this._longMonthsParse,a))||-1!==(i=we.call(this._shortMonthsParse,a))?i:null}.call(this,e,t,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),s=0;s<12;s++){if(i=_([2e3,s]),n&&!this._longMonthsParse[s]&&(this._longMonthsParse[s]=new RegExp("^"+this.months(i,"").replace(".","")+"$","i"),this._shortMonthsParse[s]=new RegExp("^"+this.monthsShort(i,"").replace(".","")+"$","i")),n||this._monthsParse[s]||(r="^"+this.months(i,"")+"|^"+this.monthsShort(i,""),this._monthsParse[s]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===t&&this._longMonthsParse[s].test(e))return s;if(n&&"MMM"===t&&this._shortMonthsParse[s].test(e))return s;if(!n&&this._monthsParse[s].test(e))return s}},kn.monthsRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||He.call(this),e?this._monthsStrictRegex:this._monthsRegex):(m(this,"_monthsRegex")||(this._monthsRegex=We),this._monthsStrictRegex&&e?this._monthsStrictRegex:this._monthsRegex)},kn.monthsShortRegex=function(e){return this._monthsParseExact?(m(this,"_monthsRegex")||He.call(this),e?this._monthsShortStrictRegex:this._monthsShortRegex):(m(this,"_monthsShortRegex")||(this._monthsShortRegex=Re),this._monthsShortStrictRegex&&e?this._monthsShortStrictRegex:this._monthsShortRegex)},kn.week=function(e){return Ae(e,this._week.dow,this._week.doy).week},kn.firstDayOfYear=function(){return this._week.doy},kn.firstDayOfWeek=function(){return this._week.dow},kn.weekdays=function(e,t){var n=o(this._weekdays)?this._weekdays:this._weekdays[e&&!0!==e&&this._weekdays.isFormat.test(t)?"format":"standalone"];return!0===e?Ie(n,this._week.dow):e?n[e.day()]:n},kn.weekdaysMin=function(e){return!0===e?Ie(this._weekdaysMin,this._week.dow):e?this._weekdaysMin[e.day()]:this._weekdaysMin},kn.weekdaysShort=function(e){return!0===e?Ie(this._weekdaysShort,this._week.dow):e?this._weekdaysShort[e.day()]:this._weekdaysShort},kn.weekdaysParse=function(e,t,n){var s,i,r;if(this._weekdaysParseExact)return function(e,t,n){var s,i,r,a=e.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],s=0;s<7;++s)r=_([2e3,1]).day(s),this._minWeekdaysParse[s]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[s]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[s]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===t?-1!==(i=we.call(this._weekdaysParse,a))?i:null:"ddd"===t?-1!==(i=we.call(this._shortWeekdaysParse,a))?i:null:-1!==(i=we.call(this._minWeekdaysParse,a))?i:null:"dddd"===t?-1!==(i=we.call(this._weekdaysParse,a))||-1!==(i=we.call(this._shortWeekdaysParse,a))||-1!==(i=we.call(this._minWeekdaysParse,a))?i:null:"ddd"===t?-1!==(i=we.call(this._shortWeekdaysParse,a))||-1!==(i=we.call(this._weekdaysParse,a))||-1!==(i=we.call(this._minWeekdaysParse,a))?i:null:-1!==(i=we.call(this._minWeekdaysParse,a))||-1!==(i=we.call(this._weekdaysParse,a))||-1!==(i=we.call(this._shortWeekdaysParse,a))?i:null}.call(this,e,t,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),s=0;s<7;s++){if(i=_([2e3,1]).day(s),n&&!this._fullWeekdaysParse[s]&&(this._fullWeekdaysParse[s]=new RegExp("^"+this.weekdays(i,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[s]=new RegExp("^"+this.weekdaysShort(i,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[s]=new RegExp("^"+this.weekdaysMin(i,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[s]||(r="^"+this.weekdays(i,"")+"|^"+this.weekdaysShort(i,"")+"|^"+this.weekdaysMin(i,""),this._weekdaysParse[s]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===t&&this._fullWeekdaysParse[s].test(e))return s;if(n&&"ddd"===t&&this._shortWeekdaysParse[s].test(e))return s;if(n&&"dd"===t&&this._minWeekdaysParse[s].test(e))return s;if(!n&&this._weekdaysParse[s].test(e))return s}},kn.weekdaysRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysStrictRegex:this._weekdaysRegex):(m(this,"_weekdaysRegex")||(this._weekdaysRegex=qe),this._weekdaysStrictRegex&&e?this._weekdaysStrictRegex:this._weekdaysRegex)},kn.weekdaysShortRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(m(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=Be),this._weekdaysShortStrictRegex&&e?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},kn.weekdaysMinRegex=function(e){return this._weekdaysParseExact?(m(this,"_weekdaysRegex")||Qe.call(this),e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(m(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=Je),this._weekdaysMinStrictRegex&&e?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},kn.isPM=function(e){return"p"===(e+"").toLowerCase().charAt(0)},kn.meridiem=function(e,t,n){return 11<e?n?"pm":"PM":n?"am":"AM"},lt("en",{eras:[{since:"0001-01-01",until:1/0,offset:1,name:"Anno Domini",narrow:"AD",abbr:"AD"},{since:"0000-12-31",until:-1/0,offset:1,name:"Before Christ",narrow:"BC",abbr:"BC"}],dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(e){var t=e%10;return e+(1===Z(e%100/10)?"th":1==t?"st":2==t?"nd":3==t?"rd":"th")}}),f.lang=n("moment.lang is deprecated. Use moment.locale instead.",lt),f.langData=n("moment.langData is deprecated. Use moment.localeData instead.",dt);var Yn=Math.abs;function On(e,t,n,s){var i=Zt(t,n);return e._milliseconds+=s*i._milliseconds,e._days+=s*i._days,e._months+=s*i._months,e._bubble()}function bn(e){return e<0?Math.floor(e):Math.ceil(e)}function xn(e){return 4800*e/146097}function Tn(e){return 146097*e/4800}function Nn(e){return function(){return this.as(e)}}var Pn=Nn("ms"),Rn=Nn("s"),Wn=Nn("m"),Cn=Nn("h"),Un=Nn("d"),Hn=Nn("w"),Fn=Nn("M"),Ln=Nn("Q"),Vn=Nn("y");function Gn(e){return function(){return this.isValid()?this._data[e]:NaN}}var En=Gn("milliseconds"),An=Gn("seconds"),jn=Gn("minutes"),In=Gn("hours"),Zn=Gn("days"),zn=Gn("months"),$n=Gn("years");var qn=Math.round,Bn={ss:44,s:45,m:45,h:22,d:26,w:null,M:11};function Jn(e,t,n,s){var i=Zt(e).abs(),r=qn(i.as("s")),a=qn(i.as("m")),o=qn(i.as("h")),u=qn(i.as("d")),l=qn(i.as("M")),h=qn(i.as("w")),d=qn(i.as("y")),c=(r<=n.ss?["s",r]:r<n.s&&["ss",r])||a<=1&&["m"]||a<n.m&&["mm",a]||o<=1&&["h"]||o<n.h&&["hh",o]||u<=1&&["d"]||u<n.d&&["dd",u];return null!=n.w&&(c=c||h<=1&&["w"]||h<n.w&&["ww",h]),(c=c||l<=1&&["M"]||l<n.M&&["MM",l]||d<=1&&["y"]||["yy",d])[2]=t,c[3]=0<+e,c[4]=s,function(e,t,n,s,i){return i.relativeTime(t||1,!!n,e,s)}.apply(null,c)}var Qn=Math.abs;function Xn(e){return(0<e)-(e<0)||+e}function Kn(){if(!this.isValid())return this.localeData().invalidDate();var e,t,n,s,i,r,a,o,u=Qn(this._milliseconds)/1e3,l=Qn(this._days),h=Qn(this._months),d=this.asSeconds();return d?(e=I(u/60),t=I(e/60),u%=60,e%=60,n=I(h/12),h%=12,s=u?u.toFixed(3).replace(/\.?0+$/,""):"",i=d<0?"-":"",r=Xn(this._months)!==Xn(d)?"-":"",a=Xn(this._days)!==Xn(d)?"-":"",o=Xn(this._milliseconds)!==Xn(d)?"-":"",i+"P"+(n?r+n+"Y":"")+(h?r+h+"M":"")+(l?a+l+"D":"")+(t||e||u?"T":"")+(t?o+t+"H":"")+(e?o+e+"M":"")+(u?o+s+"S":"")):"P0D"}var es=Ct.prototype;return es.isValid=function(){return this._isValid},es.abs=function(){var e=this._data;return this._milliseconds=Yn(this._milliseconds),this._days=Yn(this._days),this._months=Yn(this._months),e.milliseconds=Yn(e.milliseconds),e.seconds=Yn(e.seconds),e.minutes=Yn(e.minutes),e.hours=Yn(e.hours),e.months=Yn(e.months),e.years=Yn(e.years),this},es.add=function(e,t){return On(this,e,t,1)},es.subtract=function(e,t){return On(this,e,t,-1)},es.as=function(e){if(!this.isValid())return NaN;var t,n,s=this._milliseconds;if("month"===(e=V(e))||"quarter"===e||"year"===e)switch(t=this._days+s/864e5,n=this._months+xn(t),e){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(t=this._days+Math.round(Tn(this._months)),e){case"week":return t/7+s/6048e5;case"day":return t+s/864e5;case"hour":return 24*t+s/36e5;case"minute":return 1440*t+s/6e4;case"second":return 86400*t+s/1e3;case"millisecond":return Math.floor(864e5*t)+s;default:throw new Error("Unknown unit "+e)}},es.asMilliseconds=Pn,es.asSeconds=Rn,es.asMinutes=Wn,es.asHours=Cn,es.asDays=Un,es.asWeeks=Hn,es.asMonths=Fn,es.asQuarters=Ln,es.asYears=Vn,es.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*Z(this._months/12):NaN},es._bubble=function(){var e,t,n,s,i,r=this._milliseconds,a=this._days,o=this._months,u=this._data;return 0<=r&&0<=a&&0<=o||r<=0&&a<=0&&o<=0||(r+=864e5*bn(Tn(o)+a),o=a=0),u.milliseconds=r%1e3,e=I(r/1e3),u.seconds=e%60,t=I(e/60),u.minutes=t%60,n=I(t/60),u.hours=n%24,a+=I(n/24),o+=i=I(xn(a)),a-=bn(Tn(i)),s=I(o/12),o%=12,u.days=a,u.months=o,u.years=s,this},es.clone=function(){return Zt(this)},es.get=function(e){return e=V(e),this.isValid()?this[e+"s"]():NaN},es.milliseconds=En,es.seconds=An,es.minutes=jn,es.hours=In,es.days=Zn,es.weeks=function(){return I(this.days()/7)},es.months=zn,es.years=$n,es.humanize=function(e,t){if(!this.isValid())return this.localeData().invalidDate();var n,s,i=!1,r=Bn;return"object"==typeof e&&(t=e,e=!1),"boolean"==typeof e&&(i=e),"object"==typeof t&&(r=Object.assign({},Bn,t),null!=t.s&&null==t.ss&&(r.ss=t.s-1)),n=this.localeData(),s=Jn(this,!i,r,n),i&&(s=n.pastFuture(+this,s)),n.postformat(s)},es.toISOString=Kn,es.toString=Kn,es.toJSON=Kn,es.locale=tn,es.localeData=sn,es.toIsoString=n("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Kn),es.lang=nn,C("X",0,0,"unix"),C("x",0,0,"valueOf"),ce("x",ue),ce("X",/[+-]?\d+(\.\d{1,3})?/),ye("X",function(e,t,n){n._d=new Date(1e3*parseFloat(e))}),ye("x",function(e,t,n){n._d=new Date(Z(e))}),f.version="2.29.1",e=Tt,f.fn=pn,f.min=function(){return Rt("isBefore",[].slice.call(arguments,0))},f.max=function(){return Rt("isAfter",[].slice.call(arguments,0))},f.now=function(){return Date.now?Date.now():+new Date},f.utc=_,f.unix=function(e){return Tt(1e3*e)},f.months=function(e,t){return Dn(e,t,"months")},f.isDate=a,f.locale=lt,f.invalid=w,f.duration=Zt,f.isMoment=M,f.weekdays=function(e,t,n){return Sn(e,t,n,"weekdays")},f.parseZone=function(){return Tt.apply(null,arguments).parseZone()},f.localeData=dt,f.isDuration=Ut,f.monthsShort=function(e,t){return Dn(e,t,"monthsShort")},f.weekdaysMin=function(e,t,n){return Sn(e,t,n,"weekdaysMin")},f.defineLocale=ht,f.updateLocale=function(e,t){var n,s,i;return null!=t?(i=st,null!=it[e]&&null!=it[e].parentLocale?it[e].set(b(it[e]._config,t)):(null!=(s=ut(e))&&(i=s._config),t=b(i,t),null==s&&(t.abbr=e),(n=new x(t)).parentLocale=it[e],it[e]=n),lt(e)):null!=it[e]&&(null!=it[e].parentLocale?(it[e]=it[e].parentLocale,e===lt()&&lt(e)):null!=it[e]&&delete it[e]),it[e]},f.locales=function(){return s(it)},f.weekdaysShort=function(e,t,n){return Sn(e,t,n,"weekdaysShort")},f.normalizeUnits=V,f.relativeTimeRounding=function(e){return void 0===e?qn:"function"==typeof e&&(qn=e,!0)},f.relativeTimeThreshold=function(e,t){return void 0!==Bn[e]&&(void 0===t?Bn[e]:(Bn[e]=t,"s"===e&&(Bn.ss=t-1),!0))},f.calendarFormat=function(e,t){var n=e.diff(t,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},f.prototype=pn,f.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},f});
 
includes/modules/flash-sale/class.flash-sale.php CHANGED
@@ -15,10 +15,6 @@ class Woolentor_Flash_Sale{
15
  return self::$_instance;
16
  }
17
 
18
- public $options = array();
19
-
20
- public $the_product = '';
21
-
22
  /**
23
  * Constructor
24
  */
@@ -27,11 +23,26 @@ class Woolentor_Flash_Sale{
27
  // Enqueue scripts
28
  add_action('wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
29
 
30
- // Change display price for loop product and product details
31
- add_filter( 'woocommerce_get_price_html', [ $this, 'alter_display_price' ], 10, 2 );
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
- // Change price in cart
34
- add_action( 'woocommerce_before_calculate_totals', [ $this, 'alter_price_in_cart' ], 9999 );
 
 
 
35
 
36
  // Countdown position
37
  $position = woolentor_get_option( 'countdown_position', 'woolentor_flash_sale_settings', 'woocommerce_before_add_to_cart_form' );
@@ -44,22 +55,153 @@ class Woolentor_Flash_Sale{
44
  */
45
  public function enqueue_scripts(){
46
 
47
- if( is_product() ){
48
 
49
- wp_enqueue_script( 'moment', plugin_dir_url( __FILE__ ) . '/assets/js/moment.min.js', array('jquery'), '2.29.1' );
50
- wp_enqueue_script( 'moment-timezone-with-data', plugin_dir_url( __FILE__ ) . '/assets/js/moment-timezone-with-data.js', array('jquery','moment'), '0.5.34' );
51
 
52
- wp_enqueue_script( 'woolentor-flash-sale-module', plugin_dir_url( __FILE__ ) . '/assets/js/flash-sale.js', array('countdown-min'), WOOLENTOR_VERSION );
53
- wp_enqueue_style( 'woolentor-flash-sale-module', plugin_dir_url( __FILE__ ) . '/assets/css/flash-sale.css', '', WOOLENTOR_VERSION, 'all' );
 
54
 
55
- wp_localize_script( 'woolentor-flash-sale-module', 'woolentor_flash_sale_module', array(
56
- 'timeZone' => wp_timezone_string()
57
- ) );
 
 
 
 
 
 
58
 
 
 
 
 
 
 
 
59
  }
60
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  /**
64
  * Validate user previllage
65
  */
@@ -88,15 +230,31 @@ class Woolentor_Flash_Sale{
88
  return $validity;
89
  }
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  /**
92
  * Validate offer date & time
93
  */
94
  public static function datetime_validity( $deal ){
95
  $validity = false;
96
- $current_time = current_time('timestamp');
97
- $deal_time_began = strtotime( $deal['start_date'] );
98
- $deal_time_end = strtotime( $deal["end_date"] );
99
- $deal_time_end = $deal_time_end + 86399; // 23 hours + 59 minutes as the end date
100
 
101
  // if any one of the time is defined
102
  if( $deal_time_began || $deal_time_end ){
@@ -163,7 +321,8 @@ class Woolentor_Flash_Sale{
163
  /**
164
  * Loop through each deals and get the first matched deal for the given product
165
  */
166
- public static function get_deal( $product ){
 
167
  $flash_sale_settings = get_option('woolentor_flash_sale_settings');
168
 
169
  if( isset( $flash_sale_settings['deals'] ) && is_array( $flash_sale_settings['deals'] ) ){
@@ -188,100 +347,74 @@ class Woolentor_Flash_Sale{
188
  * One a deal found for the given product
189
  * Calculate the the price based on the discount/deal matched with the given product
190
  */
191
- public function get_calculated_price( $product, $deal ){
192
- $orig_price = (float) $product->get_regular_price();
193
-
194
- $discount_type = !empty($deal['discount_type']) ? $deal['discount_type'] : 'fixed_discount';
195
- $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
196
-
197
- $override_sale_price = woolentor_get_option('override_sale_price', 'woolentor_flash_sale_settings');
198
- if( $override_sale_price && $product->is_on_sale() ){
199
- $orig_price = wc_get_price_to_display( $product );
200
- }
201
-
202
- // prepare discounted price
203
- if( $discount_type == 'fixed_discount' ){
204
-
205
- return $orig_price - (float) $discount_value;
 
 
 
 
 
 
 
 
 
 
 
 
 
206
 
207
- } elseif( $discount_type == 'percentage_discount' ){
208
 
209
- return $orig_price * (1 - (float) $discount_value / 100);
210
 
211
- } elseif( $discount_type == 'fixed_price' ){
212
 
213
- return (float) $discount_value;
214
 
215
- }
216
  }
217
 
218
  /**
219
- * Alter the display price of the given product by the new discounted price
220
- * Altering product price does not apply when a customer add to cart the product
221
- * This process just for showing discounted price to the customers
222
  */
223
- public function alter_display_price( $price_html, $product ){
224
- // Only on frontend includeing elementor editor
225
- if( is_admin() && !\Elementor\Plugin::$instance->editor->is_edit_mode() ) {
226
- return $price_html;
227
- }
228
-
229
- // Only if price is not null
230
- if( '' === $product->get_price() ){
231
- return $price_html;
232
- }
233
 
234
- if( $product->get_type() != 'variation' ){
235
- $this->the_product = $product;
236
- }
237
 
238
- $deal = self::get_deal( $this->the_product );
239
- $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
 
 
240
 
241
- if( $deal && self::datetime_validity($deal) && $discount_value ){
 
242
 
243
- if( $product->get_type() == 'simple' || $product->get_type() == 'external' ){
244
 
245
- $calculated_price = $this->get_calculated_price( $product, $deal );
246
- $price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $product->get_regular_price() ) ), $calculated_price ) . $product->get_price_suffix();
247
- }
248
 
249
- }
250
 
251
- return $price_html;
252
- }
253
-
254
- /**
255
- * Loop throguh each products in cart
256
- * get the discounted price by the given product and
257
- * apply the new price customers should pay
258
- */
259
- public function alter_price_in_cart( $cart ){
260
- if( is_admin() && ! defined( 'DOING_AJAX' ) ){
261
- return;
262
- }
263
-
264
- if( did_action( 'woocommerce_before_calculate_totals' ) >= 2 ){
265
- return;
266
- }
267
-
268
- // Loop through cart items & apply discount
269
- foreach( $cart->get_cart() as $cart_item_key => $cart_item ){
270
- $product = $cart_item['data'];
271
- $price = $product->get_price();
272
- $deal = $this->get_deal( $product );
273
- $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
274
-
275
- if( $deal && $discount_value ){
276
-
277
- if($product->get_type() == 'simple' || $product->get_type() == 'external' ){
278
- $price = $this->get_calculated_price( $product, $deal );
279
- }
280
 
281
- }
282
 
283
- $cart_item['data']->set_price( $price );
284
- }
285
  }
286
 
287
  /**
@@ -293,19 +426,23 @@ class Woolentor_Flash_Sale{
293
  }
294
 
295
  global $product;
 
 
 
 
 
 
296
  $flash_sale_settings = get_option('woolentor_flash_sale_settings');
 
 
297
  $countdown_heading = woolentor_get_option('countdown_timer_title', 'woolentor_flash_sale_settings', esc_html__('Hurry Up! Offer ends in', 'woolentor'));
298
- $deal = self::get_deal($product);
299
  $countdown_status = woolentor_get_option('enable_countdown_on_product_details_page', 'woolentor_flash_sale_settings', 'on');
300
- $deal_time_end = !empty($deal['end_date']) ? date('Y-m-d', strtotime($deal['end_date']) + 86400) : ''; // formate datetime for moment timezone like this 2021-12-19 19:20, otherwise the moment timezone produce a deperecated notice
301
 
302
- // Right now support only simple product
303
- if( $product->get_type() != 'simple' ){
304
- return;
305
- }
306
 
307
  if( $deal && $deal_time_end && $countdown_status == 'on' ):
308
-
309
  $custom_labels = apply_filters('woolentor_countdown_custom_labels', array(
310
  'daytxt' => esc_html__('Days', 'woolentor'),
311
  'hourtxt' => esc_html__('Hours', 'woolentor'),
@@ -313,13 +450,65 @@ class Woolentor_Flash_Sale{
313
  'secondstxt' => esc_html__('Sec', 'woolentor')
314
  ));
315
  ?>
316
- <div class="ht-saleflash-countdown-wrap ht-align--left">
317
- <span class="ht-saleflash-countdown-title"><?php echo wp_kses_post( $countdown_heading ) ?></span>
318
- <div class="ht-product-countdown" data-countdown="<?php echo esc_attr( $deal_time_end ) ?>" data-customlavel='<?php echo json_encode( $custom_labels ) ?>'></div>
 
 
 
 
 
319
  </div>
 
320
  <?php
321
  endif;
322
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
  }
324
 
325
  Woolentor_Flash_Sale::get_instance();
15
  return self::$_instance;
16
  }
17
 
 
 
 
 
18
  /**
19
  * Constructor
20
  */
23
  // Enqueue scripts
24
  add_action('wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
25
 
26
+ // Alter display price
27
+ add_filter( 'woocommerce_get_price_html', [ $this, 'flash_sale_display_price' ], 10, 2 );
28
+
29
+ // Change simple product price only on cart & checkout page
30
+ add_filter( 'woocommerce_product_get_price', [ $this, 'flash_sale_price_simple' ], 10, 2 );
31
+ add_filter( 'woocommerce_product_get_sale_price', [ $this, 'flash_sale_price_simple' ], 10, 2 );
32
+
33
+ // Change price range of the product
34
+ add_action( 'woocommerce_product_variation_get_price', [ $this, 'flash_sale_price_variable' ], 10, 2 );
35
+ add_filter( 'woocommerce_product_variation_get_sale_price', [ $this, 'flash_sale_price_variable' ], 10, 2 );
36
+
37
+ // Change each variation price
38
+ add_filter( 'woocommerce_variation_prices_price', [ $this, 'flash_sale_price_variable' ], 10, 2 );
39
+ add_filter( 'woocommerce_variation_prices_sale_price', [ $this, 'flash_sale_price_variable' ], 10, 2 );
40
 
41
+ // Handling price caching, for better performance
42
+ add_filter( 'woocommerce_get_variation_prices_hash', array( $this, 'variable_product_prices_hash'), 10, 3 );
43
+
44
+ // Add "Flash Sale" lable with products on cart table
45
+ add_filter( 'woocommerce_get_item_data', [ $this, 'filter_get_item_data' ], 99, 2 );
46
 
47
  // Countdown position
48
  $position = woolentor_get_option( 'countdown_position', 'woolentor_flash_sale_settings', 'woocommerce_before_add_to_cart_form' );
55
  */
56
  public function enqueue_scripts(){
57
 
58
+ if( is_product() || is_cart() || is_checkout() ){
59
 
60
+ wp_enqueue_script( 'woolentor-flash-sale-module');
61
+ wp_enqueue_style( 'woolentor-flash-sale-module' );
62
 
63
+ }
64
+
65
+ }
66
 
67
+ /**
68
+ * Chagne simple product price on cart & checkout page
69
+ * For displaying the price and also the price calculation
70
+ */
71
+ public function flash_sale_price_simple( $price, $product ){
72
+ $product_id = $product->get_id();
73
+
74
+ $deal = self::get_deal( $product_id );
75
+ $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
76
 
77
+ if( $deal && self::datetime_validity($deal) && $discount_value ){
78
+ $regular_price = get_post_meta( $product_id, '_regular_price', true );
79
+ $sale_price = get_post_meta( $product_id, '_sale_price', true );
80
+
81
+ if ( $regular_price && ( is_cart() || is_checkout() ) ) {
82
+ $price = $this->get_calculated_price( $product_id, $deal );
83
+ }
84
  }
85
+
86
+ return $price;
87
+ }
88
+
89
+
90
+ /**
91
+ * Manage variable product price
92
+ */
93
+ public function flash_sale_price_variable( $price, $product ){
94
+
95
+ $product_id = $product->get_id();
96
+ $parent_id = $product->get_parent_id() == 0 ? $product_id : $product->get_parent_id();
97
+
98
+ $parent_product = wc_get_product( $parent_id );
99
+
100
+ $deal = self::get_deal( $parent_product );
101
+ $discount_type = !empty($deal['discount_type']) ? $deal['discount_type'] : 'percentage';
102
+ $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
103
+
104
+ if( $deal && self::datetime_validity($deal) && $discount_value ){
105
+ $price = $this->get_calculated_price_variable($product, $price, $deal);
106
+ }
107
+
108
+ return $price;
109
  }
110
 
111
+ /**
112
+ * Chagne display price on product loop & product details page
113
+ */
114
+ public function flash_sale_display_price( $price_html, $product ){
115
+ if ( ! $product || class_exists( 'WC_Bundles' ) ) return $price_html;
116
+
117
+ $product_id = $product->get_id();
118
+ $parent_id = $product->get_parent_id() == 0 ? $product_id : $product->get_parent_id();
119
+ $parent_product = wc_get_product($parent_id);
120
+
121
+ if( $product->get_type() == 'variation' ){
122
+ return $price_html;
123
+ }
124
+
125
+ $deal = self::get_deal( $parent_product );
126
+ $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
127
+ $flash_sale_price = '';
128
+
129
+ if( $deal && self::datetime_validity($deal) && $discount_value ){
130
+ if( !$product->is_type('variable') && !$product->is_type('grouped') ){
131
+
132
+ $flash_sale_price = wc_price( $this->get_calculated_price( $product_id, $deal ) );
133
+
134
+ } elseif( $product->is_type('variable') ){
135
+ $flash_sale_price = $price_html;
136
+ $price_min = wc_get_price_to_display( $product, [ 'price' => $product->get_variation_regular_price( 'min' ) ] );
137
+ $price_max = wc_get_price_to_display( $product, [ 'price' => $product->get_variation_regular_price( 'max' ) ] );
138
+
139
+ if($product->get_variation_regular_price( 'min' ) == $product->get_variation_regular_price( 'max' ) ){
140
+ $price_html = wc_price( $price_max );
141
+ } else {
142
+ $price_html = wc_format_price_range( $price_min, $price_max );
143
+ }
144
+
145
+ } elseif( $product->is_type('grouped') ) {
146
+ $grouped_o_prices = $this->get_grouped_prices($product);
147
+ $min_price = $grouped_o_prices['min'];
148
+ $max_price = $grouped_o_prices['max'];
149
+
150
+ if ( '' !== $min_price ) {
151
+ if ( $min_price !== $max_price ) {
152
+ $price = wc_format_price_range( $this->get_calculated_price('', $deal, $min_price), $this->get_calculated_price('', $deal, $max_price) );
153
+ } else {
154
+ $price = wc_price( $this->get_calculated_price($min_price) );
155
+ }
156
+
157
+ $is_free = 0 === $min_price && 0 === $max_price;
158
+
159
+ if ( $is_free ) {
160
+ $flash_sale_price = apply_filters( 'woocommerce_grouped_free_price_html', __( 'Free!', 'woolentor' ), $product );
161
+ } else {
162
+ $flash_sale_price = $price . $product->get_price_suffix();
163
+ }
164
+ }
165
+ }
166
+
167
+ $manage_price_label = woolentor_get_option('manage_price_label', 'woolentor_flash_sale_settings');
168
+ $manage_price_label = str_replace( '{original_price}', '<span class="woolentor-flash-sale-original-price">'.$price_html.'</span><br/>', $manage_price_label );
169
+ $manage_price_label = str_replace( '{flash_sale_price}', '<span class="woolentor-flash-sale-price">'.$flash_sale_price.'</span>', $manage_price_label );
170
+
171
+ if( is_admin() ){
172
+ return $flash_sale_price;
173
+ }else if( empty( $manage_price_label ) ){
174
+ return $flash_sale_price;
175
+ } else {
176
+ return $manage_price_label;
177
+ }
178
+
179
+ } else{
180
+ return $price_html;
181
+ }
182
+ }
183
+
184
+ /**
185
+ * Add "Flash Sale" lable with products on cart table
186
+ */
187
+ public function filter_get_item_data( $item_data, $cart_item ){
188
+ $product_id = $cart_item['product_id'];
189
+
190
+ $deal = self::get_deal( $product_id );
191
+ $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
192
+
193
+ if( $deal && self::datetime_validity($deal) && $discount_value ){
194
+ $item_data[] = array(
195
+ 'name' => 'woolentor_cart_flash_sale_label',
196
+ 'display' => '<span class="woolentor-flashsale-label">'. esc_html__('Flash Sale!', 'woolentor') .'</span>',
197
+ 'value' => '',
198
+ );
199
+ }
200
+
201
+ return $item_data;
202
+ }
203
+
204
+
205
  /**
206
  * Validate user previllage
207
  */
230
  return $validity;
231
  }
232
 
233
+ /**
234
+ * Return remaining time (seconds) to end the deal
235
+ */
236
+ public static function get_remaining_time( $deal ){
237
+ $flash_sale_end_date = !empty($deal["end_date"]) ? $deal["end_date"] : ''; // 2022-01-18
238
+ $flash_sale_end_time = '23:59:59'; // 13:00:00
239
+ $gmt_offdet = get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
240
+ $time_str = strtotime( $flash_sale_end_date );
241
+ $time_total = $gmt_offdet + $time_str;
242
+ $current_date = strtotime( date_i18n( 'Y-m-d H:i:s', current_time( 'timestamp' ) ) );
243
+
244
+ $remaining_time = ( strtotime( $flash_sale_end_time ) - strtotime( 'TODAY' ) + strtotime( $flash_sale_end_date ) ) - current_time( 'timestamp' );
245
+
246
+ return $remaining_time;
247
+ }
248
+
249
  /**
250
  * Validate offer date & time
251
  */
252
  public static function datetime_validity( $deal ){
253
  $validity = false;
254
+ $current_time = strtotime( date_i18n( 'Y-m-d H:i:s', current_time( 'timestamp' ) ) );
255
+ $deal_time_began = !empty($deal['start_date']) ? strtotime( $deal['start_date'] ) : '';
256
+ $deal_time_end = !empty($deal["end_date"]) ? strtotime( $deal["end_date"] ) : '';
257
+ $deal_time_end = (int) $deal_time_end + 86399; // 23 hours + 59 minutes as the end date
258
 
259
  // if any one of the time is defined
260
  if( $deal_time_began || $deal_time_end ){
321
  /**
322
  * Loop through each deals and get the first matched deal for the given product
323
  */
324
+ public static function get_deal( $product_id ){
325
+ $product = wc_get_product($product_id);
326
  $flash_sale_settings = get_option('woolentor_flash_sale_settings');
327
 
328
  if( isset( $flash_sale_settings['deals'] ) && is_array( $flash_sale_settings['deals'] ) ){
347
  * One a deal found for the given product
348
  * Calculate the the price based on the discount/deal matched with the given product
349
  */
350
+ public static function get_calculated_price( $product_id = '', $deal = [], $price = '' ){
351
+ $product = wc_get_product($product_id);
352
+
353
+ $regular_price = get_post_meta( $product_id, '_regular_price', true );
354
+ $sale_price = get_post_meta( $product_id, '_sale_price', true );
355
+
356
+ $discount_type = !empty($deal['discount_type']) ? $deal['discount_type'] : 'fixed_discount';
357
+ $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
358
+
359
+ $base_price = (float) $regular_price;
360
+ $override_sale_price = woolentor_get_option('override_sale_price', 'woolentor_flash_sale_settings');
361
+ if( $override_sale_price && $sale_price ){
362
+ $base_price = (float) $sale_price;
363
+ }
364
+
365
+ if($price){
366
+ $base_price = (float) $price;
367
+ }
368
+
369
+ // prepare discounted price
370
+ if( $discount_type == 'fixed_discount' ){
371
+
372
+ $discount_value = (float) $discount_value;
373
+ if( $base_price > $discount_value ){
374
+ return $base_price - $discount_value;
375
+ }else{
376
+ return 0;
377
+ }
378
 
379
+ } elseif( $discount_type == 'percentage_discount' ){
380
 
381
+ return $base_price * (1 - (float) $discount_value / 100);
382
 
383
+ } elseif( $discount_type == 'fixed_price' ){
384
 
385
+ return (float) $discount_value;
386
 
387
+ }
388
  }
389
 
390
  /**
391
+ * Calculate the discounted price for variable product
 
 
392
  */
393
+ public function get_calculated_price_variable( $product, $price, $deal ){
394
+ $base_price = (float) $product->get_regular_price();
 
 
 
 
 
 
 
 
395
 
396
+ $discount_type = !empty($deal['discount_type']) ? $deal['discount_type'] : 'fixed_discount';
397
+ $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
 
398
 
399
+ $override_sale_price = woolentor_get_option('override_sale_price', 'woolentor_flash_sale_settings');
400
+ if( $override_sale_price ){
401
+ $base_price = (float) $price;
402
+ }
403
 
404
+ // prepare discounted price
405
+ if( $discount_type == 'fixed_discount' ){
406
 
407
+ return $base_price - (float) $discount_value;
408
 
409
+ } elseif( $discount_type == 'percentage_discount' ){
 
 
410
 
411
+ return $base_price * (1 - (float) $discount_value / 100);
412
 
413
+ } elseif( $discount_type == 'fixed_price' ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
414
 
415
+ return (float) $discount_value;
416
 
417
+ }
 
418
  }
419
 
420
  /**
426
  }
427
 
428
  global $product;
429
+
430
+ $countdown_styles = array(
431
+ '1' => 'default',
432
+ '2' => 'flip',
433
+ );
434
+
435
  $flash_sale_settings = get_option('woolentor_flash_sale_settings');
436
+ $countdown_style = woolentor_get_option('countdown_style', 'woolentor_flash_sale_settings', '2');
437
+ $countdown_style = $countdown_styles[$countdown_style];
438
  $countdown_heading = woolentor_get_option('countdown_timer_title', 'woolentor_flash_sale_settings', esc_html__('Hurry Up! Offer ends in', 'woolentor'));
439
+ $deal = self::get_deal($product->get_id());
440
  $countdown_status = woolentor_get_option('enable_countdown_on_product_details_page', 'woolentor_flash_sale_settings', 'on');
441
+ $deal_time_end = !empty($deal['end_date']) ? $deal['end_date'] : '';
442
 
443
+ $remaining_time = self::get_remaining_time($deal);
 
 
 
444
 
445
  if( $deal && $deal_time_end && $countdown_status == 'on' ):
 
446
  $custom_labels = apply_filters('woolentor_countdown_custom_labels', array(
447
  'daytxt' => esc_html__('Days', 'woolentor'),
448
  'hourtxt' => esc_html__('Hours', 'woolentor'),
450
  'secondstxt' => esc_html__('Sec', 'woolentor')
451
  ));
452
  ?>
453
+
454
+ <div class="woolentor-flash-product-countdown">
455
+
456
+ <?php if($countdown_heading): ?>
457
+ <p class="woolentor-flash-product-offer-timer-text"><?php echo wp_kses_post( $countdown_heading ) ?></p>
458
+ <?php endif; ?>
459
+
460
+ <div class="woolentor-countdown woolentor-countdown-<?php echo esc_attr($countdown_style); ?>" data-countdown="<?php echo esc_attr( $remaining_time ) ?>" data-customlavel='<?php echo wp_json_encode( $custom_labels ) ?>'></div>
461
  </div>
462
+
463
  <?php
464
  endif;
465
  }
466
+
467
+ /**
468
+ * Update variable product price has to flush the cached price
469
+ */
470
+ public function variable_product_prices_hash( $price_hash, $product, $for_display ) {
471
+ $override_sale_price = woolentor_get_option('override_sale_price', 'woolentor_flash_sale_settings');
472
+
473
+ $deal = self::get_deal( $product->get_id() );
474
+ $discount_type = !empty($deal['discount_type']) ? $deal['discount_type'] : 'percentage';
475
+ $discount_value = !empty($deal['discount_value']) ? $deal['discount_value'] : '';
476
+
477
+ if( $deal && self::datetime_validity($deal) && $discount_value ){
478
+ $price_hash['wlfs_override_sale_price'] = $override_sale_price;
479
+ $price_hash['wlfs_discount_type'] = $discount_type;
480
+ $price_hash['wlfs_discount_value'] = $discount_value;
481
+ }
482
+
483
+ return $price_hash;
484
+ }
485
+
486
+ /**
487
+ * Get grouped product prices
488
+ */
489
+ public function get_grouped_prices( $product, $price = '' ) {
490
+ $tax_display_mode = get_option( 'woocommerce_tax_display_shop' );
491
+ $child_prices = array();
492
+ $price_range = array();
493
+ $children = array_filter( array_map( 'wc_get_product', $product->get_children() ), 'wc_products_array_filter_visible_grouped' );
494
+
495
+ foreach ( $children as $child ) {
496
+ if ( '' !== $child->get_price() ) {
497
+ $child_prices[] = 'incl' === $tax_display_mode ? wc_get_price_including_tax( $child ) : wc_get_price_excluding_tax( $child );
498
+ }
499
+ }
500
+
501
+ if ( ! empty( $child_prices ) ) {
502
+ $price_range['min'] = min( $child_prices );
503
+ $price_range['max'] = max( $child_prices );
504
+ } else {
505
+ $price_range['min'] = '';
506
+ $price_range['max'] = '';
507
+ }
508
+
509
+ return $price_range;
510
+ }
511
+
512
  }
513
 
514
  Woolentor_Flash_Sale::get_instance();
includes/modules/shopify-like-checkout/class.shopify-like-checkout.php CHANGED
@@ -283,7 +283,7 @@ class Woolentor_Shopify_Like_Checkout extends \WC_Checkout{
283
  <td data-title="<?php echo esc_attr__('Shipping','woolentor'); ?>">
284
  <ul id="shipping_method" class="woocommerce-shipping-methods">
285
  <li>
286
- <?php echo esc_html__('Sorry, it seems that there are no available payment methods. Please contact us if you require assistance or wish to make alternate arrangements.', 'woolentor') ?>
287
  </li>
288
  </ul>
289
  </td>
283
  <td data-title="<?php echo esc_attr__('Shipping','woolentor'); ?>">
284
  <ul id="shipping_method" class="woocommerce-shipping-methods">
285
  <li>
286
+ <?php echo wp_kses_post( apply_filters( 'woocommerce_no_shipping_available_html', __( 'There are no shipping options available. Please ensure that your address has been entered correctly, or contact us if you need any help.', 'woolentor' ) ) ); ?>
287
  </li>
288
  </ul>
289
  </td>
includes/modules/wishlist/assets/css/admin.css ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ tr.element_section_title_area {
2
+ background: #ffff;
3
+ }
4
+ h2.element_section_title.margin_0 {
5
+ margin: 0;
6
+ }
7
+
8
+ tr.element_section_title_area[class*="message-"] h2{
9
+ font-size: 12px;
10
+ font-weight: 400;
11
+ }
12
+ tr.element_section_title_area[class*="message-"]{
13
+ border: 1px solid #c3c4c7;
14
+ border-left-width: 4px;
15
+ box-shadow: 0 1px 1px rgb(0 0 0 / 4%);
16
+ }
17
+ tr.element_section_title_area.message-info{
18
+ border-left-color: #17a2b8
19
+ }
20
+
21
+ .form-table tr.element_section_title_area[class*="message-"] td {
22
+ padding: 0 10px;
23
+ }
24
+
25
+ /* Check box */
26
+ .htoptions_element_checkbox label {
27
+ padding: 2px;
28
+ width: 43px;
29
+ height: 15px;
30
+ background-color: #2c3e50;
31
+ border-radius: 60px;
32
+ -webkit-transition: background 0.2s;
33
+ transition: background 0.2s;
34
+ position: relative;
35
+ text-indent: -99999px;
36
+ }
37
+ .htoptions_element_checkbox label::before {
38
+ content: "";
39
+ position: absolute;
40
+ top: 2px;
41
+ left: 2px;
42
+ bottom: 2px;
43
+ right: 2px;
44
+ background-color: #ffffff;
45
+ border-radius: 10px;
46
+ -webkit-transition: background 0.2s;
47
+ transition: background 0.2s;
48
+ }
49
+ .htoptions_element_checkbox label::after {
50
+ content: "";
51
+ position: absolute;
52
+ top: 3px;
53
+ left: 3px;
54
+ bottom: 3px;
55
+ width: 18px;
56
+ background-color: #2c3e50;
57
+ border-radius: 10px;
58
+ -webkit-transition: margin 0.2s, background 0.2s;
59
+ transition: margin 0.2s, background 0.2s;
60
+ }
61
+ .htoptions_element_checkbox input {
62
+ opacity: 0;
63
+ width: 0;
64
+ height: 0;
65
+ position: absolute;
66
+ }
67
+ .htoptions_element_checkbox input:disabled{
68
+ opacity: 0;
69
+ }
70
+ .htoptions_element_checkbox input:checked + label {
71
+ background-color: #22b9ff;
72
+ }
73
+ .htoptions_element_checkbox input:checked + label::after {
74
+ background-color: #22b9ff;
75
+ margin-left: 23px;
76
+ }
77
+ .button.wpsa-remove {
78
+ margin-left: 10px;
79
+ }
80
+
81
+ ul.htoption_shortable li {
82
+ position: relative;
83
+ box-shadow: 0 0px 4px rgb(0 0 0 / 10%);
84
+ padding: 8px 0 7px 25px;
85
+ cursor: pointer;
86
+ }
87
+ ul.htoption_shortable li:before {
88
+ position: absolute;
89
+ content: "::";
90
+ left: 9px;
91
+ top: 4px;
92
+ font-size: 22px;
93
+ }
94
+ ul.htoption_shortable li.ui-sortable-helper{
95
+ background: #fff;
96
+ border: 1px dashed #ccc;
97
+ }
98
+
99
+ /* Dimensions Field */
100
+ .htoption_dimensions li {
101
+ float: left;
102
+ width: 75px;
103
+ }
104
+ .htoption_dimensions li input {
105
+ display: block;
106
+ text-align: center;
107
+ width: 100%;
108
+ border-color: #d5dadf;
109
+ height: 30px;
110
+ border-left: none;
111
+ border-radius: 0;
112
+ padding: 4px 4px 4px 0;
113
+ }
114
+ .htoption_dimensions li input:focus{
115
+ outline: none;
116
+ box-shadow: none;
117
+ border:1px solid #007cba !important;
118
+ }
119
+ .htoption_dimensions li:first-child input {
120
+ border-left: 1px solid #d5dadf;
121
+ border-radius: 3px 0 0 3px;
122
+ }
123
+ .htoption_dimensions li:last-child input {
124
+ border-right: 1px solid #d5dadf;
125
+ border-radius: 0 3px 3px 0;
126
+ }
127
+ .htoption_dimensions li label {
128
+ display: block !important;
129
+ text-align: center;
130
+ font-size: 13px;
131
+ text-transform: uppercase;
132
+ }
133
+ .element_section_title.margin_0{
134
+ margin: 0;
135
+ }
includes/modules/wishlist/assets/css/frontend.css ADDED
@@ -0,0 +1,457 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Wishlist Button */
2
+ a.wishsuite-addtocart.loading{
3
+ opacity: .25;
4
+ padding-right: 2.618em;
5
+ position: relative;
6
+ }
7
+ a.wishsuite-addtocart.loading::after{
8
+ font-family: WooCommerce;
9
+ content: '\e01c';
10
+ vertical-align: top;
11
+ -webkit-font-smoothing: antialiased;
12
+ font-weight: 400;
13
+ position: absolute;
14
+ top: auto;
15
+ right: 1em;
16
+ animation: spin 2s linear infinite;
17
+ }
18
+ a.wishsuite-addtocart.added::after{
19
+ font-family: WooCommerce;
20
+ content: '\e017';
21
+ margin-left: .53em;
22
+ vertical-align: bottom;
23
+ }
24
+
25
+ .wishsuite-loader {
26
+ position: absolute;
27
+ right: 10px;
28
+ }
29
+ a.wishsuite-button::after,.woocommerce a.button.wishsuite-button::after{
30
+ display: none;
31
+ }
32
+ a.wishsuite-btn.loading,.woocommerce a.button.wishsuite-btn.loading{
33
+ opacity: 1;
34
+ }
35
+ .woocommerce a.button.wishsuite-button{
36
+ display: inline-flex;
37
+ }
38
+
39
+ .wishsuite-shop-top_thumbnail{
40
+ position: absolute !important;
41
+ z-index: 9999;
42
+ top: 10px;
43
+ left: 10px !important;
44
+ margin: 0 !important;
45
+ }
46
+
47
+ .wishsuite-button img {
48
+ display: inline-block !important;
49
+ width: 25px !important;
50
+ margin: 0 10px 0 0 !important;
51
+ }
52
+
53
+ .wishsuite-button {
54
+ display: inline-flex;
55
+ align-items: center;
56
+ position: relative;
57
+ }
58
+
59
+ .wishsuite-button:focus {
60
+ outline: none;
61
+ border:none;
62
+ }
63
+
64
+ .wishsuite-button svg {
65
+ fill:currentColor;
66
+ transition: all 200ms ease-out;
67
+ width: 15px;
68
+ height: 15px;
69
+ }
70
+ .wishsuite-button svg + span{
71
+ margin-left: 6px;
72
+ }
73
+
74
+ .wishsuite-button:hover svg,
75
+ .wishlist-toggle.added svg {
76
+ fill:currentColor;
77
+ }
78
+
79
+ .wishsuite-button svg .loading,
80
+ .wishsuite-button svg .check {
81
+ opacity: 0;
82
+ }
83
+
84
+ .wishsuite-button.added svg .check,.wishsuite-button.wishsuite-btn-exist svg .check {
85
+ opacity: 1;
86
+ }
87
+
88
+ .wishsuite-button.added svg .heart,.wishsuite-button.wishsuite-btn-exist svg .heart {
89
+ opacity: 0;
90
+ }
91
+
92
+ .wishsuite-button.loading svg .loading,
93
+ .wishsuite-button.loading:before {
94
+ animation:loading 500ms 0ms infinite normal linear;
95
+ transform-origin: center;
96
+ opacity: 1;
97
+ }
98
+
99
+ .wishsuite-button.loading svg .heart {
100
+ opacity:0;
101
+ }
102
+ .wishsuite-btn-text {
103
+ display: flex;
104
+ align-items: center;
105
+ }
106
+
107
+ @keyframes loading {
108
+ from {transform: rotate(0deg);}
109
+ to {transform: rotate(360deg);}
110
+ }
111
+
112
+ /* Table style*/
113
+ .wishsuite-table-content table {
114
+ width: 100%;
115
+ margin: 0;
116
+ border: 1px solid #ebebeb;
117
+ border-collapse: collapse;
118
+ }
119
+ .wishsuite-table-content table thead > tr {
120
+ background-color: #f9f9f9;
121
+ border: 1px solid #ebebeb;
122
+ }
123
+ .wishsuite-table-content table thead > tr th {
124
+ border-top: medium none;
125
+ color: #333;
126
+ font-size: 14px;
127
+ font-weight: 500;
128
+ padding: 20px 30px 20px;
129
+ text-align: center;
130
+ text-transform: uppercase;
131
+ vertical-align: middle;
132
+ white-space: nowrap;
133
+ border:0;
134
+ }
135
+
136
+ .wishsuite-table-content table tbody > tr {
137
+ border-bottom: 1px solid #ebebeb;
138
+ }
139
+ .wishsuite-table-content table tbody > tr td {
140
+ color: #333;
141
+ font-size: 15px;
142
+ padding: 10px;
143
+ text-align: center;
144
+ border:0;
145
+ }
146
+
147
+ .wishsuite-table-content .quantity .qty {
148
+ width: 3.631em;
149
+ padding: 5px 5px 5px 5px;
150
+ text-align: center;
151
+ }
152
+
153
+ /* Table Loader */
154
+ .wishsuite-table-content {
155
+ position: relative;
156
+ overflow-y: auto;
157
+ overflow: visible;
158
+ }
159
+ .wishsuite-table-content.loading:before{
160
+ position: absolute;
161
+ content:"";
162
+ top: 0;
163
+ right: 0;
164
+ bottom: 0;
165
+ left: 0;
166
+ z-index: 1;
167
+ background-color: rgba(255,255,255,.6);
168
+ }
169
+ .wishsuite-table-content .wishsuite-table-content-loader {
170
+ border: 8px solid #f3f3f3;
171
+ border-radius: 50%;
172
+ border-top: 8px solid #3498db;
173
+ width: 50px;
174
+ height: 50px;
175
+ -webkit-animation: htcomspin 1s linear infinite;
176
+ animation: htcomspin 1s linear infinite;
177
+ position: absolute;
178
+ top: 50%;
179
+ left: 50%;
180
+ z-index: 1;
181
+ transform: translate(-30px, -25px);
182
+ display: none;
183
+ }
184
+
185
+ .wishsuite-table-content.loading .wishsuite-table-content-loader{
186
+ display: block;
187
+ }
188
+
189
+ /* Safari */
190
+ @-webkit-keyframes htcomspin {
191
+ 0% { -webkit-transform: rotate(0deg); }
192
+ 100% { -webkit-transform: rotate(360deg); }
193
+ }
194
+
195
+ @keyframes htcomspin {
196
+ 0% { transform: rotate(0deg); }
197
+ 100% { transform: rotate(360deg); }
198
+ }
199
+
200
+ /* Remove Button */
201
+ .wishsuite-remove{
202
+ position: relative;
203
+ display: inline-block;
204
+ padding: 10px;
205
+ margin-left: -5px;
206
+ transition: none;
207
+ text-decoration: none !important;
208
+ }
209
+ .wishsuite-remove:focus{
210
+ outline: none;
211
+ }
212
+ .wishsuite-remove::after, .wishsuite-remove::before {
213
+ content: " ";
214
+ position: absolute;
215
+ top: 50%;
216
+ display: inline-block;
217
+ width: 15px;
218
+ height: 2px;
219
+ background-color: #2d2a2a;
220
+ right: 0;
221
+ -webkit-transform: rotate(45deg);
222
+ transform: rotate(45deg);
223
+ }
224
+ .wishsuite-remove::after{
225
+ -webkit-transform: rotate(-45deg);
226
+ transform: rotate(-45deg);
227
+ }
228
+ .wishsuite-remove:hover::after,.wishsuite-remove:hover::before{
229
+ background: #EC1E1E;
230
+ }
231
+
232
+ .wishsuite-emplty-text{
233
+ text-align: center;
234
+ }
235
+
236
+ .wishsuite-product-add_to_cart a{
237
+ display: block;
238
+ text-decoration: none !important;
239
+ }
240
+ .wishsuite-product-add_to_cart a.wc-forward{
241
+ margin-top: 10px;
242
+ }
243
+
244
+ /* Compare wishlist adjustment */
245
+ .htcompare-btn + .wishsuite-button{
246
+ margin-left: 10px;
247
+ }
248
+
249
+ /* Variation Product Quick Cart */
250
+ .wishsuite-product-add_to_cart{
251
+ position: relative;
252
+ }
253
+ .wishsuite-quick-cart-area {
254
+ position: absolute;
255
+ width: 300px;
256
+ height: 200px;
257
+ right: 0;
258
+ bottom: 0;
259
+ display: none;
260
+ z-index: 99;
261
+ background-color: #fff;
262
+ padding: 15px 20px 15px 20px;
263
+ border: 1px solid #ddd;
264
+ }
265
+ .quick-cart-open .wishsuite-quick-cart-area{
266
+ overflow: hidden;
267
+ overflow-y: auto;
268
+ display: block;
269
+ }
270
+ .wishsuite-quick-cart-area .wishsuite-button {
271
+ display: none !important;
272
+ }
273
+ .wishsuite-product-add_to_cart .wishsuite-quick-cart-area a {
274
+ display: inline-block;
275
+ }
276
+
277
+ .wishsuite-quick-cart-close {
278
+ display: inline-block;
279
+ padding: 1px 10px;
280
+ position: absolute;
281
+ right: 0;
282
+ top: 0;
283
+ cursor: pointer;
284
+ transition: 0.4s;
285
+ }
286
+ .wishsuite-quick-cart-close:hover{
287
+ color:#D93025;
288
+ }
289
+ .wishsuite-quick-cart-area form.cart .variations select {
290
+ max-width: 100%;
291
+ min-width: 75%;
292
+ display: inline-block;
293
+ width: 100%;
294
+ margin-right: 0;
295
+ padding-top: .5em;
296
+ padding-bottom: .5em;
297
+ }
298
+ .wishsuite-quick-cart-area form.cart .variations select:focus {
299
+ outline: none;
300
+ }
301
+ .wishsuite-quick-cart-area .single_add_to_cart_button {
302
+ width: auto;
303
+ }
304
+ .wishsuite-quick-cart-area .single_add_to_cart_button.disabled {
305
+ cursor: not-allowed;
306
+ opacity: 0.5;
307
+ }
308
+ .wishsuite-quick-cart-area .quantity {
309
+ display: inline-block;
310
+ }
311
+ .wishsuite-quick-cart-area .woocommerce-variation-add-to-cart{
312
+ margin-top: 15px;
313
+ }
314
+ .wishsuite-quick-cart-area form.cart table {
315
+ border-width: 0 0 1px;
316
+ margin: 0 0 1.2em;
317
+ }
318
+
319
+ .wishsuite-quick-cart-area form.cart .variations {
320
+ border-bottom: 1px solid rgba(0,0,0,.1);
321
+ position: relative;
322
+ margin-bottom: 1em;
323
+ width: 100%;
324
+ }
325
+
326
+ .wishsuite-quick-cart-area form.cart .variations td, .wishsuite-quick-cart-area form.cart .variations th {
327
+ border: 0;
328
+ vertical-align: top;
329
+ line-height: 2em;
330
+ padding-top: 0;
331
+ padding-bottom: 0;
332
+ padding-right: 0;
333
+ display: block;
334
+ text-align: left;
335
+ }
336
+ .wishsuite-quick-cart-area form.cart table td {
337
+ padding-left: 0;
338
+ }
339
+ .wishsuite-quick-cart-area a.added_to_cart{
340
+ width: 100%;
341
+ padding: 3px;
342
+ text-align: center;
343
+ border: 1px solid #ddd;
344
+ margin-top: 5px;
345
+ }
346
+ .wishsuite-quick-cart-area a.reset_variations {
347
+ text-align: left;
348
+ }
349
+
350
+ /* Social Media Share */
351
+ .wishsuite-social-share {
352
+ display: flex;
353
+ align-items: center;
354
+ margin-top: 15px;
355
+ }
356
+ .wishsuite-social-share .wishsuite-social-title{}
357
+ .wishsuite-social-share ul{
358
+ margin: 0;
359
+ padding: 0;
360
+ list-style: none;
361
+ display: flex;
362
+ }
363
+ .wishsuite-social-share ul li{
364
+ display: inline-block;
365
+ }
366
+ .wishsuite-social-share ul li a{
367
+ display: block;
368
+ line-height: 1;
369
+ padding: 5px;
370
+ color: #3a3a3a;
371
+ }
372
+ .wishsuite-social-share ul li a .wishsuite-social-icon{}
373
+ .wishsuite-social-share ul li a .wishsuite-social-icon svg{
374
+ fill:currentColor;
375
+ width: 15px;
376
+ height: 15px;
377
+ }
378
+
379
+ /*@media only screen and (max-width: 760px),
380
+ (min-device-width: 768px) and (max-device-width: 1024px) {*/
381
+
382
+ @media (max-width: 767px) {
383
+
384
+ /* Force table to not be like tables anymore */
385
+ .wishsuite-table-content table, .wishsuite-table-content thead, .wishsuite-table-content tbody, .wishsuite-table-content th, .wishsuite-table-content td, .wishsuite-table-content tr {
386
+ display: block;
387
+ }
388
+ .wishsuite-table-content table, .wishsuite-table-content table th, .wishsuite-table-content table tbody > tr td,.wishsuite-table-content table td.wishsuite-product-title{
389
+ text-align: left;
390
+ }
391
+
392
+ .wishsuite-table-content table{
393
+ border:none;
394
+ }
395
+
396
+ .wishsuite-table-content td{
397
+ padding: 10px;
398
+ }
399
+
400
+ /* Hide table headers (but not display: none;, for accessibility) */
401
+ .wishsuite-table-content thead tr {
402
+ position: absolute;
403
+ top: -9999px;
404
+ left: -9999px;
405
+ }
406
+
407
+ .wishsuite-table-content tr {
408
+ border: 1px solid #ebebeb;
409
+ margin-top: 15px;
410
+ }
411
+
412
+ .wishsuite-table-content table tbody > tr td {
413
+ border: none;
414
+ border-bottom: 1px solid #ebebeb;
415
+ position: relative;
416
+ padding-left: 50%;
417
+ }
418
+
419
+ .wishsuite-table-content td::before {
420
+ position: absolute;
421
+ top: 34%;
422
+ left: 15px;
423
+ width: 45%;
424
+ padding-right: 10px;
425
+ white-space: nowrap;
426
+ text-align: left;
427
+ }
428
+
429
+ .wishsuite-product-add_to_cart a{
430
+ text-align: center;
431
+ }
432
+
433
+ /*
434
+ Label the data
435
+ */
436
+ .wishsuite-table-content td:nth-of-type(1):before { content: attr(data-label); }
437
+ .wishsuite-table-content td:nth-of-type(2):before { content: attr(data-label); }
438
+ .wishsuite-table-content td:nth-of-type(3):before { content: attr(data-label); }
439
+ .wishsuite-table-content td:nth-of-type(4):before { content: attr(data-label); }
440
+ .wishsuite-table-content td:nth-of-type(5):before { content: attr(data-label); }
441
+ .wishsuite-table-content td:nth-of-type(6):before { content: attr(data-label); }
442
+ .wishsuite-table-content td:nth-of-type(7):before { content: attr(data-label); }
443
+ .wishsuite-table-content td:nth-of-type(8):before { content: attr(data-label); }
444
+ .wishsuite-table-content td:nth-of-type(9):before { content: attr(data-label); }
445
+ .wishsuite-table-content td:nth-of-type(10):before { content: attr(data-label); }
446
+ .wishsuite-table-content td:nth-of-type(11):before { content: attr(data-label); }
447
+ .wishsuite-table-content td:nth-of-type(12):before { content: attr(data-label); }
448
+ .wishsuite-table-content td:nth-of-type(13):before { content: attr(data-label); }
449
+ .wishsuite-table-content td:nth-of-type(14):before { content: attr(data-label); }
450
+ .wishsuite-table-content td:nth-of-type(15):before { content: attr(data-label); }
451
+ .wishsuite-table-content td:nth-of-type(16):before { content: attr(data-label); }
452
+ .wishsuite-table-content td:nth-of-type(17):before { content: attr(data-label); }
453
+ .wishsuite-table-content td:nth-of-type(18):before { content: attr(data-label); }
454
+ .wishsuite-table-content td:nth-of-type(19):before { content: attr(data-label); }
455
+ .wishsuite-table-content td:nth-of-type(20):before { content: attr(data-label); }
456
+
457
+ }
includes/modules/wishlist/assets/images/extensions/email-candy-pro.png ADDED
Binary file
includes/modules/wishlist/assets/images/extensions/hashbar-pro.png ADDED
Binary file
includes/modules/wishlist/assets/images/extensions/htmega-pro.png ADDED
Binary file
includes/modules/wishlist/assets/images/extensions/just-tables-pro.png ADDED
Binary file
includes/modules/wishlist/assets/images/extensions/multicurrencypro.png ADDED
Binary file
includes/modules/wishlist/assets/images/extensions/whols-pro.png ADDED
Binary file
includes/modules/wishlist/assets/images/extensions/woolentor-addons-pro.png ADDED
Binary file
includes/modules/wishlist/assets/images/icon.svg ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg height="15px" width="15px" viewBox="0 0 471.701 471.701">
2
+ <path class="heart" d="M433.601,67.001c-24.7-24.7-57.4-38.2-92.3-38.2s-67.7,13.6-92.4,38.3l-12.9,12.9l-13.1-13.1
3
+ c-24.7-24.7-57.6-38.4-92.5-38.4c-34.8,0-67.6,13.6-92.2,38.2c-24.7,24.7-38.3,57.5-38.2,92.4c0,34.9,13.7,67.6,38.4,92.3
4
+ l187.8,187.8c2.6,2.6,6.1,4,9.5,4c3.4,0,6.9-1.3,9.5-3.9l188.2-187.5c24.7-24.7,38.3-57.5,38.3-92.4
5
+ C471.801,124.501,458.301,91.701,433.601,67.001z M414.401,232.701l-178.7,178l-178.3-178.3c-19.6-19.6-30.4-45.6-30.4-73.3
6
+ s10.7-53.7,30.3-73.2c19.5-19.5,45.5-30.3,73.1-30.3c27.7,0,53.8,10.8,73.4,30.4l22.6,22.6c5.3,5.3,13.8,5.3,19.1,0l22.4-22.4
7
+ c19.6-19.6,45.7-30.4,73.3-30.4c27.6,0,53.6,10.8,73.2,30.3c19.6,19.6,30.3,45.6,30.3,73.3
8
+ C444.801,187.101,434.001,213.101,414.401,232.701z"/>
9
+ <g class="loading">
10
+ <path d="M409.6,0c-9.426,0-17.067,7.641-17.067,17.067v62.344C304.667-5.656,164.478-3.386,79.411,84.479
11
+ c-40.09,41.409-62.455,96.818-62.344,154.454c0,9.426,7.641,17.067,17.067,17.067S51.2,248.359,51.2,238.933
12
+ c0.021-103.682,84.088-187.717,187.771-187.696c52.657,0.01,102.888,22.135,138.442,60.976l-75.605,25.207
13
+ c-8.954,2.979-13.799,12.652-10.82,21.606s12.652,13.799,21.606,10.82l102.4-34.133c6.99-2.328,11.697-8.88,11.674-16.247v-102.4
14
+ C426.667,7.641,419.026,0,409.6,0z"/>
15
+ <path d="M443.733,221.867c-9.426,0-17.067,7.641-17.067,17.067c-0.021,103.682-84.088,187.717-187.771,187.696
16
+ c-52.657-0.01-102.888-22.135-138.442-60.976l75.605-25.207c8.954-2.979,13.799-12.652,10.82-21.606
17
+ c-2.979-8.954-12.652-13.799-21.606-10.82l-102.4,34.133c-6.99,2.328-11.697,8.88-11.674,16.247v102.4
18
+ c0,9.426,7.641,17.067,17.067,17.067s17.067-7.641,17.067-17.067v-62.345c87.866,85.067,228.056,82.798,313.122-5.068
19
+ c40.09-41.409,62.455-96.818,62.344-154.454C460.8,229.508,453.159,221.867,443.733,221.867z"/>
20
+ </g>
21
+ <g class="check">
22
+ <path d="M238.933,0C106.974,0,0,106.974,0,238.933s106.974,238.933,238.933,238.933s238.933-106.974,238.933-238.933
23
+ C477.726,107.033,370.834,0.141,238.933,0z M238.933,443.733c-113.108,0-204.8-91.692-204.8-204.8s91.692-204.8,204.8-204.8
24
+ s204.8,91.692,204.8,204.8C443.611,351.991,351.991,443.611,238.933,443.733z"/>
25
+ <path d="M370.046,141.534c-6.614-6.388-17.099-6.388-23.712,0v0L187.733,300.134l-56.201-56.201
26
+ c-6.548-6.78-17.353-6.967-24.132-0.419c-6.78,6.548-6.967,17.353-0.419,24.132c0.137,0.142,0.277,0.282,0.419,0.419
27
+ l68.267,68.267c6.664,6.663,17.468,6.663,24.132,0l170.667-170.667C377.014,158.886,376.826,148.082,370.046,141.534z"/>
28
+ </g>
29
+ </svg>
includes/modules/wishlist/assets/images/loading.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 15 15">
2
+ <g class="loading">
3
+ <path d="M409.6,0c-9.426,0-17.067,7.641-17.067,17.067v62.344C304.667-5.656,164.478-3.386,79.411,84.479
4
+ c-40.09,41.409-62.455,96.818-62.344,154.454c0,9.426,7.641,17.067,17.067,17.067S51.2,248.359,51.2,238.933
5
+ c0.021-103.682,84.088-187.717,187.771-187.696c52.657,0.01,102.888,22.135,138.442,60.976l-75.605,25.207
6
+ c-8.954,2.979-13.799,12.652-10.82,21.606s12.652,13.799,21.606,10.82l102.4-34.133c6.99-2.328,11.697-8.88,11.674-16.247v-102.4
7
+ C426.667,7.641,419.026,0,409.6,0z"/>
8
+ <path d="M443.733,221.867c-9.426,0-17.067,7.641-17.067,17.067c-0.021,103.682-84.088,187.717-187.771,187.696
9
+ c-52.657-0.01-102.888-22.135-138.442-60.976l75.605-25.207c8.954-2.979,13.799-12.652,10.82-21.606
10
+ c-2.979-8.954-12.652-13.799-21.606-10.82l-102.4,34.133c-6.99,2.328-11.697,8.88-11.674,16.247v102.4
11
+ c0,9.426,7.641,17.067,17.067,17.067s17.067-7.641,17.067-17.067v-62.345c87.866,85.067,228.056,82.798,313.122-5.068
12
+ c40.09-41.409,62.455-96.818,62.344-154.454C460.8,229.508,453.159,221.867,443.733,221.867z"/>
13
+ </g>
14
+ </svg>
includes/modules/wishlist/assets/images/remove.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg height="15px" viewBox="1 1 15 15" width="15px" xmlns="http://www.w3.org/2000/svg"><path d="m256 0c-141.386719 0-256 114.613281-256 256s114.613281 256 256 256 256-114.613281 256-256c-.167969-141.316406-114.683594-255.832031-256-256zm0 480c-123.710938 0-224-100.289062-224-224s100.289062-224 224-224 224 100.289062 224 224c-.132812 123.65625-100.34375 223.867188-224 224zm0 0"/><path d="m380.449219 131.550781c-6.25-6.246093-16.378907-6.246093-22.625 0l-101.824219 101.824219-101.824219-101.824219c-6.140625-6.355469-16.269531-6.53125-22.625-.390625-6.355469 6.136719-6.53125 16.265625-.390625 22.621094.128906.132812.257813.265625.390625.394531l101.824219 101.824219-101.824219 101.824219c-6.355469 6.136719-6.53125 16.265625-.390625 22.625 6.136719 6.355469 16.265625 6.53125 22.621094.390625.132812-.128906.265625-.257813.394531-.390625l101.824219-101.824219 101.824219 101.824219c6.355469 6.136719 16.484375 5.960937 22.621093-.394531 5.988282-6.199219 5.988282-16.03125 0-22.230469l-101.820312-101.824219 101.824219-101.824219c6.246093-6.246093 6.246093-16.375 0-22.625zm0 0"/></svg>
includes/modules/wishlist/assets/images/social-icon/email.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg id="Capa_1" enable-background="new 0 0 479.058 479.058" height="512" viewBox="0 0 479.058 479.058" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m434.146 59.882h-389.234c-24.766 0-44.912 20.146-44.912 44.912v269.47c0 24.766 20.146 44.912 44.912 44.912h389.234c24.766 0 44.912-20.146 44.912-44.912v-269.47c0-24.766-20.146-44.912-44.912-44.912zm0 29.941c2.034 0 3.969.422 5.738 1.159l-200.355 173.649-200.356-173.649c1.769-.736 3.704-1.159 5.738-1.159zm0 299.411h-389.234c-8.26 0-14.971-6.71-14.971-14.971v-251.648l199.778 173.141c2.822 2.441 6.316 3.655 9.81 3.655s6.988-1.213 9.81-3.655l199.778-173.141v251.649c-.001 8.26-6.711 14.97-14.971 14.97z"/></svg>
includes/modules/wishlist/assets/images/social-icon/facebook.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg id="Bold" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m15.997 3.985h2.191v-3.816c-.378-.052-1.678-.169-3.192-.169-3.159 0-5.323 1.987-5.323 5.639v3.361h-3.486v4.266h3.486v10.734h4.274v-10.733h3.345l.531-4.266h-3.877v-2.939c.001-1.233.333-2.077 2.051-2.077z"/></svg>
includes/modules/wishlist/assets/images/social-icon/linkedin.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg height="682pt" viewBox="-21 -35 682.66669 682" width="682pt" xmlns="http://www.w3.org/2000/svg"><path d="m77.613281-.667969c-46.929687 0-77.613281 30.816407-77.613281 71.320313 0 39.609375 29.769531 71.304687 75.8125 71.304687h.890625c47.847656 0 77.625-31.695312 77.625-71.304687-.894531-40.503906-29.777344-71.320313-76.714844-71.320313zm0 0"/><path d="m8.109375 198.3125h137.195313v412.757812h-137.195313zm0 0"/><path d="m482.054688 188.625c-74.011719 0-123.640626 69.546875-123.640626 69.546875v-59.859375h-137.199218v412.757812h137.191406v-230.5c0-12.339843.894531-24.660156 4.519531-33.484374 9.917969-24.640626 32.488281-50.167969 70.390625-50.167969 49.644532 0 69.5 37.851562 69.5 93.339843v220.8125h137.183594v-236.667968c0-126.78125-67.6875-185.777344-157.945312-185.777344zm0 0"/></svg>
includes/modules/wishlist/assets/images/social-icon/odnoklassniki.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg id="Bold" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m4.721 12.881c-.613 1.205.083 1.781 1.671 2.765 1.35.834 3.215 1.139 4.413 1.261-.491.472 1.759-1.692-4.721 4.541-1.374 1.317.838 3.43 2.211 2.141l3.717-3.585c1.423 1.369 2.787 2.681 3.717 3.59 1.374 1.294 3.585-.801 2.226-2.141-.102-.097-5.037-4.831-4.736-4.541 1.213-.122 3.05-.445 4.384-1.261l-.001-.001c1.588-.989 2.284-1.564 1.68-2.769-.365-.684-1.349-1.256-2.659-.267 0 0-1.769 1.355-4.622 1.355-2.854 0-4.622-1.355-4.622-1.355-1.309-.994-2.297-.417-2.658.267z"/><path d="m11.999 12.142c3.478 0 6.318-2.718 6.318-6.064 0-3.36-2.84-6.078-6.318-6.078-3.479 0-6.319 2.718-6.319 6.078 0 3.346 2.84 6.064 6.319 6.064zm0-9.063c1.709 0 3.103 1.341 3.103 2.999 0 1.644-1.394 2.985-3.103 2.985s-3.103-1.341-3.103-2.985c-.001-1.659 1.393-2.999 3.103-2.999z"/></svg>
includes/modules/wishlist/assets/images/social-icon/pinterest.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg id="Bold" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m12.326 0c-6.579.001-10.076 4.216-10.076 8.812 0 2.131 1.191 4.79 3.098 5.633.544.245.472-.054.94-1.844.037-.149.018-.278-.102-.417-2.726-3.153-.532-9.635 5.751-9.635 9.093 0 7.394 12.582 1.582 12.582-1.498 0-2.614-1.176-2.261-2.631.428-1.733 1.266-3.596 1.266-4.845 0-3.148-4.69-2.681-4.69 1.49 0 1.289.456 2.159.456 2.159s-1.509 6.096-1.789 7.235c-.474 1.928.064 5.049.111 5.318.029.148.195.195.288.073.149-.195 1.973-2.797 2.484-4.678.186-.685.949-3.465.949-3.465.503.908 1.953 1.668 3.498 1.668 4.596 0 7.918-4.04 7.918-9.053-.016-4.806-4.129-8.402-9.423-8.402z"/></svg>
includes/modules/wishlist/assets/images/social-icon/reddit.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg id="Bold" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m21.325 9.308c-.758 0-1.425.319-1.916.816-1.805-1.268-4.239-2.084-6.936-2.171l1.401-6.406 4.461 1.016c0 1.108.89 2.013 1.982 2.013 1.113 0 2.008-.929 2.008-2.038s-.889-2.038-2.007-2.038c-.779 0-1.451.477-1.786 1.129l-4.927-1.108c-.248-.067-.491.113-.557.365l-1.538 7.062c-2.676.113-5.084.928-6.895 2.197-.491-.518-1.184-.837-1.942-.837-2.812 0-3.733 3.829-1.158 5.138-.091.405-.132.837-.132 1.268 0 4.301 4.775 7.786 10.638 7.786 5.888 0 10.663-3.485 10.663-7.786 0-.431-.045-.883-.156-1.289 2.523-1.314 1.594-5.115-1.203-5.117zm-15.724 5.41c0-1.129.89-2.038 2.008-2.038 1.092 0 1.983.903 1.983 2.038 0 1.109-.89 2.013-1.983 2.013-1.113.005-2.008-.904-2.008-2.013zm10.839 4.798c-1.841 1.868-7.036 1.868-8.878 0-.203-.18-.203-.498 0-.703.177-.18.491-.18.668 0 1.406 1.463 6.07 1.488 7.537 0 .177-.18.491-.18.668 0 .207.206.207.524.005.703zm-.041-2.781c-1.092 0-1.982-.903-1.982-2.011 0-1.129.89-2.038 1.982-2.038 1.113 0 2.008.903 2.008 2.038-.005 1.103-.895 2.011-2.008 2.011z"/></svg>
includes/modules/wishlist/assets/images/social-icon/telegram.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg id="Bold" enable-background="new 0 0 24 24" height="512" viewBox="0 0 24 24" width="512" xmlns="http://www.w3.org/2000/svg"><path d="m9.417 15.181-.397 5.584c.568 0 .814-.244 1.109-.537l2.663-2.545 5.518 4.041c1.012.564 1.725.267 1.998-.931l3.622-16.972.001-.001c.321-1.496-.541-2.081-1.527-1.714l-21.29 8.151c-1.453.564-1.431 1.374-.247 1.741l5.443 1.693 12.643-7.911c.595-.394 1.136-.176.691.218z"/></svg>
includes/modules/wishlist/assets/images/social-icon/twitter.svg ADDED
@@ -0,0 +1 @@
 
1
+ <svg height="681pt" viewBox="-21 -81 681.33464 681" width="681pt" xmlns="http://www.w3.org/2000/svg"><path d="m200.964844 515.292969c241.050781 0 372.871094-199.703125 372.871094-372.871094 0-5.671875-.117188-11.320313-.371094-16.9375 25.585937-18.5 47.824218-41.585937 65.371094-67.863281-23.480469 10.441406-48.753907 17.460937-75.257813 20.636718 27.054687-16.230468 47.828125-41.894531 57.625-72.488281-25.320313 15.011719-53.363281 25.917969-83.214844 31.808594-23.914062-25.472656-57.964843-41.402344-95.664062-41.402344-72.367188 0-131.058594 58.6875-131.058594 131.03125 0 10.289063 1.152344 20.289063 3.398437 29.882813-108.917968-5.480469-205.503906-57.625-270.132812-136.921875-11.25 19.363281-17.742188 41.863281-17.742188 65.871093 0 45.460938 23.136719 85.605469 58.316407 109.082032-21.5-.660156-41.695313-6.5625-59.351563-16.386719-.019531.550781-.019531 1.085937-.019531 1.671875 0 63.46875 45.171875 116.460938 105.144531 128.46875-11.015625 2.996094-22.605468 4.609375-34.558594 4.609375-8.429687 0-16.648437-.828125-24.632812-2.363281 16.683594 52.070312 65.066406 89.960937 122.425781 91.023437-44.855469 35.15625-101.359375 56.097657-162.769531 56.097657-10.5625 0-21.003906-.605469-31.2617188-1.816407 57.9999998 37.175781 126.8710938 58.871094 200.8867188 58.871094"/></svg>
includes/modules/wishlist/assets/images/social-icon/vk.svg ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 511.962 511.962" style="enable-background:new 0 0 511.962 511.962;" xml:space="preserve">
5
+ <g>
6
+ <path d="M507.399,370.471c-1.376-2.304-9.888-20.8-50.848-58.816c-42.88-39.808-37.12-33.344,14.528-102.176
7
+ c31.456-41.92,44.032-67.52,40.096-78.464c-3.744-10.432-26.88-7.68-26.88-7.68l-76.928,0.448c0,0-5.696-0.768-9.952,1.76
8
+ c-4.128,2.496-6.784,8.256-6.784,8.256s-12.192,32.448-28.448,60.032c-34.272,58.208-48,61.28-53.6,57.664
9
+ c-13.024-8.416-9.76-33.856-9.76-51.904c0-56.416,8.544-79.936-16.672-86.016c-8.384-2.016-14.528-3.36-35.936-3.584
10
+ c-27.456-0.288-50.72,0.096-63.872,6.528c-8.768,4.288-15.52,13.856-11.392,14.4c5.088,0.672,16.608,3.104,22.72,11.424
11
+ c7.904,10.72,7.616,34.848,7.616,34.848s4.544,66.4-10.592,74.656c-10.4,5.664-24.64-5.888-55.2-58.72
12
+ c-15.648-27.04-27.488-56.96-27.488-56.96s-2.272-5.568-6.336-8.544c-4.928-3.616-11.84-4.768-11.84-4.768l-73.152,0.448
13
+ c0,0-10.976,0.32-15.008,5.088c-3.584,4.256-0.288,13.024-0.288,13.024s57.28,133.984,122.112,201.536
14
+ c59.488,61.92,127.008,57.856,127.008,57.856h30.592c0,0,9.248-1.024,13.952-6.112c4.352-4.672,4.192-13.44,4.192-13.44
15
+ s-0.608-41.056,18.464-47.104c18.784-5.952,42.912,39.68,68.48,57.248c19.328,13.28,34.016,10.368,34.016,10.368l68.384-0.96
16
+ C488.583,400.807,524.359,398.599,507.399,370.471z"/>
17
+ </g>
18
+ </svg>
includes/modules/wishlist/assets/images/social-icon/whatsapp.svg ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="iso-8859-1"?>
2
+ <!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 52 52" style="enable-background:new 0 0 52 52;" xml:space="preserve">
5
+ <g>
6
+ <path d="M26,0C11.663,0,0,11.663,0,26c0,4.891,1.359,9.639,3.937,13.762C2.91,43.36,1.055,50.166,1.035,50.237
7
+ c-0.096,0.352,0.007,0.728,0.27,0.981c0.263,0.253,0.643,0.343,0.989,0.237L12.6,48.285C16.637,50.717,21.26,52,26,52
8
+ c14.337,0,26-11.663,26-26S40.337,0,26,0z M26,50c-4.519,0-8.921-1.263-12.731-3.651c-0.161-0.101-0.346-0.152-0.531-0.152
9
+ c-0.099,0-0.198,0.015-0.294,0.044l-8.999,2.77c0.661-2.413,1.849-6.729,2.538-9.13c0.08-0.278,0.035-0.578-0.122-0.821
10
+ C3.335,35.173,2,30.657,2,26C2,12.767,12.767,2,26,2s24,10.767,24,24S39.233,50,26,50z"/>
11
+ <path d="M42.985,32.126c-1.846-1.025-3.418-2.053-4.565-2.803c-0.876-0.572-1.509-0.985-1.973-1.218
12
+ c-1.297-0.647-2.28-0.19-2.654,0.188c-0.047,0.047-0.089,0.098-0.125,0.152c-1.347,2.021-3.106,3.954-3.621,4.058
13
+ c-0.595-0.093-3.38-1.676-6.148-3.981c-2.826-2.355-4.604-4.61-4.865-6.146C20.847,20.51,21.5,19.336,21.5,18
14
+ c0-1.377-3.212-7.126-3.793-7.707c-0.583-0.582-1.896-0.673-3.903-0.273c-0.193,0.039-0.371,0.134-0.511,0.273
15
+ c-0.243,0.243-5.929,6.04-3.227,13.066c2.966,7.711,10.579,16.674,20.285,18.13c1.103,0.165,2.137,0.247,3.105,0.247
16
+ c5.71,0,9.08-2.873,10.029-8.572C43.556,32.747,43.355,32.331,42.985,32.126z M30.648,39.511
17
+ c-10.264-1.539-16.729-11.708-18.715-16.87c-1.97-5.12,1.663-9.685,2.575-10.717c0.742-0.126,1.523-0.179,1.849-0.128
18
+ c0.681,0.947,3.039,5.402,3.143,6.204c0,0.525-0.171,1.256-2.207,3.293C17.105,21.48,17,21.734,17,22c0,5.236,11.044,12.5,13,12.5
19
+ c1.701,0,3.919-2.859,5.182-4.722c0.073,0.003,0.196,0.028,0.371,0.116c0.36,0.181,0.984,0.588,1.773,1.104
20
+ c1.042,0.681,2.426,1.585,4.06,2.522C40.644,37.09,38.57,40.701,30.648,39.511z"/>
21
+ </g>
22
+ </svg>
includes/modules/wishlist/assets/js/admin.js ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($){
2
+ "use strict";
3
+
4
+ // Active settigns menu item
5
+ if ( typeof WishSuite.is_settings != "undefined" && WishSuite.is_settings == 1 ){
6
+ $('.toplevel_page_wishsuite .wp-first-item').addClass('current');
7
+ }
8
+
9
+ // Save value
10
+ wishsuiteConditionField( WishSuite.option_data['btn_icon_type'], 'custom', '.button_custom_icon' );
11
+ wishsuiteConditionField( WishSuite.option_data['added_btn_icon_type'], 'custom', '.addedbutton_custom_icon' );
12
+ wishsuiteConditionField( WishSuite.option_data['shop_btn_position'], 'use_shortcode', '.depend_shop_btn_position_use_shortcode' );
13
+ wishsuiteConditionField( WishSuite.option_data['shop_btn_position'], 'custom_position', '.depend_shop_btn_position_custom_hook' );
14
+ wishsuiteConditionField( WishSuite.option_data['product_btn_position'], 'use_shortcode', '.depend_product_btn_position_use_shortcode' );
15
+ wishsuiteConditionField( WishSuite.option_data['product_btn_position'], 'custom_position', '.depend_product_btn_position_custom_hook' );
16
+ wishsuiteConditionField( WishSuite.option_data['button_style'], 'custom', '.button_custom_style' );
17
+ wishsuiteConditionField( WishSuite.option_data['table_style'], 'custom', '.table_custom_style' );
18
+ wishsuiteConditionField( WishSuite.option_data['enable_social_share'], 'on', '.depend_social_share_enable' );
19
+ wishsuiteConditionField( WishSuite.option_data['enable_login_limit'], 'on', '.depend_user_login_enable' );
20
+
21
+ // After Select field change Condition Field
22
+ wishsuiteChangeField( '.button_icon_type select', '.button_custom_icon', 'custom' );
23
+ wishsuiteChangeField( '.addedbutton_icon_type select', '.addedbutton_custom_icon', 'custom' );
24
+ wishsuiteChangeField( '.shop_btn_position select', '.depend_shop_btn_position_use_shortcode', 'use_shortcode' );
25
+ wishsuiteChangeField( '.shop_btn_position select', '.depend_shop_btn_position_custom_hook', 'custom_position' );
26
+ wishsuiteChangeField( '.product_btn_position select', '.depend_product_btn_position_use_shortcode', 'use_shortcode' );
27
+ wishsuiteChangeField( '.product_btn_position select', '.depend_product_btn_position_custom_hook', 'custom_position' );
28
+ wishsuiteChangeField( '.button_style select', '.button_custom_style', 'custom' );
29
+ wishsuiteChangeField( '.table_style select', '.table_custom_style', 'custom' );
30
+ wishsuiteChangeField( '.enable_social_share .checkbox', '.depend_social_share_enable', 'on', 'radio' );
31
+ wishsuiteChangeField( '.enable_login_limit .checkbox', '.depend_user_login_enable', 'on', 'radio' );
32
+
33
+ function wishsuiteChangeField( filedselector, selector, condition_value, fieldtype = 'select' ){
34
+ $(filedselector).on('change',function(){
35
+ var change_value = '';
36
+
37
+ if( fieldtype === 'radio' ){
38
+ if( $(this).is(":checked") ){
39
+ change_value = $(this).val();
40
+ }
41
+ }else{
42
+ change_value = $(this).val();
43
+ }
44
+
45
+ wishsuiteConditionField( change_value, condition_value, selector );
46
+ });
47
+ }
48
+
49
+ // Hide || Show
50
+ function wishsuiteConditionField( value, condition_value, selector ){
51
+ if( value === condition_value ){
52
+ $(selector).show();
53
+ }else{
54
+ $(selector).hide();
55
+ }
56
+ }
57
+
58
+ })(jQuery);
includes/modules/wishlist/assets/js/frontend.js ADDED
@@ -0,0 +1,313 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ;(function($){
2
+ "use strict";
3
+
4
+ var $body = $('body');
5
+
6
+ // Add product in wishlist table
7
+ if( 'on' !== WishSuite.option_data['btn_limit_login_off'] ){
8
+ $body.on('click', 'a.wishsuite-btn', function (e) {
9
+ var $this = $(this),
10
+ id = $this.data('product_id'),
11
+ addedText = $this.data('added-text');
12
+
13
+ e.preventDefault();
14
+
15
+ $this.addClass('loading');
16
+
17
+ $.ajax({
18
+ url: WishSuite.ajaxurl,
19
+ data: {
20
+ action: 'wishsuite_add_to_list',
21
+ id: id,
22
+ },
23
+ dataType: 'json',
24
+ method: 'GET',
25
+ success: function ( response ) {
26
+ if ( response ) {
27
+ $this.removeClass('wishsuite-btn');
28
+ $this.removeClass('loading').addClass('added');
29
+ $this.html( addedText );
30
+ } else {
31
+ console.log( 'Something wrong loading compare data' );
32
+ }
33
+ },
34
+ error: function ( response ) {
35
+ console.log('Something wrong with AJAX response.', response );
36
+ },
37
+ complete: function () {
38
+ $this.removeClass('wishsuite-btn');
39
+ $this.removeClass('loading').addClass('added');
40
+ $this.html( addedText );
41
+ },
42
+ });
43
+
44
+ });
45
+ }
46
+
47
+ // Remove data from wishlist table
48
+ $body.on('click', 'a.wishsuite-remove', function (e) {
49
+ var $table = $('.wishsuite-table-content');
50
+
51
+ e.preventDefault();
52
+ var $this = $(this),
53
+ id = $this.data('product_id');
54
+
55
+ $table.addClass('loading');
56
+ $this.addClass('loading');
57
+
58
+ $.ajax({
59
+ url: WishSuite.ajaxurl,
60
+ data: {
61
+ action: 'wishsuite_remove_from_list',
62
+ id: id,
63
+ },
64
+ dataType: 'json',
65
+ method: 'GET',
66
+ success: function (response) {
67
+ if ( response ) {
68
+
69
+ var target_row = $this.closest('tr');
70
+ target_row.hide(400, function() {
71
+ $(this).remove();
72
+ var table_row = $('.wishsuite-table-content table tbody tr').length;
73
+ if( table_row == 1 ){
74
+ $('.wishsuite-table-content table tbody tr.wishsuite-empty-tr').show();
75
+ }
76
+ });
77
+
78
+ } else {
79
+ console.log( 'Something wrong loading compare data' );
80
+ }
81
+ },
82
+ error: function (data) {
83
+ console.log('Something wrong with AJAX response.');
84
+ },
85
+ complete: function () {
86
+ $table.removeClass('loading');
87
+ $this.addClass('loading');
88
+ },
89
+ });
90
+
91
+ });
92
+
93
+ // Quentity
94
+ $("div.wishsuite-table-content").on("change", "input.qty", function() {
95
+ $(this).closest('tr').find( "[data-quantity]" ).attr( "data-quantity", this.value );
96
+ });
97
+
98
+ // Delete table row after added to cart
99
+ $(document).on('added_to_cart',function( e, fragments, carthash, button ){
100
+ if( 'on' === WishSuite.option_data['after_added_to_cart'] ){
101
+
102
+ var target_row = button.closest('.wishsuite_table tr');
103
+ target_row.find('.added_to_cart').remove();
104
+
105
+ target_row.hide(400, function() {
106
+ $(this).remove();
107
+ var table_row = $('.wishsuite-table-content table tbody tr').length;
108
+ if( table_row == 1 ){
109
+ $('.wishsuite-table-content table tbody tr.wishsuite-empty-tr').show();
110
+ }
111
+ });
112
+
113
+ }
114
+ });
115
+
116
+ /**
117
+ * Variation Product Add to cart from wishsuite page
118
+ */
119
+ $(document).on( 'click', '.wishsuite_table .product_type_variable.add_to_cart_button', function (e) {
120
+ e.preventDefault();
121
+
122
+ var $this = $(this),
123
+ $product = $this.parents('.wishsuite-product-add_to_cart').first(),
124
+ $content = $product.find('.wishsuite-quick-cart-form'),
125
+ id = $this.data('product_id'),
126
+ btn_loading_class = 'loading';
127
+
128
+ if ($this.hasClass(btn_loading_class)) return;
129
+
130
+ // Show Form
131
+ if ( $product.hasClass('quick-cart-loaded') ) {
132
+ $product.addClass('quick-cart-open');
133
+ return;
134
+ }
135
+
136
+ var data = {
137
+ action: 'wishsuite_quick_variation_form',
138
+ id: id
139
+ };
140
+ $.ajax({
141
+ type: 'post',
142
+ url: WishSuite.ajaxurl,
143
+ data: data,
144
+ beforeSend: function (response) {
145
+ $this.addClass(btn_loading_class);
146
+ $product.addClass('loading-quick-cart');
147
+ },
148
+ success: function (response) {
149
+ $content.append( response );
150
+ wishsuite_render_variation_data( $product );
151
+ wishsuite_inser_to_cart();
152
+ },
153
+ complete: function (response) {
154
+ setTimeout(function () {
155
+ $this.removeClass(btn_loading_class);
156
+ $product.removeClass('loading-quick-cart');
157
+ $product.addClass('quick-cart-open quick-cart-loaded');
158
+ }, 100);
159
+ },
160
+ });
161
+
162
+ return false;
163
+
164
+ });
165
+
166
+ $(document).on('click', '.wishsuite-quick-cart-close', function () {
167
+ var $this = $(this),
168
+ $product = $this.parents('.wishsuite-product-add_to_cart');
169
+ $product.removeClass('quick-cart-open');
170
+ });
171
+
172
+ $(document.body).on('added_to_cart', function ( e, fragments, carthash, button ) {
173
+
174
+ var target_row = button.closest('tr');
175
+ target_row.find('.wishsuite-addtocart').addClass('added');
176
+ $('.wishsuite-product-add_to_cart').removeClass('quick-cart-open');
177
+
178
+ });
179
+
180
+ /**
181
+ * [wishsuite_render_variation_data] show variation data
182
+ * @param {[selector]} $product
183
+ * @return {[void]}
184
+ */
185
+ function wishsuite_render_variation_data( $product ) {
186
+ $product.find('.variations_form').wc_variation_form().find('.variations select:eq(0)').change();
187
+ $product.find('.variations_form').trigger('wc_variation_form');
188
+ }
189
+
190
+ /**
191
+ * [wishsuite_inser_to_cart] Add to cart
192
+ * @return {[void]}
193
+ */
194
+ function wishsuite_inser_to_cart(){
195
+
196
+ $(document).on( 'click', '.wishsuite-quick-cart-form .single_add_to_cart_button:not(.disabled)', function (e) {
197
+ e.preventDefault();
198
+
199
+ var $this = $(this),
200
+ $form = $this.closest('form.cart'),
201
+ product_qty = $form.find('input[name=quantity]').val() || 1,
202
+ product_id = $form.find('input[name=product_id]').val() || $this.val(),
203
+ variation_id = $form.find('input[name=variation_id]').val() || 0;
204
+
205
+ $this.addClass('loading');
206
+
207
+ /* For Variation product */
208
+ var item = {},
209
+ variations = $form.find( 'select[name^=attribute]' );
210
+ if ( !variations.length) {
211
+ variations = $form.find( '[name^=attribute]:checked' );
212
+ }
213
+ if ( !variations.length) {
214
+ variations = $form.find( 'input[name^=attribute]' );
215
+ }
216
+
217
+ variations.each( function() {
218
+ var $thisitem = $( this ),
219
+ attributeName = $thisitem.attr( 'name' ),
220
+ attributevalue = $thisitem.val(),
221
+ index,
222
+ attributeTaxName;
223
+ $thisitem.removeClass( 'error' );
224
+ if ( attributevalue.length === 0 ) {
225
+ index = attributeName.lastIndexOf( '_' );
226
+ attributeTaxName = attributeName.substring( index + 1 );
227
+ $thisitem.addClass( 'required error' );
228
+ } else {
229
+ item[attributeName] = attributevalue;
230
+ }
231
+ });
232
+
233
+ var data = {
234
+ action: 'wishsuite_insert_to_cart',
235
+ product_id: product_id,
236
+ product_sku: '',
237
+ quantity: product_qty,
238
+ variation_id: variation_id,
239
+ variations: item,
240
+ };
241
+
242
+ $( document.body ).trigger('adding_to_cart', [$this, data]);
243
+
244
+ $.ajax({
245
+ type: 'post',
246
+ url: WishSuite.ajaxurl,
247
+ data: data,
248
+
249
+ beforeSend: function (response) {
250
+ $this.removeClass('added').addClass('loading');
251
+ },
252
+
253
+ complete: function (response) {
254
+ $this.addClass('added').removeClass('loading');
255
+ },
256
+
257
+ success: function (response) {
258
+ if ( response.error & response.product_url ) {
259
+ window.location = response.product_url;
260
+ return;
261
+ } else {
262
+ $(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $this]);
263
+ }
264
+ },
265
+
266
+ });
267
+
268
+ return false;
269
+ });
270
+
271
+ }
272
+
273
+
274
+ var wishsuite_default_data = {
275
+ price_html:'',
276
+ image_html:'',
277
+ };
278
+ $(document).on('show_variation', '.wishsuite_table .variations_form', function ( alldata, attributes, status ) {
279
+
280
+ var target_row = alldata.target.closest('tr');
281
+
282
+ // Get First image data
283
+ if( typeof wishsuite_default_data.price_html !== 'undefined' && wishsuite_default_data.price_html.length === 0 ){
284
+ wishsuite_default_data.price_html = $(target_row).find('.wishsuite-product-price').html();
285
+ wishsuite_default_data.image_html = $(target_row).find('.wishsuite-product-image').html();
286
+ }
287
+
288
+ // Set variation data
289
+ $(target_row).find('.wishsuite-product-price').html( attributes.price_html );
290
+ wishsuite_variation_image_set( target_row, attributes.image );
291
+
292
+ // reset data
293
+ wishsuite_variation_data_reset( target_row, wishsuite_default_data );
294
+
295
+ });
296
+
297
+ // Reset data
298
+ function wishsuite_variation_data_reset( target_row, default_data ){
299
+ $( target_row ).find('.reset_variations').on('click', function(e){
300
+ $(target_row).find('.wishsuite-product-price').html( default_data.price_html );
301
+ $(target_row).find('.wishsuite-product-image').html( default_data.image_html );
302
+ });
303
+ }
304
+
305
+ // variation image set
306
+ function wishsuite_variation_image_set( target_row, image ){
307
+ $(target_row).find('.wishsuite-product-image img').wc_set_variation_attr('src',image.full_src);
308
+ $(target_row).find('.wishsuite-product-image img').wc_set_variation_attr('srcset',image.srcset);
309
+ $(target_row).find('.wishsuite-product-image img').wc_set_variation_attr('sizes',image.sizes);
310
+ }
311
+
312
+
313
+ })(jQuery);
includes/modules/wishlist/includes/classes/Admin.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite;
3
+
4
+ /**
5
+ * Admin handlers class
6
+ */
7
+ class Admin {
8
+
9
+ /**
10
+ * [$_instance]
11
+ * @var null
12
+ */
13
+ private static $_instance = null;
14
+
15
+ /**
16
+ * [instance] Initializes a singleton instance
17
+ * @return [Admin]
18
+ */
19
+ public static function instance() {
20
+ if ( is_null( self::$_instance ) ) {
21
+ self::$_instance = new self();
22
+ }
23
+ return self::$_instance;
24
+ }
25
+
26
+ /**
27
+ * Initialize the class
28
+ */
29
+ private function __construct() {
30
+ require_once( __DIR__. '/Admin/Dashboard.php' );
31
+ Admin\Dashboard::instance();
32
+ }
33
+
34
+ }
includes/modules/wishlist/includes/classes/Admin/Admin_Fields.php ADDED
@@ -0,0 +1,582 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite\Admin;
3
+ /**
4
+ * Admin Page Fields handlers class
5
+ */
6
+ class Admin_Fields {
7
+
8
+ private $settings_api;
9
+
10
+ /**
11
+ * [$_instance]
12
+ * @var null
13
+ */
14
+ private static $_instance = null;
15
+
16
+ /**
17
+ * [instance] Initializes a singleton instance
18
+ * @return [Admin]
19
+ */
20
+ public static function instance() {
21
+ if ( is_null( self::$_instance ) ) {
22
+ self::$_instance = new self();
23
+ }
24
+ return self::$_instance;
25
+ }
26
+
27
+ function __construct() {
28
+ require_once( WOOLENTOR_ADDONS_PL_PATH .'includes/admin/include/settings_field_manager_default.php' );
29
+ $this->settings_api = new \WooLentor_Settings_Field_Manager_Default();
30
+ add_action( 'admin_init', [ $this, 'admin_init' ] );
31
+ }
32
+
33
+ public function admin_init() {
34
+
35
+ //set the settings
36
+ $this->settings_api->set_sections( $this->get_settings_sections() );
37
+ $this->settings_api->set_fields( $this->fields_settings() );
38
+
39
+ //initialize settings
40
+ $this->settings_api->admin_init();
41
+ }
42
+
43
+ // Options page Section register
44
+ public function get_settings_sections() {
45
+ $sections = array(
46
+
47
+ array(
48
+ 'id' => 'wishsuite_general_tabs',
49
+ 'title' => esc_html__( 'General Settings', 'wishsuite' )
50
+ ),
51
+
52
+ array(
53
+ 'id' => 'wishsuite_settings_tabs',
54
+ 'title' => esc_html__( 'Button Settings', 'wishsuite' )
55
+ ),
56
+
57
+ array(
58
+ 'id' => 'wishsuite_table_settings_tabs',
59
+ 'title' => esc_html__( 'Table Settings', 'wishsuite' )
60
+ ),
61
+
62
+ array(
63
+ 'id' => 'wishsuite_style_settings_tabs',
64
+ 'title' => esc_html__( 'Style Settings', 'wishsuite' )
65
+ ),
66
+
67
+ );
68
+ return $sections;
69
+ }
70
+
71
+ // Options page field register
72
+ protected function fields_settings() {
73
+
74
+ $settings_fields = array(
75
+
76
+ 'wishsuite_general_tabs' => array(
77
+ array(
78
+ 'name' => 'enable_login_limit',
79
+ 'label' => __( 'Limit Wishlist Use', 'wishsuite' ),
80
+ 'type' => 'checkbox',
81
+ 'default' => 'off',
82
+ 'desc' => esc_html__( 'Enable this option to allow only the logged-in users to use the Wishlist feature.', 'wishsuite' ),
83
+ ),
84
+
85
+ array(
86
+ 'name' => 'logout_button',
87
+ 'label' => __( 'Wishlist Icon Tooltip Text', 'wishsuite' ),
88
+ 'desc' => __( 'Enter a text for the tooltip that will be shown when someone hover over the Wishlist icon.', 'wishsuite' ),
89
+ 'type' => 'text',
90
+ 'default' => __( 'Please login', 'wishsuite' ),
91
+ 'class' => 'depend_user_login_enable'
92
+ ),
93
+
94
+ ),
95
+
96
+ 'wishsuite_settings_tabs' => array(
97
+
98
+ array(
99
+ 'name' => 'btn_show_shoppage',
100
+ 'label' => __( 'Show button in product list', 'wishsuite' ),
101
+ 'type' => 'checkbox',
102
+ 'default' => 'off',
103
+ ),
104
+
105
+ array(
106
+ 'name' => 'btn_show_productpage',
107
+ 'label' => __( 'Show button in single product page', 'wishsuite' ),
108
+ 'type' => 'checkbox',
109
+ 'default' => 'on',
110
+ ),
111
+
112
+ array(
113
+ 'name' => 'shop_btn_position',
114
+ 'label' => __( 'Shop page button position', 'wishsuite' ),
115
+ 'desc' => __( 'You can manage wishlist button position in product list page.', 'wishsuite' ),
116
+ 'type' => 'select',
117
+ 'default' => 'after_cart_btn',
118
+ 'options' => [
119
+ 'before_cart_btn' => __( 'Before Add To Cart', 'wishsuite' ),
120
+ 'after_cart_btn' => __( 'After Add To Cart', 'wishsuite' ),
121
+ 'top_thumbnail' => __( 'Top On Image', 'wishsuite' ),
122
+ 'use_shortcode' => __( 'Use Shortcode', 'wishsuite' ),
123
+ 'custom_position' => __( 'Custom Position', 'wishsuite' ),
124
+ ],
125
+ ),
126
+
127
+ array(
128
+ 'name' => 'shop_use_shortcode_message',
129
+ 'headding'=> wp_kses_post('<code>[wishsuite_button]</code> Use this shortcode into your theme/child theme to place the wishlist button.'),
130
+ 'type' => 'title',
131
+ 'size' => 'margin_0 regular',
132
+ 'class' => 'depend_shop_btn_position_use_shortcode element_section_title_area message-info',
133
+ ),
134
+
135
+ array(
136
+ 'name' => 'shop_custom_hook_message',
137
+ 'headding'=> esc_html__( 'Some themes remove the above positions. In that case, custom position is useful. Here you can place the custom/default hook name & priority to inject & adjust the wishlist button for the product loop.', 'wishsuite' ),
138
+ 'type' => 'title',
139
+ 'size' => 'margin_0 regular',
140
+ 'class' => 'depend_shop_btn_position_custom_hook element_section_title_area message-info',
141
+ ),
142
+
143
+ array(
144
+ 'name' => 'shop_custom_hook_name',
145
+ 'label' => __( 'Hook name', 'wishsuite' ),
146
+ 'desc' => __( 'e.g: woocommerce_after_shop_loop_item_title', 'wishsuite' ),
147
+ 'type' => 'text',
148
+ 'class' => 'depend_shop_btn_position_custom_hook'
149
+ ),
150
+
151
+ array(
152
+ 'name' => 'shop_custom_hook_priority',
153
+ 'label' => __( 'Hook priority', 'wishsuite' ),
154
+ 'desc' => __( 'Default: 10', 'wishsuite' ),
155
+ 'type' => 'text',
156
+ 'class' => 'depend_shop_btn_position_custom_hook'
157
+ ),
158
+
159
+ array(
160
+ 'name' => 'product_btn_position',
161
+ 'label' => __( 'Product page button position', 'wishsuite' ),
162
+ 'desc' => __( 'You can manage wishlist button position in single product page.', 'wishsuite' ),
163
+ 'type' => 'select',
164
+ 'default' => 'after_cart_btn',
165
+ 'options' => [
166
+ 'before_cart_btn' => __( 'Before Add To Cart', 'wishsuite' ),
167
+ 'after_cart_btn' => __( 'After Add To Cart', 'wishsuite' ),
168
+ 'after_thumbnail' => __( 'After Image', 'wishsuite' ),
169
+ 'after_summary' => __( 'After Summary', 'wishsuite' ),
170
+ 'use_shortcode' => __( 'Use Shortcode', 'wishsuite' ),
171
+ 'custom_position' => __( 'Custom Position', 'wishsuite' ),
172
+ ],
173
+ ),
174
+
175
+ array(
176
+ 'name' => 'product_use_shortcode_message',
177
+ 'headding'=> wp_kses_post('<code>[wishsuite_button]</code> Use this shortcode into your theme/child theme to place the wishlist button.'),
178
+ 'type' => 'title',
179
+ 'size' => 'margin_0 regular',
180
+ 'class' => 'depend_product_btn_position_use_shortcode element_section_title_area message-info',
181
+ ),
182
+
183
+ array(
184
+ 'name' => 'product_custom_hook_message',
185
+ 'headding'=> esc_html__( 'Some themes remove the above positions. In that case, custom position is useful. Here you can place the custom/default hook name & priority to inject & adjust the wishlist button for the single product page.', 'wishsuite' ),
186
+ 'type' => 'title',
187
+ 'size' => 'margin_0 regular',
188
+ 'class' => 'depend_product_btn_position_custom_hook element_section_title_area message-info',
189
+ ),
190
+
191
+ array(
192
+ 'name' => 'product_custom_hook_name',
193
+ 'label' => __( 'Hook name', 'wishsuite' ),
194
+ 'desc' => __( 'e.g: woocommerce_after_single_product_summary', 'wishsuite' ),
195
+ 'type' => 'text',
196
+ 'class' => 'depend_product_btn_position_custom_hook'
197
+ ),
198
+
199
+ array(
200
+ 'name' => 'product_custom_hook_priority',
201
+ 'label' => __( 'Hook priority', 'wishsuite' ),
202
+ 'desc' => __( 'Default: 10', 'wishsuite' ),
203
+ 'type' => 'text',
204
+ 'class' => 'depend_product_btn_position_custom_hook'
205
+ ),
206
+
207
+ array(
208
+ 'name' => 'button_text',
209
+ 'label' => __( 'Button Text', 'wishsuite' ),
210
+ 'desc' => __( 'Enter your wishlist button text.', 'wishsuite' ),
211
+ 'type' => 'text',
212
+ 'default' => __( 'Wishlist', 'wishsuite' ),
213
+ 'placeholder' => __( 'Wishlist', 'wishsuite' ),
214
+ ),
215
+
216
+ array(
217
+ 'name' => 'added_button_text',
218
+ 'label' => __( 'Product added text', 'wishsuite' ),
219
+ 'desc' => __( 'Enter the product added text.', 'wishsuite' ),
220
+ 'type' => 'text',
221
+ 'default' => __( 'Product Added', 'wishsuite' ),
222
+ 'placeholder' => __( 'Product Added', 'wishsuite' ),
223
+ ),
224
+
225
+ array(
226
+ 'name' => 'exist_button_text',
227
+ 'label' => __( 'Already exists in the wishlist text', 'wishsuite' ),
228
+ 'desc' => wp_kses_post( 'Enter the message for "<strong>already exists in the wishlist</strong>" text.' ),
229
+ 'type' => 'text',
230
+ 'default' => __( 'Product already added', 'wishsuite' ),
231
+ 'placeholder' => __( 'Product already added', 'wishsuite' ),
232
+ ),
233
+
234
+ ),
235
+
236
+ 'wishsuite_table_settings_tabs' => array(
237
+
238
+ array(
239
+ 'name' => 'wishlist_page',
240
+ 'label' => __( 'Wishlist page', 'wishsuite' ),
241
+ 'type' => 'select',
242
+ 'default' => '0',
243
+ 'options' => wishsuite_get_post_list(),
244
+ 'desc' => wp_kses_post('Select a wishlist page for wishlist table. It should contain the shortcode <code>[wishsuite_table]</code>'),
245
+ ),
246
+
247
+ array(
248
+ 'name' => 'after_added_to_cart',
249
+ 'label' => __( 'Remove from the "Wishlist" after adding to the cart.', 'wishsuite' ),
250
+ 'type' => 'checkbox',
251
+ 'default' => 'on',
252
+ ),
253
+
254
+ array(
255
+ 'name' => 'show_fields',
256
+ 'label' => __('Show fields in table', 'wishsuite'),
257
+ 'desc' => __('Choose which fields should be presented on the product compare page with table.', 'wishsuite'),
258
+ 'type' => 'multicheckshort',
259
+ 'options' => wishsuite_get_available_attributes(),
260
+ 'default' => [
261
+ 'remove' => esc_html__( 'Remove', 'wishsuite' ),
262
+ 'image' => esc_html__( 'Image', 'wishsuite' ),
263
+ 'title' => esc_html__( 'Title', 'wishsuite' ),
264
+ 'price' => esc_html__( 'Price', 'wishsuite' ),
265
+ 'quantity' => esc_html__( 'Quantity', 'wishsuite' ),
266
+ 'add_to_cart' => esc_html__( 'Add To Cart', 'wishsuite' ),
267
+ ],
268
+ ),
269
+
270
+ array(
271
+ 'name' => 'table_heading',
272
+ 'label' => __( 'Table heading text', 'wishsuite' ),
273
+ 'desc' => __( 'You can change table heading text from here.', 'wishsuite' ),
274
+ 'type' => 'multitext',
275
+ 'options' => wishsuite_table_heading()
276
+ ),
277
+
278
+ array(
279
+ 'name' => 'empty_table_text',
280
+ 'label' => __('Empty table text', 'wishsuite'),
281
+ 'desc' => __('Text will be displayed if the user doesn\'t add any product to the wishlist.', 'wishsuite'),
282
+ 'type' => 'textarea'
283
+ ),
284
+
285
+ array(
286
+ 'name' => 'image_size',
287
+ 'label' => __( 'Image size', 'wishsuite' ),
288
+ 'desc' => __( 'Enter your required image size.', 'wishsuite' ),
289
+ 'type' => 'multitext',
290
+ 'options' =>[
291
+ 'width' => esc_html__( 'Width', 'wishsuite' ),
292
+ 'height' => esc_html__( 'Height', 'wishsuite' ),
293
+ ],
294
+ 'default' => [
295
+ 'width' => 80,
296
+ 'height' => 80,
297
+ ],
298
+ ),
299
+
300
+ array(
301
+ 'name' => 'hard_crop',
302
+ 'label' => __( 'Image Hard Crop', 'wishsuite' ),
303
+ 'type' => 'checkbox',
304
+ 'default' => 'on',
305
+ ),
306
+
307
+ array(
308
+ 'name' => 'social_share_button_area_title',
309
+ 'headding'=> esc_html__( 'Social share button', 'wishsuite' ),
310
+ 'type' => 'title',
311
+ 'size' => 'margin_0 regular',
312
+ 'class' => 'element_section_title_area',
313
+ ),
314
+
315
+ array(
316
+ 'name' => 'enable_social_share',
317
+ 'label' => esc_html__( 'Enable social share button', 'wishsuite' ),
318
+ 'type' => 'checkbox',
319
+ 'default' => 'on',
320
+ 'desc' => esc_html__( 'Enable social share button.', 'wishsuite' ),
321
+ ),
322
+
323
+ array(
324
+ 'name' => 'social_share_button_title',
325
+ 'label' => esc_html__( 'Social share button title', 'wishsuite' ),
326
+ 'desc' => esc_html__( 'Enter your social share button title.', 'wishsuite' ),
327
+ 'type' => 'text',
328
+ 'default' => esc_html__( 'Share:', 'wishsuite' ),
329
+ 'placeholder' => esc_html__( 'Share', 'wishsuite' ),
330
+ 'class' => 'depend_social_share_enable'
331
+ ),
332
+
333
+ array(
334
+ 'name' => 'social_share_buttons',
335
+ 'label' => esc_html__('Enable share buttons', 'wishsuite'),
336
+ 'desc' => esc_html__( 'You can manage your social share buttons.', 'wishsuite' ),
337
+ 'type' => 'multicheckshort',
338
+ 'options' => [
339
+ 'facebook' => esc_html__( 'Facebook', 'wishsuite' ),
340
+ 'twitter' => esc_html__( 'Twitter', 'wishsuite' ),
341
+ 'pinterest' => esc_html__( 'Pinterest', 'wishsuite' ),
342
+ 'linkedin' => esc_html__( 'Linkedin', 'wishsuite' ),
343
+ 'email' => esc_html__( 'Email', 'wishsuite' ),
344
+ 'reddit' => esc_html__( 'Reddit', 'wishsuite' ),
345
+ 'telegram' => esc_html__( 'Telegram', 'wishsuite' ),
346
+ 'odnoklassniki' => esc_html__( 'Odnoklassniki', 'wishsuite' ),
347
+ 'whatsapp' => esc_html__( 'WhatsApp', 'wishsuite' ),
348
+ 'vk' => esc_html__( 'VK', 'wishsuite' ),
349
+ ],
350
+ 'default' => [
351
+ 'facebook' => esc_html__( 'Facebook', 'wishsuite' ),
352
+ 'twitter' => esc_html__( 'Twitter', 'wishsuite' ),
353
+ 'pinterest' => esc_html__( 'Pinterest', 'wishsuite' ),
354
+ 'linkedin' => esc_html__( 'Linkedin', 'wishsuite' ),
355
+ 'telegram' => esc_html__( 'Telegram', 'wishsuite' ),
356
+ ],
357
+ 'class' => 'depend_social_share_enable'
358
+ ),
359
+
360
+ ),
361
+
362
+ 'wishsuite_style_settings_tabs' => array(
363
+
364
+ array(
365
+ 'name' => 'button_style',
366
+ 'label' => __( 'Button style', 'wishsuite' ),
367
+ 'desc' => __( 'Choose a style for the wishlist button from here.', 'wishsuite' ),
368
+ 'type' => 'select',
369
+ 'default' => 'default',
370
+ 'options' => [
371
+ 'default' => esc_html__( 'Default style', 'wishsuite' ),
372
+ 'themestyle' => esc_html__( 'Theme style', 'wishsuite' ),
373
+ 'custom' => esc_html__( 'Custom style', 'wishsuite' ),
374
+ ]
375
+ ),
376
+
377
+ array(
378
+ 'name' => 'button_icon_type',
379
+ 'label' => __( 'Button icon type', 'wishsuite' ),
380
+ 'desc' => __( 'Choose an icon for the wishlist button from here.', 'wishsuite' ),
381
+ 'type' => 'select',
382
+ 'default' => 'default',
383
+ 'options' => [
384
+ 'none' => esc_html__( 'None', 'wishsuite' ),
385
+ 'default' => esc_html__( 'Default icon', 'wishsuite' ),
386
+ 'custom' => esc_html__( 'Custom icon', 'wishsuite' ),
387
+ ]
388
+ ),
389
+
390
+ array(
391
+ 'name' => 'button_custom_icon',
392
+ 'label' => __( 'Button custom icon', 'wishsuite' ),
393
+ 'type' => 'image_upload',
394
+ 'options' => [
395
+ 'button_label' => esc_html__( 'Upload', 'wishsuite' ),
396
+ 'button_remove_label' => esc_html__( 'Remove', 'wishsuite' ),
397
+ ],
398
+ ),
399
+
400
+ array(
401
+ 'name' => 'addedbutton_icon_type',
402
+ 'label' => __( 'Added Button icon type', 'wishsuite' ),
403
+ 'desc' => __( 'Choose an icon for the wishlist button from here.', 'wishsuite' ),
404
+ 'type' => 'select',
405
+ 'default' => 'default',
406
+ 'options' => [
407
+ 'none' => esc_html__( 'None', 'wishsuite' ),
408
+ 'default' => esc_html__( 'Default icon', 'wishsuite' ),
409
+ 'custom' => esc_html__( 'Custom icon', 'wishsuite' ),
410
+ ]
411
+ ),
412
+
413
+ array(
414
+ 'name' => 'addedbutton_custom_icon',
415
+ 'label' => __( 'Added Button custom icon', 'wishsuite' ),
416
+ 'type' => 'image_upload',
417
+ 'options' => [
418
+ 'button_label' => esc_html__( 'Upload', 'wishsuite' ),
419
+ 'button_remove_label' => esc_html__( 'Remove', 'wishsuite' ),
420
+ ],
421
+ ),
422
+
423
+ array(
424
+ 'name' => 'table_style',
425
+ 'label' => __( 'Table style', 'wishsuite' ),
426
+ 'desc' => __( 'Choose a style for the wishlist table here.', 'wishsuite' ),
427
+ 'type' => 'select',
428
+ 'default' => 'default',
429
+ 'options' => [
430
+ 'default' => esc_html__( 'Default style', 'wishsuite' ),
431
+ 'custom' => esc_html__( 'Custom style', 'wishsuite' ),
432
+ ]
433
+ ),
434
+
435
+ array(
436
+ 'name' => 'button_custom_style_title',
437
+ 'headding'=> __( 'Button custom style', 'wishsuite' ),
438
+ 'type' => 'title',
439
+ 'size' => 'margin_0 regular',
440
+ 'class' => 'button_custom_style element_section_title_area',
441
+ ),
442
+
443
+ array(
444
+ 'name' => 'button_color',
445
+ 'label' => esc_html__( 'Color', 'wishsuite' ),
446
+ 'desc' => wp_kses_post( 'Set the color of the button.', 'wishsuite' ),
447
+ 'type' => 'color',
448
+ 'class' => 'button_custom_style',
449
+ ),
450
+
451
+ array(
452
+ 'name' => 'button_hover_color',
453
+ 'label' => esc_html__( 'Hover Color', 'wishsuite' ),
454
+ 'desc' => wp_kses_post( 'Set the hover color of the button.', 'wishsuite' ),
455
+ 'type' => 'color',
456
+ 'class' => 'button_custom_style',
457
+ ),
458
+
459
+ array(
460
+ 'name' => 'background_color',
461
+ 'label' => esc_html__( 'Background Color', 'wishsuite' ),
462
+ 'desc' => wp_kses_post( 'Set the background color of the button.', 'wishsuite' ),
463
+ 'type' => 'color',
464
+ 'class' => 'button_custom_style',
465
+ ),
466
+
467
+ array(
468
+ 'name' => 'hover_background_color',
469
+ 'label' => esc_html__( 'Hover Background Color', 'wishsuite' ),
470
+ 'desc' => wp_kses_post( 'Set the hover background color of the button.', 'wishsuite' ),
471
+ 'type' => 'color',
472
+ 'class' => 'button_custom_style',
473
+ ),
474
+
475
+ array(
476
+ 'name' => 'button_custom_padding',
477
+ 'label' => __( 'Padding', 'wishsuite' ),
478
+ 'type' => 'dimensions',
479
+ 'options' => [
480
+ 'top' => esc_html__( 'Top', 'wishsuite' ),
481
+ 'right' => esc_html__( 'Right', 'wishsuite' ),
482
+ 'bottom'=> esc_html__( 'Bottom', 'wishsuite' ),
483
+ 'left' => esc_html__( 'Left', 'wishsuite' ),
484
+ 'unit' => esc_html__( 'Unit', 'wishsuite' ),
485
+ ],
486
+ 'class' => 'button_custom_style',
487
+ ),
488
+
489
+ array(
490
+ 'name' => 'button_custom_margin',
491
+ 'label' => __( 'Margin', 'wishsuite' ),
492
+ 'type' => 'dimensions',
493
+ 'options' => [
494
+ 'top' => esc_html__( 'Top', 'wishsuite' ),
495
+ 'right' => esc_html__( 'Right', 'wishsuite' ),
496
+ 'bottom'=> esc_html__( 'Bottom', 'wishsuite' ),
497
+ 'left' => esc_html__( 'Left', 'wishsuite' ),
498
+ 'unit' => esc_html__( 'Unit', 'wishsuite' ),
499
+ ],
500
+ 'class' => 'button_custom_style',
501
+ ),
502
+
503
+ array(
504
+ 'name' => 'button_custom_border_radius',
505
+ 'label' => __( 'Border Radius', 'wishsuite' ),
506
+ 'type' => 'dimensions',
507
+ 'options' => [
508
+ 'top' => esc_html__( 'Top', 'wishsuite' ),
509
+ 'right' => esc_html__( 'Right', 'wishsuite' ),
510
+ 'bottom'=> esc_html__( 'Bottom', 'wishsuite' ),
511
+ 'left' => esc_html__( 'Left', 'wishsuite' ),
512
+ 'unit' => esc_html__( 'Unit', 'wishsuite' ),
513
+ ],
514
+ 'class' => 'button_custom_style',
515
+ ),
516
+
517
+ array(
518
+ 'name' => 'table_custom_style_title',
519
+ 'headding'=> __( 'Table custom style', 'wishsuite' ),
520
+ 'type' => 'title',
521
+ 'size' => 'margin_0 regular',
522
+ 'class' => 'table_custom_style element_section_title_area',
523
+ ),
524
+
525
+ array(
526
+ 'name' => 'table_heading_color',
527
+ 'label' => esc_html__( 'Heading Color', 'wishsuite' ),
528
+ 'desc' => wp_kses_post( 'Set the heading color of the wishlist table.', 'wishsuite' ),
529
+ 'type' => 'color',
530
+ 'class' => 'table_custom_style',
531
+ ),
532
+
533
+ array(
534
+ 'name' => 'table_heading_bg_color',
535
+ 'label' => esc_html__( 'Heading Background Color', 'wishsuite' ),
536
+ 'desc' => wp_kses_post( 'Set the heading background color of the wishlist table.', 'wishsuite' ),
537
+ 'type' => 'color',
538
+ 'class' => 'table_custom_style',
539
+ ),
540
+ array(
541
+ 'name' => 'table_heading_border_color',
542
+ 'label' => esc_html__( 'Heading Border Color', 'wishsuite' ),
543
+ 'desc' => wp_kses_post( 'Set the heading border color of the wishlist table.', 'wishsuite' ),
544
+ 'type' => 'color',
545
+ 'class' => 'table_custom_style',
546
+ ),
547
+
548
+ array(
549
+ 'name' => 'table_border_color',
550
+ 'label' => esc_html__( 'Border Color', 'wishsuite' ),
551
+ 'desc' => wp_kses_post( 'Set the border color of the wishlist table.', 'wishsuite' ),
552
+ 'type' => 'color',
553
+ 'class' => 'table_custom_style',
554
+ ),
555
+
556
+ ),
557
+
558
+ );
559
+
560
+ return $settings_fields;
561
+ }
562
+
563
+ public function plugin_page() {
564
+ echo '<div class="wrap">';
565
+ echo '<h2>'.esc_html__( 'WishSuite Settings','wishsuite' ).'</h2>';
566
+ $this->save_message();
567
+ $this->settings_api->show_navigation();
568
+ $this->settings_api->show_forms();
569
+ echo '</div>';
570
+ }
571
+
572
+ public function save_message() {
573
+ if( isset( $_GET['settings-updated'] ) ) {
574
+ ?>
575
+ <div class="updated notice is-dismissible">
576
+ <p><strong><?php esc_html_e('Successfully Settings Saved.', 'wishsuite') ?></strong></p>
577
+ </div>
578
+ <?php
579
+ }
580
+ }
581
+
582
+ }
includes/modules/wishlist/includes/classes/Admin/Dashboard.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite\Admin;
3
+ /**
4
+ * Dashboard handlers class
5
+ */
6
+ class Dashboard {
7
+
8
+ /**
9
+ * Menu capability
10
+ */
11
+ const MENU_CAPABILITY = 'manage_options';
12
+
13
+ /**
14
+ * Parent Menu Page Slug
15
+ */
16
+ const MENU_PAGE_SLUG = 'wishsuite';
17
+
18
+ /**
19
+ * [$admin_menu_hook] Parent Menu Hook
20
+ * @var string
21
+ */
22
+ static $admin_menu_hook = '';
23
+
24
+
25
+ /**
26
+ * [$_instance]
27
+ * @var null
28
+ */
29
+ private static $_instance = null;
30
+
31
+ /**
32
+ * [instance] Initializes a singleton instance
33
+ * @return [Admin]
34
+ */
35
+ public static function instance() {
36
+ if ( is_null( self::$_instance ) ) {
37
+ self::$_instance = new self();
38
+ }
39
+ return self::$_instance;
40
+ }
41
+
42
+ /**
43
+ * Initialize the class
44
+ */
45
+ private function __construct() {
46
+
47
+ require_once( __DIR__. '/Admin_Fields.php' );
48
+
49
+ Admin_Fields::instance();
50
+
51
+ add_action( 'admin_menu', [ $this, 'add_menu' ], 220 );
52
+
53
+ // Add a post display state for special WishSuite page.
54
+ add_filter( 'display_post_states', [ $this, 'add_display_post_states' ], 10, 2 );
55
+
56
+ }
57
+
58
+ /**
59
+ * [add_menu] Admin Menu
60
+ */
61
+ public function add_menu(){
62
+
63
+ self::$admin_menu_hook = add_submenu_page(
64
+ 'woolentor_page',
65
+ esc_html__( 'Wishlist', 'woolentor' ),
66
+ esc_html__( 'Wishlist', 'woolentor' ),
67
+ 'manage_options',
68
+ self::MENU_PAGE_SLUG,
69
+ [ $this,'dashboard' ],
70
+ );
71
+
72
+ add_action( 'load-' . self::$admin_menu_hook, [ $this, 'init_hooks'] );
73
+
74
+
75
+ }
76
+
77
+ /**
78
+ * Initialize our hooks for the admin page
79
+ *
80
+ * @return void
81
+ */
82
+ public function init_hooks() {
83
+ add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_scripts' ] );
84
+ }
85
+
86
+ /**
87
+ * [enqueue_scripts] Add Scripts Base Menu Slug
88
+ * @param [string] $hook
89
+ * @return [void]
90
+ */
91
+ public function enqueue_scripts() {
92
+ wp_enqueue_style( 'wishsuite-admin' );
93
+ wp_enqueue_script( 'wishsuite-admin' );
94
+ }
95
+
96
+ /**
97
+ * [dashboard] Dashboard plugin page
98
+ * @return [HTML]
99
+ */
100
+ public function dashboard(){
101
+ Admin_Fields::instance()->plugin_page();
102
+ }
103
+
104
+ /**
105
+ * Add a post display state for special WishSuite page in the page list table.
106
+ *
107
+ * @param array $post_states An array of post display states.
108
+ * @param WP_Post $post The current post object.
109
+ */
110
+ public function add_display_post_states( $post_states, $post ){
111
+ if ( (int)woolentor_get_option( 'wishlist_page', 'wishsuite_table_settings_tabs' ) === $post->ID ) {
112
+ $post_states['wishsuite_page_for_wishlist_table'] = __( 'WishSuite', 'wishsuite' );
113
+ }
114
+ return $post_states;
115
+ }
116
+
117
+
118
+ }
includes/modules/wishlist/includes/classes/Admin/Settings_Api.php ADDED
@@ -0,0 +1,792 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite\Admin;
3
+ /**
4
+ * Settings Api class
5
+ */
6
+ class Settings_Api {
7
+
8
+ /**
9
+ * settings sections array
10
+ *
11
+ * @var array
12
+ */
13
+ protected $settings_sections = array();
14
+
15
+ /**
16
+ * Settings fields array
17
+ *
18
+ * @var array
19
+ */
20
+ protected $settings_fields = array();
21
+
22
+ public function __construct() {
23
+ add_action( 'admin_enqueue_scripts', [ $this, 'admin_enqueue_scripts' ] );
24
+ }
25
+
26
+ /**
27
+ * Enqueue scripts and styles
28
+ */
29
+ function admin_enqueue_scripts() {
30
+ wp_enqueue_style( 'wp-color-picker' );
31
+ wp_enqueue_media();
32
+ wp_enqueue_script( 'wp-color-picker' );
33
+ wp_enqueue_script( 'jquery-ui-sortable' );
34
+ wp_enqueue_script( 'jquery' );
35
+ }
36
+
37
+ /**
38
+ * Set settings sections
39
+ *
40
+ * @param array $sections setting sections array
41
+ */
42
+ function set_sections( $sections ) {
43
+ $this->settings_sections = $sections;
44
+
45
+ return $this;
46
+ }
47
+
48
+ /**
49
+ * Add a single section
50
+ *
51
+ * @param array $section
52
+ */
53
+ function add_section( $section ) {
54
+ $this->settings_sections[] = $section;
55
+
56
+ return $this;
57
+ }
58
+
59
+ /**
60
+ * Set settings fields
61
+ *
62
+ * @param array $fields settings fields array
63
+ */
64
+ function set_fields( $fields ) {
65
+ $this->settings_fields = $fields;
66
+
67
+ return $this;
68
+ }
69
+
70
+ function add_field( $section, $field ) {
71
+ $defaults = array(
72
+ 'name' => '',
73
+ 'label' => '',
74
+ 'desc' => '',
75
+ 'type' => 'text'
76
+ );
77
+
78
+ $arg = wp_parse_args( $field, $defaults );
79
+ $this->settings_fields[$section][] = $arg;
80
+
81
+ return $this;
82
+ }
83
+
84
+ /**
85
+ * Initialize and registers the settings sections and fileds to WordPress
86
+ *
87
+ * Usually this should be called at `admin_init` hook.
88
+ *
89
+ * This function gets the initiated settings sections and fields. Then
90
+ * registers them to WordPress and ready for use.
91
+ */
92
+ function admin_init() {
93
+
94
+ //register settings sections
95
+ foreach ( $this->settings_sections as $section ) {
96
+ if ( false == get_option( $section['id'] ) ) {
97
+ add_option( $section['id'] );
98
+ }
99
+
100
+ if ( isset($section['desc']) && !empty($section['desc']) ) {
101
+ $section['desc'] = '<div class="inside">' . $section['desc'] . '</div>';
102
+ $callback = function() use ( $section ) { echo str_replace( '"', '\"', $section['desc'] ); };
103
+ } else if ( isset( $section['callback'] ) ) {
104
+ $callback = $section['callback'];
105
+ } else {
106
+ $callback = null;
107
+ }
108
+
109
+ add_settings_section( $section['id'], $section['title'], $callback, $section['id'] );
110
+ }
111
+
112
+ //register settings fields
113
+ foreach ( $this->settings_fields as $section => $field ) {
114
+ foreach ( $field as $option ) {
115
+
116
+ $name = $option['name'];
117
+ $type = isset( $option['type'] ) ? $option['type'] : 'text';
118
+ $label = isset( $option['label'] ) ? $option['label'] : '';
119
+ $callback = isset( $option['callback'] ) ? $option['callback'] : array( $this, 'callback_' . $type );
120
+
121
+ $args = array(
122
+ 'id' => $name,
123
+ 'class' => isset( $option['class'] ) ? $option['class'] : $name,
124
+ 'label_for' => "{$section}[{$name}]",
125
+ 'desc' => isset( $option['desc'] ) ? $option['desc'] : '',
126
+ 'name' => $label,
127
+ 'section' => $section,
128
+ 'size' => isset( $option['size'] ) ? $option['size'] : null,
129
+ 'options' => isset( $option['options'] ) ? $option['options'] : '',
130
+ 'std' => isset( $option['default'] ) ? $option['default'] : '',
131
+ 'sanitize_callback' => isset( $option['sanitize_callback'] ) ? $option['sanitize_callback'] : '',
132
+ 'type' => $type,
133
+ 'placeholder' => isset( $option['placeholder'] ) ? $option['placeholder'] : '',
134
+ 'min' => isset( $option['min'] ) ? $option['min'] : '',
135
+ 'max' => isset( $option['max'] ) ? $option['max'] : '',
136
+ 'step' => isset( $option['step'] ) ? $option['step'] : '',
137
+ 'headding' => isset( $option['headding'] ) ? $option['headding'] : '',
138
+ );
139
+
140
+ add_settings_field( "{$section}[{$name}]", $label, $callback, $section, $section, $args );
141
+
142
+ }
143
+ }
144
+
145
+ // creates our settings in the options table
146
+ foreach ( $this->settings_sections as $section ) {
147
+ register_setting( $section['id'], $section['id'], array( $this, 'sanitize_options' ) );
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Get field description for display
153
+ *
154
+ * @param array $args settings field args
155
+ */
156
+ public function get_field_description( $args ) {
157
+ if ( ! empty( $args['desc'] ) ) {
158
+ $desc = sprintf( '<p class="description">%s</p>', $args['desc'] );
159
+ } else {
160
+ $desc = '';
161
+ }
162
+ return $desc;
163
+ }
164
+
165
+ /**
166
+ * Get Title for display
167
+ *
168
+ * @param array $args settings field args
169
+ */
170
+ public function callback_title( $args ) {
171
+ $headding = isset( $args['headding'] ) ? $args['headding'] : '';
172
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
173
+ $html = sprintf( '<h2 class="element_section_title %1$s-title">%2$s</h2>', $size, $headding );
174
+ echo $html;
175
+ }
176
+
177
+ /**
178
+ * Displays a text field for a settings field
179
+ *
180
+ * @param array $args settings field args
181
+ */
182
+ function callback_text( $args ) {
183
+
184
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
185
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
186
+ $type = isset( $args['type'] ) ? $args['type'] : 'text';
187
+ $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="' . $args['placeholder'] . '"';
188
+
189
+ $html = sprintf( '<input type="%1$s" class="%2$s-text" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s"%6$s/>', $type, $size, $args['section'], $args['id'], $value, $placeholder );
190
+ $html .= $this->get_field_description( $args );
191
+
192
+ echo $html;
193
+ }
194
+
195
+ /**
196
+ * Displays a multitextbox for a settings field
197
+ *
198
+ * @param array $args settings field args
199
+ */
200
+ function callback_multitext( $args ) {
201
+
202
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
203
+ $html = '<fieldset>';
204
+ foreach ( $args['options'] as $key => $label ) {
205
+ $new_value = isset( $value[$key] ) ? $value[$key] : '';
206
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
207
+ $html .= sprintf( '<input type="text" class="multitextbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%4$s" />', $args['section'], $args['id'], $key, $new_value );
208
+ $html .= sprintf( ' %1$s</label><br>', $label );
209
+ }
210
+
211
+ $html .= $this->get_field_description( $args );
212
+ $html .= '</fieldset>';
213
+
214
+ echo $html;
215
+ }
216
+
217
+ /**
218
+ * Displays a url field for a settings field
219
+ *
220
+ * @param array $args settings field args
221
+ */
222
+ function callback_url( $args ) {
223
+ $this->callback_text( $args );
224
+ }
225
+
226
+ /**
227
+ * Displays a number field for a settings field
228
+ *
229
+ * @param array $args settings field args
230
+ */
231
+ function callback_number( $args ) {
232
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
233
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
234
+ $type = isset( $args['type'] ) ? $args['type'] : 'number';
235
+ $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="' . $args['placeholder'] . '"';
236
+ $min = ( $args['min'] == '' ) ? '' : ' min="' . $args['min'] . '"';
237
+ $max = ( $args['max'] == '' ) ? '' : ' max="' . $args['max'] . '"';
238
+ $step = ( $args['step'] == '' ) ? '' : ' step="' . $args['step'] . '"';
239
+
240
+ $html = sprintf( '<input type="%1$s" class="%2$s-number" id="%3$s[%4$s]" name="%3$s[%4$s]" value="%5$s"%6$s%7$s%8$s%9$s/>', $type, $size, $args['section'], $args['id'], $value, $placeholder, $min, $max, $step );
241
+ $html .= $this->get_field_description( $args );
242
+
243
+ echo $html;
244
+ }
245
+
246
+ /**
247
+ * Displays a checkbox for a settings field
248
+ *
249
+ * @param array $args settings field args
250
+ */
251
+ function callback_checkbox( $args ) {
252
+
253
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
254
+
255
+ $html = '<fieldset class="htoptions_element_checkbox">';
256
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="off" />', $args['section'], $args['id'] );
257
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="htoptions_sp_%1$s[%2$s]" name="%1$s[%2$s]" value="on" %3$s />', $args['section'], $args['id'], checked( $value, 'on', false ) );
258
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s]">%3$s</label>', $args['section'], $args['id'], $args['desc'] );
259
+ $html .= sprintf( '<div class="htoption_checkbox_desc" id="htoptions_sp_%1$s[%2$s]">%3$s</div>', $args['section'], $args['id'], $args['desc'] );
260
+ $html .= '</fieldset>';
261
+
262
+ echo $html;
263
+ }
264
+
265
+ /**
266
+ * Displays a multicheckbox for a settings field
267
+ *
268
+ * @param array $args settings field args
269
+ */
270
+ function callback_multicheck( $args ) {
271
+
272
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
273
+ $html = '<fieldset>';
274
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="" />', $args['section'], $args['id'] );
275
+ foreach ( $args['options'] as $key => $label ) {
276
+ $checked = isset( $value[$key] ) ? $value[$key] : '0';
277
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
278
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $checked, $key, false ) );
279
+ $html .= sprintf( '%1$s</label><br>', $label );
280
+ }
281
+
282
+ $html .= $this->get_field_description( $args );
283
+ $html .= '</fieldset>';
284
+
285
+ echo $html;
286
+ }
287
+
288
+ /**
289
+ * Displays a multicheckbox for a settings field
290
+ *
291
+ * @param array $args settings field args
292
+ */
293
+ function callback_multicheckshort( $args ) {
294
+
295
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
296
+
297
+ $field_options = array_merge( $value, $args['options'] );
298
+
299
+ $html = '<fieldset><input type="checkbox" class="htoption-shortable-checkall">'.esc_html__( 'Check All', 'htoptions' ).'<ul class="htoption_shortable">';
300
+ $html .= sprintf( '<input type="hidden" name="%1$s[%2$s]" value="" />', $args['section'], $args['id'] );
301
+
302
+ foreach ( $field_options as $key => $label ) {
303
+ $checked = array_key_exists( $key, $value ) ? $key : '0';
304
+ $html .= sprintf( '<li><label for="htoptions_sp_%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
305
+ $html .= sprintf( '<input type="checkbox" class="checkbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $checked, $key, false ) );
306
+ $html .= sprintf( '%1$s</label></li>', $label );
307
+ }
308
+
309
+ $html .= '</ul>'.$this->get_field_description( $args ).'</fieldset>';
310
+
311
+ echo $html;
312
+ }
313
+
314
+ /**
315
+ * Displays a radio button for a settings field
316
+ *
317
+ * @param array $args settings field args
318
+ */
319
+ function callback_radio( $args ) {
320
+
321
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
322
+ $html = '<fieldset>';
323
+
324
+ foreach ( $args['options'] as $key => $label ) {
325
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">', $args['section'], $args['id'], $key );
326
+ $html .= sprintf( '<input type="radio" class="radio" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s]" value="%3$s" %4$s />', $args['section'], $args['id'], $key, checked( $value, $key, false ) );
327
+ $html .= sprintf( '%1$s</label><br>', $label );
328
+ }
329
+
330
+ $html .= $this->get_field_description( $args );
331
+ $html .= '</fieldset>';
332
+
333
+ echo $html;
334
+ }
335
+
336
+ /**
337
+ * Displays a selectbox for a settings field
338
+ *
339
+ * @param array $args settings field args
340
+ */
341
+ function callback_select( $args ) {
342
+
343
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
344
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
345
+ $html = sprintf( '<select class="%1$s" name="%2$s[%3$s]" id="%2$s[%3$s]">', $size, $args['section'], $args['id'] );
346
+
347
+ foreach ( $args['options'] as $key => $label ) {
348
+ $html .= sprintf( '<option value="%s"%s>%s</option>', $key, selected( $value, $key, false ), $label );
349
+ }
350
+
351
+ $html .= sprintf( '</select>' );
352
+ $html .= $this->get_field_description( $args );
353
+
354
+ echo $html;
355
+ }
356
+
357
+ /**
358
+ * Displays a multiselect for a settings field
359
+ *
360
+ * @param array $args settings field args
361
+ */
362
+ function callback_multiselect( $args ) {
363
+
364
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
365
+ $html = sprintf( '<select multiple="multiple" class="%1$s" name="%1$s[%2$s][]" id="%1$s[%2$s]">', $args['section'], $args['id'] );
366
+ foreach ( $args['options'] as $key => $label ) {
367
+ $selected = '';
368
+ if( !empty( $value ) ){
369
+ $selected = in_array( $key, $value ) ? $key : '';
370
+ }
371
+ $html .= sprintf( '<option value="%1$s" %2$s>%3$s</option>', $key, selected( $selected, $key, false ), $label );
372
+ }
373
+ $html .= sprintf( '</select>' );
374
+ $html .= $this->get_field_description( $args );
375
+
376
+ echo $html;
377
+ }
378
+
379
+ /**
380
+ * Displays a textarea for a settings field
381
+ *
382
+ * @param array $args settings field args
383
+ */
384
+ function callback_textarea( $args ) {
385
+
386
+ $value = esc_textarea( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
387
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
388
+ $placeholder = empty( $args['placeholder'] ) ? '' : ' placeholder="'.$args['placeholder'].'"';
389
+
390
+ $html = sprintf( '<textarea rows="5" cols="55" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]"%4$s>%5$s</textarea>', $size, $args['section'], $args['id'], $placeholder, $value );
391
+ $html .= $this->get_field_description( $args );
392
+
393
+ echo $html;
394
+ }
395
+
396
+ /**
397
+ * Displays the html for a settings field
398
+ *
399
+ * @param array $args settings field args
400
+ * @return string
401
+ */
402
+ function callback_html( $args ) {
403
+ echo $this->get_field_description( $args );
404
+ }
405
+
406
+ /**
407
+ * Displays a rich text textarea for a settings field
408
+ *
409
+ * @param array $args settings field args
410
+ */
411
+ function callback_wysiwyg( $args ) {
412
+
413
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
414
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : '500px';
415
+
416
+ echo '<div style="max-width: ' . $size . ';">';
417
+
418
+ $editor_settings = array(
419
+ 'teeny' => true,
420
+ 'textarea_name' => $args['section'] . '[' . $args['id'] . ']',
421
+ 'textarea_rows' => 10
422
+ );
423
+
424
+ if ( isset( $args['options'] ) && is_array( $args['options'] ) ) {
425
+ $editor_settings = array_merge( $editor_settings, $args['options'] );
426
+ }
427
+
428
+ wp_editor( $value, $args['section'] . '-' . $args['id'], $editor_settings );
429
+
430
+ echo '</div>';
431
+
432
+ echo $this->get_field_description( $args );
433
+ }
434
+
435
+ /**
436
+ * Displays a file upload field for a settings field
437
+ *
438
+ * @param array $args settings field args
439
+ */
440
+ function callback_file( $args ) {
441
+
442
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
443
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
444
+ $id = $args['section'] . '[' . $args['id'] . ']';
445
+ $label = isset( $args['options']['button_label'] ) ? $args['options']['button_label'] : __( 'Choose File' );
446
+
447
+ $html = sprintf( '<input type="text" class="%1$s-text wpsa-url" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
448
+ $html .= '<input type="button" class="button wpsa-browse" value="' . $label . '" />';
449
+ $html .= $this->get_field_description( $args );
450
+
451
+ echo $html;
452
+ }
453
+
454
+ /**
455
+ * Displays a file upload field for a settings field
456
+ *
457
+ * @param array $args settings field args
458
+ */
459
+ function callback_image_upload( $args ) {
460
+
461
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
462
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
463
+ $id = $args['section'] . '[' . $args['id'] . ']';
464
+ $label = isset( $args['options']['button_label'] ) ? $args['options']['button_label'] : __( 'Choose File' );
465
+ $remove_label = isset( $args['options']['button_remove_label'] ) ? $args['options']['button_remove_label'] : __( 'Remove' );
466
+
467
+ $save_file = ( $value != '' ) ? '<img src="'.esc_url( $value ).'" alt="'.esc_attr__( $label, 'wishsuite' ).'">' : '';
468
+
469
+ $html = '<div class="wpsa_display">'.$save_file.'</div>';
470
+ $html .= sprintf( '<input type="hidden" class="%1$s-text wpsa-url" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
471
+ $html .= '<input type="button" class="button wpsa-browse" value="' . $label . '" />';
472
+ $html .= '<input type="button" class="button wpsa-remove" value="' . $remove_label . '" />';
473
+
474
+
475
+ $html .= $this->get_field_description( $args );
476
+
477
+ echo $html;
478
+ }
479
+
480
+ /**
481
+ * Displays a password field for a settings field
482
+ *
483
+ * @param array $args settings field args
484
+ */
485
+ function callback_password( $args ) {
486
+
487
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
488
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
489
+
490
+ $html = sprintf( '<input type="password" class="%1$s-text" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s"/>', $size, $args['section'], $args['id'], $value );
491
+ $html .= $this->get_field_description( $args );
492
+
493
+ echo $html;
494
+ }
495
+
496
+ /**
497
+ * Displays a color picker field for a settings field
498
+ *
499
+ * @param array $args settings field args
500
+ */
501
+ function callback_color( $args ) {
502
+
503
+ $value = esc_attr( $this->get_option( $args['id'], $args['section'], $args['std'] ) );
504
+ $size = isset( $args['size'] ) && !is_null( $args['size'] ) ? $args['size'] : 'regular';
505
+
506
+ $html = sprintf( '<input type="text" class="%1$s-text wp-color-picker-field" id="%2$s[%3$s]" name="%2$s[%3$s]" value="%4$s" data-default-color="%5$s" />', $size, $args['section'], $args['id'], $value, $args['std'] );
507
+ $html .= $this->get_field_description( $args );
508
+
509
+ echo $html;
510
+ }
511
+
512
+ /**
513
+ * Displays a DIMENSIONS for a settings field
514
+ *
515
+ * @param array $args settings field args
516
+ */
517
+ function callback_dimensions( $args ) {
518
+
519
+ $value = $this->get_option( $args['id'], $args['section'], $args['std'] );
520
+ $html = '<fieldset><ul class="htoption_dimensions">';
521
+ foreach ( $args['options'] as $key => $label ) {
522
+ $new_value = isset( $value[$key] ) ? $value[$key] : '';
523
+ $html .= '<li>';
524
+
525
+ if( 'unit' === $key ){
526
+ $html .= sprintf( '<input type="text" class="dimensionsbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%4$s" />', $args['section'], $args['id'], $key, $new_value );
527
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">%4$s</label>', $args['section'], $args['id'], $key, $label );
528
+ }else{
529
+ $html .= sprintf( '<input type="number" class="dimensionsbox" id="htoptions_sp_%1$s[%2$s][%3$s]" name="%1$s[%2$s][%3$s]" value="%4$s" />', $args['section'], $args['id'], $key, $new_value );
530
+ $html .= sprintf( '<label for="htoptions_sp_%1$s[%2$s][%3$s]">%4$s</label>', $args['section'], $args['id'], $key, $label );
531
+ }
532
+
533
+ $html .= '</li>';
534
+ }
535
+
536
+ $html .= $this->get_field_description( $args );
537
+ $html .= '</ul></fieldset>';
538
+
539
+ echo $html;
540
+ }
541
+
542
+
543
+ /**
544
+ * Displays a select box for creating the pages select box
545
+ *
546
+ * @param array $args settings field args
547
+ */
548
+ function callback_pages( $args ) {
549
+
550
+ $dropdown_args = array(
551
+ 'selected' => esc_attr($this->get_option($args['id'], $args['section'], $args['std'] ) ),
552
+ 'name' => $args['section'] . '[' . $args['id'] . ']',
553
+ 'id' => $args['section'] . '[' . $args['id'] . ']',
554
+ 'echo' => 0
555
+ );
556
+ $html = wp_dropdown_pages( $dropdown_args );
557
+ echo $html;
558
+ }
559
+
560
+ /**
561
+ * Sanitize callback for Settings API
562
+ *
563
+ * @return mixed
564
+ */
565
+ function sanitize_options( $options ) {
566
+
567
+ if ( !$options ) {
568
+ return $options;
569
+ }
570
+
571
+ foreach( $options as $option_slug => $option_value ) {
572
+ $sanitize_callback = $this->get_sanitize_callback( $option_slug );
573
+
574
+ // If callback is set, call it
575
+ if ( $sanitize_callback ) {
576
+ $options[ $option_slug ] = call_user_func( $sanitize_callback, $option_value );
577
+ continue;
578
+ }
579
+ }
580
+
581
+ return $options;
582
+ }
583
+
584
+ /**
585
+ * Get sanitization callback for given option slug
586
+ *
587
+ * @param string $slug option slug
588
+ *
589
+ * @return mixed string or bool false
590
+ */
591
+ function get_sanitize_callback( $slug = '' ) {
592
+ if ( empty( $slug ) ) {
593
+ return false;
594
+ }
595
+
596
+ // Iterate over registered fields and see if we can find proper callback
597
+ foreach( $this->settings_fields as $section => $options ) {
598
+ foreach ( $options as $option ) {
599
+ if ( $option['name'] != $slug ) {
600
+ continue;
601
+ }
602
+
603
+ // Return the callback name
604
+ return isset( $option['sanitize_callback'] ) && is_callable( $option['sanitize_callback'] ) ? $option['sanitize_callback'] : false;
605
+ }
606
+ }
607
+
608
+ return false;
609
+ }
610
+
611
+ /**
612
+ * Get the value of a settings field
613
+ *
614
+ * @param string $option settings field name
615
+ * @param string $section the section name this field belongs to
616
+ * @param string $default default text if it's not found
617
+ * @return string
618
+ */
619
+ function get_option( $option, $section, $default = '' ) {
620
+
621
+ $options = get_option( $section );
622
+
623
+ if ( isset( $options[$option] ) ) {
624
+ return $options[$option];
625
+ }
626
+
627
+ return $default;
628
+ }
629
+
630
+ /**
631
+ * Show navigations as tab
632
+ *
633
+ * Shows all the settings section labels as tab
634
+ */
635
+ function show_navigation() {
636
+ $html = '<h2 class="nav-tab-wrapper">';
637
+
638
+ $count = count( $this->settings_sections );
639
+
640
+ // don't show the navigation if only one section exists
641
+ if ( $count === 1 ) {
642
+ return;
643
+ }
644
+
645
+ foreach ( $this->settings_sections as $tab ) {
646
+ $html .= sprintf( '<a href="#%1$s" class="nav-tab" id="%1$s-tab">%2$s</a>', $tab['id'], $tab['title'] );
647
+ }
648
+
649
+ $html .= '</h2>';
650
+
651
+ echo $html;
652
+ }
653
+
654
+ /**
655
+ * Show the section settings forms
656
+ *
657
+ * This function displays every sections in a different form
658
+ */
659
+ function show_forms() {
660
+ ?>
661
+ <div class="metabox-holder">
662
+ <?php foreach ( $this->settings_sections as $form ) { ?>
663
+ <div id="<?php echo $form['id']; ?>" class="group" style="display: none;">
664
+ <form method="post" action="options.php">
665
+ <?php
666
+ do_action( 'wsa_form_top_' . $form['id'], $form );
667
+ settings_fields( $form['id'] );
668
+ do_settings_sections( $form['id'] );
669
+ do_action( 'wsa_form_bottom_' . $form['id'], $form );
670
+ if ( isset( $this->settings_fields[ $form['id'] ] ) ):
671
+ ?>
672
+ <div class="wl-submit-button" style="padding-left: 10px">
673
+ <?php submit_button(); ?>
674
+ </div>
675
+ <?php endif; ?>
676
+ </form>
677
+ </div>
678
+ <?php } ?>
679
+ </div>
680
+ <?php
681
+ $this->script();
682
+ }
683
+
684
+ /**
685
+ * Tabbable JavaScript codes & Initiate Color Picker
686
+ *
687
+ * This code uses localstorage for displaying active tabs
688
+ */
689
+ function script() {
690
+ ?>
691
+ <script>
692
+ jQuery(document).ready(function($) {
693
+ //Initiate Color Picker
694
+ $('.wp-color-picker-field').wpColorPicker();
695
+ $(".proelement .wp-picker-container button").attr("disabled", true);
696
+
697
+ // Switches option sections
698
+ $('.group').hide();
699
+ var activetab = '';
700
+ if (typeof(localStorage) != 'undefined' ) {
701
+ activetab = localStorage.getItem("activetab");
702
+ }
703
+
704
+ //if url has section id as hash then set it as active or override the current local storage value
705
+ if(window.location.hash){
706
+ activetab = window.location.hash;
707
+ if (typeof(localStorage) != 'undefined' ) {
708
+ localStorage.setItem("activetab", activetab);
709
+ }
710
+ }
711
+
712
+ if (activetab != '' && $(activetab).length ) {
713
+ $(activetab).fadeIn();
714
+ } else {
715
+ $('.group:first').fadeIn();
716
+ }
717
+ $('.group .collapsed').each(function(){
718
+ $(this).find('input:checked').parent().parent().parent().nextAll().each(
719
+ function(){
720
+ if ($(this).hasClass('last')) {
721
+ $(this).removeClass('hidden');
722
+ return false;
723
+ }
724
+ $(this).filter('.hidden').removeClass('hidden');
725
+ });
726
+ });
727
+
728
+ if (activetab != '' && $(activetab + '-tab').length ) {
729
+ $(activetab + '-tab').addClass('nav-tab-active');
730
+ }
731
+ else {
732
+ $('.nav-tab-wrapper a:first').addClass('nav-tab-active');
733
+ }
734
+ $('.nav-tab-wrapper a').click(function(evt) {
735
+ $('.nav-tab-wrapper a').removeClass('nav-tab-active');
736
+ $(this).addClass('nav-tab-active').blur();
737
+ var clicked_group = $(this).attr('href');
738
+ if (typeof(localStorage) != 'undefined' ) {
739
+ localStorage.setItem("activetab", $(this).attr('href'));
740
+ }
741
+ $('.group').hide();
742
+ $(clicked_group).fadeIn();
743
+ evt.preventDefault();
744
+ });
745
+
746
+ $('.wpsa-browse').on('click', function (event) {
747
+ event.preventDefault();
748
+
749
+ var self = $(this);
750
+
751
+ // Create the media frame.
752
+ var file_frame = wp.media.frames.file_frame = wp.media({
753
+ title: self.data('uploader_title'),
754
+ button: {
755
+ text: self.data('uploader_button_text'),
756
+ },
757
+ multiple: false
758
+ });
759
+
760
+ file_frame.on('select', function () {
761
+ attachment = file_frame.state().get('selection').first().toJSON();
762
+ self.prev('.wpsa-url').val(attachment.url).change();
763
+ self.siblings('.wpsa_display').html('<img src="'+attachment.url+'" alt="" />');
764
+ });
765
+
766
+ // Finally, open the modal
767
+ file_frame.open();
768
+
769
+ });
770
+
771
+ // Remove Media Button
772
+ $('.wpsa-remove').on('click', function (event) {
773
+ event.preventDefault();
774
+ var self = $(this);
775
+ self.siblings('.wpsa-url').val('').change();
776
+ self.siblings('.wpsa_display').html('');
777
+ });
778
+
779
+ // Shortable field select all
780
+ $(".htoption-shortable-checkall").click(function () {
781
+ $( this ).siblings('.htoption_shortable').find('input:checkbox').not( this ).prop( 'checked', this.checked );
782
+ });
783
+
784
+ // Initiate sortable Field
785
+ $( ".htoption_shortable" ).sortable();
786
+
787
+ });
788
+ </script>
789
+ <?php
790
+ }
791
+
792
+ }
includes/modules/wishlist/includes/classes/Ajax.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite;
3
+ /**
4
+ * Ajax handlers class
5
+ */
6
+ class Ajax {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [instance] Initializes a singleton instance
16
+ * @return [Ajax]
17
+ */
18
+ public static function instance() {
19
+ if ( is_null( self::$_instance ) ) {
20
+ self::$_instance = new self();
21
+ }
22
+ return self::$_instance;
23
+ }
24
+
25
+ /**
26
+ * Initialize the class
27
+ */
28
+ private function __construct() {
29
+
30
+ // Add Ajax Callback
31
+ add_action( 'wp_ajax_wishsuite_add_to_list', [ $this, 'add_to_wishlist' ] );
32
+ add_action( 'wp_ajax_nopriv_wishsuite_add_to_list', [ $this, 'add_to_wishlist' ] );
33
+
34
+ // Remove Ajax Callback
35
+ add_action( 'wp_ajax_wishsuite_remove_from_list', [ $this, 'remove_wishlist' ] );
36
+ add_action( 'wp_ajax_nopriv_wishsuite_remove_from_list', [ $this, 'remove_wishlist' ] );
37
+
38
+ // Variation Quick cart Form Ajax Callback
39
+ add_action( 'wp_ajax_wishsuite_quick_variation_form', [ $this, 'variation_form_html' ] );
40
+ add_action( 'wp_ajax_nopriv_wishsuite_quick_variation_form', [ $this, 'variation_form_html' ] );
41
+
42
+ // For Add to cart
43
+ add_action( 'wp_ajax_wishsuite_insert_to_cart', [ $this, 'insert_to_cart' ] );
44
+ add_action( 'wp_ajax_nopriv_wishsuite_insert_to_cart', [ $this, 'insert_to_cart' ] );
45
+
46
+ }
47
+
48
+ /**
49
+ * [add_to_wishlist] Product add ajax callback
50
+ */
51
+ public function add_to_wishlist(){
52
+ $id = sanitize_text_field( $_GET['id'] );
53
+ $inserted = \WishSuite\Frontend\Manage_Wishlist::instance()->add_product( $id );
54
+ if ( ! $inserted ) {
55
+ wp_send_json_success([
56
+ 'message' => __( 'Product do not add!', 'wishsuite' )
57
+ ]);
58
+ }else{
59
+ wp_send_json_success([
60
+ 'message' => __( 'Product successfully added!', 'wishsuite' )
61
+ ]);
62
+ }
63
+
64
+ }
65
+
66
+ /**
67
+ * [remove_wishlist] Product delete ajax callback
68
+ * @return [void]
69
+ */
70
+ public function remove_wishlist(){
71
+ $id = sanitize_text_field( $_GET['id'] );
72
+ $deleted = \WishSuite\Frontend\Manage_Wishlist::instance()->remove_product( $id );
73
+ if ( ! $deleted ) {
74
+ wp_send_json_success([
75
+ 'message' => __( 'Product do not delete!', 'wishsuite' )
76
+ ]);
77
+ }else{
78
+ wp_send_json_success([
79
+ 'message' => __( 'Product successfully deleted!', 'wishsuite' )
80
+ ]);
81
+ }
82
+
83
+ }
84
+
85
+ /**
86
+ * [variation_form_html]
87
+ * @param boolean $id product id
88
+ * @return [void]
89
+ */
90
+ public function variation_form_html( $id = false ){
91
+
92
+ if( isset( $_POST['id'] ) ) {
93
+ $id = sanitize_text_field( (int) $_POST['id'] );
94
+ }
95
+ if( ! $id || ! class_exists( 'WooCommerce' ) ) {
96
+ return;
97
+ }
98
+
99
+ global $post;
100
+
101
+ $args = array(
102
+ 'post_type' => 'product',
103
+ 'post__in' => array( $id )
104
+ );
105
+
106
+ $get_posts = get_posts( $args );
107
+
108
+ foreach( $get_posts as $post ) :
109
+ setup_postdata( $post );
110
+ woocommerce_template_single_add_to_cart();
111
+ endforeach;
112
+
113
+ wp_reset_postdata();
114
+
115
+ wp_die();
116
+
117
+ }
118
+
119
+ /**
120
+ * [insert_to_cart] Insert add to cart
121
+ * @return [JSON]
122
+ */
123
+ public function insert_to_cart(){
124
+
125
+ // phpcs:disable WordPress.Security.NonceVerification.Missing
126
+ if ( ! isset( $_POST['product_id'] ) ) {
127
+ return;
128
+ }
129
+
130
+ $product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) );
131
+ $quantity = empty( $_POST['quantity'] ) ? 1 : wc_stock_amount( wp_unslash( $_POST['quantity'] ) );
132
+ $variation_id = !empty( $_POST['variation_id'] ) ? absint( $_POST['variation_id'] ) : 0;
133
+ $variations = !empty( $_POST['variations'] ) ? array_map( 'sanitize_text_field', $_POST['variations'] ) : array();
134
+ $passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations );
135
+ $product_status = get_post_status( $product_id );
136
+
137
+ if ( $passed_validation && \WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variations ) && 'publish' === $product_status ) {
138
+ do_action( 'woocommerce_ajax_added_to_cart', $product_id );
139
+ if ( 'yes' === get_option('woocommerce_cart_redirect_after_add') ) {
140
+ wc_add_to_cart_message( array( $product_id => $quantity ), true );
141
+ }
142
+ \WC_AJAX::get_refreshed_fragments();
143
+ } else {
144
+ $data = array(
145
+ 'error' => true,
146
+ 'product_url' => apply_filters('woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id ),
147
+ );
148
+ echo wp_send_json( $data );
149
+ }
150
+ wp_send_json_success();
151
+
152
+ }
153
+
154
+
155
+ }
includes/modules/wishlist/includes/classes/Assets.php ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite;
3
+ /**
4
+ * Assets handlers class
5
+ */
6
+ class Assets {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [instance] Initializes a singleton instance
16
+ * @return [Base]
17
+ */
18
+ public static function instance() {
19
+ if ( is_null( self::$_instance ) ) {
20
+ self::$_instance = new self();
21
+ }
22
+ return self::$_instance;
23
+ }
24
+
25
+ /**
26
+ * Class constructor
27
+ */
28
+ private function __construct() {
29
+ add_action( 'wp_enqueue_scripts', [ $this, 'register_assets' ] );
30
+ add_action( 'admin_enqueue_scripts', [ $this, 'register_assets' ] );
31
+ }
32
+
33
+ /**
34
+ * All available scripts
35
+ *
36
+ * @return array
37
+ */
38
+ public function get_scripts() {
39
+ return [
40
+ 'wishsuite-admin' => [
41
+ 'src' => WISHSUITE_ASSETS . '/js/admin.js',
42
+ 'version' => WOOLENTOR_VERSION,
43
+ 'deps' => [ 'jquery' ]
44
+ ],
45
+ 'wishsuite-frontend' => [
46
+ 'src' => WISHSUITE_ASSETS . '/js/frontend.js',
47
+ 'version' => WOOLENTOR_VERSION,
48
+ 'deps' => [ 'jquery', 'wc-add-to-cart-variation' ]
49
+ ],
50
+ ];
51
+ }
52
+
53
+ /**
54
+ * All available styles
55
+ *
56
+ * @return array
57
+ */
58
+ public function get_styles() {
59
+ return [
60
+ 'wishsuite-admin' => [
61
+ 'src' => WISHSUITE_ASSETS . '/css/admin.css',
62
+ 'version' => WOOLENTOR_VERSION,
63
+ ],
64
+ 'wishsuite-frontend' => [
65
+ 'src' => WISHSUITE_ASSETS . '/css/frontend.css',
66
+ 'version' => WOOLENTOR_VERSION,
67
+ ],
68
+ ];
69
+ }
70
+
71
+ /**
72
+ * Register scripts and styles
73
+ *
74
+ * @return void
75
+ */
76
+ public function register_assets() {
77
+ $scripts = $this->get_scripts();
78
+ $styles = $this->get_styles();
79
+
80
+ foreach ( $scripts as $handle => $script ) {
81
+ $deps = isset( $script['deps'] ) ? $script['deps'] : false;
82
+ wp_register_script( $handle, $script['src'], $deps, $script['version'], true );
83
+ }
84
+
85
+ foreach ( $styles as $handle => $style ) {
86
+ $deps = isset( $style['deps'] ) ? $style['deps'] : false;
87
+ wp_register_style( $handle, $style['src'], $deps, $style['version'] );
88
+ }
89
+
90
+ // Inline CSS
91
+ wp_add_inline_style( 'wishsuite-frontend', $this->inline_style() );
92
+
93
+ // Frontend Localize data
94
+ $option_data = array(
95
+ 'after_added_to_cart' => woolentor_get_option( 'after_added_to_cart', 'wishsuite_table_settings_tabs', 'on' ),
96
+ );
97
+
98
+ if( is_user_logged_in() && woolentor_get_option( 'enable_login_limit', 'wishsuite_general_tabs', 'off' ) === 'on' ){
99
+ $option_data['btn_limit_login_off'] = 'off';
100
+ }else if( !is_user_logged_in() && woolentor_get_option( 'enable_login_limit', 'wishsuite_general_tabs', 'off' ) === 'on' ){
101
+ $option_data['btn_limit_login_off'] = 'on';
102
+ }
103
+
104
+ $localize_data = array(
105
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
106
+ 'option_data' => $option_data,
107
+ );
108
+
109
+ // Admin Localize data
110
+ $setting_page = 0;
111
+ if( isset( $_GET['page'] ) && $_GET['page'] == 'wishsuite' ){
112
+ $setting_page = 1;
113
+ }
114
+ $admin_option_data = array(
115
+ 'btn_icon_type' => woolentor_get_option( 'button_icon_type', 'wishsuite_style_settings_tabs', 'default' ),
116
+ 'added_btn_icon_type' => woolentor_get_option( 'addedbutton_icon_type', 'wishsuite_style_settings_tabs', 'default' ),
117
+ 'shop_btn_position' => woolentor_get_option( 'shop_btn_position', 'wishsuite_settings_tabs', 'after_cart_btn' ),
118
+ 'product_btn_position' => woolentor_get_option( 'product_btn_position', 'wishsuite_settings_tabs', 'after_cart_btn' ),
119
+ 'button_style' => woolentor_get_option( 'button_style', 'wishsuite_style_settings_tabs', 'default' ),
120
+ 'table_style' => woolentor_get_option( 'table_style', 'wishsuite_style_settings_tabs', 'default' ),
121
+ 'enable_social_share' => woolentor_get_option( 'enable_social_share','wishsuite_table_settings_tabs','on' ),
122
+ 'enable_login_limit' => woolentor_get_option( 'enable_login_limit','wishsuite_general_tabs','off' ),
123
+ );
124
+ $admin_localize_data = array(
125
+ 'ajaxurl' => admin_url( 'admin-ajax.php' ),
126
+ 'is_settings'=> $setting_page,
127
+ 'option_data'=> $admin_option_data,
128
+ );
129
+
130
+ wp_localize_script( 'wishsuite-frontend', 'WishSuite', $localize_data );
131
+ wp_localize_script( 'wishsuite-admin', 'WishSuite', $admin_localize_data );
132
+
133
+ if( class_exists( '\Elementor\Plugin' ) && ( \Elementor\Plugin::$instance->preview->is_preview_mode() ) ){
134
+ wp_enqueue_style( 'wishsuite-frontend' );
135
+ wp_enqueue_script( 'wishsuite-frontend' );
136
+ }
137
+
138
+ }
139
+
140
+ /**
141
+ * [inline_style]
142
+ * @return [CSS String]
143
+ */
144
+ public function inline_style(){
145
+
146
+ $button_custom_css = $table_custom_css = '';
147
+
148
+ // Button Custom Style
149
+ if( 'custom' === woolentor_get_option( 'button_style', 'wishsuite_style_settings_tabs', 'default' ) ){
150
+
151
+ $btn_padding = wishsuite_dimensions( 'button_custom_padding','wishsuite_style_settings_tabs','padding' );
152
+ $btn_margin = wishsuite_dimensions( 'button_custom_margin','wishsuite_style_settings_tabs','margin' );
153
+ $btn_border_radius = wishsuite_dimensions( 'button_custom_border_radius','wishsuite_style_settings_tabs','border-radius' );
154
+
155
+ $btn_color = wishsuite_generate_css('button_color','wishsuite_style_settings_tabs','color');
156
+ $btn_bg_color = wishsuite_generate_css('background_color','wishsuite_style_settings_tabs','background-color');
157
+
158
+ // Hover
159
+ $btn_hover_color = wishsuite_generate_css('button_hover_color','wishsuite_style_settings_tabs','color');
160
+ $btn_hover_bg_color = wishsuite_generate_css('hover_background_color','wishsuite_style_settings_tabs','background-color');
161
+
162
+ $button_custom_css = "
163
+ .wishsuite-button{
164
+ {$btn_padding}
165
+ {$btn_margin}
166
+ {$btn_color}
167
+ {$btn_bg_color}
168
+ {$btn_border_radius}
169
+ }
170
+ .wishsuite-button:hover{
171
+ {$btn_hover_color}
172
+ {$btn_hover_bg_color}
173
+ }
174
+ ";
175
+ }
176
+
177
+ // Wishlist table style
178
+ if( 'custom' === woolentor_get_option( 'table_style', 'wishsuite_style_settings_tabs', 'default' ) ){
179
+
180
+ $heading_color = wishsuite_generate_css('table_heading_color','wishsuite_style_settings_tabs','color');
181
+ $heading_bg_color = wishsuite_generate_css('table_heading_bg_color','wishsuite_style_settings_tabs','background-color');
182
+ $heading_border_color = wishsuite_generate_css('table_heading_border_color','wishsuite_style_settings_tabs','border-color');
183
+
184
+ $border_color = wishsuite_generate_css('table_border_color','wishsuite_style_settings_tabs','border-color');
185
+
186
+ $table_custom_css = "
187
+ .wishsuite-table-content table thead > tr{
188
+ {$heading_border_color}
189
+ }
190
+ .wishsuite-table-content table thead > tr th{
191
+ {$heading_color}
192
+ {$heading_bg_color}
193
+ }
194
+ .wishsuite-table-content table,.wishsuite-table-content table tbody > tr{
195
+ {$border_color}
196
+ }
197
+ ";
198
+
199
+ }
200
+
201
+ return $button_custom_css.$table_custom_css;
202
+
203
+ }
204
+
205
+
206
+ }
includes/modules/wishlist/includes/classes/Frontend.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite;
3
+ /**
4
+ * Frontend handlers class
5
+ */
6
+ class Frontend {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [instance] Initializes a singleton instance
16
+ * @return [Base]
17
+ */
18
+ public static function instance() {
19
+ if ( is_null( self::$_instance ) ) {
20
+ self::$_instance = new self();
21
+ }
22
+ return self::$_instance;
23
+ }
24
+
25
+ /**
26
+ * Initialize the class
27
+ */
28
+ private function __construct() {
29
+ $this->includes();
30
+ Frontend\Shortcode::instance();
31
+ Frontend\Manage_Wishlist::instance();
32
+ }
33
+
34
+ public function includes(){
35
+ require_once( __DIR__. '/Frontend/Manage_Wishlist.php' );
36
+ require_once __DIR__ . '/Frontend/Shortcode.php';
37
+ }
38
+
39
+ }
includes/modules/wishlist/includes/classes/Frontend/Manage_Wishlist.php ADDED
@@ -0,0 +1,601 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite\Frontend;
3
+ /**
4
+ * Manage Wishlist class
5
+ */
6
+ class Manage_Wishlist {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [instance] Initializes a singleton instance
16
+ * @return [Manage_Wishlist]
17
+ */
18
+ public static function instance() {
19
+ if ( is_null( self::$_instance ) ) {
20
+ self::$_instance = new self();
21
+ }
22
+ return self::$_instance;
23
+ }
24
+
25
+ /**
26
+ * Initialize the class
27
+ */
28
+ private function __construct() {
29
+ add_action( 'init', [ $this, 'button_manager' ] );
30
+
31
+ // Remove wishlist item after add to cart.
32
+ add_action( 'woocommerce_add_to_cart', [ $this, 'remove_wishlist_after_add_to_cart' ], 10, 6 );
33
+
34
+ }
35
+
36
+ /**
37
+ * [add_product] Product Add
38
+ * @param [int] $id
39
+ */
40
+ public function add_product( $id ){
41
+
42
+ $user_id = get_current_user_id();
43
+ $add_status = false;
44
+
45
+ if( $user_id ){
46
+
47
+ $args = [
48
+ 'product_id' => $id,
49
+ 'user_id' => $user_id
50
+ ];
51
+
52
+ $insert_id = \WishSuite\Manage_Data::instance()->create( $args );
53
+ $add_status = $insert_id;
54
+
55
+ }else{
56
+
57
+ $cookie_name = $this->get_cookie_name();
58
+
59
+ if ( $this->is_product_in_wishlist( $id ) ) {
60
+ $add_status = false;
61
+ }
62
+
63
+ $products = $this->get_wishlist_products();
64
+ $products[] = $id;
65
+
66
+ setcookie( $cookie_name, json_encode( $products ), 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
67
+ $_COOKIE[$cookie_name] = json_encode( $products );
68
+ $add_status = true;
69
+
70
+ }
71
+
72
+ return $add_status;
73
+
74
+ }
75
+
76
+ /**
77
+ * [remove_product]
78
+ * @param [type] $id
79
+ * @return [void]
80
+ */
81
+ public function remove_product( $id ){
82
+ $user_id = get_current_user_id();
83
+ $delete_status = false;
84
+
85
+ if( $user_id ){
86
+ $deleted = \WishSuite\Manage_Data::instance()->delete( $user_id, $id );
87
+ $delete_status = $deleted;
88
+ }else{
89
+
90
+ $cookie_name = $this->get_cookie_name();
91
+
92
+ $products = $this->get_wishlist_products();
93
+
94
+ if( in_array( $id, $products ) ){
95
+
96
+ foreach ( $products as $prod_key => $product_id ) {
97
+ if ( intval( $id ) == $product_id ) {
98
+ unset( $products[ $prod_key ] );
99
+ }
100
+ }
101
+
102
+ if ( empty( $products ) ) {
103
+ setcookie( $cookie_name, false, 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
104
+ $_COOKIE[$cookie_name] = false;
105
+ } else {
106
+ setcookie( $cookie_name, json_encode( $products ), 0, COOKIEPATH, COOKIE_DOMAIN, false, false );
107
+ $_COOKIE[$cookie_name] = json_encode( $products );
108
+ }
109
+ $delete_status = true;
110
+
111
+ }else{
112
+ $delete_status = false;
113
+ }
114
+
115
+ }
116
+
117
+ return $delete_status;
118
+ }
119
+
120
+ /**
121
+ * [remove_wishlist_after_add_to_cart]
122
+ * @param [type] $cart_item_key
123
+ * @param [type] $product_id
124
+ * @param [type] $quantity
125
+ * @param [type] $variation_id
126
+ * @param [type] $variation
127
+ * @param [type] $cart_item_data
128
+ * @return [type]
129
+ */
130
+ public function remove_wishlist_after_add_to_cart( $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data ){
131
+ if( isset( $product_id ) && 'on' === woolentor_get_option( 'after_added_to_cart', 'wishsuite_table_settings_tabs', 'on' ) ){
132
+ $this->remove_product( $product_id );
133
+ }
134
+ }
135
+
136
+ /**
137
+ * [button_manager] Button Manager
138
+ * @return [void]
139
+ */
140
+ public function button_manager(){
141
+
142
+ $shop_page_btn_position = woolentor_get_option( 'shop_btn_position', 'wishsuite_settings_tabs', 'after_cart_btn' );
143
+ $product_page_btn_position = woolentor_get_option( 'product_btn_position', 'wishsuite_settings_tabs', 'after_cart_btn' );
144
+
145
+ $enable_btn = woolentor_get_option( 'btn_show_shoppage', 'wishsuite_settings_tabs', 'off' );
146
+ $product_enable_btn = woolentor_get_option( 'btn_show_productpage', 'wishsuite_settings_tabs', 'on' );
147
+
148
+ // Shop Button Position
149
+ if( $shop_page_btn_position != 'use_shortcode' && $enable_btn == 'on' ){
150
+ switch ( $shop_page_btn_position ) {
151
+ case 'before_cart_btn':
152
+ add_action( 'woocommerce_after_shop_loop_item', [ $this, 'button_print' ], 7 );
153
+ break;
154
+
155
+ case 'top_thumbnail':
156
+ add_action( 'woocommerce_before_shop_loop_item', [ $this, 'button_print' ], 5 );
157
+ break;
158
+
159
+ case 'custom_position':
160
+ $hook_name = woolentor_get_option( 'shop_custom_hook_name', 'wishsuite_settings_tabs', '' );
161
+ $priority = woolentor_get_option( 'shop_custom_hook_priority', 'wishsuite_settings_tabs', 10 );
162
+ if( !empty( $hook_name ) ){
163
+ add_action( $hook_name, [ $this, 'button_print' ], $priority );
164
+ }
165
+ break;
166
+
167
+ default:
168
+ add_action( 'woocommerce_after_shop_loop_item', [ $this, 'button_print' ], 20 );
169
+ break;
170
+ }
171
+ }
172
+
173
+ // Product Page Button Position
174
+ if( $product_page_btn_position != 'use_shortcode' && $product_enable_btn == 'on' ){
175
+ switch ( $product_page_btn_position ) {
176
+ case 'before_cart_btn':
177
+ add_action( 'woocommerce_before_add_to_cart_button', [ $this, 'button_print' ], 20 );
178
+ break;
179
+
180
+ case 'after_thumbnail':
181
+ add_action( 'woocommerce_product_thumbnails', [ $this, 'button_print' ], 21 );
182
+ break;
183
+
184
+ case 'after_summary':
185
+ add_action( 'woocommerce_after_single_product_summary', [ $this, 'button_print' ], 11 );
186
+ break;
187
+
188
+ case 'custom_position':
189
+ $hook_name = woolentor_get_option( 'product_custom_hook_name', 'wishsuite_settings_tabs', '' );
190
+ $priority = woolentor_get_option( 'product_custom_hook_priority', 'wishsuite_settings_tabs', 10 );
191
+ if( !empty( $hook_name ) ){
192
+ add_action( $hook_name, [ $this, 'button_print' ], $priority );
193
+ }
194
+ break;
195
+
196
+ default:
197
+ add_action( 'woocommerce_single_product_summary', [ $this, 'button_print' ], 31 );
198
+ break;
199
+ }
200
+ }
201
+
202
+ }
203
+
204
+ /**
205
+ * [add_button]
206
+ * @return [void]
207
+ */
208
+ public function button_print(){
209
+ echo do_shortcode( '[wishsuite_button]' );
210
+ }
211
+
212
+ /**
213
+ * [button_html] Wishlist Button HTML
214
+ * @param [type] $atts template attr
215
+ * @return [HTML]
216
+ */
217
+ public function button_html( $atts ) {
218
+ $button_attr = apply_filters( 'wishsuite_button_arg', $atts );
219
+ return wishsuite_get_template( 'wishsuite-button-'.$atts['template_name'].'.php', $button_attr, false );
220
+ }
221
+
222
+ /**
223
+ * [table_html] Wishlist table HTML
224
+ * @return [HTML]
225
+ */
226
+ public function table_html( $atts ) {
227
+ $table_attr = apply_filters( 'wishsuite_table_arg', $atts );
228
+ return wishsuite_get_template( 'wishsuite-table.php', $table_attr, false );
229
+ }
230
+
231
+ /**
232
+ * [get_cookie_name] Get cookie name
233
+ * @return [string]
234
+ */
235
+ public function get_cookie_name() {
236
+ $name = 'wishsuite_item_list';
237
+ if ( is_multisite() ){
238
+ $name .= '_' . get_current_blog_id();
239
+ }
240
+ return $name;
241
+ }
242
+
243
+ /**
244
+ * [get_wishlist_products]
245
+ * @param integer $per_page
246
+ * @param integer $offset
247
+ * @return [array]
248
+ */
249
+ public function get_wishlist_products( $per_page = 20, $offset = 0 ){
250
+
251
+ if( is_user_logged_in() ){
252
+ $args = [
253
+ 'number' => $per_page,
254
+ 'offset' => $offset,
255
+ ];
256
+ $items = \WishSuite\Manage_Data::instance()->read( $args );
257
+
258
+ $ids = array();
259
+ foreach ( $items as $itemkey => $item ) {
260
+ $ids[] = $item['product_id'];
261
+ }
262
+ return $ids;
263
+ }else{
264
+ $cookie_name = $this->get_cookie_name();
265
+ // return isset( $_COOKIE[ $cookie_name ] ) ? array_map( 'sanitize_text_field', json_decode( wp_unslash( $_COOKIE[ $cookie_name ] ), true ) ) : array();
266
+ if( isset( $_COOKIE[ $cookie_name ] ) && is_array( json_decode( wp_unslash( $_COOKIE[ $cookie_name ] ), true ) ) ){
267
+ return array_map( 'sanitize_text_field', json_decode( wp_unslash( $_COOKIE[ $cookie_name ] ), true ) );
268
+ }else{
269
+ return array();
270
+ }
271
+ }
272
+
273
+ }
274
+
275
+ /**
276
+ * [is_product_in_wishlist] Check product in list
277
+ * @param [int] $id [description]
278
+ * @return boolean
279
+ */
280
+ public function is_product_in_wishlist( $id ) {
281
+ $id = (string) $id;
282
+ $list = $this->get_wishlist_products();
283
+ if ( is_array( $list ) ) {
284
+ return in_array( $id, $list, true );
285
+ }else{
286
+ return false;
287
+ }
288
+ }
289
+
290
+ /**
291
+ * [get_products_data] generate wishlist products data
292
+ * @return [array] product list
293
+ */
294
+ public function get_products_data() {
295
+
296
+ $ids = $this->get_wishlist_products();
297
+
298
+ $shareablebtn = woolentor_get_option( 'enable_social_share','wishsuite_table_settings_tabs','on' );
299
+ if ( ( $shareablebtn === 'on' ) && isset( $_GET['wishsuitepids'] ) ) {
300
+ $query_perametter_ids = sanitize_text_field( $_GET['wishsuitepids'] );
301
+ if( !empty( $query_perametter_ids ) ){
302
+ $ids = explode( ',', $query_perametter_ids );
303
+ }
304
+ }
305
+
306
+ if ( empty( $ids ) ) {
307
+ return array();
308
+ }
309
+
310
+ $args = array(
311
+ 'include' => $ids,
312
+ );
313
+
314
+ $products = wc_get_products( $args );
315
+
316
+ $products_data = array();
317
+
318
+ $fields = $this->get_all_fields();
319
+
320
+ $fields = array_filter( $fields, function( $field ) {
321
+ return 'pa_' === substr( $field, 0, 3 );
322
+ }, ARRAY_FILTER_USE_KEY );
323
+
324
+ $data_none = '-';
325
+
326
+ foreach ( $products as $product ) {
327
+
328
+ $rating_count = $product->get_rating_count();
329
+ $average = $product->get_average_rating();
330
+
331
+ $get_row = \WishSuite\Manage_Data::instance()->read_single_item( get_current_user_id(), $product->get_id() );
332
+ if( is_object( $get_row ) && $get_row->quantity ){
333
+ $min_value = $get_row->quantity;
334
+ }else{
335
+ $min_value = $product->get_min_purchase_quantity();
336
+ }
337
+ $quantity_args = array(
338
+ 'input_value' => $min_value,
339
+ 'min_value' => $product->get_min_purchase_quantity(),
340
+ 'max_value' => $product->get_max_purchase_quantity(),
341
+ );
342
+
343
+ $products_data[ $product->get_id() ] = array(
344
+ 'id' => $product->get_id(),
345
+ 'remove' => $product->get_id(),
346
+ 'image' => $product->get_image() ? $product->get_image('wishsuite-image') : $data_none,
347
+ 'title' => $product->get_title() ? $product->get_title() : $data_none,
348
+ 'image_id' => $product->get_image_id(),
349
+ 'permalink' => $product->get_permalink(),
350
+ 'price' => $product->get_price_html() ? $product->get_price_html() : $data_none,
351
+ 'rating' => wc_get_rating_html( $average, $rating_count ),
352
+ 'add_to_cart' => $this->add_to_cart_html( $product, $min_value ) ? $this->add_to_cart_html( $product, $min_value ) : $data_none,
353
+ 'quantity' => woocommerce_quantity_input( $quantity_args, $product, false ),
354
+ 'dimensions' => wc_format_dimensions( $product->get_dimensions( false ) ),
355
+ 'description' => $product->get_short_description() ? $product->get_short_description() : $data_none,
356
+ 'weight' => $product->get_weight() ? $product->get_weight() : $data_none,
357
+ 'sku' => $product->get_sku() ? $product->get_sku() : $data_none,
358
+ 'availability' => $this->availability_html( $product ),
359
+ );
360
+
361
+ foreach ( $fields as $field_id => $field_name ) {
362
+ if ( taxonomy_exists( $field_id ) ) {
363
+ $products_data[ $product->get_id() ][ $field_id ] = array();
364
+ $terms = get_the_terms( $product->get_id(), $field_id );
365
+ if ( ! empty( $terms ) ) {
366
+ foreach ( $terms as $term ) {
367
+ $term = sanitize_term( $term, $field_id );
368
+ $products_data[ $product->get_id() ][ $field_id ][] = $term->name;
369
+ }
370
+ } else {
371
+ $products_data[ $product->get_id() ][ $field_id ][] = '-';
372
+ }
373
+ $products_data[ $product->get_id() ][ $field_id ] = implode( ', ', $products_data[ $product->get_id() ][ $field_id ] );
374
+ }
375
+ }
376
+
377
+ }
378
+
379
+ return $products_data;
380
+ }
381
+
382
+ /**
383
+ * [get_all_fields] Table field list
384
+ * @return [array] Table Field list
385
+ */
386
+ public function get_all_fields() {
387
+
388
+ $default_show = array(
389
+ 'remove' => esc_html__( 'Remove', 'wishsuite' ),
390
+ 'image' => esc_html__( 'Image', 'wishsuite' ),
391
+ 'title' => esc_html__( 'Title', 'wishsuite' ),
392
+ 'price' => esc_html__( 'Price', 'wishsuite' ),
393
+ 'quantity' => esc_html__( 'Quantity', 'wishsuite' ),
394
+ 'add_to_cart' => esc_html__( 'Add To Cart', 'wishsuite' ),
395
+ );
396
+
397
+ $fields_settings = woolentor_get_option( 'show_fields', 'wishsuite_table_settings_tabs' );
398
+
399
+ if ( isset( $fields_settings ) && ( is_array( $fields_settings ) ) && count( $fields_settings ) > 1 ) {
400
+ $fields = $fields_settings;
401
+ }else{
402
+ $fields = $default_show;
403
+ }
404
+
405
+ return $fields;
406
+ }
407
+
408
+ /**
409
+ * [is_products_have_field]
410
+ * @param [string] $field_id
411
+ * @param [object] $products
412
+ * @return boolean
413
+ */
414
+ public function is_products_have_field( $field_id, $products ) {
415
+ foreach ( $products as $product_id => $product ) {
416
+ if ( isset( $product[ $field_id ] ) && ( ! empty( $product[ $field_id ] ) && '-' !== $product[ $field_id ] && 'N/A' !== $product[ $field_id ] ) ) {
417
+ return true;
418
+ }
419
+ }
420
+ return false;
421
+ }
422
+
423
+ /**
424
+ * [display_field]
425
+ * @param [string] $field_id
426
+ * @param [array] $product
427
+ * @return [html]
428
+ */
429
+ public function display_field( $field_id, $product ) {
430
+
431
+ $type = $field_id;
432
+
433
+ if ( 'pa_' === substr( $field_id, 0, 3 ) ) {
434
+ $type = 'attribute';
435
+ }
436
+
437
+ switch ( $type ) {
438
+ case 'remove':
439
+ ?>
440
+ <a href="#" class="wishsuite-remove" data-product_id="<?php echo esc_attr( $product['id'] ); ?>">&nbsp;</a>
441
+ <?php
442
+ break;
443
+
444
+ case 'image':
445
+ ?>
446
+ <a href="<?php echo get_permalink( $product['id'] ); ?>"> <?php echo $product['image']; ?> </a>
447
+ <?php
448
+ break;
449
+
450
+ case 'title':
451
+ echo '<a href="'.get_permalink( $product['id'] ).'">'.$product[ $field_id ].'</a>';
452
+ break;
453
+
454
+ case 'price':
455
+ echo wp_kses_post( $product[ $field_id ] );
456
+ break;
457
+
458
+ case 'quantity':
459
+ echo $product[ $field_id ];
460
+ break;
461
+
462
+ case 'ratting':
463
+ echo '<span class="wishsuite-product-ratting">'.wp_kses_post( $product[ $field_id ] ).'</span>';
464
+ break;
465
+
466
+ case 'add_to_cart':
467
+ echo apply_filters( 'wishsuite_add_to_cart_btn', $product[ $field_id ] );
468
+ break;
469
+
470
+ case 'attribute':
471
+ echo wp_kses_post( $product[ $field_id ] );
472
+ break;
473
+
474
+ case 'weight':
475
+ if ( $product[ $field_id ] ) {
476
+ $unit = $product[ $field_id ] !== '-' ? get_option( 'woocommerce_weight_unit' ) : '';
477
+ echo wc_format_localized_decimal( $product[ $field_id ] ) . ' ' . esc_attr( $unit );
478
+ }
479
+ break;
480
+
481
+ case 'description':
482
+ echo apply_filters( 'woocommerce_short_description', $product[ $field_id ] );
483
+ break;
484
+
485
+ default:
486
+ echo wp_kses_post( $product[ $field_id ] );
487
+ break;
488
+ }
489
+
490
+
491
+ }
492
+
493
+ /**
494
+ * [field_name]
495
+ * @param [string] $field
496
+ * @return [string]
497
+ */
498
+ public function field_name( $field, $custom = false ){
499
+
500
+ if( empty( $field ) ){
501
+ return;
502
+ }
503
+
504
+ if( $custom === true ){
505
+ return $field;
506
+ }
507
+
508
+ $default = wishsuite_get_default_fields();
509
+
510
+ $str = substr( $field, 0, 3 );
511
+ if( 'pa_' === $str ){
512
+ $field_name = wc_attribute_label( $field );
513
+ }else{
514
+ $field_name = $default[$field];
515
+ }
516
+ return $field_name;
517
+
518
+ }
519
+
520
+ /**
521
+ * [add_to_cart_html]
522
+ * @param [object] $product
523
+ */
524
+ public function add_to_cart_html( $product, $quentity ) {
525
+ if ( ! $product ) return;
526
+
527
+ $btn_class = 'wishsuite-addtocart button product_type_' . $product->get_type();
528
+
529
+ $btn_class .= $product->is_purchasable() && $product->is_in_stock() ? ' add_to_cart_button' : '';
530
+
531
+ $btn_class .= $product->supports( 'ajax_add_to_cart' ) && $product->is_purchasable() && $product->is_in_stock() ? ' ajax_add_to_cart' : '';
532
+
533
+ $cart_btn = $product->add_to_cart_text();
534
+
535
+ ob_start();
536
+
537
+ if( 'variable' === $product->get_type() ):
538
+ ?>
539
+ <div class="wishsuite-quick-cart-area">
540
+ <div class="wishsuite-quick-cart-close">
541
+ <span>&#10005;</span>
542
+ </div>
543
+ <div class="wishsuite-quick-cart-form"></div>
544
+ </div>
545
+ <?php endif; ?>
546
+ <a href="<?php echo $product->add_to_cart_url(); ?>" data-quantity="<?php echo esc_attr( $quentity ); ?>" class="<?php echo $btn_class; ?>" data-product_id="<?php echo $product->get_id(); ?>"><?php echo __( $cart_btn, 'wishsuite' );?></a>
547
+ <?php
548
+ return ob_get_clean();
549
+
550
+ }
551
+
552
+ /**
553
+ * [availability_html]
554
+ * @param [object] $product
555
+ * @return [html]
556
+ */
557
+ public function availability_html( $product ) {
558
+ $html = '';
559
+ $availability = $product->get_availability();
560
+
561
+ if( empty( $availability['availability'] ) ) {
562
+ $availability['availability'] = __( 'In stock', 'woocommerce' );
563
+ }
564
+
565
+ if ( ! empty( $availability['availability'] ) ) {
566
+ ob_start();
567
+
568
+ wc_get_template( 'single-product/stock.php', array(
569
+ 'product' => $product,
570
+ 'class' => $availability['class'],
571
+ 'availability' => $availability['availability'],
572
+ ) );
573
+
574
+ $html = ob_get_clean();
575
+ }
576
+
577
+ return apply_filters( 'woocommerce_get_stock_html', $html, $product );
578
+ }
579
+
580
+ /**
581
+ * [social_media_share]
582
+ * @return [void]
583
+ */
584
+ public function social_share(){
585
+
586
+ if( woolentor_get_option( 'enable_social_share','wishsuite_table_settings_tabs','on' ) !== 'on' ){
587
+ return;
588
+ }
589
+
590
+ $ids = $this->get_wishlist_products();
591
+
592
+ $atts = [
593
+ 'products_ids' => $ids,
594
+ ];
595
+ $social_share_attr = apply_filters( 'wishsuite_social_share_arg', $atts );
596
+ wishsuite_get_template( 'wishsuite-social-share.php', $social_share_attr, true );
597
+
598
+ }
599
+
600
+
601
+ }
includes/modules/wishlist/includes/classes/Frontend/Shortcode.php ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite\Frontend;
3
+ /**
4
+ * Shortcode handler class
5
+ */
6
+ class Shortcode {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [instance] Initializes a singleton instance
16
+ * @return [Base]
17
+ */
18
+ public static function instance() {
19
+ if ( is_null( self::$_instance ) ) {
20
+ self::$_instance = new self();
21
+ }
22
+ return self::$_instance;
23
+ }
24
+
25
+ /**
26
+ * Initializes the class
27
+ */
28
+ function __construct() {
29
+ add_shortcode( 'wishsuite_button', [ $this, 'button_shortcode' ] );
30
+ add_shortcode( 'wishsuite_table', [ $this, 'table_shortcode' ] );
31
+ }
32
+
33
+ /**
34
+ * [button_shortcode] Button Shortcode callable function
35
+ * @param [type] $atts
36
+ * @param string $content
37
+ * @return [HTML]
38
+ */
39
+ public function button_shortcode( $atts, $content = '' ){
40
+ wp_enqueue_style( 'wishsuite-frontend' );
41
+ wp_enqueue_script( 'wishsuite-frontend' );
42
+
43
+ global $product;
44
+ $product_id = '';
45
+ if ( $product && is_a( $product, 'WC_Product' ) ) {
46
+ $product_id = $product->get_id();
47
+ }
48
+
49
+ $has_product = false;
50
+ if ( Manage_Wishlist::instance()->is_product_in_wishlist( $product_id ) ) {
51
+ $has_product = true;
52
+ }
53
+
54
+ //my account url
55
+ $myaccount_url = get_permalink( get_option('woocommerce_myaccount_page_id') );
56
+
57
+ // Fetch option data
58
+ $button_text = woolentor_get_option( 'button_text','wishsuite_settings_tabs', 'Wishlist' );
59
+ $button_added_text = woolentor_get_option( 'added_button_text','wishsuite_settings_tabs', 'Product Added' );
60
+ $button_exist_text = woolentor_get_option( 'exist_button_text','wishsuite_settings_tabs', 'Product already added' );
61
+ $shop_page_btn_position = woolentor_get_option( 'shop_btn_position', 'wishsuite_settings_tabs', 'after_cart_btn' );
62
+ $product_page_btn_position = woolentor_get_option( 'product_btn_position', 'wishsuite_settings_tabs', 'after_cart_btn' );
63
+ $button_style = woolentor_get_option( 'button_style', 'wishsuite_style_settings_tabs', 'default' );
64
+ $enable_login_limit = woolentor_get_option( 'enable_login_limit', 'wishsuite_general_tabs', 'off' );
65
+
66
+ if ( !is_user_logged_in() && $enable_login_limit == 'on' ) {
67
+ $button_text = woolentor_get_option( 'logout_button','wishsuite_general_tabs', 'Please login' );
68
+ $page_url = $myaccount_url;
69
+ $has_product = false;
70
+ }else{
71
+ $button_text = woolentor_get_option( 'button_text','wishsuite_settings_tabs', 'Wishlist' );
72
+ $page_url = wishsuite_get_page_url();
73
+ }
74
+
75
+ $button_class = array(
76
+ 'wishsuite-btn',
77
+ 'wishsuite-button',
78
+ 'wishsuite-shop-'.$shop_page_btn_position,
79
+ 'wishsuite-product-'.$product_page_btn_position,
80
+ );
81
+
82
+ if( $button_style === 'themestyle' ){
83
+ $button_class[] = 'button';
84
+ }
85
+
86
+ if ( $has_product === true && ( $key = array_search( 'wishsuite-btn', $button_class ) ) !== false ) {
87
+ unset( $button_class[$key] );
88
+ }
89
+
90
+
91
+ $button_icon = $this->icon_generate();
92
+ $added_button_icon = $this->icon_generate('added');
93
+
94
+ if( !empty( $button_text ) ){
95
+ $button_text = '<span class="wishsuite-btn-text">'.$button_text.'</span>';
96
+ }
97
+
98
+ if( !empty( $button_exist_text ) ){
99
+ $button_exist_text = '<span class="wishsuite-btn-text">'.$button_exist_text.'</span>';
100
+ }
101
+
102
+ if( !empty( $button_added_text ) ){
103
+ $button_added_text = '<span class="wishsuite-btn-text">'.$button_added_text.'</span>';
104
+ }
105
+
106
+ // Shortcode atts
107
+ $default_atts = array(
108
+ 'product_id' => $product_id,
109
+ 'button_url' => $page_url,
110
+ 'button_class' => implode(' ', $button_class ),
111
+ 'button_text' => $button_icon.$button_text,
112
+ 'button_added_text' => $added_button_icon.$button_added_text,
113
+ 'button_exist_text' => $added_button_icon.$button_exist_text,
114
+ 'has_product' => $has_product,
115
+ 'template_name' => ( $has_product === true ) ? 'exist' : 'add',
116
+ );
117
+ $atts = shortcode_atts( $default_atts, $atts, $content );
118
+ return Manage_Wishlist::instance()->button_html( $atts );
119
+
120
+ }
121
+
122
+ /**
123
+ * [table_shortcode] Table List Shortcode callable function
124
+ * @param [type] $atts
125
+ * @param string $content
126
+ * @return [HTML]
127
+ */
128
+ public function table_shortcode( $atts, $content = '' ){
129
+ wp_enqueue_style( 'wishsuite-frontend' );
130
+ wp_enqueue_script( 'wishsuite-frontend' );
131
+
132
+ /* Fetch From option data */
133
+ $empty_text = woolentor_get_option( 'empty_table_text', 'wishsuite_table_settings_tabs' );
134
+
135
+ /* Product and Field */
136
+ $products = Manage_Wishlist::instance()->get_products_data();
137
+ $fields = Manage_Wishlist::instance()->get_all_fields();
138
+
139
+ $custom_heading = !empty( woolentor_get_option( 'table_heading', 'wishsuite_table_settings_tabs' ) ) ? woolentor_get_option( 'table_heading', 'wishsuite_table_settings_tabs' ) : array();
140
+ $enable_login_limit = woolentor_get_option( 'enable_login_limit', 'wishsuite_general_tabs', 'off' );
141
+
142
+ $default_atts = array(
143
+ 'wishsuite' => Manage_Wishlist::instance(),
144
+ 'products' => $products,
145
+ 'fields' => $fields,
146
+ 'heading_txt' => $custom_heading,
147
+ 'empty_text' => !empty( $empty_text ) ? $empty_text : '',
148
+ );
149
+
150
+ if ( !is_user_logged_in() && $enable_login_limit == 'on' ) {
151
+ return do_shortcode('[woocommerce_my_account]');
152
+ }else{
153
+ $atts = shortcode_atts( $default_atts, $atts, $content );
154
+ return Manage_Wishlist::instance()->table_html( $atts );
155
+ }
156
+ }
157
+
158
+ /**
159
+ * [icon_generate]
160
+ * @param string $type
161
+ * @return [HTML]
162
+ */
163
+ public function icon_generate( $type = '' ){
164
+
165
+ $arrContextOptions = [
166
+ 'ssl' => [
167
+ 'verify_peer' => false,
168
+ 'verify_peer_name' => false,
169
+ ]
170
+ ];
171
+
172
+ $default_icon = file_get_contents( WISHSUITE_ASSETS .'/images/icon.svg', false, stream_context_create($arrContextOptions) );
173
+ $default_loader = '<span class="wishsuite-loader">'.file_get_contents( WISHSUITE_ASSETS .'/images/loading.svg', false, stream_context_create($arrContextOptions) ).'</span>';
174
+
175
+ $button_icon = '';
176
+ $button_text = ( $type === 'added' ) ? woolentor_get_option( 'added_button_text','wishsuite_settings_tabs', 'Wishlist' ) : woolentor_get_option( 'button_text','wishsuite_settings_tabs', 'Wishlist' );
177
+ $button_icon_type = woolentor_get_option( $type.'button_icon_type', 'wishsuite_style_settings_tabs', 'default' );
178
+
179
+ if( $button_icon_type === 'custom' ){
180
+ $button_icon = woolentor_get_option( $type.'button_custom_icon','wishsuite_style_settings_tabs', '' );
181
+ }else{
182
+ if( $button_icon_type !== 'none' ){
183
+ return $default_icon;
184
+ }
185
+ }
186
+
187
+ if( !empty( $button_icon ) ){
188
+ $button_icon = '<img src="'.esc_url( $button_icon ).'" alt="'.esc_attr( $button_text ).'">';
189
+ }
190
+
191
+ return $button_icon.$default_loader;
192
+
193
+ }
194
+
195
+
196
+ }
includes/modules/wishlist/includes/classes/Installer.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite;
3
+ /**
4
+ * Installer class
5
+ */
6
+ class Installer {
7
+
8
+ /**
9
+ * Run the installer
10
+ *
11
+ * @return void
12
+ */
13
+ public function run() {
14
+ $this->create_tables();
15
+ $this->create_page();
16
+ }
17
+
18
+ /**
19
+ * [create_tables]
20
+ * @return [void]
21
+ */
22
+ public function create_tables() {
23
+ global $wpdb;
24
+
25
+ $charset_collate = '';
26
+ if ( $wpdb->has_cap( 'collation' ) ) {
27
+ $charset_collate = $wpdb->get_charset_collate();
28
+ }
29
+
30
+ $schema = "CREATE TABLE IF NOT EXISTS `{$wpdb->prefix}wishsuite_list` (
31
+ `id` bigint( 20 ) unsigned NOT NULL AUTO_INCREMENT,
32
+ `user_id` bigint( 20 ) NULL DEFAULT NULL,
33
+ `product_id` bigint(20) NULL DEFAULT NULL,
34
+ `quantity` int(11) NULL DEFAULT NULL,
35
+ `date_added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
36
+ PRIMARY KEY (`id`)
37
+ ) $charset_collate";
38
+
39
+ if ( ! function_exists( 'dbDelta' ) ) {
40
+ require_once ABSPATH . 'wp-admin/includes/upgrade.php';
41
+ }
42
+
43
+ dbDelta( $schema );
44
+ }
45
+
46
+ /**
47
+ * [create_page] Create page
48
+ * @return [void]
49
+ */
50
+ private function create_page() {
51
+ if ( function_exists( 'WC' ) ) {
52
+ if ( !function_exists( 'wc_create_page' ) ) {
53
+ require_once WC_ABSPATH . '/includes/admin/wc-admin-functions.php';
54
+ }
55
+ $create_page_id = wc_create_page(
56
+ sanitize_title_with_dashes( _x( 'wishsuite', 'page_slug', 'wishsuite' ) ),
57
+ '',
58
+ __( 'WishSuite', 'wishsuite' ),
59
+ '<!-- wp:shortcode -->[wishsuite_table]<!-- /wp:shortcode -->'
60
+ );
61
+ if( $create_page_id ){
62
+ woolentor_update_option( 'wishsuite_table_settings_tabs','wishlist_page', $create_page_id );
63
+ }
64
+ }
65
+ }
66
+
67
+ /**
68
+ * [drop_tables] Delete table
69
+ * @return [void]
70
+ */
71
+ public static function drop_tables() {
72
+ global $wpdb;
73
+ $tables = [
74
+ "{$wpdb->prefix}wishsuite_list",
75
+ ];
76
+ foreach ( $tables as $table ) {
77
+ $wpdb->query( "DROP TABLE IF EXISTS {$table}" );
78
+ }
79
+ }
80
+
81
+
82
+ }
includes/modules/wishlist/includes/classes/Manage_Data.php ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace WishSuite;
3
+ /**
4
+ * Manage_Data handlers class
5
+ */
6
+ class Manage_Data {
7
+
8
+ /**
9
+ * [$_instance]
10
+ * @var null
11
+ */
12
+ private static $_instance = null;
13
+
14
+ /**
15
+ * [instance] Initializes a singleton instance
16
+ * @return [Manage_Data]
17
+ */
18
+ public static function instance() {
19
+ if ( is_null( self::$_instance ) ) {
20
+ self::$_instance = new self();
21
+ }
22
+ return self::$_instance;
23
+ }
24
+
25
+ /**
26
+ * [create]
27
+ * @param array $args New argument
28
+ * @return [int] return insert id | update
29
+ */
30
+ public function create( $args = [] ){
31
+ global $wpdb;
32
+
33
+ if ( empty( $args['product_id'] ) ) {
34
+ return new \WP_Error( 'no-product_id', __( 'You must provide a product ID.', 'wishsuite' ) );
35
+ }
36
+
37
+ $defaults = [
38
+ 'user_id' => 'NULL',
39
+ 'product_id' => 'NULL',
40
+ 'quantity' => 1,
41
+ 'date_added' => current_time( 'mysql' ),
42
+ ];
43
+ $data = wp_parse_args( $args, $defaults );
44
+
45
+ $get_row = $this->read_single_item( $data['user_id'], $data['product_id'] );
46
+
47
+ if( is_object( $get_row ) && $get_row->product_id ){
48
+ $data['quantity'] = ( $get_row->quantity + 1 );
49
+ $this->update( $data );
50
+ }else{
51
+ $inserted = $wpdb->insert(
52
+ $wpdb->prefix . 'wishsuite_list',
53
+ $data,
54
+ [
55
+ '%d',
56
+ '%d',
57
+ '%d',
58
+ '%s'
59
+ ]
60
+ );
61
+
62
+ if ( ! $inserted ) {
63
+ return new \WP_Error( 'failed-to-insert', __( 'Failed to insert data', 'wishsuite' ) );
64
+ }
65
+
66
+ $this->purge_cache();
67
+
68
+ return $wpdb->insert_id;
69
+ }
70
+
71
+ }
72
+
73
+ /**
74
+ * [read]
75
+ * @param array $args
76
+ * @return [array] product array
77
+ */
78
+ public function read( $args = [] ){
79
+ global $wpdb;
80
+
81
+ $defaults = [
82
+ 'number' => 20,
83
+ 'user_id' => get_current_user_id(),
84
+ 'offset' => 0,
85
+ 'orderby' => 'id',
86
+ 'order' => 'ASC'
87
+ ];
88
+
89
+ $args = wp_parse_args( $args, $defaults );
90
+
91
+ $last_changed = wp_cache_get_last_changed( 'wishsuite' );
92
+ $key = md5( serialize( array_diff_assoc( $args, $defaults ) ) );
93
+ $cache_key = "all:$key:$last_changed";
94
+
95
+ $sql = $wpdb->prepare(
96
+ "SELECT * FROM {$wpdb->prefix}wishsuite_list
97
+ WHERE user_id = {$args['user_id']}
98
+ ORDER BY {$args['orderby']} {$args['order']}
99
+ LIMIT %d, %d",
100
+ $args['offset'], $args['number']
101
+ );
102
+
103
+ $items = wp_cache_get( $cache_key, 'wishsuite' );
104
+
105
+ if ( false === $items ) {
106
+ $items = $wpdb->get_results( $sql, ARRAY_A );
107
+
108
+ wp_cache_set( $cache_key, $items, 'wishsuite' );
109
+ }
110
+
111
+ return $items;
112
+ }
113
+
114
+ /**
115
+ * [update]
116
+ * @param array $args new argument
117
+ * @return [int] update id
118
+ */
119
+ public function update( $args = [] ){
120
+ global $wpdb;
121
+
122
+ $defaults = [
123
+ 'product_id' => 'NULL',
124
+ 'quantity' => 1,
125
+ ];
126
+ $data = wp_parse_args( $args, $defaults );
127
+
128
+ $user_id = $data['user_id'];
129
+ $product_id = $data['product_id'];
130
+
131
+ unset( $data['user_id'] );
132
+ unset( $data['product_id'] );
133
+ unset( $data['date_added'] );
134
+
135
+ $updated = $wpdb->update(
136
+ $wpdb->prefix . 'wishsuite_list',
137
+ $data,
138
+ [
139
+ 'user_id' => $user_id,
140
+ 'product_id' => $product_id
141
+ ],
142
+ [
143
+ '%d',
144
+ '%d'
145
+ ],
146
+ [ '%d', '%d' ]
147
+ );
148
+
149
+ $this->purge_cache( $user_id );
150
+
151
+ return $updated;
152
+
153
+ }
154
+
155
+ /**
156
+ * [item_count] Get the count of total product
157
+ * @param [int] $user_id
158
+ * @return [int]
159
+ */
160
+ public function item_count( $user_id ) {
161
+ global $wpdb;
162
+
163
+ $count = wp_cache_get( 'count', 'wishsuite' );
164
+
165
+ if ( false === $count ) {
166
+ $count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT count(id) FROM {$wpdb->prefix}wishsuite_list WHERE user_id = %d", $user_id ) );
167
+
168
+ wp_cache_set( 'count', $count, 'wishsuite' );
169
+ }
170
+
171
+ return $count;
172
+ }
173
+
174
+ /**
175
+ * [read_single_item] Fetch single product from DB
176
+ * @param [int] $user_id
177
+ * @return [object] Table Object
178
+ */
179
+ public function read_single_item( $user_id, $product_id ) {
180
+ global $wpdb;
181
+
182
+ $product = wp_cache_get( 'wishsuite-product-' . $user_id.$product_id, 'wishsuite' );
183
+
184
+ if ( false === $product ) {
185
+ $product = $wpdb->get_row(
186
+ $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}wishsuite_list WHERE user_id = %d AND product_id = %d", $user_id, $product_id )
187
+ );
188
+ wp_cache_set( 'wishsuite-product-' . $user_id.$product_id, $product, 'wishsuite' );
189
+ }
190
+
191
+ return $product;
192
+ }
193
+
194
+ /**
195
+ * Delete an address
196
+ *
197
+ * @param int $id
198
+ *
199
+ * @return int|boolean
200
+ */
201
+ public function delete( $user_id, $product_id ) {
202
+ global $wpdb;
203
+
204
+ $this->purge_cache( $user_id );
205
+
206
+ return $wpdb->delete(
207
+ $wpdb->prefix . 'wishsuite_list',
208
+ [
209
+ 'user_id' => $user_id,
210
+ 'product_id' => $product_id
211
+ ],
212
+ [ '%d', '%d' ]
213
+ );
214
+
215
+ }
216
+
217
+ /**
218
+ * [purge_cache] Manage Object Cache
219
+ * @param [int] $user_id
220
+ * @return [type]
221
+ */
222
+ public function purge_cache( $user_id = null ) {
223
+ $group = 'wishsuite';
224
+
225
+ if ( $user_id ) {
226
+ wp_cache_delete( 'wishsuite-product-' . $user_id, $group );
227
+ }
228
+
229
+ wp_cache_delete( 'count', $group );
230
+ wp_cache_set( 'last_changed', microtime(), $group );
231
+
232
+ }
233
+
234
+
235
+
236
+ }
includes/modules/wishlist/includes/helper-functions.php ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * [wishsuite_get_post_list]
4
+ * @param string $post_type
5
+ * @return [array]
6
+ */
7
+ function wishsuite_get_post_list( $post_type = 'page' ){
8
+ $options = array();
9
+ $options['0'] = __('Select','wishsuite');
10
+ $perpage = -1;
11
+ $all_post = array( 'posts_per_page' => $perpage, 'post_type'=> $post_type );
12
+ $post_terms = get_posts( $all_post );
13
+ if ( ! empty( $post_terms ) && ! is_wp_error( $post_terms ) ){
14
+ foreach ( $post_terms as $term ) {
15
+ $options[ $term->ID ] = $term->post_title;
16
+ }
17
+ return $options;
18
+ }
19
+ }
20
+
21
+ /**
22
+ * [wishsuite_locate_template]
23
+ * @param [string] $tmp_name Template name
24
+ * @return [Template path]
25
+ */
26
+ function wishsuite_locate_template( $tmp_name ) {
27
+ $woo_tmp_base = WC()->template_path();
28
+
29
+ $woo_tmp_path = $woo_tmp_base . $tmp_name; //active theme directory/woocommerce/
30
+ $theme_tmp_path = '/' . $tmp_name; //active theme root directory
31
+ $plugin_tmp_path = WISHSUITE_DIR . 'includes/templates/' . $tmp_name;
32
+
33
+ $located = locate_template( [ $woo_tmp_path, $theme_tmp_path ] );
34
+
35
+ if ( ! $located && file_exists( $plugin_tmp_path ) ) {
36
+ return apply_filters( 'wishsuite_locate_template', $plugin_tmp_path, $tmp_name );
37
+ }
38
+
39
+ return apply_filters( 'wishsuite_locate_template', $located, $tmp_name );
40
+ }
41
+
42
+ /**
43
+ * [wishsuite_get_template]
44
+ * @param [string] $tmp_name Template name
45
+ * @param [array] $args template argument array
46
+ * @param boolean $echo
47
+ * @return [void]
48
+ */
49
+ function wishsuite_get_template( $tmp_name, $args = null, $echo = true ) {
50
+ $located = wishsuite_locate_template( $tmp_name );
51
+
52
+ if ( $args && is_array( $args ) ) {
53
+ extract( $args );
54
+ }
55
+
56
+ if ( $echo !== true ) { ob_start(); }
57
+
58
+ // include file located.
59
+ include( $located );
60
+
61
+ if ( $echo !== true ) { return ob_get_clean(); }
62
+
63
+ }
64
+
65
+ /**
66
+ * [wishsuite_get_page_url]
67
+ * @return [URL]
68
+ */
69
+ function wishsuite_get_page_url() {
70
+ $page_id = woolentor_get_option( 'wishlist_page', 'wishsuite_table_settings_tabs' );
71
+ return get_permalink( $page_id );
72
+ }
73
+
74
+ /**
75
+ * [wishsuite_add_to_cart]
76
+ * @param [object] $product
77
+ * @return [HTML]
78
+ */
79
+ function wishsuite_add_to_cart( $product, $quentity ){
80
+ return \WishSuite\Frontend\Manage_Wishlist::instance()->add_to_cart_html( $product, $quentity );
81
+ }
82
+
83
+ /**
84
+ * Get default fields List
85
+ * return array
86
+ */
87
+ function wishsuite_get_default_fields(){
88
+ $fields = array(
89
+ 'remove' => esc_html__( 'Remove', 'wishsuite' ),
90
+ 'image' => esc_html__( 'Image', 'wishsuite' ),
91
+ 'title' => esc_html__( 'Title', 'wishsuite' ),
92
+ 'price' => esc_html__( 'Price', 'wishsuite' ),
93
+ 'quantity' => esc_html__( 'Quantity', 'wishsuite' ),
94
+ 'add_to_cart' => esc_html__( 'Add To Cart', 'wishsuite' ),
95
+ 'description' => esc_html__( 'Description', 'wishsuite' ),
96
+ 'availability'=> esc_html__( 'Availability', 'wishsuite' ),
97
+ 'sku' => esc_html__( 'Sku', 'wishsuite' ),
98
+ 'weight' => esc_html__( 'Weight', 'wishsuite' ),
99
+ 'dimensions' => esc_html__( 'Dimensions', 'wishsuite' ),
100
+ );
101
+ return apply_filters( 'wishsuite_default_fields', $fields );
102
+ }
103
+
104
+ /**
105
+ * [wishsuite_table_active_heading]
106
+ * @return [array]
107
+ */
108
+ function wishsuite_table_active_heading(){
109
+ $active_heading = !empty( woolentor_get_option( 'show_fields', 'wishsuite_table_settings_tabs' ) ) ? woolentor_get_option( 'show_fields', 'wishsuite_table_settings_tabs' ) : array();
110
+ return $active_heading;
111
+ }
112
+
113
+ /**
114
+ * [wishsuite_table_heading]
115
+ * @return [array]
116
+ */
117
+ function wishsuite_table_heading(){
118
+ $new_list = array();
119
+
120
+ $active_default_fields = array(
121
+ 'remove' => esc_html__( 'Remove', 'wishsuite' ),
122
+ 'image' => esc_html__( 'Image', 'wishsuite' ),
123
+ 'title' => esc_html__( 'Title', 'wishsuite' ),
124
+ 'price' => esc_html__( 'Price', 'wishsuite' ),
125
+ 'quantity' => esc_html__( 'Quantity', 'wishsuite' ),
126
+ 'add_to_cart' => esc_html__( 'Add To Cart', 'wishsuite' ),
127
+ );
128
+
129
+ $field_list = count( wishsuite_table_active_heading() ) > 0 ? wishsuite_table_active_heading() : $active_default_fields;
130
+ foreach ( $field_list as $key => $value ) {
131
+ $new_list[$key] = \WishSuite\Frontend\Manage_Wishlist::instance()->field_name( $key );
132
+ }
133
+ return $new_list;
134
+ }
135
+
136
+ /**
137
+ * Get Post List
138
+ * return array
139
+ */
140
+ function wishsuite_get_available_attributes() {
141
+ $attribute_list = array();
142
+
143
+ if( function_exists( 'wc_get_attribute_taxonomies' ) ) {
144
+ $attribute_list = wc_get_attribute_taxonomies();
145
+ }
146
+
147
+ $fields = wishsuite_get_default_fields();
148
+
149
+ if ( count( $attribute_list ) > 0 ) {
150
+ foreach ( $attribute_list as $attribute ) {
151
+ $fields[ 'pa_' . $attribute->attribute_name ] = $attribute->attribute_label;
152
+ }
153
+ }
154
+
155
+ return $fields;
156
+ }
157
+
158
+
159
+ /**
160
+ * [wishsuite_dimensions]
161
+ * @param [string] $key
162
+ * @param [string] $tab
163
+ * @return [String | Bool]
164
+ */
165
+ function wishsuite_dimensions( $key, $tab, $css_attr ){
166
+ $dimensions = !empty( woolentor_get_option( $key, $tab ) ) ? woolentor_get_option( $key, $tab ) : array();
167
+ if( !empty( $dimensions['top'] ) || !empty( $dimensions['right'] ) || !empty( $dimensions['bottom'] ) || !empty( $dimensions['left'] ) ){
168
+ $unit = empty( $dimensions['unit'] ) ? 'px' : $dimensions['unit'];
169
+ $css_attr .= ":{$dimensions['top']}{$unit} {$dimensions['right']}{$unit} {$dimensions['bottom']}{$unit} {$dimensions['left']}{$unit}";
170
+ return $css_attr.';';
171
+ }else{
172
+ return false;
173
+ }
174
+ }
175
+
176
+ /**
177
+ * [wishsuite_generate_css]
178
+ * @return [String | Bool]
179
+ */
180
+ function wishsuite_generate_css( $key, $tab, $css_attr ){
181
+ $field_value = !empty( woolentor_get_option( $key, $tab ) ) ? woolentor_get_option( $key, $tab ) : '';
182
+
183
+ if( !empty( $field_value ) ){
184
+ $css_attr .= ":{$field_value}";
185
+ return $css_attr.';';
186
+ }else{
187
+ return false;
188
+ }
189
+
190
+ }
includes/modules/wishlist/includes/templates/wishsuite-button-add.php ADDED
@@ -0,0 +1 @@
 
1
+ <a href="<?php echo esc_url( $button_url ); ?>" class="<?php echo $button_class; ?>" data-added-text="<?php echo esc_attr__( $button_added_text, 'wishsuite'); ?>" data-product_id="<?php echo esc_attr( $product_id ); ?>"><?php echo $button_text; ?></a>
includes/modules/wishlist/includes/templates/wishsuite-button-exist.php ADDED
@@ -0,0 +1 @@
 
1
+ <a href="<?php echo esc_url( $button_url ); ?>" class="wishsuite-btn-exist <?php echo $button_class; ?>" data-added-text="<?php echo esc_attr__( $button_exist_text, 'wishsuite'); ?>" data-product_id="<?php echo esc_attr( $product_id ); ?>"><?php echo $button_exist_text; ?></a>
includes/modules/wishlist/includes/templates/wishsuite-social-share.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
+
4
+ $idsString = is_array( $products_ids ) ? implode( ',',$products_ids ) : '';
5
+
6
+ $share_link = get_the_permalink() . '?wishsuitepids='.$idsString;
7
+ $share_title = get_the_title();
8
+
9
+ $thumb_id = get_post_thumbnail_id();
10
+ $thumb_url = wp_get_attachment_image_src( $thumb_id, 'thumbnail-size', true );
11
+
12
+ $social_button_list = [
13
+ 'facebook' => [
14
+ 'title' => esc_html__( 'Facebook', 'wishsuite' ),
15
+ 'url' => 'https://www.facebook.com/sharer/sharer.php?u='.$share_link,
16
+ ],
17
+ 'twitter' => [
18
+ 'title' => esc_html__( 'Twitter', 'wishsuite' ),
19
+ 'url' => 'https://twitter.com/share?url=' . $share_link.'&amp;text='.$share_title,
20
+ ],
21
+ 'pinterest' => [
22
+ 'title' => esc_html__( 'Pinterest', 'wishsuite' ),
23
+ 'url' => 'https://pinterest.com/pin/create/button/?url='.$share_link.'&media='.$thumb_url[0],
24
+ ],
25
+ 'linkedin' => [
26
+ 'title' => esc_html__( 'Linkedin', 'wishsuite' ),
27
+ 'url' => 'https://www.linkedin.com/shareArticle?mini=true&url='.$share_link.'&amp;title='.$share_title,
28
+ ],
29
+ 'email' => [
30
+ 'title' => esc_html__( 'Email', 'wishsuite' ),
31
+ 'url' => 'mailto:?subject='.esc_html__('Check%20this%20', 'wishsuite') . $share_link,
32
+ ],
33
+ 'reddit' => [
34
+ 'title' => esc_html__( 'Reddit', 'wishsuite' ),
35
+ 'url' => 'http://reddit.com/submit?url='.$share_link.'&amp;title='.$share_title,
36
+ ],
37
+ 'telegram' => [
38
+ 'title' => esc_html__( 'Telegram', 'wishsuite' ),
39
+ 'url' => 'https://telegram.me/share/url?url=' . $share_link,
40
+ ],
41
+ 'odnoklassniki' => [
42
+ 'title' => esc_html__( 'Odnoklassniki', 'wishsuite' ),
43
+ 'url' => 'https://www.odnoklassniki.ru/dk?st.cmd=addShare&st.s=1&st._surl=' . $share_link,
44
+ ],
45
+ 'whatsapp' => [
46
+ 'title' => esc_html__( 'WhatsApp', 'wishsuite' ),
47
+ 'url' => 'https://wa.me/?text=' . $share_link,
48
+ ],
49
+ 'vk' => [
50
+ 'title' => esc_html__( 'VK', 'wishsuite' ),
51
+ 'url' => 'https://vk.com/share.php?url=' . $share_link,
52
+ ],
53
+ ];
54
+
55
+
56
+ $default_buttons = [
57
+ 'facebook' => esc_html__( 'Facebook', 'wishsuite' ),
58
+ 'twitter' => esc_html__( 'Twitter', 'wishsuite' ),
59
+ 'pinterest' => esc_html__( 'Pinterest', 'wishsuite' ),
60
+ 'linkedin' => esc_html__( 'Linkedin', 'wishsuite' ),
61
+ 'telegram' => esc_html__( 'Telegram', 'wishsuite' ),
62
+ ];
63
+ $button_list = woolentor_get_option( 'social_share_buttons','wishsuite_table_settings_tabs', $default_buttons );
64
+ $button_text = woolentor_get_option( 'social_share_button_title','wishsuite_table_settings_tabs', 'Share:' );
65
+
66
+ $arrContextOptions = [
67
+ 'ssl' => [
68
+ 'verify_peer' => false,
69
+ 'verify_peer_name' => false,
70
+ ]
71
+ ];
72
+
73
+ ?>
74
+
75
+ <div class="wishsuite-social-share">
76
+ <span class="wishsuite-social-title"><?php esc_html_e( $button_text, 'wishsuite' ); ?></span>
77
+ <ul>
78
+ <?php
79
+ foreach ( $button_list as $buttonkey => $button ) {
80
+ ?>
81
+ <li>
82
+ <a rel="nofollow" href="<?php echo esc_url( $social_button_list[$buttonkey]['url'] ); ?>" <?php echo ( $buttonkey === 'email' ? '' : 'target="_blank"' ) ?>>
83
+ <span class="wishsuite-social-icon">
84
+ <?php echo file_get_contents( WISHSUITE_ASSETS .'/images/social-icon/'.$buttonkey.'.svg', false, stream_context_create($arrContextOptions) ); ?>
85
+ </span>
86
+ </a>
87
+ </li>
88
+ <?php
89
+ }
90
+ ?>
91
+ </ul>
92
+ </div>
includes/modules/wishlist/includes/templates/wishsuite-table.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="wishsuite-table-content">
2
+ <table class="wishsuite_table">
3
+ <thead>
4
+ <?php
5
+ $cell_count = 1;
6
+ if( !empty( $fields ) ){
7
+ $cell_count = count( $fields );
8
+ echo '<tr>';
9
+ foreach ( $fields as $field_id => $field ){
10
+ $name = $wishsuite->field_name( $field_id );
11
+ if( array_key_exists( $field_id, $heading_txt ) && !empty( $heading_txt[$field_id] ) ){
12
+ $name = $wishsuite->field_name( $heading_txt[$field_id], true );
13
+ }
14
+ echo '<th>'.$name.'</th>';
15
+ }
16
+ echo '</tr>';
17
+ }
18
+ ?>
19
+ </thead>
20
+ <tbody>
21
+ <?php
22
+ if( !empty( $products ) ):
23
+ foreach ( $products as $product_id => $product ):
24
+ ?>
25
+ <tr>
26
+ <?php foreach ( $fields as $field_id => $field ) : ?>
27
+ <td class="wishsuite-product-<?php echo esc_attr( $field_id ); ?>" data-label="<?php echo esc_attr( $wishsuite->field_name( $field_id ) ); ?>">
28
+ <?php $wishsuite->display_field( $field_id, $product ); ?>
29
+ </td>
30
+ <?php endforeach; ?>
31
+ </tr>
32
+
33
+ <?php endforeach; ?>
34
+ <tr class="wishsuite-empty-tr" style="display: none;">
35
+ <td class="wishsuite-emplty-text" colspan="<?php echo esc_attr( $cell_count ); ?>">
36
+ <?php if( !empty( $empty_text ) ){ echo wp_kses_post( $empty_text ); } ?>
37
+ </td>
38
+ </tr>
39
+ <?php else: ?>
40
+ <tr>
41
+ <td class="wishsuite-emplty-text" colspan="<?php echo esc_attr( $cell_count ); ?>">
42
+ <?php if( !empty( $empty_text ) ){ echo wp_kses_post( $empty_text ); } ?>
43
+ </td>
44
+ </tr>
45
+ <?php endif; ?>
46
+ </tbody>
47
+ </table>
48
+
49
+ <?php $wishsuite->social_share(); ?>
50
+
51
+ <div class="wishsuite-table-content-loader"></div>
52
+ </div>
includes/modules/wishlist/init.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
+
4
+ /**
5
+ * Plugin Main Class
6
+ */
7
+ final class Woolentor_WishSuite_Base{
8
+
9
+ /**
10
+ * [$_instance]
11
+ * @var null
12
+ */
13
+ private static $_instance = null;
14
+
15
+ /**
16
+ * [instance] Initializes a singleton instance
17
+ * @return [Base]
18
+ */
19
+ public static function instance() {
20
+ if ( is_null( self::$_instance ) ) {
21
+ self::$_instance = new self();
22
+ }
23
+ return self::$_instance;
24
+ }
25
+
26
+ /**
27
+ * [__construct] Class Constructor
28
+ */
29
+ private function __construct(){
30
+ $this->define_constants();
31
+ $this->includes();
32
+ if( get_option('woolentor_wishsuite_status', 'no') === 'no' ){
33
+ $this->activate();
34
+ update_option( 'woolentor_wishsuite_status','yes' );
35
+ }
36
+ $this->init_plugin();
37
+ }
38
+
39
+ /**
40
+ * Define the required plugin constants
41
+ *
42
+ * @return void
43
+ */
44
+ public function define_constants() {
45
+ define( 'WISHSUITE_FILE', __FILE__ );
46
+ define( 'WISHSUITE_URL', plugins_url( '', WISHSUITE_FILE ) );
47
+ define( 'WISHSUITE_DIR', plugin_dir_path( WISHSUITE_FILE ) );
48
+ define( 'WISHSUITE_ASSETS', WISHSUITE_URL . '/assets' );
49
+ define( 'WISHSUITE_BASE', plugin_basename( WISHSUITE_FILE ) );
50
+ }
51
+
52
+ /**
53
+ * [includes] Load file
54
+ * @return [void]
55
+ */
56
+ public function includes(){
57
+ require_once(__DIR__ . '/includes/classes/Installer.php');
58
+ require_once(__DIR__ . '/includes/helper-functions.php');
59
+ require_once( __DIR__. '/includes/classes/Manage_Data.php' );
60
+ require_once(__DIR__ . '/includes/classes/Assets.php');
61
+ require_once(__DIR__ . '/includes/classes/Admin.php');
62
+ require_once(__DIR__ . '/includes/classes/Frontend.php');
63
+ require_once(__DIR__ . '/includes/classes/Ajax.php');
64
+
65
+ }
66
+
67
+ /**
68
+ * Initialize the plugin
69
+ *
70
+ * @return void
71
+ */
72
+ public function init_plugin() {
73
+
74
+ WishSuite\Assets::instance();
75
+
76
+ if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
77
+ WishSuite\Ajax::instance();
78
+ }
79
+
80
+ if ( is_admin() ) {
81
+ WishSuite\Admin::instance();
82
+ }
83
+ WishSuite\Frontend::instance();
84
+
85
+ // add image size
86
+ $this->set_image_size();
87
+
88
+ // let's filter the woocommerce image size
89
+ add_filter( 'woocommerce_get_image_size_wishsuite-image', [ $this, 'wc_image_filter_size' ], 10, 1 );
90
+
91
+
92
+ }
93
+
94
+ /**
95
+ * Do stuff upon plugin activation
96
+ *
97
+ * @return void
98
+ */
99
+ public function activate() {
100
+ $installer = new WishSuite\Installer();
101
+ $installer->run();
102
+ }
103
+
104
+ /**
105
+ * [set_image_size] Set Image Size
106
+ */
107
+ public function set_image_size(){
108
+
109
+ $image_dimention = woolentor_get_option( 'image_size', 'wishsuite_table_settings_tabs', array( 'width'=>80,'height'=>80 ) );
110
+ if( isset( $image_dimention ) && is_array( $image_dimention ) ){
111
+ $hard_crop = !empty( woolentor_get_option( 'hard_crop', 'wishsuite_table_settings_tabs' ) ) ? true : false;
112
+ add_image_size( 'wishsuite-image', absint( $image_dimention['width'] ), absint( $image_dimention['height'] ), $hard_crop );
113
+ }
114
+
115
+ }
116
+
117
+ /**
118
+ * [wc_image_filter_size]
119
+ * @return [array]
120
+ */
121
+ public function wc_image_filter_size(){
122
+
123
+ $image_dimention = woolentor_get_option( 'image_size', 'wishsuite_table_settings_tabs', array( 'width'=>80,'height'=>80 ) );
124
+ $hard_crop = !empty( woolentor_get_option( 'hard_crop', 'wishsuite_table_settings_tabs' ) ) ? true : false;
125
+
126
+ if( isset( $image_dimention ) && is_array( $image_dimention ) ){
127
+ return array(
128
+ 'width' => isset( $image_dimention['width'] ) ? absint( $image_dimention['width'] ) : 80,
129
+ 'height' => isset( $image_dimention['height'] ) ? absint( $image_dimention['height'] ) : 80,
130
+ 'crop' => isset( $hard_crop ) ? 1 : 0,
131
+ );
132
+ }
133
+
134
+ }
135
+
136
+ }
137
+
138
+ /**
139
+ * Initializes the main plugin
140
+ *
141
+ * @return Woolentor_WishSuite_Base
142
+ */
143
+ function Woolentor_WishSuite() {
144
+ return Woolentor_WishSuite_Base::instance();
145
+ }
146
+ Woolentor_WishSuite();
languages/woolentor.pot CHANGED
@@ -3,7 +3,7 @@ msgid ""
3
  msgstr ""
4
  "Project-Id-Version: WooLentor - WooCommerce Elementor Addons + Builder\n"
5
  "Report-Msgid-Bugs-To: \n"
6
- "POT-Creation-Date: 2022-01-15 05:52+0000\n"
7
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
  "Language-Team: \n"
@@ -13,7 +13,7 @@ msgstr ""
13
  "Content-Type: text/plain; charset=UTF-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
  "X-Generator: Loco https://localise.biz/\n"
16
- "X-Loco-Version: 2.5.6; wp-5.8.3\n"
17
  "X-Domain: woolentor"
18
 
19
  #. 1: Plugin name 2: PHP 3: Required PHP version
@@ -303,8 +303,8 @@ msgstr ""
303
 
304
  #: includes/admin/include/template-library.php:262
305
  #: includes/admin/include/template-library.php:314
306
- #: includes/admin/include/class.extension-manager.php:182
307
- #: includes/admin/include/class.extension-manager.php:249
308
  msgid "Activate"
309
  msgstr ""
310
 
@@ -318,8 +318,8 @@ msgstr ""
318
 
319
  #: includes/admin/include/template-library.php:273
320
  #: includes/admin/include/template-library.php:325
321
- #: includes/admin/include/class.extension-manager.php:193
322
- #: includes/admin/include/class.extension-manager.php:260
323
  msgid "Activated"
324
  msgstr ""
325
 
@@ -343,7 +343,7 @@ msgstr ""
343
  msgid "Add ID Manually"
344
  msgstr ""
345
 
346
- #: includes/admin/include/admin_field-manager.php:315
347
  msgid "Add Item"
348
  msgstr ""
349
 
@@ -389,8 +389,8 @@ msgstr ""
389
  msgid "Add to Cart Button Text"
390
  msgstr ""
391
 
392
- #: includes/helper-function.php:811 includes/helper-function.php:812
393
- #: includes/helper-function.php:828
394
  #: woolentor-blocks/includes/helper-functions.php:312
395
  #: woolentor-blocks/includes/helper-functions.php:313
396
  #: woolentor-blocks/includes/helper-functions.php:329
@@ -442,15 +442,15 @@ msgstr ""
442
  msgid "After Title"
443
  msgstr ""
444
 
445
- #: includes/admin/include/admin_fields.php:1537
446
  msgid "AJAX Add to Cart on Single Product page"
447
  msgstr ""
448
 
449
- #: includes/admin/include/admin_fields.php:1529
450
  msgid "AJAX Search Widget"
451
  msgstr ""
452
 
453
- #: includes/admin/include/admin_fields.php:1528
454
  msgid "Ajax Search Widget"
455
  msgstr ""
456
 
@@ -550,7 +550,7 @@ msgstr ""
550
  msgid "Archive Layout Default"
551
  msgstr ""
552
 
553
- #: includes/admin/include/admin_fields.php:1775
554
  msgid "Archive List View Action Button"
555
  msgstr ""
556
 
@@ -709,7 +709,7 @@ msgstr ""
709
  msgid "Background Type"
710
  msgstr ""
711
 
712
- #: includes/admin/include/admin_fields.php:1738
713
  msgid "Badge color"
714
  msgstr ""
715
 
@@ -1021,11 +1021,11 @@ msgstr ""
1021
  msgid "Button"
1022
  msgstr ""
1023
 
1024
- #: includes/admin/include/admin_fields.php:1759
1025
  msgid "Button color"
1026
  msgstr ""
1027
 
1028
- #: includes/admin/include/admin_fields.php:1766
1029
  msgid "Button hover color"
1030
  msgstr ""
1031
 
@@ -1054,7 +1054,7 @@ msgstr ""
1054
  #: classes/class.assest_management.php:345
1055
  #: includes/admin/include/template-library.php:281
1056
  #: includes/admin/include/template-library.php:333
1057
- #: includes/admin/include/class.extension-manager.php:213
1058
  #: includes/admin/templates/dashboard-popup.php:14
1059
  msgid "Buy Now"
1060
  msgstr ""
@@ -1110,7 +1110,7 @@ msgid ""
1110
  msgstr ""
1111
 
1112
  #: classes/class.widgets_control.php:233
1113
- #: includes/admin/include/admin_fields.php:1677
1114
  msgid "Category"
1115
  msgstr ""
1116
 
@@ -1118,7 +1118,7 @@ msgstr ""
1118
  msgid "Category Color"
1119
  msgstr ""
1120
 
1121
- #: includes/admin/include/admin_fields.php:1682
1122
  msgid "Category color"
1123
  msgstr ""
1124
 
@@ -1136,7 +1136,7 @@ msgstr ""
1136
  msgid "Category Hover Color"
1137
  msgstr ""
1138
 
1139
- #: includes/admin/include/admin_fields.php:1689
1140
  msgid "Category hover color"
1141
  msgstr ""
1142
 
@@ -1388,15 +1388,18 @@ msgstr ""
1388
  msgid "Columns"
1389
  msgstr ""
1390
 
1391
- #: includes/helper-function.php:773
1392
  #: includes/addons/product_image_accordion.php:146
1393
  #: includes/addons/product_accordion.php:167
1394
  #: includes/addons/product_curvy.php:202 includes/addons/product_tabs.php:166
1395
  msgid "Comment count"
1396
  msgstr ""
1397
 
1398
- #: includes/helper-function.php:828
1399
  #: woolentor-blocks/includes/helper-functions.php:329
 
 
 
1400
  msgid "Compare"
1401
  msgstr ""
1402
 
@@ -1423,7 +1426,7 @@ msgstr ""
1423
  msgid "Content Area"
1424
  msgstr ""
1425
 
1426
- #: includes/admin/include/admin_fields.php:1626
1427
  msgid "Content area background"
1428
  msgstr ""
1429
 
@@ -1479,11 +1482,11 @@ msgstr ""
1479
  msgid "Countdown Timer Title"
1480
  msgstr ""
1481
 
1482
- #: includes/admin/include/admin_fields.php:1810
1483
  msgid "Counter Timer"
1484
  msgstr ""
1485
 
1486
- #: includes/admin/include/admin_fields.php:1815
1487
  msgid "Counter timer color"
1488
  msgstr ""
1489
 
@@ -1540,7 +1543,7 @@ msgstr ""
1540
  msgid "Customer Review"
1541
  msgstr ""
1542
 
1543
- #: includes/admin/admin-init.php:305
1544
  msgid "Data Fetch successfully!"
1545
  msgstr ""
1546
 
@@ -1548,7 +1551,7 @@ msgstr ""
1548
  msgid "Data Saved successfully!"
1549
  msgstr ""
1550
 
1551
- #: includes/helper-function.php:770 includes/addons/wb_product_upsell.php:62
1552
  #: includes/addons/wb_archive_product.php:127
1553
  #: includes/addons/product_image_accordion.php:143
1554
  #: includes/addons/wb_product_related.php:77
@@ -1566,29 +1569,29 @@ msgstr ""
1566
  msgid "Default"
1567
  msgstr ""
1568
 
1569
- #: includes/admin/include/admin_fields.php:1627
1570
- #: includes/admin/include/admin_fields.php:1641
1571
- #: includes/admin/include/admin_fields.php:1648
1572
- #: includes/admin/include/admin_fields.php:1662
1573
- #: includes/admin/include/admin_fields.php:1669
1574
- #: includes/admin/include/admin_fields.php:1683
1575
- #: includes/admin/include/admin_fields.php:1690
1576
- #: includes/admin/include/admin_fields.php:1704
1577
- #: includes/admin/include/admin_fields.php:1718
1578
- #: includes/admin/include/admin_fields.php:1725
1579
- #: includes/admin/include/admin_fields.php:1739
1580
- #: includes/admin/include/admin_fields.php:1753
1581
- #: includes/admin/include/admin_fields.php:1760
1582
- #: includes/admin/include/admin_fields.php:1767
1583
- #: includes/admin/include/admin_fields.php:1781
1584
- #: includes/admin/include/admin_fields.php:1788
1585
- #: includes/admin/include/admin_fields.php:1795
1586
- #: includes/admin/include/admin_fields.php:1802
1587
- #: includes/admin/include/admin_fields.php:1816
1588
  msgid "Default Color for universal layout."
1589
  msgstr ""
1590
 
1591
- #: includes/helper-function.php:584
1592
  msgid "Default sorting"
1593
  msgstr ""
1594
 
@@ -1620,7 +1623,7 @@ msgstr ""
1620
  msgid "Description"
1621
  msgstr ""
1622
 
1623
- #: includes/admin/include/admin_fields.php:1703
1624
  msgid "Description color"
1625
  msgstr ""
1626
 
@@ -1652,7 +1655,7 @@ msgstr ""
1652
  msgid "Discount Type"
1653
  msgstr ""
1654
 
1655
- #: includes/helper-function.php:424
1656
  msgid "div"
1657
  msgstr ""
1658
 
@@ -1664,8 +1667,8 @@ msgstr ""
1664
  msgid "Do you want to individual icon ?"
1665
  msgstr ""
1666
 
1667
- #: includes/admin/include/admin_field-manager.php:236
1668
- #: includes/admin/include/admin_field-manager.php:353
1669
  #: includes/admin/templates/dashboard-welcome.php:19
1670
  msgid "Documentation"
1671
  msgstr ""
@@ -1713,7 +1716,7 @@ msgstr ""
1713
  msgid "Elements"
1714
  msgstr ""
1715
 
1716
- #: includes/admin/include/class.extension-manager.php:131
1717
  msgid ""
1718
  "Email Candy is an outstanding WordPress plugin that allows you to customize "
1719
  "the default WooCommerce email templates and give a professional look to your "
@@ -1722,7 +1725,7 @@ msgid ""
1722
  "will come in handy."
1723
  msgstr ""
1724
 
1725
- #: includes/admin/include/class.extension-manager.php:128
1726
  msgid "Email Candy Pro - Email customizer for WooCommerce"
1727
  msgstr ""
1728
 
@@ -1744,7 +1747,7 @@ msgstr ""
1744
  msgid "Empty Rating Color"
1745
  msgstr ""
1746
 
1747
- #: includes/admin/include/admin_fields.php:1717
1748
  msgid "Empty rating color"
1749
  msgstr ""
1750
 
@@ -1795,7 +1798,9 @@ msgid "Enter your address to view shipping options."
1795
  msgstr ""
1796
 
1797
  #: includes/custom-metabox.php:26
1798
- msgid "Enter your preferred SaleFlash text. Ex: New / Free etc"
 
 
1799
  msgstr ""
1800
 
1801
  #: includes/addons/wb_product_suggest_price.php:177
@@ -1811,13 +1816,12 @@ msgstr ""
1811
  msgid "Event Name"
1812
  msgstr ""
1813
 
1814
- #: includes/admin/include/admin_fields.php:1869
1815
  msgid "Ever Compare"
1816
  msgstr ""
1817
 
1818
  #: classes/class.widgets_control.php:357
1819
  #: includes/addons/wb_ever_compare_table.php:45
1820
- #: includes/admin/include/class.extension-manager.php:71
1821
  msgid "EverCompare"
1822
  msgstr ""
1823
 
@@ -1919,7 +1923,7 @@ msgstr ""
1919
  msgid "FAQ Title"
1920
  msgstr ""
1921
 
1922
- #: includes/helper-function.php:775
1923
  msgid "Featured"
1924
  msgstr ""
1925
 
@@ -2053,7 +2057,7 @@ msgstr ""
2053
  msgid "Free"
2054
  msgstr ""
2055
 
2056
- #: includes/admin/include/class.extension-manager.php:159
2057
  msgid "Free extension"
2058
  msgstr ""
2059
 
@@ -2090,27 +2094,35 @@ msgstr ""
2090
  msgid "Gradient Color"
2091
  msgstr ""
2092
 
2093
- #: includes/helper-function.php:417
 
 
 
 
 
 
 
 
2094
  msgid "H1"
2095
  msgstr ""
2096
 
2097
- #: includes/helper-function.php:418
2098
  msgid "H2"
2099
  msgstr ""
2100
 
2101
- #: includes/helper-function.php:419
2102
  msgid "H3"
2103
  msgstr ""
2104
 
2105
- #: includes/helper-function.php:420
2106
  msgid "H4"
2107
  msgstr ""
2108
 
2109
- #: includes/helper-function.php:421
2110
  msgid "H5"
2111
  msgstr ""
2112
 
2113
- #: includes/helper-function.php:422
2114
  msgid "H6"
2115
  msgstr ""
2116
 
@@ -2177,7 +2189,7 @@ msgstr ""
2177
  msgid "Helping Screenshot"
2178
  msgstr ""
2179
 
2180
- #: includes/helper-function.php:703 includes/helper-function.php:721
2181
  msgid "here"
2182
  msgstr ""
2183
 
@@ -2351,7 +2363,7 @@ msgstr ""
2351
  msgid "Icon Width"
2352
  msgstr ""
2353
 
2354
- #: includes/helper-function.php:769
2355
  #: includes/addons/product_image_accordion.php:142
2356
  #: includes/addons/product_accordion.php:163
2357
  #: includes/addons/product_curvy.php:198 includes/addons/product_tabs.php:162
@@ -2461,8 +2473,8 @@ msgstr ""
2461
 
2462
  #: includes/admin/include/template-library.php:268
2463
  #: includes/admin/include/template-library.php:320
2464
- #: includes/admin/include/class.extension-manager.php:188
2465
- #: includes/admin/include/class.extension-manager.php:255
2466
  msgid "Install Now"
2467
  msgstr ""
2468
 
@@ -2514,15 +2526,15 @@ msgid "Justified"
2514
  msgstr ""
2515
 
2516
  #: classes/class.widgets_control.php:364 includes/addons/wb_just_table.php:44
2517
- #: includes/admin/include/admin_fields.php:1879
2518
  msgid "JustTable"
2519
  msgstr ""
2520
 
2521
- #: includes/admin/include/class.extension-manager.php:86
2522
  msgid "JustTables"
2523
  msgstr ""
2524
 
2525
- #: includes/admin/include/class.extension-manager.php:104
2526
  msgid ""
2527
  "JustTables is an incredible WordPress plugin that lets you showcase all your "
2528
  "WooCommerce products in a sortable and filterable table view. It allows your "
@@ -2532,7 +2544,7 @@ msgid ""
2532
  "sale on your online store."
2533
  msgstr ""
2534
 
2535
- #: includes/admin/include/class.extension-manager.php:101
2536
  msgid "JustTables Pro"
2537
  msgstr ""
2538
 
@@ -2637,23 +2649,23 @@ msgstr ""
2637
  msgid "List Item"
2638
  msgstr ""
2639
 
2640
- #: includes/admin/include/admin_fields.php:1794
2641
  msgid "List View Button background color"
2642
  msgstr ""
2643
 
2644
- #: includes/admin/include/admin_fields.php:1780
2645
  msgid "List View Button color"
2646
  msgstr ""
2647
 
2648
- #: includes/admin/include/admin_fields.php:1801
2649
  msgid "List View Button hover background color"
2650
  msgstr ""
2651
 
2652
- #: includes/admin/include/admin_fields.php:1787
2653
  msgid "List View Button Hover color"
2654
  msgstr ""
2655
 
2656
- #: includes/admin/include/admin_fields.php:1601
2657
  msgid "Load Products in Elementor Addons"
2658
  msgstr ""
2659
 
@@ -2868,25 +2880,25 @@ msgstr ""
2868
  msgid "Modules"
2869
  msgstr ""
2870
 
2871
- #: includes/admin/include/class.extension-manager.php:210
2872
- #: includes/admin/include/class.extension-manager.php:278
2873
  msgid "More Details"
2874
  msgstr ""
2875
 
2876
- #: includes/admin/include/admin_fields.php:1899
2877
- #: includes/admin/include/class.extension-manager.php:91
2878
  msgid "Multi Currency"
2879
  msgstr ""
2880
 
2881
- #: includes/admin/include/class.extension-manager.php:119
2882
  msgid "Multi Currency Pro for WooCommerce"
2883
  msgstr ""
2884
 
2885
- #: includes/admin/include/admin_fields.php:1589
2886
  msgid "Multi Step Checkout"
2887
  msgstr ""
2888
 
2889
- #: includes/admin/include/class.extension-manager.php:122
2890
  msgid ""
2891
  "Multi-Currency Pro for WooCommerce is a prominent currency switcher plugin "
2892
  "for WooCommerce. This plugin allows your website or online store visitors to "
@@ -2945,7 +2957,7 @@ msgstr ""
2945
  msgid "N/A"
2946
  msgstr ""
2947
 
2948
- #: includes/helper-function.php:771 includes/addons/wl_testimonial.php:78
2949
  #: includes/addons/wl_testimonial.php:572
2950
  #: includes/addons/product_image_accordion.php:144
2951
  #: includes/addons/product_accordion.php:165
@@ -3034,7 +3046,7 @@ msgstr ""
3034
  msgid "No Results Found"
3035
  msgstr ""
3036
 
3037
- #: includes/helper-function.php:282
3038
  msgid "No saved templates found."
3039
  msgstr ""
3040
 
@@ -3055,7 +3067,7 @@ msgstr ""
3055
  msgid "Nonce Varification Faild !"
3056
  msgstr ""
3057
 
3058
- #: includes/helper-function.php:768
3059
  #: includes/addons/product_image_accordion.php:141
3060
  #: includes/addons/product_accordion.php:162
3061
  #: includes/addons/product_curvy.php:197
@@ -3222,7 +3234,7 @@ msgid ""
3222
  "the pro version."
3223
  msgstr ""
3224
 
3225
- #: includes/helper-function.php:511 includes/helper-function.php:555
3226
  msgid "Out of stock"
3227
  msgstr ""
3228
 
@@ -3230,7 +3242,7 @@ msgstr ""
3230
  msgid "Override Sale Price"
3231
  msgstr ""
3232
 
3233
- #: includes/helper-function.php:423
3234
  msgid "p"
3235
  msgstr ""
3236
 
@@ -3296,11 +3308,11 @@ msgstr ""
3296
  msgid "Parent Item:"
3297
  msgstr ""
3298
 
3299
- #: includes/admin/include/admin_fields.php:1544
3300
  msgid "Partial Payment"
3301
  msgstr ""
3302
 
3303
- #: includes/admin/include/admin_fields.php:1545
3304
  msgid "Partial Payment Module"
3305
  msgstr ""
3306
 
@@ -3400,7 +3412,7 @@ msgstr ""
3400
  msgid "Position"
3401
  msgstr ""
3402
 
3403
- #: includes/admin/include/admin_fields.php:1843
3404
  msgid "Post Duplicator Condition"
3405
  msgstr ""
3406
 
@@ -3418,17 +3430,17 @@ msgctxt "Post Type Singular Name"
3418
  msgid "Template Builder"
3419
  msgstr ""
3420
 
3421
- #: includes/admin/include/admin_fields.php:1554
3422
  msgid "Pre Orders"
3423
  msgstr ""
3424
 
3425
- #: includes/admin/include/admin_fields.php:1555
3426
  msgid "Pre Orders Module"
3427
  msgstr ""
3428
 
3429
  #: classes/class.assest_management.php:346
3430
- #: includes/admin/include/admin_field-manager.php:235
3431
- #: includes/admin/include/admin_field-manager.php:352
3432
  msgid "Preview"
3433
  msgstr ""
3434
 
@@ -3439,7 +3451,7 @@ msgstr ""
3439
  #: includes/addons/wb_archive_product.php:402
3440
  #: includes/addons/wb_product_related.php:79
3441
  #: includes/addons/wl_product_filter.php:40
3442
- #: includes/admin/include/admin_fields.php:1656
3443
  msgid "Price"
3444
  msgstr ""
3445
 
@@ -3486,12 +3498,12 @@ msgstr ""
3486
  #: includes/admin/include/class.template-manager.php:374
3487
  #: includes/admin/include/admin_field-manager.php:99
3488
  #: includes/admin/include/admin_field-manager.php:218
3489
- #: includes/admin/include/admin_field-manager.php:333
3490
  #: includes/admin/include/templates_list.php:53
3491
  msgid "Pro"
3492
  msgstr ""
3493
 
3494
- #: includes/admin/include/class.extension-manager.php:160
3495
  msgid "Pro extension"
3496
  msgstr ""
3497
 
@@ -3503,7 +3515,7 @@ msgstr ""
3503
  msgid "Product Add To Cart"
3504
  msgstr ""
3505
 
3506
- #: includes/helper-function.php:813
3507
  #: woolentor-blocks/includes/helper-functions.php:314
3508
  msgid "Product Added"
3509
  msgstr ""
@@ -3524,7 +3536,7 @@ msgstr ""
3524
  msgid "Product Archive Page Template"
3525
  msgstr ""
3526
 
3527
- #: includes/custom-metabox.php:7 includes/admin/include/admin_fields.php:1733
3528
  msgid "Product Badge"
3529
  msgstr ""
3530
 
@@ -3673,7 +3685,7 @@ msgstr ""
3673
  msgid "Product Meta Info"
3674
  msgstr ""
3675
 
3676
- #: classes/class.widgets_control.php:302 includes/helper-function.php:776
3677
  #: includes/addons/product_image_accordion.php:407
3678
  #: includes/addons/product_accordion.php:485
3679
  #: includes/addons/product_curvy.php:478 includes/addons/product_tabs.php:1000
@@ -3737,7 +3749,7 @@ msgstr ""
3737
  msgid "Product Social Share"
3738
  msgstr ""
3739
 
3740
- #: includes/admin/include/admin_fields.php:1564
3741
  msgid "Product sticky Add to cart"
3742
  msgstr ""
3743
 
@@ -3845,7 +3857,7 @@ msgstr ""
3845
  msgid "Query Settings"
3846
  msgstr ""
3847
 
3848
- #: includes/admin/include/admin_fields.php:1747
3849
  msgid "Quick Action Button"
3850
  msgstr ""
3851
 
@@ -3853,7 +3865,7 @@ msgstr ""
3853
  msgid "Quick View Template"
3854
  msgstr ""
3855
 
3856
- #: includes/helper-function.php:774 includes/addons/wb_product_upsell.php:67
3857
  #: includes/addons/wb_archive_product.php:132
3858
  #: includes/addons/product_image_accordion.php:147
3859
  #: includes/addons/wb_product_related.php:82
@@ -3878,7 +3890,7 @@ msgstr ""
3878
  #: includes/addons/wb_archive_product.php:478
3879
  #: includes/addons/wb_product_related.php:81
3880
  #: includes/addons/wb_customer_review.php:557
3881
- #: includes/admin/include/admin_fields.php:1712
3882
  msgid "Rating"
3883
  msgstr ""
3884
 
@@ -3888,7 +3900,7 @@ msgstr ""
3888
  msgid "Rating Color"
3889
  msgstr ""
3890
 
3891
- #: includes/admin/include/admin_fields.php:1724
3892
  msgid "Rating color"
3893
  msgstr ""
3894
 
@@ -3933,7 +3945,7 @@ msgstr ""
3933
  msgid "Regular Price Color"
3934
  msgstr ""
3935
 
3936
- #: includes/admin/include/admin_fields.php:1668
3937
  msgid "Regular price color"
3938
  msgstr ""
3939
 
@@ -4102,7 +4114,7 @@ msgstr ""
4102
  msgid "Sale Price Color"
4103
  msgstr ""
4104
 
4105
- #: includes/admin/include/admin_fields.php:1661
4106
  msgid "Sale price color"
4107
  msgstr ""
4108
 
@@ -4116,7 +4128,7 @@ msgstr ""
4116
  msgid "Sale Tag"
4117
  msgstr ""
4118
 
4119
- #: includes/helper-function.php:508 includes/helper-function.php:550
4120
  msgid "Sale!"
4121
  msgstr ""
4122
 
@@ -4174,7 +4186,7 @@ msgstr ""
4174
  msgid "Sec"
4175
  msgstr ""
4176
 
4177
- #: includes/helper-function.php:259
4178
  msgid "Select"
4179
  msgstr ""
4180
 
@@ -4266,7 +4278,7 @@ msgstr ""
4266
  msgid "Select Table"
4267
  msgstr ""
4268
 
4269
- #: includes/helper-function.php:284 includes/addons/wl_faq.php:93
4270
  msgid "Select Template"
4271
  msgstr ""
4272
 
@@ -4306,7 +4318,7 @@ msgstr ""
4306
  msgid "Set the image position of the notification."
4307
  msgstr ""
4308
 
4309
- #: includes/helper-function.php:703 includes/helper-function.php:721
4310
  msgid "Set the initial stock amount from"
4311
  msgstr ""
4312
 
@@ -4318,7 +4330,7 @@ msgstr ""
4318
  msgid "Set the number of notifications to display."
4319
  msgstr ""
4320
 
4321
- #: includes/admin/include/admin_fields.php:1602
4322
  msgid "Set the number of products to load in Elementor Addons"
4323
  msgstr ""
4324
 
@@ -4390,7 +4402,7 @@ msgstr ""
4390
  msgid "Shopify Style Checkout"
4391
  msgstr ""
4392
 
4393
- #: includes/admin/include/admin_fields.php:1698
4394
  msgid "Short Description"
4395
  msgstr ""
4396
 
@@ -4447,7 +4459,7 @@ msgstr ""
4447
  msgid "Show/Display all products from each order"
4448
  msgstr ""
4449
 
4450
- #: includes/admin/include/admin_fields.php:1573
4451
  msgid "Side Mini Cart"
4452
  msgstr ""
4453
 
@@ -4466,7 +4478,7 @@ msgstr ""
4466
  msgid "Single Category"
4467
  msgstr ""
4468
 
4469
- #: includes/admin/include/admin_fields.php:1536
4470
  msgid "Single Product Ajax Add To Cart"
4471
  msgstr ""
4472
 
@@ -4588,7 +4600,7 @@ msgstr ""
4588
  msgid "Slider Option"
4589
  msgstr ""
4590
 
4591
- #: includes/helper-function.php:716
4592
  msgid "Sold"
4593
  msgstr ""
4594
 
@@ -4611,12 +4623,6 @@ msgid ""
4611
  "arrangements."
4612
  msgstr ""
4613
 
4614
- #: includes/modules/shopify-like-checkout/class.shopify-like-checkout.php:286
4615
- msgid ""
4616
- "Sorry, it seems that there are no available payment methods. Please contact "
4617
- "us if you require assistance or wish to make alternate arrangements."
4618
- msgstr ""
4619
-
4620
  #: includes/admin/include/template-library.php:391
4621
  msgid "Sorry, you are not allowed to install themes on this site."
4622
  msgstr ""
@@ -4628,23 +4634,23 @@ msgstr ""
4628
  msgid "Sort By"
4629
  msgstr ""
4630
 
4631
- #: includes/helper-function.php:586
4632
  msgid "Sort by average rating"
4633
  msgstr ""
4634
 
4635
- #: includes/helper-function.php:587
4636
  msgid "Sort by latest"
4637
  msgstr ""
4638
 
4639
- #: includes/helper-function.php:585
4640
  msgid "Sort by popularity"
4641
  msgstr ""
4642
 
4643
- #: includes/helper-function.php:589
4644
  msgid "Sort by price: high to low"
4645
  msgstr ""
4646
 
4647
- #: includes/helper-function.php:588
4648
  msgid "Sort by price: low to high"
4649
  msgstr ""
4650
 
@@ -4658,7 +4664,7 @@ msgstr ""
4658
  msgid "Spacing"
4659
  msgstr ""
4660
 
4661
- #: includes/helper-function.php:425
4662
  msgid "span"
4663
  msgstr ""
4664
 
@@ -4679,7 +4685,7 @@ msgstr ""
4679
  msgid "Start from $100"
4680
  msgstr ""
4681
 
4682
- #: includes/admin/include/admin_fields.php:1565
4683
  msgid "Sticky Add to Cart on Single Product page"
4684
  msgstr ""
4685
 
@@ -4813,7 +4819,7 @@ msgstr ""
4813
  msgid "Support"
4814
  msgstr ""
4815
 
4816
- #: includes/admin/include/class.extension-manager.php:76
4817
  msgid "Swatchly"
4818
  msgstr ""
4819
 
@@ -4913,7 +4919,7 @@ msgid "Template Settings"
4913
  msgstr ""
4914
 
4915
  #: includes/admin/include/class.template_cpt.php:30
4916
- #: includes/admin/include/admin_fields.php:1830
4917
  #: includes/admin/include/templates_list.php:33
4918
  msgid "Templates"
4919
  msgstr ""
@@ -5011,6 +5017,7 @@ msgstr ""
5011
  msgid "Theme Activated"
5012
  msgstr ""
5013
 
 
5014
  #: includes/modules/shopify-like-checkout/templates/cart-shipping.php:53
5015
  msgid ""
5016
  "There are no shipping options available. Please ensure that your address has "
@@ -5040,7 +5047,7 @@ msgstr ""
5040
  msgid "Time Interval"
5041
  msgstr ""
5042
 
5043
- #: includes/helper-function.php:772 includes/addons/wl_faq.php:64
5044
  #: includes/addons/wl_faq.php:338
5045
  #: includes/addons/wl_product_horizontal_filter.php:193
5046
  #: includes/addons/wl_product_horizontal_filter.php:366
@@ -5062,7 +5069,7 @@ msgstr ""
5062
  #: includes/addons/wb_image_marker.php:300 includes/addons/product_tabs.php:165
5063
  #: includes/addons/product_tabs.php:942 includes/addons/add_banner.php:147
5064
  #: includes/addons/wl_category_grid.php:539
5065
- #: includes/admin/include/admin_fields.php:1635
5066
  msgid "Title"
5067
  msgstr ""
5068
 
@@ -5078,7 +5085,7 @@ msgid "Title Color"
5078
  msgstr ""
5079
 
5080
  #: includes/addons/product_tabs.php:988 includes/addons/product_tabs.php:1070
5081
- #: includes/admin/include/admin_fields.php:1640
5082
  msgid "Title color"
5083
  msgstr ""
5084
 
@@ -5087,7 +5094,7 @@ msgstr ""
5087
  msgid "Title Hover Color"
5088
  msgstr ""
5089
 
5090
- #: includes/admin/include/admin_fields.php:1647
5091
  msgid "Title hover color"
5092
  msgstr ""
5093
 
@@ -5104,7 +5111,7 @@ msgstr ""
5104
  msgid "to"
5105
  msgstr ""
5106
 
5107
- #: includes/admin/include/admin_fields.php:1752
5108
  msgid "Tool tip color"
5109
  msgstr ""
5110
 
@@ -5119,7 +5126,7 @@ msgstr ""
5119
  msgid "Top Left"
5120
  msgstr ""
5121
 
5122
- #: includes/helper-function.php:778
5123
  msgid "Top Rated"
5124
  msgstr ""
5125
 
@@ -5133,7 +5140,7 @@ msgstr ""
5133
  msgid "Top Right"
5134
  msgstr ""
5135
 
5136
- #: includes/helper-function.php:777
5137
  msgid "Top Seller"
5138
  msgstr ""
5139
 
@@ -5223,7 +5230,7 @@ msgstr ""
5223
  msgid "Typography"
5224
  msgstr ""
5225
 
5226
- #: includes/admin/include/admin_fields.php:1620
5227
  msgid "Universal layout style options"
5228
  msgstr ""
5229
 
@@ -5341,12 +5348,12 @@ msgid "When to start notification load duration."
5341
  msgstr ""
5342
 
5343
  #: classes/class.widgets_control.php:371
5344
- #: includes/admin/include/admin_fields.php:1889
5345
- #: includes/admin/include/class.extension-manager.php:81
5346
  msgid "Whols"
5347
  msgstr ""
5348
 
5349
- #: includes/admin/include/class.extension-manager.php:113
5350
  msgid ""
5351
  "Whols is an outstanding WordPress plugin for WooCommerce that allows store "
5352
  "owners to set wholesale prices for the products of their online stores. This "
@@ -5357,7 +5364,7 @@ msgid ""
5357
  "manually or automatically."
5358
  msgstr ""
5359
 
5360
- #: includes/admin/include/class.extension-manager.php:110
5361
  msgid "Whols Pro – WooCommerce Wholesale Prices"
5362
  msgstr ""
5363
 
@@ -5372,13 +5379,18 @@ msgstr ""
5372
  msgid "Width for mobile"
5373
  msgstr ""
5374
 
 
 
 
 
 
 
5375
  #: includes/addons/wb_wishsuite_table.php:45
5376
- #: includes/admin/include/class.extension-manager.php:66
5377
  msgid "WishSuite"
5378
  msgstr ""
5379
 
5380
  #: classes/class.widgets_control.php:350
5381
- #: includes/admin/include/admin_fields.php:1859
5382
  msgid "WishSuite Table"
5383
  msgstr ""
5384
 
@@ -5673,7 +5685,7 @@ msgstr ""
5673
  msgid "You can enable / disable shopify style checkout page from here."
5674
  msgstr ""
5675
 
5676
- #: includes/admin/include/admin_fields.php:1844
5677
  msgid "You can enable duplicator for individual post."
5678
  msgstr ""
5679
 
3
  msgstr ""
4
  "Project-Id-Version: WooLentor - WooCommerce Elementor Addons + Builder\n"
5
  "Report-Msgid-Bugs-To: \n"
6
+ "POT-Creation-Date: 2022-01-20 09:16+0000\n"
7
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
8
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
9
  "Language-Team: \n"
13
  "Content-Type: text/plain; charset=UTF-8\n"
14
  "Content-Transfer-Encoding: 8bit\n"
15
  "X-Generator: Loco https://localise.biz/\n"
16
+ "X-Loco-Version: 2.5.7; wp-5.8.3\n"
17
  "X-Domain: woolentor"
18
 
19
  #. 1: Plugin name 2: PHP 3: Required PHP version
303
 
304
  #: includes/admin/include/template-library.php:262
305
  #: includes/admin/include/template-library.php:314
306
+ #: includes/admin/include/class.extension-manager.php:172
307
+ #: includes/admin/include/class.extension-manager.php:239
308
  msgid "Activate"
309
  msgstr ""
310
 
318
 
319
  #: includes/admin/include/template-library.php:273
320
  #: includes/admin/include/template-library.php:325
321
+ #: includes/admin/include/class.extension-manager.php:183
322
+ #: includes/admin/include/class.extension-manager.php:250
323
  msgid "Activated"
324
  msgstr ""
325
 
343
  msgid "Add ID Manually"
344
  msgstr ""
345
 
346
+ #: includes/admin/include/admin_field-manager.php:316
347
  msgid "Add Item"
348
  msgstr ""
349
 
389
  msgid "Add to Cart Button Text"
390
  msgstr ""
391
 
392
+ #: includes/helper-function.php:825 includes/helper-function.php:826
393
+ #: includes/helper-function.php:842
394
  #: woolentor-blocks/includes/helper-functions.php:312
395
  #: woolentor-blocks/includes/helper-functions.php:313
396
  #: woolentor-blocks/includes/helper-functions.php:329
442
  msgid "After Title"
443
  msgstr ""
444
 
445
+ #: includes/admin/include/admin_fields.php:1551
446
  msgid "AJAX Add to Cart on Single Product page"
447
  msgstr ""
448
 
449
+ #: includes/admin/include/admin_fields.php:1543
450
  msgid "AJAX Search Widget"
451
  msgstr ""
452
 
453
+ #: includes/admin/include/admin_fields.php:1542
454
  msgid "Ajax Search Widget"
455
  msgstr ""
456
 
550
  msgid "Archive Layout Default"
551
  msgstr ""
552
 
553
+ #: includes/admin/include/admin_fields.php:1799
554
  msgid "Archive List View Action Button"
555
  msgstr ""
556
 
709
  msgid "Background Type"
710
  msgstr ""
711
 
712
+ #: includes/admin/include/admin_fields.php:1762
713
  msgid "Badge color"
714
  msgstr ""
715
 
1021
  msgid "Button"
1022
  msgstr ""
1023
 
1024
+ #: includes/admin/include/admin_fields.php:1783
1025
  msgid "Button color"
1026
  msgstr ""
1027
 
1028
+ #: includes/admin/include/admin_fields.php:1790
1029
  msgid "Button hover color"
1030
  msgstr ""
1031
 
1054
  #: classes/class.assest_management.php:345
1055
  #: includes/admin/include/template-library.php:281
1056
  #: includes/admin/include/template-library.php:333
1057
+ #: includes/admin/include/class.extension-manager.php:203
1058
  #: includes/admin/templates/dashboard-popup.php:14
1059
  msgid "Buy Now"
1060
  msgstr ""
1110
  msgstr ""
1111
 
1112
  #: classes/class.widgets_control.php:233
1113
+ #: includes/admin/include/admin_fields.php:1701
1114
  msgid "Category"
1115
  msgstr ""
1116
 
1118
  msgid "Category Color"
1119
  msgstr ""
1120
 
1121
+ #: includes/admin/include/admin_fields.php:1706
1122
  msgid "Category color"
1123
  msgstr ""
1124
 
1136
  msgid "Category Hover Color"
1137
  msgstr ""
1138
 
1139
+ #: includes/admin/include/admin_fields.php:1713
1140
  msgid "Category hover color"
1141
  msgstr ""
1142
 
1388
  msgid "Columns"
1389
  msgstr ""
1390
 
1391
+ #: includes/helper-function.php:787
1392
  #: includes/addons/product_image_accordion.php:146
1393
  #: includes/addons/product_accordion.php:167
1394
  #: includes/addons/product_curvy.php:202 includes/addons/product_tabs.php:166
1395
  msgid "Comment count"
1396
  msgstr ""
1397
 
1398
+ #: includes/helper-function.php:842
1399
  #: woolentor-blocks/includes/helper-functions.php:329
1400
+ #: includes/admin/include/admin_fields.php:1535
1401
+ #: includes/modules/compare/includes/classes/Admin/Dashboard.php:59
1402
+ #: includes/modules/compare/includes/classes/Admin/Dashboard.php:60
1403
  msgid "Compare"
1404
  msgstr ""
1405
 
1426
  msgid "Content Area"
1427
  msgstr ""
1428
 
1429
+ #: includes/admin/include/admin_fields.php:1650
1430
  msgid "Content area background"
1431
  msgstr ""
1432
 
1482
  msgid "Countdown Timer Title"
1483
  msgstr ""
1484
 
1485
+ #: includes/admin/include/admin_fields.php:1834
1486
  msgid "Counter Timer"
1487
  msgstr ""
1488
 
1489
+ #: includes/admin/include/admin_fields.php:1839
1490
  msgid "Counter timer color"
1491
  msgstr ""
1492
 
1543
  msgid "Customer Review"
1544
  msgstr ""
1545
 
1546
+ #: includes/admin/admin-init.php:320
1547
  msgid "Data Fetch successfully!"
1548
  msgstr ""
1549
 
1551
  msgid "Data Saved successfully!"
1552
  msgstr ""
1553
 
1554
+ #: includes/helper-function.php:784 includes/addons/wb_product_upsell.php:62
1555
  #: includes/addons/wb_archive_product.php:127
1556
  #: includes/addons/product_image_accordion.php:143
1557
  #: includes/addons/wb_product_related.php:77
1569
  msgid "Default"
1570
  msgstr ""
1571
 
1572
+ #: includes/admin/include/admin_fields.php:1651
1573
+ #: includes/admin/include/admin_fields.php:1665
1574
+ #: includes/admin/include/admin_fields.php:1672
1575
+ #: includes/admin/include/admin_fields.php:1686
1576
+ #: includes/admin/include/admin_fields.php:1693
1577
+ #: includes/admin/include/admin_fields.php:1707
1578
+ #: includes/admin/include/admin_fields.php:1714
1579
+ #: includes/admin/include/admin_fields.php:1728
1580
+ #: includes/admin/include/admin_fields.php:1742
1581
+ #: includes/admin/include/admin_fields.php:1749
1582
+ #: includes/admin/include/admin_fields.php:1763
1583
+ #: includes/admin/include/admin_fields.php:1777
1584
+ #: includes/admin/include/admin_fields.php:1784
1585
+ #: includes/admin/include/admin_fields.php:1791
1586
+ #: includes/admin/include/admin_fields.php:1805
1587
+ #: includes/admin/include/admin_fields.php:1812
1588
+ #: includes/admin/include/admin_fields.php:1819
1589
+ #: includes/admin/include/admin_fields.php:1826
1590
+ #: includes/admin/include/admin_fields.php:1840
1591
  msgid "Default Color for universal layout."
1592
  msgstr ""
1593
 
1594
+ #: includes/helper-function.php:592
1595
  msgid "Default sorting"
1596
  msgstr ""
1597
 
1623
  msgid "Description"
1624
  msgstr ""
1625
 
1626
+ #: includes/admin/include/admin_fields.php:1727
1627
  msgid "Description color"
1628
  msgstr ""
1629
 
1655
  msgid "Discount Type"
1656
  msgstr ""
1657
 
1658
+ #: includes/helper-function.php:432
1659
  msgid "div"
1660
  msgstr ""
1661
 
1667
  msgid "Do you want to individual icon ?"
1668
  msgstr ""
1669
 
1670
+ #: includes/admin/include/admin_field-manager.php:237
1671
+ #: includes/admin/include/admin_field-manager.php:355
1672
  #: includes/admin/templates/dashboard-welcome.php:19
1673
  msgid "Documentation"
1674
  msgstr ""
1716
  msgid "Elements"
1717
  msgstr ""
1718
 
1719
+ #: includes/admin/include/class.extension-manager.php:121
1720
  msgid ""
1721
  "Email Candy is an outstanding WordPress plugin that allows you to customize "
1722
  "the default WooCommerce email templates and give a professional look to your "
1725
  "will come in handy."
1726
  msgstr ""
1727
 
1728
+ #: includes/admin/include/class.extension-manager.php:118
1729
  msgid "Email Candy Pro - Email customizer for WooCommerce"
1730
  msgstr ""
1731
 
1747
  msgid "Empty Rating Color"
1748
  msgstr ""
1749
 
1750
+ #: includes/admin/include/admin_fields.php:1741
1751
  msgid "Empty rating color"
1752
  msgstr ""
1753
 
1798
  msgstr ""
1799
 
1800
  #: includes/custom-metabox.php:26
1801
+ msgid ""
1802
+ "Enter your preferred Sale badge text. Ex: New / Free etc (Only for Universal "
1803
+ "layout addon)"
1804
  msgstr ""
1805
 
1806
  #: includes/addons/wb_product_suggest_price.php:177
1816
  msgid "Event Name"
1817
  msgstr ""
1818
 
1819
+ #: includes/admin/include/admin_fields.php:1893
1820
  msgid "Ever Compare"
1821
  msgstr ""
1822
 
1823
  #: classes/class.widgets_control.php:357
1824
  #: includes/addons/wb_ever_compare_table.php:45
 
1825
  msgid "EverCompare"
1826
  msgstr ""
1827
 
1923
  msgid "FAQ Title"
1924
  msgstr ""
1925
 
1926
+ #: includes/helper-function.php:789
1927
  msgid "Featured"
1928
  msgstr ""
1929
 
2057
  msgid "Free"
2058
  msgstr ""
2059
 
2060
+ #: includes/admin/include/class.extension-manager.php:149
2061
  msgid "Free extension"
2062
  msgstr ""
2063
 
2094
  msgid "Gradient Color"
2095
  msgstr ""
2096
 
2097
+ #: includes/admin/include/admin_fields.php:1578
2098
+ msgid "GTM Conversion Tracking"
2099
+ msgstr ""
2100
+
2101
+ #: includes/admin/include/admin_fields.php:1579
2102
+ msgid "GTM Conversion Tracking Module"
2103
+ msgstr ""
2104
+
2105
+ #: includes/helper-function.php:425
2106
  msgid "H1"
2107
  msgstr ""
2108
 
2109
+ #: includes/helper-function.php:426
2110
  msgid "H2"
2111
  msgstr ""
2112
 
2113
+ #: includes/helper-function.php:427
2114
  msgid "H3"
2115
  msgstr ""
2116
 
2117
+ #: includes/helper-function.php:428
2118
  msgid "H4"
2119
  msgstr ""
2120
 
2121
+ #: includes/helper-function.php:429
2122
  msgid "H5"
2123
  msgstr ""
2124
 
2125
+ #: includes/helper-function.php:430
2126
  msgid "H6"
2127
  msgstr ""
2128
 
2189
  msgid "Helping Screenshot"
2190
  msgstr ""
2191
 
2192
+ #: includes/helper-function.php:711 includes/helper-function.php:729
2193
  msgid "here"
2194
  msgstr ""
2195
 
2363
  msgid "Icon Width"
2364
  msgstr ""
2365
 
2366
+ #: includes/helper-function.php:783
2367
  #: includes/addons/product_image_accordion.php:142
2368
  #: includes/addons/product_accordion.php:163
2369
  #: includes/addons/product_curvy.php:198 includes/addons/product_tabs.php:162
2473
 
2474
  #: includes/admin/include/template-library.php:268
2475
  #: includes/admin/include/template-library.php:320
2476
+ #: includes/admin/include/class.extension-manager.php:178
2477
+ #: includes/admin/include/class.extension-manager.php:245
2478
  msgid "Install Now"
2479
  msgstr ""
2480
 
2526
  msgstr ""
2527
 
2528
  #: classes/class.widgets_control.php:364 includes/addons/wb_just_table.php:44
2529
+ #: includes/admin/include/admin_fields.php:1903
2530
  msgid "JustTable"
2531
  msgstr ""
2532
 
2533
+ #: includes/admin/include/class.extension-manager.php:76
2534
  msgid "JustTables"
2535
  msgstr ""
2536
 
2537
+ #: includes/admin/include/class.extension-manager.php:94
2538
  msgid ""
2539
  "JustTables is an incredible WordPress plugin that lets you showcase all your "
2540
  "WooCommerce products in a sortable and filterable table view. It allows your "
2544
  "sale on your online store."
2545
  msgstr ""
2546
 
2547
+ #: includes/admin/include/class.extension-manager.php:91
2548
  msgid "JustTables Pro"
2549
  msgstr ""
2550
 
2649
  msgid "List Item"
2650
  msgstr ""
2651
 
2652
+ #: includes/admin/include/admin_fields.php:1818
2653
  msgid "List View Button background color"
2654
  msgstr ""
2655
 
2656
+ #: includes/admin/include/admin_fields.php:1804
2657
  msgid "List View Button color"
2658
  msgstr ""
2659
 
2660
+ #: includes/admin/include/admin_fields.php:1825
2661
  msgid "List View Button hover background color"
2662
  msgstr ""
2663
 
2664
+ #: includes/admin/include/admin_fields.php:1811
2665
  msgid "List View Button Hover color"
2666
  msgstr ""
2667
 
2668
+ #: includes/admin/include/admin_fields.php:1625
2669
  msgid "Load Products in Elementor Addons"
2670
  msgstr ""
2671
 
2880
  msgid "Modules"
2881
  msgstr ""
2882
 
2883
+ #: includes/admin/include/class.extension-manager.php:200
2884
+ #: includes/admin/include/class.extension-manager.php:268
2885
  msgid "More Details"
2886
  msgstr ""
2887
 
2888
+ #: includes/admin/include/admin_fields.php:1923
2889
+ #: includes/admin/include/class.extension-manager.php:81
2890
  msgid "Multi Currency"
2891
  msgstr ""
2892
 
2893
+ #: includes/admin/include/class.extension-manager.php:109
2894
  msgid "Multi Currency Pro for WooCommerce"
2895
  msgstr ""
2896
 
2897
+ #: includes/admin/include/admin_fields.php:1613
2898
  msgid "Multi Step Checkout"
2899
  msgstr ""
2900
 
2901
+ #: includes/admin/include/class.extension-manager.php:112
2902
  msgid ""
2903
  "Multi-Currency Pro for WooCommerce is a prominent currency switcher plugin "
2904
  "for WooCommerce. This plugin allows your website or online store visitors to "
2957
  msgid "N/A"
2958
  msgstr ""
2959
 
2960
+ #: includes/helper-function.php:785 includes/addons/wl_testimonial.php:78
2961
  #: includes/addons/wl_testimonial.php:572
2962
  #: includes/addons/product_image_accordion.php:144
2963
  #: includes/addons/product_accordion.php:165
3046
  msgid "No Results Found"
3047
  msgstr ""
3048
 
3049
+ #: includes/helper-function.php:290
3050
  msgid "No saved templates found."
3051
  msgstr ""
3052
 
3067
  msgid "Nonce Varification Faild !"
3068
  msgstr ""
3069
 
3070
+ #: includes/helper-function.php:782
3071
  #: includes/addons/product_image_accordion.php:141
3072
  #: includes/addons/product_accordion.php:162
3073
  #: includes/addons/product_curvy.php:197
3234
  "the pro version."
3235
  msgstr ""
3236
 
3237
+ #: includes/helper-function.php:519 includes/helper-function.php:563
3238
  msgid "Out of stock"
3239
  msgstr ""
3240
 
3242
  msgid "Override Sale Price"
3243
  msgstr ""
3244
 
3245
+ #: includes/helper-function.php:431
3246
  msgid "p"
3247
  msgstr ""
3248
 
3308
  msgid "Parent Item:"
3309
  msgstr ""
3310
 
3311
+ #: includes/admin/include/admin_fields.php:1558
3312
  msgid "Partial Payment"
3313
  msgstr ""
3314
 
3315
+ #: includes/admin/include/admin_fields.php:1559
3316
  msgid "Partial Payment Module"
3317
  msgstr ""
3318
 
3412
  msgid "Position"
3413
  msgstr ""
3414
 
3415
+ #: includes/admin/include/admin_fields.php:1867
3416
  msgid "Post Duplicator Condition"
3417
  msgstr ""
3418
 
3430
  msgid "Template Builder"
3431
  msgstr ""
3432
 
3433
+ #: includes/admin/include/admin_fields.php:1568
3434
  msgid "Pre Orders"
3435
  msgstr ""
3436
 
3437
+ #: includes/admin/include/admin_fields.php:1569
3438
  msgid "Pre Orders Module"
3439
  msgstr ""
3440
 
3441
  #: classes/class.assest_management.php:346
3442
+ #: includes/admin/include/admin_field-manager.php:236
3443
+ #: includes/admin/include/admin_field-manager.php:354
3444
  msgid "Preview"
3445
  msgstr ""
3446
 
3451
  #: includes/addons/wb_archive_product.php:402
3452
  #: includes/addons/wb_product_related.php:79
3453
  #: includes/addons/wl_product_filter.php:40
3454
+ #: includes/admin/include/admin_fields.php:1680
3455
  msgid "Price"
3456
  msgstr ""
3457
 
3498
  #: includes/admin/include/class.template-manager.php:374
3499
  #: includes/admin/include/admin_field-manager.php:99
3500
  #: includes/admin/include/admin_field-manager.php:218
3501
+ #: includes/admin/include/admin_field-manager.php:334
3502
  #: includes/admin/include/templates_list.php:53
3503
  msgid "Pro"
3504
  msgstr ""
3505
 
3506
+ #: includes/admin/include/class.extension-manager.php:150
3507
  msgid "Pro extension"
3508
  msgstr ""
3509
 
3515
  msgid "Product Add To Cart"
3516
  msgstr ""
3517
 
3518
+ #: includes/helper-function.php:827
3519
  #: woolentor-blocks/includes/helper-functions.php:314
3520
  msgid "Product Added"
3521
  msgstr ""
3536
  msgid "Product Archive Page Template"
3537
  msgstr ""
3538
 
3539
+ #: includes/custom-metabox.php:7 includes/admin/include/admin_fields.php:1757
3540
  msgid "Product Badge"
3541
  msgstr ""
3542
 
3685
  msgid "Product Meta Info"
3686
  msgstr ""
3687
 
3688
+ #: classes/class.widgets_control.php:302 includes/helper-function.php:790
3689
  #: includes/addons/product_image_accordion.php:407
3690
  #: includes/addons/product_accordion.php:485
3691
  #: includes/addons/product_curvy.php:478 includes/addons/product_tabs.php:1000
3749
  msgid "Product Social Share"
3750
  msgstr ""
3751
 
3752
+ #: includes/admin/include/admin_fields.php:1588
3753
  msgid "Product sticky Add to cart"
3754
  msgstr ""
3755
 
3857
  msgid "Query Settings"
3858
  msgstr ""
3859
 
3860
+ #: includes/admin/include/admin_fields.php:1771
3861
  msgid "Quick Action Button"
3862
  msgstr ""
3863
 
3865
  msgid "Quick View Template"
3866
  msgstr ""
3867
 
3868
+ #: includes/helper-function.php:788 includes/addons/wb_product_upsell.php:67
3869
  #: includes/addons/wb_archive_product.php:132
3870
  #: includes/addons/product_image_accordion.php:147
3871
  #: includes/addons/wb_product_related.php:82
3890
  #: includes/addons/wb_archive_product.php:478
3891
  #: includes/addons/wb_product_related.php:81
3892
  #: includes/addons/wb_customer_review.php:557
3893
+ #: includes/admin/include/admin_fields.php:1736
3894
  msgid "Rating"
3895
  msgstr ""
3896
 
3900
  msgid "Rating Color"
3901
  msgstr ""
3902
 
3903
+ #: includes/admin/include/admin_fields.php:1748
3904
  msgid "Rating color"
3905
  msgstr ""
3906
 
3945
  msgid "Regular Price Color"
3946
  msgstr ""
3947
 
3948
+ #: includes/admin/include/admin_fields.php:1692
3949
  msgid "Regular price color"
3950
  msgstr ""
3951
 
4114
  msgid "Sale Price Color"
4115
  msgstr ""
4116
 
4117
+ #: includes/admin/include/admin_fields.php:1685
4118
  msgid "Sale price color"
4119
  msgstr ""
4120
 
4128
  msgid "Sale Tag"
4129
  msgstr ""
4130
 
4131
+ #: includes/helper-function.php:516 includes/helper-function.php:558
4132
  msgid "Sale!"
4133
  msgstr ""
4134
 
4186
  msgid "Sec"
4187
  msgstr ""
4188
 
4189
+ #: includes/helper-function.php:267
4190
  msgid "Select"
4191
  msgstr ""
4192
 
4278
  msgid "Select Table"
4279
  msgstr ""
4280
 
4281
+ #: includes/helper-function.php:292 includes/addons/wl_faq.php:93
4282
  msgid "Select Template"
4283
  msgstr ""
4284
 
4318
  msgid "Set the image position of the notification."
4319
  msgstr ""
4320
 
4321
+ #: includes/helper-function.php:711 includes/helper-function.php:729
4322
  msgid "Set the initial stock amount from"
4323
  msgstr ""
4324
 
4330
  msgid "Set the number of notifications to display."
4331
  msgstr ""
4332
 
4333
+ #: includes/admin/include/admin_fields.php:1626
4334
  msgid "Set the number of products to load in Elementor Addons"
4335
  msgstr ""
4336
 
4402
  msgid "Shopify Style Checkout"
4403
  msgstr ""
4404
 
4405
+ #: includes/admin/include/admin_fields.php:1722
4406
  msgid "Short Description"
4407
  msgstr ""
4408
 
4459
  msgid "Show/Display all products from each order"
4460
  msgstr ""
4461
 
4462
+ #: includes/admin/include/admin_fields.php:1597
4463
  msgid "Side Mini Cart"
4464
  msgstr ""
4465
 
4478
  msgid "Single Category"
4479
  msgstr ""
4480
 
4481
+ #: includes/admin/include/admin_fields.php:1550
4482
  msgid "Single Product Ajax Add To Cart"
4483
  msgstr ""
4484
 
4600
  msgid "Slider Option"
4601
  msgstr ""
4602
 
4603
+ #: includes/helper-function.php:724
4604
  msgid "Sold"
4605
  msgstr ""
4606
 
4623
  "arrangements."
4624
  msgstr ""
4625
 
 
 
 
 
 
 
4626
  #: includes/admin/include/template-library.php:391
4627
  msgid "Sorry, you are not allowed to install themes on this site."
4628
  msgstr ""
4634
  msgid "Sort By"
4635
  msgstr ""
4636
 
4637
+ #: includes/helper-function.php:594
4638
  msgid "Sort by average rating"
4639
  msgstr ""
4640
 
4641
+ #: includes/helper-function.php:595
4642
  msgid "Sort by latest"
4643
  msgstr ""
4644
 
4645
+ #: includes/helper-function.php:593
4646
  msgid "Sort by popularity"
4647
  msgstr ""
4648
 
4649
+ #: includes/helper-function.php:597
4650
  msgid "Sort by price: high to low"
4651
  msgstr ""
4652
 
4653
+ #: includes/helper-function.php:596
4654
  msgid "Sort by price: low to high"
4655
  msgstr ""
4656
 
4664
  msgid "Spacing"
4665
  msgstr ""
4666
 
4667
+ #: includes/helper-function.php:433
4668
  msgid "span"
4669
  msgstr ""
4670
 
4685
  msgid "Start from $100"
4686
  msgstr ""
4687
 
4688
+ #: includes/admin/include/admin_fields.php:1589
4689
  msgid "Sticky Add to Cart on Single Product page"
4690
  msgstr ""
4691
 
4819
  msgid "Support"
4820
  msgstr ""
4821
 
4822
+ #: includes/admin/include/class.extension-manager.php:66
4823
  msgid "Swatchly"
4824
  msgstr ""
4825
 
4919
  msgstr ""
4920
 
4921
  #: includes/admin/include/class.template_cpt.php:30
4922
+ #: includes/admin/include/admin_fields.php:1854
4923
  #: includes/admin/include/templates_list.php:33
4924
  msgid "Templates"
4925
  msgstr ""
5017
  msgid "Theme Activated"
5018
  msgstr ""
5019
 
5020
+ #: includes/modules/shopify-like-checkout/class.shopify-like-checkout.php:286
5021
  #: includes/modules/shopify-like-checkout/templates/cart-shipping.php:53
5022
  msgid ""
5023
  "There are no shipping options available. Please ensure that your address has "
5047
  msgid "Time Interval"
5048
  msgstr ""
5049
 
5050
+ #: includes/helper-function.php:786 includes/addons/wl_faq.php:64
5051
  #: includes/addons/wl_faq.php:338
5052
  #: includes/addons/wl_product_horizontal_filter.php:193
5053
  #: includes/addons/wl_product_horizontal_filter.php:366
5069
  #: includes/addons/wb_image_marker.php:300 includes/addons/product_tabs.php:165
5070
  #: includes/addons/product_tabs.php:942 includes/addons/add_banner.php:147
5071
  #: includes/addons/wl_category_grid.php:539
5072
+ #: includes/admin/include/admin_fields.php:1659
5073
  msgid "Title"
5074
  msgstr ""
5075
 
5085
  msgstr ""
5086
 
5087
  #: includes/addons/product_tabs.php:988 includes/addons/product_tabs.php:1070
5088
+ #: includes/admin/include/admin_fields.php:1664
5089
  msgid "Title color"
5090
  msgstr ""
5091
 
5094
  msgid "Title Hover Color"
5095
  msgstr ""
5096
 
5097
+ #: includes/admin/include/admin_fields.php:1671
5098
  msgid "Title hover color"
5099
  msgstr ""
5100
 
5111
  msgid "to"
5112
  msgstr ""
5113
 
5114
+ #: includes/admin/include/admin_fields.php:1776
5115
  msgid "Tool tip color"
5116
  msgstr ""
5117
 
5126
  msgid "Top Left"
5127
  msgstr ""
5128
 
5129
+ #: includes/helper-function.php:792
5130
  msgid "Top Rated"
5131
  msgstr ""
5132
 
5140
  msgid "Top Right"
5141
  msgstr ""
5142
 
5143
+ #: includes/helper-function.php:791
5144
  msgid "Top Seller"
5145
  msgstr ""
5146
 
5230
  msgid "Typography"
5231
  msgstr ""
5232
 
5233
+ #: includes/admin/include/admin_fields.php:1644
5234
  msgid "Universal layout style options"
5235
  msgstr ""
5236
 
5348
  msgstr ""
5349
 
5350
  #: classes/class.widgets_control.php:371
5351
+ #: includes/admin/include/admin_fields.php:1913
5352
+ #: includes/admin/include/class.extension-manager.php:71
5353
  msgid "Whols"
5354
  msgstr ""
5355
 
5356
+ #: includes/admin/include/class.extension-manager.php:103
5357
  msgid ""
5358
  "Whols is an outstanding WordPress plugin for WooCommerce that allows store "
5359
  "owners to set wholesale prices for the products of their online stores. This "
5364
  "manually or automatically."
5365
  msgstr ""
5366
 
5367
+ #: includes/admin/include/class.extension-manager.php:100
5368
  msgid "Whols Pro – WooCommerce Wholesale Prices"
5369
  msgstr ""
5370
 
5379
  msgid "Width for mobile"
5380
  msgstr ""
5381
 
5382
+ #: includes/admin/include/admin_fields.php:1528
5383
+ #: includes/modules/wishlist/includes/classes/Admin/Dashboard.php:65
5384
+ #: includes/modules/wishlist/includes/classes/Admin/Dashboard.php:66
5385
+ msgid "Wishlist"
5386
+ msgstr ""
5387
+
5388
  #: includes/addons/wb_wishsuite_table.php:45
 
5389
  msgid "WishSuite"
5390
  msgstr ""
5391
 
5392
  #: classes/class.widgets_control.php:350
5393
+ #: includes/admin/include/admin_fields.php:1883
5394
  msgid "WishSuite Table"
5395
  msgstr ""
5396
 
5685
  msgid "You can enable / disable shopify style checkout page from here."
5686
  msgstr ""
5687
 
5688
+ #: includes/admin/include/admin_fields.php:1868
5689
  msgid "You can enable duplicator for individual post."
5690
  msgstr ""
5691
 
readme.txt CHANGED
@@ -2,8 +2,8 @@
2
  Contributors: hasthemes, htplugins, devitemsllc, tarekht
3
  Tags: Elementor, WooCommerce, WooCommerce Elementor, WooCommerce Builder, WooCommerce Product
4
  Requires at least: 4.7
5
- Tested up to: 5.8.2
6
- Stable tag: 2.1.6
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
@@ -251,6 +251,9 @@ Customers may utilize the partial payment option to make a part payment since th
251
  <strong>Pre-Order Module (Pro)</strong>
252
  A preorder is a purchase in which a customer makes before the product officially becomes available. Pre-ordering is a powerful marketing module that lets you reserve items ahead of time and charge customers a deposit or full payment. Customers also enjoy pre-ordering as it ensures that they will obtain the product right after it has been released. The main benefit of utilizing a pre-order strategy is that it allows you to grow eCommerce sales and forecast consumer demand.
253
 
 
 
 
254
  == Extensions: ==
255
 
256
  <strong>❤️ [WishSuite for WooCommerce Wishlist](https://wordpress.org/plugins/wishsuite/)</strong>
@@ -334,6 +337,14 @@ Elementor Pro is not required. But you can use wooLentor with Elementor free & P
334
 
335
  == Changelog ==
336
 
 
 
 
 
 
 
 
 
337
  = Version: 2.1.6 - Date: 2022-01-15 =
338
  * Improved : Gutenberg Asset load on frontend site.
339
  * Solved : FlashSale Empty deals warning issue.
2
  Contributors: hasthemes, htplugins, devitemsllc, tarekht
3
  Tags: Elementor, WooCommerce, WooCommerce Elementor, WooCommerce Builder, WooCommerce Product
4
  Requires at least: 4.7
5
+ Tested up to: 5.9
6
+ Stable tag: 2.1.7
7
  License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
 
251
  <strong>Pre-Order Module (Pro)</strong>
252
  A preorder is a purchase in which a customer makes before the product officially becomes available. Pre-ordering is a powerful marketing module that lets you reserve items ahead of time and charge customers a deposit or full payment. Customers also enjoy pre-ordering as it ensures that they will obtain the product right after it has been released. The main benefit of utilizing a pre-order strategy is that it allows you to grow eCommerce sales and forecast consumer demand.
253
 
254
+ <strong>GTM Conversion Tracking (Google Tag Manager) Module (Pro)</strong>
255
+ GTM Conversion Tracking Module helps you keep track of conversions and assign them to specific sources. You may identify whether a sale was caused by a Google Ads/Facebook Ads, a direct website visit, or a social media post. When you link your store seamlessly with GTM, you'll generate more income from advertising by gathering precise sales data.
256
+
257
  == Extensions: ==
258
 
259
  <strong>❤️ [WishSuite for WooCommerce Wishlist](https://wordpress.org/plugins/wishsuite/)</strong>
337
 
338
  == Changelog ==
339
 
340
+ = Version: 2.1.7 - Date: 2022-01-24 =
341
+ * Added : Wishlist and compare module.
342
+ * Added : Flash Sale Addon.
343
+ * Solved : Shopify style checkout page shipping method empty message issue.
344
+ * Solved : Repeater field select2 style issue.
345
+ * Solved : Product showing issue in Module popup.
346
+ * Solved : Same Height box content area issue.
347
+
348
  = Version: 2.1.6 - Date: 2022-01-15 =
349
  * Improved : Gutenberg Asset load on frontend site.
350
  * Solved : FlashSale Empty deals warning issue.
woolentor_addons_elementor.php CHANGED
@@ -3,21 +3,21 @@
3
  * Plugin Name: WooLentor - WooCommerce Elementor Addons + Builder
4
  * Description: The WooCommerce elements library for Elementor page builder plugin for WordPress.
5
  * Plugin URI: https://woolentor.com/
6
- * Version: 2.1.6
7
  * Author: HasThemes
8
  * Author URI: https://hasthemes.com/plugins/woolentor-pro/
9
  * License: GPL-2.0+
10
  * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11
  * Text Domain: woolentor
12
  * Domain Path: /languages
13
- * WC tested up to: 6.1.0
14
  * Elementor tested up to: 3.5.3
15
  * Elementor Pro tested up to: 3.5.2
16
  */
17
 
18
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
19
 
20
- define( 'WOOLENTOR_VERSION', '2.1.6' );
21
  define( 'WOOLENTOR_ADDONS_PL_ROOT', __FILE__ );
22
  define( 'WOOLENTOR_ADDONS_PL_URL', plugins_url( '/', WOOLENTOR_ADDONS_PL_ROOT ) );
23
  define( 'WOOLENTOR_ADDONS_PL_PATH', plugin_dir_path( WOOLENTOR_ADDONS_PL_ROOT ) );
3
  * Plugin Name: WooLentor - WooCommerce Elementor Addons + Builder
4
  * Description: The WooCommerce elements library for Elementor page builder plugin for WordPress.
5
  * Plugin URI: https://woolentor.com/
6
+ * Version: 2.1.7
7
  * Author: HasThemes
8
  * Author URI: https://hasthemes.com/plugins/woolentor-pro/
9
  * License: GPL-2.0+
10
  * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
11
  * Text Domain: woolentor
12
  * Domain Path: /languages
13
+ * WC tested up to: 6.1.1
14
  * Elementor tested up to: 3.5.3
15
  * Elementor Pro tested up to: 3.5.2
16
  */
17
 
18
  if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
19
 
20
+ define( 'WOOLENTOR_VERSION', '2.1.7' );
21
  define( 'WOOLENTOR_ADDONS_PL_ROOT', __FILE__ );
22
  define( 'WOOLENTOR_ADDONS_PL_URL', plugins_url( '/', WOOLENTOR_ADDONS_PL_ROOT ) );
23
  define( 'WOOLENTOR_ADDONS_PL_PATH', plugin_dir_path( WOOLENTOR_ADDONS_PL_ROOT ) );