Ecwid Ecommerce Shopping Cart - Version 4.6

Version Description

  • Compatibility with the "Contact form 7 designer" plugin . When installed, the "Contact form 7 designer" plugin adds its own code to the and tags on the page on every page of the site. This conflicted with Ecwid storefront styles. We fixed that now if you use the both plugin t the same time, your site pages styles should work fine. Note: this plugin is not the same as the popular "Contact form 7". Ecwid ecommerce functionality works well with the latter, so don't worry if you use it on your site.
  • Fix for a store links issue in the "Flora" theme by Wyde. Users with "Flora" theme on their sites reported that there are glitches in the way Ecwid online store links behave in that theme. We fixed that Ecwid now works well with "Flora".
  • Compatibility with the "Trend" Wordpress theme. Ecwid shopping cart is designed to work great with all WordPress themes. However, we sometimes see that Ecwid has troubles working with some AJAX-driven WordPress themes. We found a way to fix this and started working on improving the plugin. With this release, the Ecwid plugin becomes compatible with the beautiful "Trend" theme. We'll get to the other AJAX themes in the future releases. If you find a theme that Ecwid has troubles with, please let us know we'll fix that.
  • Fixed a bug with the store menu item duplicates. In a recent update, we fixed duplicate Store pages appearing when you deactivate and re-activate the plugin several times. In this release, we fixed a similar bug with the "Store" menu items. However often you enable/disable the plugin, the site navigation menu now works properly, keeping a single Store link, unless you deliberately add a few shop links to the menu (e.g. to have store category links in the menu).
  • Minor improvement and fixes to make the plugin more stable and user friendly.
Download this release

Release Info

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

Code changes from version 4.5 to 4.6

css/frontend.css CHANGED
@@ -8,8 +8,8 @@ html#ecwid_html body#ecwid_body .ecwid-SearchPanel input {
8
  max-width: 300px;
9
  }
10
 
11
- html#ecwid_html body#ecwid_body.ecwid-shopping-cart .ecwid-shopping-cart-categories #horizontal-menu,
12
- html#ecwid_html body#ecwid_body.ecwid-shopping-cart .ecwid-shopping-cart-categories .horizontal-menu
13
  {
14
  margin-top: 10px;
15
  margin-bottom: 10px;
8
  max-width: 300px;
9
  }
10
 
11
+ html#ecwid_html body#ecwid_body .ecwid-shopping-cart-categories #horizontal-menu,
12
+ html#ecwid_html body#ecwid_body .ecwid-shopping-cart-categories .horizontal-menu
13
  {
14
  margin-top: 10px;
15
  margin-bottom: 10px;
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 Team
8
- Version: 4.5
9
  Author URI: http://www.ecwid.com?source=wporg
10
  */
11
 
@@ -33,11 +33,14 @@ if ( ! defined( 'ECWID_PLUGIN_URL' ) ) {
33
  define( 'ECWID_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
34
  }
35
 
 
 
 
 
36
  // Older versions of Google XML Sitemaps plugin generate it in admin, newer in site area, so the hook should be assigned in both of them
37
  add_action('sm_buildmap', 'ecwid_build_google_xml_sitemap');
38
 
39
  // Needs to be in both front-end and back-end to allow admin zone recognize the shortcode
40
- add_shortcode('ecwid_productbrowser', 'ecwid_productbrowser_shortcode');
41
  add_shortcode('ecwid', 'ecwid_shortcode');
42
 
43
  add_action( 'plugins_loaded', 'ecwid_init_integrations' );
@@ -62,16 +65,13 @@ if ( is_admin() ){
62
  add_action('admin_head', 'ecwid_ie8_fonts_inclusion');
63
  add_action('admin_head', 'ecwid_send_stats');
64
  add_action('save_post', 'ecwid_save_post');
65
- add_action('init', 'ecwid_apply_theme');
66
  add_action('get_footer', 'ecwid_admin_get_footer');
67
  add_action('admin_post_ecwid_connect', 'ecwid_admin_post_connect');
68
  add_filter('tiny_mce_before_init', 'ecwid_tinymce_init');
69
  add_action('admin_post_ecwid_get_debug', 'ecwid_get_debug_file');
70
  } else {
71
  add_shortcode('ecwid_script', 'ecwid_script_shortcode');
72
- add_shortcode('ecwid_minicart', 'ecwid_minicart_shortcode');
73
- add_shortcode('ecwid_searchbox', 'ecwid_searchbox_shortcode');
74
- add_shortcode('ecwid_categories', 'ecwid_categories_shortcode');
75
  add_shortcode('ecwid_product', 'ecwid_product_shortcode');
76
  add_action('init', 'ecwid_backward_compatibility');
77
  add_action('send_headers', 'ecwid_503_on_store_closed');
@@ -107,6 +107,8 @@ $ecwid_script_rendered = false; // controls single script.js on page
107
  require_once ECWID_PLUGIN_DIR . 'includes/themes.php';
108
  require_once ECWID_PLUGIN_DIR . 'includes/oembed.php';
109
  require_once ECWID_PLUGIN_DIR . 'includes/widgets.php';
 
 
110
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-message-manager.php';
111
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-store-editor.php';
112
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-oauth.php';
@@ -286,6 +288,10 @@ function ecwid_enqueue_frontend() {
286
  )
287
  );
288
  }
 
 
 
 
289
  }
290
 
