boxalino_plugin - Version 1.1.0.0

Version Notes

Minor changes, thanks everyone for the feedback.

Download this release

Release Info

Developer Marcel Zenger
Extension boxalino_plugin
Version 1.1.0.0
Comparing to
See all releases


Code changes from version 1.0.0 to 1.1.0.0

app/code/local/Boxalino/CemSearch/Block/Cart/Crosssell.php CHANGED
@@ -72,7 +72,6 @@ class Boxalino_CemSearch_Block_Cart_Crosssell extends Mage_Checkout_Block_Cart_C
72
  );
73
  $this->_addProductAttributesAndPrices($itemCollection);
74
  }
75
- // Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($itemCollection);
76
  Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($itemCollection);
77
 
78
  $itemCollection->load();
72
  );
73
  $this->_addProductAttributesAndPrices($itemCollection);
74
  }
 
75
  Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($itemCollection);
76
 
77
  $itemCollection->load();
app/code/local/Boxalino/CemSearch/Block/Head.php CHANGED
@@ -32,6 +32,6 @@ class Boxalino_CemSearch_Block_Head extends Boxalino_CemSearch_Block_Abstract
32
 
33
  public function addExternalJS($args)
34
  {
35
- echo '<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>';
36
  }
37
  }
32
 
33
  public function addExternalJS($args)
34
  {
35
+ echo '<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>';
36
  }
37
  }
app/code/local/Boxalino/CemSearch/Helper/P13n/Adapter.php CHANGED
@@ -124,7 +124,6 @@ class Boxalino_CemSearch_Helper_P13n_Adapter
124
  $categoryNames[] = $categoryName;
125
  }
126
  }
127
- // $categoryDepth = count($categoryNames) - 1;
128
 
129
  $this->addFilterHierarchy('categories', $categoryId, $categoryNames);
130
 
@@ -140,7 +139,6 @@ class Boxalino_CemSearch_Helper_P13n_Adapter
140
  $category = Mage::getModel('catalog/category')->load($categoryId);
141
 
142
  if($category != null){
143
- // $this->addFilterHierarchy('categories', $categoryId, $category->getName());
144
  $filter = new \com\boxalino\p13n\api\thrift\Filter();
145
 
146
  $filter->fieldName = 'categories';
124
  $categoryNames[] = $categoryName;
125
  }
126
  }
 
127
 
128
  $this->addFilterHierarchy('categories', $categoryId, $categoryNames);
129
 
139
  $category = Mage::getModel('catalog/category')->load($categoryId);
140
 
141
  if($category != null){
 
142
  $filter = new \com\boxalino\p13n\api\thrift\Filter();
143
 
144
  $filter->fieldName = 'categories';
app/code/local/Boxalino/CemSearch/Helper/P13n/Client.php CHANGED
@@ -115,10 +115,6 @@ class Boxalino_CemSearch_Helper_P13n_Client
115
  $contextItem->role = 'mainProduct';
116
  $inquiry->contextItems = array($contextItem);
117
  }
118
- // elseif ($widgetType === 'category' && Utils::requestExists('categoryId')) {
119
- // $categoryId = Utils::requestString('categoryId');
120
- // $choiceRequest->requestContext->parameters['category_id'] = array($categoryId);
121
- // }
122
  $choiceRequest->inquiries[] = $inquiry;
123
  }
124
  $choiceResponse = $this->p13n->choose($choiceRequest);
115
  $contextItem->role = 'mainProduct';
116
  $inquiry->contextItems = array($contextItem);
117
  }
 
 
 
 
118
  $choiceRequest->inquiries[] = $inquiry;
119
  }
120
  $choiceResponse = $this->p13n->choose($choiceRequest);
app/code/local/Boxalino/CemSearch/Lib/vendor/Thrift/HttpP13n.php CHANGED
@@ -81,7 +81,11 @@ class HttpP13n
81
  protected function getClient()
82
  {
83
  if ($this->client === null || $this->transport === null) {
84
- $this->transport = new \Thrift\Transport\P13nTHttpClient($this->host, $this->port, $this->uri, $this->schema);
 
 
 
 
85
  $this->transport->setAuthorization($this->username, $this->password);
86
  $this->client = new \com\boxalino\p13n\api\thrift\P13nServiceClient(new \Thrift\Protocol\TCompactProtocol($this->transport));
87
  }
81
  protected function getClient()
82
  {
83
  if ($this->client === null || $this->transport === null) {
84
+ if(function_exists('curl_version')) {
85
+ $this->transport = new \Thrift\Transport\P13nTCurlClient($this->host, $this->port, $this->uri, $this->schema);
86
+ } else {
87
+ $this->transport = new \Thrift\Transport\P13nTHttpClient($this->host, $this->port, $this->uri, $this->schema);
88
+ }
89
  $this->transport->setAuthorization($this->username, $this->password);
90
  $this->client = new \com\boxalino\p13n\api\thrift\P13nServiceClient(new \Thrift\Protocol\TCompactProtocol($this->transport));
91
  }
app/code/local/Boxalino/CemSearch/Lib/vendor/Thrift/Transport/P13nTCurlClient.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ namespace Thrift\Transport;
3
+
4
+ use Thrift\Transport\TTransport;
5
+ use Thrift\Exception\TTransportException;
6
+ use Thrift\Factory\TStringFuncFactory;
7
+
8
+ class P13nTCurlClient extends TCurlClient {
9
+
10
+ private static $curlHandle;
11
+
12
+ protected $authorizationString;
13
+
14
+ /**
15
+ * Opens and sends the actual request over the HTTP connection
16
+ *
17
+ * @throws TTransportException if a writing error occurs
18
+ */
19
+ public function flush() {
20
+ // God, PHP really has some esoteric ways of doing simple things.
21
+ if (!self::$curlHandle) {
22
+ register_shutdown_function(array('Thrift\\Transport\\TCurlClient', 'closeCurlHandle'));
23
+ self::$curlHandle = curl_init();
24
+ curl_setopt(self::$curlHandle, CURLOPT_RETURNTRANSFER, true);
25
+ curl_setopt(self::$curlHandle, CURLOPT_BINARYTRANSFER, true);
26
+ curl_setopt(self::$curlHandle, CURLOPT_USERAGENT, 'PHP/TCurlClient');
27
+ curl_setopt(self::$curlHandle, CURLOPT_CUSTOMREQUEST, 'POST');
28
+ // FOLLOWLOCATION cannot be activated when safe_mode is enabled or an open_basedir is set
29
+ @curl_setopt(self::$curlHandle, CURLOPT_FOLLOWLOCATION, true);
30
+ curl_setopt(self::$curlHandle, CURLOPT_MAXREDIRS, 1);
31
+ }
32
+ $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
33
+ $fullUrl = $this->scheme_."://".$host.$this->uri_;
34
+
35
+ $headers = array('Host: '.$host,
36
+ 'Accept: application/x-thrift',
37
+ 'User-Agent: PHP/THttpClient',
38
+ 'Content-Type: application/x-thrift',
39
+ 'Content-Length: '.TStringFuncFactory::create()->strlen($this->request_),
40
+ 'Authorization: Basic '.$this->authorizationString);
41
+
42
+ curl_setopt(self::$curlHandle, CURLOPT_HTTPHEADER, $headers);
43
+
44
+ if ($this->timeout_ > 0) {
45
+ curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $this->timeout_);
46
+ }
47
+ curl_setopt(self::$curlHandle, CURLOPT_POSTFIELDS, $this->request_);
48
+ $this->request_ = '';
49
+
50
+ curl_setopt(self::$curlHandle, CURLOPT_URL, $fullUrl);
51
+ $this->response_ = curl_exec(self::$curlHandle);
52
+
53
+ // Connect failed?
54
+ if (!$this->response_) {
55
+ curl_close(self::$curlHandle);
56
+ self::$curlHandle = null;
57
+ $error = 'TCurlClient: Could not connect to '.$fullUrl;
58
+ throw new TTransportException($error, TTransportException::NOT_OPEN);
59
+ }
60
+ }
61
+
62
+ static function closeCurlHandle() {
63
+ try {
64
+ if (self::$curlHandle) {
65
+ curl_close(self::$curlHandle);
66
+ self::$curlHandle = null;
67
+ }
68
+ } catch (\Exception $x) {
69
+ error_log('There was an error closing the curl handle: ' . $x->getMessage());
70
+ }
71
+ }
72
+
73
+ public function setAuthorization($username, $password) {
74
+ $this->authorizationString = base64_encode($username.':'.$password);
75
+ }
76
+ }
app/code/local/Boxalino/CemSearch/Lib/vendor/Thrift/Transport/TCurlClient.php ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * Licensed to the Apache Software Foundation (ASF) under one
4
+ * or more contributor license agreements. See the NOTICE file
5
+ * distributed with this work for additional information
6
+ * regarding copyright ownership. The ASF licenses this file
7
+ * to you under the Apache License, Version 2.0 (the
8
+ * "License"); you may not use this file except in compliance
9
+ * with the License. You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing,
14
+ * software distributed under the License is distributed on an
15
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ * KIND, either express or implied. See the License for the
17
+ * specific language governing permissions and limitations
18
+ * under the License.
19
+ *
20
+ * @package thrift.transport
21
+ */
22
+
23
+ namespace Thrift\Transport;
24
+
25
+ use Thrift\Transport\TTransport;
26
+ use Thrift\Exception\TTransportException;
27
+ use Thrift\Factory\TStringFuncFactory;
28
+
29
+ /**
30
+ * HTTP client for Thrift
31
+ *
32
+ * @package thrift.transport
33
+ */
34
+ class TCurlClient extends TTransport {
35
+
36
+ private static $curlHandle;
37
+
38
+ /**
39
+ * The host to connect to
40
+ *
41
+ * @var string
42
+ */
43
+ protected $host_;
44
+
45
+ /**
46
+ * The port to connect on
47
+ *
48
+ * @var int
49
+ */
50
+ protected $port_;
51
+
52
+ /**
53
+ * The URI to request
54
+ *
55
+ * @var string
56
+ */
57
+ protected $uri_;
58
+
59
+ /**
60
+ * The scheme to use for the request, i.e. http, https
61
+ *
62
+ * @var string
63
+ */
64
+ protected $scheme_;
65
+
66
+ /**
67
+ * Buffer for the HTTP request data
68
+ *
69
+ * @var string
70
+ */
71
+ protected $request_;
72
+
73
+ /**
74
+ * Buffer for the HTTP response data.
75
+ *
76
+ * @var binary string
77
+ */
78
+ protected $response_;
79
+
80
+ /**
81
+ * Read timeout
82
+ *
83
+ * @var float
84
+ */
85
+ protected $timeout_;
86
+
87
+ /**
88
+ * Make a new HTTP client.
89
+ *
90
+ * @param string $host
91
+ * @param int $port
92
+ * @param string $uri
93
+ */
94
+ public function __construct($host, $port=80, $uri='', $scheme = 'http') {
95
+ if ((TStringFuncFactory::create()->strlen($uri) > 0) && ($uri{0} != '/')) {
96
+ $uri = '/'.$uri;
97
+ }
98
+ $this->scheme_ = $scheme;
99
+ $this->host_ = $host;
100
+ $this->port_ = $port;
101
+ $this->uri_ = $uri;
102
+ $this->request_ = '';
103
+ $this->response_ = null;
104
+ $this->timeout_ = null;
105
+ }
106
+
107
+ /**
108
+ * Set read timeout
109
+ *
110
+ * @param float $timeout
111
+ */
112
+ public function setTimeoutSecs($timeout) {
113
+ $this->timeout_ = $timeout;
114
+ }
115
+
116
+ /**
117
+ * Whether this transport is open.
118
+ *
119
+ * @return boolean true if open
120
+ */
121
+ public function isOpen() {
122
+ return true;
123
+ }
124
+
125
+ /**
126
+ * Open the transport for reading/writing
127
+ *
128
+ * @throws TTransportException if cannot open
129
+ */
130
+ public function open() {
131
+ }
132
+
133
+ /**
134
+ * Close the transport.
135
+ */
136
+ public function close() {
137
+ $this->request_ = '';
138
+ $this->response_ = null;
139
+ }
140
+
141
+ /**
142
+ * Read some data into the array.
143
+ *
144
+ * @param int $len How much to read
145
+ * @return string The data that has been read
146
+ * @throws TTransportException if cannot read any more data
147
+ */
148
+ public function read($len) {
149
+ if ($len >= strlen($this->response_)) {
150
+ return $this->response_;
151
+ } else {
152
+ $ret = substr($this->response_, 0, $len);
153
+ $this->response_ = substr($this->response_, $len);
154
+ return $ret;
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Writes some data into the pending buffer
160
+ *
161
+ * @param string $buf The data to write
162
+ * @throws TTransportException if writing fails
163
+ */
164
+ public function write($buf) {
165
+ $this->request_ .= $buf;
166
+ }
167
+
168
+ /**
169
+ * Opens and sends the actual request over the HTTP connection
170
+ *
171
+ * @throws TTransportException if a writing error occurs
172
+ */
173
+ public function flush() {
174
+ if (!self::$curlHandle) {
175
+ register_shutdown_function(array('Thrift\\Transport\\TCurlClient', 'closeCurlHandle'));
176
+ self::$curlHandle = curl_init();
177
+ curl_setopt(self::$curlHandle, CURLOPT_RETURNTRANSFER, true);
178
+ curl_setopt(self::$curlHandle, CURLOPT_BINARYTRANSFER, true);
179
+ curl_setopt(self::$curlHandle, CURLOPT_USERAGENT, 'PHP/TCurlClient');
180
+ curl_setopt(self::$curlHandle, CURLOPT_CUSTOMREQUEST, 'POST');
181
+ curl_setopt(self::$curlHandle, CURLOPT_FOLLOWLOCATION, true);
182
+ curl_setopt(self::$curlHandle, CURLOPT_MAXREDIRS, 1);
183
+ }
184
+ // God, PHP really has some esoteric ways of doing simple things.
185
+ $host = $this->host_.($this->port_ != 80 ? ':'.$this->port_ : '');
186
+ $fullUrl = $this->scheme_."://".$host.$this->uri_;
187
+
188
+ $headers = array('Accept: application/x-thrift',
189
+ 'Content-Type: application/x-thrift',
190
+ 'Content-Length: '.TStringFuncFactory::create()->strlen($this->request_));
191
+ curl_setopt(self::$curlHandle, CURLOPT_HTTPHEADER, $headers);
192
+
193
+ if ($this->timeout_ > 0) {
194
+ curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $this->timeout_);
195
+ }
196
+ curl_setopt(self::$curlHandle, CURLOPT_POSTFIELDS, $this->request_);
197
+ $this->request_ = '';
198
+
199
+ curl_setopt(self::$curlHandle, CURLOPT_URL, $fullUrl);
200
+ $this->response_ = curl_exec(self::$curlHandle);
201
+
202
+ // Connect failed?
203
+ if (!$this->response_) {
204
+ curl_close(self::$curlHandle);
205
+ self::$curlHandle = null;
206
+ $error = 'TCurlClient: Could not connect to '.$fullUrl;
207
+ throw new TTransportException($error, TTransportException::NOT_OPEN);
208
+ }
209
+ }
210
+
211
+ static function closeCurlHandle() {
212
+ try {
213
+ if (self::$curlHandle) {
214
+ curl_close(self::$curlHandle);
215
+ self::$curlHandle = null;
216
+ }
217
+ } catch (\Exception $x) {
218
+ error_log('There was an error closing the curl handle: ' . $x->getMessage());
219
+ }
220
+ }
221
+
222
+ }
app/code/local/Boxalino/CemSearch/Model/Advanced.php CHANGED
@@ -4,7 +4,7 @@
4
  * Created at: 06.06.14 11:45
5
  */
6
 
7
- require_once "Mage/CatalogSearch/Model/Advanced.php";
8
 
9
  /**
10
  *
@@ -12,7 +12,6 @@ require_once "Mage/CatalogSearch/Model/Advanced.php";
12
  * @package Mage_CatalogSearch
13
  * @author Szymon Nosal <szymon.nosal@codete.com>
14
  */
15
- //class Boxalino_CemSearch_Model_Advanced extends Mage_Core_Model_Abstract
16
  class Boxalino_CemSearch_Model_Advanced extends Mage_CatalogSearch_Model_Advanced
17
  {
18
  /**
@@ -72,21 +71,10 @@ class Boxalino_CemSearch_Model_Advanced extends Mage_CatalogSearch_Model_Advance
72
  } else {
73
  $rate = 1;
74
  }
75
- // if ($this->_getResource()->addRatedPriceFilter(
76
- // $this->getProductCollection(), $attribute, $value, $rate)
77
- // ) {
78
- // $hasConditions = true;
79
- // $this->_addSearchCriteria($attribute, $value);
80
- // }
81
  $this->_addSearchCriteria($attribute, $value);
82
  }
83
  } else if ($attribute->isIndexable()) {
84
  if (!is_string($value) || strlen($value) != 0) {
85
- // if ($this->_getResource()->addIndexableAttributeModifiedFilter(
86
- // $this->getProductCollection(), $attribute, $value)) {
87
- // $hasConditions = true;
88
- // $this->_addSearchCriteria($attribute, $value);
89
- // }
90
  $this->_addSearchCriteria($attribute, $value);
91
  }
92
  } else {
@@ -96,17 +84,8 @@ class Boxalino_CemSearch_Model_Advanced extends Mage_CatalogSearch_Model_Advance
96
  }
97
 
98
  $this->_addSearchCriteria($attribute, $value);
99
-
100
- // $table = $attribute->getBackend()->getTable();
101
- // if ($attribute->getBackendType() == 'static'){
102
- // $attributeId = $attribute->getAttributeCode();
103
- // } else {
104
- // $attributeId = $attribute->getId();
105
- // }
106
- // $allConditions[$table][$attributeId] = $condition;
107
  }
108
  }
109
- // $allConditions = array();
110
  //Add id from boxalino
111
  $this->getProductCollection()->addIdFromBoxalino($ids);
112
  if ($allConditions) {
4
  * Created at: 06.06.14 11:45
5
  */
6
 
7
+ require_once 'Mage/CatalogSearch/Model/Advanced.php';
8
 
9
  /**
10
  *
12
  * @package Mage_CatalogSearch
13
  * @author Szymon Nosal <szymon.nosal@codete.com>
14
  */
 
15
  class Boxalino_CemSearch_Model_Advanced extends Mage_CatalogSearch_Model_Advanced
16
  {
17
  /**
71
  } else {
72
  $rate = 1;
73
  }
 
 
 
 
 
 
74
  $this->_addSearchCriteria($attribute, $value);
75
  }
76
  } else if ($attribute->isIndexable()) {
77
  if (!is_string($value) || strlen($value) != 0) {
 
 
 
 
 
78
  $this->_addSearchCriteria($attribute, $value);
79
  }
80
  } else {
84
  }
85
 
86
  $this->_addSearchCriteria($attribute, $value);
 
 
 
 
 
 
 
 
87
  }
88
  }
 
89
  //Add id from boxalino
90
  $this->getProductCollection()->addIdFromBoxalino($ids);
91
  if ($allConditions) {
app/code/local/Boxalino/CemSearch/Model/Resource/Fulltext.php CHANGED
@@ -112,8 +112,6 @@ class Boxalino_CemSearch_Model_Resource_Fulltext extends Mage_CatalogSearch_Mode
112
  array(),
113
  Varien_Db_Adapter_Interface::INSERT_ON_DUPLICATE);
114
  $adapter->query($sql, $bind);
115
-
116
- //$query->setIsProcessed(1);
117
  }
118
 
119
 
112
  array(),
113
  Varien_Db_Adapter_Interface::INSERT_ON_DUPLICATE);
114
  $adapter->query($sql, $bind);
 
 
115
  }
116
 
117
 
app/code/local/Boxalino/CemSearch/controllers/AdvancedController.php CHANGED
@@ -83,7 +83,7 @@ class Boxalino_CemSearch_AdvancedController extends Mage_CatalogSearch_AdvancedC
83
  $p13nSort,
84
  0, $limit
85
  );
86
- ## ADD FILTERS
87
 
88
  $skip = array('name');
89
 
@@ -116,7 +116,6 @@ class Boxalino_CemSearch_AdvancedController extends Mage_CatalogSearch_AdvancedC
116
 
117
  foreach ($criteria as $criterium) {
118
 
119
- // $name = strtolower($criterium['name']);
120
  $name = Mage::helper("Boxalino_CemSearch")->sanitizeFieldName($queryAttribute[$criterium['name']]);
121
 
122
  if (in_array($name, $skip)) {
83
  $p13nSort,
84
  0, $limit
85
  );
86
+ //add filters
87
 
88
  $skip = array('name');
89
 
116
 
117
  foreach ($criteria as $criterium) {
118
 
 
119
  $name = Mage::helper("Boxalino_CemSearch")->sanitizeFieldName($queryAttribute[$criterium['name']]);
120
 
121
  if (in_array($name, $skip)) {
app/code/local/Boxalino/Exporter/Helper/Data.php CHANGED
@@ -4,19 +4,9 @@ class Boxalino_Exporter_Helper_Data extends Mage_Core_Helper_Data
4
  {
5
  const URL_XML = 'http://di1.bx-cloud.com/frontend/dbmind/en/dbmind/api/data/source/update';
6
  const URL_XML_DEV = 'http://di1.bx-cloud.com/frontend/dbmind/_/en/dbmind/api/data/source/update';
7
- const URL_ZIP = "http://di1.bx-cloud.com/frontend/dbmind/en/dbmind/api/data/push";
8
- const URL_ZIP_DEV = "http://di1.bx-cloud.com/frontend/dbmind/_/en/dbmind/api/data/push";
9
- /**
10
- * Array of parent_id for specified products.
11
- * IMPORTANT: We assume that every simple product has at most one configurable parent.
12
- *
13
- * @var null
14
- */
15
- /**
16
- * Array of variants ids for specified products.
17
- *
18
- * @var null
19
- */
20
  public $XML_DELIMITER = ',';
21
  public $XML_ENCLOSURE = '"';
22
  public $XML_ENCLOSURE_TEXT = "&quot;"; // it's $XML_ENCLOSURE
@@ -27,23 +17,16 @@ class Boxalino_Exporter_Helper_Data extends Mage_Core_Helper_Data
27
  protected $_attributesWithIds = array();
28
  protected $_allTags = array();
29
  protected $_countries = array();
30
-
31
- public function defaultAttributes()
32
- {
33
- $attributes = array(
34
- 'entity_id',
35
- 'name',
36
- 'description',
37
- 'short_description',
38
- 'sku',
39
- 'price',
40
- 'special_price',
41
- 'visibility',
42
- 'category_ids',
43
- );
44
-
45
- return $attributes;
46
- }
47
 
48
  /**
49
  * @param $language
@@ -51,21 +34,9 @@ class Boxalino_Exporter_Helper_Data extends Mage_Core_Helper_Data
51
  */
52
  public function isAvailableLanguages($language)
53
  {
54
- $languages = array(
55
- 'en',
56
- 'fr',
57
- 'de',
58
- 'it',
59
- 'es',
60
- 'zh',
61
- 'cz',
62
- 'ru',
63
- );
64
-
65
- if (array_search($language, $languages) !== false) {
66
  return true;
67
  }
68
-
69
  return false;
70
  }
71
 
@@ -145,11 +116,73 @@ class Boxalino_Exporter_Helper_Data extends Mage_Core_Helper_Data
145
 
146
  public function getCountry($countryCode)
147
  {
 
148
  if(!isset($this->_countries[$countryCode])) {
149
- $this->_countries[$countryCode] = Mage::getSingleton('directory/country')->loadByCode($countryCode);
 
150
  }
151
 
152
  return $this->_countries[$countryCode];
153
  }
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  }
4
  {
5
  const URL_XML = 'http://di1.bx-cloud.com/frontend/dbmind/en/dbmind/api/data/source/update';
6
  const URL_XML_DEV = 'http://di1.bx-cloud.com/frontend/dbmind/_/en/dbmind/api/data/source/update';
7
+ const URL_ZIP = 'http://di1.bx-cloud.com/frontend/dbmind/en/dbmind/api/data/push';
8
+ const URL_ZIP_DEV = 'http://di1.bx-cloud.com/frontend/dbmind/_/en/dbmind/api/data/push';
9
+
 
 
 
 
 
 
 
 
 
 
10
  public $XML_DELIMITER = ',';
11
  public $XML_ENCLOSURE = '"';
12
  public $XML_ENCLOSURE_TEXT = "&quot;"; // it's $XML_ENCLOSURE
17
  protected $_attributesWithIds = array();
18
  protected $_allTags = array();
19
  protected $_countries = array();
20
+ protected $_languages = array(
21
+ 'en',
22
+ 'fr',
23
+ 'de',
24
+ 'it',
25
+ 'es',
26
+ 'zh',
27
+ 'cz',
28
+ 'ru',
29
+ );
 
 
 
 
 
 
 
30
 
31
  /**
32
  * @param $language
34
  */
35
  public function isAvailableLanguages($language)
36
  {
37
+ if (array_search($language, $this->_languages) !== false) {
 
 
 
 
 
 
 
 
 
 
 
38
  return true;
39
  }
 
40
  return false;
41
  }
42
 
116
 
117
  public function getCountry($countryCode)
118
  {
119
+
120
  if(!isset($this->_countries[$countryCode])) {
121
+ $country = Mage::getModel('directory/country')->loadByCode($countryCode);
122
+ $this->_countries[$countryCode] = $country;
123
  }
124
 
125
  return $this->_countries[$countryCode];
126
  }
127
 
128
+ /**
129
+ * Modifies a string to remove all non ASCII characters and spaces.
130
+ */
131
+ public function sanitizeFieldName($text)
132
+ {
133
+
134
+ $maxLength = 50;
135
+ $delimiter = "_";
136
+
137
+ // replace non letter or digits by -
138
+ $text = preg_replace('~[^\\pL\d]+~u', $delimiter, $text);
139
+
140
+ // trim
141
+ $text = trim($text, $delimiter);
142
+
143
+ // transliterate
144
+ if (function_exists('iconv'))
145
+ {
146
+ $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);
147
+ }
148
+
149
+ // lowercase
150
+ $text = strtolower($text);
151
+
152
+ // remove unwanted characters
153
+ $text = preg_replace('~[^_\w]+~', '', $text);
154
+
155
+ if (empty($text))
156
+ {
157
+ return null;
158
+ }
159
+
160
+ // max $maxLength (50) chars
161
+ $text = substr($text, 0, $maxLength);
162
+ $text = trim($text, $delimiter);
163
+
164
+ return $text;
165
+ }
166
+
167
+ public function escapeString($string)
168
+ {
169
+ return htmlspecialchars(trim(preg_replace('/\s+/', ' ', $string)));
170
+ }
171
+
172
+ public function delTree($dir)
173
+ {
174
+ if(!file_exists($dir)){
175
+ return;
176
+ }
177
+ $files = array_diff(scandir($dir), array('.','..'));
178
+ foreach ($files as $file) {
179
+ if(is_dir("$dir/$file")){
180
+ self::delTree("$dir/$file");
181
+ } else if(file_exists("$dir/$file")){
182
+ @unlink("$dir/$file");
183
+ }
184
+ }
185
+ return rmdir($dir);
186
+ }
187
+
188
  }
app/code/local/Boxalino/Exporter/Model/Mysql4/Exporter/Delta.php CHANGED
@@ -3,6 +3,7 @@
3
  class Boxalino_Exporter_Model_Mysql4_Exporter_Delta extends Boxalino_Exporter_Model_Mysql4_Indexer
4
  {
5
  const INDEX_TYPE = 'delta';
 
6
  /** @var date Date of last data sync */
7
  protected $_lastIndex = 0;
8
 
@@ -53,36 +54,6 @@ class Boxalino_Exporter_Model_Mysql4_Exporter_Delta extends Boxalino_Exporter_Mo
53
  $this->_lastIndex = $date;
54
  }
55
 
56
- /**
57
- * @description Get all transactions from Magento
58
- * @return object All transactions for store
59
- */
60
- protected function _getTransactions()
61
- {
62
- $transaction = Mage::getModel('sales/order')->setStoreId($this->_storeId)->getCollection()->addAttributeToFilter('updated_at', array('from' => $this->_getLastIndex(), 'date' => true))->addAttributeToSelect('*');
63
- return $transaction;
64
- }
65
-
66
- /**
67
- * @description Get all customers from Magento
68
- * @return object All customers
69
- */
70
- protected function _getCustomers()
71
- {
72
- $customers = Mage::getModel('customer/customer')->getCollection()->addAttributeToFilter('updated_at', array('from' => $this->_getLastIndex(), 'date' => true))->addAttributeToSelect('*');
73
- return $customers;
74
- }
75
-
76
- /**
77
- * @description Get list of all categories
78
- * @return object All categories for Store
79
- */
80
- protected function _getCategories()
81
- {
82
- $categories = Mage::getModel('catalog/category')->setStoreId($this->_storeId)->getCollection()->addAttributeToSelect('*');
83
- return $categories;
84
- }
85
-
86
  /**
87
  * @description Get list of products with their tags
88
  * @return object List of products with their tags
@@ -97,22 +68,4 @@ class Boxalino_Exporter_Model_Mysql4_Exporter_Delta extends Boxalino_Exporter_Mo
97
  }
98
  return $this->_allProductTags;
99
  }
100
-
101
- /**
102
- * @description Get products for store by storeId
103
- * @return object All products of magento for store
104
- */
105
- protected function _getStoreProducts()
106
- {
107
- $products = Mage::getModel('catalog/product')->setStoreId($this->_storeId)->getCollection()->addAttributeToFilter('updated_at', array('from' => $this->_getLastIndex(), 'date' => true))->addAttributeToSelect($this->_listOfAttributes);
108
- return $products;
109
- }
110
-
111
- /**
112
- * @return string Index type
113
- */
114
- protected function _getIndexType()
115
- {
116
- return self::INDEX_TYPE;
117
- }
118
  }
3
  class Boxalino_Exporter_Model_Mysql4_Exporter_Delta extends Boxalino_Exporter_Model_Mysql4_Indexer
4
  {
5
  const INDEX_TYPE = 'delta';
6
+
7
  /** @var date Date of last data sync */
8
  protected $_lastIndex = 0;
9
 
54
  $this->_lastIndex = $date;
55
  }
56
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  /**
58
  * @description Get list of products with their tags
59
  * @return object List of products with their tags
68
  }
69
  return $this->_allProductTags;
70
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
app/code/local/Boxalino/Exporter/Model/Mysql4/Exporter/Indexer.php CHANGED
@@ -13,58 +13,4 @@ class Boxalino_Exporter_Model_Mysql4_Exporter_Indexer extends Boxalino_Exporter_
13
  $this->_init('boxalinoexporter/indexer', '');
14
  }
15
 
16
- protected function _prepareFiles($website,&$categories = null, &$tags = null)
17
- {
18
- }
19
-
20
- /**
21
- * @description Get all transactions from Magento
22
- * @return object All transactions for store
23
- */
24
- protected function _getTransactions()
25
- {
26
- // $transaction = Mage::getModel('sales/order')->setStoreId($this->_storeId)->getCollection()->addAttributeToSelect('*');
27
- //
28
- // return $transaction;
29
- }
30
-
31
- /**
32
- * @description Get all customers from Magento
33
- * @return object All customers
34
- */
35
- protected function _getCustomers()
36
- {
37
- // $customers = Mage::getModel('customer/customer')->getCollection()->addAttributeToSelect('*');
38
- //
39
- // return $customers;
40
- }
41
-
42
- /**
43
- * @description Get list of all categories
44
- * @return object All categories for Store
45
- */
46
- protected function _getCategories()
47
- {
48
- $categories = Mage::getModel('catalog/category')->setStoreId($this->_storeId)->getCollection()->addAttributeToSelect('*');
49
-
50
- return $categories;
51
- }
52
-
53
- /**
54
- * @description Get products for store by storeId
55
- * @return object All products of magento for store
56
- */
57
- protected function _getStoreProducts()
58
- {
59
- // $products = Mage::getModel('catalog/product')->setStoreId($this->_storeId)->getCollection()->addAttributeToSelect($this->_listOfAttributes);
60
- // return $products;
61
- }
62
-
63
- /**
64
- * @return string Index type
65
- */
66
- protected function _getIndexType()
67
- {
68
- return self::INDEX_TYPE;
69
- }
70
  }
