Ecwid Ecommerce Shopping Cart - Version 2.3

Version Description

  • Added compatibility with Google XML Sitemaps plugin. Now you can submit your store items links along with the other site pages to search engines. To use this feature, please install the "Google XML Sitemaps" plugin (http://wordpress.org/plugins/google-sitemap-generator/), generate a sitemap (it will include your products and categories links) and submit it to the search engines to help them better crawl and categorize your site.

  • Improved compatibility with SEO Ultimate plugin. Ecwid plugin always displays your store pages in a proper SEO-friendly format to make the store indexable by search engines. Moreover, we constantly adjust the plugin to make it work fine with popular third party SEO modules. So Ecwid is perfectly compatible with "Wordpress SEO by Yoast", "All in one SEO Pack", "Platinum SEO Pack" and now with "SEO Ultimate" plugin.

  • Minor design improvements of the plugin settings pages to make them mobile-friendly for better compatibility with the backend layout of new Wordpress versions. Now you can manage Ecwid plugin settings in your Wordpress administrator panel using your mobile device.

  • New "Ecwid badges" widget is available. If you like Ecwid and want to help it grow and become the most popular e-commerce solution, you can now add a fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid. Please find the new widget under 'Appearance Widgets' section in your Wordpress backend.

Download this release

Release Info

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

Code changes from version 2.2.1 to 2.3

css/admin.css CHANGED
@@ -1,44 +1,64 @@
1
- #wpadminbar .ecwid-top-menu-item {
2
- margin-top: 0px;
3
- width: 23px;
4
- height: 28px;
5
- background: url(../images/icon-head-default.png) no-repeat 0% 2px;
6
- }
7
-
8
- #wpadminbar .ecwid-top-menu-item:hover,
9
- #wpadminbar .hover .ecwid-top-menu-item{
10
- background-image: url(../images/icon-head-active.png);
11
- }
12
-
13
- #adminmenu #toplevel_page_ecwid div.wp-menu-image {
14
- background: url(../images/icon-sidebar-default.png) no-repeat 5px 2px;
15
- margin: 2px 3px 2px 2px;
16
- width: 23px;
17
- height: 23px;
18
- }
19
-
20
- #adminmenu #toplevel_page_ecwid:hover div.wp-menu-image,
21
- #adminmenu #toplevel_page_ecwid.wp-has-current-submenu div.wp-menu-image
22
- {
23
- background-image: url(../images/icon-sidebar-active.png);
24
- }
25
-
26
- .ecwid-settings h2 {
27
- background:url(../images/icon-title.png) no-repeat 0% 50%;
28
- padding-left: 43px;
29
- line-height: 32px;
30
- margin-bottom: 30px;
31
- }
32
-
33
- #hide-vote-message {
34
- text-decoration: underline;
35
- cursor: pointer;
36
- }
37
-
38
- #hide-vote-message.hiding {
39
- cursor: wait;
40
- }
41
-
42
- #wp-toolbar > ul > li#wp-admin-bar-ecwid-main {
43
- display: block;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  }
1
+ #wpadminbar .ecwid-top-menu-item {
2
+ margin-top: 0px;
3
+ width: 23px;
4
+ height: 28px;
5
+ background: url(../images/icon-head-default.png) no-repeat 0% 2px;
6
+ }
7
+
8
+ #wpadminbar .ecwid-top-menu-item:hover,
9
+ #wpadminbar .hover .ecwid-top-menu-item{
10
+ background-image: url(../images/icon-head-active.png);
11
+ }
12
+
13
+ #adminmenu #toplevel_page_ecwid div.wp-menu-image {
14
+ background: url(../images/icon-sidebar-default.png) no-repeat 5px 2px;
15
+ margin: 2px 3px 2px 2px;
16
+ width: 23px;
17
+ height: 23px;
18
+ }
19
+
20
+ #adminmenu #toplevel_page_ecwid:hover div.wp-menu-image,
21
+ #adminmenu #toplevel_page_ecwid.wp-has-current-submenu div.wp-menu-image
22
+ {
23
+ background-image: url(../images/icon-sidebar-active.png);
24
+ }
25
+
26
+ .ecwid-settings h2 {
27
+ background:url(../images/icon-title.png) no-repeat 0% 50%;
28
+ padding-left: 43px;
29
+ line-height: 32px;
30
+ margin-bottom: 30px;
31
+ }
32
+
33
+ #hide-vote-message {
34
+ text-decoration: underline;
35
+ cursor: pointer;
36
+ }
37
+
38
+ #hide-vote-message.hiding {
39
+ cursor: wait;
40
+ }
41
+
42
+ #wp-toolbar > ul > li#wp-admin-bar-ecwid-main {
43
+ display: block;
44
+ }
45
+
46
+ .ecwid-badge {
47
+ display: table;
48
+ width: 70%;
49
+ min-width: 200px;
50
+ padding: 3px;
51
+ }
52
+
53
+ .ecwid-badge > div {
54
+ display: table-cell;
55
+ vertical-align: middle;
56
+ height: 55px;
57
+ }
58
+
59
+ .ecwid-badge .checkbox {
60
+ width: 15px;
61
+ }
62
+ .ecwid-badge .image {
63
+ text-align: center;
64
  }
css/settings.3.8.css CHANGED
@@ -58,4 +58,176 @@
58
 
59
  .ecwid-pb-view-size .ruler {
60
  background: #cacaca;
61
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
 
59
  .ecwid-pb-view-size .ruler {
60
  background: #cacaca;
61
+ }
62
+
63
+ @media screen and (max-width: 782px) {
64
+ .ecwid-settings.general-settings,
65
+ .ecwid-settings.appearance-settings,
66
+ .ecwid-settings.advanced-settings
67
+ {
68
+ max-width: inherit;
69
+ width: inherit;
70
+ }
71
+
72
+ .ecwid-settings h2 {
73
+ margin-bottom: 0px;
74
+ }
75
+
76
+ .ecwid-settings.pure-form fieldset > :not(legend) {
77
+ margin-left: 0px;
78
+ }
79
+
80
+
81
+ .general-settings.ecwid-settings .greeting-box {
82
+ height: inherit;
83
+ text-align: center;
84
+ }
85
+
86
+ .general-settings.ecwid-settings .greeting-box > div {
87
+ display: block;
88
+ }
89
+ .general-settings.ecwid-settings ol {
90
+ padding-left: 0px;
91
+ }
92
+
93
+ .general-settings.ecwid-settings .section {
94
+ width: 100%;
95
+ }
96
+
97
+ .general-settings.ecwid-settings .section .left,
98
+ .general-settings.ecwid-settings .note {
99
+ margin-top: 0px;
100
+ }
101
+
102
+ .general-settings.ecwid-settings .section .left,
103
+ .general-settings.ecwid-settings .section .right {
104
+ text-align: left;
105
+ display: block;
106
+ }
107
+
108
+ .general-settings.ecwid-settings button,
109
+ .general-settings.ecwid-settings #ecwid_store_id,
110
+ .general-settings.ecwid-settings .pure-button {
111
+ display: block;
112
+ width: inherit;
113
+ margin: 10px 0px 10px 0px;
114
+ padding: 0px 5px;
115
+ }
116
+ .general-settings.ecwid-settings button,
117
+ .general-settings.ecwid-settings #ecwid_store_id {
118
+ width: 100%;
119
+ }
120
+
121
+ .general-settings.ecwid-settings .button-primary {
122
+ width: 100%;
123
+ text-align: center;
124
+ margin-top: 10px;
125
+ }
126
+
127
+ .general-settings.ecwid-settings .two-buttons {
128
+ position: relative;
129
+ }
130
+
131
+ .general-settings.ecwid-settings .two-buttons .pure-button:last-child {
132
+ position: absolute;
133
+ right: 0px;
134
+ }
135
+ .general-settings.ecwid-settings .two-buttons .pure-button {
136
+ display: inline-block;
137
+ min-width: 44%;
138
+ width: inherit;
139
+ }
140
+
141
+ .general-settings.ecwid-settings input {
142
+ display: block;
143
+ width: 100%;
144
+ }
145
+
146
+ .ecwid-settings .pure-control-group {
147
+ position: relative;
148
+ }
149
+
150
+ .appearance-settings.ecwid-settings .ecwid-pb-view-size {
151
+ display: block;
152
+ }
153
+
154
+ .appearance-settings.ecwid-settings .ecwid-pb-view-size input {
155
+ position: relative;
156
+ z-index: 2;
157
+ }
158
+
159
+ .appearance-settings.ecwid-settings .pure-control-group.small-input input {
160
+ margin: 0px auto;
161
+ }
162
+
163
+ .appearance-settings.ecwid-settings .ecwid-pb-view-size {
164
+ margin: 0px auto 33px;
165
+ padding: 0px;
166
+ }
167
+
168
+ .appearance-settings.ecwid-settings .ecwid-pb-view-size .ruler {
169
+ z-index: 1;
170
+ position: absolute;
171
+ }
172
+
173
+ .appearance-settings.ecwid-settings .ecwid-pb-view-size .bottom {
174
+ margin-top: 5px;
175
+ }
176
+
177
+ .appearance-settings.ecwid-settings .ecwid-pb-view-size.list,
178
+ .appearance-settings.ecwid-settings .ecwid-pb-view-size.table {
179
+ margin-bottom: 0px;
180
+ }
181
+
182
+ .appearance-settings.ecwid-settings .note.pb-note {
183
+ margin: 0px;
184
+ }
185
+
186
+ .appearance-settings.ecwid-settings select {
187
+ width: 100%;
188
+ }
189
+
190
+ .advanced-settings.ecwid-settings label {
191
+ margin-top:35px;
192
+ }
193
+
194
+ .advanced-settings.ecwid-settings input,
195
+ .advanced-settings.ecwid-settings select {
196
+ width: 100%;
197
+ }
198
+
199
+ .advanced-settings.ecwid-settings label {
200
+ margin-bottom: 10px;
201
+ }
202
+
203
+ .advanced-settings.ecwid-settings .note {
204
+ margin-top: 5px;
205
+ }
206
+
207
+ .ecwid-settings fieldset {
208
+ min-width: 0px !important;
209
+ }
210
+
211
+ .ecwid-pb-view-size .bottom .ruler {
212
+ bottom: 15px;
213
+ }
214
+ .pure-control-group.small-input .input > div,
215
+ .pure-control-group.small-input .input input,
216
+ .pure-control-group.small-input .label > label {
217
+ position: static;
218
+ }
219
+
220
+ .pure-control-group.small-input .label,
221
+ .pure-control-group.small-input .label label {
222
+ width: auto;
223
+ margin-bottom: 0px;
224
+ }
225
+
226
+ .pure-control-group.small-input .note {
227
+ display: block;
228
+ position: relative;
229
+ left: 45px;
230
+ margin-right: 45px;
231
+ }
232
+ }
233
+
css/settings.css CHANGED
@@ -47,11 +47,46 @@
47
  box-shadow: none;
48
  }
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  /* 2.8 compatibility for left menu icon */
51
  .wp-menu-image>a>img {
52
  display: none;
53
  }
54
 
 
 
 
 
 
 
55
  .ecwid-settings {
56
  width: 650px;
57
  }
@@ -323,7 +358,12 @@ display: none;
323
  }
324
 
325
  .general-settings .ecwid-account-buttons .pure-button {
326
- margin: 20px 17px 20px 0px;
 
 
 
 
 
327
  }
328
 
329
  .general-settings p.note {
@@ -403,4 +443,4 @@ display: none;
403
  color: #A0A0A0;
404
  margin-top:10px;
405
  margin-bottom: 10px;
406
- }
47
  box-shadow: none;
48
  }
49
 
50
+ .pure-control-group.small-input > div {
51
+ display: table-cell;
52
+ vertical-align: middle;
53
+ position: relative;
54
+ }
55
+
56
+ .pure-control-group.small-input .label {
57
+ width: 265px;
58
+ font-weight: bold;
59
+ }
60
+
61
+ .pure-control-group.small-input .input > div {
62
+ width: 45px;
63
+ text-align: center;
64
+ vertical-align: middle;
65
+ z-index: 10;
66
+ position: relative;
67
+ left: 265px;
68
+ }
69
+
70
+ .pure-control-group.small-input .input input {
71
+ margin: 0px auto;
72
+ }
73
+
74
+ .pure-control-group.small-input .label > * {
75
+ position: relative;
76
+ left: -45px;
77
+ }
78
+
79
  /* 2.8 compatibility for left menu icon */
