Ecwid Ecommerce Shopping Cart - Version 6.4.2

Version Description

  • Nov 21, 2018 =
  • Speedup for the store main page. We're working on making Ecwid stores load faster on WordPress sites. This update brings a set of loading speed improvements for some part of the stores. We will gradually roll out these enhancements to all users. No actions required from your side your store will get all of the improvements in this or upcoming releases. But if you ever noticed your store loading slowly, please contact us so we can help you enable this new feature on your site right now.
  • Fixed an issue in the plugin settings menu on Wordpress.com. Ecwid e-commerce plugin works on Wordpress.com sites as well. In the admin backend of WordPress.com sites, the plugin menu didn't look well some of the styles and colors were broken. We fixed it, now the plugin admin backend should work fine on both Wordpress.org and Wordpress.com installations.
  • Minor fixes and improvements.
Download this release

Release Info

Developer Ecwid
Plugin Icon 128x128 Ecwid Ecommerce Shopping Cart
Version 6.4.2
Comparing to
See all releases

Code changes from version 6.4.1 to 6.4.2

css/admin.css CHANGED
@@ -716,6 +716,35 @@ body[class*="_page_ecwid"] .ecwid-message {
716
  color: #ffffff;
717
  }
718
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
719
  .ecwid-admin-iframe .update-nag {
720
  display: none;
721
  }
716
  color: #ffffff;
717
  }
718
 
719
+ /* WP.com-ish styles */
720
+ #adminmenu #toplevel_page_ec-store.wpcom-menu .wp-submenu3 {
721
+ background: white;
722
+ }
723
+
724
+ #adminmenu #toplevel_page_ec-store.wpcom-menu .wp-has-submenu3:not(.wp-has-current-submenu3) .wp-submenu3 {
725
+ left: 273px;
726
+ }
727
+
728
+ #adminmenu #toplevel_page_ec-store.wpcom-menu .wp-submenu3 {
729
+ min-width: 200px;
730
+ }
731
+
732
+ #adminmenu #toplevel_page_ec-store.wpcom-menu .wp-submenu3 li:hover>a {
733
+ background: #f3f6f8;
734
+ }
735
+
736
+ #adminmenu #toplevel_page_ec-store.wpcom-menu .wp-has-submenu3:not(.wp-has-current-submenu3) .wp-submenu3>li>a {
737
+ padding-left: 18px;
738
+ }
739
+
740
+ #adminmenu #toplevel_page_ec-store.wpcom-menu .wp-has-submenu3.wp-has-current-submenu3 .wp-submenu3>li>a {
741
+ padding-left: 55px;
742
+ }
743
+
744
+ #adminmenu #toplevel_page_ec-store.wpcom-menu li.wp-has-submenu3.opensub:not(.wp-has-current-submenu3):after {
745
+ border: 0;
746
+ }
747
+
748
  .ecwid-admin-iframe .update-nag {
749
  display: none;
750
  }
css/frontend.css CHANGED
@@ -63,4 +63,21 @@ html#ecwid_html body#ecwid_body .ecwid table {
63
 
64
  .ecwid-random-product:not(.loaded) {
65
  min-height: 290px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  }
63
 
64
  .ecwid-random-product:not(.loaded) {
65
  min-height: 290px;
66
+ }
67
+
68
+ .ecwid-shopping-cart-categories {
69
+ min-height: 51px;
70
+ margin: 10px 0;
71
+ }
72
+
73
+ .ecwid-shopping-cart-search {
74
+ min-height: 42px;
75
+ }
76
+
77
+ #static-ecwid {
78
+ opacity: 0;
79
+ }
80
+
81
+ #dynamic-ecwid {
82
+ display: none;
83
  }
ecwid-shopping-cart.php CHANGED
@@ -5,7 +5,7 @@ Plugin URI: http://www.ecwid.com?source=wporg
5
  Description: Ecwid is a free full-featured shopping cart. It can be easily integrated with any Wordpress blog and takes less than 5 minutes to set up.
6
  Text Domain: ecwid-shopping-cart
7
  Author: Ecwid Ecommerce
8
- Version: 6.4.1
9
  Author URI: https://ecwid.to/ecwid-site
10
  */
11
 
@@ -118,6 +118,7 @@ require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-products.php';
118
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-config.php';
119
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-admin.php';
120
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-admin-main-page.php';
 
121
 