13
  $this->_init('boxalinoexporter/indexer', '');
14
  }
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
app/code/local/Boxalino/Exporter/Model/Mysql4/Indexer.php CHANGED
@@ -1,7 +1,5 @@
1
  <?php
2
 
3
- //ini_set('memory_limit', '-1');
4
-
5
  abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_Mysql4_Abstract
6
  {
7
  /** @var array Configuration for each Store View */
@@ -33,8 +31,6 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
33
 
34
  protected $_attributesValuesByName = array();
35
 
36
- protected $_tmp = array();
37
-
38
  protected $_files = array();
39
 
40
  protected $_count = 0;
@@ -51,19 +47,16 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
51
  protected $_helperExporter = null;
52
  protected $_helperSearch = null;
53
 
54
- private $_parentId = null;
55
- private $_simpleIds = null;
56
- private $_isLoad = false;
57
- private $logger = null;
58
 
59
  /**
60
- * @description Start of apocalypse
61
  */
62
  public function reindexAll()
63
  {
64
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Indexer init'));
65
  $this->_websiteExport();
66
- $this->_closeExport();
67
  return $this;
68
  }
69
 
@@ -74,12 +67,12 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
74
  protected function _websiteExport()
75
  {
76
  $this->_helperExporter = Mage::helper('boxalinoexporter');
77
- $this->_helperSearch = Mage::helper("Boxalino_CemSearch");
78
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Helpers init'));
79
  foreach (Mage::app()->getWebsites() as $website) {
80
 
81
- $this->delTree($this->_dir);
82
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'After delTree'));
83
 
84
  if (!$this->_isEnabled()) {
85
  continue;
@@ -87,27 +80,24 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
87
 
88
  $data = $this->_storeExport($website);
89
 
90
- // if ($this->_getIndexType() == 'delta' && count($data['products']) == 0 && count($data['customers']) == 0 && count($data['transactions']) == 0) {
91
- // continue;
92
- // }
93
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'something with attributes - before'));
94
 
95
- foreach($this->_listOfAttributes as $k => $attr){
96
- if(
97
  !isset($this->_attributesValuesByName[$attr]) ||
98
  (isset($this->_attrProdCount[$attr]) &&
99
- $this->_attrProdCount[$attr])
100
- ){
101
  continue;
102
- } else{
103
  unset($this->_attributesValuesByName[$attr]);
104
  unset($this->_listOfAttributes[$k]);
105
  }
106
  }
107
 
108
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'something with attributes - after'));
109
  $file = $this->prepareFiles($website, $data['categories'], $data['tags']);
110
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Push files'));
111
 
112
  $this->pushXML($file);
113
  $this->pushZip($file);
@@ -117,7 +107,6 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
117
  $this->_transformedProducts = array();
118
  $this->_categoryParent = array();
119
  $this->_availableLanguages = array();
120
- $this->_tmp = array();
121
  $this->_attrProdCount = array();
122
  $this->_count = 0;
123
 
@@ -133,24 +122,22 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
133
  {
134
  $products = array();
135
  $categories = array();
136
- // $customers = array();
137
  $tags = array();
138
- // $transactions = array();
139
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Preparing data for website start'));
140
  foreach ($website->getGroups() as $group) {
141
 
142
  $this->group = $group;
143
 
144
  foreach ($group->getStores() as $store) {
145
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Start store:'.$store->getId()));
146
  $this->_prepareStoreConfig($store->getId());
147
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Configuration for store loaded'));
148
  if ($this->_isEnabled()) {
149
  $categories = $this->_exportCategories();
150
  $tags = $this->_exportTags();
151
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Without available languages'));
152
  $this->_availableLanguages[] = $this->_storeConfig['language'];
153
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'With available languages'));
154
 
155
  }
156
  }
@@ -158,13 +145,12 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
158
  if ($this->_isEnabled()) {
159
  $this->_exportCustomers();
160
  $this->_exportTransactions();
161
- $products = $this->_exportProducts();
162
  }
163
 
164
  }
165
 
166
  return array(
167
- 'products' => $products,
168
  'categories' => $categories,
169
  'tags' => $tags,
170
  );
@@ -196,11 +182,21 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
196
  */
197
  protected function _mergeAllAttributes()