80
  .wp-menu-image>a>img {
81
  display: none;
82
  }
83
 
84
+ @media screen and (max-width: 782px) {
85
+ .ecwid-settings {
86
+ width: 100%;
87
+ }
88
+ }
89
+
90
  .ecwid-settings {
91
  width: 650px;
92
  }
358
  }
359
 
360
  .general-settings .ecwid-account-buttons .pure-button {
361
+ margin: 5px 17px 5px 0px;
362
+ }
363
+
364
+ .general-settings .ecwid-account-buttons {
365
+ padding: 20px 0px;
366
+ margin-bottom: -5px;
367
  }
368
 
369
  .general-settings p.note {
443
  color: #A0A0A0;
444
  margin-top:10px;
445
  margin-bottom: 10px;
446
+ }
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: 2.2
9
  Author URI: http://www.ecwid.com?source=wporg
10
  */
11
 
@@ -35,6 +35,7 @@ if ( is_admin() ){
35
  add_filter('plugins_loaded', 'ecwid_load_textdomain');
36
  add_filter('plugin_action_links_ecwid-shopping-cart/ecwid-shopping-cart.php', 'ecwid_plugin_actions');
37
  add_action('admin_head', 'ecwid_ie8_fonts_inclusion');
 
38
  } else {
39
  add_shortcode('ecwid_script', 'ecwid_script_shortcode');
40
  add_shortcode('ecwid_minicart', 'ecwid_minicart_shortcode');
@@ -44,6 +45,7 @@ if ( is_admin() ){
44
  add_action('init', 'ecwid_backward_compatibility');
45
  add_action('send_headers', 'ecwid_503_on_store_closed');
46
  add_action('template_redirect', 'ecwid_404_on_broken_escaped_fragment');
 
47
  add_action('wp_title', 'ecwid_seo_compatibility_init', 0);
48
  add_filter('wp_title', 'ecwid_seo_title', 20);
49
  add_action('plugins_loaded', 'ecwid_minifier_compatibility', 0);
@@ -52,10 +54,13 @@ if ( is_admin() ){
52
  add_action('wp_head', 'ecwid_meta');
53
  add_action('wp_head', 'ecwid_seo_compatibility_restore', 1000);
54
  add_filter( 'widget_meta_poweredby', 'ecwid_add_credits');
 
55
  $ecwid_seo_title = '';
56
  }
57
  add_action('admin_bar_menu', 'add_ecwid_admin_bar_node', 1000);
58
 
 
 
59
  $version = get_bloginfo('version');
60
 
61
  if (version_compare($version, '3.6') < 0) {
@@ -88,6 +93,7 @@ if (version_compare($version, '3.6') < 0) {
88
  }
89
  }
90
  }
 
91
  $theme_name = '';
92
  if (version_compare($version, '3.4') < 0) {
93
  $theme_name = get_current_theme();
@@ -202,6 +208,33 @@ function ecwid_backward_compatibility() {
202
  }
203
  }
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  function ecwid_minifier_compatibility()
206
  {
207
  if ( !function_exists( 'get_plugins' ) ) { require_once ( ABSPATH . 'wp-admin/includes/plugin.php' ); }
@@ -232,6 +265,19 @@ function ecwid_override_option($name, $new_value = null)
232
  }
233
  }