122
  if ( is_admin() ) {
123
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-help-page.php';
@@ -454,7 +455,7 @@ JS;
454
 
455
  function ecwid_load_textdomain() {
456
  load_plugin_textdomain( 'ecwid-shopping-cart', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
457
-
458
  }
459
 
460
  function ecwid_404_on_broken_escaped_fragment() {
@@ -471,6 +472,7 @@ function ecwid_404_on_broken_escaped_fragment() {
471
  $params = Ecwid_Seo_Links::maybe_extract_html_catalog_params();
472
  }
473
 
 
474
  if (isset($params['mode']) && !empty($params['mode']) && isset($params['id'])) {
475
  $result = array();
476
  $is_root_cat = $params['mode'] == 'category' && $params['id'] == 0;
@@ -681,6 +683,9 @@ function ecwid_check_version()
681
 
682
  // Since 6.2.x
683
  delete_option( 'force_scriptjs_render' );
 
 
 
684
 
685
  do_action( 'ecwid_on_plugin_update' );
686
 
@@ -848,8 +853,9 @@ function ecwid_seo_compatibility_restore()
848
  ecwid_override_option('aiosp_rewrite_titles');
849
  }
850
 
851
- function ecwid_check_api_cache()
852
- {
 
853
  $last_cache = get_option('ecwid_last_api_cache_check');
854
 
855
 
@@ -860,9 +866,11 @@ function ecwid_check_api_cache()
860
 
861
  function ecwid_admin_check_api_cache()
862
  {
863
- $last_cache = get_option('ecwid_last_api_cache_check');
 
 
864
 
865
- if (time() - $last_cache > MINUTE_IN_SECONDS * 5 ) {
866
  Ecwid_Api_V3::reset_api_status();
867
  }
868
 
@@ -881,14 +889,21 @@ function ecwid_invalidate_cache( $full_reset = false)
881
 
882
  function ecwid_regular_cache_check()
883
  {
884
- if (Ecwid_Api_V3::is_available()) {
 
 
 
 
885
  $api = new Ecwid_Api_V3();
886
 
887
  $stats = $api->get_store_update_stats();
888
 
 
 
889
  if ( $stats ) {
890
  EcwidPlatform::invalidate_products_cache_from( strtotime( $stats->productsUpdated ) );
891
  EcwidPlatform::invalidate_categories_cache_from( strtotime( $stats->categoriesUpdated ) );
 
892
  update_option( 'ecwid_last_api_cache_check', time() );
893
  }
894
  }
@@ -900,6 +915,7 @@ function ecwid_full_cache_reset()
900
 
901
  EcwidPlatform::invalidate_categories_cache_from( time() );
902
  EcwidPlatform::invalidate_products_cache_from( time() );
 
903
  EcwidPlatform::cache_reset( Ecwid_Api_V3::PROFILE_CACHE_NAME );
904
  EcwidPlatform::cache_reset( 'all_categories' );
905
 
@@ -1078,6 +1094,16 @@ function ecwid_meta() {
1078
  echo '<link href="https://ecwid-images-ru.gcdn.co" rel="preconnect" crossorigin />' . PHP_EOL;
1079
  echo '<link href="https://app.ecwid.com" rel="preconnect" crossorigin />' . PHP_EOL;
1080
 
 
 
 
 
 
 
 
 
 
 
1081
  if (ecwid_is_store_page_available()) {
1082
 
1083
  $store_id = get_ecwid_store_id();
@@ -1489,6 +1515,10 @@ function ecwid_get_scriptjs_params( $force_lang = null ) {
1489
  if ( class_exists( 'Ecwid_Importer' ) && get_option( Ecwid_Importer::OPTION_WOO_CATALOG_IMPORTED ) ) {
1490
  $params .= '&data_imported=1';
1491
  }
 
 
 
 
1492
 
1493
  return $params;
1494
  }
@@ -1620,6 +1650,7 @@ function ecwid_shortcode($attributes)
1620
 
1621
  $widgets_order = array('minicart', 'search', 'categories', 'productbrowser');
1622
  foreach ($widgets_order as $widget) {
 
1623
  if (in_array($widget, $widgets)) {
1624
  if ( class_exists( 'Ecwid_Shortcode_' . $widget ) ) {
1625
 
@@ -1686,7 +1717,7 @@ function ecwid_store_activate() {
1686
  $shortcode = Ecwid_Shortcode_Base::get_current_store_shortcode_name();
1687
 
1688
  $content = <<<EOT
1689
- [$shortcode]
1690
  EOT;
1691
 
1692
  $content = <<<EOT
@@ -1953,6 +1984,18 @@ function ecwid_get_update_params_options() {
1953
  'off',
1954
  'auto'
1955
  )
 
 
 
 
 
 
 
 
 
 
 
 
1956
  )
1957
  );
1958
 
@@ -2031,6 +2074,7 @@ function ecwid_register_admin_styles($hook_suffix) {
2031
 
2032
  wp_enqueue_style('ecwid-admin-css', ECWID_PLUGIN_URL . 'css/admin.css', array(), get_option('ecwid_plugin_version'));
2033
  wp_enqueue_style('ecwid-fonts-css', ECWID_PLUGIN_URL . 'css/fonts.css', array(), get_option('ecwid_plugin_version'));
 
2034
 
2035
  if (isset($_GET['page']) && strpos($_GET['page'], 'ec-store') === 0) {
2036
 
@@ -2046,7 +2090,6 @@ function ecwid_register_admin_styles($hook_suffix) {
2046
  );
2047
 
2048
  wp_enqueue_style('ecwid-landing-css', ECWID_PLUGIN_URL . 'css/landing.css', array(), get_option('ecwid_plugin_version'), 'all');
2049
- wp_enqueue_style('ecwid-landing-fonts', 'https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,300', array(), get_option('ecwid_plugin_version'));
2050
  } else {
2051
  // We already connected and disconnected the store, no need for fancy landing
2052
  wp_enqueue_script('ecwid-connect-js', ECWID_PLUGIN_URL . 'js/dashboard.js', array(), get_option('ecwid_plugin_version'));
@@ -2379,7 +2422,7 @@ function ecwid_admin_do_page( $page ) {
2379
  $page = $_GET['ec-store-page'];
2380
  }
2381
 
2382
- if ($page == ecwid_get_admin_iframe_upgrade_page()) {
2383
  update_option('ecwid_api_check_time', time() - ECWID_API_AVAILABILITY_CHECK_TIME + 10 * 60);
2384
  }
2385
 
@@ -2445,20 +2488,20 @@ function ecwid_admin_do_page( $page ) {
2445
 
2446
  function ecwid_admin_products_do_page() {
2447
  Ecwid_Admin_Main_Page::do_integrated_admin_page(
2448
- Ecwid_Admin_Main_Page::PAGE_PRODUCTS
2449
  );
2450
  }
2451
 
2452
  function ecwid_admin_orders_do_page() {
2453
  Ecwid_Admin_Main_Page::do_integrated_admin_page(
2454
- Ecwid_Admin_Main_Page::PAGE_ORDERS
2455
  );
2456
  }
2457
 
2458
 
2459
  function ecwid_admin_mobile_do_page() {
2460
  Ecwid_Admin_Main_Page::do_integrated_admin_page(
2461
- Ecwid_Admin_Main_Page::PAGE_MOBILE
2462
  );
2463
  }
2464
 
@@ -2659,10 +2702,6 @@ function get_reconnect_link() {
2659
  return admin_url('admin-post.php?action=ec_connect&reconnect&api_v3_sso');
2660
  }
2661
 
2662
- function ecwid_get_admin_iframe_upgrade_page() {
2663
- return 'billing:feature=sso&plan=ecwid_venture';
2664
- }
2665
-
2666
  function ecwid_debug_do_page() {
2667
 
2668
  if ( array_key_exists( 'reset_cache', $_GET ) ) {
@@ -2673,9 +2712,11 @@ function ecwid_debug_do_page() {
2673
 
2674
  global $ecwid_oauth;
2675
 
 
2676
  require_once ECWID_PLUGIN_DIR . 'templates/debug.php';
2677
  }
2678
 
 
2679
  function ecwid_get_debug_file() {
2680
  if (!current_user_can('manage_options')) {
2681
  return;
5
  Description: Ecwid is a free full-featured shopping cart. It can be easily integrated with any Wordpress blog and takes less than 5 minutes to set up.
6
  Text Domain: ecwid-shopping-cart
7
  Author: Ecwid Ecommerce
8
+ Version: 6.4.2
9
  Author URI: https://ecwid.to/ecwid-site
10
  */
11
 
118
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-config.php';
119
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-admin.php';
120
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-admin-main-page.php';
121
+ require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-static-home-page.php';
122
 
123
  if ( is_admin() ) {
124
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-help-page.php';
455
 
456
  function ecwid_load_textdomain() {
457
  load_plugin_textdomain( 'ecwid-shopping-cart', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' );
458
+ // )
459
  }
460
 
461
  function ecwid_404_on_broken_escaped_fragment() {
472
  $params = Ecwid_Seo_Links::maybe_extract_html_catalog_params();
473
  }
474
 
475
+
476
  if (isset($params['mode']) && !empty($params['mode']) && isset($params['id'])) {
477
  $result = array();
478
  $is_root_cat = $params['mode'] == 'category' && $params['id'] == 0;
683
 
684
  // Since 6.2.x
685
  delete_option( 'force_scriptjs_render' );
686
+
687
+ // Since 6.4.x
688
+ add_option( EcwidPlatform::OPTION_LOG_CACHE );
689
 
690
  do_action( 'ecwid_on_plugin_update' );
691
 
853
  ecwid_override_option('aiosp_rewrite_titles');
854
  }
855
 
856
+ function ecwid_check_api_cache() {
857
+ EcwidPlatform::cache_log_record( 'init', array() );
858
+
859
  $last_cache = get_option('ecwid_last_api_cache_check');
860
 
861
 
866
 
867
  function ecwid_admin_check_api_cache()
868
  {
869
+ EcwidPlatform::cache_log_record( 'admin_init', array() );
870
+
871
+ $last_cache = get_option( 'ecwid_last_api_cache_check' );
872
 
873
+ if ( time() - $last_cache > MINUTE_IN_SECONDS * 5 ) {
874
  Ecwid_Api_V3::reset_api_status();
875
  }
876
 
889
 
890
  function ecwid_regular_cache_check()
891
  {
892
+ static $already_checked = false;
893
+
894
+ if ( Ecwid_Api_V3::is_available() && !$already_checked ) {
895
+
896
+ $already_checked = true;
897
  $api = new Ecwid_Api_V3();
898
 
899
  $stats = $api->get_store_update_stats();
900
 
901
+ EcwidPlatform::cache_log_record('reg cache check', array( 'stats' => $stats ) );
902
+
903
  if ( $stats ) {
904
  EcwidPlatform::invalidate_products_cache_from( strtotime( $stats->productsUpdated ) );
905
  EcwidPlatform::invalidate_categories_cache_from( strtotime( $stats->categoriesUpdated ) );
906
+ EcwidPlatform::invalidate_profile_cache_from( strtotime( $stats->profileUpdated ) );
907
  update_option( 'ecwid_last_api_cache_check', time() );
908
  }
909
  }
915
 
916
  EcwidPlatform::invalidate_categories_cache_from( time() );
917
  EcwidPlatform::invalidate_products_cache_from( time() );
918
+ EcwidPlatform::invalidate_profile_cache_from( time() );
919
  EcwidPlatform::cache_reset( Ecwid_Api_V3::PROFILE_CACHE_NAME );
920
  EcwidPlatform::cache_reset( 'all_categories' );
921
 
1094
  echo '<link href="https://ecwid-images-ru.gcdn.co" rel="preconnect" crossorigin />' . PHP_EOL;
1095
  echo '<link href="https://app.ecwid.com" rel="preconnect" crossorigin />' . PHP_EOL;
1096
 
1097
+ if ( Ecwid_Static_Home_Page::is_enabled() && Ecwid_Static_Home_Page::get_data_for_current_page() ) {
1098
+ echo '<link href="https://d3j0zfs7paavns.cloudfront.net" rel="preconnect" crossorigin>' . PHP_EOL;
1099
+
1100
+ $data = Ecwid_Static_Home_Page::get_data_for_current_page();
1101
+
1102
+ foreach ( $data->cssFiles as $ind => $item ) {
1103
+ echo '<link rel="prefetch" href="' . $item . '">' . PHP_EOL;
1104
+ }
1105
+ }
1106
+
1107
  if (ecwid_is_store_page_available()) {
1108
 
1109
  $store_id = get_ecwid_store_id();
1515
  if ( class_exists( 'Ecwid_Importer' ) && get_option( Ecwid_Importer::OPTION_WOO_CATALOG_IMPORTED ) ) {
1516
  $params .= '&data_imported=1';
1517
  }
1518
+
1519
+ if ( Ecwid_Static_Home_Page::is_enabled() ) {
1520
+ $params .= '&data_static_home=1';
1521
+ }
1522
 
1523
  return $params;
1524
  }
1650
 
1651
  $widgets_order = array('minicart', 'search', 'categories', 'productbrowser');
1652
  foreach ($widgets_order as $widget) {
1653
+
1654
  if (in_array($widget, $widgets)) {
1655
  if ( class_exists( 'Ecwid_Shortcode_' . $widget ) ) {
1656
 
1717
  $shortcode = Ecwid_Shortcode_Base::get_current_store_shortcode_name();
1718
 
1719
  $content = <<<EOT
1720
+ [$shortcode widgets="productbrowser" default_category_id="0"]
1721
  EOT;
1722
 
1723
  $content = <<<EOT
1984
  'off',
1985
  'auto'
1986
  )
1987
+ ),
1988
+
1989
+ Ecwid_Static_Home_Page::OPTION_IS_ENABLED => array(
1990
+ 'values' => array(
1991
+ Ecwid_Static_Home_Page::OPTION_VALUE_AUTO,
1992
+ Ecwid_Static_Home_Page::OPTION_VALUE_ENABLED,
1993
+ Ecwid_Static_Home_Page::OPTION_VALUE_DISABLED
1994
+ )
1995
+ ),
1996
+
1997
+ 'ecwid_api_status' => array(
1998
+ 'type' => 'string'
1999
  )
2000
  );
2001
 
2074
 
2075
  wp_enqueue_style('ecwid-admin-css', ECWID_PLUGIN_URL . 'css/admin.css', array(), get_option('ecwid_plugin_version'));
2076
  wp_enqueue_style('ecwid-fonts-css', ECWID_PLUGIN_URL . 'css/fonts.css', array(), get_option('ecwid_plugin_version'));
2077
+ wp_enqueue_style('ecwid-opensans', 'https://fonts.googleapis.com/css?family=Open+Sans:400,600,700,300', array(), get_option('ecwid_plugin_version'));
2078
 
2079
  if (isset($_GET['page']) && strpos($_GET['page'], 'ec-store') === 0) {
2080
 
2090
  );
2091
 
2092
  wp_enqueue_style('ecwid-landing-css', ECWID_PLUGIN_URL . 'css/landing.css', array(), get_option('ecwid_plugin_version'), 'all');
 
2093
  } else {
2094
  // We already connected and disconnected the store, no need for fancy landing
2095
  wp_enqueue_script('ecwid-connect-js', ECWID_PLUGIN_URL . 'js/dashboard.js', array(), get_option('ecwid_plugin_version'));
2422
  $page = $_GET['ec-store-page'];
2423
  }
2424
 
2425
+ if ( $page == Ecwid_Admin_Main_Page::PAGE_HASH_UPGRADE ) {
2426
  update_option('ecwid_api_check_time', time() - ECWID_API_AVAILABILITY_CHECK_TIME + 10 * 60);
2427
  }
2428
 
2488
 
2489
  function ecwid_admin_products_do_page() {
2490
  Ecwid_Admin_Main_Page::do_integrated_admin_page(
2491
+ Ecwid_Admin_Main_Page::PAGE_HASH_PRODUCTS
2492
  );
2493
  }
2494
 
2495
  function ecwid_admin_orders_do_page() {
2496
  Ecwid_Admin_Main_Page::do_integrated_admin_page(
2497
+ Ecwid_Admin_Main_Page::PAGE_HASH_ORDERS
2498
  );
2499
  }
2500
 
2501
 
2502
  function ecwid_admin_mobile_do_page() {
2503
  Ecwid_Admin_Main_Page::do_integrated_admin_page(
2504
+ Ecwid_Admin_Main_Page::PAGE_HASH_MOBILE
2505
  );
2506
  }
2507
 
2702
  return admin_url('admin-post.php?action=ec_connect&reconnect&api_v3_sso');
2703
  }
2704
 
 
 
 
 
2705
  function ecwid_debug_do_page() {
2706
 
2707
  if ( array_key_exists( 'reset_cache', $_GET ) ) {
2712
 
2713
  global $ecwid_oauth;
2714
 
2715
+ require_once ECWID_PLUGIN_DIR . 'templates/cache_log.php';
2716
  require_once ECWID_PLUGIN_DIR . 'templates/debug.php';
2717
  }
2718
 
2719
+
2720
  function ecwid_get_debug_file() {
2721
  if (!current_user_can('manage_options')) {
2722
  return;
includes/class-ecwid-admin-main-page.php CHANGED
@@ -4,11 +4,12 @@ define( 'ECWID_ADMIN_TEMPLATES_DIR', ECWID_PLUGIN_DIR . '/templates/admin' );
4
 
5
  class Ecwid_Admin_Main_Page
6
  {
7
- const PAGE_DASHBOARD = 'dashboard';
8
- const PAGE_PRODUCTS = 'products';
9
- const PAGE_ORDERS = 'orders';
10
- const PAGE_MOBILE = 'mobile';
11
-
 
12
  public function do_page()
13
  {
14
  if ( $this->_is_forced_reconnect() ) {
@@ -76,13 +77,13 @@ class Ecwid_Admin_Main_Page
76
  && !Ecwid_Admin::disable_dashboard();
77
  }
78
 
79
- public static function do_integrated_admin_page( $page = self::PAGE_DASHBOARD )
80
  {
81
  $this_obj = new Ecwid_Admin_Main_Page();
82
  $this_obj->_do_integrated_admin_page( $page );
83
  }
84
 
85
- public function _do_integrated_admin_page( $page = self::PAGE_DASHBOARD )
86
  {
87
  if (isset($_GET['show_timeout']) && $_GET['show_timeout'] == '1') {
88
  require_once ECWID_PLUGIN_DIR . 'templates/admin-timeout.php';
@@ -104,11 +105,11 @@ class Ecwid_Admin_Main_Page
104
  $page = $_GET['ec-store-page'];
105
  }
106
 
107
- if ($page == ecwid_get_admin_iframe_upgrade_page()) {
108
  update_option('ecwid_api_check_time', time() - ECWID_API_AVAILABILITY_CHECK_TIME + 10 * 60);
109
  }
110
 
111
- if ($page == 'dashboard') {
112
  $show_reconnect = true;
113
  }
114
 
@@ -119,7 +120,7 @@ class Ecwid_Admin_Main_Page
119
  $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
120
 
121
  if (!$request) {
122
- echo Ecwid_Message_Manager::show_message('no_oauth');
123
  return;
124
  }
125
 
@@ -138,7 +139,7 @@ class Ecwid_Admin_Main_Page
138
 
139
  $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
140
  if (!$request) {
141
- echo Ecwid_Message_Manager::show_message('no_oauth');
142
  return;
143
  }
144
  $result = $request->do_request();
@@ -153,8 +154,12 @@ class Ecwid_Admin_Main_Page
153
  $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
154
  $result = $request->do_request();
155
  }
 
 
 
 
156
 
157
- if (empty($result['code']) && empty($result['data']) ) {
158
  require_once ECWID_PLUGIN_DIR . 'templates/admin-timeout.php';
159
  } else if ($result['code'] != 200) {
160
  if (ecwid_test_oauth(true)) {
@@ -167,6 +172,11 @@ class Ecwid_Admin_Main_Page
167
  }
168
  }
169
 
 
 
 
 
 
170
  protected function _do_simple_dashboard_page()
171
  {
172
  require_once ECWID_ADMIN_TEMPLATES_DIR . '/simple-dashboard.php';
4
 
5
  class Ecwid_Admin_Main_Page
6
  {
7
+ const PAGE_HASH_DASHBOARD = 'dashboard';
8
+ const PAGE_HASH_PRODUCTS = 'products';
9
+ const PAGE_HASH_ORDERS = 'orders';
10
+ const PAGE_HASH_MOBILE = 'mobile';
11
+ const PAGE_HASH_UPGRADE = 'billing:feature=sso&plan=ecwid_venture';
12
+
13
  public function do_page()
14
  {
15
  if ( $this->_is_forced_reconnect() ) {
77
  && !Ecwid_Admin::disable_dashboard();
78
  }
79
 
80
+ public static function do_integrated_admin_page( $page = self::PAGE_HASH_DASHBOARD )
81
  {
82
  $this_obj = new Ecwid_Admin_Main_Page();
83
  $this_obj->_do_integrated_admin_page( $page );
84
  }
85
 
86
+ public function _do_integrated_admin_page( $page = self::PAGE_HASH_DASHBOARD )
87
  {
88
  if (isset($_GET['show_timeout']) && $_GET['show_timeout'] == '1') {
89
  require_once ECWID_PLUGIN_DIR . 'templates/admin-timeout.php';
105
  $page = $_GET['ec-store-page'];
106
  }
107
 
108
+ if ( $page == self::PAGE_HASH_UPGRADE ) {
109
  update_option('ecwid_api_check_time', time() - ECWID_API_AVAILABILITY_CHECK_TIME + 10 * 60);
110
  }
111
 
112
+ if ( $page == self::PAGE_HASH_DASHBOARD ) {
113
  $show_reconnect = true;
114
  }
115
 
120
  $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
121
 
122
  if (!$request) {
123
+ Ecwid_Message_Manager::show_message('no_oauth');
124
  return;
125
  }
126
 
139
 
140
  $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
141
  if (!$request) {
142
+ Ecwid_Message_Manager::show_message('no_oauth');
143
  return;
144
  }
145
  $result = $request->do_request();
154
  $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
155
  $result = $request->do_request();
156
  }
157
+
158
+ if ( $result['code'] == 403 ) {
159
+ Ecwid_Api_V3::save_token('');
160
+ }
161
 
162
+ if ( empty( $result['code'] ) && empty( $result['data'] ) || $result['code'] == 500 ) {
163
  require_once ECWID_PLUGIN_DIR . 'templates/admin-timeout.php';
164
  } else if ($result['code'] != 200) {
165
  if (ecwid_test_oauth(true)) {
172
  }
173
  }
174
 
175
+ protected static function _get_upgrade_page_hash()
176
+ {
177
+ return 'billing:feature=sso&plan=ecwid_venture';
178
+ }
179
+
180
  protected function _do_simple_dashboard_page()
181
  {
182
  require_once ECWID_ADMIN_TEMPLATES_DIR . '/simple-dashboard.php';
includes/class-ecwid-static-home-page.php ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-product-browser.php';
4
+
5
+ class Ecwid_Static_Home_Page {
6
+
7
+ const OPTION_IS_ENABLED = 'ecwid_static_home_page_enabled';
8
+
9
+ const OPTION_VALUE_ENABLED = 'Y';
10
+ const OPTION_VALUE_DISABLED = 'N';
11
+ const OPTION_VALUE_AUTO = '';
12
+
13
+ const CACHE_DATA = 'static_home_page_data';
14
+ const PARAM_VALID_FROM = 'static_home_page_valid_from';
15
+
16
+ public function __construct() {
17
+
18
+ add_option( self::OPTION_IS_ENABLED );
19
+
20
+ if ( !is_admin() ) {
21
+ add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
22
+ }
23
+ }
24
+
25
+ public function enqueue_scripts()
26
+ {
27
+ if ( !self::is_enabled() ) {
28
+ return null;
29
+ }
30
+
31
+ $data = $this->get_data_for_current_page();
32
+
33
+ if ( !$data || !is_array( $data->cssFiles ) || empty ( $data->cssFiles ) ) return;
34
+
35
+ EcwidPlatform::enqueue_script( 'static-home-page' );
36
+
37
+ foreach ( $data->cssFiles as $ind => $item ) {
38
+ wp_enqueue_style( 'ecwid-static-home-page-' . $ind, $item );
39
+ }
40
+
41
+ wp_add_inline_script( 'ecwid-static-home-page', "window.ec.config.interactive = false;" );
42
+ }
43
+
44
+ public static function get_data_for_current_page()
45
+ {
46
+ if ( !self::is_enabled() ) {
47
+ return null;
48
+ }
49
+
50
+ if ( current_user_can( Ecwid_Admin::get_capability() ) ) {
51
+ EcwidPlatform::force_catalog_cache_reset();
52
+ }
53
+
54
+
55
+ if ( Ecwid_Seo_Links::is_enabled() && Ecwid_Seo_Links::is_product_browser_url() ) {
56
+ return null;
57
+ }
58
+
59
+ $data = self::_maybe_fetch_data();
60
+
61
+ if ( $data ) {
62
+ return $data;
63
+ }
64
+
65
+ return null;
66
+ }
67
+
68
+ protected static function _maybe_fetch_data()
69
+ {
70
+ $store_page_params = self::_get_store_page_params();
71
+ $params = array();
72
+
73
+ if ( Ecwid_Seo_Links::is_enabled() ) {
74
+ $params['clean_links'] = 'true';
75
+ $params['base_url'] = get_permalink();
76
+ }
77
+
78
+ foreach ( Ecwid_Product_Browser::get_attributes() as $attribute ) {
79
+ $name = $attribute['name'];
80
+ if ( @$attribute['is_storefront_api'] && isset( $store_page_params[$name] ) ) {
81
+ if ( @$attribute['type'] == 'boolean' ) {
82
+ $value = $store_page_params[$name] ? 'true' : 'false';
83
+ } else {
84
+ $value = $store_page_params[$name];
85
+ }
86
+
87
+ $params['tplvar_ec.storefront.' . $name] = $value;
88
+ }
89
+ }
90
+
91
+ $url = 'https://storefront.ecwid.com/home-page/' . get_ecwid_store_id() . '/static-code?';
92
+ foreach ( $params as $name => $value ) {
93
+ $url .= $name . '=' . urlencode( $value ) . '&';
94
+ }
95
+
96
+ $cached_data = EcwidPlatform::get_from_catalog_cache( $url );
97
+
98
+ if ( $cached_data ) {
99
+ return $cached_data;
100
+ }
101
+
102
+ $fetched_data = null;
103
+
104
+ $fetched_data = EcwidPlatform::fetch_url( $url, array( 'timeout' => 3 ) );
105
+
106
+
107
+ if ( $fetched_data && @$fetched_data['data'] ) {
108
+
109
+ $fetched_data = @json_decode( $fetched_data['data'] );
110
+ EcwidPlatform::store_in_catalog_cache( $url, $fetched_data );
111
+
112
+ return $fetched_data;
113
+ }
114
+
115
+ return null;
116
+ }
117
+
118
+ protected static function _get_store_params()
119
+ {
120
+ $store_id = get_ecwid_store_id();
121
+
122
+ $post = get_post();
123
+ if ( !$post ) {
124
+ return null;
125
+ }
126
+ $post_modified = strtotime( $post->post_modified_gmt );
127
+
128
+ $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
129
+ $lang = substr( $lang, 0, strpos( $lang, ';' ) );
130
+
131
+ $cache_key = "static_post_content $store_id $post->ID $post_modified $lang";
132
+
133
+ $store_params = EcwidPlatform::get_from_catalog_cache( $cache_key );
134
+
135
+ if ( !$store_params ) {
136
+ $store_params = self::_get_store_page_params();
137
+ }
138
+
139
+ $non_tplvar_params = array(
140
+ 'default_category_id',
141
+ 'lang'
142
+ );
143
+
144
+ $result = array();
145
+
146
+ foreach ( $store_params as $name => $value ) {
147
+ if ( in_array( $name, $non_tplvar_params ) ) {
148
+ $result[$name] = $value;
149
+ } else {
150
+ $result['tplvar_ec.storefront.' . $name] = $value;
151
+ }
152
+ }
153
+
154
+ return $result;
155
+ }
156
+
157
+
158
+ public static function is_enabled()
159
+ {
160
+ if ( !EcwidPlatform::is_catalog_cache_trusted() ) {
161
+ return false;
162
+ }
163
+
164
+ if ( get_option( self::OPTION_IS_ENABLED ) == self::OPTION_VALUE_ENABLED ) {
165
+ return true;
166
+ }
167
+
168
+ if ( !self::is_feature_available() ) {
169
+ return false;
170
+ }
171
+
172
+ if ( get_option( self::OPTION_IS_ENABLED ) == self::OPTION_VALUE_DISABLED ) {
173
+ return false;
174
+ }
175
+
176
+ return false;
177
+
178
+ if ( get_ecwid_store_id() > 15182050 && get_ecwid_store_id() % 10 == 0 ) {
179
+ return true;
180
+ }
181
+
182
+ return false;
183
+ }
184
+
185
+ public static function is_feature_available()
186
+ {
187
+ $api = new Ecwid_Api_V3();
188
+
189
+ return $api->is_store_feature_enabled( Ecwid_Api_V3::FEATURE_STATIC_HOME_PAGE )
190
+ && $api->is_store_feature_enabled( Ecwid_Api_V3::FEATURE_NEW_PRODUCT_LIST );
191
+ }
192
+
193
+ public static function save_store_page_params( $data ) {
194
+ $existing = self::_get_store_page_params();
195
+
196
+ $data = array_merge( $existing, $data );
197
+
198
+ EcwidPlatform::store_in_catalog_cache(
199
+ self::_get_store_page_data_key(),
200
+ $data
201
+ );
202
+ }
203
+
204
+ protected static function _get_store_page_params( ) {
205
+ $params = EcwidPlatform::get_from_catalog_cache( self::_get_store_page_data_key() );
206
+
207
+ if ( !empty( $params) ) return $params;
208
+
209
+ return array();
210
+ }
211
+
212
+ protected static function _get_store_page_data_key()
213
+ {
214
+ $post = get_post();
215
+ $lang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
216
+ $lang = substr( $lang, 0, strpos( $lang, ';' ) );
217
+
218
+ return get_ecwid_store_id() . '_' . $post->ID . '_' . $post->post_modified_gmt . '_' . $lang;
219
+
220
+ }
221
+ }
222
+
223
+ $__ecwid_static_home_page = new Ecwid_Static_Home_Page();
includes/class-ecwid-store-page.php CHANGED
@@ -7,6 +7,8 @@ class Ecwid_Store_Page {
7
  const OPTION_LAST_STORE_PAGE_ID = 'ecwid_last_store_page_id';
8
  const OPTION_FLUSH_REWRITES = 'ecwid_flush_rewrites';
9
  const WARMUP_ACTION = 'ecwid_warmup_store';
 
 
10
 
11
  protected static $_store_pages = false;
12
 
@@ -163,32 +165,6 @@ class Ecwid_Store_Page {
163
 
164
  return $page_id;
165
  }
166
-
167
- public static function save_store_page_data( $name, $value ) {
168
- $current = get_the_ID();
169
-
170
- $data = get_post_meta( $current, self::META_STORE_DATA, true );
171
-
172
- if (! is_array( $data ) ) {
173
- $data = array();
174
- }
175
-
176
- $data[$name] = $value;
177
-
178
- update_post_meta( $current, self::META_STORE_DATA, $data );
179
- }
180
-
181
- public static function get_store_page_data( $name ) {
182
- $current = get_the_ID();
183
-
184
- $data = get_post_meta( $current, self::META_STORE_DATA, true );
185
-
186
- if ( class_exists( 'Ecwid_Integration_Gutenberg' ) ) {
187
- $data = array_merge( $data, Ecwid_Integration_Gutenberg::get_store_block_data_from_current_page() );
188
- }
189
-
190
- return @$data[$name];
191
- }
192
 
193
  public static function is_store_page( $page_id = 0 ) {
194
 
7
  const OPTION_LAST_STORE_PAGE_ID = 'ecwid_last_store_page_id';
8
  const OPTION_FLUSH_REWRITES = 'ecwid_flush_rewrites';
9
  const WARMUP_ACTION = 'ecwid_warmup_store';
10
+
11
+ const META_STORE_DATA = 'ecwid_store';
12
 
13
  protected static $_store_pages = false;
14
 
165
 
166
  return $page_id;
167
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
  public static function is_store_page( $page_id = 0 ) {
170
 
includes/integrations/class-ecwid-integration-gutenberg.php CHANGED
@@ -8,7 +8,7 @@ class Ecwid_Integration_Gutenberg {
8
  const PRODUCT_BLOCK = 'ecwid/product-block';
9
 
10
  public function __construct() {
11
-
12
  if ( isset( $_GET['classic-editor'] ) ) return;
13
 
14
  add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
@@ -150,6 +150,8 @@ class Ecwid_Integration_Gutenberg {
150
  return '';
151
  }
152
 
 
 
153
  $params['widgets'] = 'productbrowser';
154
  if ( @$params['show_categories'] ) {
155
  $params['widgets'] .= ' categories';
@@ -158,20 +160,31 @@ class Ecwid_Integration_Gutenberg {
158
  $params['widgets'] .= ' search';
159
  }
160
 
161
- $result = ecwid_shortcode( $params );
162
- $result .= '<script type="text/javascript">
 
 
 
 
 
 
163
  window.ec = window.ec || Object();
164
  window.ec.storefront = window.ec.storefront || Object();
165
- ';
166
 
167
  $attributes = $this->_get_attributes_for_editor();
168
 
 
 
169
  foreach ( $attributes as $key => $attribute ) {
170
 
171
  $name = $attribute['name'];
172
  // we do not print defaults
173
- if ( !isset( $params[$name] ) ) continue;
174
-
 
 
 
175
  $value = $params[$name];
176
 
177
  if ( $name == 'show_description_under_image' ) {
@@ -199,10 +212,10 @@ class Ecwid_Integration_Gutenberg {
199
  } else {
200
  $result .= 'window.ec.storefront.' . $name . "='" . $value . "';" . PHP_EOL;
201
  }
 
202
  }
203
  }
204
 
205
-
206
  $colors = array();
207
  foreach ( array( 'foreground', 'background', 'link', 'price', 'button' ) as $kind ) {
208
  $color = @$params['chameleon_color_' . $kind];
@@ -230,6 +243,12 @@ class Ecwid_Integration_Gutenberg {
230
  if ( !isset( $chameleon['colors'] ) ) {
231
  $chameleon['colors'] = json_encode($colors);
232
  }
 
 
 
 
 
 
233
 
234
  if ( $chameleon['colors'] != 'auto' ) {
235
  $result .= <<<JS
8
  const PRODUCT_BLOCK = 'ecwid/product-block';
9
 
10
  public function __construct() {
11
+
12
  if ( isset( $_GET['classic-editor'] ) ) return;
13
 
14
  add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_block_editor_assets' ) );
150
  return '';
151
  }
152
 
153
+ $result = "[ecwid";
154
+
155
  $params['widgets'] = 'productbrowser';
156
  if ( @$params['show_categories'] ) {
157
  $params['widgets'] .= ' categories';
160
  $params['widgets'] .= ' search';
161
  }
162
 
163
+ foreach ($params as $key => $value) {
164
+ $result .= " $key='$value'";
165
+ }
166
+
167
+ $result .= ']';
168
+
169
+ $result .= <<<HTML
170
+ <script type="text/javascript">
171
  window.ec = window.ec || Object();
172
  window.ec.storefront = window.ec.storefront || Object();
173
+ HTML;
174
 
175
  $attributes = $this->_get_attributes_for_editor();
176
 
177
+ $store_page_data = array();
178
+
179
  foreach ( $attributes as $key => $attribute ) {
180
 
181
  $name = $attribute['name'];
182
  // we do not print defaults
183
+ if ( !isset( $params[$name] ) ) {
184
+ $store_page_data[$name] = $attribute['default'];
185
+ continue;
186
+ }
187
+
188
  $value = $params[$name];
189
 
190
  if ( $name == 'show_description_under_image' ) {
212
  } else {
213
  $result .= 'window.ec.storefront.' . $name . "='" . $value . "';" . PHP_EOL;
214
  }
215
+ $store_page_data[$name] = $value;
216
  }
217
  }
218
 
 
219
  $colors = array();
220
  foreach ( array( 'foreground', 'background', 'link', 'price', 'button' ) as $kind ) {
221
  $color = @$params['chameleon_color_' . $kind];
243
  if ( !isset( $chameleon['colors'] ) ) {
244
  $chameleon['colors'] = json_encode($colors);
245
  }
246
+
247
+ $store_page_data['chameleon-colors'] = $chameleon['colors'];
248
+
249
+ if ( Ecwid_Static_Home_Page::is_enabled() ) {
250
+ Ecwid_Static_Home_Page::save_store_page_params( $store_page_data );
251
+ }
252
 
253
  if ( $chameleon['colors'] != 'auto' ) {
254
  $result .= <<<JS
includes/shortcodes/class-ecwid-shortcode-base.php CHANGED
@@ -20,8 +20,9 @@ abstract class Ecwid_Shortcode_Base {
20
  if (isset($params['lang']) && $params['lang']) {
21
  $this->_lang = $params['lang'];
22
  }
 
23
  $this->_process_params( $params );
24
-
25
  if (!isset(self::$shortcodes[$this->get_shortcode_name()])) {
26
  self::$shortcodes[$this->get_shortcode_name()] = array();
27
  }
20
  if (isset($params['lang']) && $params['lang']) {
21
  $this->_lang = $params['lang'];
22
  }
23
+
24
  $this->_process_params( $params );
25
+
26
  if (!isset(self::$shortcodes[$this->get_shortcode_name()])) {
27
  self::$shortcodes[$this->get_shortcode_name()] = array();
28
  }
includes/shortcodes/class-ecwid-shortcode-productbrowser.php CHANGED
@@ -21,6 +21,7 @@ class Ecwid_Shortcode_ProductBrowser extends Ecwid_Shortcode_Base {
21
  }
22
 
23
  public function render() {
 
24
  Ecwid_Store_Page::add_store_page( get_the_ID() );
25
  if( current_user_can( Ecwid_Admin::get_capability() ) ) {
26
 
@@ -28,7 +29,27 @@ class Ecwid_Shortcode_ProductBrowser extends Ecwid_Shortcode_Base {
28
  $seo_links->check_base_urls_on_view_store_page_as_admin();
29
  }
30
 
31
- return parent::render();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
33
 
34
  public function render_placeholder( ) {
@@ -39,7 +60,7 @@ class Ecwid_Shortcode_ProductBrowser extends Ecwid_Shortcode_Base {
39
 
40
  $html_catalog_params = false;
41
 
42
- if ( Ecwid_Api_V3::is_available() ) {
43
 
44
  if (ecwid_should_display_escaped_fragment_catalog()) {
45
  $html_catalog_params = ecwid_parse_escaped_fragment($_GET['_escaped_fragment_']);
@@ -53,6 +74,18 @@ class Ecwid_Shortcode_ProductBrowser extends Ecwid_Shortcode_Base {
53
  $plain_content = $this->_build_html_catalog($store_id, $html_catalog_params);
54
  }
55
  }
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  $classname = $this->_get_html_class_name();
58
  $result = <<<HTML
21
  }
22
 
23
  public function render() {
24
+
25
  Ecwid_Store_Page::add_store_page( get_the_ID() );
26
  if( current_user_can( Ecwid_Admin::get_capability() ) ) {
27
 
29
  $seo_links->check_base_urls_on_view_store_page_as_admin();
30
  }
31
 
32
+ $default_render = parent::render();
33
+
34
+ $data = Ecwid_Static_Home_Page::get_data_for_current_page();
35
+ if ( !$data ) {
36
+ return $default_render;
37
+ }
38
+
39
+ $code = '<div id="static-ecwid">' . htmlspecialchars_decode( $data->htmlCode ) . '</div>';
40
+
41
+ $code .= '<div id="dynamic-ecwid">' . $default_render . '</div>';
42
+
43
+ $code .= <<<HTML
44
+ <script language="JavaScript">
45
+ EcwidStaticPageLoader.processStaticHomePage('static-ecwid', 'dynamic-ecwid');
46
+ if ( location.hash != '' ) {
47
+ EcwidStaticPageLoader.switchToDynamicMode();
48
+ }
49
+ </script>
50
+ HTML;
51
+
52
+ return $code;
53
  }
54
 
55
  public function render_placeholder( ) {
60
 
61
  $html_catalog_params = false;
62
 
63
+ if ( Ecwid_Api_V3::is_available() && !Ecwid_Static_Home_Page::get_data_for_current_page() ) {
64
 
65
  if (ecwid_should_display_escaped_fragment_catalog()) {
66
  $html_catalog_params = ecwid_parse_escaped_fragment($_GET['_escaped_fragment_']);
74
  $plain_content = $this->_build_html_catalog($store_id, $html_catalog_params);
75
  }
76
  }
77
+
78
+ if ( Ecwid_Static_Home_Page::is_enabled() ) {
79
+ $params = array();
80
+ if ( $this->_lang ) {
81
+ $params['lang'] = $this->_lang;
82
+ }
83
+ if ( @$this->_params['defaultCategoryId'] ) {
84
+ $params['default_category_id'] = $this->_params['defaultCategoryId'];
85
+ }
86
+
87
+ Ecwid_Static_Home_Page::save_store_page_params( $params );
88
+ }
89
 
90
  $classname = $this->_get_html_class_name();
91
  $result = <<<HTML
includes/themes.php CHANGED
@@ -112,6 +112,8 @@ function ecwid_apply_theme($theme_name = null)
112
  if ( in_array($theme_name, $custom_themes) ) {
113
  $theme_file = ECWID_THEMES_DIR . '/class-ecwid-theme-' . $theme_name . '.php';
114
  $theme_file = apply_filters( 'ecwid_get_theme_file', $theme_file );
 
 
115
  if ( !empty( $theme_file ) && is_file( $theme_file ) && is_readable( $theme_file ) ) {
116
  require_once( $theme_file );
117
  }
112
  if ( in_array($theme_name, $custom_themes) ) {
113
  $theme_file = ECWID_THEMES_DIR . '/class-ecwid-theme-' . $theme_name . '.php';
114
  $theme_file = apply_filters( 'ecwid_get_theme_file', $theme_file );
115
+ $theme_file = strtolower($theme_file);
116
+
117
  if ( !empty( $theme_file ) && is_file( $theme_file ) && is_readable( $theme_file ) ) {
118
  require_once( $theme_file );
119
  }
js/admin-menu.js CHANGED
@@ -172,5 +172,12 @@ jQuery(document).ready(function() {
172
  ecwidApplyIframeAdminMenu($link, {slug:'ec-store', url: 'admin.php?page=ec-store', hash:'dashboard'});
173
 
174
  }
 
 
 
 
 
 
 
175
  ecwidRefreshEcwidMenuItemSelection();
176
- });
172
  ecwidApplyIframeAdminMenu($link, {slug:'ec-store', url: 'admin.php?page=ec-store', hash:'dashboard'});
173
 
174
  }
175
+
176
+ if ( jQuery( '#calypsoify_wpadminmods_css-css' ).length > 0 ) {
177
+ jQuery('#toplevel_page_ec-store').addClass('wpcom-menu');
178
+ }
179
+ if ( jQuery( '#toplevel_page_ec-store .wp-submenu3 li.current' ).length > 0 ) {
180
+ jQuery('#toplevel_page_ec-store > a').addClass('wp-has-current-submenu');
181
+ }
182
  ecwidRefreshEcwidMenuItemSelection();
183
+ });
js/static-home-page.js ADDED
@@ -0,0 +1,255 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var EcwidStaticPageLoader = {
2
+ isTouchDevice: false,
3
+ staticId: null,
4
+ dynamicId: null,
5
+
6
+ find: function (selector) {
7
+ return document.querySelector(selector);
8
+ },
9
+
10
+ findAll: function (selector) {
11
+ return document.querySelectorAll(selector);
12
+ },
13
+
14
+ isVisible: function (elem) {
15
+ return !!(elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length);
16
+ },
17
+
18
+ forEach: function (elements, fn) {
19
+ return Array.prototype.forEach.call(elements, fn);
20
+ },
21
+
22
+ isRootCategory: function () {
23
+ return window.location.hash === '' || window.location.hash.indexOf("#!/c/0/") !== -1;
24
+ },
25
+
26
+ onDocumentReady: function (fn) {
27
+ if (document.attachEvent ? document.readyState === "complete" : document.readyState !== "loading") {
28
+ fn();
29
+ } else {
30
+ document.addEventListener('DOMContentLoaded', fn);
31
+ }
32
+ },
33
+
34
+ processStaticHomePage: function (staticId, dynamicId) {
35
+ this.staticId = staticId;
36
+ this.dynamicId = dynamicId;
37
+
38
+ this.onDocumentReady(function () {
39
+ if (!!('ontouchstart' in window)) {
40
+ this.isTouchDevice = true;
41
+ document.body.classList.add('touchable');
42
+ }
43
+
44
+ if (!EcwidStaticPageLoader.isRootCategory()) {
45
+ EcwidStaticPageLoader.hideStorefront();
46
+ EcwidStaticPageLoader.switchToDynamicMode();
47
+ return;
48
+ }
49
+
50
+ EcwidStaticPageLoader.hideStorefront();
51
+ EcwidStaticPageLoader.showStaticHtml();
52
+ EcwidStaticPageLoader.addStaticPageHandlers();
53
+
54
+ Ecwid.OnPageLoad.add(function (openedPage) {
55
+ var staticHtml = EcwidStaticPageLoader.find('#' + EcwidStaticPageLoader.staticId);
56
+ if (!EcwidStaticPageLoader.isVisible(staticHtml)) {
57
+ // if we've already switched to dynamic, we don't need to dispatch this event anymore
58
+ return;
59
+ }
60
+ if (openedPage.type == "CART"
61
+ || openedPage.type == "ORDERS"
62
+ || openedPage.type == "FAVORITES"
63
+ || openedPage.type == "SIGN_IN") {
64
+ // static links from bottom of the page should be processed before page load event finishes,
65
+ // so that pre-opening scroll didn't make the page jump
66
+ EcwidStaticPageLoader.switchToDynamicMode();
67
+ }
68
+ });
69
+
70
+ Ecwid.OnPageLoaded.add(function (openedPage) {
71
+ var staticHtml = EcwidStaticPageLoader.find('#' + EcwidStaticPageLoader.staticId);
72
+ if (!EcwidStaticPageLoader.isVisible(staticHtml)) {
73
+ // if we've already switched to dynamic, we don't need to dispatch this event anymore
74
+ return;
75
+ }
76
+ if (openedPage.type == "CATEGORY" && openedPage.categoryId == 0) {
77
+ // we don't need to dispatch root category loading,
78
+ // since our static contents covers it for the first time
79
+ return;
80
+ }
81
+ // other than that we must show opened page in dynamic view,
82
+ // because static view contains only root category page
83
+ EcwidStaticPageLoader.switchToDynamicModeDeferred();
84
+ });
85
+ });
86
+ },
87
+
88
+ addStaticPageHandlers: function () {
89
+ var categoryLinks = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .grid-category__card a');
90
+ if (categoryLinks.length > 0) {
91
+ EcwidStaticPageLoader.forEach(categoryLinks, function (element) {
92
+ var categoryId = element.getAttribute('data-category-id');
93
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('category', {'id': categoryId}));
94
+ });
95
+ }
96
+
97
+ var productLinks = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .grid-product a');
98
+ if (productLinks.length > 0) {
99
+ EcwidStaticPageLoader.forEach(productLinks, function (element) {
100
+ var productId = element.getAttribute('data-product-id');
101
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('product', {'id': productId}));
102
+ });
103
+ }
104
+
105
+ var buyNowLinks = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .grid-product__buy-now');
106
+ if (buyNowLinks.length > 0) {
107
+ EcwidStaticPageLoader.forEach(buyNowLinks, function (element) {
108
+ var productId = element.getAttribute('data-product-id');
109
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('product', {'id': productId}));
110
+ });
111
+ }
112
+
113
+ var trackOrdersLink = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .footer__link--track-order');
114
+ if (trackOrdersLink.length > 0) {
115
+ EcwidStaticPageLoader.forEach(trackOrdersLink, function (element) {
116
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('account/orders'));
117
+ });
118
+ }
119
+
120
+ var favoritesLink = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .footer__link--shopping-favorites');
121
+ if (favoritesLink.length > 0) {
122
+ EcwidStaticPageLoader.forEach(favoritesLink, function (element) {
123
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('account/favorites'));
124
+ });
125
+ }
126
+
127
+ var shoppingCartLink = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .footer__link--shopping-cart');
128
+ if (shoppingCartLink.length > 0) {
129
+ EcwidStaticPageLoader.forEach(shoppingCartLink, function (element) {
130
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('cart'));
131
+ });
132
+ }
133
+
134
+ var signInLink = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .footer__link--sigin-in');
135
+ if (signInLink.length > 0) {
136
+ EcwidStaticPageLoader.forEach(signInLink, function (element) {
137
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('signin'));
138
+ });
139
+ }
140
+
141
+ var pagerButtonLinks = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .pager__button');
142
+ if (pagerButtonLinks.length > 0) {
143
+ EcwidStaticPageLoader.forEach(pagerButtonLinks, function (element) {
144
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('category', {
145
+ 'id': 0,
146
+ 'page': 2
147
+ }));
148
+ });
149
+ }
150
+
151
+ var pagerNumberLinks = EcwidStaticPageLoader.findAll('#' + this.staticId + ' .pager__number');
152
+ if (pagerNumberLinks.length > 0) {
153
+ EcwidStaticPageLoader.forEach(pagerNumberLinks, function (element) {
154
+ var pageNumber = element.getAttribute('data-page-number');
155
+ EcwidStaticPageLoader.addStaticClickEvent(element, EcwidStaticPageLoader.openEcwidPage('category', {
156
+ 'id': 0,
157
+ 'page': pageNumber
158
+ }));
159
+ });
160
+ }
161
+ },
162
+
163
+ addStaticClickEvent: function (el, callback) {
164
+ var x = 0,
165
+ y = 0,
166
+ dx = 0,
167
+ dy = 0,
168
+ isTap = false;
169
+
170
+ if (this.isTouchDevice) {
171
+ el.addEventListener('touchstart', function (e) {
172
+ isTap = true;
173
+ x = e.originalEvent.touches[0].clientX;
174
+ y = e.originalEvent.touches[0].clientY;
175
+ dx = 0;
176
+ dy = 0;
177
+ }).addEventListener('touchmove', function (e) {
178
+ dx = e.originalEvent.changedTouches[0].clientX - x;
179
+ dy = e.originalEvent.changedTouches[0].clientY - y;
180
+ }).addEventListener('touchend', function (e) {
181
+ if (isTap && Math.abs(dx) < 10 && Math.abs(dy) < 10) {
182
+ callback.bind(this)(e);
183
+ }
184
+ });
185
+ }
186
+
187
+ el.addEventListener('click', function (e) {
188
+ if (!isTap) {
189
+ callback.bind(this)(e);
190
+ }
191
+ else {
192
+ isTap = false;
193
+ }
194
+ });
195
+ },
196
+
197
+ openEcwidPage: function (page, params) {
198
+ return function (e) {
199
+ e.preventDefault();
200
+ // we must wait for Ecwid first page to be ready before changing it
201
+ Ecwid.OnPageLoaded.add(function () {
202
+ var staticHtml = EcwidStaticPageLoader.find('#' + EcwidStaticPageLoader.staticId);
203
+ if (!EcwidStaticPageLoader.isVisible(staticHtml)) {
204
+ // if we've already switched to dynamic, we don't need to dispatch this event anymore
205
+ return;
206
+ }
207
+ Ecwid.openPage(page, params);
208
+ });
209
+ }
210
+ },
211
+
212
+ hideStorefront: function () {
213
+ var dynamicEl = EcwidStaticPageLoader.find('#' + this.dynamicId);
214
+ // the dynamic div container must be visible while loading Ecwid,
215
+ // so that the scripts could calculate available container width,
216
+ // therefore we ensure the element is visible and hide it via zero-height trick
217
+ dynamicEl.style.display = 'block';
218
+ dynamicEl.style.overflowY = 'auto';
219
+ dynamicEl.style.height = '0';
220
+ dynamicEl.style.minHeight = '0';
221
+ dynamicEl.style.maxHeight = '0';
222
+ },
223
+
224
+ showStorefront: function () {
225
+ var dynamicEl = EcwidStaticPageLoader.find('#' + this.dynamicId);
226
+ // disable zero-height trick to show the storefront
227
+ dynamicEl.style.height = '';
228
+ dynamicEl.style.minHeight = '';
229
+ dynamicEl.style.maxHeight = '';
230
+ },
231
+
232
+ hideStaticHtml: function () {
233
+ var staticEl = EcwidStaticPageLoader.find('#' + this.staticId);
234
+ staticEl.style.opacity = 0;
235
+ staticEl.style.display = 'none';
236
+ },
237
+
238
+ showStaticHtml: function () {
239
+ var staticEl = EcwidStaticPageLoader.find('#' + this.staticId);
240
+ staticEl.style.opacity = 1;
241
+ },
242
+
243
+ switchToDynamicMode: function () {
244
+ this.showStorefront();
245
+ this.hideStaticHtml();
246
+ },
247
+
248
+ switchToDynamicModeDeferred: function () {
249
+ // defer switching to dynamic to avoid blinking effect
250
+ setTimeout(function () {
251
+ EcwidStaticPageLoader.switchToDynamicMode();
252
+ }, 0);
253
+ }
254
+
255
+ };
lib/ecwid_api_v3.php CHANGED
@@ -17,6 +17,9 @@ class Ecwid_Api_V3
17
  const API_STATUS_ERROR_TLS = 'fail_old_tls';
18
  const API_STATUS_ERROR_OTHER = 'fail_other';
19
  const API_STATUS_ERROR_TOKEN = 'fail_token';
 
 
 
20
 
21
  public static function get_api_status_list()
22
  {
@@ -29,7 +32,6 @@ class Ecwid_Api_V3
29
  );
30
  }
31
 
32
- const FEATURE_NEW_PRODUCT_LIST = 'NEW_PRODUCT_LIST';
33
  const FEATURE_VARIATIONS = 'COMBINATIONS';
34
  const FEATURE_NEW_DETAILS_PAGE = 'NEW_DETAILS_PAGE';
35
 
17
  const API_STATUS_ERROR_TLS = 'fail_old_tls';
18
  const API_STATUS_ERROR_OTHER = 'fail_other';
19
  const API_STATUS_ERROR_TOKEN = 'fail_token';
20
+
21
+ const FEATURE_NEW_PRODUCT_LIST = 'NEW_PRODUCT_LIST';
22
+ const FEATURE_STATIC_HOME_PAGE = 'STATIC_HOME_PAGE';
23
 
24
  public static function get_api_status_list()
25
  {
32
  );
33
  }
34
 
 
35
  const FEATURE_VARIATIONS = 'COMBINATIONS';
36
  const FEATURE_NEW_DETAILS_PAGE = 'NEW_DETAILS_PAGE';
37
 
lib/ecwid_platform.php CHANGED
@@ -9,9 +9,16 @@ class EcwidPlatform {
9
 
10
  static protected $crypt = null;
11
 
 
 
 
12
  const CATEGORIES_CACHE_VALID_FROM = 'categories_cache_valid_from';
13
  const PRODUCTS_CACHE_VALID_FROM = 'products_cache_valid_from';
14
-
 
 
 
 
15
  static public function get_store_id()
16
  {
17
  return get_ecwid_store_id();
@@ -128,6 +135,44 @@ class EcwidPlatform {
128
  return esc_html($value);
129
  }
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  static public function get_price_label()
132
  {
133
  return __('Price', 'ecwid-shopping-cart');
@@ -136,6 +181,9 @@ class EcwidPlatform {
136
  static public function cache_get($name, $default = false)
137
  {
138
  $result = get_transient('ecwid_' . $name);
 
 
 
139
  if ($default !== false && $result === false) {
140
  return $default;
141
  }
@@ -145,10 +193,12 @@ class EcwidPlatform {
145
 
146
  static public function cache_set($name, $value, $expires_after)
147
  {
 
148
  set_transient('ecwid_' . $name, $value, $expires_after);
149
  }
150
 
151
  static public function cache_reset($name) {
 
152
  delete_transient('ecwid_' . $name);
153
  }
154
 
@@ -245,29 +295,34 @@ class EcwidPlatform {
245
 
246
  static public function get( $name, $default = null )
247
  {
248
- $options = get_option( 'ecwid_plugin_data' );
249
-
250
- if ( is_array( $options ) && array_key_exists( $name, $options ) ) {
251
- return $options[$name];
 
 
252
  }
253
 
254
  return $default;
255
  }
256
-
257
  static public function set( $name, $value ) {
258
- $options = get_option( 'ecwid_plugin_data' );
259
-
260
- if ( !is_array( $options ) ) {
261
- $options = array();
 
 
 
262
  }
263
 
264
- $options[$name] = $value;
265
 
266
- update_option( 'ecwid_plugin_data', $options );
267
  }
268
 
269
  static public function reset( $name ) {
270
- $options = get_option( 'ecwid_plugin_data' );
271
 
272
  if ( !is_array( $options ) || !array_key_exists($name, $options)) {
273
  return;
@@ -275,7 +330,7 @@ class EcwidPlatform {
275
 
276
  unset($options[$name]);
277
 
278
- update_option( 'ecwid_plugin_data', $options );
279
 
280
  }
281
 
@@ -289,7 +344,6 @@ class EcwidPlatform {
289
  }
290
 
291
  static public function store_in_products_cache( $url, $data ) {
292
-
293
  self::_store_in_cache($url, 'products', $data);
294
  }
295
 
@@ -298,6 +352,10 @@ class EcwidPlatform {
298
  self::_store_in_cache($url, 'categories', $data);
299
  }
300
 
 
 
 
 
301
  static protected function _store_in_cache( $url, $type, $data ) {
302
  $name = self::_build_cache_name( $url, $type );
303
 
@@ -307,6 +365,8 @@ class EcwidPlatform {
307
  );
308
 
309
  self::cache_set( $name, $to_store, MONTH_IN_SECONDS );
 
 
310
  }
311
 
312
  static public function get_from_categories_cache( $key )
@@ -314,6 +374,16 @@ class EcwidPlatform {
314
  $cache_name = self::_build_cache_name( $key, 'categories' );
315
 
316
  $result = self::cache_get( $cache_name );
 
 
 
 
 
 
 
 
 
 
317
  if ( $result['time'] > EcwidPlatform::get( self::CATEGORIES_CACHE_VALID_FROM ) ) {
318
  return $result['data'];
319
  }
@@ -327,12 +397,63 @@ class EcwidPlatform {
327
 
328
  $result = self::cache_get( $cache_name );
329
 
 
 
 
 
 
 
 
 
 
330
  if ( $result['time'] > EcwidPlatform::get( self::PRODUCTS_CACHE_VALID_FROM ) ) {
331
  return $result['data'];
332
  }
333
 
334
  return false;
335
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
336
 
337
  static protected function _build_cache_name( $url, $type ) {
338
  return $type . '_' . md5($url);
@@ -342,12 +463,38 @@ class EcwidPlatform {
342
  {
343
  $time = is_null( $time ) ? time() : $time;
344
  EcwidPlatform::set( self::PRODUCTS_CACHE_VALID_FROM, $time );
 
 
 
 
 
 
 
345
  }
346
 
347
  static public function invalidate_categories_cache_from( $time = null )
348
  {
349
  $time = is_null( $time ) ? time() : $time;
350
  EcwidPlatform::set( self::CATEGORIES_CACHE_VALID_FROM, $time );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
  }
352
  }
353
 
9
 
10
  static protected $crypt = null;
11
 
12
+ static protected $ecwid_plugin_data = null;
13
+
14
+ const FORCES_CATALOG_CACHE_RESET_VALID_FROM = 'forced_catalog_cache_reset_valid_from';
15
  const CATEGORIES_CACHE_VALID_FROM = 'categories_cache_valid_from';
16
  const PRODUCTS_CACHE_VALID_FROM = 'products_cache_valid_from';
17
+ const PROFILE_CACHE_VALID_FROM = 'profile_cache_valid_from';
18
+
19
+ const OPTION_LOG_CACHE = 'ecwid_log_cache';
20
+ const OPTION_ECWID_PLUGIN_DATA = 'ecwid_plugin_data';
21
+
22
  static public function get_store_id()
23
  {
24
  return get_ecwid_store_id();
135
  return esc_html($value);
136
  }
137
 
138
+ static public function cache_log_record( $operation, $params ) {
139
+
140
+ if ( !get_option( self::OPTION_LOG_CACHE, false ) ) { return; }
141
+
142
+ if (!$params) $params = array();
143
+ $backtrace = debug_backtrace(false);
144
+
145
+ $file = $line = '';
146
+ foreach ( $backtrace as $entry ) {
147
+ if ( strpos( @$entry['file'], 'ecwid_platform.php' ) !== false ) {
148
+ continue;
149
+ }
150
+
151
+ @$file = $entry['file'];
152
+ @$line = $entry['line'];
153
+ }
154
+
155
+ $log_entry = array(
156
+ 'operation' => $operation,
157
+ 'file' => $file,
158
+ 'line' => $line,
159
+ 'timestamp' => time()
160
+ );
161
+
162
+ $log_entry = array_merge(
163
+ $log_entry,
164
+ $params
165
+ );
166
+
167
+ $cache = get_option( 'ecwid_cache_log' );
168
+ if (!$cache) {
169
+ $cache = array();
170
+ }
171
+ $cache[] = $log_entry;
172
+
173
+ update_option('ecwid_cache_log', $cache );
174
+ }
175
+
176
  static public function get_price_label()
177
  {
178
  return __('Price', 'ecwid-shopping-cart');
181
  static public function cache_get($name, $default = false)
182
  {
183
  $result = get_transient('ecwid_' . $name);
184
+
185
+ self::cache_log_record( 'get', array( 'name' => $name, 'default' => $default, 'result' => $result ) );
186
+
187
  if ($default !== false && $result === false) {
188
  return $default;
189
  }
193
 
194
  static public function cache_set($name, $value, $expires_after)
195
  {
196
+ self::cache_log_record( 'set', array( 'name' => $name, 'value' => $value, 'expires' => $expires_after ) );
197
  set_transient('ecwid_' . $name, $value, $expires_after);
198
  }
199
 
200
  static public function cache_reset($name) {
201
+ self::cache_log_record( 'reset', array( 'name' => $name ) );
202
  delete_transient('ecwid_' . $name);
203
  }
204
 
295
 
296
  static public function get( $name, $default = null )
297
  {
298
+ if ( !self::$ecwid_plugin_data ) {
299
+ self::$ecwid_plugin_data = get_option( self::OPTION_ECWID_PLUGIN_DATA );
300
+ }
301
+
302
+ if ( is_array( self::$ecwid_plugin_data ) && array_key_exists( $name, self::$ecwid_plugin_data ) ) {
303
+ return self::$ecwid_plugin_data[$name];
304
  }
305
 
306
  return $default;
307
  }
308
+
309
  static public function set( $name, $value ) {
310
+
311
+ if ( is_null( self::$ecwid_plugin_data ) ) {
312
+ self::$ecwid_plugin_data = get_option( self::OPTION_ECWID_PLUGIN_DATA );
313
+ }
314
+
315
+ if ( !is_array( self::$ecwid_plugin_data ) ) {
316
+ self::$ecwid_plugin_data = array();
317
  }
318
 
319
+ self::$ecwid_plugin_data[$name] = $value;
320
 
321
+ update_option( self::OPTION_ECWID_PLUGIN_DATA, self::$ecwid_plugin_data );
322
  }
323
 
324
  static public function reset( $name ) {
325
+ $options = get_option( self::OPTION_ECWID_PLUGIN_DATA );
326
 
327
  if ( !is_array( $options ) || !array_key_exists($name, $options)) {
328
  return;
330
 
331
  unset($options[$name]);
332
 
333
+ update_option( self::OPTION_ECWID_PLUGIN_DATA, $options );
334
 
335
  }
336
 
344
  }
345
 
346
  static public function store_in_products_cache( $url, $data ) {
 
347
  self::_store_in_cache($url, 'products', $data);
348
  }
349
 
352
  self::_store_in_cache($url, 'categories', $data);
353
  }
354
 
355
+ static public function store_in_catalog_cache( $url, $data ) {
356
+ self::_store_in_cache($url, 'catalog', $data);
357
+ }
358
+
359
  static protected function _store_in_cache( $url, $type, $data ) {
360
  $name = self::_build_cache_name( $url, $type );
361
 
365
  );
366
 
367
  self::cache_set( $name, $to_store, MONTH_IN_SECONDS );
368
+
369
+ self::cache_log_record( 'store_in_entity_cache', array( 'name' => $url, 'type' => $type, 'data' => $data ), 'set' );
370
  }
371
 
372
  static public function get_from_categories_cache( $key )
374
  $cache_name = self::_build_cache_name( $key, 'categories' );
375
 
376
  $result = self::cache_get( $cache_name );
377
+
378
+ self::cache_log_record(
379
+ 'get_from_categories_cache',
380
+ array(
381
+ 'name' => $key,
382
+ 'result' => $result,
383
+ 'valid_from' => EcwidPlatform::get( self::CATEGORIES_CACHE_VALID_FROM )
384
+ )
385
+ );
386
+
387
  if ( $result['time'] > EcwidPlatform::get( self::CATEGORIES_CACHE_VALID_FROM ) ) {
388
  return $result['data'];
389
  }
397
 
398
  $result = self::cache_get( $cache_name );
399
 
400
+ self::cache_log_record(
401
+ 'get_from_products_cache',
402
+ array(
403
+ 'name' => $key,
404
+ 'result' => $result,
405
+ 'valid_from' => EcwidPlatform::get( self::CATEGORIES_CACHE_VALID_FROM )
406
+ )
407
+ );
408
+
409
  if ( $result['time'] > EcwidPlatform::get( self::PRODUCTS_CACHE_VALID_FROM ) ) {
410
  return $result['data'];
411
  }
412
 
413
  return false;
414
  }
415
+
416
+ static public function get_from_catalog_cache( $key )
417
+ {
418
+ $cache_name = self::_build_cache_name( $key, 'catalog' );
419
+
420
+ $result = self::cache_get( $cache_name );
421
+
422
+ $valid_from = max(
423
+ EcwidPlatform::get( self::CATEGORIES_CACHE_VALID_FROM ),
424
+ EcwidPlatform::get( self::PRODUCTS_CACHE_VALID_FROM ),
425
+ EcwidPlatform::get( self::PROFILE_CACHE_VALID_FROM ),
426
+ EcwidPlatform::get( self::FORCES_CATALOG_CACHE_RESET_VALID_FROM )
427
+ );
428
+
429
+ self::cache_log_record(
430
+ 'get_from_catalog_cache',
431
+ array(
432
+ 'name' => $key,
433
+ 'result' => $result,
434
+ 'valid_from' => $valid_from
435
+ )
436
+ );
437
+
438
+ if ( $result['time'] > $valid_from ) {
439
+ return $result['data'];
440
+ }
441
+
442
+ return false;
443
+ }
444
+
445
+ static public function is_catalog_cache_trusted() {
446
+
447
+ $valid_from = max(
448
+ EcwidPlatform::get( self::CATEGORIES_CACHE_VALID_FROM ),
449
+ EcwidPlatform::get( self::PRODUCTS_CACHE_VALID_FROM ),
450
+ EcwidPlatform::get( self::PROFILE_CACHE_VALID_FROM )
451
+ );
452
+
453
+ self::cache_log_record( 'is_trusted', array( 'result' => time() - $valid_from > 10, 'time' => time(), 'cats' => EcwidPlatform::get( self::CATEGORIES_CACHE_VALID_FROM ), 'prods' => EcwidPlatform::get( self::PRODUCTS_CACHE_VALID_FROM )));
454
+
455
+ return time() - $valid_from > 10;
456
+ }
457
 
458
  static protected function _build_cache_name( $url, $type ) {
459
  return $type . '_' . md5($url);
463
  {
464
  $time = is_null( $time ) ? time() : $time;
465
  EcwidPlatform::set( self::PRODUCTS_CACHE_VALID_FROM, $time );
466
+ self::cache_log_record(
467
+ 'invalidate_products_cache',
468
+ array(
469
+ 'time' => $time
470
+ )
471
+ );
472
+
473
  }
474
 
475
  static public function invalidate_categories_cache_from( $time = null )
476
  {
477
  $time = is_null( $time ) ? time() : $time;
478
  EcwidPlatform::set( self::CATEGORIES_CACHE_VALID_FROM, $time );
479
+ self::cache_log_record(
480
+ 'invalidate_categories_cache',
481
+ array(
482
+ 'time' => $time
483
+ )
484
+ );
485
+ }
486
+
487
+ static public function invalidate_profile_cache_from( $time = null )
488
+ {
489
+ $time = is_null( $time ) ? time() : $time;
490
+ EcwidPlatform::set( self::PROFILE_CACHE_VALID_FROM, $time );
491
+ }
492
+
493
+
494
+ static public function force_catalog_cache_reset( $time = null )
495
+ {
496
+ $time = is_null( $time ) ? time() : $time;
497
+ EcwidPlatform::set( self::FORCES_CATALOG_CACHE_RESET_VALID_FROM, $time );
498
  }
499
  }
500
 
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: Ecwid
3
  Tags: ecommerce, downloadable products, Facebook ecommerce, online store, paypal, product catalog, shop, shopping cart, store
4
  Requires at least: 3.7
5
  Tested up to: 4.9
6
- Stable tag: 6.4.1
7
 
8
  Powerful, easy to use ecommerce shopping cart. Sell on Facebook and Instagram. iPhone & Android apps. Superb support. Free plan available.
9
 
@@ -150,8 +150,13 @@ You can use Ecwid’s built-in import tools to copy your store products from any
150
  * [Ecwid eCommerce Forums](https://www.ecwid.com/forums/forumdisplay.php?f=19)
151
 
152
  == Changelog ==
 
 
 
 
 
153
  = 6.4.1 - Nov 13, 2018 =
154
- - WordPress v 5.0 compatibility. This update brings compatibility with the upcoming WordPress version. In particular, we made sure Ecwid e-commerce stores looks good with the new Twenty Nineteenth theme. Also, we polished the Ecwid online store block in the new WordPress editor (Gutenberg) to make sure you can add a product listing to any site page and customize its appearance including colors, product grid layout, store navigation controls, product page appearance and more.
155
 
156
 
157
  = 6.4 - Oct 25, 2018 =
3
  Tags: ecommerce, downloadable products, Facebook ecommerce, online store, paypal, product catalog, shop, shopping cart, store
4
  Requires at least: 3.7
5
  Tested up to: 4.9
6
+ Stable tag: 6.4.2
7
 
8
  Powerful, easy to use ecommerce shopping cart. Sell on Facebook and Instagram. iPhone & Android apps. Superb support. Free plan available.
9
 
150
  * [Ecwid eCommerce Forums](https://www.ecwid.com/forums/forumdisplay.php?f=19)
151
 
152
  == Changelog ==
153
+ = 6.4.2 - Nov 21, 2018 =
154
+ - **Speedup for the store main page.** We're working on making Ecwid stores load faster on WordPress sites. This update brings a set of loading speed improvements for some part of the stores. We will gradually roll out these enhancements to all users. No actions required from your side — your store will get all of the improvements in this or upcoming releases. But if you ever noticed your store loading slowly, please contact us so we can help you enable this new feature on your site right now.
155
+ - **Fixed an issue in the plugin settings menu on [Wordpress.com](http://wordpress.com).** Ecwid e-commerce plugin works on Wordpress.com sites as well. In the admin backend of [WordPress.com](http://wordpress.com) sites, the plugin menu didn't look well — some of the styles and colors were broken. We fixed it, now the plugin admin backend should work fine on both [Wordpress.org](http://wordpress.org) and Wordpress.com installations.
156
+ - Minor fixes and improvements.
157
+
158
  = 6.4.1 - Nov 13, 2018 =
159
+ - **WordPress v 5.0 compatibility.** This update brings compatibility with the upcoming WordPress version. In particular, we made sure Ecwid e-commerce stores looks good with the new Twenty Nineteenth theme. Also, we polished the Ecwid online store block in the new WordPress editor (Gutenberg) to make sure you can add a product listing to any site page and customize its appearance including colors, product grid layout, store navigation controls, product page appearance and more.
160
 
161
 
162
  = 6.4 - Oct 25, 2018 =
templates/advanced-settings.php CHANGED
@@ -71,7 +71,7 @@
71
  <div class="upgrade-note">
72
  <a
73
  class="button ecwid-button button-green" target="_blank"
74
- href="<?php echo Ecwid_Admin::get_dashboard_url(); ?>&ec-page=<?php echo urlencode(ecwid_get_admin_iframe_upgrade_page()); ?>">
75
  <?php _e( 'Upgrade to get this feature', 'ecwid-shopping-cart' ); ?>
76
  </a>
77
  <div class="note grayed-links">
71
  <div class="upgrade-note">
72
  <a
73
  class="button ecwid-button button-green" target="_blank"
74
+ href="<?php echo Ecwid_Admin::get_dashboard_url(); ?>&ec-page=<?php echo urlencode( Ecwid_Admin_Main_Page::PAGE_HASH_UPGRADE ); ?>">
75
  <?php _e( 'Upgrade to get this feature', 'ecwid-shopping-cart' ); ?>
76
  </a>
77
  <div class="note grayed-links">
templates/cache_log.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <style>
2
+ .cache_log > div {
3
+ display: table-cell;
4
+ }
5
+
6
+ .cache_log .title {
7
+ width: 200px;
8
+ }
9
+
10
+ .cache_log .entity-title {
11
+ width: 340px;
12
+ }
13
+
14
+ .cache_log .time {
15
+ width: 190px;
16
+ }
17
+
18
+ .cache_log .timestamp {
19
+ width: 120px;
20
+ }
21
+
22
+ .cache_log .op {
23
+ width: 180px;
24
+ }
25
+
26
+ .cache_log .size-300 {
27
+ width: 300px;
28
+ }
29
+
30
+ .cache_log .nested-field {
31
+ display: table-row;
32
+ }
33
+
34
+ .cache_log .nested-field .param-name,
35
+ .cache_log .nested-field .param-value {
36
+ display: table-cell;
37
+ }
38
+
39
+ .cache_log .title.collapsed:before {
40
+ border: 1px solid black;
41
+ content: '+';
42
+ }
43
+
44
+ .cache_log .title.collapsed:after {
45
+ content: '...';
46
+ }
47
+
48
+ .cache_log .title.collapsed>.data {
49
+ display: none;
50
+ }
51
+
52
+ .cache_log .title.expanded:before {
53
+ border: 1px solid black;
54
+ content: '-';
55
+ }
56
+
57
+ .cache_log .title.expanded>.data {
58
+ display: block;
59
+ padding-left: 15px;
60
+ }
61
+ </style>
62
+ <?php
63
+
64
+ function render_nested( $name, $data ) {
65
+ if ( is_array( $data ) || is_object( $data ) ) {
66
+
67
+ echo "<div class='size-300'><label class='title collapsed' onClick='jQuery(this).toggleClass(\"expanded\").toggleClass(\"collapsed\"); event.stopPropagation(); return false;'>$name";
68
+
69
+ foreach ( $data as $key => $item ) {
70
+ echo '<div class="data">';
71
+ render_nested( $key, $item );
72
+ echo '</div>';
73
+ }
74
+
75
+ echo '</label></div>';
76
+ } else {
77
+ echo "<div class='nested-field'><div class='param-name'>" . $name . ":</div><div class='param-value'>" . $data . '</div></div>';
78
+ }
79
+ }
80
+
81
+ $cache = get_option('ecwid_cache_log');
82
+
83
+ $kill = @$_GET['kill'];
84
+ while ( $kill-- > 0 && count($cache) > 0) {
85
+ array_pop($cache);
86
+ }
87
+
88
+ update_option('ecwid_cache_log', $cache );
89
+
90
+ $cache = get_option('ecwid_cache_log');
91
+
92
+ foreach ($cache as $item) {
93
+ echo '<div class="cache_log">';
94
+ $ts = strftime( '%H:%M:%S %D', $item['timestamp'] );
95
+ echo "<div class=\"timestamp\">$ts</div>";
96
+ echo "<div class=\"op\">$item[operation]</div>";
97
+ if ($item['operation'] == 'invalidate_products_cache' || $item['operation'] == 'invalidate_categories_cache') {
98
+ $time = strftime('%c', $item['time']);
99
+ echo <<<HTML
100
+ <div class="time">$time</div>
101
+ HTML;
102
+ }
103
+ if ($item['operation'] == 'get') {
104
+ echo <<<HTML
105
+ <div class="entity-title">$item[name]</div>
106
+ HTML;
107
+ render_nested( 'result', $item['result'] );
108
+ }
109
+ if ($item['operation'] == 'set') {
110
+ echo <<<HTML
111
+ <div class="entity-title">$item[name]</div>
112
+ HTML;
113
+ render_nested('value', $item['value']);
114
+ }
115
+ if (in_array( $item['operation'], array( 'get_from_categories_cache', 'get_from_products_cache', 'get_from_catalog_cache' ) ) ) {
116
+ $key = @$item['name'];
117
+ echo <<<HTML
118
+ <div class="entity-title">$key</div>
119
+ HTML;
120
+ render_nested('result', $item['result']);
121
+ }
122
+ if ($item['operation'] == 'get_from_catalog_cache') {
123
+ $valid_from = @$item['valid_from'];
124
+ echo <<<HTML
125
+ <div class="entity-title">$valid_from</div>
126
+ HTML;
127
+ }
128
+
129
+ if ($item['operation'] == 'reg cache check') {
130
+ render_nested('stats', $item['stats']);
131
+ }
132
+
133
+ if ($item['operation'] == 'is_trusted') {
134
+ render_nested('self', $item);
135
+ }
136
+
137
+ echo '</div>';
138
+ }
139
+
140
+ echo '' . '<br />';
141
+ echo 'cats:' . EcwidPlatform::get( EcwidPlatform::CATEGORIES_CACHE_VALID_FROM ) . '<br />';
142
+ echo 'prods:' . EcwidPlatform::get( EcwidPlatform::PRODUCTS_CACHE_VALID_FROM ) . '<br />';
143
+ echo 'profile:' . EcwidPlatform::get( EcwidPlatform::PROFILE_CACHE_VALID_FROM ) . '<br />';
templates/debug.php CHANGED
@@ -1,7 +1,6 @@
1
  <div class="ecwid-debug">
2
  <?php
3
-
4
-
5
  $all_plugins = get_plugins();
6
 
7
  $active_plugins = get_option('active_plugins');
@@ -51,7 +50,7 @@
51
  </div>
52
 
53
  <h2>Remote get test</h2>
54
- <div><?php var_export($remote_get_results); ?></div>
55
 
56
  <h2>Api V3 profile test</h2>
57
  <div><?php var_export($api_v3_profile_results); ?></div>
@@ -94,7 +93,7 @@
94
  <h2>Store pages</h2>
95
  <?php foreach (Ecwid_Store_Page::get_store_pages_array() as $page_id): ?>
96
  <div>
97
- <a target="_blank" href="post.php?post=<?php echo $page_id; ?>&action=edit"><?php echo get_post($page_id)->post_name; ?></a>
98
  <?php if ( $page_id == get_option( Ecwid_Store_Page::OPTION_MAIN_STORE_PAGE_ID ) ): ?>
99
  <b> - main</b>
100
  <?php endif ;?>
1
  <div class="ecwid-debug">
2
  <?php
3
+ return;
 
4
  $all_plugins = get_plugins();
5
 
6
  $active_plugins = get_option('active_plugins');
50
  </div>
51
 
52
  <h2>Remote get test</h2>
53
+ <div><?php var_export(@$remote_get_results); ?></div>
54
 
55
  <h2>Api V3 profile test</h2>
56
  <div><?php var_export($api_v3_profile_results); ?></div>
93
  <h2>Store pages</h2>
94
  <?php foreach (Ecwid_Store_Page::get_store_pages_array() as $page_id): ?>
95
  <div>
96
+ <a target="_blank" href="post.php?post=<?php echo $page_id; ?>&action=edit"><?php echo @get_post($page_id)->post_name; ?></a>
97
  <?php if ( $page_id == get_option( Ecwid_Store_Page::OPTION_MAIN_STORE_PAGE_ID ) ): ?>
98
  <b> - main</b>
99
  <?php endif ;?>