198
  {
199
- $this->_listOfAttributes = $this->_helperExporter->defaultAttributes();
 
 
 
 
 
 
 
 
 
 
200
 
201
  $attributes = array();
202
 
203
- foreach(Mage::getResourceModel('catalog/product_attribute_collection')->getItems() as $at){
204
  $attributes[] = $at->getAttributeCode();
205
  }
206
 
@@ -208,11 +204,11 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
208
  $fields = explode(',', $this->_storeConfig['additional_attributes']);
209
  foreach ($fields as $field) {
210
 
211
- if(!in_array($field, $attributes)){
212
- Mage::throwException("Attribute \"$field\" not exist!" );
213
  }
214
 
215
- if($field != null && strlen($field) > 0){
216
  $this->_listOfAttributes[] = $field;
217
  }
218
 
@@ -234,7 +230,7 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
234
  $options = Mage::getModel('eav/config')->getAttribute('catalog_product', $attribute)->setStoreId($this->_storeId)->getSource()->getAllOptions();
235
  foreach ($options as $option) {
236
  if (!empty($option['value'])) {
237
- $this->_attributesValues[$this->_storeId][$attribute][$option['value']] = $this->escapeString($option['label']);
238
 
239
  $value = intval($option['value']);
240
  $name = 'value_' . $this->_storeConfig['language'];
@@ -243,15 +239,15 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
243
 
244
  if (isset($this->_attributesValuesByName[$attribute][$value])) {
245
  $this->_attributesValuesByName[$attribute][$value][$name] = /*strtolower*/
246
- $this->escapeString($option['label']);
247
  } else {
248
  $this->_attributesValuesByName[$attribute][$value] = array($attribute . '_id' => $value, $name => /*strtolower*/
249
- $this->escapeString($option['label']));
250
  }
251
 
252
  } else {
253
  $this->_attributesValuesByName[$attribute] = array($value => array($attribute . '_id' => $value, $name => /*strtolower*/
254
- $this->escapeString($option['label'])));
255
  }
256
 
257
  }
@@ -270,7 +266,7 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
270
  {
271
  if (isset($this->_storeConfig['enabled']) && $this->_storeConfig['enabled']) {
272
  return true;
273
- } else if(!isset($this->_storeConfig['enabled']) && Mage::getStoreConfig('Boxalino_General/general/enabled')){
274
  return true;
275
  }
276
 
@@ -279,14 +275,14 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
279
 
280
  /**
281
  * @description Preparing categories to export
282
- * @return array Cateroies
283
  */
284
  protected function _exportCategories()
285
  {
286
  if ($this->_storeConfig['export_categories']) {
287
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Categories are not loaded'));
288
  $categories = $this->_getCategories();
289
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Categories are loaded'));
290
  foreach ($categories as $category) {
291
 
292
  if ($category->getParentId() == null) {
@@ -294,26 +290,31 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
294
  }
295
 
296
  if (isset($this->_transformedCategories[$category->getId()])) {
297
- $this->_transformedCategories[$category->getId()]['value_' . $this->_storeConfig['language']] = $this->escapeString($category->getName());
298
  } else {
299
  $parentId = null;
300
  if ($category->getParentId() != 0) {
301
  $parentId = $category->getParentId();
302
  }
303
- $this->_transformedCategories[$category->getId()] = array('category_id' => $category->getId(), 'parent_id' => $parentId, 'value_' . $this->_storeConfig['language'] => $this->escapeString($category->getName()));
304
  }
305
  }
306
- $categories = null;;
307
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Categories are returned for data saving'));
308
  return $this->_transformedCategories;
309
  }
310
-
311
-
312
  return null;
313
-
314
  }
315
 
316
- abstract protected function _getCategories();
 
 
 
 
 
 
 
 
317
 
318
  /**
319
  * @description Preparing tags to export
@@ -324,9 +325,9 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
324
  {
325
 
326
  if ($this->_storeConfig['export_tags']) {
327
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Tags are not loaded'));
328
  $tags = $this->_helperExporter->getAllTags();
329
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Tags are loaded'));
330
 
331
  foreach ($tags as $id => $tag) {
332
  if (isset($this->_transformedTags[$id])) {
@@ -337,7 +338,7 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
337
  }
338
 
339
  $tags = null;
340
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Tags are returned for data saving'));
341
  return $this->_transformedTags;
342
  }
343
 
@@ -346,53 +347,48 @@ abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_My
346
 
347
  /**
348
  * @description Preparing products to export
349
- * @return array Products
350
  */
351
  protected function _exportProducts()
352
  {
353
-
354
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - start of export'));
355
  $attrs = $this->_listOfAttributes;
356
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get info about attributes - before'));
357
- $query = "
358
- SELECT `main_table`.`attribute_id`, `main_table`.`entity_type_id`, `main_table`.`attribute_code`, `main_table`.`attribute_model`, `main_table`.`backend_model`, `main_table`.`backend_type`, `main_table`.`backend_table`, `main_table`.`frontend_input`, `main_table`.`source_model`, `additional_table`.`is_global`, `additional_table`.`is_html_allowed_on_front`, `additional_table`.`is_wysiwyg_enabled` FROM `eav_attribute` AS `main_table`
359
- INNER JOIN `catalog_eav_attribute` AS `additional_table` ON additional_table.attribute_id = main_table.attribute_id WHERE (main_table.entity_type_id = 4) AND (attribute_code IN('" .
360
- implode('\',\'', $this->_listOfAttributes) .
361
- "'))
362
- ";
363
-
364
- $config = Mage::getConfig()->getResourceConnectionConfig("default_setup");
365
-
366
- $dbinfo = array('host' => $config->host,
367
- 'user' => $config->username,
368
- 'pass' => $config->password,
369
- 'dbname' => $config->dbname
370
- );
371
- unset($config);
 
 
 
 
372
 
373
- $pdo = new PDO('mysql:host=' . $dbinfo['host'] .';dbname=' . $dbinfo['dbname'], $dbinfo['user'], $dbinfo['pass']);
374
-
375
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - connected to DB'));
376
- $readConnection = $pdo->prepare($query);
377
- $readConnection->execute();
378
- $results = $readConnection->fetchAll();
379
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get info about attributes - after'));
380
- $attrFDB = array();
381
  $attrsFromDb = array(
382
- "int" => array(),
383
- "varchar" => array(),
384
- "text" => array(),
385
- "decimal" => array(),
386
  );
387
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - attributes preparing'));
388
- foreach($results as $r){
389
  $type = $r['backend_type'];
390
- if(isset($attrsFromDb[$type])){
391
  $attrsFromDb[$type][] = $r['attribute_id'];
392
- $attrFDB[$r['attribute_id']] = $r['attribute_code'];
393
  }
394
  }
395
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - attributes preparing done'));
 
396
  $countMax = $this->_storeConfig['maximum_population'];
397
  $localeCount = 0;
398
 
@@ -401,241 +397,302 @@ SELECT `main_table`.`attribute_id`, `main_table`.`entity_type_id`, `main_table`.
401
  $page = 1;
402
  $header = true;
403
 
404
- while($count >= $limit){
405
-
406
 
407
- if ($countMax > 0 && $this->_count >= $countMax) {
408
- break;
409
- }
410
 
411
- foreach ($this->group->getStores() as $store) {
412
 
413
- $storeId = $store->getId();
 
 
 
 
414
 
415
- $lang = Mage::app()->getStore($store->getId())->getConfig('boxalinoexporter/export_data/language');
416
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - fetch products - before'));
417
- $query = "SELECT `e`.* FROM `catalog_product_entity` AS `e` LIMIT $limit OFFSET " . (($page-1) * $limit);
418
- $readConnection = $pdo->prepare($query);
419
- $readConnection->execute();
420
- $results = $readConnection->fetchAll();
421
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - fetch products - after'));
422
 
423
- $products = array();
424
- $ids = "";
425
- foreach($results as $r){
426
- $products[$r['entity_id']] = $r;
427
- $ids .= $r['entity_id'] . ',';
428
- $products[$r['entity_id']]['website'] = array();
429
- $products[$r['entity_id']]['categories'] = array();
430
- }
431
 
432
- $count = count($results);
 
 
433
 
434
- $results = null;
435
- $readConnection = null;
436
 
437
- $ids = substr($ids, 0, -1);
438
- $query = "
439
- SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`, `t_s`.`value` AS `store_value`, IF(t_s.value_id IS NULL, t_d.value, t_s.value) AS `value` FROM `catalog_product_entity_varchar` AS `t_d`
440
- LEFT JOIN `catalog_product_entity_varchar` AS `t_s` ON t_s.attribute_id = t_d.attribute_id AND t_s.entity_id = t_d.entity_id AND t_s.store_id = $storeId WHERE (t_d.entity_type_id = 4) AND (t_d.entity_id IN (" . $ids . ")) AND (t_d.attribute_id IN ('" . implode('\',\'', $attrsFromDb['varchar']) . "')) AND (t_d.store_id = 0) UNION ALL SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`, `t_s`.`value` AS `store_value`, IF(t_s.value_id IS NULL, t_d.value, t_s.value) AS `value` FROM `catalog_product_entity_text` AS `t_d`
441
- LEFT JOIN `catalog_product_entity_text` AS `t_s` ON t_s.attribute_id = t_d.attribute_id AND t_s.entity_id = t_d.entity_id AND t_s.store_id = $storeId WHERE (t_d.entity_type_id = 4) AND (t_d.entity_id IN (" . $ids . ")) AND (t_d.attribute_id IN ('" . implode('\',\'', $attrsFromDb['text']) . "')) AND (t_d.store_id = 0) UNION ALL SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`, `t_s`.`value` AS `store_value`, IF(t_s.value_id IS NULL, t_d.value, t_s.value) AS `value` FROM `catalog_product_entity_decimal` AS `t_d`
442
- LEFT JOIN `catalog_product_entity_decimal` AS `t_s` ON t_s.attribute_id = t_d.attribute_id AND t_s.entity_id = t_d.entity_id AND t_s.store_id = $storeId WHERE (t_d.entity_type_id = 4) AND (t_d.entity_id IN (" . $ids . ")) AND (t_d.attribute_id IN ('" . implode('\',\'', $attrsFromDb['decimal']) . "')) AND (t_d.store_id = 0) UNION ALL SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`, `t_s`.`value` AS `store_value`, IF(t_s.value_id IS NULL, t_d.value, t_s.value) AS `value` FROM `catalog_product_entity_int` AS `t_d`
443
- LEFT JOIN `catalog_product_entity_int` AS `t_s` ON t_s.attribute_id = t_d.attribute_id AND t_s.entity_id = t_d.entity_id AND t_s.store_id = $storeId WHERE (t_d.entity_type_id = 4) AND (t_d.entity_id IN (" . $ids . ")) AND (t_d.attribute_id IN ('" . implode('\',\'', $attrsFromDb['int']) . "')) AND (t_d.store_id = 0)
444
- ";
445
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get attributes - before'));
446
- $readConnection = $pdo->prepare($query);
447
- $readConnection->execute();
448
- $results = $readConnection->fetchAll();
449
 
450
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get attributes - after'));
451
- foreach($results as $r){
452
 
453
- $products[$r['entity_id']][$attrFDB[$r['attribute_id']]] = $r['value'];
454
 
455
- }
 
456
 
457
- $results = null;
458
- $readConnection = null;
 
 
459
 
460
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get stock - before'));
461
- $query = "SELECT `cataloginventory_stock_status`.`product_id`, `cataloginventory_stock_status`.`stock_status` FROM `cataloginventory_stock_status` WHERE (product_id IN(" . $ids .")) AND (stock_id=1) AND (website_id=1)";
462
 
463
- $readConnection = $pdo->prepare($query);
464
- $readConnection->execute();
465
- $results = $readConnection->fetchAll();
466
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get stock - after'));
467
 
 
 
 
 
 
 
468
 
469
- foreach($results as $r){
470
 
471
- $products[$r['product_id']]['stock_status'] = $r['stock_status'];
472
 
 
 
 
 
 
 
 
 
 
473
  }
474
 
475
- $results = null;
476
- $readConnection = null;
477
-
478
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get products from website - before'));
479
- $query = "SELECT `catalog_product_website`.* FROM `catalog_product_website` WHERE (product_id IN (" . $ids ."))";
480
-
481
- $readConnection = $pdo->prepare($query);
482
- $readConnection->execute();
483
- $results = $readConnection->fetchAll();
484
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get products from website - after'));
485
-
486
- foreach($results as $r){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  $products[$r['product_id']]['website'][] = $r['website_id'];
489
-
490
  }
491
-
492
- $results = null;
493
- $readConnection = null;
494
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get products connections - before'));
495
-
496
- $query = "select * from catalog_product_super_link WHERE (product_id IN (" . $ids ."))";
497
- $readConnection = $pdo->prepare($query);
498
- $readConnection->execute();
499
- $results = $readConnection->fetchAll();
500
-
501
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get products connections - after'));
502
- foreach($results as $r){
503
-
504
  $products[$r['product_id']]['parent_id'] = $r['parent_id'];
505
-
506
  }
507
-
508
- $results = null;
509
- $readConnection = null;
510
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get categories - before'));
511
-
512
- $query = "select * from catalog_category_product WHERE (product_id IN (" . $ids ."))";
513
- $readConnection = $pdo->prepare($query);
514
- $readConnection->execute();
515
- $results = $readConnection->fetchAll();
516
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - get categories - after'));
517
-
518
- foreach($results as $r){
519
-
 
520
  $products[$r['product_id']]['categories'][] = $r['category_id'];
521
-
522
  }
 
 
523
 
524
- foreach ($products as $pr) {
525
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - start transform'));
526
-
527
- $product = new stdClass();
528
- foreach ($pr as $key => $value)
529
- {
530
- $product->$key = $value;
531
- }
532
 
533
- $pr = null;
534
-
535
- if (count($product->website) == 0) {
536
-
537
- $products = null;
538
  continue;
539
  }
540
 
541
- $id = $product->entity_id;
542
 
543
  $productParam = array();
544
  $haveParent = false;
545
 
546
- if ($this->getParentId($id) != null && $product->type_id == 'simple') {
547
- $id = $this->getParentId($id);
548
  $haveParent = true;
549
- } else if ($product->visibility == 1 && $this->getParentId($id) == null) {
550
  $product = null;
551
  continue;
552
  }
553
 
554
  foreach ($attrs as $attr) {
555
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - start attributes transform'));
556
 
557
  if (isset($this->_attributesValuesByName[$attr])) {
558
 
559
- $val = $this->escapeString($this->getFromClass($product, $attr));
560
-
561
- $attr = $this->_helperSearch->sanitizeFieldName($attr);
562
-
563
  if ($val == null) {
564
  continue;
565
  }
566
 
 
 
567
  $this->_attrProdCount[$attr] = true;
568
 
569
- if (isset($this->_tmp[$attr][$id]) && in_array($val, $this->_tmp[$attr][$id])) {
570
- continue;
571
- }
 
 
572
 
573
- if (isset($this->_transformedProducts['productsMtM'][$attr])) {
574
- // If visibility is set everywhere (have value "4"), then we split it for value "2" and "3" (search and catalog separately)
575
- if ($attr == 'visibility' && $val == '4') {
576
- $this->_transformedProducts['productsMtM'][$attr][] = array(/*'id' => count($this->_transformedProducts['productsMtM'][$attr])+1,*/
577
- 0 => $id, 1 => '2');
578
- $this->_transformedProducts['productsMtM'][$attr][] = array(/*'id' => count($this->_transformedProducts['productsMtM'][$attr])+1,*/
579
- 0 => $id, 1 => '3');
580
- $this->_tmp[$attr][$id][] = $val;
581
- } else {
582
- $this->_transformedProducts['productsMtM'][$attr][] = array(/*'id' => count($this->_transformedProducts['productsMtM'][$attr])+1,*/
583
- 0 => $id, 1 => $val);
584
- $this->_tmp[$attr][$id][] = $val;
585
- }
586
  } else {
587
- $this->_transformedProducts['productsMtM'][$attr] = array();
588
- // If visibility is set everywhere (have value "4"), then we split it for value "2" and "3" (search and catalog separately)
589
- if ($attr == 'visibility' && $val == '4') {
590
- $this->_transformedProducts['productsMtM'][$attr][] = array(/*'id' => 1,*/
591
- 0 => $id, 1 => '2');
592
- $this->_transformedProducts['productsMtM'][$attr][] = array(/*'id' => 2,*/
593
- 0 => $id, 1 => '3');
594
- $this->_tmp[$attr][$id] = array($val);
595
- } else {
596
- $this->_transformedProducts['productsMtM'][$attr][] = array(/*'id' => 1,*/
597
- 0 => $id, 1 => $val);
598
- $this->_tmp[$attr][$id] = array($val);
599
- }
600
  }
601
 
 
 
 
602
  continue;
603
  }
604
 
605
-
606
  switch ($attr) {
 
 
607
  case 'description':
608
  case 'short_description':
609
  case 'name':
610
- $productParam[$attr . '_' . $lang] = $this->escapeString($this->getFromClass($product, $attr));
611
- break;
612
- case 'category_ids':
613
  break;
614
  default:
615
- $productParam[$attr] = $this->escapeString($this->getFromClass($product, $attr));
616
  break;
617
  }
618
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - end attributes transform'));
619
 
620
  }
621
 
622
  if ($haveParent) {
 
623
  continue;
624
  }
625
 
626
  if (!isset($this->_transformedProducts['products'][$id])) {
627
  if ($countMax > 0 && $this->_count >= $countMax) {
 
 
628
  break;
629
  }
630
  $productParam['entity_id'] = $id;
631
  $this->_transformedProducts['products'][$id] = $productParam;
632
 
633
  //Add categories
634
- if(isset($product->categories) && count($product->categories) > 0){
635
- foreach ($product->categories as $cat) {
636
 
637
  while ($cat != null) {
638
- $this->_transformedProducts['productsMtM']['categories'][] = array(0 => $id, 1 => $cat);
639
  if (isset($this->_transformedCategories[$cat]['parent_id'])) {
640
  $cat = $this->_transformedCategories[$cat]['parent_id'];
641
  } else {
@@ -649,55 +706,32 @@ SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`
649
 
650
  } elseif (isset($this->_transformedProducts['products'][$id])) {
651
  $this->_transformedProducts['products'][$id] = array_merge($this->_transformedProducts['products'][$id], $productParam);
652
-
653
  }
 
654
  $productParam = null;
655
  $product = null;
656
 
657
  ksort($this->_transformedProducts['products'][$id]);
658
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - end transform'));
659
 
660
  }
661
  }
662
 
663
- if(isset($this->_transformedProducts['products']) && count($this->_transformedProducts['products']) > 0){
664
 
665
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - validate names start'));
666
 
667
  $data = $this->_transformedProducts['products'];
668
 
669
- foreach ($this->_transformedProducts['productsMtM'] as $key => $val) {
670
-
671
- $dataMtM = $val;
672
-
673
- if($header){
674
-
675
- if($key == 'categories'){
676
- $dataMtM = array_merge(array(array("entity_id", "category_id")), $dataMtM);
677
- } else{
678
- $dataMtM = array_merge(array(array("entity_id", $key . "_id")), $dataMtM);
679
- }
680
- /** @TODO UNUSED! */
681
- $csvFiles[] = "product_" . $this->_helperSearch->sanitizeFieldName($key);
682
- }
683
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - validate names end'));
684
-
685
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - save to file with corrected name'));
686
- $this->savePartToCsv( "product_" . $this->_helperSearch->sanitizeFieldName($key) . '.csv' , $dataMtM);
687
- $this->_transformedProducts['productsMtM'][$key] = null;
688
- }
689
-
690
- if($header && count($data) > 0){
691
  $data = array_merge(array(array_keys(end($data))), $data);
692
  $header = false;
693
  }
694
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Products - save to file'));
695
  $this->savePartToCsv('products.csv', $data);
696
-
697
  $data = null;
698
-
699
  $this->_transformedProducts['products'] = array();
700
- $this->_transformedProducts['productsMtM'] = array();
701
 
702
  }
703
 
@@ -707,234 +741,420 @@ SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`
707
 
708
  }
709
 
 
 
 
710
  $this->_transformedProducts = null;
711
- $this->_parentId = null;
712
- $this->_simpleIds = null;
713
 
 
 
 
 
714
 
715
- return $this->_transformedProducts;
716
- }
717
 
718
- abstract protected function _getStoreProducts();
719
 
720
  /**
721
  * @description Preparing customers to export
722
- * @return array Customers
723
  *
724
  */
725
  protected function _exportCustomers()
726
  {
727
 
728
- if ($this->_storeConfig['export_customers']) {
729
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Customers - Countries are not loaded'));
730
- $collection = Mage::getModel('directory/country')->getCollection();
731
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Customers - Countries are loaded'));
732
 
733
- if ($this->_countries == null) {
734
- foreach ($collection as $country) {
735
- $this->_countries[$country->getId()] = $country->getName();
736
- }
 
 
 
737
  }
 
 
738
 
739
- $limit = $this->_storeConfig['export_chunk'];
740
- $count = $limit;
741
- $page = 1;
742
- $header = true;
743
-
744
- do{
745
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Customers - load page '.$page));
746
- $customers_to_save = array();
747
- $customers = Mage::getModel('customer/customer')
748
- ->getCollection()
749
- ->setPageSize($limit)
750
- ->setCurPage($page)
751
- ->addAttributeToSelect('*');
752
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Customers - loaded page '.$page));
753
-
754
- foreach ($customers as $customer) {
755
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Customers - Load billing address '));
756
- $billing = $customer->getPrimaryBillingAddress();
757
- if(!empty($billing)) {
758
- $countryCode = $billing->getCountry();
759
- }
760
 
761
- switch ($customer->getGender()) {
762
- case 1:
763
- $gender = 'male';
764
- break;
765
- case 2:
766
- $gender = 'female';
767
- break;
768
- default:
769
- $gender = null;
770
- break;
771
- }
772
 
773
- $customers_to_save[] = array(
774
- 'customer_id' => $customer->getId(),
775
- 'gender' => $gender,
776
- 'dob' => $customer->getDob(),
777
- 'country' => !empty($countryCode) ? $this->_helperExporter->getCountry($countryCode)->getName() : '',
778
- 'zip' => !empty($billing) ? $billing->getPostcode() : ''
779
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
780
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
  }
782
 
783
- $data = $customers_to_save;
 
 
 
784
 
785
- if($header){
786
- $data = array_merge(array(array_keys(end($customers_to_save))), $customers_to_save);
787
- $header = false;
 
 
 
 
 
788
  }
789
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Customers - save to file'));
790
- $this->savePartToCsv('customers.csv', $data);
791
 
792
- $count = count($customers_to_save);
793
- $page++;
 
 
 
 
 
794
 
795
- } while($count >= $limit);
796
- $customers = null;
797
- }
798
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Customers - end of exporting '));
799
- return null;
800
- }
 
 
 
 
 
 
 
 
 
 
 
 
801
 
802
- abstract protected function _getCustomers();
 
 
 
 
803
 
804
  /**
805
  * @description Preparing transactions to export
806
- * @return array Transaction
807
  */
808
  protected function _exportTransactions()
809
  {
810
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Transactions - start of export'));
811
- if ($this->_storeConfig['export_transactions']) {
812
-
813
- $limit = $this->_storeConfig['export_chunk'];
814
- $count = $limit;
815
- $page = 1;
816
- $header = true;
817
 
818
- while($count >= $limit){
819
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Transactions - load page '.$page));
820
 
821
- $transactions_to_save = array();
822
- $transactions = Mage::getModel('sales/order')
823
- // ->setStoreId($this->_storeId)
824
- ->getCollection()
825
- ->setPageSize($limit)
826
- ->setCurPage($page)
827
- ->addAttributeToSelect('*');
828
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Transactions - loaded page '.$page));
829
 
830
- foreach ($transactions as $transaction) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
831
 
832
- if ($transaction->getStatus() == 'canceled') {
833
- continue;
834
- }
835
 
836
- $configurable = array();
 
 
 
837
 
838
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Transactions - get all items - before'));
839
- $products = ($transaction->getAllItems());
840
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Transactions - get all items - after'));
 
841
 
842
- foreach ($products as $product) {
 
843
 
844
- //is configurable
845
- if ($product->getParentItemId() == null && $product->getProductType() != 'simple') {
846
- $configurable[$product->getId()] = $product;
847
- continue;
848
- }
849
 
850
- //is configurable - simple product
851
- if (intval($product->getPrice()) == 0) {
852
- if(isset($configurable[$product->getParentItemId()])){
853
- $pid = $configurable[$product->getParentItemId()];
854
- } else{
855
- $pid = Mage::getModel('catalog/product')->load($product->getParentItemId());
856
- }
857
- $product->setOriginalPrice($pid->getOriginalPrice());
858
- $product->setPrice($pid->getPrice());
859
- }
860
 
861
- $status = 0; // 0 - pending, 1 - confirmed, 2 - shipping
862
-
863
- if ($transaction->getUpdatedAt() != $transaction->getCreatedAt()) {
864
-
865
- switch ($transaction->getStatus()) {
866
- case 'canceled':
867
- continue;
868
- continue;
869
- break;
870
- case 'processing':
871
- $status = 1;
872
- break;
873
- case 'complete':
874
- $status = 2;
875
- break;
876
- }
877
- }
878
- $transactions_to_save[] = array(
879
- 'order_id' => $transaction->getId(),
880
- 'entity_id' => $product->getProductId(),
881
- 'customer_id' => $transaction->getCustomerId(),
882
- 'price' => $product->getOriginalPrice(),
883
- 'discounted_price' => $product->getPrice(),
884
- 'quantity' => $product->getQtyOrdered(),
885
- 'total_order_value' => ($transaction->getBaseSubtotal() + $transaction->getShippingAmount()),
886
- 'shipping_costs' => $transaction->getShippingAmount(),
887
- 'order_date' => $transaction->getCreatedAt(),
888
- 'confirmation_date' => $status == 1 ? $transaction->getUpdatedAt() : null,
889
- 'shipping_date' => $status == 2 ? $transaction->getUpdatedAt() : null,
890
- 'status' => $transaction->getStatus()
891
- );
892
  }
893
-
894
- $configurable = null;
895
- $products = null;
896
  }
897
 
898
- $data = $transactions_to_save;
899
- $count = count($transactions);
900
-
901
- if($header){
902
- $data = array_merge(array(array_keys(end($transactions_to_save))), $transactions_to_save);
903
- $header = false;
 
 
 
 
 
 
 
904
  }
905
 
906
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Transactions - save to file'));
907
- $this->savePartToCsv('transactions.csv', $data);
 
 
 
 
 
 
 
 
 
 
 
 
 
908
 
909
- $page++;
 
910
 
911
- $transactions = null;
 
912
 
 
 
913
  }
914
 
 
 
 
 
 
 
 
 
 
 
 
915
  }
916
 
917
- Boxalino_CemSearch_Model_Logger::saveMemoryTracking('info', 'Indexer', array('memory_usage' => memory_get_usage(true), 'method' => __METHOD__, 'description' => 'Transactions - end of export'));
918
- return null;
919
  }
920
 
921
- abstract protected function _getTransactions();
922
-
923
- abstract protected function _getIndexType();
 
 
 
 
924
 
925
  /**
926
  * @description Preparing files to send
927
  */
928
- protected function prepareFiles($website, &$categories = null, &$tags = null )
929
  {
930
 
931
  //Prepare attributes
932
  $csvFiles = array();
933
- if (!file_exists("/tmp/boxalino")) {
934
- mkdir("/tmp/boxalino");
935
  }
936
 
937
- //create csv
938
  //save attributes
939
  foreach ($this->_attributesValuesByName as $attrName => $attrValues) {
940
  $csvFiles[] = $this->createCsv($this->_helperSearch->sanitizeFieldName($attrName), $attrValues);
@@ -947,7 +1167,7 @@ SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`
947
  }
948
 
949
  //save tags
950
- if ($tags != null) {
951
  $csvFiles[] = $this->createCsv('tag', $tags);
952
 
953
  $loop = 1;
@@ -956,41 +1176,33 @@ SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`
956
  }
957
 
958
  $csvFiles[] = $this->createCsv('product_tag', $csvdata);
959
-
960
  }
961
-
962
- // csv done
963
 
964
  //Create name for file
965
  $exportFile = '/tmp/boxalino/' . $this->_storeConfig['di_username'];
966
-
967
  $csvFiles = array_filter($csvFiles);
968
 
969
  //Create xml
970
- $this->createXML($exportFile . '.xml');
971
 
972
  //Create zip
973
-
974
  $this->createZip($exportFile . '.zip', array_filter($this->_files), $exportFile . '.xml');
975
 
976
  return $exportFile;
977
-
978
- //
979
-
980
  }
981
 
982
  /**
983
  * @param $name
984
  * @param $data
985
- * @param $csv
986
  * @return string
987
  */
988
  protected function createCsv($name, &$data)
989
  {
990
  $file = $name . '.csv';
991
 
992
- if(!is_array($data) || count($data) == 0){
993
- Mage::getModel('adminhtml/session')->addWarning("Data for $file have wrong format or is empty. " . "[" . gettype($data) . "]");
994
  }
995
 
996
  $csvdata = array_merge(array(array_keys(end($data))), $data);
@@ -1005,8 +1217,6 @@ SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`
1005
  $this->_files[] = $file;
1006
 
1007
  return $file;
1008
-
1009
-
1010
  }
1011
 
1012
  /**
@@ -1026,7 +1236,7 @@ SELECT `t_d`.`entity_id`, `t_d`.`attribute_id`, `t_d`.`value` AS `default_value`
1026
  return $this->_allProductTags;
1027
  }
1028
 
1029
- protected function createXML($name)
1030
  {
1031
 
1032
  $xml = new SimpleXMLElement('<root/>');
@@ -1143,9 +1353,9 @@ XML;
1143
  $products->addAttribute('type', 'products');
1144
 
1145
  $sources = $products->addChild('sources');
 
1146
 
1147
  //product source
1148
- #########################################################################
1149
  $source = $sources->addChild('source');
1150
  $source->addAttribute('id', 'item_vals');
1151
  $source->addAttribute('type', 'item_data_file');
@@ -1154,20 +1364,16 @@ XML;
1154
  $source->addChild('itemIdColumn')->addAttribute('value', 'entity_id');
1155
 
1156
  $this->sxml_append_options($source);
1157
- #########################################################################
1158
 
1159
  $attrs = array_keys($this->_attributesValuesByName);
1160
- if ($this->_storeConfig['export_tags']) {
1161
  $attrs[] = 'tag';
1162
 
1163
  }
1164
 
1165
  foreach ($attrs as $attr) {
1166
 
1167
- // if(!array_key_exists($attr . '.csv', $this->_files)){
1168
- // continue;
1169
- // }
1170
-
1171
  $attr = $this->_helperSearch->sanitizeFieldName($attr);
1172
 
1173
  //attribute
@@ -1200,7 +1406,7 @@ XML;
1200
 
1201
  }
1202
 
1203
- ########################################################################
1204
  if ($this->_storeConfig['export_categories']) {
1205
  //categories
1206
  $sourceCategory = $sources->addChild('source');
@@ -1232,21 +1438,17 @@ XML;
1232
 
1233
  $this->sxml_append_options($source);
1234
  }
1235
- #########################################################################
1236
 
1237
  //property
1238
  $properties = $products->addChild('properties');
1239
- $props = $this->prepareProperties();
1240
 
1241
  foreach ($props as $prop) {
1242
  if ($prop['id'] == 'entity_id') {
1243
 
1244
  }
1245
 
1246
- // if($prop['type'] == 'reference' && !array_key_exists($prop['name'], $this->_files)){
1247
- // continue;
1248
- // }
1249
-
1250
  $property = $properties->addChild('property');
1251
  $property->addAttribute('id', $this->_helperSearch->sanitizeFieldName($prop['id']));
1252
  $property->addAttribute('type', $prop['ptype']);
@@ -1272,9 +1474,9 @@ XML;
1272
  }
1273
 
1274
  }
1275
- ##################################
1276
 
1277
- ##################################
1278
 
1279
  if ($this->_storeConfig['export_customers']) {
1280
  $customer = simplexml_load_string($customerString);
@@ -1292,16 +1494,25 @@ XML;
1292
  $dom->loadXML($xml->asXML());
1293
  $saveXML = $dom->saveXML();
1294
  file_put_contents($name, $saveXML);
1295
- // $dom->save($name);
1296
-
1297
 
 
 
 
 
 
 
 
 
 
 
1298
  }
1299
 
1300
  /**
1301
- * desciption: add default xmlElements
1302
  * @param SimpleXMLElement $xml
1303
  */
1304
- function sxml_append_options(SimpleXMLElement &$xml)
1305
  {
1306
  $xml->addChild('format')->addAttribute('value', $this->_helperExporter->XML_FORMAT);
1307
  $xml->addChild('encoding')->addAttribute('value', $this->_helperExporter->XML_ENCODE);
@@ -1314,18 +1525,15 @@ XML;
1314
  /**
1315
  * @return array
1316
  */
1317
- function prepareProperties()
1318
  {
1319
 
1320
  $properties = array();
1321
 
1322
  $attrs = $this->_listOfAttributes;
1323
- // $attrs[] = 'parent_id';
1324
 
1325
  foreach ($attrs as $attr) {
1326
-
1327
  $ptype = 'string';
1328
-
1329
  // set property type
1330
  switch ($attr) {
1331
  case 'name':
@@ -1352,17 +1560,16 @@ XML;
1352
  case 'length':
1353
  $ptype = 'number';
1354
  break;
1355
-
1356
  }
1357
 
1358
  if (isset($this->_attributesValuesByName[$attr])) {
1359
  $properties[] = array(
1360
- 'id' => $attr,
1361
- 'name' => $attr,
1362
- 'ptype' => 'text',
1363
- 'type' => 'reference',
1364
- 'field' => $attr . '_id',
1365
- 'has_lang' => false,
1366
  'reference' => $attr
1367
  );
1368
  } elseif ($attr == 'category_ids') {
@@ -1382,25 +1589,25 @@ XML;
1382
  break;
1383
  }
1384
  $properties[] = array(
1385
- 'id' => $attr,
1386
- 'name' => null,
1387
- 'ptype' => $ptype,
1388
- 'type' => $type,
1389
- 'field' => $field,
1390
- 'has_lang' => $lang,
1391
  'reference' => $ref
1392
  );
1393
  }
1394
  }
1395
  //tag
1396
- if ($this->_storeConfig['export_tags']) {
1397
  $properties[] = array(
1398
- 'id' => 'tag',
1399
- 'name' => 'tag',
1400
- 'ptype' => 'text',
1401
- 'type' => 'reference',
1402
- 'field' => 'tag_id',
1403
- 'has_lang' => false,
1404
  'reference' => 'tag'
1405
  );
1406
  }
@@ -1408,32 +1615,26 @@ XML;
1408
  //categories
1409
  if ($this->_storeConfig['export_categories']) {
1410
  $properties[] = array(
1411
- 'id' => 'category',
1412
- 'name' => 'categories', //property id
1413
- 'ptype' => 'hierarchical', //property type
1414
- 'type' => 'reference', //logic type
1415
- 'field' => 'category_id', //field colummn
1416
- 'has_lang' => false,
1417
  'reference' => 'categories'
1418
  );
1419
  }
1420
- $properties[] = array('id' => 'product_entity_id', 'name' => null, 'ptype' => 'string', 'type' => 'direct', 'field' => 'entity_id', 'has_lang' => false, 'reference' => null);
 
 
 
 
 
 
 
 
1421
 
1422
  return $properties;
1423
-
1424
- }
1425
-
1426
- /**
1427
- *
1428
- * description: add xmlElement to other xmlElement
1429
- * @param SimpleXMLElement $to
1430
- * @param SimpleXMLElement $from
1431
- */
1432
- function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from)
1433
- {
1434
- $toDom = dom_import_simplexml($to);
1435
- $fromDom = dom_import_simplexml($from);
1436
- $toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
1437
  }
1438
 
1439
  /**
@@ -1472,11 +1673,11 @@ XML;
1472
  {
1473
 
1474
  $fields = array(
1475
- "username" => $this->_storeConfig['di_username'],
1476
- "password" => $this->_storeConfig['di_password'],
1477
- "account" => $this->_storeConfig['di_account'],
1478
- "template" => 'standard_source',
1479
- "xml" => file_get_contents($file . '.xml')
1480
  );
1481
 
1482
  $url = $this->_helperExporter->getXMLSyncUrl($this->_storeConfig['account_dev']);
@@ -1493,7 +1694,7 @@ XML;
1493
  curl_setopt($s, CURLOPT_URL, $url);
1494
  curl_setopt($s, CURLOPT_TIMEOUT, 35000);
1495
  curl_setopt($s, CURLOPT_POST, true);
1496
- curl_setopt($s, CURLOPT_ENCODING, "");
1497
  curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
1498
  curl_setopt($s, CURLOPT_POSTFIELDS, $fields);
1499
 
@@ -1511,12 +1712,12 @@ XML;
1511
  protected function pushZip($file)
1512
  {
1513
  $fields = array(
1514
- "username" => $this->_storeConfig['di_username'],
1515
- "password" => $this->_storeConfig['di_password'],
1516
- "account" => $this->_storeConfig['di_account'],
1517
- "dev" => $this->_storeConfig['account_dev'] == 0 ? 'false' : 'true',
1518
- "delta" => $this->_getIndexType() == 'delta' ? "true" : "false", // I know...
1519
- "data" => '@' . $file . '.zip;type=application/zip'
1520
  );
1521
 
1522
  $url = $this->_helperExporter->getZIPSyncUrl($this->_storeConfig['account_dev']);
@@ -1524,49 +1725,15 @@ XML;
1524
  return $this->pushFile($fields, $url, 'zip');
1525
  }
1526
 
1527
- /**
1528
- * @description Closing sync to export
1529
- */
1530
- protected function _closeExport()
1531
- {
1532
- $this->delTree($this->_dir);
1533
- }
1534
-
1535
- function getmicrotime($mt, $string = true)
1536
  {
1537
- list($usec, $sec) = explode(" ", $mt);
1538
 
1539
- if ($string)
1540
- return date('Y-m-d H:i:s', (float)$usec + (float)$sec) . '.' . $usec;
1541
- else
1542
- return ((float)$usec + (float)$sec);
1543
- }
1544
-
1545
- /**
1546
- * @description Get stock of all products
1547
- * @return array List of stocks qty for products
1548
- */
1549
- protected function _getProductsStockQty()
1550
- {
1551
- if (empty($this->_productsStockQty)) {
1552
- $products = Mage::getModel('cataloginventory/stock_item')->getCollection();
1553
- foreach ($products as $product) {
1554
- $this->_productsStockQty[$product->getProductId()] = $product->getQty();
1555
- }
1556
- $products = null;
1557
- }
1558
-
1559
- return $this->_productsStockQty;
1560
- }
1561
-
1562
- protected function savePartToCsv($file, &$data){
1563
-
1564
- if (!file_exists("/tmp/boxalino")) {
1565
- mkdir("/tmp/boxalino");
1566
  }
1567
 
1568
  //save
1569
- if(!in_array($file, $this->_files)){
1570
  $this->_files[] = $file;
1571
  }
1572
 
@@ -1580,127 +1747,44 @@ XML;
1580
 
1581
  }
1582
 
1583
- public static function delTree($dir) {
1584
- if(!file_exists($dir)){
1585
- return;
1586
- }
1587
- $files = array_diff(scandir($dir), array('.','..'));
1588
- foreach ($files as $file) {
1589
- if(is_dir("$dir/$file")){
1590
- delTree("$dir/$file");
1591
- } else if(file_exists("$dir/$file")){
1592
- @unlink("$dir/$file");
1593
- }
1594
- // (is_dir("$dir/$file")) ? delTree("$dir/$file") : @unlink("$dir/$file");
1595
- }
1596
- return rmdir($dir);
1597
- }
1598
-
1599
- protected function escapeString($string){
1600
-
1601
- return htmlspecialchars(trim(preg_replace('/\s+/', ' ', $string)));
1602
-
1603
- }
1604
-
1605
- private static function clearMemory(&$obj){
1606
- $obj = null;
1607
- }
1608
-
1609
- private static function getFromClass(&$class, $val){
1610
-
1611
- if(isset($class->$val)){
1612
- return $class->$val;
1613
- } else{
1614
- return '';
1615
- }
1616
-
1617
- }
1618
-
1619
  /**
1620
- * Load connection arrays if necessary.
1621
  */
1622
- private function loadProductLinks()
1623
  {
1624
-
1625
- // If arrays already set - nothing to do here.
1626
- if ($this->_isLoad) {
1627
- return;
1628
- }
1629
-
1630
- // Get database connection
1631
- $connection = Mage::getSingleton('core/resource')->getConnection('core_read');
1632
- $tableName = $connection->getTableName('catalog_product_super_link');
1633
- // Get all data from `catalog_product_super_link`
1634
- $query = 'select * from ' . $tableName;
1635
- $this->_simples = array();
1636
- $this->_configurables = array();
1637
-
1638
- // Iterate through collection
1639
- foreach ($connection->fetchAll($query) as $row) {
1640
- $productId = $row['product_id'];
1641
- $parentId = $row['parent_id'];
1642
-
1643
- // Set simpleIds array if not set yet for specified parent.
1644
- if (!isset($this->_simpleIds[$parentId])) {
1645
- $this->_simpleIds[$parentId] = array();
1646
- }
1647
- // Add simple product to collection of parent.
1648
- $this->_simpleIds[$parentId][] = $productId;
1649
- // Add parent to simple product.
1650
- $this->_parentId[$productId] = $parentId;
1651
- }
1652
- unset($connection);
1653
- $this->_isLoad = true;
1654
- }
1655
-
1656
- /**
1657
- * Return parent id.
1658
- *
1659
- * @param null $productId
1660
- * @return null|int|array
1661
- */
1662
- public function getParentId($productId = null)
1663
- {
1664
- // Load connections if necessary.
1665
- $this->loadProductLinks();
1666
-
1667
- // If no product is specified - return whole array.
1668
- if (!isset($productId)) {
1669
- return $this->_parentId;
1670
- }
1671
-
1672
- // If we have parent id for specified product - return it.
1673
- if (isset($this->_parentId[$productId])) {
1674
- return $this->_parentId[$productId];
1675
- }
1676
-
1677
- // No parent - return null.
1678
- return null;
1679
  }
1680
 
1681
  /**
1682
- * Return simple ids.
1683
  *
1684
- * @param null $productId
1685
- * @return null|int|array
1686
  */
1687
- public function getSimpleIds($productId = null)
1688
  {
1689
-
1690
- // Load connections if necessary.
1691
- $this->loadProductLinks();
1692
-
1693
- // If no product is specified - return whole array.
1694
- if (!isset($productId)) {
1695
- return $this->_simpleIds;
1696
- }
1697
-
1698
- // If we have simple ids for specified product - return it.
1699
- if (isset($this->_simpleIds[$productId])) {
1700
- return $this->_simpleIds[$productId];
1701
  }
1702
- // No simple ids - return null.
1703
- return null;
1704
  }
1705
 
1706
  }
1
  <?php
2
 
 
 
3
  abstract class Boxalino_Exporter_Model_Mysql4_Indexer extends Mage_Core_Model_Mysql4_Abstract
4
  {
5
  /** @var array Configuration for each Store View */
31
 
32
  protected $_attributesValuesByName = array();
33
 
 
 
34
  protected $_files = array();
35
 
36
  protected $_count = 0;
47
  protected $_helperExporter = null;
48
  protected $_helperSearch = null;
49
 
50
+ protected $_entityIds = null;
 
 
 
51
 
52
  /**
53
+ * @description Start of reindex
54
  */
55
  public function reindexAll()
56
  {
57
+ self::logMem('Indexer init');
58
  $this->_websiteExport();
59
+ $this->_helperExporter->delTree($this->_dir);
60
  return $this;
61
  }
62
 
67
  protected function _websiteExport()
68
  {
69
  $this->_helperExporter = Mage::helper('boxalinoexporter');
70
+ $this->_helperSearch = Mage::helper('boxalinoexporter');
71
+ self::logMem('Helpers init');
72
  foreach (Mage::app()->getWebsites() as $website) {
73
 
74
+ $this->_helperExporter->delTree($this->_dir);
75
+ self::logMem('After delTree');
76
 
77
  if (!$this->_isEnabled()) {
78
  continue;
80
 
81
  $data = $this->_storeExport($website);
82
 
83
+ self::logMem('something with attributes - before');
 
 
 
84
 
85
+ foreach ($this->_listOfAttributes as $k => $attr) {
86
+ if (
87
  !isset($this->_attributesValuesByName[$attr]) ||
88
  (isset($this->_attrProdCount[$attr]) &&
89
+ $this->_attrProdCount[$attr])
90
+ ) {
91
  continue;
92
+ } else {
93
  unset($this->_attributesValuesByName[$attr]);
94
  unset($this->_listOfAttributes[$k]);
95
  }
96
  }
97
 
98
+ self::logMem('something with attributes - after');
99
  $file = $this->prepareFiles($website, $data['categories'], $data['tags']);
100
+ self::logMem('Push files');
101
 
102
  $this->pushXML($file);
103
  $this->pushZip($file);
107
  $this->_transformedProducts = array();
108
  $this->_categoryParent = array();
109
  $this->_availableLanguages = array();
 
110
  $this->_attrProdCount = array();
111
  $this->_count = 0;
112
 
122
  {
123
  $products = array();
124
  $categories = array();
 
125
  $tags = array();
126
+ self::logMem('Preparing data for website start');
 
127
  foreach ($website->getGroups() as $group) {
128
 
129
  $this->group = $group;
130
 
131
  foreach ($group->getStores() as $store) {
132
+ self::logMem('Start store:' . $store->getId());
133
  $this->_prepareStoreConfig($store->getId());
134
+ self::logMem('Configuration for store loaded');
135
  if ($this->_isEnabled()) {
136
  $categories = $this->_exportCategories();
137
  $tags = $this->_exportTags();
138
+ self::logMem('Without available languages');
139
  $this->_availableLanguages[] = $this->_storeConfig['language'];
140
+ self::logMem('With available languages');
141
 
142
  }
143
  }
145
  if ($this->_isEnabled()) {
146
  $this->_exportCustomers();
147
  $this->_exportTransactions();
148
+ $this->_exportProducts();
149
  }
150
 
151
  }
152
 
153
  return array(
 
154
  'categories' => $categories,
155
  'tags' => $tags,
156
  );
182
  */
183
  protected function _mergeAllAttributes()
184
  {
185
+ $this->_listOfAttributes = array(
186
+ 'entity_id',
187
+ 'name',
188
+ 'description',
189
+ 'short_description',
190
+ 'sku',
191
+ 'price',
192
+ 'special_price',
193
+ 'visibility',
194
+ 'category_ids',
195
+ );
196
 
197
  $attributes = array();
198
 
199
+ foreach (Mage::getResourceModel('catalog/product_attribute_collection')->getItems() as $at) {
200
  $attributes[] = $at->getAttributeCode();
201
  }
202
 
204
  $fields = explode(',', $this->_storeConfig['additional_attributes']);
205
  foreach ($fields as $field) {
206
 
207
+ if (!in_array($field, $attributes)) {
208
+ Mage::throwException("Attribute \"$field\" not exist!");
209
  }
210
 
211
+ if ($field != null && strlen($field) > 0) {
212
  $this->_listOfAttributes[] = $field;
213
  }
214
 
230
  $options = Mage::getModel('eav/config')->getAttribute('catalog_product', $attribute)->setStoreId($this->_storeId)->getSource()->getAllOptions();
231
  foreach ($options as $option) {
232
  if (!empty($option['value'])) {
233
+ $this->_attributesValues[$this->_storeId][$attribute][$option['value']] = $this->_helperSearch->escapeString($option['label']);
234
 
235
  $value = intval($option['value']);
236
  $name = 'value_' . $this->_storeConfig['language'];
239
 
240
  if (isset($this->_attributesValuesByName[$attribute][$value])) {
241
  $this->_attributesValuesByName[$attribute][$value][$name] = /*strtolower*/
242
+ $this->_helperSearch->escapeString($option['label']);
243
  } else {
244
  $this->_attributesValuesByName[$attribute][$value] = array($attribute . '_id' => $value, $name => /*strtolower*/
245
+ $this->_helperSearch->escapeString($option['label']));
246
  }
247
 
248
  } else {
249
  $this->_attributesValuesByName[$attribute] = array($value => array($attribute . '_id' => $value, $name => /*strtolower*/
250
+ $this->_helperSearch->escapeString($option['label'])));
251
  }
252
 
253
  }
266
  {
267
  if (isset($this->_storeConfig['enabled']) && $this->_storeConfig['enabled']) {
268
  return true;
269
+ } else if (!isset($this->_storeConfig['enabled']) && Mage::getStoreConfig('Boxalino_General/general/enabled')) {
270
  return true;
271
  }
272
 
275
 
276
  /**
277
  * @description Preparing categories to export
278
+ * @return array Categories
279
  */
280
  protected function _exportCategories()
281
  {
282
  if ($this->_storeConfig['export_categories']) {
283
+ self::logMem('Categories are not loaded');
284
  $categories = $this->_getCategories();
285
+ self::logMem('Categories are loaded');
286
  foreach ($categories as $category) {
287
 
288
  if ($category->getParentId() == null) {
290
  }
291
 
292
  if (isset($this->_transformedCategories[$category->getId()])) {
293
+ $this->_transformedCategories[$category->getId()]['value_' . $this->_storeConfig['language']] = $this->_helperSearch->escapeString($category->getName());
294
  } else {
295
  $parentId = null;
296
  if ($category->getParentId() != 0) {
297
  $parentId = $category->getParentId();
298
  }
299
+ $this->_transformedCategories[$category->getId()] = array('category_id' => $category->getId(), 'parent_id' => $parentId, 'value_' . $this->_storeConfig['language'] => $this->_helperSearch->escapeString($category->getName()));
300
  }
301
  }
302
+ $categories = null;
303
+ self::logMem('Categories are returned for data saving');
304
  return $this->_transformedCategories;
305
  }
 
 
306
  return null;
 
307
  }
308
 
309
+ /**
310
+ * @description Get list of all categories
311
+ * @return object All categories for Store
312
+ */
313
+ protected function _getCategories()
314
+ {
315
+ $categories = Mage::getModel('catalog/category')->setStoreId($this->_storeId)->getCollection()->addAttributeToSelect('*');
316
+ return $categories;
317
+ }
318
 
319
  /**
320
  * @description Preparing tags to export
325
  {
326
 
327
  if ($this->_storeConfig['export_tags']) {
328
+ self::logMem('Tags are not loaded');
329
  $tags = $this->_helperExporter->getAllTags();
330
+ self::logMem('Tags are loaded');
331
 
332
  foreach ($tags as $id => $tag) {
333
  if (isset($this->_transformedTags[$id])) {
338
  }
339
 
340
  $tags = null;
341
+ self::logMem('Tags are returned for data saving');
342
  return $this->_transformedTags;
343
  }
344
 
347
 
348
  /**
349
  * @description Preparing products to export
350
+ * @return void
351
  */
352
  protected function _exportProducts()
353
  {
354
+ self::logMem('Products - start of export');
 
355
  $attrs = $this->_listOfAttributes;
356
+ self::logMem('Products - get info about attributes - before');
357
+
358
+ $db = $this->_getReadAdapter();
359
+ $select = $db->select()
360
+ ->from(
361
+ array('main_table' => 'eav_attribute'),
362
+ array(
363
+ 'attribute_id',
364
+ 'attribute_code',
365
+ 'backend_type',
366
+ )
367
+ )
368
+ ->joinInner(
369
+ array('additional_table' => 'catalog_eav_attribute'),
370
+ 'additional_table.attribute_id = main_table.attribute_id'
371
+ )
372
+ ->where('main_table.entity_type_id = ?', $this->getEntityIdFor('catalog_product'))
373
+ ->where('main_table.attribute_code IN(?)', $attrs);
374
+
375
+ self::logMem('Products - connected to DB, built attribute info query');
376
 
 
 
 
 
 
 
 
 
377
  $attrsFromDb = array(
378
+ 'int' => array(),
379
+ 'varchar' => array(),
380
+ 'text' => array(),
381
+ 'decimal' => array(),
382
  );
383
+
384
+ foreach ($db->fetchAll($select) as $r) {
385
  $type = $r['backend_type'];
386
+ if (isset($attrsFromDb[$type])) {
387
  $attrsFromDb[$type][] = $r['attribute_id'];
 
388
  }
389
  }
390
+ self::logMem('Products - attributes preparing done');
391
+
392
  $countMax = $this->_storeConfig['maximum_population'];
393
  $localeCount = 0;
394
 
397
  $page = 1;
398
  $header = true;
399
 
400
+ $stores = array();
401
+ foreach ($this->group->getStores() as $store){
402
 
403
+ $stores[$store->getId()]['id'] = $store->getId();
404
+ $stores[$store->getId()]['lang'] = Mage::app()->getStore($store->getId())->getConfig('boxalinoexporter/export_data/language');
 
405
 
406
+ }
407
 
408
+ //prepare files
409
+ $filesMtM = array();
410
+ $tmp =array_keys($this->_attributesValuesByName);
411
+ $tmp[] = 'categories';
412
+ foreach($tmp as $attr){
413
 
414
+ $key = $attr;
 
 
 
 
 
 
415
 
416
+ if ($attr == 'categories') {
417
+ $key = 'category';
418
+ }
 
 
 
 
 
419
 
420
+ if (!file_exists('/tmp/boxalino')) {
421
+ mkdir('/tmp/boxalino');
422
+ }
423
 
424
+ $file = 'product_' . $attr . '.csv';
 
425
 
426
+ //save
427
+ if (!in_array($file, $this->_files)) {
428
+ $this->_files[] = $file;
429
+ }
 
 
 
 
 
 
 
 
430
 
431
+ $fh = fopen($this->_dir . '/' . $file, 'a');
432
+ fputcsv($fh, array('entity_id', $key . '_id'), $this->_helperExporter->XML_DELIMITER, $this->_helperExporter->XML_ENCLOSURE);
433
 
434
+ $filesMtM[$attr] = $fh;
435
 
436
+ }
437
+ $tmp = null;
438
 
439
+ while($count >= $limit) {
440
+ if ($countMax > 0 && $this->_count >= $countMax) {
441
+ break;
442
+ }
443
 
444
+ foreach ($stores as $store) {
 
445
 
446
+ $storeId = $store['id'];
447
+ $lang = $store['lang'];
 
 
448
 
449
+ self::logMem('Products - fetch products - before');
450
+ $select = $db->select()
451
+ ->from(
452
+ array('e' => 'catalog_product_entity')
453
+ )
454
+ ->limit($limit, ($page - 1) * $limit);
455
 
456
+ $this->_getIndexType() == 'delta' ? $select->where('created_at >= ? OR updated_at >= ?', $this->_getLastIndex()) : '';
457
 
458
+ self::logMem('Products - fetch products - after');
459
 
460
+ $products = array();
461
+ $ids = array();
462
+ $count = 0;
463
+ foreach ($db->fetchAll($select) as $r) {
464
+ $products[$r['entity_id']] = $r;
465
+ $ids[] = $r['entity_id'];
466
+ $products[$r['entity_id']]['website'] = array();
467
+ $products[$r['entity_id']]['categories'] = array();
468
+ $count++;
469
  }
470
 
471
+ self::logMem('Products - get attributes - before');
472
+ $columns = array(
473
+ 'entity_id',
474
+ 'attribute_id',
475
+ );
476
+ $joinCondition = $db->quoteInto('t_s.attribute_id = t_d.attribute_id AND t_s.entity_id = t_d.entity_id AND t_s.store_id = ?', $storeId);
477
+ $joinColumns = array('value' => 'IF(t_s.value_id IS NULL, t_d.value, t_s.value)');
478
+
479
+ $select1 = $db->select()
480
+ ->joinLeft(array('ea' => 'eav_attribute'), 't_d.attribute_id = ea.attribute_id', 'ea.attribute_code')
481
+ ->where('t_d.store_id = ?', 0)
482
+ ->where('t_d.entity_type_id = ?', $this->getEntityIdFor('catalog_product'))
483
+ ->where('t_d.entity_id IN(?)', $ids);
484
+ $select2 = clone $select1;
485
+ $select3 = clone $select1;
486
+ $select4 = clone $select1;
487
+
488
+ $select1->from(
489
+ array('t_d' => 'catalog_product_entity_varchar'),
490
+ $columns
491
+ )
492
+ ->joinLeft(
493
+ array('t_s' => 'catalog_product_entity_varchar'),
494
+ $joinCondition,
495
+ $joinColumns
496
+ )
497
+ ->where('t_d.attribute_id IN(?)', $attrsFromDb['varchar']);
498
+ $select2->from(
499
+ array('t_d' => 'catalog_product_entity_text'),
500
+ $columns
501
+ )
502
+ ->joinLeft(
503
+ array('t_s' => 'catalog_product_entity_text'),
504
+ $joinCondition,
505
+ $joinColumns
506
+ )
507
+ ->where('t_d.attribute_id IN(?)', $attrsFromDb['text']);
508
+ $select3->from(
509
+ array('t_d' => 'catalog_product_entity_decimal'),
510
+ $columns
511
+ )
512
+ ->joinLeft(
513
+ array('t_s' => 'catalog_product_entity_decimal'),
514
+ $joinCondition,
515
+ $joinColumns
516
+ )
517
+ ->where('t_d.attribute_id IN(?)', $attrsFromDb['decimal']);
518
+ $select4->from(
519
+ array('t_d' => 'catalog_product_entity_int'),
520
+ $columns
521
+ )
522
+ ->joinLeft(
523
+ array('t_s' => 'catalog_product_entity_int'),
524
+ $joinCondition,
525
+ $joinColumns
526
+ )
527
+ ->where('t_d.attribute_id IN(?)', $attrsFromDb['int']);
528
+
529
+ $select = $db->select()
530
+ ->union(
531
+ array($select1, $select2, $select3, $select4),
532
+ Zend_Db_Select::SQL_UNION_ALL
533
+ );
534
 
535
+ $select1 = null;
536
+ $select2 = null;
537
+ $select3 = null;
538
+ $select4 = null;
539
+ foreach ($db->fetchAll($select) as $r) {
540
+ $products[$r['entity_id']][$r['attribute_code']] = $r['value'];
541
+ }
542
+ self::logMem('Products - get attributes - after');
543
+
544
+ self::logMem('Products - get stock - before');
545
+ $select = $db->select()
546
+ ->from(
547
+ 'cataloginventory_stock_status',
548
+ array(
549
+ 'product_id',
550
+ 'stock_status',
551
+ )
552
+ )
553
+ ->where('stock_id = ?', 1)
554
+ ->where('website_id = ?', 1)
555
+ ->where('product_id IN(?)', $ids);
556
+ foreach ($db->fetchAll($select) as $r) {
557
+ $products[$r['product_id']]['stock_status'] = $r['stock_status'];
558
+ }
559
+ self::logMem('Products - get stock - after');
560
+
561
+ self::logMem('Products - get products from website - before');
562
+ $select = $db->select()
563
+ ->from(
564
+ 'catalog_product_website',
565
+ array(
566
+ 'product_id',
567
+ 'website_id',
568
+ )
569
+ )
570
+ ->where('product_id IN(?)', $ids);
571
+ foreach ($db->fetchAll($select) as $r) {
572
  $products[$r['product_id']]['website'][] = $r['website_id'];
 
573
  }
574
+ self::logMem('Products - get products from website - after');
575
+
576
+ self::logMem('Products - get products connections - before');
577
+ $select = $db->select()
578
+ ->from(
579
+ 'catalog_product_super_link',
580
+ array(
581
+ 'product_id',
582
+ 'parent_id',
583
+ )
584
+ )
585
+ ->where('product_id IN(?)', $ids);
586
+ foreach ($db->fetchAll($select) as $r) {
587
  $products[$r['product_id']]['parent_id'] = $r['parent_id'];
 
588
  }
589
+ self::logMem('Products - get products connections - after');
590
+
591
+ self::logMem('Products - get categories - before');
592
+ $select = $db->select()
593
+ ->from(
594
+ 'catalog_category_product',
595
+ array(
596
+ 'product_id',
597
+ 'category_id',
598
+ )
599
+ )
600
+ ->where('product_id IN(?)', $ids);
601
+ $ids = null;
602
+ foreach ($db->fetchAll($select) as $r) {
603
  $products[$r['product_id']]['categories'][] = $r['category_id'];
 
604
  }
605
+ $select = null;
606
+ self::logMem('Products - get categories - after');
607
 
608
+ foreach ($products as $product) {
609
+ self::logMem('Products - start transform');
 
 
 
 
 
 
610
 
611
+ if (count($product['website']) == 0) {
612
+ $product = null;
 
 
 
613
  continue;
614
  }
615
 
616
+ $id = $product['entity_id'];
617
 
618
  $productParam = array();
619
  $haveParent = false;
620
 
621
+ if (array_key_exists('parent_id', $product)) {
622
+ $id = $product['parent_id'];
623
  $haveParent = true;
624
+ } else if ($product['visibility'] == 1 && !array_key_exists('parent_id', $product)) {
625
  $product = null;
626
  continue;
627
  }
628
 
629
  foreach ($attrs as $attr) {
630
+ self::logMem('Products - start attributes transform');
631
 
632
  if (isset($this->_attributesValuesByName[$attr])) {
633
 
634
+ $val = array_key_exists($attr, $product) ? $this->_helperSearch->escapeString($product[$attr]) : '';
 
 
 
635
  if ($val == null) {
636
  continue;
637
  }
638
 
639
+ $attr = $this->_helperSearch->sanitizeFieldName($attr);
640
+
641
  $this->_attrProdCount[$attr] = true;
642
 
643
+ // if visibility is set everywhere (have value "4"),
644
+ // then we split it for value "2" and "3" (search and catalog separately)
645
+ if ($attr == 'visibility' && $val == '4') {
646
+ fputcsv($filesMtM[$attr], array($id, '2'), $this->_helperExporter->XML_DELIMITER, $this->_helperExporter->XML_ENCLOSURE);
647
+ fputcsv($filesMtM[$attr], array($id, '3'), $this->_helperExporter->XML_DELIMITER, $this->_helperExporter->XML_ENCLOSURE);
648
 
 
 
 
 
 
 
 
 
 
 
 
 
 
649
  } else {
650
+ fputcsv($filesMtM[$attr], array($id, $val), $this->_helperExporter->XML_DELIMITER, $this->_helperExporter->XML_ENCLOSURE);
 
 
 
 
 
 
 
 
 
 
 
 
651
  }
652
 
653
+
654
+ $val = null;
655
+
656
  continue;
657
  }
658
 
659
+ $val = array_key_exists($attr, $product) ? $this->_helperSearch->escapeString($product[$attr]) : '';
660
  switch ($attr) {
661
+ case 'category_ids':
662
+ break;
663
  case 'description':
664
  case 'short_description':
665
  case 'name':
666
+ $productParam[$attr . '_' . $lang] = $val;
 
 
667
  break;
668
  default:
669
+ $productParam[$attr] = $val;
670
  break;
671
  }
672
+ self::logMem('Products - end attributes transform');
673
 
674
  }
675
 
676
  if ($haveParent) {
677
+ $product = null;
678
  continue;
679
  }
680
 
681
  if (!isset($this->_transformedProducts['products'][$id])) {
682
  if ($countMax > 0 && $this->_count >= $countMax) {
683
+ $product = null;
684
+ $products = null;
685
  break;
686
  }
687
  $productParam['entity_id'] = $id;
688
  $this->_transformedProducts['products'][$id] = $productParam;
689
 
690
  //Add categories
691
+ if (isset($product['categories']) && count($product['categories']) > 0) {
692
+ foreach ($product['categories'] as $cat) {
693
 
694
  while ($cat != null) {
695
+ fputcsv($filesMtM['categories'], array($id, $cat), $this->_helperExporter->XML_DELIMITER, $this->_helperExporter->XML_ENCLOSURE);
696
  if (isset($this->_transformedCategories[$cat]['parent_id'])) {
697
  $cat = $this->_transformedCategories[$cat]['parent_id'];
698
  } else {
706
 
707
  } elseif (isset($this->_transformedProducts['products'][$id])) {
708
  $this->_transformedProducts['products'][$id] = array_merge($this->_transformedProducts['products'][$id], $productParam);
 
709
  }
710
+
711
  $productParam = null;
712
  $product = null;
713
 
714
  ksort($this->_transformedProducts['products'][$id]);
715
+ self::logMem('Products - end transform');
716
 
717
  }
718
  }
719
 
720
+ if (isset($this->_transformedProducts['products']) && count($this->_transformedProducts['products']) > 0) {
721
 
722
+ self::logMem('Products - validate names start');
723
 
724
  $data = $this->_transformedProducts['products'];
725
 
726
+ if ($header && count($data) > 0) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
727
  $data = array_merge(array(array_keys(end($data))), $data);
728
  $header = false;
729
  }
730
+ self::logMem('Products - save to file');
731
  $this->savePartToCsv('products.csv', $data);
 
732
  $data = null;
733
+ $this->_transformedProducts['products'] = null;
734
  $this->_transformedProducts['products'] = array();
 
735
 
736
  }
737
 
741
 
742
  }
743
 
744
+ $attrFDB = null;
745
+ $attrsFromDb = null;
746
+ $attrs = null;
747
  $this->_transformedProducts = null;
748
+ $db = null;
 
749
 
750
+ //close file
751
+ foreach($filesMtM as $f){
752
+ fclose($f);
753
+ }
754
 
 
 
755
 
756
+ }
757
 
758
  /**
759
  * @description Preparing customers to export
760
+ * @return void
761
  *
762
  */
763
  protected function _exportCustomers()
764
  {
765
 
766
+ if (!$this->_storeConfig['export_customers']) {
767
+ return;
768
+ }
 
769
 
770
+ self::logMem('Customers - Countries are not loaded');
771
+ $countryCollection = Mage::getModel('directory/country')->getCollection();
772
+ self::logMem('Customers - Countries are loaded');
773
+
774
+ if ($this->_countries == null) {
775
+ foreach ($countryCollection as $country) {
776
+ $this->_countries[$country->getId()] = $country->getName();
777
  }
778
+ }
779
+ $countryCollection = null;
780
 
781
+ $limit = $this->_storeConfig['export_chunk'];
782
+ $count = $limit;
783
+ $page = 1;
784
+ $header = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
785
 
786
+ $attrsFromDb = array(
787
+ 'int' => array(),
788
+ 'varchar' => array(),
789
+ 'datetime' => array(),
790
+ );
 
 
 
 
 
 
791
 
792
+ $db = $this->_getReadAdapter();
793
+ $select = $db->select()
794
+ ->from(
795
+ array('main_table' => 'eav_attribute'),
796
+ array(
797
+ 'aid' => 'attribute_id',
798
+ 'attribute_code',
799
+ 'backend_type',
800
+ )
801
+ )
802
+ ->joinInner(
803
+ array('additional_table' => 'customer_eav_attribute'),
804
+ 'additional_table.attribute_id = main_table.attribute_id'
805
+ )
806
+ ->joinLeft( // @todo is this left join still necessary?
807
+ array('scope_table' => 'customer_eav_attribute_website'),
808
+ 'scope_table.attribute_id = main_table.attribute_id AND ' .
809
+ 'scope_table.website_id = ' . $this->group->getWebsiteId()
810
+ )
811
+ ->where('main_table.entity_type_id = ?', $this->getEntityIdFor('customer'))
812
+ ->where('attribute_code IN ("dob", "gender")');
813
+
814
+ foreach ($db->fetchAll($select) as $attr) {
815
+ if (isset($attrsFromDb[$attr['backend_type']])) {
816
+ $attrsFromDb[$attr['backend_type']][] = $attr['aid'];
817
+ }
818
+ }
819
+
820
+ do {
821
+ self::logMem("Customers - load page $page");
822
+ $customers_to_save = array();
823
+
824
+ $customers = array();
825
+
826
+ $select = $db->select()
827
+ ->from(
828
+ 'customer_entity',
829
+ array('entity_id', 'created_at', 'updated_at')
830
+ )
831
+ ->where('entity_type_id = ?', '1')->limit($limit, ($page - 1) * $limit);
832
+
833
+ $this->_getIndexType() == 'delta' ? $select->where('created_at >= ? OR updated_at >= ?', $this->_getLastIndex()) : '';
834
+
835
+ foreach ($db->fetchAll($select) as $r) {
836
+ $customers[$r['entity_id']] = array('id' => $r['entity_id']);
837
+ }
838
+
839
+ $ids = array_keys($customers);
840
+ $columns = array(
841
+ 'entity_id',
842
+ 'attribute_id',
843
+ 'value',
844
+ );
845
+
846
+ $select = $db->select()
847
+ ->joinLeft(array('ea' => 'eav_attribute'), 'ce.attribute_id = ea.attribute_id', 'ea.attribute_code')
848
+ ->where('ce.entity_type_id = ?', 1)
849
+ ->where('ce.entity_id IN(?)', $ids);
850
+
851
+ $select1 = null;
852
+ $select2 = null;
853
+ $select3 = null;
854
+
855
+ $selects = array();
856
+
857
+ if(count($attrsFromDb['varchar']) > 0){
858
+ $select1 = clone $select;
859
+ $select1->from(array('ce' => 'customer_entity_varchar'), $columns)
860
+ ->where('ce.attribute_id IN(?)', $attrsFromDb['varchar']);
861
+ $selects[] = $select1;
862
+ }
863
 
864
+ if(count($attrsFromDb['int']) > 0){
865
+ $select2 = clone $select;
866
+ $select2->from(array('ce' => 'customer_entity_int'), $columns)
867
+ ->where('ce.attribute_id IN(?)', $attrsFromDb['int']);
868
+ $selects[] = $select2;
869
+ }
870
+
871
+ if(count($attrsFromDb['datetime']) > 0){
872
+ $select3 = clone $select;
873
+ $select3->from(array('ce' => 'customer_entity_datetime'), $columns)
874
+ ->where('ce.attribute_id IN(?)', $attrsFromDb['datetime']);
875
+ $selects[] = $select3;
876
+ }
877
+
878
+ $select = $db->select()
879
+ ->union(
880
+ $selects,
881
+ Zend_Db_Select::SQL_UNION_ALL
882
+ );
883
+
884
+ foreach ($db->fetchAll($select) as $r) {
885
+ $customers[$r['entity_id']][$r['attribute_code']] = $r['value'];
886
+ }
887
+
888
+ $select = null;
889
+ $select1 = null;
890
+ $select2 = null;
891
+ $select3 = null;
892
+ $selects = null;
893
+
894
+ $select = $db->select()
895
+ ->from(
896
+ 'eav_attribute',
897
+ array(
898
+ 'attribute_id',
899
+ 'attribute_code',
900
+ )
901
+ )
902
+ ->where('entity_type_id = ?', $this->getEntityIdFor('customer_address'))
903
+ ->where('attribute_code IN ("country_id","postcode")');
904
+
905
+ $addressAttr = array();
906
+ foreach ($db->fetchAll($select) as $r) {
907
+ $addressAttr[$r['attribute_id']] = $r['attribute_code'];
908
+ }
909
+ $addressIds = array_keys($addressAttr);
910
+
911
+ self::logMem('Customers - loaded page ' . $page);
912
+
913
+ foreach ($customers as $customer) {
914
+ self::logMem('Customers - Load billing address ');
915
+ $id = $customer['id'];
916
+
917
+ $select = $db->select()
918
+ ->from(
919
+ 'customer_address_entity',
920
+ array('entity_id')
921
+ )
922
+ ->where('entity_type_id = ?', 2)
923
+ ->where('parent_id = ?', $id);
924
+
925
+ $select = $db->select()
926
+ ->from(
927
+ 'customer_address_entity_varchar',
928
+ array('attribute_id', 'value')
929
+ )
930
+ ->where('entity_type_id = ?', $this->getEntityIdFor('customer_address'))
931
+ ->where('entity_id = ?', $select)
932
+ ->where('attribute_id IN(?)', $addressIds);
933
+
934
+ $billingResult = array();
935
+ foreach ($db->fetchAll($select) as $br) {
936
+ if (in_array($br['attribute_id'], $addressIds)) {
937
+ $billingResult[$addressAttr[$br['attribute_id']]] = $br['value'];
938
+ }
939
  }
940
 
941
+ $countryCode = null;
942
+ if (isset($billingResult['country_id'])) {
943
+ $countryCode = $billingResult['country_id'];
944
+ }
945
 
946
+ if (array_key_exists('gender', $customer)) {
947
+ if ($customer['gender'] % 2 == 0) {
948
+ $gender = 'female';
949
+ } else {
950
+ $gender = 'male';
951
+ }
952
+ } else {
953
+ $gender = '';
954
  }
 
 
955
 
956
+ $customers_to_save[] = array(
957
+ 'customer_id' => $id,
958
+ 'gender' => $gender,
959
+ 'dob' => array_key_exists('dob', $customer) ? $customer['dob'] : '',
960
+ 'country' => !empty($countryCode) ? $this->_helperExporter->getCountry($countryCode)->getName() : '',
961
+ 'zip' => array_key_exists('postcode', $billingResult) ? $billingResult['postcode'] : '',
962
+ );
963
 
964
+ }
965
+
966
+ $data = $customers_to_save;
967
+
968
+ if (count($customers) == 0 && $header) {
969
+ return null;
970
+ }
971
+
972
+ if ($header) {
973
+ $data = array_merge(array(array_keys(end($customers_to_save))), $customers_to_save);
974
+ $header = false;
975
+ }
976
+ self::logMem('Customers - save to file');
977
+ $this->savePartToCsv('customers.csv', $data);
978
+ $data = null;
979
+
980
+ $count = count($customers_to_save);
981
+ $page++;
982
 
983
+ } while ($count >= $limit);
984
+ $customers = null;
985
+
986
+ self::logMem('Customers - end of exporting');
987
+ }
988
 
989
  /**
990
  * @description Preparing transactions to export
991
+ * @return void
992
  */
993
  protected function _exportTransactions()
994
  {
995
+ if (!$this->_storeConfig['export_transactions']) {
996
+ return;
997
+ }
 
 
 
 
998
 
999
+ self::logMem('Transactions - start of export');
1000
+ $db = $this->_getReadAdapter();
1001
 
1002
+ $limit = $this->_storeConfig['export_chunk'];
1003
+ $count = $limit;
1004
+ $page = 1;
1005
+ $header = true;
 
 
 
 
1006
 
1007
+ while ($count >= $limit) {
1008
+ self::logMem('Transactions - load page ' . $page);
1009
+ $transactions_to_save = array();
1010
+ $configurable = array();
1011
+
1012
+ $select = $db
1013
+ ->select()
1014
+ ->from(
1015
+ array('order' => 'sales_flat_order'),
1016
+ array(
1017
+ 'entity_id',
1018
+ 'status',
1019
+ 'updated_at',
1020
+ 'created_at',
1021
+ 'customer_id',
1022
+ 'base_subtotal',
1023
+ 'shipping_amount',
1024
+ )
1025
+ )
1026
+ ->joinLeft(
1027
+ array('item' => 'sales_flat_order_item'),
1028
+ 'order.entity_id = item.order_id',
1029
+ array(
1030
+ 'product_id',
1031
+ 'product_options',
1032
+ 'price',
1033
+ 'original_price',
1034
+ 'product_type',
1035
+ 'qty_ordered',
1036
+ )
1037
+ )
1038
+ ->where('order.status <> ?', 'canceled')
1039
+ ->order(array('order.entity_id', 'item.product_type'))
1040
+ ->limit($limit, ($page - 1) * $limit);
1041
+
1042
+ $this->_getIndexType() == 'delta' ? $select->where('order.created_at >= ? OR order.updated_at >= ?', $this->_getLastIndex()) : '';
1043
+
1044
+ $transactions = $db->fetchAll($select);
1045
+ self::logMem("Transactions - loaded page $page");
1046
+
1047
+ foreach ($transactions as $transaction) {
1048
+ //is configurable
1049
+ if ($transaction['product_type'] == 'configurable') {
1050
+ $configurable[$transaction['product_id']] = $transaction;
1051
+ continue;
1052
+ }
1053
 
1054
+ $productOptions = unserialize($transaction['product_options']);
 
 
1055
 
1056
+ //is configurable - simple product
1057
+ if (intval($transaction['price']) == 0 && $transaction['product_type'] == 'simple') {
1058
+ if (isset($configurable[$productOptions['info_buyRequest']['product']])) {
1059
+ $pid = $configurable[$productOptions['info_buyRequest']['product']];
1060
 
1061
+ $transaction['original_price'] = $pid['original_price'];
1062
+ $transaction['price'] = $pid['price'];
1063
+ } else {
1064
+ $pid = Mage::getModel('catalog/product')->load($productOptions['info_buyRequest']['product']);
1065
 
1066
+ $transaction['original_price'] = ($pid->getPrice());
1067
+ $transaction['price'] = ($pid->getPrice());
1068
 
1069
+ $tmp = array();
1070
+ $tmp['original_price'] = $transaction['original_price'];
1071
+ $tmp['price'] = $transaction['price'];
 
 
1072
 
1073
+ $configurable[$productOptions['info_buyRequest']['product']] = $tmp;
 
 
 
 
 
 
 
 
 
1074
 
1075
+ $pid = null;
1076
+ $tmp = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1077
  }
 
 
 
1078
  }
1079
 
1080
+ $status = 0; // 0 - pending, 1 - confirmed, 2 - shipping
1081
+ if ($transaction['updated_at'] != $transaction['created_at']) {
1082
+ switch ($transaction['status']) {
1083
+ case 'canceled':
1084
+ continue;
1085
+ break;
1086
+ case 'processing':
1087
+ $status = 1;
1088
+ break;
1089
+ case 'complete':
1090
+ $status = 2;
1091
+ break;
1092
+ }
1093
  }
1094
 
1095
+ $transactions_to_save[] = array(
1096
+ 'order_id' => $transaction['entity_id'],
1097
+ 'entity_id' => $transaction['product_id'],
1098
+ 'customer_id' => array_key_exists('customer_id', $transaction) ? $transaction['customer_id'] : '',
1099
+ 'price' => $transaction['original_price'],
1100
+ 'discounted_price' => $transaction['price'],
1101
+ 'quantity' => $transaction['qty_ordered'],
1102
+ 'total_order_value' => ($transaction['base_subtotal'] + $transaction['shipping_amount']),
1103
+ 'shipping_costs' => $transaction['shipping_amount'],
1104
+ 'order_date' => $transaction['created_at'],
1105
+ 'confirmation_date' => $status == 1 ? $transaction['updated_at'] : null,
1106
+ 'shipping_date' => $status == 2 ? $transaction['updated_at'] : null,
1107
+ 'status' => $transaction['status'],
1108
+ );
1109
+ }
1110
 
1111
+ $data = $transactions_to_save;
1112
+ $count = count($transactions);
1113
 
1114
+ $configurable = null;
1115
+ $transactions = null;
1116
 
1117
+ if ($count == 0 && $header) {
1118
+ return;
1119
  }
1120
 
1121
+ if ($header) {
1122
+ $data = array_merge(array(array_keys(end($transactions_to_save))), $transactions_to_save);
1123
+ $header = false;
1124
+ }
1125
+
1126
+ self::logMem('Transactions - save to file');
1127
+ $this->savePartToCsv('transactions.csv', $data);
1128
+ $data = null;
1129
+
1130
+ $page++;
1131
+
1132
  }
1133
 
1134
+ self::logMem('Transactions - end of export');
 
1135
  }
1136
 
1137
+ /**
1138
+ * @return string Index type
1139
+ */
1140
+ protected function _getIndexType()
1141
+ {
1142
+ return static::INDEX_TYPE; // access via late static binding (PHP 5.3)
1143
+ }
1144
 
1145
  /**
1146
  * @description Preparing files to send
1147
  */
1148
+ protected function prepareFiles($website, &$categories = null, &$tags = null)
1149
  {
1150
 
1151
  //Prepare attributes
1152
  $csvFiles = array();
1153
+ if (!file_exists('/tmp/boxalino')) {
1154
+ mkdir('/tmp/boxalino');
1155
  }
1156
 
1157
+ //create csvs
1158
  //save attributes
1159
  foreach ($this->_attributesValuesByName as $attrName => $attrValues) {
1160
  $csvFiles[] = $this->createCsv($this->_helperSearch->sanitizeFieldName($attrName), $attrValues);
1167
  }
1168
 
1169
  //save tags
1170
+ if ($tags != null && $this->_getProductTags() != null) {
1171
  $csvFiles[] = $this->createCsv('tag', $tags);
1172
 
1173
  $loop = 1;
1176
  }
1177
 
1178
  $csvFiles[] = $this->createCsv('product_tag', $csvdata);
 
1179
  }
1180
+ //csvs done
 
1181
 
1182
  //Create name for file
1183
  $exportFile = '/tmp/boxalino/' . $this->_storeConfig['di_username'];
 
1184
  $csvFiles = array_filter($csvFiles);
1185
 
1186
  //Create xml
1187
+ $this->createXML($exportFile . '.xml', ($tags != null && $this->_getProductTags() != null) ? true : false);
1188
 
1189
  //Create zip
 
1190
  $this->createZip($exportFile . '.zip', array_filter($this->_files), $exportFile . '.xml');
1191
 
1192
  return $exportFile;
 
 
 
1193
  }
1194
 
1195
  /**
1196
  * @param $name
1197
  * @param $data
 
1198
  * @return string
1199
  */
1200
  protected function createCsv($name, &$data)
1201
  {
1202
  $file = $name . '.csv';
1203
 
1204
+ if (!is_array($data) || count($data) == 0) {
1205
+ Mage::getModel('adminhtml/session')->addWarning("Data for $file is not an array or is empty. [" . gettype($data) . ']');
1206
  }
1207
 
1208
  $csvdata = array_merge(array(array_keys(end($data))), $data);
1217
  $this->_files[] = $file;
1218
 
1219
  return $file;
 
 
1220
  }
1221
 
1222
  /**
1236
  return $this->_allProductTags;
1237
  }
1238
 
1239
+ protected function createXML($name, $withTag)
1240
  {
1241
 
1242
  $xml = new SimpleXMLElement('<root/>');
1353
  $products->addAttribute('type', 'products');
1354
 
1355
  $sources = $products->addChild('sources');
1356
+ //#########################################################################
1357
 
1358
  //product source
 
1359
  $source = $sources->addChild('source');
1360
  $source->addAttribute('id', 'item_vals');
1361
  $source->addAttribute('type', 'item_data_file');
1364
  $source->addChild('itemIdColumn')->addAttribute('value', 'entity_id');
1365
 
1366
  $this->sxml_append_options($source);
1367
+ //#########################################################################
1368
 
1369
  $attrs = array_keys($this->_attributesValuesByName);
1370
+ if ($this->_storeConfig['export_tags'] && $withTag) {
1371
  $attrs[] = 'tag';
1372
 
1373
  }
1374
 
1375
  foreach ($attrs as $attr) {
1376
 
 
 
 
 
1377
  $attr = $this->_helperSearch->sanitizeFieldName($attr);
1378
 
1379
  //attribute
1406
 
1407
  }
1408
 
1409
+ //########################################################################
1410
  if ($this->_storeConfig['export_categories']) {
1411
  //categories
1412
  $sourceCategory = $sources->addChild('source');
1438
 
1439
  $this->sxml_append_options($source);
1440
  }
1441
+ //#########################################################################
1442
 
1443
  //property
1444
  $properties = $products->addChild('properties');
1445
+ $props = $this->prepareProperties($withTag);
1446
 
1447
  foreach ($props as $prop) {
1448
  if ($prop['id'] == 'entity_id') {
1449
 
1450
  }
1451
 
 
 
 
 
1452
  $property = $properties->addChild('property');
1453
  $property->addAttribute('id', $this->_helperSearch->sanitizeFieldName($prop['id']));
1454
  $property->addAttribute('type', $prop['ptype']);
1474
  }
1475
 
1476
  }
1477
+ //##################################
1478
 
1479
+ //##################################
1480
 
1481
  if ($this->_storeConfig['export_customers']) {
1482
  $customer = simplexml_load_string($customerString);
1494
  $dom->loadXML($xml->asXML());
1495
  $saveXML = $dom->saveXML();
1496
  file_put_contents($name, $saveXML);
1497
+ }
 
1498
 
1499
+ /**
1500
+ * @description add xmlElement to other xmlElement
1501
+ * @param SimpleXMLElement $to
1502
+ * @param SimpleXMLElement $from
1503
+ */
1504
+ protected function sxml_append(SimpleXMLElement $to, SimpleXMLElement $from)
1505
+ {
1506
+ $toDom = dom_import_simplexml($to);
1507
+ $fromDom = dom_import_simplexml($from);
1508
+ $toDom->appendChild($toDom->ownerDocument->importNode($fromDom, true));
1509
  }
1510
 
1511
  /**
1512
+ * @desciption add default xmlElements
1513
  * @param SimpleXMLElement $xml
1514
  */
1515
+ protected function sxml_append_options(SimpleXMLElement &$xml)
1516
  {
1517
  $xml->addChild('format')->addAttribute('value', $this->_helperExporter->XML_FORMAT);
1518
  $xml->addChild('encoding')->addAttribute('value', $this->_helperExporter->XML_ENCODE);
1525
  /**
1526
  * @return array
1527
  */
1528
+ protected function prepareProperties($withTag)
1529
  {
1530
 
1531
  $properties = array();
1532
 
1533
  $attrs = $this->_listOfAttributes;
 
1534
 
1535
  foreach ($attrs as $attr) {
 
1536
  $ptype = 'string';
 
1537
  // set property type
1538
  switch ($attr) {
1539
  case 'name':
1560
  case 'length':
1561
  $ptype = 'number';
1562
  break;
 
1563
  }
1564
 
1565
  if (isset($this->_attributesValuesByName[$attr])) {
1566
  $properties[] = array(
1567
+ 'id' => $attr,
1568
+ 'name' => $attr,
1569
+ 'ptype' => 'text',
1570
+ 'type' => 'reference',
1571
+ 'field' => $attr . '_id',
1572
+ 'has_lang' => false,
1573
  'reference' => $attr
1574
  );
1575
  } elseif ($attr == 'category_ids') {
1589
  break;
1590
  }
1591
  $properties[] = array(
1592
+ 'id' => $attr,
1593
+ 'name' => null,
1594
+ 'ptype' => $ptype,
1595
+ 'type' => $type,
1596
+ 'field' => $field,
1597
+ 'has_lang' => $lang,
1598
  'reference' => $ref
1599
  );
1600
  }
1601
  }
1602
  //tag
1603
+ if ($this->_storeConfig['export_tags'] && $withTag) {
1604
  $properties[] = array(
1605
+ 'id' => 'tag',
1606
+ 'name' => 'tag',
1607
+ 'ptype' => 'text',
1608
+ 'type' => 'reference',
1609
+ 'field' => 'tag_id',
1610
+ 'has_lang' => false,
1611
  'reference' => 'tag'
1612
  );
1613
  }
1615
  //categories
1616
  if ($this->_storeConfig['export_categories']) {
1617
  $properties[] = array(
1618
+ 'id' => 'category',
1619
+ 'name' => 'categories', //property id
1620
+ 'ptype' => 'hierarchical', //property type
1621
+ 'type' => 'reference', //logic type
1622
+ 'field' => 'category_id', //field colummn
1623
+ 'has_lang' => false,
1624
  'reference' => 'categories'
1625
  );
1626
  }
1627
+ $properties[] = array(
1628
+ 'id' => 'product_entity_id',
1629
+ 'name' => null,
1630
+ 'ptype' => 'string',
1631
+ 'type' => 'direct',
1632
+ 'field' => 'entity_id',
1633
+ 'has_lang' => false,
1634
+ 'reference' => null
1635
+ );
1636
 
1637
  return $properties;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1638
  }
1639
 
1640
  /**
1673
  {
1674
 
1675
  $fields = array(
1676
+ 'username' => $this->_storeConfig['di_username'],
1677
+ 'password' => $this->_storeConfig['di_password'],
1678
+ 'account' => $this->_storeConfig['di_account'],
1679
+ 'template' => 'standard_source',
1680
+ 'xml' => file_get_contents($file . '.xml')
1681
  );
1682
 
1683
  $url = $this->_helperExporter->getXMLSyncUrl($this->_storeConfig['account_dev']);
1694
  curl_setopt($s, CURLOPT_URL, $url);
1695
  curl_setopt($s, CURLOPT_TIMEOUT, 35000);
1696
  curl_setopt($s, CURLOPT_POST, true);
1697
+ curl_setopt($s, CURLOPT_ENCODING, '');
1698
  curl_setopt($s, CURLOPT_RETURNTRANSFER, true);
1699
  curl_setopt($s, CURLOPT_POSTFIELDS, $fields);
1700
 
1712
  protected function pushZip($file)
1713
  {
1714
  $fields = array(
1715
+ 'username' => $this->_storeConfig['di_username'],
1716
+ 'password' => $this->_storeConfig['di_password'],
1717
+ 'account' => $this->_storeConfig['di_account'],
1718
+ 'dev' => $this->_storeConfig['account_dev'] == 0 ? 'false' : 'true',
1719
+ 'delta' => $this->_getIndexType() == 'delta' ? 'true' : 'false', // I know...
1720
+ 'data' => "@$file.zip;type=application/zip",
1721
  );
1722
 
1723
  $url = $this->_helperExporter->getZIPSyncUrl($this->_storeConfig['account_dev']);
1725
  return $this->pushFile($fields, $url, 'zip');
1726
  }
1727
 
1728
+ protected function savePartToCsv($file, &$data)
 
 
 
 
 
 
 
 
1729
  {
 
1730
 
1731
+ if (!file_exists('/tmp/boxalino')) {
1732
+ mkdir('/tmp/boxalino');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1733
  }
1734
 
1735
  //save
1736
+ if (!in_array($file, $this->_files)) {
1737
  $this->_files[] = $file;
1738
  }
1739
 
1747
 
1748
  }
1749
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1750
  /**
1751
+ * Store memory tracking information in log file, if enabled
1752
  */
1753
+ private static function logMem($message)
1754
  {
1755
+ $callers = debug_backtrace();
1756
+ Boxalino_CemSearch_Model_Logger::saveMemoryTracking(
1757
+ 'info',
1758
+ 'Indexer',
1759
+ array(
1760
+ 'memory_usage' => memory_get_usage(true),
1761
+ 'method' => $callers[1]['function'],
1762
+ 'description' => $message
1763
+ )
1764
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1765
  }
1766
 
1767
  /**
1768
+ * Fetch entity id for a entity type.
1769
  *
1770
+ * @param string $entityType
1771
+ * @return null|string
1772
  */
1773
+ public function getEntityIdFor($entityType)
1774
  {
1775
+ if ($this->_entityIds == null) {
1776
+ $db = $this->_getReadAdapter();
1777
+ $select = $db->select()
1778
+ ->from(
1779
+ 'eav_entity_type',
1780
+ array('entity_type_id', 'entity_type_code')
1781
+ );
1782
+ $this->_entityIds = array();
1783
+ foreach ($db->fetchAll($select) as $row) {
1784
+ $this->_entityIds[$row['entity_type_code']] = $row['entity_type_id'];
1785
+ }
 
1786
  }
1787
+ return array_key_exists($entityType, $this->_entityIds) ? $this->_entityIds[$entityType] : null;
 
1788
  }
1789
 
1790
  }
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>boxalino_plugin</name>
4
- <version>1.0.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.boxalino.com">Custom License</license>
7
  <channel>community</channel>
@@ -18,9 +18,9 @@ Boxalino is the best solution for Conversion Optimization on the market that int
18
  Check out www.boxalino.com for details or give us a shout at sales@boxalino.com.</description>
19
  <notes>Minor changes, thanks everyone for the feedback.</notes>
20
  <authors><author><name>Boxalino</name><user>Boxalino</user><email>support@boxalino.com</email></author></authors>
21
- <date>2014-10-22</date>
22
- <time>14:50:14</time>
23
- <contents><target name="magelocal"><dir name="Boxalino"><dir name="CemSearch"><dir name="Block"><file name="Abstract.php" hash="45253ec10623b07c67cd623c626ad5f4"/><file name="Autocomplete.php" hash="aeaac0c28363bd9202c9daa620cab986"/><dir name="Cart"><file name="Crosssell.php" hash="fabc21793a718693a3d5a2db345dd638"/></dir><file name="Head.php" hash="5bbb03b8b0e8371559f4de05942183e3"/><dir name="Product"><dir name="List"><file name="Related.php" hash="fbef1af7977e15dd7e7e8063fdca5f49"/><file name="Upsell.php" hash="ebc3d467479811012e155371b97a69e3"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="1c7101bfe4cbc861c6490013539cd5de"/><dir name="P13n"><file name="Adapter.php" hash="5b011b673b67d90e99bc0d2213363022"/><file name="Client.php" hash="a4d0dd78a9c35b4d0ba1c32e1cff3231"/><file name="Config.php" hash="82597fa7e5fc6695137ad2f96267378a"/><file name="Recommendation.php" hash="cf23dac423edc4a46454546f6fad4534"/><file name="Sort.php" hash="83ab4da66d6e8122f4c28a9da3576d19"/></dir></dir><dir name="Lib"><file name="AbstractThrift.php" hash="d6c88b8524dbd810d51ca9b568ca64ee"/><file name="P13nService.php" hash="5e3f956a5cd75bc64e53df92f02597eb"/><file name="Types.php" hash="a6b956aff5a57a95042234bfb88f7556"/><dir name="vendor"><dir name="Thrift"><dir name="Base"><file name="TBase.php" hash="b383bf43ac76a57e3b1168cfacffbf22"/></dir><dir name="ClassLoader"><file name="ThriftClassLoader.php" hash="13159566c8b2dcc5b260ef9a0844167e"/></dir><dir name="Exception"><file name="TApplicationException.php" hash="1ee65cc5fb3dc82550a85cc18a31850c"/><file name="TException.php" hash="756e6a847c9e6bd1560c24b9a7373d2c"/><file name="TProtocolException.php" hash="148ebd5d8eba2587cd6e039cf70e04ab"/><file name="TTransportException.php" hash="aca39eea001fcbfd452db9ca7d5c218c"/></dir><dir name="Factory"><file name="TBinaryProtocolFactory.php" hash="bcd6e0555d6e2670a3bc7dd39ff3dbaf"/><file name="TCompactProtocolFactory.php" hash="0118b6363e09080548de3c6daf153290"/><file name="TJSONProtocolFactory.php" hash="28af1d10b4133df7f8ad8022ca39d703"/><file name="TProtocolFactory.php" hash="300bf2d805fa4a227cc3dc2b6ed0200c"/><file name="TStringFuncFactory.php" hash="242f32ade732f9c0d9b62a81b6901cd4"/><file name="TTransportFactory.php" hash="8347271458aea0453e774170a5b3e9fd"/></dir><file name="HttpP13n.php" hash="d066d652e7b24e593b389c4374e256aa"/><dir name="Protocol"><dir name="JSON"><file name="BaseContext.php" hash="ed1d83fba59a1d04c07416094ece8ee1"/><file name="ListContext.php" hash="9c8a970f54c30be1299c2d38da60ed56"/><file name="LookaheadReader.php" hash="315a96446f0f530ed1b0b1350b37f58d"/><file name="PairContext.php" hash="3fa06b3f7c9698642aefe00cd322f68b"/></dir><file name="TBinaryProtocol.php" hash="933d2be5503504cddd544992a4af0ee3"/><file name="TBinaryProtocolAccelerated.php" hash="444ba8026d73b83fbcf303d9a550cb70"/><file name="TCompactProtocol.php" hash="6e68904415f43e7575b00e6e93448faf"/><file name="TJSONProtocol.php" hash="fac76e10fbc711cbfbcf6bdbc0b60191"/><file name="TProtocol.php" hash="d9c9a8105ad160bf0b87e8053d4b9d7c"/></dir><dir name="Serializer"><file name="TBinarySerializer.php" hash="e1fef75686b1fbadc28242b7f3697397"/></dir><dir name="Server"><file name="TForkingServer.php" hash="6e319d0d7f45350a03e387fc2f22473d"/><file name="TServer.php" hash="dc87f6a299fb4fb9ab76206f3b6bec72"/><file name="TServerSocket.php" hash="468fc875e7a5e4899e502e95f823455d"/><file name="TServerTransport.php" hash="ca2ab3e25a0760d37eb3538274dfaccb"/><file name="TSimpleServer.php" hash="38d5685001585a0d9f31b9d8c46656d2"/></dir><dir name="StringFunc"><file name="Core.php" hash="4493a096c73f5922316d95cc2c5fb687"/><file name="Mbstring.php" hash="b5ee27dd6bdceee0f2133df01c8d4fcd"/><file name="TStringFunc.php" hash="89fd7900f1b258391e4d4fdc924bc0f0"/></dir><dir name="Transport"><file name="P13nTHttpClient.php" hash="8223e00845b717bb55981649d9ce6616"/><file name="TBufferedTransport.php" hash="7ace771173641cf47b3b11ca0bfebcfa"/><file name="TFramedTransport.php" hash="c6fc032e990e4cf3507741ef1d5b83b2"/><file name="THttpClient.php" hash="b299d30eecc318d7dde4d012ebe8a512"/><file name="TMemoryBuffer.php" hash="7367faa512ec8d25489819ca2ed8848f"/><file name="TNullTransport.php" hash="82d683d7d76ef2938fad1c58878f45e5"/><file name="TPhpStream.php" hash="44769e5da4709a4b6c2025137e4898b3"/><file name="TSocket.php" hash="d689b1f877eda19f7caaa9cb46788f96"/><file name="TSocketPool.php" hash="73d86dbd017130fe2aa0778132b42b26"/><file name="TTransport.php" hash="9185e82d3a440d1db97c6983573bd1ab"/></dir><dir name="Type"><file name="TMessageType.php" hash="20a9fb9a1de1ffe03bfac3057c913101"/><file name="TType.php" hash="261cc40ce2573ebf414c0ec06a2ee093"/></dir></dir></dir></dir><dir name="Model"><file name="Advanced.php" hash="d9c87128bd8e25dd1e401e3e0a837d10"/><file name="Logger.php" hash="a222e0461ade14b41012d416d2a3a45c"/><file name="Observer.php" hash="55476eeb88a30b69a99f878e7abcb5fc"/><dir name="Resource"><dir name="Advanced"><file name="Collection.php" hash="db5c45e391512f25198195d25f1f09f7"/></dir><file name="Advanced.php" hash="9373a9e12a268ab37f1d111f8b77cd57"/><file name="Fulltext.php" hash="0b333b366e433d778891441c67b35f65"/></dir><file name="Session.php" hash="f5f6948355cfc10882dd7a4f80e2713f"/></dir><dir name="controllers"><file name="AdvancedController.php" hash="084f9b0a5cdf1594b95fbcad5250256b"/><file name="AjaxController.php" hash="8331416b6beee0fb635da991790b8f40"/><file name="IndexController.php" hash="0f9ba5d1ee9bf4d7f9d6868a502738cd"/><file name="ResultController.php" hash="e43539a5921da7db3364b8e70dac2bdc"/></dir><dir name="etc"><file name="adminhtml.xml" hash="13af90d012dc3871c9af59c804d3588f"/><file name="config.xml" hash="61fb6a31b4702c39beaaf32490cf791f"/><file name="system.xml" hash="b420dcb3910abbaa251a8b3b68285c00"/></dir></dir><dir name="Exporter"><dir name="Helper"><file name="Data.php" hash="e284068074518b3126a4ea720cc94f71"/></dir><dir name="Model"><file name="Delta.php" hash="664b8a733751dd7e85169f3c9d99322f"/><file name="Indexer.php" hash="d9c10401971e9544992fbf34594fb600"/><dir name="Mysql4"><dir name="Exporter"><file name="Delta.php" hash="298628009eb4bf5afca7d12cb28d2a79"/><file name="Indexer.php" hash="9cd98755bdd03146a9661ecdd3f62e76"/></dir><file name="Indexer.php" hash="ff84d7a1116d07bd42c5e899a77bfb2d"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="57e26697c6d9b55a58f6da88b5a8d822"/><file name="config.xml" hash="c46f60130d206e165fd3d84c2b1915a1"/><file name="system.xml" hash="0cc11c40a20d5e3102fa72e02c536e97"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="boxalino.xml" hash="03575b20bf1e91b9307fad66cdfdabf4"/></dir><dir name="template"><dir name="boxalino"><dir name="catalogsearch"><file name="form.mini.phtml" hash="19b7d2c8d3fbe8fb6f7481bcc5747eb5"/></dir><file name="head.phtml" hash="a7246e26d2e98cdac6a2d4664058b926"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Boxalino_CemSearch.xml" hash="94c2434b422de7dfaac195298310f56d"/><file name="Boxalino_Exporter.xml" hash="b50cc52bc40c36b25677b6ef60bbf376"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="js"><file name="boxalinoAutocomplete.js" hash="ea1f943c034c0dcc79c3615e01531297"/><file name="jquery-1.10.2.min.js" hash="628072e7212db1e8cdacb22b21752cda"/><file name="jquery-noConflict.js" hash="6932bbddf488374a70b55fbb62052fd2"/></dir><dir name="css"><file name="boxalinoCemSearch.css" hash="799e9fb003952533360ac38bea3e7bc0"/></dir></dir></dir></dir></target></contents>
24
  <compatible/>
25
- <dependencies><required><php><min>5.3.0</min><max>5.5.0</max></php></required></dependencies>
26
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>boxalino_plugin</name>
4
+ <version>1.1.0.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.boxalino.com">Custom License</license>
7
  <channel>community</channel>
18
  Check out www.boxalino.com for details or give us a shout at sales@boxalino.com.</description>
19
  <notes>Minor changes, thanks everyone for the feedback.</notes>
20
  <authors><author><name>Boxalino</name><user>Boxalino</user><email>support@boxalino.com</email></author></authors>
21
+ <date>2014-11-07</date>
22
+ <time>14:57:48</time>
23
+ <contents><target name="magelocal"><dir name="Boxalino"><dir name="CemSearch"><dir name="Block"><file name="Abstract.php" hash="45253ec10623b07c67cd623c626ad5f4"/><file name="Autocomplete.php" hash="aeaac0c28363bd9202c9daa620cab986"/><dir name="Cart"><file name="Crosssell.php" hash="953705995c9c867e6b0b76ac89b78645"/></dir><file name="Head.php" hash="7619e84e7ddcc3c7d932470e2dc88c88"/><dir name="Product"><dir name="List"><file name="Related.php" hash="fbef1af7977e15dd7e7e8063fdca5f49"/><file name="Upsell.php" hash="ebc3d467479811012e155371b97a69e3"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="1c7101bfe4cbc861c6490013539cd5de"/><dir name="P13n"><file name="Adapter.php" hash="3bdeb7cdc6ae2d0dfd240c50cc0bbd93"/><file name="Client.php" hash="57b407b2b9eee0bdfdda8d32fa96edbb"/><file name="Config.php" hash="82597fa7e5fc6695137ad2f96267378a"/><file name="Recommendation.php" hash="cf23dac423edc4a46454546f6fad4534"/><file name="Sort.php" hash="83ab4da66d6e8122f4c28a9da3576d19"/></dir></dir><dir name="Lib"><file name="AbstractThrift.php" hash="d6c88b8524dbd810d51ca9b568ca64ee"/><file name="P13nService.php" hash="5e3f956a5cd75bc64e53df92f02597eb"/><file name="Types.php" hash="a6b956aff5a57a95042234bfb88f7556"/><dir name="vendor"><dir name="Thrift"><dir name="Base"><file name="TBase.php" hash="b383bf43ac76a57e3b1168cfacffbf22"/></dir><dir name="ClassLoader"><file name="ThriftClassLoader.php" hash="13159566c8b2dcc5b260ef9a0844167e"/></dir><dir name="Exception"><file name="TApplicationException.php" hash="1ee65cc5fb3dc82550a85cc18a31850c"/><file name="TException.php" hash="756e6a847c9e6bd1560c24b9a7373d2c"/><file name="TProtocolException.php" hash="148ebd5d8eba2587cd6e039cf70e04ab"/><file name="TTransportException.php" hash="aca39eea001fcbfd452db9ca7d5c218c"/></dir><dir name="Factory"><file name="TBinaryProtocolFactory.php" hash="bcd6e0555d6e2670a3bc7dd39ff3dbaf"/><file name="TCompactProtocolFactory.php" hash="0118b6363e09080548de3c6daf153290"/><file name="TJSONProtocolFactory.php" hash="28af1d10b4133df7f8ad8022ca39d703"/><file name="TProtocolFactory.php" hash="300bf2d805fa4a227cc3dc2b6ed0200c"/><file name="TStringFuncFactory.php" hash="242f32ade732f9c0d9b62a81b6901cd4"/><file name="TTransportFactory.php" hash="8347271458aea0453e774170a5b3e9fd"/></dir><file name="HttpP13n.php" hash="662ddadcdcabcacfddcf0127918def10"/><dir name="Protocol"><dir name="JSON"><file name="BaseContext.php" hash="ed1d83fba59a1d04c07416094ece8ee1"/><file name="ListContext.php" hash="9c8a970f54c30be1299c2d38da60ed56"/><file name="LookaheadReader.php" hash="315a96446f0f530ed1b0b1350b37f58d"/><file name="PairContext.php" hash="3fa06b3f7c9698642aefe00cd322f68b"/></dir><file name="TBinaryProtocol.php" hash="933d2be5503504cddd544992a4af0ee3"/><file name="TBinaryProtocolAccelerated.php" hash="444ba8026d73b83fbcf303d9a550cb70"/><file name="TCompactProtocol.php" hash="6e68904415f43e7575b00e6e93448faf"/><file name="TJSONProtocol.php" hash="fac76e10fbc711cbfbcf6bdbc0b60191"/><file name="TProtocol.php" hash="d9c9a8105ad160bf0b87e8053d4b9d7c"/></dir><dir name="Serializer"><file name="TBinarySerializer.php" hash="e1fef75686b1fbadc28242b7f3697397"/></dir><dir name="Server"><file name="TForkingServer.php" hash="6e319d0d7f45350a03e387fc2f22473d"/><file name="TServer.php" hash="dc87f6a299fb4fb9ab76206f3b6bec72"/><file name="TServerSocket.php" hash="468fc875e7a5e4899e502e95f823455d"/><file name="TServerTransport.php" hash="ca2ab3e25a0760d37eb3538274dfaccb"/><file name="TSimpleServer.php" hash="38d5685001585a0d9f31b9d8c46656d2"/></dir><dir name="StringFunc"><file name="Core.php" hash="4493a096c73f5922316d95cc2c5fb687"/><file name="Mbstring.php" hash="b5ee27dd6bdceee0f2133df01c8d4fcd"/><file name="TStringFunc.php" hash="89fd7900f1b258391e4d4fdc924bc0f0"/></dir><dir name="Transport"><file name="P13nTCurlClient.php" hash="aaa63d036b6920b57e0777f90c08064f"/><file name="P13nTHttpClient.php" hash="8223e00845b717bb55981649d9ce6616"/><file name="TBufferedTransport.php" hash="7ace771173641cf47b3b11ca0bfebcfa"/><file name="TCurlClient.php" hash="16b14d5f643b20c872468dc96218708d"/><file name="TFramedTransport.php" hash="c6fc032e990e4cf3507741ef1d5b83b2"/><file name="THttpClient.php" hash="b299d30eecc318d7dde4d012ebe8a512"/><file name="TMemoryBuffer.php" hash="7367faa512ec8d25489819ca2ed8848f"/><file name="TNullTransport.php" hash="82d683d7d76ef2938fad1c58878f45e5"/><file name="TPhpStream.php" hash="44769e5da4709a4b6c2025137e4898b3"/><file name="TSocket.php" hash="d689b1f877eda19f7caaa9cb46788f96"/><file name="TSocketPool.php" hash="73d86dbd017130fe2aa0778132b42b26"/><file name="TTransport.php" hash="9185e82d3a440d1db97c6983573bd1ab"/></dir><dir name="Type"><file name="TMessageType.php" hash="20a9fb9a1de1ffe03bfac3057c913101"/><file name="TType.php" hash="261cc40ce2573ebf414c0ec06a2ee093"/></dir></dir></dir></dir><dir name="Model"><file name="Advanced.php" hash="3f8e4904b2017fbf20bd5e458902b660"/><file name="Logger.php" hash="a222e0461ade14b41012d416d2a3a45c"/><file name="Observer.php" hash="55476eeb88a30b69a99f878e7abcb5fc"/><dir name="Resource"><dir name="Advanced"><file name="Collection.php" hash="db5c45e391512f25198195d25f1f09f7"/></dir><file name="Advanced.php" hash="9373a9e12a268ab37f1d111f8b77cd57"/><file name="Fulltext.php" hash="f0a6f2811fb26b3d617c25556eacef53"/></dir><file name="Session.php" hash="f5f6948355cfc10882dd7a4f80e2713f"/></dir><dir name="controllers"><file name="AdvancedController.php" hash="a39f542ea8beeeab5e3b4a0082472816"/><file name="AjaxController.php" hash="8331416b6beee0fb635da991790b8f40"/><file name="IndexController.php" hash="0f9ba5d1ee9bf4d7f9d6868a502738cd"/><file name="ResultController.php" hash="e43539a5921da7db3364b8e70dac2bdc"/></dir><dir name="etc"><file name="adminhtml.xml" hash="13af90d012dc3871c9af59c804d3588f"/><file name="config.xml" hash="61fb6a31b4702c39beaaf32490cf791f"/><file name="system.xml" hash="b420dcb3910abbaa251a8b3b68285c00"/></dir></dir><dir name="Exporter"><dir name="Helper"><file name="Data.php" hash="80a666faee82acd4a5c598e82b767fc8"/></dir><dir name="Model"><file name="Delta.php" hash="664b8a733751dd7e85169f3c9d99322f"/><file name="Indexer.php" hash="d9c10401971e9544992fbf34594fb600"/><dir name="Mysql4"><dir name="Exporter"><file name="Delta.php" hash="f4175abe070a035fd16399d3dbda1509"/><file name="Indexer.php" hash="bc1524bba09adc0c796872c718d5b6c1"/></dir><file name="Indexer.php" hash="488347c62c3144f7c4122e890f247c09"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="57e26697c6d9b55a58f6da88b5a8d822"/><file name="config.xml" hash="c46f60130d206e165fd3d84c2b1915a1"/><file name="system.xml" hash="0cc11c40a20d5e3102fa72e02c536e97"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="boxalino.xml" hash="03575b20bf1e91b9307fad66cdfdabf4"/></dir><dir name="template"><dir name="boxalino"><dir name="catalogsearch"><file name="form.mini.phtml" hash="19b7d2c8d3fbe8fb6f7481bcc5747eb5"/></dir><file name="head.phtml" hash="a7246e26d2e98cdac6a2d4664058b926"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Boxalino_CemSearch.xml" hash="94c2434b422de7dfaac195298310f56d"/><file name="Boxalino_Exporter.xml" hash="b50cc52bc40c36b25677b6ef60bbf376"/></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="js"><file name="boxalinoAutocomplete.js" hash="ea1f943c034c0dcc79c3615e01531297"/><file name="jquery-1.10.2.min.js" hash="628072e7212db1e8cdacb22b21752cda"/><file name="jquery-noConflict.js" hash="6932bbddf488374a70b55fbb62052fd2"/></dir><dir name="css"><file name="boxalinoCemSearch.css" hash="799e9fb003952533360ac38bea3e7bc0"/></dir></dir></dir></dir></target></contents>
24
  <compatible/>
25
+ <dependencies><required><php><min>5.3.0</min><max>5.6.0</max></php></required></dependencies>
26
  </package>