234
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  function ecwid_seo_compatibility_init($title)
236
  {
237
  if (!array_key_exists('_escaped_fragment_', $_GET) || !ecwid_page_has_productbrowser()) {
@@ -262,9 +308,9 @@ function ecwid_seo_compatibility_init($title)
262
  // Canonical
263
  $aioseop_options['aiosp_can'] = false;
264
  // Title
265
- add_filter('aioseop_title', __return_null);
266
  // Description
267
- add_filter('aioseop_description', __return_null);
268
 
269
 
270
  return $title;
@@ -414,8 +460,14 @@ function ecwid_get_product_and_category($category_id, $product_id) {
414
  $api = ecwid_new_product_api();
415
  $batch_result = $api->get_batch_request($params);
416
 
417
- $category = $batch_result["c"];
418
- $product = $batch_result["p"];
 
 
 
 
 
 
419
  $return = "";
420
 
421
  if (is_array($product)) {
@@ -487,25 +539,36 @@ function ecwid_add_credits($powered_by)
487
  return $powered_by;
488
  }
489
 
 
 
 
 
 
 
 
 
 
490
  function ecwid_wrap_shortcode_content($content)
491
  {
492
- return "<!-- Ecwid shopping cart plugin v 2.2 -->"
493
  . ecwid_get_scriptjs_code()
494
  . "<div>$content</div>"
495
- . "<!-- END Ecwid Shopping Cart v 2.2 -->";
496
  }
497
 
498
  function ecwid_get_scriptjs_code($force_lang = null) {
499
- if (!defined('ECWID_SCRIPTJS')) {
500
- $store_id = get_ecwid_store_id();
501
- $force_lang_str = !is_null($force_lang) ? "&lang=$force_lang" : '';
502
- $s = '<script type="text/javascript" data-cfasync="false" src="//' . APP_ECWID_COM . '/script.js?' . $store_id . $force_lang_str . '"></script>';
503
-
504
- define('ECWID_SCRIPTJS','Yep');
505
- $s = $s . ecwid_sso();
506
- return $s;
 
 
507
  } else {
508
- return '';
509
  }
510
  }
511
 
@@ -719,7 +782,7 @@ EOT;
719
  }
720
 
721
  function ecwid_show_admin_messages() {
722
- if (get_ecwid_store_id() == ECWID_DEMO_STORE_ID && $_GET['page'] != 'ecwid') {
723
 
724
  $ecwid_page_id = get_option("ecwid_store_page_id");
725
  $page_url = get_page_link($ecwid_page_id);
@@ -814,26 +877,24 @@ function ecwid_options_add_page() {
814
  }
815
 
816
  function ecwid_register_admin_styles() {
817
- global $version;
818
 
819
  wp_register_style('ecwid-admin-css', plugins_url('ecwid-shopping-cart/css/admin.css'), array(), '', 'all');
820
  wp_enqueue_style('ecwid-admin-css');
821
 
822
- if (version_compare($version, '3.8-beta') > 0) {
823
  wp_register_style('ecwid-admin38-css', plugins_url('ecwid-shopping-cart/css/admin.3.8.css'), array('ecwid-admin-css'), '', 'all');
824
  wp_enqueue_style('ecwid-admin38-css');
825
  }
826
  }
827
 
828
  function ecwid_register_settings_styles() {
829
- global $version;
830
 
831
  wp_register_style('ecwid-settings-pure-css', plugins_url('ecwid-shopping-cart/css/pure-min.css'), array(), '', 'all');
832
  wp_enqueue_style('ecwid-settings-pure-css');
833
  wp_register_style('ecwid-settings-css', plugins_url('ecwid-shopping-cart/css/settings.css'), array(), '', 'all');
834
  wp_enqueue_style('ecwid-settings-css');
835
 
836
- if (version_compare($version, '3.8-beta') > 0) {
837
  wp_register_style('ecwid-settings38-css', plugins_url('ecwid-shopping-cart/css/settings.3.8.css'), array('ecwid-settings-css'), '', 'all');
838
  wp_enqueue_style('ecwid-settings38-css');
839
  }}
@@ -979,6 +1040,138 @@ function ecwid_add_dashboard_widgets() {
979
  }
980
 
981
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
982
  class EcwidMinicartWidget extends WP_Widget {
983
 
984
  function EcwidMinicartWidget() {
@@ -1182,6 +1375,7 @@ function ecwid_sidebar_widgets_init() {
1182
  register_widget('EcwidSearchWidget');
1183
  register_widget('EcwidVCategoriesWidget');
1184
  register_widget('EcwidMinicartMiniViewWidget');
 
1185
  }
1186
 
1187
  add_action('widgets_init', 'ecwid_sidebar_widgets_init');
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: 2.3
9
  Author URI: http://www.ecwid.com?source=wporg
10
  */
11
 
35
  add_filter('plugins_loaded', 'ecwid_load_textdomain');
36
  add_filter('plugin_action_links_ecwid-shopping-cart/ecwid-shopping-cart.php', 'ecwid_plugin_actions');
37
  add_action('admin_head', 'ecwid_ie8_fonts_inclusion');
38
+ add_action('sm_buildmap', 'ecwid_build_sitemap_pages');
39
  } else {
40
  add_shortcode('ecwid_script', 'ecwid_script_shortcode');
41
  add_shortcode('ecwid_minicart', 'ecwid_minicart_shortcode');
45
  add_action('init', 'ecwid_backward_compatibility');
46
  add_action('send_headers', 'ecwid_503_on_store_closed');
47
  add_action('template_redirect', 'ecwid_404_on_broken_escaped_fragment');
48
+ add_action('wp_loaded', 'ecwid_seo_ultimate_compatibility', 0);
49
  add_action('wp_title', 'ecwid_seo_compatibility_init', 0);
50
  add_filter('wp_title', 'ecwid_seo_title', 20);
51
  add_action('plugins_loaded', 'ecwid_minifier_compatibility', 0);
54
  add_action('wp_head', 'ecwid_meta');
55
  add_action('wp_head', 'ecwid_seo_compatibility_restore', 1000);
56
  add_filter( 'widget_meta_poweredby', 'ecwid_add_credits');
57
+ add_filter('the_content', 'ecwid_content_started', 0);
58
  $ecwid_seo_title = '';
59
  }
60
  add_action('admin_bar_menu', 'add_ecwid_admin_bar_node', 1000);
61
 
62
+ $ecwid_script_rendered = false; // controls single script.js on page
63
+
64
  $version = get_bloginfo('version');
65
 
66
  if (version_compare($version, '3.6') < 0) {
93
  }
94
  }
95
  }
96
+
97
  $theme_name = '';
98
  if (version_compare($version, '3.4') < 0) {
99
  $theme_name = get_current_theme();
208
  }
209
  }
210
 
211
+
212
+ function ecwid_build_sitemap_pages()
213
+ {
214
+ $page_url = get_page_link(get_option("ecwid_store_page_id"));
215
+
216
+ include ECWID_PLUGIN_DIR . '/lib/EcwidSitemapBuilder.php';
217
+
218
+ $sitemap = new EcwidSitemapBuilder($page_url, 'build_sitemap_callback', ecwid_new_product_api());
219
+
220
+ $sitemap->generate();
221
+ }
222
+
223
+ function build_sitemap_callback($url, $priority, $frequency)
224
+ {
225
+ echo $url . '<br />';
226
+
227
+ static $generatorObject = null;
228
+ if (is_null($generatorObject)) {
229
+ $generatorObject = &GoogleSitemapGenerator::GetInstance(); //Please note the "&" sign!
230
+ }
231
+
232
+ if($generatorObject != null) {
233
+ $page = new GoogleSitemapGeneratorPage($url, $priority, $frequency);
234
+ $generatorObject->AddElement($page);
235
+ }
236
+ }
237
+
238
  function ecwid_minifier_compatibility()
239
  {
240
  if ( !function_exists( 'get_plugins' ) ) { require_once ( ABSPATH . 'wp-admin/includes/plugin.php' ); }
265
  }
266
  }
267
 
268
+ function ecwid_seo_ultimate_compatibility()
269
+ {
270
+ global $seo_ultimate;
271
+
272
+ if ($seo_ultimate) {
273
+ remove_action('template_redirect', array($seo_ultimate->modules['titles'], 'before_header'), 0);
274
+ remove_action('wp_head', array($seo_ultimate->modules['titles'], 'after_header'), 1000);
275
+ remove_action('su_head', array($seo_ultimate->modules['meta-descriptions'], 'head_tag_output'));
276
+ remove_action('su_head', array($seo_ultimate->modules['canonical'], 'link_rel_canonical_tag'));
277
+ remove_action('su_head', array($seo_ultimate->modules['canonical'], 'http_link_rel_canonical'));
278
+ }
279
+ }
280
+
281
  function ecwid_seo_compatibility_init($title)
282
  {
283
  if (!array_key_exists('_escaped_fragment_', $_GET) || !ecwid_page_has_productbrowser()) {
308
  // Canonical
309
  $aioseop_options['aiosp_can'] = false;
310
  // Title
311
+ add_filter('aioseop_title', '__return_null');
312
  // Description
313
+ add_filter('aioseop_description', '__return_null');
314
 
315
 
316
  return $title;
460
  $api = ecwid_new_product_api();
461
  $batch_result = $api->get_batch_request($params);
462
 
463
+ if (false == $batch_result) {
464
+ $product = $api->get_product($product_id);
465
+ $category = false;
466
+ } else {
467
+ $category = $batch_result["c"];
468
+ $product = $batch_result["p"];
469
+ }
470
+
471
  $return = "";
472
 
473
  if (is_array($product)) {
539
  return $powered_by;
540
  }
541
 
542
+ function ecwid_content_started($content)
543
+ {
544
+ global $ecwid_script_rendered;
545
+
546
+ $ecwid_script_rendered = false;
547
+
548
+ return $content;
549
+ }
550
+
551
  function ecwid_wrap_shortcode_content($content)
552
  {
553
+ return "<!-- Ecwid shopping cart plugin v 2.3 -->"
554
  . ecwid_get_scriptjs_code()
555
  . "<div>$content</div>"
556
+ . "<!-- END Ecwid Shopping Cart v 2.3 -->";
557
  }
558
 
559
  function ecwid_get_scriptjs_code($force_lang = null) {
560
+ global $ecwid_script_rendered;
561
+
562
+ if (!$ecwid_script_rendered) {
563
+ $store_id = get_ecwid_store_id();
564
+ $force_lang_str = !is_null($force_lang) ? "&lang=$force_lang" : '';
565
+ $s = '<script type="text/javascript" data-cfasync="false" src="//' . APP_ECWID_COM . '/script.js?' . $store_id . $force_lang_str . '"></script>';
566
+ $s = $s . ecwid_sso();
567
+ $ecwid_script_rendered = true;
568
+
569
+ return $s;
570
  } else {
571
+ return '';
572
  }
573
  }
574
 
782
  }
783
 
784
  function ecwid_show_admin_messages() {
785
+ if (get_ecwid_store_id() == ECWID_DEMO_STORE_ID && isset($_GET['page']) && $_GET['page'] != 'ecwid') {
786
 
787
  $ecwid_page_id = get_option("ecwid_store_page_id");
788
  $page_url = get_page_link($ecwid_page_id);
877
  }
878
 
879
  function ecwid_register_admin_styles() {
 
880
 
881
  wp_register_style('ecwid-admin-css', plugins_url('ecwid-shopping-cart/css/admin.css'), array(), '', 'all');
882
  wp_enqueue_style('ecwid-admin-css');
883
 
884
+ if (version_compare(get_bloginfo('version'), '3.8-beta') > 0) {
885
  wp_register_style('ecwid-admin38-css', plugins_url('ecwid-shopping-cart/css/admin.3.8.css'), array('ecwid-admin-css'), '', 'all');
886
  wp_enqueue_style('ecwid-admin38-css');
887
  }
888
  }
889
 
890
  function ecwid_register_settings_styles() {
 
891
 
892
  wp_register_style('ecwid-settings-pure-css', plugins_url('ecwid-shopping-cart/css/pure-min.css'), array(), '', 'all');
893
  wp_enqueue_style('ecwid-settings-pure-css');
894
  wp_register_style('ecwid-settings-css', plugins_url('ecwid-shopping-cart/css/settings.css'), array(), '', 'all');
895
  wp_enqueue_style('ecwid-settings-css');
896
 
897
+ if (version_compare(get_bloginfo('version'), '3.8-beta') > 0) {
898
  wp_register_style('ecwid-settings38-css', plugins_url('ecwid-shopping-cart/css/settings.3.8.css'), array('ecwid-settings-css'), '', 'all');
899
  wp_enqueue_style('ecwid-settings38-css');
900
  }}
1040
  }
1041
 
1042
 
1043
+ class EcwidBadgeWidget extends WP_Widget {
1044
+
1045
+ var $url_template = "http://static.ecwid.com/badges/%s.png";
1046
+ var $available_badges;
1047
+
1048
+ function EcwidBadgeWidget() {
1049
+ $widget_ops = array('classname' => 'widget_ecwid_badge', 'description' => __("If you like Ecwid and want to help it grow and become the most popular e-commerce solution, you can now add a fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid.", 'ecwid-shopping-cart') );
1050
+ $this->WP_Widget('ecwidbadge', __('Ecwid Badge', 'ecwid-shopping-cart'), $widget_ops);
1051
+
1052
+ $this->available_badges = array(
1053
+ 'ecwid-shopping-cart-widget-5' => array (
1054
+ 'name' => 'ecwid-shopping-cart-widget-5',
1055
+ 'width' => '73',
1056
+ 'height' => '20',
1057
+ 'alt' => __('Ecwid shopping cart widget', 'ecwid-shopping-cart')
1058
+ ),
1059
+ 'ecwid-shopping-cart-widget-6' => array (
1060
+ 'name' => 'ecwid-shopping-cart-widget-6',
1061
+ 'width' => '73',
1062
+ 'height' => '20',
1063
+ 'alt' => __('Ecwid shopping cart widget', 'ecwid-shopping-cart')
1064
+ ),
1065
+ 'ecwid-shopping-cart-2' => array (
1066
+ 'name' => 'ecwid-shopping-cart-3',
1067
+ 'width' => '165',
1068
+ 'height' => '56',
1069
+ 'alt' => __('Ecwid shopping cart', 'ecwid-shopping-cart')
1070
+ ),
1071
+ 'ecwid-ecommerce-widgets-2' => array (
1072
+ 'name' => 'ecwid-ecommerce-widgets-3',
1073
+ 'width' => '165',
1074
+ 'height' => '58',
1075
+ 'alt' => __('Ecwid e-commerce widgets', 'ecwid-shopping-cart')
1076
+ ),
1077
+ 'ecwid-ecommerce-solution-2' => array (
1078
+ 'name' => 'ecwid-ecommerce-solution-2',
1079
+ 'width' => '165',
1080
+ 'height' => '58',
1081
+ 'alt' => __('Ecwid ecommerce solution', 'ecwid-shopping-cart')
1082
+ ),
1083
+ 'ecwid-free-shopping-cart-2' => array (
1084
+ 'name' => 'ecwid-free-shopping-cart-2',
1085
+ 'width' => '175',
1086
+ 'height' => '58',
1087
+ 'alt' => __('Ecwid free shopping cart', 'ecwid-shopping-cart')
1088
+ ),
1089
+ 'ecwid-shopping-cart-3' => array (
1090
+ 'name' => 'ecwid-shopping-cart-3',
1091
+ 'width' => '165',
1092
+ 'height' => '56',
1093
+ 'alt' => __('Ecwid shopping cart', 'ecwid-shopping-cart')
1094
+ ),
1095
+ 'ecwid-ecommerce-widgets-3' => array (
1096
+ 'name' => 'ecwid-ecommerce-widgets-3',
1097
+ 'width' => '165',
1098
+ 'height' => '58',
1099
+ 'alt' => __('Ecwid e-commerce widgets', 'ecwid-shopping-cart')
1100
+ ),
1101
+ 'ecwid-ecommerce-solution-3' => array (
1102
+ 'name' => 'ecwid-ecommerce-solution-3',
1103
+ 'width' => '165',
1104
+ 'height' => '58',
1105
+ 'alt' => __('Ecwid ecommerce solution', 'ecwid-shopping-cart')
1106
+ ),
1107
+ 'ecwid-free-shopping-cart-3' => array (
1108
+ 'name' => 'ecwid-free-shopping-cart-3',
1109
+ 'width' => '175',
1110
+ 'height' => '58',
1111
+ 'alt' => __('Ecwid free shopping cart', 'ecwid-shopping-cart')
1112
+ )
1113
+ );
1114
+ }
1115
+
1116
+ function widget($args, $instance)
1117
+ {
1118
+ extract($args);
1119
+
1120
+ if (!isset($instance['badge_id']) || !array_key_exists($instance['badge_id'], $this->available_badges)) {
1121
+ return;
1122
+ }
1123
+ $badge = $this->available_badges[$instance['badge_id']];
1124
+ $url = sprintf($this->url_template, $badge['name']);
1125
+
1126
+ echo $before_widget;
1127
+
1128
+ echo <<<HTML
1129
+ <div>
1130
+ <a target="_blank" rel="nofollow" href="http://www.ecwid.com?source=wporg-badge">
1131
+ <img src="$url" width="$badge[width]" height="$badge[height]" alt="$badge[alt]" />
1132
+ </a>
1133
+ </div>
1134
+ HTML;
1135
+
1136
+ echo $after_widget;
1137
+ }
1138
+
1139
+ function update($new_instance, $old_instance){
1140
+ $instance = $old_instance;
1141
+ $instance['badge_id'] =
1142
+ array_key_exists($new_instance['badge_id'], $this->available_badges)
1143
+ ? $new_instance['badge_id']
1144
+ : '';
1145
+
1146
+ return $instance;
1147
+ }
1148
+
1149
+ function form($instance) {
1150
+ $instance = wp_parse_args( (array) $instance, array('badge_id' => 'ecwid-shopping-cart-widget-5') );
1151
+
1152
+ foreach ($this->available_badges as $id => $widget) {
1153
+ $element_id = "badge-$id";
1154
+ $name = $this->get_field_name('badge_id');
1155
+ $checked = '';
1156
+ if (isset($instance['badge_id']) && $instance['badge_id'] == $id) {
1157
+ $checked = 'checked="checked"';
1158
+ }
1159
+ $url = sprintf($this->url_template, $id);
1160
+ $content = <<<HTML
1161
+ <label class="ecwid-badge">
1162
+ <div class="checkbox">
1163
+ <input name="$name" type="radio" value="$widget[name]"$checked/>
1164
+ </div>
1165
+ <div class="image">
1166
+ <img src="$url" width="$widget[width]" height="$widget[height]" alt="$widget[alt]" />
1167
+ </div>
1168
+ </label>
1169
+ HTML;
1170
+ echo $content;
1171
+ }
1172
+ }
1173
+ }
1174
+
1175
  class EcwidMinicartWidget extends WP_Widget {
1176
 
1177
  function EcwidMinicartWidget() {
1375
  register_widget('EcwidSearchWidget');
1376
  register_widget('EcwidVCategoriesWidget');
1377
  register_widget('EcwidMinicartMiniViewWidget');
1378
+ register_widget('EcwidBadgeWidget');
1379
  }
1380
 
1381
  add_action('widgets_init', 'ecwid_sidebar_widgets_init');
languages/ecwid-shopping-cart-ru_RU.mo CHANGED
Binary file
languages/ecwid-shopping-cart-ru_RU.po CHANGED
@@ -3,27 +3,18 @@
3
  # Your Email: test@example.com
4
  # Your Website: wordpress36
5
  # Your URL: http://localhost/wordpress36
6
- # Your Locale: ru_RU (MO: /languages/ecwid-shopping-cart-ru_RU.mo)
7
- # Your Language: ru-RU
8
  #, fuzzy
9
  msgid ""
10
  msgstr ""
11
  "Project-Id-Version: Ecwid Shopping Cart\n"
12
- "PO-Revision-Date: 2013-11-25 17:38:21\n"
13
  "Last-Translator: <test@example.com>\n"
14
  "MIME-Version: 1.0\n"
15
  "Content-Type: text/plain; charset=UTF-8\n"
16
  "Content-Transfer-Encoding: 8bit\n"
17
 
18
- msgid "Ecwid Shopping Cart"
19
- msgstr "Интернет-магазин Ecwid"
20
-
21
- msgid "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."
22
- msgstr "Ecwid - это бесплатный полнофункциональный интернет магазин. Его можно добавить к любому сайту, построенному на WordPress, и он требует не более 5 минут на настройку."
23
-
24
- msgid "Ecwid Team"
25
- msgstr "Команда Ecwid"
26
-
27
  msgid "Get help"
28
  msgstr "Получить помощь"
29
 
@@ -42,8 +33,8 @@ msgstr "Изменить настройки плагина"
42
  msgid "→ Sell on Facebook"
43
  msgstr "→ Начать продавать на Facebook"
44
 
45
- msgid "Online store powered by <a %s>Ecwid</a>"
46
- msgstr "Интернет магазин построен на <a %s>Ecwid</a>"
47
 
48
  msgid "Store"
49
  msgstr "Магазин"
@@ -102,6 +93,27 @@ msgstr "Вертикальное меню категорий"
102
  msgid "Ecwid Vertical Categories"
103
  msgstr "Вертикальное меню категорий Ecwid"
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  msgid "Price"
106
  msgstr "Цена"
107
 
@@ -189,9 +201,6 @@ msgstr "Таблица"
189
  msgid "Default view mode on search results"
190
  msgstr "Вид страницы результатов поиска по умолчанию"
191
 
192
- msgid "Store powered by Ecwid"
193
- msgstr "Интернет-магазин построен на Ecwid"
194
-
195
  msgid "Ecwid Shopping Cart - General settings"
196
  msgstr "Магазин Ecwid - Основные настройки"
197
 
@@ -275,3 +284,4 @@ msgstr "Апгрейд"
275
 
276
  msgid "If you want to connect another Ecwid store, you can <a %s>disconnect the current one and change Store ID</a>."
277
  msgstr "Если вы хотите подключить другой магазин Ecwid, вы можете <a %s>отключить этот и ввести другой ID Магазина</a>."
 
3
  # Your Email: test@example.com
4
  # Your Website: wordpress36
5
  # Your URL: http://localhost/wordpress36
6
+ # Your Locale: en_US (MO: /languages/ecwid-shopping-cart-ru_RU.mo)
7
+ # Your Language: en-US
8
  #, fuzzy
9
  msgid ""
10
  msgstr ""
11
  "Project-Id-Version: Ecwid Shopping Cart\n"
12
+ "PO-Revision-Date: 2014-01-20 15:46:29\n"
13
  "Last-Translator: <test@example.com>\n"
14
  "MIME-Version: 1.0\n"
15
  "Content-Type: text/plain; charset=UTF-8\n"
16
  "Content-Transfer-Encoding: 8bit\n"
17
 
 
 
 
 
 
 
 
 
 
18
  msgid "Get help"
19
  msgstr "Получить помощь"
20
 
33
  msgid "→ Sell on Facebook"
34
  msgstr "→ Начать продавать на Facebook"
35
 
36
+ msgid "<a %s>Online store powered by Ecwid</a>"
37
+ msgstr "<a %s>Интернет магазин построен на Ecwid</a>"
38
 
39
  msgid "Store"
40
  msgstr "Магазин"
93
  msgid "Ecwid Vertical Categories"
94
  msgstr "Вертикальное меню категорий Ecwid"
95
 
96
+ msgid "If you like Ecwid and want to help it grow and become the most popular e-commerce solution, you can now add a fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid."
97
+ msgstr "Если вам нравится Ecwid и вы хотите помочь ему расти и стать самым популярным конструктором интернет-магазинов, вы можете добавить значок Ecwid на ваш сайт, чтобы показать посетителям, что вы пользуетесь Ecwid."
98
+
99
+ msgid "Ecwid Badge"
100
+ msgstr "Значок Ecwid"
101
+
102
+ msgid "Ecwid shopping cart widget"
103
+ msgstr "Виджет интернет-магазина Ecwid"
104
+
105
+ msgid "Ecwid shopping cart"
106
+ msgstr "Интернет-магазин Ecwid"
107
+
108
+ msgid "Ecwid e-commerce widgets"
109
+ msgstr "Виджеты для электронной коммерции Ecwid"
110
+
111
+ msgid "Ecwid ecommerce solution"
112
+ msgstr "Решение для электронной коммерции Ecwid"
113
+
114
+ msgid "Ecwid free shopping cart"
115
+ msgstr "Беспланный конструктов интернет-магазинов Ecwid"
116
+
117
  msgid "Price"
118
  msgstr "Цена"
119
 
201
  msgid "Default view mode on search results"
202
  msgstr "Вид страницы результатов поиска по умолчанию"
203
 
 
 
 
204
  msgid "Ecwid Shopping Cart - General settings"
205
  msgstr "Магазин Ecwid - Основные настройки"
206
 
284
 
285
  msgid "If you want to connect another Ecwid store, you can <a %s>disconnect the current one and change Store ID</a>."
286
  msgstr "Если вы хотите подключить другой магазин Ecwid, вы можете <a %s>отключить этот и ввести другой ID Магазина</a>."
287
+
languages/ecwid-shopping-cart.pot CHANGED
@@ -1,12 +1,3 @@
1
- msgid "Ecwid Shopping Cart"
2
- msgstr ""
3
-
4
- msgid "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."
5
- msgstr ""
6
-
7
- msgid "Ecwid Team"
8
- msgstr ""
9
-
10
  msgid "Get help"
11
  msgstr ""
12
 
@@ -25,7 +16,7 @@ msgstr ""
25
  msgid "→ Sell on Facebook"
26
  msgstr ""
27
 
28
- msgid "Online store powered by <a %s>Ecwid</a>"
29
  msgstr ""
30
 
31
  msgid "Store"
@@ -85,6 +76,27 @@ msgstr ""
85
  msgid "Ecwid Vertical Categories"
86
  msgstr ""
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  msgid "Price"
89
  msgstr ""
90
 
@@ -172,9 +184,6 @@ msgstr ""
172
  msgid "Default view mode on search results"
173
  msgstr ""
174
 
175
- msgid "Store powered by Ecwid"
176
- msgstr ""
177
-
178
  msgid "Ecwid Shopping Cart - General settings"
179
  msgstr ""
180
 
@@ -258,3 +267,4 @@ msgstr ""
258
 
259
  msgid "If you want to connect another Ecwid store, you can <a %s>disconnect the current one and change Store ID</a>."
260
  msgstr ""
 
 
 
 
 
 
 
 
 
 
1
  msgid "Get help"
2
  msgstr ""
3
 
16
  msgid "→ Sell on Facebook"
17
  msgstr ""
18
 
19
+ msgid "<a %s>Online store powered by Ecwid</a>"
20
  msgstr ""
21
 
22
  msgid "Store"
76
  msgid "Ecwid Vertical Categories"
77
  msgstr ""
78
 
79
+ msgid "If you like Ecwid and want to help it grow and become the most popular e-commerce solution, you can now add a fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid."
80
+ msgstr ""
81
+
82
+ msgid "Ecwid Badge"
83
+ msgstr ""
84
+
85
+ msgid "Ecwid shopping cart widget"
86
+ msgstr ""
87
+
88
+ msgid "Ecwid shopping cart"
89
+ msgstr ""
90
+
91
+ msgid "Ecwid e-commerce widgets"
92
+ msgstr ""
93
+
94
+ msgid "Ecwid ecommerce solution"
95
+ msgstr ""
96
+
97
+ msgid "Ecwid free shopping cart"
98
+ msgstr ""
99
+
100
  msgid "Price"
101
  msgstr ""
102
 
184
  msgid "Default view mode on search results"
185
  msgstr ""
186
 
 
 
 
187
  msgid "Ecwid Shopping Cart - General settings"
188
  msgstr ""
189
 
267
 
268
  msgid "If you want to connect another Ecwid store, you can <a %s>disconnect the current one and change Store ID</a>."
269
  msgstr ""
270
+
lib/EcwidSitemapBuilder.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once dirname(__FILE__) . '/JSONStreamingParser/Listener.php';
4
+ require_once dirname(__FILE__) . '/JSONStreamingParser/Parser.php';
5
+
6
+
7
+ class EcwidSitemapBuilder implements JsonStreamingParser_Listener {
8
+ var $_stack;
9
+ var $_key;
10
+ var $callback;
11
+ var $base_url;
12
+ var $api;
13
+ var $type;
14
+
15
+ public function __construct($base_url, $callback, $api) {
16
+ $this->callback = $callback;
17
+ $this->base_url = $base_url;
18
+ $this->api = $api;
19
+ }
20
+
21
+ public function generate() {
22
+
23
+ foreach (array('products', 'categories') as $type) {
24
+ $this->type = $type;
25
+ $stream = $this->api->get_method_response_stream($type);
26
+ if (!is_null($stream)) {
27
+ try {
28
+ $parser = new JsonStreamingParser_Parser($stream, $this);
29
+ $parser->parse();
30
+ } catch (Exception $e) {
31
+ fclose($stream);
32
+ throw $e;
33
+ }
34
+ }
35
+ }
36
+
37
+ return true;
38
+ }
39
+
40
+ public function file_position($line, $char) {
41
+
42
+ }
43
+
44
+ public function start_document() {
45
+ $this->_stack = array();
46
+
47
+ $this->_key = null;
48
+ }
49
+
50
+ public function end_document() {
51
+ }
52
+
53
+ public function start_object() {
54
+ array_push($this->_stack, array());
55
+ }
56
+
57
+ public function end_object() {
58
+ $obj = array_pop($this->_stack);
59
+ if (is_array($obj) && array_key_exists('id', $obj)) {
60
+ $callback = $this->callback;
61
+ $callback(
62
+ $this->base_url . '#!/~/' . ($this->type == 'products' ? 'product' : 'category') . '/id=' . $obj['id'],
63
+ $this->type == 'products' ? 0.6 : 0.5,
64
+ 'weekly'
65
+ );
66
+ }
67
+ }
68
+
69
+ public function start_array() {
70
+ }
71
+
72
+ public function end_array() {
73
+ }
74
+
75
+ public function key($key) {
76
+ $this->_key = $key;
77
+ }
78
+
79
+ public function value($value) {
80
+ if ($this->_key == 'id') {
81
+ array_push($this->_stack, array('id' => $value));
82
+ }
83
+ }
84
+ }
lib/JSONStreamingParser/LICENSE.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+ Copyright © 2013 <copyright holders>
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
5
+
6
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
7
+
8
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
lib/JSONStreamingParser/Listener.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ interface JsonStreamingParser_Listener {
3
+
4
+ public function file_position($line, $char);
5
+
6
+ public function start_document();
7
+ public function end_document();
8
+
9
+ public function start_object();
10
+ public function end_object();
11
+
12
+ public function start_array();
13
+ public function end_array();
14
+
15
+ // Key will always be a string
16
+ public function key($key);
17
+
18
+ // Note that value may be a string, integer, boolean, array, etc.
19
+ public function value($value);
20
+ }
lib/JSONStreamingParser/Listener/SubsetConsumer.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace JsonStreamingParser\Listener;
4
+
5
+ abstract class SubsetConsumer implements \JsonStreamingParser_Listener
6
+ {
7
+ private $keyValueStack;
8
+ private $key;
9
+
10
+ /**
11
+ * @param mixed $data
12
+ * @return boolean if data was consumed and can be discarded
13
+ */
14
+ abstract protected function consume($data);
15
+
16
+ public function file_position($line, $char) {
17
+
18
+ }
19
+
20
+ public function start_document()
21
+ {
22
+ $this->keyValueStack = array();
23
+ }
24
+
25
+ public function end_document()
26
+ {
27
+ }
28
+
29
+ public function start_object()
30
+ {
31
+ array_push($this->keyValueStack, is_null($this->key) ? array(array()) : array($this->key => array()));
32
+ $this->key = null;
33
+ }
34
+
35
+ public function end_object()
36
+ {
37
+ $keyValue = array_pop($this->keyValueStack);
38
+ $obj = reset($keyValue);
39
+ $this->key = key($keyValue);
40
+ $hasBeenConsumed = $this->consume($obj);
41
+
42
+ if (!empty($this->keyValueStack)) {
43
+ $this->value($hasBeenConsumed ? '*consumed*' : $obj);
44
+ }
45
+
46
+ }
47
+
48
+ public function start_array()
49
+ {
50
+ $this->start_object();
51
+ }
52
+
53
+ public function end_array()
54
+ {
55
+ $this->end_object();
56
+ }
57
+
58
+ public function key($key)
59
+ {
60
+ $this->key = $key;
61
+ }
62
+
63
+ public function value($value)
64
+ {
65
+ $keyValue = array_pop($this->keyValueStack);
66
+ $objKey = key($keyValue);
67
+
68
+ if ($this->key) {
69
+ $keyValue[$objKey][$this->key] = $value;
70
+ } else {
71
+ array_push($keyValue[$objKey], $value);
72
+ }
73
+ array_push($this->keyValueStack, $keyValue);
74
+ }
75
+ }
lib/JSONStreamingParser/Parser.php ADDED
@@ -0,0 +1,493 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once 'ParsingError.php';
3
+ require_once 'Listener.php';
4
+
5
+ class JsonStreamingParser_Parser {
6
+ private $_state;
7
+ const STATE_START_DOCUMENT = 0;
8
+ const STATE_DONE = -1;
9
+ const STATE_IN_ARRAY = 1;
10
+ const STATE_IN_OBJECT = 2;
11
+ const STATE_END_KEY = 3;
12
+ const STATE_AFTER_KEY = 4;
13
+ const STATE_IN_STRING = 5;
14
+ const STATE_START_ESCAPE = 6;
15
+ const STATE_UNICODE = 7;
16
+ const STATE_IN_NUMBER = 8;
17
+ const STATE_IN_TRUE = 9;
18
+ const STATE_IN_FALSE = 10;
19
+ const STATE_IN_NULL = 11;
20
+ const STATE_AFTER_VALUE = 12;
21
+
22
+ const STACK_OBJECT = 0;
23
+ const STACK_ARRAY = 1;
24
+ const STACK_KEY = 2;
25
+ const STACK_STRING = 3;
26
+ private $_stack;
27
+
28
+ private $_stream;
29
+
30
+ /**
31
+ * @var JsonStreamingParser_Listener
32
+ */
33
+ private $_listener;
34
+
35
+ private $_buffer;
36
+ private $_buffer_size;
37
+ private $_unicode_buffer;
38
+ private $_unicode_high_codepoint;
39
+ private $_line_ending;
40
+
41
+ private $_line_number;
42
+ private $_char_number;
43
+
44
+
45
+ public function __construct($stream, $listener, $line_ending = "\n") {
46
+ if (!is_resource($stream) || get_resource_type($stream) != 'stream') {
47
+ throw new InvalidArgumentException("Argument is not a stream");
48
+ }
49
+ if (!in_array("JsonStreamingParser_Listener", class_implements(get_class($listener)))) {
50
+ throw new InvalidArgumentException("Listener must implement JsonStreamingParser_Listener");
51
+ }
52
+
53
+ $this->_stream = $stream;
54
+ $this->_listener = $listener;
55
+
56
+ $this->_state = self::STATE_START_DOCUMENT;
57
+ $this->_stack = array();
58
+
59
+ $this->_buffer = '';
60
+ $this->_buffer_size = 8192;
61
+ $this->_unicode_buffer = array();
62
+ $this->_unicode_high_codepoint = -1;
63
+ $this->_line_ending = $line_ending;
64
+ }
65
+
66
+
67
+ public function parse() {
68
+ $this->_line_number = 1;
69
+ $this->_char_number = 1;
70
+
71
+ while (!feof($this->_stream)) {
72
+ $pos = ftell($this->_stream);
73
+ $line = stream_get_line($this->_stream, $this->_buffer_size, $this->_line_ending);
74
+ $ended = (bool)(ftell($this->_stream) - strlen($line) - $pos);
75
+
76
+ $byteLen = strlen($line);
77
+ for ($i = 0; $i < $byteLen; $i++) {
78
+ $this->_listener->file_position($this->_line_number, $this->_char_number);
79
+ $this->_consume_char($line[$i]);
80
+ $this->_char_number++;
81
+ }
82
+
83
+ if ($ended) {
84
+ $this->_line_number++;
85
+ $this->_char_number = 1;
86
+ }
87
+
88
+ }
89
+ }
90
+
91
+ private function _consume_char($c) {
92
+ // valid whitespace characters in JSON (from RFC4627 for JSON) include:
93
+ // space, horizontal tab, line feed or new line, and carriage return.
94
+ // thanks: http://stackoverflow.com/questions/16042274/definition-of-whitespace-in-json
95
+ if (($c === " " || $c === "\t" || $c === "\n" || $c === "\r") &&
96
+ !($this->_state === self::STATE_IN_STRING ||
97
+ $this->_state === self::STATE_UNICODE ||
98
+ $this->_state === self::STATE_START_ESCAPE ||
99
+ $this->_state === self::STATE_IN_NUMBER ||
100
+ $this->_state === self::STATE_START_DOCUMENT)) {
101
+ return;
102
+ }
103
+
104
+ switch ($this->_state) {
105
+
106
+ case self::STATE_START_DOCUMENT:
107
+ $this->_listener->start_document();
108
+ if ($c === '[') {
109
+ $this->_start_array();
110
+ } elseif ($c === '{') {
111
+ $this->_start_object();
112
+ } else {
113
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
114
+ "Document must start with object or array.");
115
+ }
116
+ break;
117
+
118
+ case self::STATE_IN_ARRAY:
119
+ if ($c === ']') {
120
+ $this->_end_array();
121
+ } else {
122
+ $this->_start_value($c);
123
+ }
124
+ break;
125
+
126
+ case self::STATE_IN_OBJECT:
127
+ if ($c === '}') {
128
+ $this->_end_object();
129
+ } elseif ($c === '"') {
130
+ $this->_start_key();
131
+ } else {
132
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
133
+ "Start of string expected for object key. Instead got: ".$c);
134
+ }
135
+ break;
136
+
137
+ case self::STATE_END_KEY:
138
+ if ($c !== ':') {
139
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
140
+ "Expected ':' after key.");
141
+ }
142
+ $this->_state = self::STATE_AFTER_KEY;
143
+ break;
144
+
145
+ case self::STATE_AFTER_KEY:
146
+ $this->_start_value($c);
147
+ break;
148
+
149
+ case self::STATE_IN_STRING:
150
+ if ($c === '"') {
151
+ $this->_end_string();
152
+ } elseif ($c === '\\') {
153
+ $this->_state = self::STATE_START_ESCAPE;
154
+ } elseif (($c < "\x1f") || ($c === "\x7f")) {
155
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
156
+ "Unescaped control character encountered: ".$c);
157
+ } else {
158
+ $this->_buffer .= $c;
159
+ }
160
+ break;
161
+
162
+ case self::STATE_START_ESCAPE:
163
+ $this->_process_escape_character($c);
164
+ break;
165
+
166
+ case self::STATE_UNICODE:
167
+ $this->_process_unicode_character($c);
168
+ break;
169
+
170
+ case self::STATE_AFTER_VALUE:
171
+ $within = end($this->_stack);
172
+ if ($within === self::STACK_OBJECT) {
173
+ if ($c === '}') {
174
+ $this->_end_object();
175
+ } elseif ($c === ',') {
176
+ $this->_state = self::STATE_IN_OBJECT;
177
+ } else {
178
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
179
+ "Expected ',' or '}' while parsing object. Got: ".$c);
180
+ }
181
+ } elseif ($within === self::STACK_ARRAY) {
182
+ if ($c === ']') {
183
+ $this->_end_array();
184
+ } elseif ($c === ',') {
185
+ $this->_state = self::STATE_IN_ARRAY;
186
+ } else {
187
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
188
+ "Expected ',' or ']' while parsing array. Got: ".$c);
189
+ }
190
+ } else {
191
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
192
+ "Finished a literal, but unclear what state to move to. Last state: ".$within);
193
+ }
194
+ break;
195
+
196
+ case self::STATE_IN_NUMBER:
197
+ if (preg_match('/\d/', $c)) {
198
+ $this->_buffer .= $c;
199
+ } elseif ($c === '.') {
200
+ if (strpos($this->_buffer, '.') !== false) {
201
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
202
+ "Cannot have multiple decimal points in a number.");
203
+ } elseif (stripos($this->_buffer, 'e') !== false) {
204
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
205
+ "Cannot have a decimal point in an exponent.");
206
+ }
207
+ $this->_buffer .= $c;
208
+ } elseif ($c === 'e' || $c === 'E') {
209
+ if (stripos($this->_buffer, 'e') !== false) {
210
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
211
+ "Cannot have multiple exponents in a number.");
212
+ }
213
+ $this->_buffer .= $c;
214
+ } elseif ($c === '+' || $c === '-') {
215
+ $last = mb_substr($this->_buffer, -1);
216
+ if (!($last === 'e' || $last === 'E')) {
217
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
218
+ "Can only have '+' or '-' after the 'e' or 'E' in a number.");
219
+ }
220
+ $this->_buffer .= $c;
221
+ } else {
222
+ $this->_end_number();
223
+ // we have consumed one beyond the end of the number
224
+ $this->_consume_char($c);
225
+ }
226
+ break;
227
+
228
+ case self::STATE_IN_TRUE:
229
+ $this->_buffer .= $c;
230
+ if (mb_strlen($this->_buffer) === 4) {
231
+ $this->_end_true();
232
+ }
233
+ break;
234
+
235
+ case self::STATE_IN_FALSE:
236
+ $this->_buffer .= $c;
237
+ if (mb_strlen($this->_buffer) === 5) {
238
+ $this->_end_false();
239
+ }
240
+ break;
241
+
242
+ case self::STATE_IN_NULL:
243
+ $this->_buffer .= $c;
244
+ if (mb_strlen($this->_buffer) === 4) {
245
+ $this->_end_null();
246
+ }
247
+ break;
248
+
249
+ case self::STATE_DONE:
250
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
251
+ "Expected end of document.");
252
+
253
+ default:
254
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
255
+ "Internal error. Reached an unknown state: ".$this->_state);
256
+ }
257
+ }
258
+
259
+ private function _is_hex_character($c) {
260
+ return preg_match('/[0-9a-fA-F]/u', $c);
261
+ }
262
+
263
+ // Thanks: http://stackoverflow.com/questions/1805802/php-convert-unicode-codepoint-to-utf-8
264
+ private function _convert_codepoint_to_character($num) {
265
+ if($num<=0x7F) return chr($num);
266
+ if($num<=0x7FF) return chr(($num>>6)+192).chr(($num&63)+128);
267
+ if($num<=0xFFFF) return chr(($num>>12)+224).chr((($num>>6)&63)+128).chr(($num&63)+128);
268
+ if($num<=0x1FFFFF) return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128).chr(($num&63)+128);
269
+ return '';
270
+ }
271
+
272
+ private function _is_digit($c) {
273
+ // Only concerned with the first character in a number.
274
+ return preg_match('/[0-9]|-/u',$c);
275
+ }
276
+
277
+
278
+ private function _start_value($c) {
279
+ if ($c === '[') {
280
+ $this->_start_array();
281
+ } elseif ($c === '{') {
282
+ $this->_start_object();
283
+ } elseif ($c === '"') {
284
+ $this->_start_string();
285
+ } elseif ($this->_is_digit($c)) {
286
+ $this->_start_number($c);
287
+ } elseif ($c === 't') {
288
+ $this->_state = self::STATE_IN_TRUE;
289
+ $this->_buffer .= $c;
290
+ } elseif ($c === 'f') {
291
+ $this->_state = self::STATE_IN_FALSE;
292
+ $this->_buffer .= $c;
293
+ } elseif ($c === 'n') {
294
+ $this->_state = self::STATE_IN_NULL;
295
+ $this->_buffer .= $c;
296
+ } else {
297
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
298
+ "Unexpected character for value: ".$c);
299
+ }
300
+ }
301
+
302
+
303
+ private function _start_array() {
304
+ $this->_listener->start_array();
305
+ $this->_state = self::STATE_IN_ARRAY;
306
+ array_push($this->_stack, self::STACK_ARRAY);
307
+ }
308
+
309
+ private function _end_array() {
310
+ $popped = array_pop($this->_stack);
311
+ if ($popped !== self::STACK_ARRAY) {
312
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
313
+ "Unexpected end of array encountered.");
314
+ }
315
+ $this->_listener->end_array();
316
+ $this->_state = self::STATE_AFTER_VALUE;
317
+
318
+ if (empty($this->_stack)) {
319
+ $this->_end_document();
320
+ }
321
+ }
322
+
323
+
324
+ private function _start_object() {
325
+ $this->_listener->start_object();
326
+ $this->_state = self::STATE_IN_OBJECT;
327
+ array_push($this->_stack, self::STACK_OBJECT);
328
+ }
329
+
330
+ private function _end_object() {
331
+ $popped = array_pop($this->_stack);
332
+ if ($popped !== self::STACK_OBJECT) {
333
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
334
+ "Unexpected end of object encountered.");
335
+ }
336
+ $this->_listener->end_object();
337
+ $this->_state = self::STATE_AFTER_VALUE;
338
+
339
+ if (empty($this->_stack)) {
340
+ $this->_end_document();
341
+ }
342
+ }
343
+
344
+ private function _start_string() {
345
+ array_push($this->_stack, self::STACK_STRING);
346
+ $this->_state = self::STATE_IN_STRING;
347
+ }
348
+
349
+ private function _start_key() {
350
+ array_push($this->_stack, self::STACK_KEY);
351
+ $this->_state = self::STATE_IN_STRING;
352
+ }
353
+
354
+ private function _end_string() {
355
+ $popped = array_pop($this->_stack);
356
+ if ($popped === self::STACK_KEY) {
357
+ $this->_listener->key($this->_buffer);
358
+ $this->_state = self::STATE_END_KEY;
359
+ } elseif ($popped === self::STACK_STRING) {
360
+ $this->_listener->value($this->_buffer);
361
+ $this->_state = self::STATE_AFTER_VALUE;
362
+ } else {
363
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
364
+ "Unexpected end of string.");
365
+ }
366
+ $this->_buffer = '';
367
+ }
368
+
369
+ private function _process_escape_character($c) {
370
+ if ($c === '"') {
371
+ $this->_buffer .= '"';
372
+ } elseif ($c === '\\') {
373
+ $this->_buffer .= '\\';
374
+ } elseif ($c === '/') {
375
+ $this->_buffer .= '/';
376
+ } elseif ($c === 'b') {
377
+ $this->_buffer .= "\x08";
378
+ } elseif ($c === 'f') {
379
+ $this->_buffer .= "\f";
380
+ } elseif ($c === 'n') {
381
+ $this->_buffer .= "\n";
382
+ } elseif ($c === 'r') {
383
+ $this->_buffer .= "\r";
384
+ } elseif ($c === 't') {
385
+ $this->_buffer .= "\t";
386
+ } elseif ($c === 'u') {
387
+ $this->_state = self::STATE_UNICODE;
388
+ } else {
389
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
390
+ "Expected escaped character after backslash. Got: ".$c);
391
+ }
392
+
393
+ if ($this->_state !== self::STATE_UNICODE) {
394
+ $this->_state = self::STATE_IN_STRING;
395
+ }
396
+ }
397
+
398
+ private function _process_unicode_character($c) {
399
+ if (!$this->_is_hex_character($c)) {
400
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
401
+ "Expected hex character for escaped unicode character. Unicode parsed: " . implode($this->_unicode_buffer) . " and got: ".$c);
402
+ }
403
+ array_push($this->_unicode_buffer, $c);
404
+ if (count($this->_unicode_buffer) === 4) {
405
+ $codepoint = hexdec(implode($this->_unicode_buffer));
406
+
407
+ if ($codepoint >= 0xD800 && $codepoint < 0xDC00) {
408
+ $this->_unicode_high_codepoint = $codepoint;
409
+ $this->_unicode_buffer = array();
410
+ } elseif ($codepoint >= 0xDC00 && $codepoint <= 0xDFFF) {
411
+ if ($this->_unicode_high_codepoint === -1) {
412
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
413
+ "Missing high codepoint for unicode low codepoint.");
414
+ }
415
+ $combined_codepoint = (($this->_unicode_high_codepoint - 0xD800) * 0x400) + ($codepoint - 0xDC00) + 0x10000;
416
+
417
+ $this->_end_unicode_character($combined_codepoint);
418
+ } else {
419
+ $this->_end_unicode_character($codepoint);
420
+ }
421
+ }
422
+ }
423
+
424
+ private function _end_unicode_character($codepoint) {
425
+ $this->_buffer .= $this->_convert_codepoint_to_character($codepoint);
426
+ $this->_unicode_buffer = array();
427
+ $this->_unicode_high_codepoint = -1;
428
+ $this->_state = self::STATE_IN_STRING;
429
+ }
430
+
431
+
432
+ private function _start_number($c) {
433
+ $this->_state = self::STATE_IN_NUMBER;
434
+ $this->_buffer .= $c;
435
+ }
436
+
437
+ private function _end_number() {
438
+ $num = $this->_buffer;
439
+ if (preg_match('/\./', $num)) {
440
+ $num = (float)($num);
441
+ } else {
442
+ $num = (int)($num);
443
+ }
444
+ $this->_listener->value($num);
445
+
446
+ $this->_buffer = '';
447
+ $this->_state = self::STATE_AFTER_VALUE;
448
+ }
449
+
450
+
451
+ private function _end_true() {
452
+ $true = $this->_buffer;
453
+ if ($true === 'true') {
454
+ $this->_listener->value(true);
455
+ } else {
456
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
457
+ "Expected 'true'. Got: ".$true);
458
+ }
459
+ $this->_buffer = '';
460
+ $this->_state = self::STATE_AFTER_VALUE;
461
+ }
462
+
463
+ private function _end_false() {
464
+ $false = $this->_buffer;
465
+ if ($false === 'false') {
466
+ $this->_listener->value(false);
467
+ } else {
468
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
469
+ "Expected 'false'. Got: ".$false);
470
+ }
471
+ $this->_buffer = '';
472
+ $this->_state = self::STATE_AFTER_VALUE;
473
+ }
474
+
475
+ private function _end_null() {
476
+ $null = $this->_buffer;
477
+ if ($null === 'null') {
478
+ $this->_listener->value(null);
479
+ } else {
480
+ throw new JsonStreamingParser_ParsingError($this->_line_number, $this->_char_number,
481
+ "Expected 'null'. Got: ".$null);
482
+ }
483
+ $this->_buffer = '';
484
+ $this->_state = self::STATE_AFTER_VALUE;
485
+ }
486
+
487
+
488
+ private function _end_document() {
489
+ $this->_listener->end_document();
490
+ $this->_state = self::STATE_DONE;
491
+ }
492
+
493
+ }
lib/JSONStreamingParser/ParsingError.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class JsonStreamingParser_ParsingError extends Exception {
3
+
4
+ /**
5
+ * @param int $line
6
+ * @param int $char
7
+ * @param string $message
8
+ */
9
+ public function __construct($line, $char, $message) {
10
+ parent::__construct("Parsing error in [$line:$char]. " . $message);
11
+ }
12
+ }
lib/ecwid_product_api.php CHANGED
@@ -1,192 +1,228 @@
1
- <?php
2
-
3
- class EcwidProductApi {
4
- var $store_id = '';
5
-
6
- var $error = '';
7
-
8
- var $error_code = '';
9
-
10
- var $ECWID_PRODUCT_API_ENDPOINT = "http://app.ecwid.com/api/v1";
11
-
12
- function __construct($store_id) {
13
- $this->store_id = intval($store_id);
14
- }
15
-
16
- function EcwidProductApi($store_id) {
17
- if(version_compare(PHP_VERSION,"5.0.0","<")) {
18
- $this->__construct($store_id);
19
- }
20
- }
21
-
22
- function internal_parse_json($json) {
23
- if(version_compare(PHP_VERSION,"5.2.0",">=")) {
24
- return json_decode($json, true);
25
- }
26
- include_once('JSON.php');
27
- $json_parser = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
28
- return $json_parser->decode($json);
29
- }
30
-
31
- function internal_fetch_url_libcurl($url) {
32
- $timeout = 90;
33
- if (!function_exists('curl_init'))
34
- return array("code"=>"0","data"=>"The libcurl module isn't installed on your server. Please contact your hosting or server administrator to have it installed.");
35
- $headers[] = "Content-Type: application/x-www-form-urlencoded";
36
- $ch = curl_init();
37
-
38
- curl_setopt ($ch, CURLOPT_URL, $url);
39
- curl_setopt ($ch, CURLOPT_HEADER, 0);
40
- curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
41
- curl_setopt ($ch, CURLOPT_HTTPGET, 1);
42
- curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
43
-
44
- $body = curl_exec ($ch);
45
- $errno = curl_errno ($ch);
46
- $error = curl_error($ch);
47
-
48
- $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
49
- $result = array();
50
- if( $error ) {
51
- return array("code"=>"0","data"=>"libcurl error($errno): $error");
52
- }
53
-
54
- return array("code"=>$httpcode, "data"=>$body);
55
- }
56
-
57
- function process_request($url) {
58
-
59
- $result = $this->internal_fetch_url_libcurl($url);
60
- if ($result['code'] == 200) {
61
- $this->error = '';
62
- $this->error_code = '';
63
- $json = $result['data'];
64
- return $this->internal_parse_json($json);
65
- } else {
66
- $this->error = $result['data'];
67
- $this->error_code = $result['code'];
68
- return false;
69
- }
70
- }
71
-
72
- function get_all_categories() {
73
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/categories";
74
- $categories = $this->process_request($api_url);
75
- return $categories;
76
- }
77
-
78
- function get_subcategories_by_id($parent_category_id = 0) {
79
- $parent_category_id = intval($parent_category_id);
80
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/categories?parent=" .
81
- $parent_category_id;
82
- $categories = $this->process_request($api_url);
83
- return $categories;
84
- }
85
-
86
- function get_all_products() {
87
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/products";
88
- $products = $this->process_request($api_url);
89
- return $products;
90
- }
91
-
92
-
93
- function get_products_by_category_id($category_id = 0) {
94
- $category_id = intval($category_id);
95
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/products?category=" . $category_id;
96
- $products = $this->process_request($api_url);
97
- return $products;
98
- }
99
-
100
- function get_product($product_id) {
101
- static $cached;
102
-
103
- $product_id = intval($product_id);
104
-
105
- if (isset($cached[$product_id])) {
106
- return $cached[$product_id];
107
- }
108
-
109
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/product?id=" . $product_id;
110
- $cached[$product_id] = $this->process_request($api_url);
111
-
112
- return $cached[$product_id];
113
- }
114
-
115
- function get_category($category_id) {
116
- static $cached = array();
117
-
118
- $category_id = intval($category_id);
119
-
120
- if (isset($cached[$category_id])) {
121
- return $cached[$category_id];
122
- }
123
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/category?id=" . $category_id;
124
- $cached[$category_id] = $this->process_request($api_url);
125
-
126
- return $cached[$category_id];
127
- }
128
-
129
- function get_batch_request($params) {
130
- if (!is_array($params)) {
131
- return false;
132
- } else {
133
- $api_url = '';
134
- foreach ($params as $param) {
135
- $alias = $param["alias"];
136
- $action = $param["action"];
137
-
138
- if (isset($param['params']))
139
- $action_params = $param["params"];
140
-
141
- if (!empty($api_url))
142
- $api_url .= "&";
143
-
144
- $api_url .= ($alias . "=" . $action);
145
-
146
- // if there are the parameters - add it to url
147
- if (is_array($action_params)) {
148
- $action_param_str = "?";
149
- $is_first = true;
150
- foreach ($action_params as $action_param_name => $action_param_value) {
151
- if (!$is_first) {
152
- $action_param_str .= "&";
153
- }
154
- $action_param_str .= $action_param_name . "=" . $action_param_value;
155
- $is_first = false;
156
- }
157
- $action_param_str = urlencode($action_param_str);
158
- $api_url .= $action_param_str;
159
- }
160
- }
161
-
162
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/batch?". $api_url;
163
- $data = $this->process_request($api_url);
164
- return $data;
165
- }
166
- }
167
- function get_random_products($count) {
168
- $count = intval($count);
169
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/random_products?count=" . $count;
170
- $random_products = $this->process_request($api_url);
171
- return $random_products;
172
- }
173
-
174
- function get_profile() {
175
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/profile";
176
- $profile = $this->process_request($api_url);
177
- return $profile;
178
- }
179
-
180
- function is_api_enabled() {
181
- // quick and lightweight request
182
- $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/profile";
183
- $this->process_request($api_url);
184
- if ($this->error_code === '') {
185
- return true;
186
- } else {
187
- return false;
188
- }
189
- }
190
- }
191
-
192
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class EcwidProductApi {
4
+ var $store_id = '';
5
+
6
+ var $error = '';
7
+
8
+ var $error_code = '';
9
+
10
+ var $ECWID_PRODUCT_API_ENDPOINT = "http://app.ecwid.com/api/v1";
11
+
12
+ function __construct($store_id) {
13
+ $this->store_id = intval($store_id);
14
+ }
15
+
16
+ function EcwidProductApi($store_id) {
17
+ if(version_compare(PHP_VERSION,"5.0.0","<")) {
18
+ $this->__construct($store_id);
19
+ }
20
+ }
21
+
22
+ function internal_parse_json($json) {
23
+ if(version_compare(PHP_VERSION,"5.2.0",">=")) {
24
+ return json_decode($json, true);
25
+ }
26
+ include_once('JSON.php');
27
+ $json_parser = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
28
+ return $json_parser->decode($json);
29
+ }
30
+
31
+ function internal_fetch_url_libcurl($url) {
32
+ $timeout = 90;
33
+ if (!function_exists('curl_init'))
34
+ return array("code"=>"0","data"=>"The libcurl module isn't installed on your server. Please contact your hosting or server administrator to have it installed.");
35
+ $headers[] = "Content-Type: application/x-www-form-urlencoded";
36
+ $ch = curl_init();
37
+
38
+ curl_setopt ($ch, CURLOPT_URL, $url);
39
+ curl_setopt ($ch, CURLOPT_HEADER, 0);
40
+ curl_setopt ($ch, CURLOPT_HTTPHEADER, $headers);
41
+ curl_setopt ($ch, CURLOPT_HTTPGET, 1);
42
+ curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
43
+
44
+ $body = curl_exec ($ch);
45
+ $errno = curl_errno ($ch);
46
+ $error = curl_error($ch);
47
+
48
+ $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
49
+ $result = array();
50
+ if( $error ) {
51
+ return array("code"=>"0","data"=>"libcurl error($errno): $error");
52
+ }
53
+
54
+ return array("code"=>$httpcode, "data"=>$body);
55
+ }
56
+
57
+ function process_request($url) {
58
+
59
+ $result = $this->internal_fetch_url_libcurl($url);
60
+ if ($result['code'] == 200) {
61
+ $this->error = '';
62
+ $this->error_code = '';
63
+ $json = $result['data'];
64
+ return $this->internal_parse_json($json);
65
+ } else {
66
+ $this->error = $result['data'];
67
+ $this->error_code = $result['code'];
68
+ return false;
69
+ }
70
+ }
71
+
72
+ function get_all_categories() {
73
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/categories";
74
+ $categories = $this->process_request($api_url);
75
+ return $categories;
76
+ }
77
+
78
+ function get_subcategories_by_id($parent_category_id = 0) {
79
+ $parent_category_id = intval($parent_category_id);
80
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/categories?parent=" .
81
+ $parent_category_id;
82
+ $categories = $this->process_request($api_url);
83
+ return $categories;
84
+ }
85
+
86
+ function get_all_products() {
87
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/products";
88
+ $products = $this->process_request($api_url);
89
+ return $products;
90
+ }
91
+
92
+
93
+ function get_products_by_category_id($category_id = 0) {
94
+ $category_id = intval($category_id);
95
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/products?category=" . $category_id;
96
+ $products = $this->process_request($api_url);
97
+ return $products;
98
+ }
99
+
100
+ function get_product($product_id) {
101
+ static $cached;
102
+
103
+ $product_id = intval($product_id);
104
+
105
+ if (isset($cached[$product_id])) {
106
+ return $cached[$product_id];
107
+ }
108
+
109
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/product?id=" . $product_id;
110
+ $cached[$product_id] = $this->process_request($api_url);
111
+
112
+ return $cached[$product_id];
113
+ }
114
+
115
+ function get_category($category_id) {
116
+ static $cached = array();
117
+
118
+ $category_id = intval($category_id);
119
+
120
+ if (isset($cached[$category_id])) {
121
+ return $cached[$category_id];
122
+ }
123
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/category?id=" . $category_id;
124
+ $cached[$category_id] = $this->process_request($api_url);
125
+
126
+ return $cached[$category_id];
127
+ }
128
+
129
+ function get_batch_request($params) {
130
+ if (!is_array($params)) {
131
+ return false;
132
+ } else {
133
+ $api_url = '';
134
+ foreach ($params as $param) {
135
+ $alias = $param["alias"];
136
+ $action = $param["action"];
137
+
138
+ if (isset($param['params']))
139
+ $action_params = $param["params"];
140
+
141
+ if (!empty($api_url))
142
+ $api_url .= "&";
143
+
144
+ $api_url .= ($alias . "=" . $action);
145
+
146
+ // if there are the parameters - add it to url
147
+ if (is_array($action_params)) {
148
+ $action_param_str = "?";
149
+ $is_first = true;
150
+ foreach ($action_params as $action_param_name => $action_param_value) {
151
+ if (!$is_first) {
152
+ $action_param_str .= "&";
153
+ }
154
+ $action_param_str .= $action_param_name . "=" . $action_param_value;
155
+ $is_first = false;
156
+ }
157
+ $action_param_str = urlencode($action_param_str);
158
+ $api_url .= $action_param_str;
159
+ }
160
+ }
161
+
162
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/batch?". $api_url;
163
+ $data = $this->process_request($api_url);
164
+ return $data;
165
+ }
166
+ }
167
+ function get_random_products($count) {
168
+ $count = intval($count);
169
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/random_products?count=" . $count;
170
+ $random_products = $this->process_request($api_url);
171
+ return $random_products;
172
+ }
173
+
174
+ function get_profile() {
175
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/profile";
176
+ $profile = $this->process_request($api_url);
177
+ return $profile;
178
+ }
179
+
180
+ function is_api_enabled() {
181
+ // quick and lightweight request
182
+ $api_url = $this->ECWID_PRODUCT_API_ENDPOINT . "/" . $this->store_id . "/profile";
183
+ $this->process_request($api_url);
184
+ if ($this->error_code === '') {
185
+ return true;
186
+ } else {
187
+ return false;
188
+ }
189
+ }
190
+
191
+ function get_method_response_stream($method)
192
+ {
193
+ $request_url = '';
194
+ switch($method) {
195
+ case 'products':
196
+ case 'categories':
197
+ $request_url = $this->ECWID_PRODUCT_API_ENDPOINT . '/' . $this->store_id . '/' . $method;
198
+ break;
199
+ default:
200
+ return false;
201
+ }
202
+
203
+ $stream = null;
204
+ if (ini_get('allow_url_fopen')) {
205
+ $stream = fopen($request_url, 'r');
206
+ } elseif (version_compare(PHP_VERSION, '5.1.0')) {
207
+
208
+ $body = '';
209
+
210
+ if (defined('WP_CONTENT_DIR') && function_exists('get_temp_dir') && function_exists('wp_remote_get')) {
211
+ // we are in wordpress
212
+ $response = wp_remote_get($request_url);
213
+ $body = $response['body'];
214
+ } else {
215
+ $response = internal_fetch_url_libcurl($request_url);
216
+ $body = $response['data'];
217
+ }
218
+
219
+ $stream = fopen('php://temp', 'rw');
220
+ fwrite($stream, $body);
221
+ rewind($stream);
222
+ }
223
+
224
+ return $stream;
225
+ }
226
+ }
227
+
228
+ ?>
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: Ecwid Team
3
  Tags: ecwid, shopping cart, ecommerce, wordpress ecommerce, wp e-commerce, paypal, e-commerce, online store, store, shop, cart, online shop, shopping, digital goods, downloadable products, product catalog, ecomerce, products, facebook, f-commerce