291
  function ecwid_enqueue_external_chameleon() {
@@ -360,6 +366,7 @@ function ecwid_404_on_broken_escaped_fragment() {
360
  } elseif (!$is_root_cat && $params['mode'] == 'category') {
361
  $result = $api->get_category($params['id']);
362
  }
 
363
  if (!$is_root_cat && empty($result)) {
364
  global $wp_query;
365
 
@@ -712,7 +719,7 @@ TEXT;
712
  $wp_admin_bar->add_menu( array(
713
  'id' => 'ecwid-main',
714
  'title' => '<span class="ab-icon ecwid-top-menu-item"></span>',
715
- 'href' => 'admin.php?page=ecwid',
716
  ));
717
 
718
  $wp_admin_bar->add_menu(array(
@@ -1046,10 +1053,10 @@ function ecwid_content_started($content)
1046
 
1047
  function ecwid_wrap_shortcode_content($content, $name, $attrs)
1048
  {
1049
- return "<!-- Ecwid shopping cart plugin v 4.5 --><!-- noptimize -->"
1050
  . ecwid_get_scriptjs_code(@$attrs['lang'])
1051
  . "<div class=\"ecwid-shopping-cart-$name\">$content</div>"
1052
- . "<!-- /noptimize --><!-- END Ecwid Shopping Cart v 4.5 -->";
1053
  }
1054
 
1055
  function ecwid_get_scriptjs_code($force_lang = null) {
@@ -1085,118 +1092,6 @@ function ecwid_script_shortcode($params) {
1085
  return ecwid_wrap_shortcode_content($content, 'script', $params);
1086
  }
1087
 
1088
- function ecwid_minicart_shortcode($attributes) {
1089
-
1090
- $params = shortcode_atts(
1091
- array(
1092
- 'layout' => null,
1093
- 'is_ecwid_shortcode' => false,
1094
- 'lang' => null
1095
- ), $attributes
1096
- );
1097
-
1098
- $layout = $params['layout'];
1099
- if (!in_array($layout, array('', 'attachToCategories', 'floating', 'Mini', 'MiniAttachToProductBrowser'), true)) {
1100
- $layout = 'MiniAttachToProductBrowser';
1101
- }
1102
-
1103
- if ($params['is_ecwid_shortcode']) {
1104
- // it is a part of the ecwid shortcode, we need to show it anyways
1105
- $ecwid_enable_minicart = $ecwid_show_categories = true;
1106
- } else {
1107
- // it is a ecwid_minicart widget that works based on appearance settings
1108
- $ecwid_enable_minicart = get_option('ecwid_enable_minicart');
1109
- $ecwid_show_categories = get_option('ecwid_show_categories');
1110
- }
1111
-
1112
- $result = '';
1113
-
1114
- if (!empty($ecwid_enable_minicart) && !empty($ecwid_show_categories)) {
1115
- $result = <<<EOT
1116
- <script data-cfasync="false" type="text/javascript"> xMinicart("style=","layout=$layout"); </script>
1117
- EOT;
1118
- }
1119
-
1120
- $result = apply_filters('ecwid_minicart_shortcode_content', $result);
1121
-
1122
- if (!empty($result)) {
1123
- $result = ecwid_wrap_shortcode_content($result, 'minicart', $params);
1124
- }
1125
-
1126
- return $result;
1127
- }
1128
-
1129
- function ecwid_get_search_js_code() {
1130
- if (get_option('ecwid_use_new_search', false)) {
1131
- return 'xSearch("style=");';
1132
- } else {
1133
- return 'xSearchPanel("style=")';
1134
- }
1135
- }
1136
-
1137
- function ecwid_searchbox_shortcode($attributes) {
1138
-
1139
- $params = shortcode_atts(
1140
- array(
1141
- 'is_ecwid_shortcode' => false,
1142
- 'lang' => null
1143
- ), $attributes
1144
- );
1145
-
1146
- $ecwid_show_search_box = $params['is_ecwid_shortcode'] ? true : get_option('ecwid_show_search_box');
1147
-
1148
- $result = '';
1149
- if (!empty($ecwid_show_search_box)) {
1150
- $code = ecwid_get_search_js_code();
1151
- $result = <<<EOT
1152
- <script data-cfasync="false" type="text/javascript"> $code </script>
1153
- EOT;
1154
- }
1155
-
1156
- $result = apply_filters('ecwid_search_shortcode_content', $result);
1157
-
1158
- if (!empty($result)) {
1159
- $result = ecwid_wrap_shortcode_content($result, 'search', $params);
1160
- }
1161
-
1162
- return $result;
1163
- }
1164
-
1165
- function ecwid_categories_shortcode($attributes) {
1166
-
1167
- $params = shortcode_atts(
1168
- array(
1169
- 'is_ecwid_shortcode' => false,
1170
- 'lang' => null
1171
- ), $attributes
1172
- );
1173
-
1174
- $ecwid_show_categories = $params['is_ecwid_shortcode'] ? true : get_option('ecwid_show_categories');
1175
-
1176
- $result = '';
1177
- if (!empty($ecwid_show_categories)) {
1178
- if (get_option('ecwid_use_new_horizontal_categories')) {
1179
- $store_id = get_ecwid_store_id();
1180
- $ver = get_option('ecwid_plugin_version');
1181
- $result = <<<HTML
1182
- <script data-cfasync="false" type="text/javascript"> xCategoriesV2("style="); </script>
1183
- HTML;
1184
- } else {
1185
- $result = <<<EOT
1186
- <script data-cfasync="false" type="text/javascript"> xCategories("style="); </script>
1187
- EOT;
1188
- }
1189
- }
1190
-
1191
- $result = apply_filters('ecwid_categories_shortcode_content', $result);
1192
-
1193
- if (!empty($result)) {
1194
- $result = ecwid_wrap_shortcode_content($result, 'categories', $params);
1195
- }
1196
-
1197
- return $result;
1198
- }
1199
-
1200
  function ecwid_product_shortcode($shortcode_attributes) {
1201
 
1202
  $attributes = shortcode_atts(
@@ -1324,141 +1219,24 @@ function ecwid_shortcode($attributes)
1324
  $widgets_order = array('minicart', 'search', 'categories', 'productbrowser');
1325
  foreach ($widgets_order as $widget) {
1326
  if (in_array($widget, $widgets)) {
1327
- if ($widget == 'search') {
1328
- $widget = 'searchbox';
1329
- }
1330
-
1331
- $result .= call_user_func_array('ecwid_' . $widget . '_shortcode', array($attributes));
1332
- }
1333
- }
1334
-
1335
- update_option('ecwid_store_shortcode_used', time());
1336
-
1337
- $result = apply_filters('ecwid_shortcode_content', $result);
1338
-
1339
- return $result;
1340
- }
1341
-
1342
- function ecwid_productbrowser_shortcode($shortcode_params) {
1343
 
1344
- if (current_user_can('manage_options')) {
1345
- Ecwid_Kissmetrics::record('storefrontIsOpened');
1346
- }
1347
-
1348
- $atts = shortcode_atts(
1349
- array(
1350
- 'categories_per_row' => false,
1351
- 'grid' => false,
1352
- 'list' => false,
1353
- 'table' => false,
1354
- 'search_view' => false,
1355
- 'category_view' => false
1356
- ), $shortcode_params
1357
- );
1358
-
1359
- $grid = explode(',', $atts['grid']);
1360
- if (count($grid) == 2) {
1361
- $atts['grid_rows'] = intval($grid[0]);
1362
- $atts['grid_cols'] = intval($grid[1]);
1363
- } else {
1364
- list($atts['grid_rows'], $atts['grid_cols']) = array(false, false);
1365
- }
1366
-
1367
- $store_id = get_ecwid_store_id();
1368
- $list_of_views = array('list','grid','table');
1369
-
1370
- $ecwid_pb_categoriesperrow = $atts['categories_per_row'] ? $atts['categories_per_row'] : get_option('ecwid_pb_categoriesperrow');
1371
- $ecwid_pb_productspercolumn_grid = $atts['grid_rows'] ? $atts['grid_rows'] : get_option('ecwid_pb_productspercolumn_grid');
1372
- $ecwid_pb_productsperrow_grid = $atts['grid_cols'] ? $atts['grid_cols'] : get_option('ecwid_pb_productsperrow_grid');
1373
- $ecwid_pb_productsperpage_list = $atts['list'] ? $atts['list'] : get_option('ecwid_pb_productsperpage_list');
1374
- $ecwid_pb_productsperpage_table = $atts['table'] ? $atts['table'] : get_option('ecwid_pb_productsperpage_table');
1375
- $ecwid_pb_defaultview = $atts['category_view'] ? $atts['category_view'] : get_option('ecwid_pb_defaultview');
1376
- $ecwid_pb_searchview = $atts['search_view'] ? $atts['search_view'] : get_option('ecwid_pb_searchview');
1377
-
1378
- $ecwid_mobile_catalog_link = get_option('ecwid_mobile_catalog_link');
1379
- $ecwid_default_category_id =
1380
- !empty($shortcode_params) && array_key_exists('default_category_id', $shortcode_params)
1381
- ? $shortcode_params['default_category_id']
1382
- : get_option('ecwid_default_category_id');
1383
-
1384
- $defaults = ecwid_get_default_pb_size();
1385
-
1386
- if (empty($ecwid_pb_categoriesperrow)) {
1387
- $ecwid_pb_categoriesperrow = 3;
1388
- }
1389
- if (empty($ecwid_pb_productspercolumn_grid)) {
1390
- $ecwid_pb_productspercolumn_grid = $defaults['grid_rows'];
1391
- }
1392
- if (empty($ecwid_pb_productsperrow_grid)) {
1393
- $ecwid_pb_productsperrow_grid = $defaults['grid_columns'];
1394
- }
1395
- if (empty($ecwid_pb_productsperpage_list)) {
1396
- $ecwid_pb_productsperpage_list = $defaults['list_rows'];
1397
- }
1398
- if (empty($ecwid_pb_productsperpage_table)) {
1399
- $ecwid_pb_productsperpage_table = $defaults['list_rows'];
1400
- }
1401
-
1402
- if (empty($ecwid_pb_defaultview) || !in_array($ecwid_pb_defaultview, $list_of_views)) {
1403
- $ecwid_pb_defaultview = 'grid';
1404
- }
1405
- if (empty($ecwid_pb_searchview) || !in_array($ecwid_pb_searchview, $list_of_views)) {
1406
- $ecwid_pb_searchview = 'list';
1407
- }
1408
-
1409
- if (empty($ecwid_default_category_id)) {
1410
- $ecwid_default_category_str = '';
1411
- } else {
1412
- $ecwid_default_category_str = ',"defaultCategoryId='. $ecwid_default_category_id .'"';
1413
- }
1414
 
1415
- $plain_content = '';
1416
-
1417
- if (ecwid_can_display_html_catalog()) {
1418
- $params = ecwid_parse_escaped_fragment($_GET['_escaped_fragment_']);
1419
- include_once ECWID_PLUGIN_DIR . 'lib/ecwid_product_api.php';
1420
- include_once ECWID_PLUGIN_DIR . 'lib/ecwid_catalog.php';
1421
-
1422
- $page_url = get_page_link();
1423
-
1424
- $catalog = new EcwidCatalog($store_id, $page_url);
1425
-
1426
- if (isset($params['mode']) && !empty($params['mode'])) {
1427
- if ($params['mode'] == 'product') {
1428
- $plain_content = $catalog->get_product($params['id']);
1429
- $url = ecwid_get_product_url(ecwid_new_product_api()->get_product($params['id']));
1430
- } elseif ($params['mode'] == 'category') {
1431
- $plain_content = $catalog->get_category($params['id']);
1432
- $ecwid_default_category_str = ',"defaultCategoryId=' . $params['id'] . '"';
1433
- $url = ecwid_get_category_url(ecwid_new_product_api()->get_category($params['id']));
1434
- }
1435
 
1436
- } else {
1437
- $plain_content = $catalog->get_category(intval($ecwid_default_category_id));
1438
- if (empty($plain_content)) {
1439
- $plain_content = $catalog->get_category(0);
1440
  } else {
1441
- $url = ecwid_get_category_url(ecwid_new_product_api()->get_category($params['id']));
1442
  }
1443
  }
1444
- if ($url) {
1445
- $parsed = parse_url($url);
1446
- $plain_content .= '<script data-cfasync="false" type="text/javascript"> if (!document.location.hash) document.location.hash = "'. $parsed['fragment'] . '";</script>';
1447
- }
1448
- }
1449
 
1450
- $s = '';
1451
 
1452
- $s = <<<EOT
1453
- <div id="ecwid-store-$store_id">
1454
- {$plain_content}
1455
- </div>
1456
- <script data-cfasync="false" type="text/javascript"> xProductBrowser("categoriesPerRow=$ecwid_pb_categoriesperrow","views=grid($ecwid_pb_productspercolumn_grid,$ecwid_pb_productsperrow_grid) list($ecwid_pb_productsperpage_list) table($ecwid_pb_productsperpage_table)","categoryView=$ecwid_pb_defaultview","searchView=$ecwid_pb_searchview","style="$ecwid_default_category_str, "id=ecwid-store-$store_id");</script>
1457
- EOT;
1458
- return ecwid_wrap_shortcode_content($s, 'product-browser', $shortcode_params);
1459
  }
1460
 
1461
-
1462
  function ecwid_parse_escaped_fragment($escaped_fragment) {
1463
  static $parsed = array();
1464
 
@@ -1554,6 +1332,8 @@ EOT;
1554
 
1555
  /* All new options should go to check_version thing */
1556
 
 
 
1557
  $id = get_option("ecwid_store_page_id");
1558
  $_tmp_page = null;
1559
  if (!empty($id) and ($id > 0)) {
@@ -1577,6 +1357,7 @@ EOT;
1577
  }
1578
 
1579
  } else {
 
1580
  ecwid_load_textdomain();
1581
  $my_post['post_title'] = __('Store', 'ecwid-shopping-cart');
1582
  $my_post['post_content'] = $content;
@@ -1587,14 +1368,14 @@ EOT;
1587
  $id = wp_insert_post( $my_post );
1588
  update_option('ecwid_store_page_id', $id);
1589
 
 
 
1590
  if (ecwid_get_theme_identification() == 'responsive') {
1591
  update_post_meta($id, '_wp_page_template', 'full-width-page.php');
1592
  update_option("ecwid_show_search_box", 'Y');
1593
  }
1594
  }
1595
 
1596
- require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-nav-menus.php';
1597
-
1598
  Ecwid_Nav_Menus::add_menu_on_activate();
1599
 
1600
  Ecwid_Message_Manager::enable_message('on_activate');
@@ -1757,7 +1538,7 @@ function ecwid_build_menu() {
1757
  );
1758
  }
1759
 
1760
- add_submenu_page('', 'Ecwid debug', '', 'manage_options', 'ecwid-debug', 'ecwid_debug_do_page');
1761
  add_submenu_page('', 'Ecwid get mobile app', '', 'manage_options', 'ecwid-admin-mobile', 'ecwid_admin_mobile_do_page');
1762
  add_submenu_page(
1763
  'ecwid',
@@ -1772,17 +1553,16 @@ function ecwid_get_categories($nocache = false) {
1772
  $categories = EcwidPlatform::cache_get('all_categories');
1773
 
1774
  if ( false == $categories || $nocache ) {
1775
- $callback = 'ecwidcatscallback';
1776
- $result = EcwidPlatform::fetch_url(ecwid_get_categories_js_url($callback));
1777
- $result = $result['data'];
1778
-
1779
- $prefix_length = strlen($callback . '(');
1780
- $suffix_length = strlen(');');
1781
- $result = substr($result, $prefix_length, strlen($result) - $suffix_length - $prefix_length - 1);
1782
-
1783
- $categories = json_decode($result);
1784
 
1785
- $result = EcwidPlatform::cache_set('all_categories', $categories, 60 * 60 * 2);
 
 
1786
  }
1787
 
1788
  return $categories;
@@ -2035,36 +1815,24 @@ function ecwid_general_settings_do_page() {
2035
  } else {
2036
  $time = time() - get_option('ecwid_time_correction', 0);
2037
  $page = 'dashboard';
2038
- $iframe_src = sprintf(
2039
- 'https://my.ecwid.com/api/v3/%s/sso?token=%s&timestamp=%s&signature=%s&place=%s&inline&lang=%s&min-height=700',
2040
- get_ecwid_store_id(),
2041
- Ecwid_Api_V3::get_token(),
2042
- $time,
2043
- hash( 'sha256', get_ecwid_store_id() . Ecwid_Api_V3::get_token() . $time . Ecwid_Api_V3::CLIENT_SECRET ),
2044
- $page,
2045
- substr( get_bloginfo( 'language' ), 0, 2 )
2046
- );
2047
-
2048
- $result = EcwidPlatform::fetch_url( $iframe_src );
2049
 
2050
- if ($result['code'] == 403 && strpos($result['data'], 'Token too old') !== false ) {
2051
 
2052
- $result = wp_remote_get($iframe_src);
 
 
 
 
 
2053
 
2054
  if (isset($result['headers']['date'])) {
2055
  $time = strtotime($result['headers']['date']);
2056
 
2057
- $iframe_src = sprintf(
2058
- 'https://my.ecwid.com/api/v3/%s/sso?token=%s&timestamp=%s&signature=%s&place=%s&inline&lang=%s&min-height=700',
2059
- get_ecwid_store_id(),
2060
- Ecwid_Api_V3::get_token(),
2061
- $time,
2062
- hash('sha256', get_ecwid_store_id() . Ecwid_Api_V3::get_token() . $time . Ecwid_Api_V3::CLIENT_SECRET),
2063
- $page,
2064
- substr(get_bloginfo('language'), 0, 2)
2065
- );
2066
 
2067
- $result = EcwidPlatform::fetch_url($iframe_src);
2068
 
2069
  if ($result['code'] == 200) {
2070
  update_option('ecwid_time_correction', time() - $time);
@@ -2082,6 +1850,19 @@ function ecwid_general_settings_do_page() {
2082
  }
2083
  }
2084
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2085
  function ecwid_admin_do_page( $page ) {
2086
 
2087
  if (isset($_GET['show_timeout']) && $_GET['show_timeout'] == '1') {
@@ -2090,7 +1871,7 @@ function ecwid_admin_do_page( $page ) {
2090
  }
2091
  global $ecwid_oauth;
2092
 
2093
- if ($_GET['ecwid_page']) {
2094
  $page = $_GET['ecwid_page'];
2095
  }
2096
 
@@ -2107,17 +1888,11 @@ function ecwid_admin_do_page( $page ) {
2107
 
2108
  $time = time() - get_option('ecwid_time_correction', 0);
2109
 
2110
- $iframe_src = sprintf(
2111
- 'https://my.ecwid.com/api/v3/%s/sso?token=%s&timestamp=%s&signature=%s&place=%s&inline&lang=%s&min-height=700',
2112
- get_ecwid_store_id(),
2113
- Ecwid_Api_V3::get_token(),
2114
- $time,
2115
- hash('sha256', get_ecwid_store_id() . Ecwid_Api_V3::get_token() . $time . Ecwid_Api_V3::CLIENT_SECRET),
2116
- $page,
2117
- substr(get_bloginfo('language'), 0, 2)
2118
- );
2119
 
2120
- $result = EcwidPlatform::fetch_url($iframe_src);
 
 
2121
 
2122
  if (empty($result['code']) && empty($result['data'])) {
2123
  require_once ECWID_PLUGIN_DIR . 'templates/admin-timeout.php';
@@ -2274,10 +2049,8 @@ function ecwid_advanced_settings_do_page() {
2274
 
2275
  $has_create_customers_scope = $ecwid_oauth->has_scope('create_customers');
2276
 
2277
- $key = get_option('ecwid_sso_secret_key');
2278
-
2279
- $is_sso_checkbox_disabled = !$is_sso_enabled && !$has_create_customers_scope && empty($key);
2280
-
2281
 
2282
  $reconnect_link = admin_url('admin-post.php?action=ecwid_connect&reconnect&api_v3_sso');
2283
 
@@ -2317,6 +2090,8 @@ function ecwid_debug_do_page() {
2317
  $api_v3_profile_results = wp_remote_get( 'https://app.ecwid.com/api/v3/' . get_ecwid_store_id() . '/profile?token=' . Ecwid_Api_V3::get_token() );
2318
  }
2319
 
 
 
2320
  require_once ECWID_PLUGIN_DIR . 'templates/debug.php';
2321
  }
2322
 
@@ -2797,8 +2572,15 @@ function ecwid_embed_svg($name) {
2797
  echo $code;
2798
  }
2799
 
2800
- function ecwid_get_categories_js_url($callback) {
2801
- return 'https://my.ecwid.com/categories.js?ownerid=' . get_ecwid_store_id() . '&callback=' . $callback;
 
 
 
 
 
 
 
2802
  }
2803
 
2804
 
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 Team
8
+ Version: 4.6
9
  Author URI: http://www.ecwid.com?source=wporg
10
  */
11
 
33
  define( 'ECWID_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
34
  }
35
 
36
+ if ( ! defined('ECWID_SHORTCODES_DIR' ) ) {
37
+ define( 'ECWID_SHORTCODES_DIR', ECWID_PLUGIN_DIR . 'includes/shortcodes' );
38
+ }
39
+
40
  // Older versions of Google XML Sitemaps plugin generate it in admin, newer in site area, so the hook should be assigned in both of them
41
  add_action('sm_buildmap', 'ecwid_build_google_xml_sitemap');
42
 
43
  // Needs to be in both front-end and back-end to allow admin zone recognize the shortcode
 
44
  add_shortcode('ecwid', 'ecwid_shortcode');
45
 
46
  add_action( 'plugins_loaded', 'ecwid_init_integrations' );
65
  add_action('admin_head', 'ecwid_ie8_fonts_inclusion');
66
  add_action('admin_head', 'ecwid_send_stats');
67
  add_action('save_post', 'ecwid_save_post');
68
+ add_action('init', 'ecwid_apply_theme', 0);
69
  add_action('get_footer', 'ecwid_admin_get_footer');
70
  add_action('admin_post_ecwid_connect', 'ecwid_admin_post_connect');
71
  add_filter('tiny_mce_before_init', 'ecwid_tinymce_init');
72
  add_action('admin_post_ecwid_get_debug', 'ecwid_get_debug_file');
73
  } else {
74
  add_shortcode('ecwid_script', 'ecwid_script_shortcode');
 
 
 
75
  add_shortcode('ecwid_product', 'ecwid_product_shortcode');
76
  add_action('init', 'ecwid_backward_compatibility');
77
  add_action('send_headers', 'ecwid_503_on_store_closed');
107
  require_once ECWID_PLUGIN_DIR . 'includes/themes.php';
108
  require_once ECWID_PLUGIN_DIR . 'includes/oembed.php';
109
  require_once ECWID_PLUGIN_DIR . 'includes/widgets.php';
110
+ require_once ECWID_PLUGIN_DIR . 'includes/shortcodes.php';
111
+
112
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-message-manager.php';
113
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-store-editor.php';
114
  require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-oauth.php';
288
  )
289
  );
290
  }
291
+
292
+ if (is_plugin_active('contact-form-7-designer/cf7-styles.php')) {
293
+ wp_enqueue_script('ecwid-cf7designer', ECWID_PLUGIN_URL . 'js/cf7designer.js', array(), get_option('ecwid-plugin-version'), true);
294
+ }
295
  }
296
 
297
  function ecwid_enqueue_external_chameleon() {
366
  } elseif (!$is_root_cat && $params['mode'] == 'category') {
367
  $result = $api->get_category($params['id']);
368
  }
369
+
370
  if (!$is_root_cat && empty($result)) {
371
  global $wp_query;
372
 
719
  $wp_admin_bar->add_menu( array(
720
  'id' => 'ecwid-main',
721
  'title' => '<span class="ab-icon ecwid-top-menu-item"></span>',
722
+ 'href' => admin_url('admin.php?page=ecwid'),
723
  ));
724
 
725
  $wp_admin_bar->add_menu(array(
1053
 
1054
  function ecwid_wrap_shortcode_content($content, $name, $attrs)
1055
  {
1056
+ return "<!-- Ecwid shopping cart plugin v 4.6 --><!-- noptimize -->"
1057
  . ecwid_get_scriptjs_code(@$attrs['lang'])
1058
  . "<div class=\"ecwid-shopping-cart-$name\">$content</div>"
1059
+ . "<!-- /noptimize --><!-- END Ecwid Shopping Cart v 4.6 -->";
1060
  }
1061
 
1062
  function ecwid_get_scriptjs_code($force_lang = null) {
1092
  return ecwid_wrap_shortcode_content($content, 'script', $params);
1093
  }
1094
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1095
  function ecwid_product_shortcode($shortcode_attributes) {
1096
 
1097
  $attributes = shortcode_atts(
1219
  $widgets_order = array('minicart', 'search', 'categories', 'productbrowser');
1220
  foreach ($widgets_order as $widget) {
1221
  if (in_array($widget, $widgets)) {
1222
+ if ( class_exists( 'Ecwid_Shortcode_' . $widget ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1223
 
1224
+ $class = 'Ecwid_Shortcode_' . $widget;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1225
 
1226
+ $shortcode = new $class($attributes);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1227
 
1228
+ $result .= $shortcode->render();
 
 
 
1229
  } else {
1230
+ $result .= call_user_func_array( 'ecwid_' . $widget . '_shortcode', array( $attributes ) );
1231
  }
1232
  }
1233
+ }
 
 
 
 
1234
 
1235
+ update_option('ecwid_store_shortcode_used', time());
1236
 
1237
+ return $result;
 
 
 
 
 
 
1238
  }
1239
 
 
1240
  function ecwid_parse_escaped_fragment($escaped_fragment) {
1241
  static $parsed = array();
1242
 
1332
 
1333
  /* All new options should go to check_version thing */
1334
 
1335
+ require_once ECWID_PLUGIN_DIR . 'includes/class-ecwid-nav-menus.php';
1336
+
1337
  $id = get_option("ecwid_store_page_id");
1338
  $_tmp_page = null;
1339
  if (!empty($id) and ($id > 0)) {
1357
  }
1358
 
1359
  } else {
1360
+
1361
  ecwid_load_textdomain();
1362
  $my_post['post_title'] = __('Store', 'ecwid-shopping-cart');
1363
  $my_post['post_content'] = $content;
1368
  $id = wp_insert_post( $my_post );
1369
  update_option('ecwid_store_page_id', $id);
1370
 
1371
+ Ecwid_Nav_Menus::replace_auto_added_menu();
1372
+
1373
  if (ecwid_get_theme_identification() == 'responsive') {
1374
  update_post_meta($id, '_wp_page_template', 'full-width-page.php');
1375
  update_option("ecwid_show_search_box", 'Y');
1376
  }
1377
  }
1378
 
 
 
1379
  Ecwid_Nav_Menus::add_menu_on_activate();
1380
 
1381
  Ecwid_Message_Manager::enable_message('on_activate');
1538
  );
1539
  }
1540
 
1541
+ add_submenu_page('', 'Ecwid debug', '', 'manage_options', 'ecwid_debug', 'ecwid_debug_do_page');
1542
  add_submenu_page('', 'Ecwid get mobile app', '', 'manage_options', 'ecwid-admin-mobile', 'ecwid_admin_mobile_do_page');
1543
  add_submenu_page(
1544
  'ecwid',
1553
  $categories = EcwidPlatform::cache_get('all_categories');
1554
 
1555
  if ( false == $categories || $nocache ) {
1556
+ $request = Ecwid_Http::create_get(
1557
+ 'get_categories_through_endpoint',
1558
+ ecwid_get_categories_js_url(),
1559
+ array( Ecwid_Http::POLICY_EXPECT_JSONP )
1560
+ );
1561
+ $categories = $request->do_request();
 
 
 
1562
 
1563
+ if (!is_null($categories)) {
1564
+ EcwidPlatform::cache_set( 'all_categories', $categories, 60 * 60 * 2 );
1565
+ }
1566
  }
1567
 
1568
  return $categories;
1815
  } else {
1816
  $time = time() - get_option('ecwid_time_correction', 0);
1817
  $page = 'dashboard';
 
 
 
 
 
 
 
 
 
 
 
1818
 
1819
+ $iframe_src = ecwid_get_iframe_src($time, $page);
1820
 
1821
+ $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
1822
+ $result = $request->do_request(array(
1823
+ 'timeout' => 20
1824
+ ));
1825
+
1826
+ if ($result['code'] == 403 && strpos($result['data'], 'Token too old') !== false ) {
1827
 
1828
  if (isset($result['headers']['date'])) {
1829
  $time = strtotime($result['headers']['date']);
1830
 
1831
+ $iframe_src = ecwid_get_iframe_src($time, $page);
1832
+
1833
+ $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
 
 
 
 
 
 
1834
 
1835
+ $result = $request->do_request();
1836
 
1837
  if ($result['code'] == 200) {
1838
  update_option('ecwid_time_correction', time() - $time);
1850
  }
1851
  }
1852
 
1853
+ function ecwid_get_iframe_src($time, $page) {
1854
+
1855
+ return sprintf(
1856
+ 'https://my.ecwid.com/api/v3/%s/sso?token=%s&timestamp=%s&signature=%s&place=%s&inline&lang=%s&min-height=700',
1857
+ get_ecwid_store_id(),
1858
+ Ecwid_Api_V3::get_token(),
1859
+ $time,
1860
+ hash( 'sha256', get_ecwid_store_id() . Ecwid_Api_V3::get_token() . $time . Ecwid_Api_V3::CLIENT_SECRET ),
1861
+ $page,
1862
+ substr( get_bloginfo( 'language' ), 0, 2 )
1863
+ );
1864
+ }
1865
+
1866
  function ecwid_admin_do_page( $page ) {
1867
 
1868
  if (isset($_GET['show_timeout']) && $_GET['show_timeout'] == '1') {
1871
  }
1872
  global $ecwid_oauth;
1873
 
1874
+ if (isset($_GET['ecwid_page']) && $_GET['ecwid_page']) {
1875
  $page = $_GET['ecwid_page'];
1876
  }
1877
 
1888
 
1889
  $time = time() - get_option('ecwid_time_correction', 0);
1890
 
1891
+ $iframe_src = ecwid_get_iframe_src($time, $page);
 
 
 
 
 
 
 
 
1892
 
1893
+ $request = Ecwid_Http::create_get('embedded_admin_iframe', $iframe_src, array(Ecwid_Http::POLICY_RETURN_VERBOSE));
1894
+
1895
+ $result = $request->do_request();
1896
 
1897
  if (empty($result['code']) && empty($result['data'])) {
1898
  require_once ECWID_PLUGIN_DIR . 'templates/admin-timeout.php';
2049
 
2050
  $has_create_customers_scope = $ecwid_oauth->has_scope('create_customers');
2051
 
2052
+ $key = get_option('ecwid_sso_secret_key');
2053
+ $is_sso_checkbox_disabled = !$is_sso_enabled && !$has_create_customers_scope && empty($key);
 
 
2054
 
2055
  $reconnect_link = admin_url('admin-post.php?action=ecwid_connect&reconnect&api_v3_sso');
2056
 
2090
  $api_v3_profile_results = wp_remote_get( 'https://app.ecwid.com/api/v3/' . get_ecwid_store_id() . '/profile?token=' . Ecwid_Api_V3::get_token() );
2091
  }
2092
 
2093
+ global $ecwid_oauth;
2094
+
2095
  require_once ECWID_PLUGIN_DIR . 'templates/debug.php';
2096
  }
2097
 
2572
  echo $code;
2573
  }
2574
 
2575
+ function ecwid_get_categories_js_url($callback = null) {
2576
+
2577
+ $url = 'https://my.ecwid.com/categories.js?ownerid=' . get_ecwid_store_id();
2578
+
2579
+ if ($callback) {
2580
+ $url .= '&callback=' . $callback;
2581
+ }
2582
+
2583
+ return $url;
2584
  }
2585
 
2586
 
includes/class-ecwid-integration-divibuilder.php CHANGED
@@ -4,11 +4,15 @@ class Ecwid_Integration_Divibuilder {
4
  public function __construct() {
5
  if (is_admin()) {
6
  add_action('admin_init', 'ecwid_create_divi_module' );
7
- wp_enqueue_style('ecwid-divi', ECWID_PLUGIN_URL . '/css/divibuilder.css', array('et_pb_admin_css'));
8
  } else {
9
  add_action('wp', 'ecwid_create_divi_module' );
10
  }
11
  }
 
 
 
 
12
  }
13
 
14
  new Ecwid_Integration_Divibuilder();
4
  public function __construct() {
5
  if (is_admin()) {
6
  add_action('admin_init', 'ecwid_create_divi_module' );
7
+ add_action('admin_enqueue_style', array($this, 'enqueue_style'));
8
  } else {
9
  add_action('wp', 'ecwid_create_divi_module' );
10
  }
11
  }
12
+
13
+ public function enqueue_style() {
14
+ wp_enqueue_style('ecwid-divi', ECWID_PLUGIN_URL . '/css/divibuilder.css', array('et_pb_admin_css'));
15
+ }
16
  }
17
 
18
  new Ecwid_Integration_Divibuilder();
includes/class-ecwid-message-manager.php CHANGED
@@ -295,6 +295,8 @@ TXT
295
  return $result;
296
 
297
  case "install_ecwid_theme":
 
 
298
  $install_date = ecwid_get_wp_install_date();
299
  $theme = ecwid_get_theme_identification();
300
 
295
  return $result;
296
 
297
  case "install_ecwid_theme":
298
+ return false;
299
+
300
  $install_date = ecwid_get_wp_install_date();
301
  $theme = ecwid_get_theme_identification();
302
 
includes/class-ecwid-nav-menus.php CHANGED
@@ -64,6 +64,30 @@ class Ecwid_Nav_Menus {
64
  );
65
  }
66
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  static protected function _find_existing_store_page_menu($menu_id) {
68
  $items = wp_get_nav_menu_items($menu_id);
69
 
@@ -72,6 +96,10 @@ class Ecwid_Nav_Menus {
72
  foreach ($items as $item) {
73
  if ( $item->object == 'page' && $item->object_id == ecwid_get_current_store_page_id() )
74
  return $item;
 
 
 
 
75
  }
76
 
77
  return null;
64
  );
65
  }
66
 
67
+ static public function replace_auto_added_menu() {
68
+
69
+ $options = get_option('nav_menu_options');
70
+ $autofill = $options['auto_add'];
71
+ if (empty($autofill)) {
72
+ return false;
73
+ }
74
+
75
+ $store_page_id = get_option('ecwid_store_page_id');
76
+ foreach ($autofill as $menu_id) {
77
+ $items = wp_get_nav_menu_items($menu_id);
78
+ foreach ($items as $item) {
79
+ if ( $item->object == 'page' && $item->object_id == $store_page_id && time() - strtotime($item->post_date_gmt) < 60 ) {
80
+ $result = wp_update_nav_menu_item($menu_id, $item->db_id, array(
81
+ 'menu-item-title' => $item->title,
82
+ 'menu-item-status' => $item->status,
83
+ 'menu-item-object' => 'ecwid-store-with-categories',
84
+ 'menu-item-type' => 'ecwid_menu_item')
85
+ );
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
  static protected function _find_existing_store_page_menu($menu_id) {
92
  $items = wp_get_nav_menu_items($menu_id);
93
 
96
  foreach ($items as $item) {
97
  if ( $item->object == 'page' && $item->object_id == ecwid_get_current_store_page_id() )
98
  return $item;
99
+
100
+ if ($item->object == 'ecwid-store-with-categories' || $item->object == 'ecwid-store') {
101
+ return $item;
102
+ }
103
  }
104
 
105
  return null;
includes/class-ecwid-oauth.php CHANGED
@@ -98,10 +98,14 @@ class Ecwid_OAuth {
98
 
99
  $params['grant_type'] = 'authorization_code';
100
 
101
- $return = EcwidPlatform::http_post_request('https://my.ecwid.com/api/oauth/token', $params);
 
 
102
 
103
- if (is_array($return) && isset($return['body'])) {
104
- $result = json_decode($return['body']);
 
 
105
  }
106
 
107
  if (
@@ -208,8 +212,7 @@ class Ecwid_OAuth {
208
  }
209
 
210
  if (isset($last_error)) {
211
- $url = 'http://' . APP_ECWID_COM . '/script.js?805056&data_platform=wporg&data_wporg_error=' . urlencode($last_error) . '&url=' . urlencode(get_bloginfo('url'));
212
- EcwidPlatform::fetch_url($url);
213
  }
214
 
215
  wp_redirect('admin.php?page=ecwid&connection_error' . ($mode == self::MODE_RECONNECT ? '&reconnect' : ''));
98
 
99
  $params['grant_type'] = 'authorization_code';
100
 
101
+ $request = Ecwid_HTTP::create_post( 'oauth_authorize', 'https://my.ecwid.com/api/oauth/token', array(
102
+ Ecwid_HTTP::POLICY_RETURN_VERBOSE
103
+ ));
104
 
105
+ $return = $request->do_request(array('body' => $params));
106
+
107
+ if (is_array($return) && isset($return['data'])) {
108
+ $result = json_decode($return['data']);
109
  }
110
 
111
  if (
212
  }
213
 
214
  if (isset($last_error)) {
215
+ EcwidPlatform::report_error($last_error);
 
216
  }
217
 
218
  wp_redirect('admin.php?page=ecwid&connection_error' . ($mode == self::MODE_RECONNECT ? '&reconnect' : ''));
includes/shortcodes.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ include_once "shortcodes/class-ecwid-shortcode-productbrowser.php";
4
+ include_once "shortcodes/class-ecwid-shortcode-minicart.php";
5
+ include_once "shortcodes/class-ecwid-shortcode-search.php";
6
+ include_once "shortcodes/class-ecwid-shortcode-categories.php";
7
+
8
+ add_shortcode('ecwid_productbrowser', 'ecwid_render_shortcode');
9
+ add_shortcode('ecwid_minicart', 'ecwid_render_shortcode');
10
+ add_shortcode('ecwid_search', 'ecwid_render_shortcode');
11
+ add_shortcode('ecwid_categories', 'ecwid_render_shortcode');
12
+
13
+ function ecwid_render_shortcode($params, $content = '', $name) {
14
+ $names = array('productbrowser', 'minicart', 'search', 'categories');
15
+
16
+ $prefix = substr($name, 0, 6);
17
+
18
+ if ($prefix != 'ecwid_') return '';
19
+
20
+ $base = substr($name, 6);
21
+
22
+ if (in_array($base, $names)) {
23
+ $classname = 'Ecwid_Shortcode_' . $base;
24
+
25
+ $shortcode = new $classname($params);
26
+
27
+ return $shortcode->render();
28
+ }
29
+ }
includes/shortcodes/class-ecwid-shortcode-base.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ abstract class Ecwid_Shortcode_Base {
3
+
4
+ protected $_params = array();
5
+ protected $_lang;
6
+ protected $_should_render = true;
7
+ protected $_index;
8
+
9
+ static protected $shortcodes = array();
10
+
11
+ abstract public function get_shortcode_name();
12
+ abstract protected function _process_params( $shortcode_params = array() );
13
+ abstract public function get_ecwid_widget_function_name();
14
+
15
+ public function __construct( $params ) {
16
+
17
+ if ($params['lang']) {
18
+ $this->_lang = $params['lang'];
19
+ }
20
+ $this->_process_params( $params );
21
+
22
+ if (!isset(self::$shortcodes[$this->get_shortcode_name()])) {
23
+ self::$shortcodes[$this->get_shortcode_name()] = array();
24
+ }
25
+ $this->_index = count(self::$shortcodes[$this->get_shortcode_name()]);
26
+ self::$shortcodes[$this->get_shortcode_name()][] = $this;
27
+ }
28
+
29
+ public function wrap_code($code) {
30
+
31
+ return "<!-- Ecwid shopping cart plugin v 4.4 --><!-- noptimize -->"
32
+ . ecwid_get_scriptjs_code($this->_lang)
33
+ . $code
34
+ . "<!-- /noptimize --><!-- END Ecwid Shopping Cart v 4.4 -->";
35
+ }
36
+
37
+ public function render() {
38
+ if (!$this->_should_render) return '';
39
+
40
+ $custom_renderer = apply_filters('ecwid_shortcode_custom_renderer', null, $this);
41
+ if (is_callable($custom_renderer)) {
42
+ return call_user_func( $custom_renderer, $this );
43
+ }
44
+
45
+ return self::_default_render();
46
+ }
47
+
48
+ public function render_script() {
49
+ $params_string = $this->build_params_string(
50
+ array_merge(
51
+ $this->_params,
52
+ array('id' => $this->get_html_id())
53
+ )
54
+ );
55
+
56
+ $function = $this->get_ecwid_widget_function_name();
57
+
58
+ return <<<HTML
59
+ <script data-cfasync="false" type="text/javascript"> $function($params_string);</script>
60
+ HTML;
61
+ }
62
+
63
+ public function render_placeholder() {
64
+
65
+ $classname = $this->_get_html_class_name();
66
+ $id = $this->get_html_id();
67
+ return <<<HTML
68
+ <div class="ecwid-shopping-cart-$classname" id="$id"></div>
69
+ HTML;
70
+ }
71
+
72
+ protected function _get_html_class_name() {
73
+ return $this->get_shortcode_name();
74
+ }
75
+
76
+ public function get_html_id() {
77
+ return 'ecwid-shopping-cart-' . $this->get_shortcode_name() . '-' . ( $this->_index + 1);
78
+ }
79
+
80
+ protected function _default_render() {
81
+ $result = '';
82
+
83
+ $result .= $this->render_placeholder();
84
+ $result .= $this->render_script();
85
+
86
+ $result = apply_filters('ecwid_' . $this->get_shortcode_name() . '_shortcode_content', $result);
87
+
88
+ if ($result) {
89
+ return $this->wrap_code( $result );
90
+ }
91
+
92
+ return '';
93
+ }
94
+
95
+ public function build_params_string($params = null) {
96
+
97
+ if (is_null($params)) {
98
+ $params = $this->_params;
99
+ }
100
+
101
+ $pieces = array();
102
+ if ( !empty ( $params ) ) {
103
+ foreach ( $params as $key => $value ) {
104
+ $pieces[] = "$key=$value";
105
+ }
106
+ }
107
+
108
+ return '"' . implode('","', $pieces) . '"';
109
+ }
110
+ }
includes/shortcodes/class-ecwid-shortcode-categories.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once ECWID_SHORTCODES_DIR . '/class-ecwid-shortcode-base.php';
4
+
5
+ class Ecwid_Shortcode_Categories extends Ecwid_Shortcode_Base {
6
+
7
+ protected function _process_params( $params = array() ) {
8
+ $this->_should_render = $params['is_ecwid_shortcode'] ? true : get_option('ecwid_show_categories');
9
+ }
10
+
11
+ public function get_shortcode_name() {
12
+ return 'categories';
13
+ }
14
+
15
+ public function get_ecwid_widget_function_name() {
16
+ if ( get_option('ecwid_use_new_horizontal_categories') ) {
17
+ return 'xCategoriesV2';
18
+ } else {
19
+ return 'xCategories';
20
+ }
21
+ }
22
+
23
+ public function render_placeholder() {
24
+ $classname = $this->_get_html_class_name();
25
+ $id = $this->get_html_id();
26
+ return <<<HTML
27
+ <div class="ecwid-shopping-cart-$classname"><div id="$id"></div></div>
28
+ HTML;
29
+ }
30
+ }
includes/shortcodes/class-ecwid-shortcode-minicart.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once ECWID_SHORTCODES_DIR . '/class-ecwid-shortcode-base.php';
4
+
5
+ class Ecwid_Shortcode_Minicart extends Ecwid_Shortcode_Base {
6
+
7
+ protected function _process_params( $shortcode_attributes = array() ) {
8
+
9
+ $params = shortcode_atts(
10
+ array(
11
+ 'layout' => NULL,
12
+ 'is_ecwid_shortcode' => FALSE,
13
+ ), $shortcode_attributes
14
+ );
15
+
16
+ $layout = $params['layout'];
17
+ if ( ! in_array( $layout, array(
18
+ '',
19
+ 'attachToCategories',
20
+ 'floating',
21
+ 'Mini',
22
+ 'MiniAttachToProductBrowser'
23
+ ), true )
24
+ ) {
25
+ $layout = 'MiniAttachToProductBrowser';
26
+ }
27
+
28
+ $this->_params = array(
29
+ 'layout' => $layout
30
+ );
31
+
32
+ if ( $params['is_ecwid_shortcode'] ) {
33
+ // it is a part of the ecwid shortcode, we need to show it anyways
34
+ $ecwid_enable_minicart = $ecwid_show_categories = TRUE;
35
+ } else {
36
+ // it is a ecwid_minicart widget that works based on appearance settings
37
+ $ecwid_enable_minicart = get_option( 'ecwid_enable_minicart' );
38
+ $ecwid_show_categories = get_option( 'ecwid_show_categories' );
39
+ }
40
+
41
+ $this->_should_render = ! empty( $ecwid_enable_minicart ) && ! empty( $ecwid_show_categories );
42
+ }
43
+
44
+ public function get_shortcode_name() {
45
+ return 'minicart';
46
+ }
47
+
48
+ public function get_ecwid_widget_function_name() {
49
+ return 'xMinicart';
50
+ }
51
+
52
+ public function build_params_string($params = null) {
53
+ if (!is_null($params) && array_key_exists('id', $params)) {
54
+ unset($params['id']);
55
+ }
56
+
57
+ return parent::build_params_string($params);
58
+ }
59
+ }
includes/shortcodes/class-ecwid-shortcode-productbrowser.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once ECWID_SHORTCODES_DIR . '/class-ecwid-shortcode-base.php';
4
+
5
+ class Ecwid_Shortcode_ProductBrowser extends Ecwid_Shortcode_Base {
6
+
7
+ public function get_shortcode_name() {
8
+ return 'productbrowser';
9
+ }
10
+
11
+ protected function _get_html_class_name() {
12
+ return 'product-browser';
13
+ }
14
+
15
+ public function get_html_id() {
16
+ return 'ecwid-store-' . get_ecwid_store_id();
17
+ }
18
+
19
+ public function get_ecwid_widget_function_name() {
20
+ return 'xProductBrowser';
21
+ }
22
+
23
+ public function render() {
24
+ if (current_user_can('manage_options')) {
25
+ Ecwid_Kissmetrics::record('storefrontIsOpened');
26
+ }
27
+
28
+ return parent::render();
29
+ }
30
+
31
+ public function render_placeholder( ) {
32
+
33
+ $store_id = get_ecwid_store_id();
34
+
35
+ $plain_content = '';
36
+
37
+ if (ecwid_can_display_html_catalog()) {
38
+ $params = ecwid_parse_escaped_fragment($_GET['_escaped_fragment_']);
39
+ include_once ECWID_PLUGIN_DIR . 'lib/ecwid_product_api.php';
40
+ include_once ECWID_PLUGIN_DIR . 'lib/ecwid_catalog.php';
41
+
42
+ $page_url = get_page_link();
43
+
44
+ $catalog = new EcwidCatalog($store_id, $page_url);
45
+
46
+ $url = false;
47
+
48
+ if (isset($params['mode']) && !empty($params['mode'])) {
49
+ if ($params['mode'] == 'product') {
50
+ $plain_content = $catalog->get_product($params['id']);
51
+ $url = ecwid_get_product_url(ecwid_new_product_api()->get_product($params['id']));
52
+ } elseif ($params['mode'] == 'category') {
53
+ $plain_content = $catalog->get_category($params['id']);
54
+ $url = ecwid_get_category_url(ecwid_new_product_api()->get_category($params['id']));
55
+ }
56
+
57
+ } else {
58
+ $id = intval($this->_get_param_default_category_id($params));
59
+ $plain_content = $catalog->get_category();
60
+ if (empty($plain_content)) {
61
+ $plain_content = $catalog->get_category(0);
62
+ } else {
63
+ $url = ecwid_get_category_url(ecwid_new_product_api()->get_category($params['id']));
64
+ }
65
+ }
66
+
67
+ if ($url) {
68
+ $parsed = parse_url($url);
69
+ $plain_content .= '<script data-cfasync="false" type="text/javascript"> if (!document.location.hash) document.location.hash = "'. $parsed['fragment'] . '";</script>';
70
+ }
71
+ }
72
+
73
+ $classname = $this->_get_html_class_name();
74
+ $result = <<<HTML
75
+ <div id="ecwid-store-$store_id" class="ecwid-shopping-cart-$classname">
76
+ {$plain_content}
77
+ </div>
78
+ HTML;
79
+
80
+ return $result;
81
+ }
82
+
83
+ protected function _process_params( $shortcode_params = array() ) {
84
+
85
+ $atts = shortcode_atts(
86
+ array(
87
+ 'categories_per_row' => false,
88
+ 'grid' => false,
89
+ 'list' => false,
90
+ 'table' => false,
91
+ 'search_view' => false,
92
+ 'category_view' => false
93
+ ), $shortcode_params
94
+ );
95
+
96
+ $grid = explode(',', $atts['grid']);
97
+ if (count($grid) == 2) {
98
+ $atts['grid_rows'] = intval($grid[0]);
99
+ $atts['grid_cols'] = intval($grid[1]);
100
+ } else {
101
+ list($atts['grid_rows'], $atts['grid_cols']) = array(false, false);
102
+ }
103
+
104
+ $list_of_views = array('list','grid','table');
105
+
106
+ $cats_per_row = $atts['categories_per_row'] ? $atts['categories_per_row'] : get_option('ecwid_pb_categoriesperrow');
107
+ $products_per_column_in_grid = $atts['grid_rows'] ? $atts['grid_rows'] : get_option('ecwid_pb_productspercolumn_grid');
108
+ $products_per_row_in_grid = $atts['grid_cols'] ? $atts['grid_cols'] : get_option('ecwid_pb_productsperrow_grid');
109
+ $products_in_list = $atts['list'] ? $atts['list'] : get_option('ecwid_pb_productsperpage_list');
110
+ $products_in_table = $atts['table'] ? $atts['table'] : get_option('ecwid_pb_productsperpage_table');
111
+ $default_view = $atts['category_view'] ? $atts['category_view'] : get_option('ecwid_pb_defaultview');
112
+ $search_view = $atts['search_view'] ? $atts['search_view'] : get_option('ecwid_pb_searchview');
113
+
114
+ $ecwid_default_category_id = $this->_get_param_default_category_id( $shortcode_params );
115
+
116
+ $store_id = get_ecwid_store_id();
117
+
118
+ if (empty($cats_per_row)) {
119
+ $cats_per_row = 3;
120
+ }
121
+ if (empty($products_per_column_in_grid)) {
122
+ $products_per_column_in_grid = 3;
123
+ }
124
+ if (empty($products_per_row_in_grid)) {
125
+ $products_per_row_in_grid = 3;
126
+ }
127
+ if (empty($products_in_list)) {
128
+ $products_in_list = 10;
129
+ }
130
+ if (empty($products_in_table)) {
131
+ $products_in_table = 20;
132
+ }
133
+
134
+ if (empty($default_view) || !in_array($default_view, $list_of_views)) {
135
+ $default_view = 'grid';
136
+ }
137
+ if (empty($search_view) || !in_array($search_view, $list_of_views)) {
138
+ $search_view = 'list';
139
+ }
140
+
141
+ $input_params = array(
142
+ 'categoriesPerRow' => $cats_per_row,
143
+ 'views' => "grid($products_per_column_in_grid,$products_per_row_in_grid) list($products_in_list) table($products_in_table)",
144
+ 'categoryView' => $default_view,
145
+ 'searchView' => $search_view,
146
+ 'id' => "ecwid-store-$store_id"
147
+ );
148
+
149
+ if ($ecwid_default_category_id) {
150
+ $input_params['defaultCategoryId'] = $ecwid_default_category_id;
151
+ }
152
+
153
+ $this->_params = $input_params;
154
+ }
155
+
156
+ /**
157
+ * @param $shortcode_params
158
+ *
159
+ * @return mixed|void
160
+ */
161
+ protected function _get_param_default_category_id( $shortcode_params ) {
162
+ $ecwid_default_category_id =
163
+ ! empty( $shortcode_params ) && array_key_exists( 'default_category_id', $shortcode_params )
164
+ ? $shortcode_params['default_category_id']
165
+ : get_option( 'ecwid_default_category_id' );
166
+
167
+ return $ecwid_default_category_id;
168
+ }
169
+ }
includes/shortcodes/class-ecwid-shortcode-search.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once ECWID_SHORTCODES_DIR . '/class-ecwid-shortcode-base.php';
4
+
5
+ class Ecwid_Shortcode_Search extends Ecwid_Shortcode_Base {
6
+
7
+ protected function _process_params( $params = array() ) {
8
+ $this->_should_render = $params['is_ecwid_shortcode'] ? true : get_option('ecwid_show_search_box');
9
+ }
10
+
11
+ public function get_shortcode_name() {
12
+ return 'search';
13
+ }
14
+
15
+ public function get_ecwid_widget_function_name() {
16
+ if (get_option('ecwid_use_new_search', false)) {
17
+ return 'xSearch';
18
+ } else {
19
+ return 'xSearchBox';
20
+ }
21
+ }
22
+ }
includes/themes.php CHANGED
@@ -52,7 +52,8 @@ function ecwid_apply_theme($theme_name = null)
52
  'sliding-door' => array( 'css-no-parent' ),
53
  'zerif-lite' => array( 'css-no-parent' ),
54
  'storefront' => array( 'css' ),
55
- 'salient' => array( 'css-no-parent')
 
56
  );
57
  $generic_themes = apply_filters('ecwid_generic_themes', $generic_themes);
58
 
@@ -64,7 +65,8 @@ function ecwid_apply_theme($theme_name = null)
64
  'genesis',
65
  'twentysixteen',
66
  'central',
67
- 'mfupdate'
 
68
  );
69
  $custom_themes = apply_filters( 'ecwid_custom_themes', $custom_themes );
70
 
52
  'sliding-door' => array( 'css-no-parent' ),
53
  'zerif-lite' => array( 'css-no-parent' ),
54
  'storefront' => array( 'css' ),
55
+ 'salient' => array( 'css-no-parent'),
56
+ 'flora' => array('js')
57
  );
58
  $generic_themes = apply_filters('ecwid_generic_themes', $generic_themes);
59
 
65
  'genesis',
66
  'twentysixteen',
67
  'central',
68
+ 'mfupdate',
69
+ 'trend'
70
  );
71
  $custom_themes = apply_filters( 'ecwid_custom_themes', $custom_themes );
72
 
includes/themes/class-ecwid-theme-trend.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once ECWID_THEMES_DIR . '/class-ecwid-theme-base.php';
4
+
5
+ class Ecwid_Theme_Trend extends Ecwid_Theme_Base
6
+ {
7
+ protected $name = 'Trend';
8
+
9
+ protected $shortcodes = array();
10
+
11
+ public function __construct()
12
+ {
13
+ parent::__construct();
14
+
15
+ add_filter('ecwid_disable_widgets', '__return_true');
16
+ add_filter('ecwid_shortcode_custom_renderer', array($this, 'get_custom_renderer'));
17
+ add_filter('the_content', array($this, 'add_shortcodes'));
18
+ }
19
+
20
+ public function get_custom_renderer() {
21
+ return array($this, 'render_shortcode');
22
+ }
23
+
24
+ public function render_shortcode($shortcode) {
25
+
26
+ if ($shortcode instanceof Ecwid_Shortcode_Base) {
27
+ return $shortcode->render_placeholder() . $this->_render_shortcode_script($shortcode);
28
+ }
29
+
30
+ return '';
31
+ }
32
+
33
+ public function add_shortcodes($content) {
34
+ $ecwid_store_id = get_ecwid_store_id();
35
+ $before = <<<HTML
36
+ <script>
37
+ ecwid_shortcodes = [];
38
+ </script>
39
+ HTML;
40
+ $after = <<<HTML
41
+ <script>
42
+ window.ecwid_script_defer = true;
43
+ window.ecwid_dynamic_widgets = true;
44
+
45
+ if (typeof Ecwid != 'undefined') Ecwid.destroy();
46
+
47
+ if (typeof ecwid_shortcodes != 'undefined') {
48
+ window._xnext_initialization_scripts = ecwid_shortcodes;
49
+
50
+ if (!document.getElementById('ecwid-script')) {
51
+ var script = document.createElement('script');
52
+ script.charset = 'utf-8';
53
+ script.type = 'text/javascript';
54
+ script.src = 'https://app.ecwid.com/script.js?$ecwid_store_id';
55
+ script.id = 'ecwid-script'
56
+ document.body.appendChild(script);
57
+ } else {
58
+ ecwid_onBodyDone();
59
+ }
60
+
61
+ }
62
+ </script>
63
+ HTML;
64
+ return $before . $content . $after;
65
+ }
66
+
67
+ protected function _render_shortcode_script(Ecwid_Shortcode_Base $shortcode) {
68
+
69
+ $args = $shortcode->build_params_string();
70
+ $id = $shortcode->get_html_id();
71
+ $widgetType = substr($shortcode->get_ecwid_widget_function_name(), 1);
72
+ if ($widgetType == 'Search') {
73
+ $widgetType = 'SearchWidget';
74
+ }
75
+ $store_id = get_ecwid_store_id();
76
+
77
+ $code = <<<HTML
78
+ <script type="text/javascript">
79
+ ecwid_shortcodes[ecwid_shortcodes.length] = {
80
+ widgetType: '$widgetType',
81
+ id: '$id',
82
+ arg: [$args]
83
+ };
84
+ </script>
85
+ HTML;
86
+ return $code;
87
+
88
+ }
89
+ }
90
+
91
+ $ecwid_current_theme = new Ecwid_Theme_Trend();
includes/widgets.php CHANGED
@@ -14,6 +14,13 @@ if (ecwid_migrations_is_original_plugin_version_older_than('4.3')) {
14
  }
15
 
16
  function ecwid_sidebar_widgets_init() {
 
 
 
 
 
 
 
17
  register_widget('Ecwid_Widget_Badge');
18
  register_widget('Ecwid_Widget_Search');
19
 
14
  }
15
 
16
  function ecwid_sidebar_widgets_init() {
17
+
18
+ $disable_widgets = apply_filters('ecwid_disable_widgets', false);
19
+
20
+ if ($disable_widgets) {
21
+ return;
22
+ }
23
+
24
  register_widget('Ecwid_Widget_Badge');
25
  register_widget('Ecwid_Widget_Search');
26
 
js/cf7designer.js ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ if (typeof(Ecwid) == 'object') {
2
+ Ecwid.OnAPILoaded.add(function(page){
3
+ jQuery('html').attr('id', 'ecwid_html')
4
+ });
5
+ }
js/themes/flora.js ADDED
@@ -0,0 +1,2 @@
 
 
1
+ if (!window.History.options) window.History.options = {};
2
+ window.History.options.html4Mode=1;
js/themes/trend-shortcodes.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ window.ecwid_script_defer = true;
2
+ window.ecwid_dynamic_widgets = true;
3
+
4
+ if (typeof Ecwid != 'undefined') Ecwid.destroy();
5
+
6
+ if (typeof ecwid_shortcodes != 'undefined' && typeof ecwid_store_id != 'undefined') {
7
+ window._xnext_initialization_scripts = ecwid_shortcodes;
8
+
9
+ if (!document.getElementById('ecwid-script')) {
10
+ var script = document.createElement('script');
11
+ script.charset = 'utf-8';
12
+ script.type = 'text/javascript';
13
+ script.src = 'https://app.ecwid.com/script.js?' + ecwid_store_id;
14
+ script.id = 'ecwid-script'
15
+ document.body.appendChild(script);
16
+ } else {
17
+ ecwid_onBodyDone();
18
+ }
19
+
20
+ }
lib/ecwid_api_v3.php CHANGED
@@ -38,6 +38,7 @@ class Ecwid_Api_V3
38
  update_option(self::TOKEN_OPTION_NAME, $value);
39
  }
40
 
 
41
  public function get_categories($input_params)
42
  {
43
  $params = array('token');
@@ -107,6 +108,7 @@ class Ecwid_Api_V3
107
 
108
  return $result->items;
109
  }
 
110
 
111
  protected static function _load_token()
112
  {
@@ -163,7 +165,11 @@ class Ecwid_Api_V3
163
 
164
  $url = $this->build_request_url($this->_stores_api_url, $params);
165
 
166
- $result = EcwidPlatform::http_get_request($url);
 
 
 
 
167
 
168
  return @$result['code'] == 200;
169
  }
@@ -230,7 +236,7 @@ class Ecwid_Api_V3
230
  array(
231
  'timeout' => 20,
232
  'headers' => array(
233
- 'Content-Type' => 'application/json;application/json;charest="utf-8"')
234
  )
235
  );
236
 
38
  update_option(self::TOKEN_OPTION_NAME, $value);
39
  }
40
 
41
+ /*
42
  public function get_categories($input_params)
43
  {
44
  $params = array('token');
108
 
109
  return $result->items;
110
  }
111
+ */
112
 
113
  protected static function _load_token()
114
  {
165
 
166
  $url = $this->build_request_url($this->_stores_api_url, $params);
167
 
168
+ $request = Ecwid_Http::create_get('does_store_exist', $url, array(
169
+ Ecwid_Http::POLICY_RETURN_VERBOSE
170
+ ));
171
+
172
+ $result = $request->do_request();
173
 
174
  return @$result['code'] == 200;
175
  }
236
  array(
237
  'timeout' => 20,
238
  'headers' => array(
239
+ 'Content-Type' => 'application/json;charset="utf-8"')
240
  )
241
  );
242
 
lib/ecwid_platform.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class EcwidPlatform {
4
 
5
  static protected $http_use_streams = false;
@@ -73,6 +75,11 @@ class EcwidPlatform {
73
  return wp_parse_args($args, $defaults);
74
  }
75
 
 
 
 
 
 
76
  static public function fetch_url($url, $options = array())
77
  {
78
  $default_timeout = 10;
1
  <?php
2
 
3
+ require_once 'ecwid_requests.php';
4
+
5
  class EcwidPlatform {
6
 
7
  static protected $http_use_streams = false;
75
  return wp_parse_args($args, $defaults);
76
  }
77
 
78
+ static public function report_error($error) {
79
+ $request = Ecwid_HTTP::create_error_report($error);
80
+ $request->do_request();
81
+ }
82
+
83
  static public function fetch_url($url, $options = array())
84
  {
85
  $default_timeout = 10;
lib/ecwid_product_api.php CHANGED
@@ -19,10 +19,22 @@ class EcwidProductApi {
19
  $this->store_id = intval($store_id);
20
  }
21
 
 
 
 
 
 
 
 
 
 
 
22
  function process_request($url) {
23
 
24
  $result = false;
25
- $fetch_result = EcwidPlatform::fetch_url($url);
 
 
26
 
27
  if ($fetch_result['code'] == 200) {
28
  $this->error = '';
@@ -215,7 +227,8 @@ class EcwidProductApi {
215
  if (ini_get('allow_url_fopen')) {
216
  $stream = fopen($request_url, 'r');
217
  } else {
218
- $response = EcwidPlatform::fetch_url($request_url);
 
219
  $body = $response['data'];
220
  $stream = fopen('php://temp', 'rw');
221
  fwrite($stream, $body);
19
  $this->store_id = intval($store_id);
20
  }
21
 
22
+ function get_request($url) {
23
+ return Ecwid_HTTP::create_get(
24
+ 'api_v1_request',
25
+ $url,
26
+ array(
27
+ Ecwid_HTTP::POLICY_RETURN_JSON_ARRAY, Ecwid_HTTP::POLICY_RETURN_VERBOSE
28
+ )
29
+ );
30
+ }
31
+
32
  function process_request($url) {
33
 
34
  $result = false;
35
+
36
+ $request = $this->get_request($url);
37
+ $fetch_result = $request->do_request();
38
 
39
  if ($fetch_result['code'] == 200) {
40
  $this->error = '';
227
  if (ini_get('allow_url_fopen')) {
228
  $stream = fopen($request_url, 'r');
229
  } else {
230
+ $request = $this->get_request($request_url);
231
+ $response = $request->do_request();
232
  $body = $response['data'];
233
  $stream = fopen('php://temp', 'rw');
234
  fwrite($stream, $body);
lib/ecwid_requests.php ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class Ecwid_Http {
4
+
5
+ protected $name = '';
6
+ protected $url = '';
7
+ protected $policies;
8
+ protected $is_error = false;
9
+ protected $error_message = '';
10
+ protected $raw_result;
11
+ protected $processed_data;
12
+ protected $timeout;
13
+ protected $jsonp_callback = null;
14
+ protected $code;
15
+ protected $message;
16
+ protected $headers;
17
+
18
+ const TRANSPORT_CHECK_EXPIRATION = 86400;
19
+
20
+ /**
21
+ * No error handling whatsoever
22
+ */
23
+ const POLICY_IGNORE_ERRORS = 'ignore_errors';
24
+
25
+ /**
26
+ * Data sent and received will be treated like jsonp
27
+ */
28
+ const POLICY_RETURN_JSON = 'return_json';
29
+
30
+ /**
31
+ * Data received will be interpreted as json array
32
+ */
33
+ const POLICY_RETURN_JSON_ARRAY = 'expect_json_array';
34
+
35
+ /**
36
+ * Data sent and received will be treated like jsonp
37
+ */
38
+ const POLICY_EXPECT_JSONP = 'expect_jsonp';
39
+
40
+ /**
41
+ * Returns all response data with headers and such instead of data only
42
+ */
43
+ const POLICY_RETURN_VERBOSE = 'return_verbose';
44
+
45
+ abstract protected function _do_request($url, $args);
46
+
47
+ public function __construct($name, $url, $policies) {
48
+ $this->name = $name;
49
+ $this->url = $url;
50
+ $this->policies = $policies;
51
+ }
52
+
53
+ public function get_response_meta() {
54
+ return array(
55
+ 'data' => $this->raw_result,
56
+ 'code' => $this->code,
57
+ 'message' => $this->message,
58
+ 'headers' => $this->headers
59
+ );
60
+ }
61
+
62
+ public function do_request($args = array()) {
63
+ $url = $this->_preprocess_url($this->url);
64
+
65
+ $data = $this->_do_request($url, $args);
66
+
67
+ if ( is_null( $data ) || $this->is_error ) return null;
68
+
69
+ $this->_process_data($data);
70
+
71
+ return $this->processed_data;
72
+ }
73
+
74
+ public static function create_error_report($message) {
75
+ $error_url = 'http://' . APP_ECWID_COM . '/script.js?805056&data_platform=wporg&data_wporg_error=' . urlencode($message) . '&url=' . urlencode(get_bloginfo('url'));
76
+ return self::create_get(
77
+ 'error_report',
78
+ $error_url,
79
+ array(
80
+ self::POLICY_IGNORE_ERRORS
81
+ )
82
+ );
83
+ }
84
+
85
+ public static function create_get($name, $url, $params) {
86
+ $transport_class = self::_get_transport($name, $url, $params);
87
+
88
+ if (!$transport_class) {
89
+ $transport_class = self::_detect_get_transport($name, $url, $params);
90
+ }
91
+
92
+ if (empty($transport_class)) {
93
+ return null;
94
+ }
95
+
96
+ $transport = new $transport_class($name, $url, $params);
97
+
98
+ return $transport;
99
+ }
100
+
101
+ public static function create_post($name, $url, $params) {
102
+ $transport_class = self::_post_transport($name, $url, $params);
103
+
104
+ if (!$transport_class) {
105
+ $transport_class = self::_detect_post_transport($name, $url, $params);
106
+ }
107
+
108
+ if (empty($transport_class)) {
109
+ return null;
110
+ }
111
+
112
+ $transport = new $transport_class($name, $url, $params);
113
+
114
+ return $transport;
115
+ }
116
+
117
+ protected static function _get_transport($name) {
118
+ $data = EcwidPlatform::get('get_transport_' . $name);
119
+
120
+ if (!empty($data) && @$data['use_default']) {
121
+ return self::_get_default_transport();
122
+ }
123
+
124
+ $preferred = @$data['preferred'];
125
+ if (!empty($preferred) && ( time() - @$data['last_check'] ) < self::TRANSPORT_CHECK_EXPIRATION ) {
126
+ return $preferred;
127
+ }
128
+
129
+ return null;
130
+ }
131
+
132
+
133
+ protected static function _post_transport($name) {
134
+ $data = EcwidPlatform::get('get_transport_' . $name);
135
+
136
+ if (!empty($data) && @$data['use_default']) {
137
+ return self::_post_default_transport();
138
+ }
139
+ $preferred = @$data['preferred'];
140
+ if (!empty($preferred) && ( time() - @$data['last_check'] ) < self::TRANSPORT_CHECK_EXPIRATION ) {
141
+ return $preferred;
142
+ }
143
+
144
+ return null;
145
+ }
146
+
147
+ protected static function _detect_get_transport($name, $url, $params) {
148
+
149
+ foreach (self::_get_transports() as $transport_class) {
150
+ $transport = new $transport_class($name, $url, $params);
151
+
152
+ $result = $transport->do_request();
153
+
154
+ if (!$transport->is_error) {
155
+ self::_set_transport_for_request(
156
+ $name,
157
+ array(
158
+ 'preferred' => $transport_class,
159
+ 'last_check' => time()
160
+ )
161
+ );
162
+
163
+ return $transport_class;
164
+ }
165
+ }
166
+
167
+ return null;
168
+ }
169
+
170
+
171
+ protected static function _detect_post_transport($name, $url, $params) {
172
+
173
+ foreach (self::_get_transports() as $transport_class) {
174
+ $transport = new $transport_class($name, $url, $params);
175
+
176
+ $result = $transport->do_request();
177
+
178
+ if (!$transport->is_error) {
179
+ self::_set_transport_for_request(
180
+ $name,
181
+ array(
182
+ 'preferred' => $transport_class,
183
+ 'last_check' => time()
184
+ )
185
+ );
186
+
187
+ return $transport_class;
188
+ }
189
+ }
190
+
191
+ return null;
192
+ }
193
+
194
+ protected static function _set_transport_for_request($name, $transport) {
195
+ EcwidPlatform::set('get_transport_' . $name, $transport);
196
+ }
197
+
198
+ protected static function _get_transport_for_request($name) {
199
+ return EcwidPlatform::get('get_transport_' . $name);
200
+ }
201
+
202
+ protected static function _get_default_transport() {
203
+ return 'Ecwid_HTTP_Get_WpRemoteGet';
204
+ }
205
+
206
+ protected static function _post_default_transport() {
207
+ return 'Ecwid_HTTP_Post_WpRemotePost';
208
+ }
209
+
210
+ protected static function _get_transports() {
211
+ return array('Ecwid_HTTP_Get_WpRemoteGet', 'Ecwid_HTTP_Get_Fopen');
212
+ }
213
+
214
+ protected static function _post_transports() {
215
+ return array('Ecwid_HTTP_Post_WpRemotePost', 'Ecwid_HTTP_Post_Fopen');
216
+ }
217
+
218
+ protected function _trigger_error() {
219
+ $this->is_error = true;
220
+ $this->error = $this->raw_result;
221
+
222
+ self::_set_transport_for_request($this->name, null);
223
+
224
+ if ( $this->_has_policy(self::POLICY_IGNORE_ERRORS) ) {
225
+ return false;
226
+ }
227
+
228
+ return true;
229
+ }
230
+
231
+ protected function _has_policy( $policy ) {
232
+ return in_array( $policy, $this->policies );
233
+ }
234
+
235
+ protected function _process_data($raw_data) {
236
+ $result = $raw_data;
237
+
238
+ if ( in_array( self::POLICY_EXPECT_JSONP, $this->policies ) ) {
239
+ $prefix_length = strlen($this->jsonp_callback . '(');
240
+ $suffix_length = strlen(');');
241
+ $result = substr($raw_data, $prefix_length, strlen($result) - $suffix_length - $prefix_length - 1);
242
+
243
+ $result = json_decode($result);
244
+ }
245
+
246
+ if ( in_array( self::POLICY_RETURN_JSON_ARRAY, $this->policies ) ) {
247
+ $result = json_decode($raw_data, true);
248
+ }
249
+
250
+ if ( in_array( self::POLICY_RETURN_JSON, $this->policies ) ) {
251
+ $result = json_decode($raw_data);
252
+ }
253
+
254
+ if ( $this->_has_policy( self::POLICY_RETURN_VERBOSE ) ) {
255
+ $result = $this->get_response_meta();
256
+ $result['data'] = $raw_data;
257
+ }
258
+
259
+ $this->processed_data = $result;
260
+ }
261
+
262
+ protected function _preprocess_url($url) {
263
+
264
+ if ( in_array( 'expect_jsonp', $this->policies ) ) {
265
+ $this->jsonp_callback = 'jsoncallback' . time();
266
+ $url .= '&callback=' . $this->jsonp_callback;
267
+ }
268
+
269
+ return $url;
270
+ }
271
+ }
272
+
273
+ abstract class Ecwid_HTTP_Get extends Ecwid_Http {
274
+ protected function _trigger_error() {
275
+ $continue = parent::_trigger_error();
276
+
277
+ if (!$continue) {
278
+ return false;
279
+ }
280
+ update_option('ecwid_remote_get_fails', 1);
281
+
282
+ $report = $this->create_error_report($this->message);
283
+
284
+ $report->do_request();
285
+ }
286
+ }
287
+
288
+ class Ecwid_HTTP_Get_WpRemoteGet extends Ecwid_HTTP_Get {
289
+
290
+ protected function _do_request($url, $args) {
291
+
292
+ $this->raw_result = wp_remote_get(
293
+ $url,
294
+ $args
295
+ );
296
+
297
+ if (is_wp_error($this->raw_result)) {
298
+ $this->_trigger_error();
299
+
300
+ return $this->raw_result;
301
+ }
302
+
303
+ $this->code = $this->raw_result['response']['code'];
304
+ $this->message = $this->raw_result['response']['message'];
305
+ $this->headers = $this->raw_result['headers'];
306
+
307
+ return $this->raw_result['body'];
308
+ }
309
+
310
+ protected function _trigger_error() {
311
+
312
+ if (is_wp_error($this->error)) {
313
+ $a = new WP_Error;
314
+
315
+ $this->error_message = $this->error->get_error_message();
316
+ }
317
+
318
+ return parent::_trigger_error();
319
+ }
320
+ }
321
+
322
+ class Ecwid_HTTP_Get_Fopen extends Ecwid_HTTP_Get {
323
+
324
+ protected function _do_request($url, $args) {
325
+
326
+ $stream_context_args = array('http'=> array());
327
+ if (@$args['timeout']) {
328
+ $stream_context_args['http']['timeout'] = $args['timeout'];
329
+ }
330
+
331
+ $ctx = stream_context_create($stream_context_args);
332
+ $handle = @fopen($url, 'r', null, $ctx);
333
+
334
+ if (!$handle) {
335
+ $this->_trigger_error();
336
+
337
+ $last = error_get_last();
338
+ $this->message = $last['message'];
339
+
340
+ return null;
341
+ }
342
+
343
+ $this->raw_result = stream_get_contents($handle);
344
+
345
+ $this->headers = $this->_get_meta($handle);
346
+ $this->code = $this->headers['code'];
347
+ $this->message = $this->headers['message'];
348
+
349
+ return $this->raw_result;
350
+ }
351
+
352
+ protected function _get_meta($handle) {
353
+ $meta = stream_get_meta_data($handle);
354
+
355
+ $result = array();
356
+
357
+ foreach ($meta['wrapper_data'] as $item) {
358
+
359
+ $match = array();
360
+ if (preg_match('|HTTP/\d\.\d\s+(\d+)\s+(.*)|',$item, $match)) {
361
+ $result['code'] = $match[1];
362
+ $result['message'] = $match[2];
363
+ }
364
+
365
+ $colon_pos = strpos($item, ':');
366
+
367
+ if (!$colon_pos) continue;
368
+
369
+ $name = substr($item, 0, $colon_pos);
370
+ $result[strtolower($name)] = trim(substr($item, $colon_pos + 1));
371
+ }
372
+
373
+ return $result;
374
+ }
375
+ }
376
+
377
+ abstract class Ecwid_HTTP_Post extends Ecwid_Http {
378
+
379
+ }
380
+
381
+ class Ecwid_HTTP_Post_WpRemotePost extends Ecwid_Http_Post {
382
+
383
+ protected function _do_request($url, $args) {
384
+
385
+ $this->raw_result = wp_remote_post(
386
+ $url,
387
+ $args
388
+ );
389
+
390
+ if (is_wp_error($this->raw_result)) {
391
+ $this->_trigger_error();
392
+
393
+ return $this->raw_result;
394
+ }
395
+
396
+ $this->code = $this->raw_result['response']['code'];
397
+ $this->message = $this->raw_result['response']['message'];
398
+ $this->headers = $this->raw_result['headers'];
399
+
400
+ return $this->raw_result['body'];
401
+
402
+ }
403
+ }
404
+
405
+ class Ecwid_HTTP_Post_Fopen extends Ecwid_Http_Post {
406
+ protected function _do_request($url, $args) {
407
+
408
+ $stream_context_args = array(
409
+ 'http'=> array(
410
+ 'method' => 'POST',
411
+ 'headers' => 'Content-Type: application/x-www-form-urlencoded\r\n'
412
+ )
413
+ );
414
+ if (@$args['timeout']) {
415
+ $stream_context_args['http']['timeout'] = $args['timeout'];
416
+ }
417
+
418
+ if (@$args['headers']) {
419
+ $stream_context_args['http']['headers'] = $args['headers'];
420
+ }
421
+
422
+ if (@$args['body']) {
423
+ $stream_context_args['http']['content'] = http_build_query($args['body']);
424
+ }
425
+
426
+
427
+ $ctx = stream_context_create($stream_context_args);
428
+ $handle = @fopen($url, 'r', null, $ctx);
429
+
430
+ if (!$handle) {
431
+ $this->_trigger_error();
432
+ $this->message = error_get_last();
433
+
434
+ return null;
435
+ }
436
+
437
+ $this->raw_result = stream_get_contents($handle);
438
+
439
+ $this->headers = $this->_get_meta($handle);
440
+ $this->code = $this->headers['code'];
441
+ $this->message = $this->headers['message'];
442
+
443
+ return $this->raw_result;
444
+ }
445
+
446
+ protected function _get_meta($handle) {
447
+ $meta = stream_get_meta_data($handle);
448
+
449
+ $result = array();
450
+
451
+ foreach ($meta['wrapper_data'] as $item) {
452
+
453
+ $match = array();
454
+ if (preg_match('|HTTP/\d\.\d\s+(\d+)\s+(.*)|',$item, $match)) {
455
+ $result['code'] = $match[1];
456
+ $result['message'] = $match[2];
457
+ }
458
+
459
+ $colon_pos = strpos($item, ':');
460
+
461
+ if (!$colon_pos) continue;
462
+
463
+ $name = substr($item, 0, $colon_pos);
464
+ $result[strtolower($name)] = trim(substr($item, $colon_pos + 1));
465
+ }
466
+
467
+ return $result;
468
+ }
469
+
470
+
471
+ }
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.5
5
  Tested up to: 4.6
6
- Stable tag: 4.5
7
 
8
  Powerful, easy to use ecommerce shopping cart. Bank level PCI DSS Level 1 security. iPhone & Android apps. Superb support. Free plan available.
9
 
@@ -149,6 +149,14 @@ You can use Ecwid’s built-in import tools to copy your store products from any
149
  * [Ecwid eCommerce Forums](https://www.ecwid.com/forums/forumdisplay.php?f=19)
150
 
151
  == Changelog ==
 
 
 
 
 
 
 
 
152
  = 4.5 =
153
  - **Update in the Single Sign On Module (Ecwid SSO).** Single Sign-On allows your customers to have a single login for your WordPress site and your Ecwid store. We updated it to use the latest Ecwid ecommerce APIs to make it more convenient for you. Now the module doesn't require a separate API key – it works seamlessly with no extra setup.
154
  - **Compatibility with Divi builder editor.** Divi builder adds a nice WYSIWYG editor to the Wordpress admin. Ecwid shopping cart now is compatible with that editor – so you can add Ecwid store shortcode right from the Divi builder editor, no need to switch back to the default Wordpress editor if you prefer to use the Divi's one.
3
  Tags: ecommerce, downloadable products, Facebook ecommerce, online store, paypal, product catalog, shop, shopping cart, store
4
  Requires at least: 3.5
5
  Tested up to: 4.6
6
+ Stable tag: 4.6
7
 
8
  Powerful, easy to use ecommerce shopping cart. Bank level PCI DSS Level 1 security. iPhone & Android apps. Superb support. Free plan available.
9
 
149
  * [Ecwid eCommerce Forums](https://www.ecwid.com/forums/forumdisplay.php?f=19)
150
 
151
  == Changelog ==
152
+ = 4.6 =
153
+ - **Compatibility with the "Contact form 7 designer" plugin** . When installed, the "Contact form 7 designer" plugin adds its own code to the <html> and <body> tags on the page on every page of the site. This conflicted with Ecwid storefront styles. We fixed that – now if you use the both plugin t the same time, your site pages styles should work fine. Note: this plugin is not the same as the popular "Contact form 7". Ecwid ecommerce functionality works well with the latter, so don't worry if you use it on your site.
154
+ - **Fix for a store links issue in the "Flora" theme by Wyde.** Users with "Flora" theme on their sites reported that there are glitches in the way Ecwid online store links behave in that theme. We fixed that – Ecwid now works well with "Flora".
155
+ - **Compatibility with the "Trend" Wordpress theme.** Ecwid shopping cart is designed to work great with all WordPress themes. However, we sometimes see that Ecwid has troubles working with some AJAX-driven WordPress themes. We found a way to fix this and started working on improving the plugin. With this release, the Ecwid plugin becomes compatible with the beautiful "Trend" theme. We'll get to the other AJAX themes in the future releases. If you find a theme that Ecwid has troubles with, please let us know – we'll fix that.
156
+ - **Fixed a bug with the store menu item duplicates.** In a recent update, we fixed duplicate Store pages appearing when you deactivate and re-activate the plugin several times. In this release, we fixed a similar bug with the "Store" menu items. However often you enable/disable the plugin, the site navigation menu now works properly, keeping a single Store link, unless you deliberately add a few shop links to the menu (e.g. to have store category links in the menu).
157
+ - Minor improvement and fixes to make the plugin more stable and user friendly.
158
+
159
+
160
  = 4.5 =
161
  - **Update in the Single Sign On Module (Ecwid SSO).** Single Sign-On allows your customers to have a single login for your WordPress site and your Ecwid store. We updated it to use the latest Ecwid ecommerce APIs to make it more convenient for you. Now the module doesn't require a separate API key – it works seamlessly with no extra setup.
162
  - **Compatibility with Divi builder editor.** Divi builder adds a nice WYSIWYG editor to the Wordpress admin. Ecwid shopping cart now is compatible with that editor – so you can add Ecwid store shortcode right from the Divi builder editor, no need to switch back to the default Wordpress editor if you prefer to use the Divi's one.
templates/help.php CHANGED
@@ -216,6 +216,7 @@
216
  </div>
217
  </div>
218
 
 
219
  <div class="block-contact">
220
  <h2><?php _e( 'Send a message to our support team', 'ecwid-shopping-cart' ); ?> </h2>
221
 
@@ -249,6 +250,7 @@
249
  <p><a id="show-ecwid-contact-again" href="#"><?php _e( 'You can send a new request here.', 'ecwid-shopping-cart'); ?></a></p>
250
 
251
  </div>
 
252
 
253
  </div>
254
 
216
  </div>
217
  </div>
218
 
219
+ <?php if (!in_array($_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1'))): ?>
220
  <div class="block-contact">
221
  <h2><?php _e( 'Send a message to our support team', 'ecwid-shopping-cart' ); ?> </h2>
222
 
250
  <p><a id="show-ecwid-contact-again" href="#"><?php _e( 'You can send a new request here.', 'ecwid-shopping-cart'); ?></a></p>
251
 
252
  </div>
253
+ <?php endif; ?>
254
 
255
  </div>
256