4
  Requires at least: 2.8
5
  Tested up to: 3.8
6
- Stable tag: 2.2.1
7
 
8
  Ecwid is a free full-featured shopping cart that can easily be added to any blog
9
  and takes less than 5 minutes to set up.
@@ -78,6 +78,15 @@ http://codex.wordpress.org/Managing_Plugins#Installing_Plugins
78
  - Knowledge Base: [http://kb.ecwid.com](http://kb.ecwid.com)
79
 
80
  == Changelog ==
 
 
 
 
 
 
 
 
 
81
  = 2.2.1 =
82
  - Fixed layout error on General Settings page in Firefox
83
 
3
  Tags: ecwid, shopping cart, ecommerce, wordpress ecommerce, wp e-commerce, paypal, e-commerce, online store, store, shop, cart, online shop, shopping, digital goods, downloadable products, product catalog, ecomerce, products, facebook, f-commerce
4
  Requires at least: 2.8
5
  Tested up to: 3.8
6
+ Stable tag: 2.3
7
 
8
  Ecwid is a free full-featured shopping cart that can easily be added to any blog
9
  and takes less than 5 minutes to set up.
78
  - Knowledge Base: [http://kb.ecwid.com](http://kb.ecwid.com)
79
 
80
  == Changelog ==
81
+ = 2.3 =
82
+ - Added compatibility with Google XML Sitemaps plugin. Now you can submit your store items links along with the other site pages to search engines. To use this feature, please install the "Google XML Sitemaps" plugin (http://wordpress.org/plugins/google-sitemap-generator/), generate a sitemap (it will include your products and categories links) and submit it to the search engines to help them better crawl and categorize your site.
83
+
84
+ - Improved compatibility with SEO Ultimate plugin. Ecwid plugin always displays your store pages in a proper SEO-friendly format to make the store indexable by search engines. Moreover, we constantly adjust the plugin to make it work fine with popular third party SEO modules. So Ecwid is perfectly compatible with "Wordpress SEO by Yoast", "All in one SEO Pack", "Platinum SEO Pack" and now with "SEO Ultimate" plugin.
85
+
86
+ - Minor design improvements of the plugin settings pages to make them mobile-friendly for better compatibility with the backend layout of new Wordpress versions. Now you can manage Ecwid plugin settings in your Wordpress administrator panel using your mobile device.
87
+
88
+ - New "Ecwid badges" widget is available. If you like Ecwid and want to help it grow and become the most popular e-commerce solution, you can now add a fancy 'Powered by Ecwid' badge on your site to show your visitors that you're a proud user of Ecwid. Please find the new widget under 'Appearance → Widgets' section in your Wordpress backend.
89
+
90
  = 2.2.1 =
91
  - Fixed layout error on General Settings page in Firefox
92
 
templates/advanced-settings.php CHANGED
@@ -1,4 +1,5 @@
1
- <form class="wrap pure-form pure-form-aligned ecwid-settings advanced-settings" method="POST" action="options.php">
 
2
 
3
  <h2><?php _e('Ecwid Shopping Cart - Advanced settings', 'ecwid-shopping-cart'); ?></h2>
4
 
@@ -7,7 +8,7 @@
7
 
8
  <fieldset>
9
 
10
- <div class="pure-control-group">
11
 
12
  <?php if (ecwid_is_paid_account()): ?>
13
  <label for="ecwid_default_category_id">
@@ -89,4 +90,5 @@
89
  </button>
90
  </div>
91
  </fieldset>
92
- </form>
 
1
+ <div class="wrap">
2
+ <form class="pure-form pure-form-aligned ecwid-settings advanced-settings" method="POST" action="options.php">
3
 
4
  <h2><?php _e('Ecwid Shopping Cart - Advanced settings', 'ecwid-shopping-cart'); ?></h2>
5
 
8
 
9
  <fieldset>
10
 
11
+ <div class="pure-control-group bottom-border">
12
 
13
  <?php if (ecwid_is_paid_account()): ?>
14
  <label for="ecwid_default_category_id">
90
  </button>
91
  </div>
92
  </fieldset>
93
+ </form>
94
+ </div>
templates/appearance-settings.php CHANGED
@@ -6,8 +6,8 @@ function ecwid_embed_svg($name) {
6
  }
7
 
8
  ?>
9
-
10
- <form class="wrap pure-form pure-form-aligned ecwid-settings appearance-settings" method="POST" action="options.php">
11
 
12
  <h2><?php _e('Ecwid Shopping Cart - Appearance settings', 'ecwid-shopping-cart'); ?></h2>
13
 
@@ -16,76 +16,99 @@ function ecwid_embed_svg($name) {
16
 
17
  <fieldset>
18
 
19
- <div class="pure-control-group">
20
- <label for="ecwid_show_search_box">
21
- <?php _e('Display search box above products', 'ecwid-shopping-cart'); ?>
22
- </label>
23
-
24
- <input
25
- id="ecwid_show_search_box"
26
- name="ecwid_show_search_box"
27
- type="checkbox"
28
- <?php if (get_option('ecwid_show_search_box')): ?>
29
- checked="checked"
30
- <?php endif; ?>
31
- $disabled_str
32
- />
33
- <span class="note inline-note">
 
 
 
 
 
34
  <?php _e('Or you can add search box to your website\'s toolbar using <a href="widgets.php">WordPress native widgets</a>.', 'ecwid-shopping-cart'); ?>
35
- </span>
36
  </div>
37
 
38
- <div class="pure-control-group">
39
- <label for="ecwid_show_categories">
40
- <?php _e('Display horizontal categories above products', 'ecwid-shopping-cart'); ?>
41
- </label>
42
-
43
- <input
44
- id="ecwid_show_categories"
45
- name="ecwid_show_categories"
46
- type="checkbox"
47
- <?php if (get_option('ecwid_show_categories')): ?>
48
- checked="checked"
49
- <?php endif; ?>
50
- $disabled_str
51
- />
52
- <span class="note inline-note">
 
 
 
 
 
53
  <?php _e('Or you can add vertical categories to your website\'s toolbar using <a href="widgets.php">WordPress native widgets</a>.', 'ecwid-shopping-cart'); ?>
54
- </span>
55
  </div>
56
 
57
- <div class="pure-control-group">
58
- <label for="ecwid_enable_minicart">
59
- <?php _e('Enable minicart attached to horizontal categories', 'ecwid-shopping-cart'); ?>
60
- </label>
61
 
62
- <input
63
- id="ecwid_enable_minicart"
64
- name="ecwid_enable_minicart"
65
- type="checkbox"
66
- <?php if (get_option('ecwid_enable_minicart')): ?>
67
- checked="checked"
68
- <?php endif; ?>
69
- $disabled_str
70
- />
71
- <span class="note inline-note">
 
 
 
 
 
 
 
 
 
 
72
  <?php _e("You should disable this option, if you added minicart to your website's&nbsp;sidebar.", 'ecwid-shopping-cart'); ?>
73
- </span>
74
  </div>
75
-
76
- <div class="pure-control-group">
77
- <label for="ecwid_pb_categoriesperrow">
78
- <?php _e('Number of categories per row', 'ecwid-shopping-cart'); ?>
79
- </label>
80
 
81
- <input
82
- id="ecwid_pb_categoriesperrow"
83
- name="ecwid_pb_categoriesperrow"
84
- type="text"
85
- class="number"
86
- value="<?php echo esc_attr(get_option('ecwid_pb_categoriesperrow')); ?>"
87
- $disabled_str
88
- />
 
 
 
 
 
 
 
 
 
 
 
 
89
  </div>
90
 
91
  <hr />
@@ -202,4 +225,6 @@ function ecwid_embed_svg($name) {
202
  <button type="submit" class="<?php echo ECWID_MAIN_BUTTON_CLASS; ?>"><?php _e('Save changes', 'ecwid-shopping-cart'); ?></button>
203
  </div>
204
  </fieldset>
205
- </form>
 
 
6
  }
7
 
8
  ?>
9
+ <div class="wrap">
10
+ <form class="pure-form pure-form-aligned ecwid-settings appearance-settings" method="POST" action="options.php">
11
 
12
  <h2><?php _e('Ecwid Shopping Cart - Appearance settings', 'ecwid-shopping-cart'); ?></h2>
13
 
16
 
17
  <fieldset>
18
 
19
+ <div class="pure-control-group small-input">
20
+ <div class="input">
21
+ <div>
22
+ <input
23
+ id="ecwid_show_search_box"
24
+ name="ecwid_show_search_box"
25
+ type="checkbox"
26
+ <?php if (get_option('ecwid_show_search_box')): ?>
27
+ checked="checked"
28
+ <?php endif; ?>
29
+ <?php echo $disabled_str; ?>
30
+ />
31
+ </div>
32
+ </div>
33
+ <div class="label">
34
+ <label for="ecwid_show_search_box">
35
+ <?php _e('Display search box above products', 'ecwid-shopping-cart'); ?>
36
+ </label>
37
+ </div>
38
+ <div class="note">
39
  <?php _e('Or you can add search box to your website\'s toolbar using <a href="widgets.php">WordPress native widgets</a>.', 'ecwid-shopping-cart'); ?>
40
+ </div>
41
  </div>
42
 
43
+ <div class="pure-control-group small-input">
44
+ <div class="input">
45
+ <div>
46
+ <input
47
+ id="ecwid_show_categories"
48
+ name="ecwid_show_categories"
49
+ type="checkbox"
50
+ <?php if (get_option('ecwid_show_categories')): ?>
51
+ checked="checked"
52
+ <?php endif; ?>
53
+ <?php echo $disabled_str; ?>
54
+ />
55
+ </div>
56
+ </div>
57
+ <div class="label">
58
+ <label for="ecwid_show_categories">
59
+ <?php _e('Display horizontal categories above products', 'ecwid-shopping-cart'); ?>
60
+ </label>
61
+ </div>
62
+ <div class="note">
63
  <?php _e('Or you can add vertical categories to your website\'s toolbar using <a href="widgets.php">WordPress native widgets</a>.', 'ecwid-shopping-cart'); ?>
64
+ </div>
65
  </div>
66
 
 
 
 
 
67
 
68
+ <div class="pure-control-group small-input">
69
+ <div class="input">
70
+ <div>
71
+ <input
72
+ id="ecwid_enable_minicart"
73
+ name="ecwid_enable_minicart"
74
+ type="checkbox"
75
+ <?php if (get_option('ecwid_enable_minicart')): ?>
76
+ checked="checked"
77
+ <?php endif; ?>
78
+ <?php echo $disabled_str; ?>
79
+ />
80
+ </div>
81
+ </div>
82
+ <div class="label">
83
+ <label for="ecwid_enable_minicart">
84
+ <?php _e('Enable minicart attached to horizontal categories', 'ecwid-shopping-cart'); ?>
85
+ </label>
86
+ </div>
87
+ <div class="note">
88
  <?php _e("You should disable this option, if you added minicart to your website's&nbsp;sidebar.", 'ecwid-shopping-cart'); ?>
89
+ </div>
90
  </div>
 
 
 
 
 
91
 
92
+ <div class="pure-control-group small-input">
93
+ <div class="input">
94
+ <div>
95
+ <input
96
+ id="ecwid_pb_categoriesperrow"
97
+ name="ecwid_pb_categoriesperrow"
98
+ type="text"
99
+ class="number"
100
+ value="<?php echo esc_attr(get_option('ecwid_pb_categoriesperrow')); ?>"
101
+ <?php echo $disabled_str; ?>
102
+ />
103
+ </div>
104
+ </div>
105
+ <div class="label">
106
+ <label for="ecwid_pb_categoriesperrow">
107
+ <?php _e('Number of categories per row', 'ecwid-shopping-cart'); ?>
108
+ </label>
109
+ </div>
110
+ <div class="note">
111
+ </div>
112
  </div>
113
 
114
  <hr />
225
  <button type="submit" class="<?php echo ECWID_MAIN_BUTTON_CLASS; ?>"><?php _e('Save changes', 'ecwid-shopping-cart'); ?></button>
226
  </div>
227
  </fieldset>
228
+ </form>
229
+
230
+ </div>
templates/general-settings-initial.php CHANGED
@@ -1,8 +1,7 @@
1
- <div class="wrap pure-form ecwid-settings general-settings">
2
 
3
- <h2><?php _e('Ecwid Shopping Cart - General settings', 'ecwid-shopping-cart'); ?></h2>
4
-
5
- <form method="POST" action="options.php">
6
  <?php settings_fields('ecwid_options_page'); ?>
7
  <fieldset>
8
 
@@ -73,4 +72,4 @@
73
  <p><?php _e('Questions? Visit <a href="http://help.ecwid.com/?source=wporg">Ecwid support center</a>.', 'ecwid-shopping-cart'); ?></p>
74
  </fieldset>
75
  </form>
76
- </div>
1
+ <div class="wrap">
2
 
3
+ <form method="POST" action="options.php" class="pure-form ecwid-settings general-settings">
4
+ <h2><?php _e('Ecwid Shopping Cart - General settings', 'ecwid-shopping-cart'); ?></h2>
 
5
  <?php settings_fields('ecwid_options_page'); ?>
6
  <fieldset>
7
 
72
  <p><?php _e('Questions? Visit <a href="http://help.ecwid.com/?source=wporg">Ecwid support center</a>.', 'ecwid-shopping-cart'); ?></p>
73
  </fieldset>
74
  </form>
75
+ </div>
templates/general-settings.php CHANGED
@@ -1,8 +1,7 @@
1
- <div class="wrap pure-form ecwid-settings general-settings">
2
- <h2><?php _e('Ecwid Shopping Cart - General settings', 'ecwid-shopping-cart'); ?></h2>
3
 
4
-
5
- <form method="POST" action="options.php" name="settings">
6
  <?php settings_fields('ecwid_options_page'); ?>
7
  <fieldset>
8
 
@@ -14,7 +13,7 @@
14
  </div>
15
 
16
  <div class="messages-container">
17
- <?php if ($_GET['settings-updated']): ?>
18
 
19
  <div class="main-message"><?php _e('Congratulations!', 'ecwid-shopping-cart'); ?></div>
20
  <div class="secondary-message"?><?php _e('Your Ecwid store is now connected to your WordPress website.', 'ecwid-shopping-cart'); ?></div>
@@ -33,7 +32,7 @@
33
  <?php _e('Store ID', 'ecwid-shopping-cart'); ?>: <strong><? echo esc_attr(get_ecwid_store_id()); ?></strong>
34
  </span>
35
  </div>
36
- <div class="right"">
37
  <a class="pure-button" target="_blank" href="https://my.ecwid.com/cp/?source=wporg#t1=&t2=Dashboard">
38
  <?php _e('Control panel', 'ecwid-shopping-cart'); ?>
39
  </a>
@@ -94,4 +93,4 @@
94
  <p><?php _e('Questions? Visit <a href="http://help.ecwid.com/?source=wporg">Ecwid support center</a>.', 'ecwid-shopping-cart'); ?></p>
95
  </fieldset>
96
  </form>
97
- </div>
1
+ <div class="wrap">
 
2
 
3
+ <form method="POST" action="options.php" class="pure-form ecwid-settings general-settings" name="settings">
4
+ <h2><?php _e('Ecwid Shopping Cart - General settings', 'ecwid-shopping-cart'); ?></h2>
5
  <?php settings_fields('ecwid_options_page'); ?>
6
  <fieldset>
7
 
13
  </div>
14
 
15
  <div class="messages-container">
16
+ <?php if (array_key_exists('settings-updated', $_GET)): ?>
17
 
18
  <div class="main-message"><?php _e('Congratulations!', 'ecwid-shopping-cart'); ?></div>
19
  <div class="secondary-message"?><?php _e('Your Ecwid store is now connected to your WordPress website.', 'ecwid-shopping-cart'); ?></div>
32
  <?php _e('Store ID', 'ecwid-shopping-cart'); ?>: <strong><? echo esc_attr(get_ecwid_store_id()); ?></strong>
33
  </span>
34
  </div>
35
+ <div class="right two-buttons">
36
  <a class="pure-button" target="_blank" href="https://my.ecwid.com/cp/?source=wporg#t1=&t2=Dashboard">
37
  <?php _e('Control panel', 'ecwid-shopping-cart'); ?>
38
  </a>
93
  <p><?php _e('Questions? Visit <a href="http://help.ecwid.com/?source=wporg">Ecwid support center</a>.', 'ecwid-shopping-cart'); ?></p>
94
  </fieldset>
95
  </form>
96
+ </div>