LetsSyncroLLC_Oct8ne - Version 2.1.0

Version Notes

- New pluggable search system.
- New pluggable image helpers to support specific scenarios.
- New image fallback system.
- New product description fallback system.
- Debug & instrumentation helpers.
- Custom settings to support different scenarios.
- New sales data gathering system.
- API 2.1:
o New getProductsSummary method
o New simplified data structures
o Automatic API tester (beta)

Download this release

Release Info

Developer Oct8ne
Extension LetsSyncroLLC_Oct8ne
Version 2.1.0
Comparing to
See all releases


Code changes from version 2.0.3 to 2.1.0

Files changed (36) hide show
  1. app/code/community/LetsSyncroLLC/Oct8ne/Block/Accountconfig.php +0 -2
  2. app/code/community/LetsSyncroLLC/Oct8ne/Helper/CustomerData.php +6 -15
  3. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Data.php +204 -92
  4. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Debug.php +32 -0
  5. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Image.php +0 -32
  6. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Image/Default.php +219 -0
  7. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Reports.php +43 -0
  8. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Search.php +0 -74
  9. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Search/Base.php +84 -0
  10. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Search/Magento.php +164 -0
  11. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Search/Sli.php +210 -0
  12. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Version.php +1 -1
  13. app/code/community/LetsSyncroLLC/Oct8ne/Helper/Wishlist.php +7 -7
  14. app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Order.php +9 -0
  15. app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Order/Collection.php +8 -0
  16. app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Orderproducts.php +0 -8
  17. app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Orderproducts/Collection.php +0 -9
  18. app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Quoteproducts.php +0 -8
  19. app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Quoteproducts/Collection.php +0 -9
  20. app/code/community/LetsSyncroLLC/Oct8ne/Model/Observer.php +143 -53
  21. app/code/community/LetsSyncroLLC/Oct8ne/Model/Order.php +9 -0
  22. app/code/community/LetsSyncroLLC/Oct8ne/Model/SearchEngines.php +12 -0
  23. app/code/community/LetsSyncroLLC/Oct8ne/controllers/FrameController.php +93 -168
  24. app/code/community/LetsSyncroLLC/Oct8ne/controllers/SetupController.php +172 -0
  25. app/code/community/LetsSyncroLLC/Oct8ne/etc/config.xml +53 -48
  26. app/code/community/LetsSyncroLLC/Oct8ne/etc/system.xml +130 -7
  27. app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-install-2.1.0.php +74 -0
  28. app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-1-2.1.0.php +59 -0
  29. app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-1.1.6-1.1.7.php +4 -4
  30. app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-1.1.7-2.0.0.php +8 -0
  31. app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-2.0.0-2.0.3.php +8 -0
  32. app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-2.0.0.php +0 -6
  33. app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-2.0.3-2.1.0.php +42 -0
  34. app/design/frontend/base/default/template/oct8ne/letssyncro.phtml +3 -2
  35. app/etc/modules/LetsSyncroLLC_Oct8ne.xml +1 -1
  36. package.xml +15 -5
app/code/community/LetsSyncroLLC/Oct8ne/Block/Accountconfig.php CHANGED
@@ -57,8 +57,6 @@ class LetsSyncroLLC_Oct8ne_Block_Accountconfig extends Mage_Core_Block_Template
57
  document.getElementById(\'generalsettings\').submit();
58
  }
59
  </script>
60
- <link href="' . Mage::getStoreConfig('web/unsecure/base_url') . '/app/design/adminhtml/default/default/template/oct8ne/letssyncro.css" rel="stylesheet" type="text/css" />
61
- <script type="text/javascript" src="' . Mage::getStoreConfig('web/unsecure/base_url') . '/app/design/adminhtml/default/default/template/oct8ne/letssyncro.js"></script>
62
  <div class="content-header">
63
  <p><img src="' . $this->getSkinUrl('images/LetsSyncro_Logo.png') . '" alt="Oct8ne" title="Oct8ne" /></p>
64
  </div>
57
  document.getElementById(\'generalsettings\').submit();
58
  }
59
  </script>
 
 
60
  <div class="content-header">
61
  <p><img src="' . $this->getSkinUrl('images/LetsSyncro_Logo.png') . '" alt="Oct8ne" title="Oct8ne" /></p>
62
  </div>
app/code/community/LetsSyncroLLC/Oct8ne/Helper/CustomerData.php CHANGED
@@ -1,12 +1,7 @@
1
  <?php
2
 
3
  class LetsSyncroLLC_Oct8ne_Helper_CustomerData extends Mage_Core_Helper_Abstract {
4
-
5
- static public function getCurrency() {
6
- $raw = Mage::app()->getLocale()->currency(Mage::app()->getStore()->getCurrentCurrencyCode())->toCurrency();
7
- return mb_substr($raw, 0, 1, mb_detect_encoding($raw));
8
- }
9
-
10
  public function getLoginData() {
11
  if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
12
  return null;
@@ -22,19 +17,15 @@ class LetsSyncroLLC_Oct8ne_Helper_CustomerData extends Mage_Core_Helper_Abstract
22
  }
23
 
24
  public function getCartData() {
25
- $currency = self::getCurrency();
 
26
  $quote = Mage::getSingleton('checkout/session')->getQuote();
27
  $items = $quote->getAllVisibleItems();
28
-
29
- $productIds = array();
30
- $qtysPerProduct = array();
31
  foreach ($items as $item) {
32
- $id = $item->getProductId();
33
- $productIds[] = $id;
34
- $qtysPerProduct[$id] = $item->getQty();
35
  }
36
- $dataHelper = Mage::helper("oct8ne"); /* @var $dataHelper LetsSyncroLLC_Oct8ne_Helper_Data */
37
- return $dataHelper->getProductsInfoByIds($productIds, $qtysPerProduct);
38
  }
39
 
40
  public function getWishlistData() {
1
  <?php
2
 
3
  class LetsSyncroLLC_Oct8ne_Helper_CustomerData extends Mage_Core_Helper_Abstract {
4
+
 
 
 
 
 
5
  public function getLoginData() {
6
  if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
7
  return null;
17
  }
18
 
19
  public function getCartData() {
20
+ $dataHelper = Mage::helper("oct8ne"); /* @var $dataHelper LetsSyncroLLC_Oct8ne_Helper_Data */
21
+
22
  $quote = Mage::getSingleton('checkout/session')->getQuote();
23
  $items = $quote->getAllVisibleItems();
24
+ $result = array();
 
 
25
  foreach ($items as $item) {
26
+ $result[] = $dataHelper->createProductSummaryFromProduct($item->product, $item->getQty());
 
 
27
  }
28
+ return $result;
 
29
  }
30
 
31
  public function getWishlistData() {
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Data.php CHANGED
@@ -2,33 +2,91 @@
2
 
3
  class LetsSyncroLLC_Oct8ne_Helper_Data extends Mage_Core_Helper_Abstract {
4
 
5
- static protected $_productThumbnail = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
- static public function getProductsInfoByIds($productIds, $qtyPerProduct = null) {
 
 
 
 
 
 
 
 
 
 
8
  if (empty($productIds)) {
9
  return array();
10
  }
 
 
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  $attributes = Mage::getSingleton('catalog/config')->getProductAttributes();
13
  $products = Mage::getModel('catalog/product')
14
  ->getCollection()
15
  ->addAttributeToFilter('entity_id', array('in' => $productIds))
16
  ->addAttributeToSelect($attributes)
17
- ->addAttributeToSelect('description')
18
  ->addAttributeToSelect('image')
 
 
19
  ->addFinalPrice();
20
 
 
 
 
21
  // Add stock information
22
  Mage::getModel('catalogInventory/stock')->addItemsToProducts($products);
23
 
24
- // Loads the media gallery for every product
25
- self::addMediaGalleryAttributeToCollection($products);
 
 
26
 
27
- // Store the products in a dictionary
28
  $productDict = array();
29
  foreach ($products as $product) {
30
  $id = $product->getId();
31
- $qty = $qtyPerProduct && array_key_exists($id, $qtyPerProduct)? $qtyPerProduct[$id]: null;
32
  $productDict[$id] = self::createProductInfoFromProduct($product, $qty);
33
  }
34
 
@@ -47,42 +105,66 @@ class LetsSyncroLLC_Oct8ne_Helper_Data extends Mage_Core_Helper_Abstract {
47
  return self::createProductInfoFromProduct($product, $qty);
48
  }
49
 
50
- static public function createProductInfoFromProduct($product, $qty = null) {
51
  $product_id = $product->getId();
52
- $description = htmlspecialchars($product->getDescription(), ENT_QUOTES, "UTF-8");
53
- $description = trim($description, "\r\n\t ");
54
- $description = str_replace("\r", "", $description);
55
- $description = str_replace("\t", "", $description);
56
- $description = str_replace("\n", "&lt;br\/&gt;", $description);
57
-
58
  $prevPrice = Mage::helper('core')->currency($product->getPrice(), false, false);
59
  $finalPrice = Mage::helper('core')->currency($product->getFinalPrice(), false, false);
60
  $productUrl = self::_remove_http($product->getProductUrl());
61
  $thumbnail = self::_remove_http(self::getProductThumbnail($product, 120));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
 
 
 
 
 
 
 
 
63
  $useProductUrl = true;
64
  if (self::isSaleable($product)) {
65
  if (!self::productHasOptions($product)) {
66
  $useProductUrl = false;
67
  }
68
  }
69
- $medias = self::getProductImagesUrl($product); // Requires a database query
70
-
71
- $tmp = is_null($qty) ? array() : array('qty' => $qty);
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  $result = array_merge($tmp, array(
74
- 'internalId' => $product_id,
75
- 'title' => htmlspecialchars($product->getName(), ENT_QUOTES, "UTF-8"),
76
- 'prevPrice' => number_format($prevPrice, '2', '.', ','),
77
- 'price' => number_format($finalPrice, '2', '.', ','),
78
  'description' => trim($description),
79
  'rating' => 'no-rating',
80
- 'productUrl' => $productUrl,
81
  'addToCartUrl' => self::getProductBuyUrl($product),
82
  'useProductUrl' => $useProductUrl,
83
  'medias' => $medias,
84
- 'thumbnail' => $thumbnail,
85
  ));
 
 
86
  return $result;
87
  }
88
 
@@ -93,6 +175,11 @@ class LetsSyncroLLC_Oct8ne_Helper_Data extends Mage_Core_Helper_Abstract {
93
  $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
94
  }
95
 
 
 
 
 
 
96
  if ($stockItem->getManageStock() > 0) {
97
  $stock = intval($stockItem->getQty());
98
  if ($stock > 0) {
@@ -118,68 +205,62 @@ class LetsSyncroLLC_Oct8ne_Helper_Data extends Mage_Core_Helper_Abstract {
118
  ->addAttributeToSelect('id')
119
  ->addAttributeToSort('price', 'asc')
120
  ->setPageSize($pageSize)
121
- ->setCurPage($page);
122
 
123
  if ($relatedCollection->count() > 0) {
124
- return self::loadRelatedProductsFromCollectionOfIds($relatedCollection, $page, $pageSize);
 
 
 
 
125
  }
126
 
127
- // If no related products specified by admins, get them by category
128
- $categoryIds = $product->getCategoryIds();
129
- if (empty($categoryIds)) {
130
- return array();
131
  }
132
-
133
- $collection = mage::getModel('catalog/product')->getCollection()
134
- ->addAttributeToSelect('id')
135
- ->addAttributeToFilter('visibility', 4)
136
- ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
137
- ->addAttributeToFilter('entity_id', array('neq' => $productId))
138
- ->addAttributeToSort('price', 'asc');
139
-
140
- Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($collection);
141
-
142
- $collection->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
143
- ->addAttributeToFilter('category_id', array('in' => $categoryIds));
144
-
145
- $collection->getSelect()->group('e.entity_id');
146
- $collection->setPageSize($pageSize)
147
- ->setCurPage($page);
148
-
149
- return self::loadRelatedProductsFromCollectionOfIds($collection, $page, $pageSize);
150
  }
151
 
152
- static private function loadRelatedProductsFromCollectionOfIds($collection, $page, $pageSize) {
153
- $relatedProductIds = array();
154
- foreach ($collection as $relatedProduct) {
155
- $relatedProductIds[] = $relatedProduct->getId();
156
- }
157
-
158
  // Until the coviewer supports pagination, just
159
  // return as total the number of related products in the first page
160
  $productsCount = sizeof($relatedProductIds);
161
-
162
  $result = array(
163
  'total' => $productsCount,
164
- 'results' => self::getProductsInfoByIds($relatedProductIds)
165
  );
166
 
167
  return $result;
168
  }
169
 
170
- static public function getProductThumbnail($product, $width = null) {
171
- $id = $product->getId();
172
- if (array_key_exists($id, self::$_productThumbnail)) {
173
- return self::$_productThumbnail[$id];
 
 
 
 
 
 
 
 
 
 
 
174
  }
175
- $thumb = Mage::helper('catalog/image')->init($product, 'image');
176
- if (!is_null($width)) {
177
- $thumb->resize($width);
 
 
 
178
  }
179
- $file = (string) $thumb;
180
- self::$_productThumbnail[$id] = $file;
181
-
182
- return $file;
183
  }
184
 
185
  static private function _remove_http($str) {
@@ -208,29 +289,8 @@ class LetsSyncroLLC_Oct8ne_Helper_Data extends Mage_Core_Helper_Abstract {
208
  }
209
 
210
  static private function getProductImagesUrl($product) {
211
- $v = array();
212
- $gallery_data = $product->getData('media_gallery');
213
- if (!$gallery_data) {
214
- $product->load('media_gallery');
215
- $gallery_data = $product->getData('media_gallery');
216
- }
217
- $url = Mage::getUrl('oct8ne/frame/image');
218
- $join = (strstr($url, "?") === FALSE) ? '?' : '&';
219
- $gallery_info = $gallery_data['images'];
220
-
221
- if (array_key_exists('configurable_images', $gallery_data))
222
- $gallery_info = $gallery_data['configurable_images'];
223
-
224
- foreach ($gallery_info as $image) {
225
- $file = $image['file'];
226
- if (strpos($file, '/') !== 0)
227
- $file = "/$file";
228
-
229
- $v[] = array(
230
- 'url' => self::_remove_http($url) . $join . 'file=catalog/product' . $file
231
- );
232
- }
233
- return $v;
234
  }
235
 
236
  // Loads the media for all products in just one query
@@ -245,19 +305,23 @@ class LetsSyncroLLC_Oct8ne_Helper_Data extends Mage_Core_Helper_Abstract {
245
 
246
  $ids = $_productCollection->getAllIds($pageSize, $offset);
247
 
 
 
248
  if (count($ids) > 0) {
249
  $sql = '
250
  SELECT
251
  main.entity_id, `main`.`value_id`, `main`.`value` AS `file`, `value`.`disabled`,
 
252
  `default_value`.`disabled` AS `disabled_default`
253
- FROM `catalog_product_entity_media_gallery` AS `main`
254
- LEFT JOIN `catalog_product_entity_media_gallery_value` AS `value`
255
  ON main.value_id=value.value_id AND value.store_id=' . Mage::app()->getStore()->getId() . '
256
- LEFT JOIN `catalog_product_entity_media_gallery_value` AS `default_value`
257
  ON main.value_id=default_value.value_id AND default_value.store_id=0
258
  WHERE (
259
  main.attribute_id = ' . $_read->quote($_mediaGalleryAttributeId) . ')
260
  AND (main.entity_id IN (' . $_read->quote($_productCollection->getAllIds()) . '))
 
261
  ';
262
  $_mediaGalleryData = $_read->fetchAll($sql);
263
 
@@ -282,4 +346,52 @@ class LetsSyncroLLC_Oct8ne_Helper_Data extends Mage_Core_Helper_Abstract {
282
  return $_productCollection;
283
  }
284
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  }
2
 
3
  class LetsSyncroLLC_Oct8ne_Helper_Data extends Mage_Core_Helper_Abstract {
4
 
5
+ static public function getProductsSummaryByIds($productIds) {
6
+ if (empty($productIds)) {
7
+ return array();
8
+ }
9
+
10
+ $attributes = Mage::getSingleton('catalog/config')->getProductAttributes();
11
+ $products = Mage::getModel('catalog/product')
12
+ ->getCollection()
13
+ ->addAttributeToFilter('entity_id', array('in' => $productIds))
14
+ ->addAttributeToSelect($attributes)
15
+ ->addAttributeToSelect('image')
16
+ ->addAttributeToSelect('small_image')
17
+ ->addAttributeToSelect('thumbnail')
18
+ ->addFinalPrice();
19
+
20
+ // Store the products in a dictionary
21
+ $productDict = array();
22
+ foreach ($products as $product) {
23
+ $id = $product->getId();
24
+ $productDict[$id] = self::createProductSummaryFromProduct($product);
25
+ }
26
 
27
+ // Return the products in the same order that they were queried
28
+ $result = array();
29
+ foreach ($productIds as $id) {
30
+ if (array_key_exists($id, $productDict)) {
31
+ $result[] = $productDict[$id];
32
+ }
33
+ }
34
+ return $result;
35
+ }
36
+
37
+ static public function getProductsInfoByIds($productIds, $qtyPerProduct = null) {
38
  if (empty($productIds)) {
39
  return array();
40
  }
41
+ $profiler = self::getProfiler(); /* @var $profiler LetsSyncroLLC_Oct8ne_Helper_Debug */
42
+ $startTime = $profiler->startProfile();
43
 
44
+ if (Mage::getStoreConfig('oct8neData/advancedDataConfig/loadCompleteProductInfo')) {
45
+ $result = self::getFullProductsInfoByIds($productIds, $qtyPerProduct);
46
+ } else {
47
+ $result = self::getOptimizedProductsInfoByIds($productIds, $qtyPerProduct);
48
+ }
49
+ $profiler->endProfile($startTime, "[Data] Create product info");
50
+ return $result;
51
+ }
52
+
53
+
54
+ static private function getFullProductsInfoByIds($productIds, $qtyPerProduct = null) {
55
+ $result = array();
56
+ foreach ($productIds as $id) {
57
+ $product = Mage::getModel('catalog/product')->load($id);
58
+ $qty = $qtyPerProduct && array_key_exists($id, $qtyPerProduct) ? $qtyPerProduct[$id] : null;
59
+ $result[] = self::createProductInfoFromProduct($product, $qty);
60
+ }
61
+ return $result;
62
+ }
63
+
64
+ static private function getOptimizedProductsInfoByIds($productIds, $qtyPerProduct = null) {
65
  $attributes = Mage::getSingleton('catalog/config')->getProductAttributes();
66
  $products = Mage::getModel('catalog/product')
67
  ->getCollection()
68
  ->addAttributeToFilter('entity_id', array('in' => $productIds))
69
  ->addAttributeToSelect($attributes)
 
70
  ->addAttributeToSelect('image')
71
+ ->addAttributeToSelect('small_image')
72
+ ->addAttributeToSelect('thumbnail')
73
  ->addFinalPrice();
74
 
75
+ // Add product description attributes
76
+ self::addProductDescriptionsToQuery($products);
77
+
78
  // Add stock information
79
  Mage::getModel('catalogInventory/stock')->addItemsToProducts($products);
80
 
81
+ // Preloads the media gallery for every product
82
+ if (Mage::getStoreConfig('oct8neData/advancedDataConfig/imageGalleryPrefetch')) {
83
+ self::addMediaGalleryAttributeToCollection($products);
84
+ }
85
 
 
86
  $productDict = array();
87
  foreach ($products as $product) {
88
  $id = $product->getId();
89
+ $qty = $qtyPerProduct && array_key_exists($id, $qtyPerProduct) ? $qtyPerProduct[$id] : null;
90
  $productDict[$id] = self::createProductInfoFromProduct($product, $qty);
91
  }
92
 
105
  return self::createProductInfoFromProduct($product, $qty);
106
  }
107
 
108
+ static public function createProductSummaryFromProduct($product, $qty = null) {
109
  $product_id = $product->getId();
 
 
 
 
 
 
110
  $prevPrice = Mage::helper('core')->currency($product->getPrice(), false, false);
111
  $finalPrice = Mage::helper('core')->currency($product->getFinalPrice(), false, false);
112
  $productUrl = self::_remove_http($product->getProductUrl());
113
  $thumbnail = self::_remove_http(self::getProductThumbnail($product, 120));
114
+ $title = htmlspecialchars($product->getName(), ENT_QUOTES, "UTF-8");
115
+
116
+ $result = array(
117
+ 'internalId' => $product_id,
118
+ 'title' => $title,
119
+ 'prevPrice' => number_format($prevPrice, '2', '.', ','),
120
+ 'price' => number_format($finalPrice, '2', '.', ','),
121
+ 'productUrl' => $productUrl,
122
+ 'thumbnail' => $thumbnail,
123
+ );
124
+ if($qty) {
125
+ $result['qty'] = $qty;
126
+ }
127
+ return $result;
128
+ }
129
 
130
+ static public function createProductInfoFromProduct($product, $qty = null) {
131
+
132
+ $profiler = self::getProfiler(); /* @var $profiler LetsSyncroLLC_Oct8ne_Helper_Debug */
133
+
134
+ $tmp = self::createProductSummaryFromProduct($product);
135
+
136
+ $description = self::getSanitizedDescription($product);
137
  $useProductUrl = true;
138
  if (self::isSaleable($product)) {
139
  if (!self::productHasOptions($product)) {
140
  $useProductUrl = false;
141
  }
142
  }
 
 
 
143
 
144
+ $start = $profiler->startProfile('[Data] - Start getting medias');
145
+ $medias = self::getProductImagesUrl($product);
146
+ $profiler->endProfile($start, '[Data] - End get medias');
147
+
148
+ // If medias is empty, return the thumbnail as unique main image
149
+ if ((count($medias) == 0) && array_key_exists("thumbnail", $tmp)) {
150
+ $medias = array(
151
+ 'url' => $tmp["thumbnail"]
152
+ );
153
+ }
154
+
155
+ $start = $profiler->startProfile();
156
+ if (!is_null($qty)) {
157
+ $tmp['qty'] = $qty;
158
+ }
159
  $result = array_merge($tmp, array(
 
 
 
 
160
  'description' => trim($description),
161
  'rating' => 'no-rating',
 
162
  'addToCartUrl' => self::getProductBuyUrl($product),
163
  'useProductUrl' => $useProductUrl,
164
  'medias' => $medias,
 
165
  ));
166
+ $profiler->endProfile($start, '[Data] - Compose ProductInfo structure');
167
+
168
  return $result;
169
  }
170
 
175
  $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
176
  }
177
 
178
+ // If we are not managing stocks for this product, it is saleable.
179
+ // If we are managing stocks for this product,
180
+ // we consider it saleable if we have it in stock
181
+ // or stock = 0 but we allow backorders (orders over without stock).
182
+
183
  if ($stockItem->getManageStock() > 0) {
184
  $stock = intval($stockItem->getQty());
185
  if ($stock > 0) {
205
  ->addAttributeToSelect('id')
206
  ->addAttributeToSort('price', 'asc')
207
  ->setPageSize($pageSize)
208
+ ->setCurPage($page);
209
 
210
  if ($relatedCollection->count() > 0) {
211
+ $relatedProductIds = array();
212
+ foreach ($relatedCollection as $relatedProduct) {
213
+ $relatedProductIds[] = $relatedProduct->getId();
214
+ }
215
+ return self::loadRelatedProductsFromCollectionOfIds($relatedProductIds, $page, $pageSize);
216
  }
217
 
218
+ // If no related products specified by admins, ask the search engine for them
219
+ $searchEngineName = strtolower(Mage::getStoreConfig('oct8neSearch/searchEngine/engine'));
220
+ if ($searchEngineName == '') {
221
+ $searchEngineName = 'Magento';
222
  }
223
+ $searchEngine = Mage::Helper('oct8ne/search_' . $searchEngineName); /* @var $searchEngine LetsSyncroLLC_Oct8ne_Helper_Search_Base */
224
+ $productIds = $searchEngine->getRelatedProductIds($product, $page, $pageSize);
225
+ return self::loadRelatedProductsFromCollectionOfIds($productIds, $page, $pageSize);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  }
227
 
228
+ static private function loadRelatedProductsFromCollectionOfIds($relatedProductIds, $page, $pageSize) {
 
 
 
 
 
229
  // Until the coviewer supports pagination, just
230
  // return as total the number of related products in the first page
231
  $productsCount = sizeof($relatedProductIds);
 
232
  $result = array(
233
  'total' => $productsCount,
234
+ 'results' => self::getProductsSummaryByIds($relatedProductIds)
235
  );
236
 
237
  return $result;
238
  }
239
 
240
+ static public function getProductThumbnail($product, $width) {
241
+ $imageHelper = self::getImageHelper();
242
+ return $imageHelper->getProductThumbnail($product, $width);
243
+ }
244
+
245
+ static private function getSanitizedDescription($product) {
246
+ $attrs = self::getDescriptionAttributes();
247
+ $description = NULL;
248
+ foreach ($attrs as $attr) {
249
+ if (trim($attr) != '') {
250
+ $description = $product[$attr];
251
+ if (!is_null($description) && strlen(trim($description)) > 0) {
252
+ break;
253
+ }
254
+ }
255
  }
256
+ if (!is_null($description)) {
257
+ $description = htmlspecialchars($description, ENT_QUOTES, "UTF-8");
258
+ $description = trim($description, "\r\n\t ");
259
+ $description = str_replace("\r", "", $description);
260
+ $description = str_replace("\t", "", $description);
261
+ $description = str_replace("\n", "&lt;br\/&gt;", $description);
262
  }
263
+ return $description;
 
 
 
264
  }
265
 
266
  static private function _remove_http($str) {
289
  }
290
 
291
  static private function getProductImagesUrl($product) {
292
+ $helper = self::getImageHelper(); /* @var $helper LetsSyncroLLC_Oct8ne_Helper_Image_Default */
293
+ return $helper->getProductImagesUrl($product);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  }
295
 
296
  // Loads the media for all products in just one query
305
 
306
  $ids = $_productCollection->getAllIds($pageSize, $offset);
307
 
308
+ $galleryTable = Mage::getConfig()->getTablePrefix() . 'catalog_product_entity_media_gallery';
309
+ $galleryValuesTable = Mage::getConfig()->getTablePrefix() . 'catalog_product_entity_media_gallery_value';
310
  if (count($ids) > 0) {
311
  $sql = '
312
  SELECT
313
  main.entity_id, `main`.`value_id`, `main`.`value` AS `file`, `value`.`disabled`,
314
+ `value`.`position` AS `position`, `default_value`.`position` AS `default_position`,
315
  `default_value`.`disabled` AS `disabled_default`
316
+ FROM `' . $galleryTable . '` AS `main`
317
+ LEFT JOIN `' . $galleryValuesTable . '` AS `value`
318
  ON main.value_id=value.value_id AND value.store_id=' . Mage::app()->getStore()->getId() . '
319
+ LEFT JOIN `' . $galleryValuesTable . '` AS `default_value`
320
  ON main.value_id=default_value.value_id AND default_value.store_id=0
321
  WHERE (
322
  main.attribute_id = ' . $_read->quote($_mediaGalleryAttributeId) . ')
323
  AND (main.entity_id IN (' . $_read->quote($_productCollection->getAllIds()) . '))
324
+ ORDER BY value.position, default_position
325
  ';
326
  $_mediaGalleryData = $_read->fetchAll($sql);
327
 
346
  return $_productCollection;
347
  }
348
 
349
+ private static function addProductDescriptionsToQuery($products) {
350
+ $attrs = self::getDescriptionAttributes();
351
+ foreach ($attrs as $attr) {
352
+ if (trim($attr) != '') {
353
+ $products->addAttributeToSelect($attr);
354
+ }
355
+ }
356
+ }
357
+
358
+ private static function getDescriptionAttributes() {
359
+ $descriptionAttrs = Mage::getStoreConfig('oct8neData/productData/productDataDescription');
360
+ if (trim($descriptionAttrs) == '') {
361
+ $attrs = array('description', 'short_description');
362
+ } else {
363
+ $attrs = explode(',', $descriptionAttrs);
364
+
365
+ // Uncomment the following block if we want to add
366
+ // description & short_description attributes if
367
+ // they have not been already included.
368
+ //
369
+ // if (!array_search('description', $attrs)) {
370
+ // $attrs[] = 'description';
371
+ // }
372
+ // if (!array_search('short_description', $attrs)) {
373
+ // $attrs[] = 'short_description';
374
+ // }
375
+ }
376
+ return $attrs;
377
+ }
378
+
379
+ private static $profiler = NULL;
380
+
381
+ private static function getProfiler() {
382
+ if (is_null(self::$profiler)) {
383
+ self::$profiler = Mage::helper('oct8ne/debug');
384
+ }
385
+ return self::$profiler;
386
+ }
387
+
388
+ static private function getImageHelper() {
389
+ $helperName = Mage::getStoreConfig('oct8neData/advancedDataConfig/imageHelperName');
390
+ if (!$helperName) {
391
+ $helperName = 'default';
392
+ }
393
+ $helperName = 'oct8ne/image_' . $helperName;
394
+ return Mage::helper($helperName);
395
+ }
396
+
397
  }
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Debug.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LetsSyncroLLC_Oct8ne_Helper_Debug extends Mage_Core_Helper_Abstract {
4
+
5
+ private static $LOG_ENABLED = FALSE;
6
+ private static $PROFILER_ENABLED = FALSE;
7
+
8
+ public static function log($message) {
9
+ if (self::$LOG_ENABLED) {
10
+ Mage::log($message, null, "oct8ne.log", TRUE);
11
+ }
12
+ }
13
+
14
+ public static function startProfile($msg = NULL) {
15
+ if(!self::$PROFILER_ENABLED) {
16
+ return;
17
+ }
18
+ if (!is_null($msg)) {
19
+ self::log($msg);
20
+ }
21
+ return microtime(true);
22
+ }
23
+
24
+ public static function endProfile($start, $action) {
25
+ if(!self::$PROFILER_ENABLED) {
26
+ return;
27
+ }
28
+ $now = microtime(true);
29
+ self::log($action . ': ' . number_format($now - $start, 4) . ' secs');
30
+ }
31
+
32
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Image.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
-
3
- class LetsSyncroLLC_Oct8ne_Helper_Image extends Mage_Core_Helper_Url {
4
-
5
- public function resizeImg($fileName, $width, $height = null) {
6
- $folderURL = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA);
7
- $imageURL = $folderURL . $fileName;
8
-
9
- $basePath = Mage::getBaseDir(Mage_Core_Model_Store::URL_TYPE_MEDIA) . DS . $fileName;
10
- $newPath = Mage::getBaseDir(Mage_Core_Model_Store::URL_TYPE_MEDIA) . DS . "catalog" . DS . "product" . DS . "cache" . DS . "resized" . DS . $width . DS . $fileName;
11
- //if width empty then return original size image's URL
12
- if ($width != '') {
13
- //if image has already resized then just return URL
14
- if (file_exists($basePath) && is_file($basePath) && !file_exists($newPath)) {
15
- $imageObj = new Varien_Image($basePath);
16
- if ($imageObj->getOriginalWidth() <= $width) {
17
- return $basePath;
18
- }
19
- $imageObj->constrainOnly(TRUE);
20
- $imageObj->keepAspectRatio(FALSE);
21
- $imageObj->keepFrame(FALSE);
22
- $imageObj->keepTransparency(TRUE);
23
- $imageObj->resize($width, $height);
24
- $imageObj->save($newPath);
25
- }
26
- $resizedURL = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . "catalog" . DS . "product" . DS . "cache" . DS . "resized" . DS . $fileName;
27
- } else {
28
- $resizedURL = $imageURL;
29
- }
30
- return $newPath; // $resizedURL;
31
- }
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Image/Default.php ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LetsSyncroLLC_Oct8ne_Helper_Image_Default extends Mage_Core_Helper_Url {
4
+
5
+ private static $profiler = NULL;
6
+
7
+ public function getProductImagesUrl($product) {
8
+
9
+ $profiler = $this->getProfiler(); /* @var $profiler LetsSyncroLLC_Oct8ne_Helper_Debug */
10
+ $gallery_data = $product->getData('media_gallery');
11
+ $start = $profiler->startProfile();
12
+ if (!$gallery_data) {
13
+ $attributes = $product->getTypeInstance(true)->getSetAttributes($product);
14
+ $media_gallery = $attributes['media_gallery'];
15
+ $backend = $media_gallery->getBackend();
16
+ $backend->afterLoad($product);
17
+ $gallery_data = $product->getMediaGalleryImages();
18
+ $gallery_info = $gallery_data;
19
+ // $product->load('media_gallery');
20
+ // $gallery_data = $product->getData('media_gallery');
21
+ } else {
22
+ $gallery_info = $gallery_data['images'];
23
+ if (array_key_exists('configurable_images', $gallery_data)) {
24
+ $gallery_info = $gallery_data['configurable_images'];
25
+ }
26
+ }
27
+ $profiler->endProfile($start, '[Data] - Load medias from database');
28
+
29
+ $start = $profiler->startProfile();
30
+
31
+ // Proof of concept: get valid images
32
+ $images = $this->getValidImages($gallery_info, $product);
33
+
34
+ $v = array();
35
+ foreach ($images as $image) {
36
+ $v[] = array(
37
+ 'url' => $image
38
+ );
39
+ }
40
+ $profiler->endProfile($start, '[Data] - Compose array of image urls');
41
+ return $v;
42
+ }
43
+
44
+ public function getProductThumbnail($product, $width = null) {
45
+ $result = $this->getThumbnail($product, $width, 'thumbnail', $product->getThumbnail());
46
+ if (!$result) {
47
+ $result = $this->getThumbnail($product, $width, 'small_image', $product->getSmallImage());
48
+ if (!$result) {
49
+ $result = $this->getThumbnail($product, $width, 'image', $product->getImage());
50
+ if (!$result) {
51
+ $result = $this->getFirstGalleryImage($product, $width);
52
+ if (!$result) {
53
+ return $this->getParentThumbnail($product, $width);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ return $result;
59
+ }
60
+
61
+ public function resizeImg($fileName, $width, $height = null) {
62
+
63
+ // If not filename specified, return the small placeholder
64
+ if (!$fileName) {
65
+ return $this->getPlaceholder($width, $height);
66
+ }
67
+
68
+ $originalImageUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . DS . $this->getProductDir($fileName);
69
+ $originalImagePhysicalPath = $this->getImagePhysicalPath($fileName);
70
+ $resizedImagePhysicalPath = Mage::getBaseDir(Mage_Core_Model_Store::URL_TYPE_MEDIA) . DS . $this->getCachedProductDir($fileName, $width);
71
+ $resizedImageUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA) . DS . $this->getCachedProductDir($fileName, $width);
72
+
73
+ // If the original image doesn`t exist, return the small placeholder
74
+ if (!file_exists($originalImagePhysicalPath) && is_file($originalImagePhysicalPath)) {
75
+ return $this->getPlaceholder($width, $height);
76
+ }
77
+
78
+ // If width is not specified, the image is returned "as is"
79
+ if (!$width) {
80
+ return $this->removeHttp($originalImageUrl);
81
+ }
82
+
83
+ // If the cached image already exists, return it
84
+ if (file_exists($resizedImagePhysicalPath)) {
85
+ return $this->removeHttp($resizedImageUrl);
86
+ }
87
+
88
+ // If the cached image if smaller than the width requested, return it
89
+ $imageObj = new Varien_Image($originalImagePhysicalPath);
90
+ if ($imageObj->getOriginalWidth() <= $width) {
91
+ return $this->removeHttp($originalImageUrl);
92
+ }
93
+
94
+ // If we got this so far, resize and return the new image
95
+ $imageObj->constrainOnly(TRUE);
96
+ $imageObj->keepAspectRatio(FALSE);
97
+ $imageObj->keepFrame(FALSE);
98
+ $imageObj->keepTransparency(TRUE);
99
+ $imageObj->resize($width, $height);
100
+ $imageObj->save($resizedImagePhysicalPath);
101
+ return $this->removeHttp($resizedImageUrl);
102
+ }
103
+
104
+ public function getImagePhysicalPath($fileName) {
105
+ return Mage::getBaseDir(Mage_Core_Model_Store::URL_TYPE_MEDIA) . DS . $this->getProductDir($fileName);
106
+ }
107
+
108
+ protected function getPlaceholder($width, $height) {
109
+ $width = $width ? $width : 120;
110
+ $height = $height ? $height : $width;
111
+ return $this->removeHttp(Mage::getModel('catalog/product')->getSmallImageUrl($width, $height));
112
+ }
113
+
114
+ protected function getFirstGalleryImage($product, $width) {
115
+ $product->getResource()->getAttribute('media_gallery')
116
+ ->getBackend()->afterLoad($product);
117
+
118
+ $gallery = $product->getMediaGalleryImages();
119
+ $imageUrl = NULL;
120
+ $file = NULL;
121
+ foreach ($gallery as $image) {
122
+ $file = $image['file'];
123
+ break;
124
+ }
125
+ if (!is_null($width) && $file) {
126
+ $imageUrl = $this->resizeImg($file, $width);
127
+ }
128
+ return $imageUrl;
129
+ }
130
+
131
+ protected function getProductDir($file) {
132
+ return "catalog" . DS . "product" . DS . $file;
133
+ }
134
+
135
+ protected function getCachedProductDir($file, $width) {
136
+ return "catalog" . DS . "product" . DS . "cache" . DS . "resized" . DS . $width . DS . $file;
137
+ }
138
+
139
+ protected function removeHttp($str) {
140
+ return preg_replace('#^https?:#', '', $str);
141
+ }
142
+
143
+ protected function getProfiler() {
144
+ if (is_null(self::$profiler)) {
145
+ self::$profiler = Mage::helper('oct8ne/debug');
146
+ }
147
+ return self::$profiler;
148
+ }
149
+
150
+ private function getThumbnail($product, $width, $imageType, $url) {
151
+ if ($url == 'no_selection') {
152
+ return NULL;
153
+ }
154
+ $thumb = Mage::helper('catalog/image')->init($product, $imageType);
155
+ if (!is_null($width)) {
156
+ $thumb->resize($width);
157
+ }
158
+ $file = (string) $thumb;
159
+ return $file;
160
+ }
161
+
162
+ private function getParentThumbnail($product, $width) {
163
+ if ($product->getTypeId() == "simple") {
164
+ $parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
165
+ if (!$parentIds) {
166
+ $parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
167
+ }
168
+ if (isset($parentIds[0])) {
169
+ $parent = Mage::getModel('catalog/product')->load($parentIds[0]);
170
+ return $this->getProductThumbnail($parent, $width);
171
+ }
172
+ }
173
+ $imageUrl = $this->getPlaceholder($width, $width);
174
+ return $imageUrl;
175
+ }
176
+
177
+ // Returns valid gallery images for a product.
178
+ // If the last parameter is:
179
+ // TRUE -> we want to return both included and excluded images
180
+ // FALSE -> we want to return only not excluded images
181
+ // If no image could be found:
182
+ // - Try to return Image, Small_Image or Thumbnail (in that order)
183
+ // - If still no images found, return the placeholder
184
+
185
+ private function getValidImages($gallery, $product) {
186
+ $mustIgnoreExcludedImages = Mage::getStoreConfig('oct8neData/productData/ignoreExcludedImages');
187
+ $url = Mage::getUrl('oct8ne/frame/image');
188
+ $join = (strstr($url, "?") === FALSE) ? '?' : '&';
189
+ $result = array();
190
+ foreach ($gallery as $image) {
191
+ $isImageExcluded = $image['disabled'] == '1' || $image['disabled_default'] == '1';
192
+ if (!$isImageExcluded || !$mustIgnoreExcludedImages) {
193
+ $file = $image['file'];
194
+ if (strpos($file, '/') !== 0) {
195
+ $file = "/$file";
196
+ }
197
+ $result[] = $this->removeHttp($url) . $join . 'file=' . $file;
198
+ }
199
+ }
200
+ if (empty($result)) {
201
+ if ($product->getImage() != 'no_selection') {
202
+ $result[] = $product->getImageUrl();
203
+ } else {
204
+ if ($product->getSmallImage() != 'no_selection') {
205
+ $result[] = $product->getSmallImageUrl();
206
+ } else {
207
+ if ($product->getThumbnail() != 'no_selection') {
208
+ $result[] = $product->getThumbnailUrl();
209
+ } else {
210
+ // Return the standard placeholder
211
+ $result[] = $this->removeHttp(Mage::getModel('catalog/product')->getImageUrl(400, 400));
212
+ }
213
+ }
214
+ }
215
+ }
216
+ return $result;
217
+ }
218
+
219
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Reports.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LetsSyncroLLC_Oct8ne_Helper_Reports extends Mage_Core_Helper_Abstract {
4
+
5
+ public function getSales($from, $to, $storeId = NULL) {
6
+ $orderCollection = Mage::getModel('oct8ne/order')->getCollection();
7
+
8
+ if (!empty($from)) {
9
+ $from = date('Y-m-d', strtotime($from)) . ' 00:00:00';
10
+ $orderCollection->getSelect()->where("utc_last_modified >= CAST(? AS DATETIME)", $from);
11
+ }
12
+ if (!empty($to)) {
13
+ $to = date('Y-m-d', strtotime($to)) . ' 23:59:59';
14
+ $orderCollection->getSelect()->where("CAST(? AS DATETIME) >= utc_last_modified", $to);
15
+ }
16
+
17
+ if(!empty($storeId)) {
18
+ $orderCollection->getSelect()->where("store_id = ?", storeId);
19
+ }
20
+ $orderCollection->setOrder('utc_last_modified', 'ASC');
21
+
22
+ $result = array();
23
+ foreach ($orderCollection as $item) {
24
+ $result[] = array(
25
+ 'quoteId' => $item['quote_id'],
26
+ 'orderId' => $item['order_id'],
27
+ // 'storeId' => $item['store_id'], // Not needed for now
28
+ 'sessionId' => $item['session_id'],
29
+ 'customerId' => $item['customer_id'],
30
+ 'price' => $item['price'],
31
+ 'finalPrice' => $item['final_price'],
32
+ 'currency' => $item['currency'],
33
+ 'productsCount' => $item['products_count'],
34
+ 'itemsCount' => $item['items_count'],
35
+ 'lastAction' => $item['last_action'],
36
+ 'utcCreated' => $item['utc_created'],
37
+ 'utcLastUpdated' => $item['utc_last_modified']
38
+ );
39
+ }
40
+ return $result;
41
+ }
42
+
43
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Search.php DELETED
@@ -1,74 +0,0 @@
1
- <?php
2
-
3
- class LetsSyncroLLC_Oct8ne_Helper_Search extends Mage_Core_Helper_Abstract {
4
-
5
- /**
6
- * Query object
7
- *
8
- * @var Mage_CatalogSearch_Model_Query
9
- */
10
- protected $_query;
11
-
12
- /**
13
- * Query string
14
- *
15
- * @var string
16
- */
17
- protected $_queryText;
18
-
19
- /**
20
- * Retrieve search query text
21
- *
22
- * @return string
23
- */
24
- public function getQueryText() {
25
- if ( !isset($this->_queryText) ) {
26
- $this->_queryText = $this->_getRequest()->getParam('q');
27
- if ($this->_queryText === null)
28
- $this->_queryText = '';
29
- else {
30
- /* @var $stringHelper Mage_Core_Helper_String */
31
- $stringHelper = Mage::helper('core/string');
32
- $this->_queryText = is_array($this->_queryText) ? ''
33
- : $stringHelper->cleanString(trim($this->_queryText));
34
-
35
- $maxQueryLength = $this->getMaxQueryLength();
36
- if ($maxQueryLength !== '' && $stringHelper->strlen($this->_queryText) > $maxQueryLength) {
37
- $this->_queryText = $stringHelper->substr($this->_queryText, 0, $maxQueryLength);
38
- $this->_isMaxLength = true;
39
- }
40
- }
41
-
42
- }
43
-
44
- return $this->_queryText;
45
- }
46
-
47
- /**
48
- * Retrieve query model object
49
- *
50
- * @return Mage_CatalogSearch_Model_Query
51
- */
52
- public function getQuery() {
53
- if (!$this->_query) {
54
- $this->_query = Mage::getModel('catalogsearch/query')
55
- ->loadByQuery($this->getQueryText());
56
- if (!$this->_query->getId()) {
57
- $this->_query->setQueryText($this->getQueryText());
58
- }
59
- }
60
- return $this->_query;
61
- }
62
-
63
- /**
64
- * Retrieve maximum query length
65
- *
66
- * @param mixed $store
67
- * @return int|string
68
- */
69
- public function getMaxQueryLength( $store = null ) {
70
- return Mage::getStoreConfig( Mage_CatalogSearch_Model_Query::XML_PATH_MAX_QUERY_LENGTH, $store );
71
- }
72
-
73
- };
74
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Search/Base.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class LetsSyncroLLC_Oct8ne_Helper_Search_Base extends Mage_Core_Helper_Abstract {
4
+
5
+ private $params = array();
6
+
7
+ public abstract function getEngineName();
8
+
9
+ public abstract function search($storeId, $searchTerm, $searchOrder, $searchDir, $page, $pageSize, &$totalSearchResults, &$attrs_applied, &$attrs_available);
10
+
11
+ public abstract function getRelatedProductIds($product, $page, $pageSize);
12
+
13
+ public abstract function isValidSearchCriteria($searchTerm);
14
+
15
+ public function __construct() {
16
+
17
+ // $configurationString example:
18
+ // key1=value1;key2=value2
19
+ $configurationString = Mage::getStoreConfig('oct8neSearch/searchEngine/params');
20
+
21
+ if (!is_null($configurationString) && strlen($configurationString) > 0) {
22
+ $lines = explode(';', $configurationString);
23
+ foreach ($lines as $line) {
24
+ $keyValue = explode('=', $line);
25
+ if (count($keyValue) == 2) {
26
+ $this->params[trim($keyValue[0])] = trim($keyValue[1]);
27
+ }
28
+ }
29
+ }
30
+ }
31
+
32
+ protected function getEngineParam($param) {
33
+ return $this->params[$param];
34
+ }
35
+
36
+ public function getRequest() {
37
+ return Mage::app()->getRequest();
38
+ }
39
+
40
+ /**
41
+ * Creates a filter option structure
42
+ * @param string $label Text to show
43
+ * @param string $value Value to apply when the option is selected
44
+ * @param number $count Number of products found
45
+ * @return A FilterOption object
46
+ */
47
+ protected function createFilterOption($label, $value, $count) {
48
+
49
+ return array(
50
+ "valueLabel" => $label,
51
+ "value" => $value,
52
+ "count" => $count
53
+ );
54
+ }
55
+
56
+ /**
57
+ * Creates a filter info structure
58
+ * @param string $param Parameter name sent to the search action
59
+ * @param string $paramLabel Parameter text description
60
+ * @param array $options Array of filterOptions
61
+ * @param string $currentValueLabel Current filter label
62
+ * @param string $currentValue Current filter value
63
+ * @return A filter info object
64
+ */
65
+ protected function createFilterInfo($param, $paramLabel, $options, $currentValueLabel = null, $currentValue = null) {
66
+ $result = array(
67
+ 'param' => $param,
68
+ 'paramLabel' => $paramLabel,
69
+ 'options' => $options
70
+ );
71
+ if (!is_null($currentValue)) {
72
+ $result['valueLabel'] = $currentValueLabel;
73
+ $result['value'] = $currentValue;
74
+ }
75
+ return $result;
76
+ }
77
+
78
+ protected function log($message) {
79
+ $debug = Mage::helper('oct8ne/debug'); /* @var $debug LetsSyncroLLC_Oct8ne_Helper_Debug */
80
+ $engineName = $this->getEngineName();
81
+ $debug->log("[Search-{$engineName}] " . $message);
82
+ }
83
+
84
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Search/Magento.php ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LetsSyncroLLC_Oct8ne_Helper_Search_Magento extends LetsSyncroLLC_Oct8ne_Helper_Search_Base {
4
+
5
+ public function getEngineName() {
6
+ return "magento";
7
+ }
8
+
9
+ public function isValidSearchCriteria($searchTerm) {
10
+ $this->getRequest()->setParam('q', $searchTerm);
11
+ if (is_null($searchTerm) || strlen($searchTerm) == 0) {
12
+ return false;
13
+ }
14
+ $helper = Mage::helper("catalogsearch"); /* @var $helper Mage_CatalogSearch_Helper_Data */
15
+ $len = strlen($searchTerm);
16
+ if ($len < $helper->getMinQueryLength() || $len > $helper->getMaxQueryLength()) {
17
+ return false;
18
+ }
19
+ return true;
20
+ }
21
+
22
+ public function search($storeId, $searchTerm, $searchOrder, $searchDir, $page, $pageSize, &$totalSearchResults, &$attrs_applied, &$attrs_available) {
23
+ parent::log("Searching " . $searchTerm);
24
+ $this->getRequest()->setParam('q', $searchTerm);
25
+ $products = $this->getFilteredProducts($storeId, $attrs_applied, $attrs_available);
26
+ $totalSearchResults = $products->getSize();
27
+
28
+ $products->setOrder($searchOrder, $searchDir);
29
+ $products->setPageSize($pageSize)
30
+ ->setCurPage($page);
31
+
32
+ $result = array();
33
+ foreach ($products as $product) {
34
+ $result[] = $product->getId();
35
+ }
36
+
37
+ return $result;
38
+ }
39
+
40
+ private function getFilteredProducts($storeId, &$attrs_applied, &$attrs_available) {
41
+ $request = $this->getRequest();
42
+ $query = Mage::helper('catalogsearch')->getQuery();
43
+ $query->setStoreId($storeId);
44
+ if ($query->getId()) {
45
+ $query->setPopularity($query->getPopularity() + 1);
46
+ } else {
47
+ $query->setPopularity(1);
48
+ }
49
+ $query->prepare();
50
+ Mage::helper('catalogsearch')->checkNotes();
51
+
52
+ $query = Mage::getModel('catalogsearch/layer');
53
+
54
+ $filterableAttributes = $query->getFilterableAttributes();
55
+ $attrs = array();
56
+
57
+ if (!empty($filterableAttributes)) {
58
+ $tmp = new Mage_Catalog_Model_Resource_Eav_Attribute();
59
+ $tmp->SetAttributeCode('category');
60
+ $tmp->setFrontendLabel('Category');
61
+ $filterableAttributes->addItem($tmp);
62
+ }
63
+
64
+ foreach ($filterableAttributes as $attribute) {
65
+ $code = $attribute->getAttributeCode();
66
+ $name = $attribute->getFrontendLabel();
67
+
68
+ // INIT
69
+ $items = array();
70
+ switch ($code) {
71
+ case 'price':
72
+ $_filterModelName = "catalog/layer_filter_price";
73
+ break;
74
+ case 'decimal':
75
+ $_filterModelName = "catalog/layer_filter_decimal";
76
+ break;
77
+ case 'category':
78
+ $_filterModelName = "catalog/layer_filter_category";
79
+ break;
80
+ default:
81
+ $_filterModelName = "catalog/layer_filter_attribute";
82
+ break;
83
+ }
84
+
85
+ $filter = Mage::getModel($_filterModelName)
86
+ ->setLayer($query)
87
+ ->setAttributeModel($attribute);
88
+ $filter->apply($request, $this);
89
+ $items = $filter->getItems();
90
+
91
+ // En los filtros aplicados no nos viene el nombre, solo el id, lo obtenemos aqui
92
+ $optionId = $request->getParam($filter->getRequestVar());
93
+ $featurename = "";
94
+ if (!is_null($optionId)) {
95
+ switch ($code) {
96
+ case 'price':
97
+ $featurename = $request->get($code);
98
+ break;
99
+ case 'decimal':
100
+ $featurename = $request->get($code);
101
+ break;
102
+ case 'category':
103
+ $featurename = $filter->getCategory()->getName();
104
+ break;
105
+ default:
106
+ $featurename = $filter->getAttributeModel()->getFrontend()->getOption($optionId);
107
+ break;
108
+ }
109
+ }
110
+
111
+ $options = array();
112
+ foreach ($items as $item) {
113
+ if ($item->getCount() > 0) {
114
+ $options[] = $this->createFilterOption($item->getLabel(), $item->getValue(), $item->getCount());
115
+ }
116
+ }
117
+ $value = $request->getParam($code);
118
+ $attrs[] = $this->createFilterInfo($code, $name, $options, $featurename, $value);
119
+ }
120
+
121
+ foreach ($attrs as $attr) {
122
+ if (!is_null($request->getParam($attr['param']))) {
123
+ $attrs_applied[] = $attr;
124
+ } else {
125
+ $attrs_available[] = $attr;
126
+ }
127
+ }
128
+
129
+ $result_collection = $query->getProductCollection();
130
+ return $result_collection;
131
+ }
132
+
133
+ public function getRelatedProductIds($product, $page, $pageSize) {
134
+
135
+ $productId = $product->getId();
136
+ $categoryIds = $product->getCategoryIds();
137
+ if (empty($categoryIds)) {
138
+ return array();
139
+ }
140
+
141
+ $collection = mage::getModel('catalog/product')->getCollection()
142
+ ->addAttributeToSelect('id')
143
+ ->addAttributeToFilter('visibility', 4)
144
+ ->addAttributeToFilter('status', array('eq' => Mage_Catalog_Model_Product_Status::STATUS_ENABLED))
145
+ ->addAttributeToFilter('entity_id', array('neq' => $productId))
146
+ ->addAttributeToSort('price', 'asc');
147
+
148
+ Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($collection);
149
+
150
+ $collection->joinField('category_id', 'catalog/category_product', 'category_id', 'product_id=entity_id', null, 'left')
151
+ ->addAttributeToFilter('category_id', array('in' => $categoryIds));
152
+
153
+ $collection->getSelect()->group('e.entity_id');
154
+ $collection->setPageSize($pageSize)
155
+ ->setCurPage($page);
156
+
157
+ $relatedProductIds = array();
158
+ foreach ($collection as $relatedProduct) {
159
+ $relatedProductIds[] = $relatedProduct->getId();
160
+ }
161
+ return $relatedProductIds;
162
+ }
163
+
164
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Search/Sli.php ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LetsSyncroLLC_Oct8ne_Helper_Search_Sli extends LetsSyncroLLC_Oct8ne_Helper_Search_Base {
4
+
5
+ public function getEngineName() {
6
+ return "sli";
7
+ }
8
+
9
+ public function isValidSearchCriteria($searchTerm) {
10
+ if (is_null($searchTerm) || strlen($searchTerm) == 0) {
11
+ return false;
12
+ }
13
+ return true;
14
+ }
15
+
16
+ public function search($storeId, $searchTerm, $searchOrder, $searchDir, $page, $pageSize, &$totalSearchResults, &$attrs_applied, &$attrs_available) {
17
+ $this->log("Searching " . $searchTerm);
18
+ $result = $this->executeSliSearchQuery($searchTerm, NULL, $searchOrder, $searchDir, $page, $pageSize);
19
+ if (is_null($result)) {
20
+ return array();
21
+ }
22
+ $totalSearchResults = $result["result_meta"]["total"];
23
+ $attrs_available = $this->getAvailableFilters($result);
24
+ $attrs_applied = $this->getResponseAppliedFilter($attrs_available);
25
+ $productIds = $this->getProductIds($result);
26
+ $this->log("Total {$totalSearchResults}, ids of this page: [" . implode(",", $productIds) . "]");
27
+ return $productIds;
28
+ }
29
+
30
+ public function getRelatedProductIds($product, $page, $pageSize) {
31
+ $categoryIds = $product->getCategoryIds();
32
+ while(count($categoryIds) > 2) {
33
+ array_pop($categoryIds);
34
+ }
35
+ if(!empty($categoryIds)) {
36
+ $result = $this->executeSliSearchQuery(NULL, $categoryIds, 'score', 'asc', $page, $pageSize, FALSE);
37
+ } else {
38
+ $name = $product->getName();
39
+ $result = $this->executeSliSearchQuery($name, NULL, 'score', 'asc', $page, $pageSize, FALSE, 'or');
40
+ }
41
+ $productIds = $this->getProductIds($result);
42
+ return $productIds;
43
+ }
44
+
45
+ private function executeSliSearchQuery($searchTerm, $searchCategories, $searchOrder, $searchDir, $page, $pageSize, $includeFacets = TRUE, $method = NULL) {
46
+ if (!function_exists('curl_init')) {
47
+ return NULL;
48
+ }
49
+ $host = $this->normalizeHost($this->getEngineParam("host"));
50
+ $queryParams = array(
51
+ 'ts' => 'json-full',
52
+ 'w' => $searchTerm,
53
+ 'cnt' => $pageSize,
54
+ 'srt' => $pageSize * ($page - 1),
55
+ 'isort' => $this->getSliSort($searchOrder, $searchDir),
56
+ 'usecache' => 'no'
57
+ );
58
+ if ($searchCategories) {
59
+ $queryParams['catfilter'] = implode('^', $searchCategories);
60
+ $queryParams["w"] = '*';
61
+ }
62
+
63
+ if ($includeFacets) {
64
+ $queryParams['af'] = $this->getFacets();
65
+ }
66
+ if (!is_null($method)) {
67
+ $queryParams["method"] = $method;
68
+ }
69
+
70
+ $query = $host . '/search?' . http_build_query($queryParams);
71
+
72
+ $this->log("Executing query: {$query}");
73
+
74
+ $request = curl_init($query);
75
+ curl_setopt($request, CURLOPT_POST, 1);
76
+ curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
77
+ $response = curl_exec($request);
78
+ $err = curl_error($request);
79
+ if (is_null($err) || $err == "") {
80
+ $result = json_decode($response, true);
81
+ $this->log("Query result received");
82
+ } else {
83
+ $this->log("Search error: " . $err);
84
+ $result = NULL;
85
+ }
86
+ curl_close($request);
87
+ return $result;
88
+ }
89
+
90
+ private function getProductIds($result) {
91
+ $productIds = array();
92
+ foreach ($result["results"] as $product) {
93
+ $productIds[] = $product["product_id"];
94
+ }
95
+
96
+ // TODO: Remove
97
+ // $productIds = array('142', '1403', '1639', '1919', '3034', '5629', '7740', '10121', '17952', '23361');
98
+
99
+ return $productIds;
100
+ }
101
+
102
+ function normalizeHost($host) {
103
+ $host = rtrim($host, '/');
104
+ if (!$this->startsWith($host, 'http://') && !!$this->startsWith($host, 'https://')) {
105
+ $host = 'http://' . $host;
106
+ }
107
+ return $host;
108
+ }
109
+
110
+ function endsWith($str, $subStr) {
111
+ $length = strlen($subStr);
112
+ if ($length == 0) {
113
+ return true;
114
+ }
115
+ return (substr($str, -$length) === $subStr);
116
+ }
117
+
118
+ function startsWith($str, $subStr) {
119
+ $length = strlen($subStr);
120
+ return (substr($str, 0, $length) === $subStr);
121
+ }
122
+
123
+ private function getSliSort($searchOrder, $searchDir) {
124
+ $result = "";
125
+ switch ($searchOrder) {
126
+ case "score":
127
+ $result .= "score";
128
+ break;
129
+ case "relevance":
130
+ $result .= "rel";
131
+ break;
132
+ case "price":
133
+ $result .= "price";
134
+ break;
135
+ case "name":
136
+ $result .= "title";
137
+ }
138
+ if ($searchDir == "desc") {
139
+ $result .= "+rev";
140
+ }
141
+ return $result;
142
+ }
143
+
144
+ private function getAvailableFilters($result) {
145
+ $filters = array();
146
+ foreach ($result["facets"] as $facet) {
147
+ if (key_exists("parent_id", $facet)) {
148
+ continue; // Ignore sub-facets
149
+ }
150
+
151
+ $options = array();
152
+ foreach ($facet["values"] as $value) {
153
+ $options[] = $this->createFilterOption($value["name"], $value["id"], $value["count"]);
154
+ }
155
+ $filters[] = $this->createFilterInfo($facet["id"], $facet["name"], $options);
156
+ }
157
+ return $filters;
158
+ }
159
+
160
+ private function getResponseAppliedFilter($availableFilters) {
161
+ $filters = array();
162
+ $request = $this->getRequest();
163
+ foreach ($availableFilters as $availableFilter) {
164
+ $filterParameterValue = $request->getParam($availableFilter["param"]);
165
+ if (!is_null($filterParameterValue)) {
166
+ $options = $availableFilter["options"];
167
+ $currentLabel = $this->getCurrentOptionLabel($filterParameterValue, $options);
168
+ $filters[] = $this->createFilterInfo(
169
+ $availableFilter["param"], $availableFilter["paramLabel"], $options, $currentLabel, $filterParameterValue
170
+ );
171
+ }
172
+ }
173
+ return $filters;
174
+ }
175
+
176
+ private function getCurrentOptionLabel($value, $options) {
177
+ foreach ($options as $option) {
178
+ if ($option['value'] == $value) {
179
+ return $option["valueLabel"];
180
+ }
181
+ }
182
+ return $value;
183
+ }
184
+
185
+ private function getFacets() {
186
+ $request = $this->getRequest();
187
+ $queryStringParams = array_keys($_GET);
188
+ $facet = "";
189
+ foreach ($queryStringParams as $param) {
190
+ // Ignore standard query standard params
191
+ if (substr($param, 0, 1) == '_' || $param == 'callback' || $param == 'search' || $param == 'store' || $param == 'orderby' || $param == 'dir' || $param == 'page' || $param == 'pageSize') {
192
+ continue;
193
+ }
194
+
195
+ // If we get here, the param is a facet
196
+ $value = $request->getParam($param);
197
+ if (!is_null($value) && trim($value) != '') {
198
+ $facet .= $param . ':' . $value . ' ';
199
+ }
200
+ }
201
+ return trim($facet);
202
+ }
203
+
204
+ protected function log($message) {
205
+ $debug = Mage::helper('oct8ne/debug'); /* @var $debug LetsSyncroLLC_Oct8ne_Helper_Debug */
206
+ $engineName = $this->getEngineName();
207
+ $debug->log("[Search-{$engineName}] " . $message);
208
+ }
209
+
210
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Version.php CHANGED
@@ -8,6 +8,6 @@ class LetsSyncroLLC_Oct8ne_Helper_Version extends Mage_Core_Helper_Abstract {
8
  }
9
 
10
  static public function getApiVersion() {
11
- return "2.0";
12
  }
13
  }
8
  }
9
 
10
  static public function getApiVersion() {
11
+ return "2.1";
12
  }
13
  }
app/code/community/LetsSyncroLLC/Oct8ne/Helper/Wishlist.php CHANGED
@@ -23,21 +23,21 @@ class LetsSyncroLLC_Oct8ne_Helper_wishlist extends Mage_Core_Helper_Abstract {
23
  if ($wishList == null) {
24
  return array();
25
  }
26
-
27
  $wishListItemCollection = $wishList->getItemCollection();
 
 
28
 
29
- $productIds = array();
30
  foreach ($wishListItemCollection as $item) {
31
- $productIds[] = $item->getProductId();
32
  }
33
- $dataHelper = Mage::helper("oct8ne"); /* @var $dataHelper LetsSyncroLLC_Oct8ne_Helper_Data */
34
- return $dataHelper->getProductsInfoByIds($productIds);
35
  }
36
 
37
  public function removeFromWishlist($productId) {
38
  $wishList = $this->getCurrentCustomerWishlist();
39
- if ($wishList == null)
40
  return false;
 
41
 
42
  $found = false;
43
  $wishListItemCollection = $wishList->getItemCollection();
@@ -60,7 +60,7 @@ class LetsSyncroLLC_Oct8ne_Helper_wishlist extends Mage_Core_Helper_Abstract {
60
  return null;
61
  }
62
  $customer = Mage::getSingleton('customer/session')->getCustomer();
63
- $wishList = Mage::getSingleton('wishlist/wishlist')->loadByCustomer($customer);
64
  return $wishList;
65
  }
66
  }
23
  if ($wishList == null) {
24
  return array();
25
  }
 
26
  $wishListItemCollection = $wishList->getItemCollection();
27
+ $result = array();
28
+ $dataHelper = Mage::helper("oct8ne"); /* @var $dataHelper LetsSyncroLLC_Oct8ne_Helper_Data */
29
 
 
30
  foreach ($wishListItemCollection as $item) {
31
+ $result[] = $dataHelper->createProductSummaryFromProduct($item->product);
32
  }
33
+ return $result;
 
34
  }
35
 
36
  public function removeFromWishlist($productId) {
37
  $wishList = $this->getCurrentCustomerWishlist();
38
+ if ($wishList == null) {
39
  return false;
40
+ }
41
 
42
  $found = false;
43
  $wishListItemCollection = $wishList->getItemCollection();
60
  return null;
61
  }
62
  $customer = Mage::getSingleton('customer/session')->getCustomer();
63
+ $wishList = Mage::getSingleton('wishlist/wishlist')->loadByCustomer($customer, true);
64
  return $wishList;
65
  }
66
  }
app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Order.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LetsSyncroLLC_Oct8ne_Model_Mysql4_Order extends Mage_Core_Model_Mysql4_Abstract {
4
+
5
+ protected function _construct() {
6
+ $this->_init('oct8ne/order', 'quote_id');
7
+ $this->_isPkAutoIncrement = false;
8
+ }
9
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Order/Collection.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LetsSyncroLLC_Oct8ne_Model_Mysql4_Order_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
3
+ {
4
+ public function _construct()
5
+ {
6
+ $this->_init('oct8ne/order');
7
+ }
8
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Orderproducts.php DELETED
@@ -1,8 +0,0 @@
1
- <?php
2
- class LetsSyncroLLC_Oct8ne_Model_Mysql4_Orderproducts extends Mage_Core_Model_Mysql4_Abstract
3
- {
4
- protected function _construct()
5
- {
6
- $this->_init('oct8ne/orderproducts', 'orderproducts_id');
7
- }
8
- }
 
 
 
 
 
 
 
 
app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Orderproducts/Collection.php DELETED
@@ -1,9 +0,0 @@
1
- <?php
2
- class LetsSyncroLLC_Oct8ne_Model_Mysql4_Orderproducts_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
3
- {
4
- public function _construct()
5
- {
6
- //parent::__construct();
7
- $this->_init('oct8ne/orderproducts');
8
- }
9
- }
 
 
 
 
 
 
 
 
 
app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Quoteproducts.php DELETED
@@ -1,8 +0,0 @@
1
- <?php
2
- class LetsSyncroLLC_Oct8ne_Model_Mysql4_Quoteproducts extends Mage_Core_Model_Mysql4_Abstract
3
- {
4
- protected function _construct()
5
- {
6
- $this->_init('oct8ne/quoteproducts', 'quoteproducts_id');
7
- }
8
- }
 
 
 
 
 
 
 
 
app/code/community/LetsSyncroLLC/Oct8ne/Model/Mysql4/Quoteproducts/Collection.php DELETED
@@ -1,9 +0,0 @@
1
- <?php
2
- class LetsSyncroLLC_Oct8ne_Model_Mysql4_Quoteproducts_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
3
- {
4
- public function _construct()
5
- {
6
- //parent::__construct();
7
- $this->_init('oct8ne/quoteproducts');
8
- }
9
- }
 
 
 
 
 
 
 
 
 
app/code/community/LetsSyncroLLC/Oct8ne/Model/Observer.php CHANGED
@@ -31,69 +31,144 @@ class LetsSyncroLLC_Oct8ne_Model_Observer {
31
  }
32
  }
33
 
34
- /**
35
- * Get checkout session model instance
36
- *
37
- * @return Mage_Checkout_Model_Session
38
- */
39
- protected function _getSession() {
40
- return Mage::getSingleton('checkout/session');
 
 
 
 
 
 
 
 
 
41
  }
42
 
43
- public function placeOrderBefore($observer) {
44
- $order = $observer->getEvent()->getOrder();
45
- $items = $order->getAllVisibleItems();
46
-
47
- foreach ($items as $item) {
48
- $product = $item->getProduct();
49
- $qty = $item->getQtyOrdered();
50
- $session = Mage::getModel('core/cookie')->get('oct8ne-session');
51
- $model = Mage::getModel('oct8ne/orderproducts');
52
- $model->setOrderId($order->getId());
53
- $model->setCustomerId($order->getCustomerId());
54
- $model->setProductId($product->getId());
55
- $model->setProductPrice($product->getPrice()); // getFinalPrice?
56
- $model->setOrderPrice($order->getGrandTotal()); // getSubtotal?
57
- $model->setCreatedAt($order->getCreatedAt());
58
- $model->setOct8ne($session);
59
- $model->setQty($qty);
60
- $model->setCurrency($order->getOrderCurrency()->getCode());
61
- $model->save();
62
  }
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
 
65
- public function saveQuoteAfter($observer) {
66
 
67
- $quote = $observer->getEvent()->getQuote();
 
68
 
69
- // Eliminar los datos anteriores
70
- $items = Mage::getModel('oct8ne/quoteproducts')
71
- ->getCollection()
72
- ->addFilter('quote_id', $quote->getId());
 
 
 
 
 
 
73
 
74
- foreach ($items as $ccitem) {
75
- $ccitem->delete();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  }
77
 
78
- // Añadir el estado actual del carrito
79
- $session = Mage::getModel('core/cookie')->get('oct8ne-session');
80
- $items = $quote->getAllVisibleItems();
 
 
 
 
81
 
82
- foreach ($items as $item) {
83
- $product = $item->getProduct();
84
- $qty = $item->getQty();
85
-
86
- $model = Mage::getModel('oct8ne/quoteproducts');
87
- $model->setQuoteId($quote->getId());
88
- $model->setCustomerId($quote->getCustomerId());
89
- $model->setProductId($product->getId());
90
- $model->setProductPrice($product->getPrice()); // getFinalPrice?
91
- $model->setQuotePrice($quote->getGrandTotal()); // getSubtotal?
92
- $model->setCreatedAt($quote->getCreatedAt());
93
- $model->setOct8ne($session);
94
- $model->setQty($qty);
95
- $model->setCurrency($quote->getQuoteCurrencyCode());
96
- $model->save();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  }
98
  }
99
 
@@ -108,9 +183,14 @@ class LetsSyncroLLC_Oct8ne_Model_Observer {
108
  }
109
 
110
  public function updatedCartOct($observer) {
 
 
 
 
 
111
  $oct8neHostName = Mage::helper("oct8ne/url")->getOct8neHostName();
112
  $oct8ne_url = $oct8neHostName . "/PlatformConnection/update";
113
- $visitor = $_COOKIE["TokenVisitor"];
114
 
115
  if ($visitor != null) {
116
  if (function_exists('curl_init') == 1) {
@@ -123,4 +203,14 @@ class LetsSyncroLLC_Oct8ne_Model_Observer {
123
  }
124
  }
125
  }
 
 
 
 
 
 
 
 
 
 
126
  }
31
  }
32
  }
33
 
34
+ // Observer for event "sales_quote_save_after"
35
+ public function cartUpdated($observer) {
36
+
37
+ // Return if oct8ne is not involved in this cart or if we have just placed an order
38
+ $sessionId = Mage::getModel('core/cookie')->get('oct8ne-session');
39
+ if (is_null($sessionId) || !$sessionId || trim($sessionId) == '' || Mage::registry("oct8ne_sale") == '1') {
40
+ return;
41
+ }
42
+ // Return if no quote is present
43
+ $currentQuote = $observer->getEvent()->getQuote();
44
+ if (is_null($currentQuote)) {
45
+ return;
46
+ }
47
+
48
+ // Create or update an oct8ne order record
49
+ $this->updateOrderModel($sessionId, $currentQuote);
50
  }
51
 
52
+ // Observer for event "sales_order_place_after"
53
+ public function orderSaved($observer) {
54
+
55
+ // Return if oct8ne was not involved in this sale
56
+ $sessionId = Mage::getModel('core/cookie')->get('oct8ne-session');
57
+ if (is_null($sessionId) || !$sessionId || trim($sessionId) == '') {
58
+ return;
59
+ }
60
+ // Return if no order or quote is present
61
+ $currentOrder = $observer->getEvent()->getOrder();
62
+ if (is_null($currentOrder)) {
63
+ return;
 
 
 
 
 
 
 
64
  }
65
+ $currentQuote = $currentOrder->quote;
66
+ if (is_null($currentQuote)) {
67
+ return;
68
+ }
69
+
70
+ // Create or update an oct8ne order record
71
+ $this->updateOrderModel($sessionId, $currentQuote, $currentOrder);
72
+
73
+ // Next, Magento will call cartUpdated() function,
74
+ // so we setup a sentinel to avoid the cart to be saved again
75
+ Mage::register("oct8ne_sale", "1");
76
  }
77
 
78
+ private function updateOrderModel($sessionId, $currentQuote, $currentOrder = NULL) {
79
 
80
+ $quoteId = $currentQuote->getId();
81
+ $oct8neOrder = Mage::getModel('oct8ne/order')->load($quoteId);
82
 
83
+ if (!$oct8neOrder->getQuoteId()) {
84
+ $oct8neOrder = Mage::getModel('oct8ne/order');
85
+ $oct8neOrder->setQuoteId($quoteId);
86
+ $storeId = $currentQuote->getStoreId();
87
+ $oct8neOrder->setStoreId($storeId);
88
+ $oct8neOrder->setUtcCreated(gmdate('Y-m-d H:i:s'));
89
+ $oct8neOrder->setLastAction('C');
90
+ } else {
91
+ $oct8neOrder->setLastAction('U');
92
+ }
93
 
94
+ // Set only updated fields
95
+ if (!$currentOrder && $oct8neOrder->getOrderId()) {
96
+ $oct8neOrder->setOrderId(NULL); // The checkout failed, so we should clear the orderId
97
+ }
98
+
99
+ if ($currentOrder && $oct8neOrder->getOrderId() != $currentOrder->getId()) {
100
+ $oct8neOrder->setOrderId($currentOrder->getId()); // The checkout succeed
101
+ }
102
+
103
+ if ($oct8neOrder->getCustomerId() != $currentQuote->getCustomerId()) {
104
+ $oct8neOrder->setCustomerId($currentQuote->getCustomerId());
105
+ }
106
+
107
+ if ($oct8neOrder->getItemsCount() != $currentQuote->getItemsQty()) {
108
+ $oct8neOrder->setItemsCount($currentQuote->getItemsQty());
109
+ }
110
+
111
+ if ($oct8neOrder->getProductsCount() != $currentQuote->getItemsCount()) {
112
+ $oct8neOrder->setProductsCount($currentQuote->getItemsCount());
113
+ }
114
+ if ($oct8neOrder->getPrice() != $currentQuote->getSubtotal()) {
115
+ $oct8neOrder->setPrice($currentQuote->getSubtotal());
116
  }
117
 
118
+ if ($oct8neOrder->getFinalPrice() != $currentQuote->getGrandTotal()) {
119
+ $oct8neOrder->setFinalPrice($currentQuote->getGrandTotal());
120
+ }
121
+
122
+ if ($oct8neOrder->getCurrency() != $currentQuote->getQuoteCurrencyCode()) {
123
+ $oct8neOrder->setCurrency($currentQuote->getQuoteCurrencyCode());
124
+ }
125
 
126
+ if ($oct8neOrder->getSessionId() != $sessionId) {
127
+ $oct8neOrder->setSessionId($sessionId);
128
+ }
129
+
130
+ // Finally, if some fields have changed, save the record
131
+ if ($oct8neOrder->hasDataChanges()) {
132
+ $oct8neOrder->setUtcLastModified(gmdate('Y-m-d H:i:s'));
133
+ $oct8neOrder->save();
134
+ }
135
+ }
136
+
137
+ // Invoked when an anonymous customer has added some products to the cart, and
138
+ // then log in as user of the platform. If he had products stored in the cart,
139
+ // both carts are merged.
140
+ public function cartMerged($observer) {
141
+
142
+ // Return if oct8ne is not involved in this session
143
+ $sessionId = Mage::getModel('core/cookie')->get('oct8ne-session');
144
+ if (is_null($sessionId) || !$sessionId || trim($sessionId) == '') {
145
+ return;
146
+ }
147
+
148
+ $session = Mage::getSingleton('checkout/session');
149
+ $quoteId = $session->getQuoteId();
150
+ if (!$quoteId) {
151
+ return;
152
+ }
153
+
154
+ $model = Mage::getModel('oct8ne/order');
155
+ $quote = $model->load($quoteId);
156
+ try {
157
+ // We must mark the old quote as deleted because
158
+ // it was created by the anonymous user and we don't need it anymore
159
+ if ($quote->getQuoteId()) {
160
+ $quote->setLastAction('D');
161
+ $quote->setUtcLastModified(gmdate('Y-m-d H:i:s'));
162
+ $quote->save();
163
+ }
164
+
165
+ // And then save the new quote (merged)
166
+ $event = $observer->getEvent();
167
+ $prevQuote = $event->getQuote();
168
+ $this->updateOrderModel($sessionId, $prevQuote);
169
+
170
+ } catch (Exception $e) {
171
+ // Nothing to do
172
  }
173
  }
174
 
183
  }
184
 
185
  public function updatedCartOct($observer) {
186
+ $cookieName = "oct8ne-visitor";
187
+ if (!isset($_COOKIE[$cookieName])) {
188
+ return;
189
+ }
190
+
191
  $oct8neHostName = Mage::helper("oct8ne/url")->getOct8neHostName();
192
  $oct8ne_url = $oct8neHostName . "/PlatformConnection/update";
193
+ $visitor = $_COOKIE[$cookieName];
194
 
195
  if ($visitor != null) {
196
  if (function_exists('curl_init') == 1) {
203
  }
204
  }
205
  }
206
+
207
+ /**
208
+ * Get checkout session model instance
209
+ *
210
+ * @return Mage_Checkout_Model_Session
211
+ */
212
+ protected function _getSession() {
213
+ return Mage::getSingleton('checkout/session');
214
+ }
215
+
216
  }
app/code/community/LetsSyncroLLC/Oct8ne/Model/Order.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LetsSyncroLLC_Oct8ne_Model_Order extends Mage_Core_Model_Abstract
3
+ {
4
+ public function _construct()
5
+ {
6
+ parent::_construct();
7
+ $this->_init('oct8ne/order');
8
+ }
9
+ }
app/code/community/LetsSyncroLLC/Oct8ne/Model/SearchEngines.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LetsSyncroLLC_Oct8ne_Model_SearchEngines extends Mage_Core_Model_Abstract {
4
+
5
+ public function toOptionArray() {
6
+ return array(
7
+ array('value' => 'magento', 'label' => '(Default)'),
8
+ array('value' => 'sli', 'label' => 'SLI Search')
9
+ );
10
+ }
11
+
12
+ }
app/code/community/LetsSyncroLLC/Oct8ne/controllers/FrameController.php CHANGED
@@ -1,5 +1,9 @@
1
  <?php
2
 
 
 
 
 
3
  class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Action {
4
 
5
  public function customerDataAction() {
@@ -19,7 +23,7 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
19
  $this->returnJson($results);
20
  }
21
 
22
- // REVIEW: Remove this function?
23
  public function productviewAction() {
24
  Mage::register('oct8ne_rewrite', 1, true); // lo usamos para deshabilitar el redirect
25
 
@@ -53,6 +57,9 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
53
 
54
  public function getAdapterInfoAction() {
55
 
 
 
 
56
  $versionHelper = Mage::helper("oct8ne/version");
57
  $apiVersion = $versionHelper->getApiVersion();
58
  $adapterVersion = $versionHelper->getAdapterVersion();
@@ -63,15 +70,25 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
63
  "adapterVersion" => $adapterVersion,
64
  "developedBy" => "Oct8ne Inc",
65
  "supportUrl" => "http://www.oct8ne.com/support/magento",
66
- "apiVersion" => $apiVersion
 
67
  );
68
 
69
  $this->returnJson($results);
70
  }
71
 
72
  public function searchAction() {
 
 
 
 
73
  $storeId = $this->getRequest()->getParam('store', null);
74
  $currency = $this->getRequest()->getParam('currency', null);
 
 
 
 
 
75
 
76
  if (is_null($storeId)) {
77
  $storeId = Mage::app()->getStore()->getId();
@@ -87,9 +104,13 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
87
  Mage::app()->getStore()->setCurrentCurrencyCode($currency);
88
  }
89
 
90
- $searchTerm = $this->getRequest()->getParam('search', null);
91
- $this->getRequest()->setParam('q', $searchTerm);
92
- if (! $this->isValidSearchCriteria($searchTerm)) {
 
 
 
 
93
  Mage::app()->getStore()->setCurrentCurrencyCode($currentCurrency);
94
  $results = array(
95
  'total' => 0,
@@ -103,29 +124,15 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
103
  return;
104
  }
105
 
 
106
  $attrs_applied = array();
107
  $attrs_available = array();
108
- $products = $this->getFilteredProducts($storeId, $attrs_applied, $attrs_available);
109
 
110
- $total_search_results = $products->getSize();
111
 
112
- $currency = Mage::helper('oct8ne/customerData')->getCurrency();
113
 
114
- $search_order = $this->getRequest()->getParam('orderby', 'relevance');
115
- $search_dir = $this->getRequest()->getParam('dir', 'asc');
116
- $products->setOrder($search_order, $search_dir);
117
 
118
- $page = $this->getRequest()->getParam("page", 1);
119
- $pageSize = $this->getRequest()->getParam('pageSize', 10);
120
- $products->setPageSize($pageSize)
121
- ->setCurPage($page);
122
-
123
- $ids = array();
124
- foreach ($products as $item) {
125
- $ids[] = $item->getId();
126
- }
127
-
128
- $productInfos = Mage::helper('oct8ne')->getProductsInfoByIds($ids);
129
  $results = array(
130
  'total' => $total_search_results,
131
  'results' => $productInfos,
@@ -142,29 +149,17 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
142
 
143
  Mage::app()->getStore()->setCurrentCurrencyCode($currentCurrency);
144
 
 
145
  $this->returnJson($results);
146
  }
147
 
148
  public function getCartAction() {
149
- $result = array();
150
- $cart = Mage::getSingleton('checkout/cart');
151
- $helper = Mage::helper('oct8ne');
152
-
153
- foreach ($cart->getItems() as $item) {
154
- $product = $item->getProduct();
155
- $qty = $item->getQty();
156
- $type = $product->getTypeId();
157
-
158
- if ($type == Mage_Catalog_Model_Product_Type::TYPE_SIMPLE || $type == Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL) {
159
- $result[] = $helper->getProductInfo($product->getId(), $qty);
160
- }
161
- }
162
-
163
  $results = array(
164
  'total' => count($cart),
165
- 'results' => $result
166
  );
167
-
168
  $this->returnJson($results);
169
  }
170
 
@@ -200,6 +195,9 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
200
  }
201
 
202
  public function productInfoAction() {
 
 
 
203
  $products = $this->getRequest()->getParam('productIds', null);
204
  $product_Ids = explode(',', $products);
205
  if (count($product_Ids) > 0) {
@@ -208,6 +206,22 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
208
  } else {
209
  $result = array();
210
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  $this->returnJson($result);
212
  }
213
 
@@ -220,24 +234,41 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
220
  }
221
 
222
  public function imageAction() {
223
- $imageHelper = Mage::helper("oct8ne/image"); /* @var $imageHelper LetsSyncroLLC_Oct8ne_Helper_Image */
224
  $file = $this->getRequest()->getParam('file', null);
225
  if ($file == null) {
226
  $this->returnNoContent();
227
  return;
228
  }
229
 
230
- $base = Mage::getBaseDir('media');
231
  $width = $this->getRequest()->getParam('width', null);
232
-
233
  if ($width == null) {
234
- $newFile = "$base" . DS . "$file";
235
  } else {
236
- $newFile = $imageHelper->resizeImg($file, $width);
 
 
 
 
 
 
 
 
 
 
 
237
  }
238
- $this->returnImage($newFile);
 
 
 
 
 
 
 
239
  }
240
 
 
241
  public function getReportDataAction() {
242
  if (!$this->checkApiToken()) {
243
  $this->returnNotAuthorized();
@@ -290,7 +321,7 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
290
  'total' => $result_collection->getSize(),
291
  'results' => $v
292
  );
293
- $this->returnJson($results, false /* <- Don't use JSONP */);
294
  }
295
 
296
  public function systemCheckAction() {
@@ -309,14 +340,14 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
309
  private function checkApiToken() {
310
  $letssyncromodel = Mage::getModel('oct8ne/letssyncro')->load(1);
311
  $token = $letssyncromodel->getApitoken();
312
- $apitoken = $this->getRequest()->getParam('apitoken', null);
313
  return ($apitoken == $token);
314
  }
315
 
316
- private function returnJson($jsonData, $isJsonp = true) {
317
  $response = json_encode($jsonData);
318
- if ($isJsonp) {
319
- $callback = $this->getRequest()->getParam('callback', 'callback');
320
  $response = $callback . "(" . $response . ");";
321
  }
322
  $this->getResponse()->setHeader('Content-type', 'application/json; charset=UTF8', true);
@@ -329,10 +360,10 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
329
  $response->setHeader('HTTP/1.0', '401', true);
330
  }
331
 
332
- private function returnNoContent() {
333
  $response = $this->getResponse();
334
  $response->clearHeaders();
335
- $response->setHeader('HTTP/1.0', '204', true);
336
  }
337
 
338
  private function returnImage($physicalFilePath) {
@@ -366,10 +397,10 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
366
  );
367
  }
368
 
369
- //
370
- // For debugging purposes
371
- // Usage: $this->returnContent($anyObject)
372
- //
373
  private function returnContent($object) {
374
  $response = $this->getResponse();
375
  $response->clearHeaders();
@@ -377,119 +408,13 @@ class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Ac
377
  print_r($object);
378
  }
379
 
380
- private function getFilteredProducts($storeId, &$attrs_applied, &$attrs_available) {
381
- $query = Mage::helper('catalogsearch')->getQuery();
382
- $query->setStoreId($storeId);
383
- if ($query->getId()) {
384
- $query->setPopularity($query->getPopularity() + 1);
385
- } else {
386
- $query->setPopularity(1);
387
- }
388
- $query->prepare();
389
- Mage::helper('catalogsearch')->checkNotes();
390
-
391
- $query = Mage::getModel('catalogsearch/layer');
392
-
393
- $filterableAttributes = $query->getFilterableAttributes();
394
- $attrs = array();
395
-
396
- if (!empty($filterableAttributes)) {
397
- $tmp = new Mage_Catalog_Model_Resource_Eav_Attribute();
398
- $tmp->SetAttributeCode('category');
399
- $tmp->setFrontendLabel('Category');
400
- $filterableAttributes->addItem($tmp);
401
- }
402
-
403
- foreach ($filterableAttributes as $attribute) {
404
- $code = $attribute->getAttributeCode();
405
- $name = $attribute->getFrontendLabel();
406
-
407
- // INIT
408
- $items = array();
409
- switch ($code) {
410
- case 'price':
411
- $_filterModelName = "catalog/layer_filter_price";
412
- break;
413
- case 'decimal':
414
- $_filterModelName = "catalog/layer_filter_decimal";
415
- break;
416
- case 'category':
417
- $_filterModelName = "catalog/layer_filter_category";
418
- break;
419
- default:
420
- $_filterModelName = "catalog/layer_filter_attribute";
421
- break;
422
- }
423
-
424
- $filter = Mage::getModel($_filterModelName)
425
- ->setLayer($query)
426
- ->setAttributeModel($attribute);
427
- $filter->apply($this->getRequest(), $this);
428
- $items = $filter->getItems();
429
-
430
- // En los filtros aplicados no nos viene el nombre, solo el id, lo obtenemos aqui
431
- $optionId = $this->getRequest()->getParam($filter->getRequestVar());
432
- $featurename = "";
433
- if (!is_null($optionId)) {
434
- switch ($code) {
435
- case 'price':
436
- $featurename = $this->getRequest()->get($code);
437
- break;
438
- case 'decimal':
439
- $featurename = $this->getRequest()->get($code);
440
- break;
441
- case 'category':
442
- $featurename = $filter->getCategory()->getName();
443
- break;
444
- default:
445
- $featurename = $filter->getAttributeModel()->getFrontend()->getOption($optionId);
446
- break;
447
- }
448
- }
449
-
450
- $options = array();
451
- foreach ($items as $item) {
452
- if ($item->getCount() > 0) {
453
- $options[] = array(
454
- "valueLabel" => $item->getLabel(),
455
- "value" => $item->getValue(),
456
- "count" => $item->getCount()
457
- );
458
- }
459
- }
460
-
461
- $attrs[] = array(
462
- 'param' => $code,
463
- 'paramLabel' => $name,
464
- 'options' => $options,
465
- 'valueLabel' => $featurename
466
- );
467
- }
468
-
469
- foreach ($attrs as $attr) {
470
- if (!is_null($this->getRequest()->getParam($attr['param']))) {
471
- $attr['value'] = $this->getRequest()->getParam($attr['param']);
472
- $attrs_applied[] = $attr;
473
- } else {
474
- $attrs_available[] = $attr;
475
- }
476
  }
477
-
478
- $result_collection = $query->getProductCollection();
479
- return $result_collection;
480
  }
481
 
482
- private function isValidSearchCriteria($searchTerm) {
483
- if (is_null($searchTerm) || strlen($searchTerm) == 0) {
484
- return false;
485
- }
486
-
487
- $helper = Mage::helper("catalogsearch"); /* @var $helper Mage_CatalogSearch_Helper_Data */
488
- $len = strlen($searchTerm);
489
- if ($len < $helper->getMinQueryLength() || $len > $helper->getMaxQueryLength()) {
490
- return false;
491
- }
492
-
493
- return true;
494
- }
495
- }
1
  <?php
2
 
3
+ // Uncomment these lines to show error 500 descriptions
4
+ // Mage::setIsDeveloperMode(true);
5
+ // ini_set('display_errors', 1);
6
+
7
  class LetsSyncroLLC_Oct8ne_FrameController extends Mage_Core_Controller_Front_Action {
8
 
9
  public function customerDataAction() {
23
  $this->returnJson($results);
24
  }
25
 
26
+ // REVIEW: Remove this function?
27
  public function productviewAction() {
28
  Mage::register('oct8ne_rewrite', 1, true); // lo usamos para deshabilitar el redirect
29
 
57
 
58
  public function getAdapterInfoAction() {
59
 
60
+ $model = Mage::getModel('oct8ne/letssyncro')->load(1);
61
+ $enabled = $model ? $model->getEnabled() : FALSE;
62
+
63
  $versionHelper = Mage::helper("oct8ne/version");
64
  $apiVersion = $versionHelper->getApiVersion();
65
  $adapterVersion = $versionHelper->getAdapterVersion();
70
  "adapterVersion" => $adapterVersion,
71
  "developedBy" => "Oct8ne Inc",
72
  "supportUrl" => "http://www.oct8ne.com/support/magento",
73
+ "apiVersion" => $apiVersion,
74
+ "enabled" => $enabled ? 'true' : 'false'
75
  );
76
 
77
  $this->returnJson($results);
78
  }
79
 
80
  public function searchAction() {
81
+
82
+ $profiler = Mage::helper('oct8ne/debug'); /* @var $profiler LetsSyncroLLC_Oct8ne_Helper_Debug */
83
+ $actionStart = $profiler->startProfile("[FrameController] Starting search action");
84
+
85
  $storeId = $this->getRequest()->getParam('store', null);
86
  $currency = $this->getRequest()->getParam('currency', null);
87
+ $searchTerm = $this->getRequest()->getParam('search', null);
88
+ $searchOrder = $this->getRequest()->getParam('orderby', 'relevance');
89
+ $searchDir = $this->getRequest()->getParam('dir', 'asc');
90
+ $page = $this->getRequest()->getParam("page", 1);
91
+ $pageSize = $this->getRequest()->getParam('pageSize', 10);
92
 
93
  if (is_null($storeId)) {
94
  $storeId = Mage::app()->getStore()->getId();
104
  Mage::app()->getStore()->setCurrentCurrencyCode($currency);
105
  }
106
 
107
+ $searchEngineName = strtolower(Mage::getStoreConfig('oct8neSearch/searchEngine/engine'));
108
+ if ($searchEngineName == '') {
109
+ $searchEngineName = 'Magento';
110
+ }
111
+ $searchEngine = Mage::Helper('oct8ne/search_' . $searchEngineName); /* @var $searchEngine LetsSyncroLLC_Oct8ne_Helper_Search_Base */
112
+
113
+ if (!$searchEngine->isValidSearchCriteria($searchTerm)) {
114
  Mage::app()->getStore()->setCurrentCurrencyCode($currentCurrency);
115
  $results = array(
116
  'total' => 0,
124
  return;
125
  }
126
 
127
+ $total_search_results = 0;
128
  $attrs_applied = array();
129
  $attrs_available = array();
 
130
 
131
+ $productIds = $searchEngine->search($storeId, $searchTerm, $searchOrder, $searchDir, $page, $pageSize, $total_search_results, $attrs_applied, $attrs_available);
132
 
 
133
 
134
+ $productInfos = Mage::helper('oct8ne')->getProductsSummaryByIds($productIds);
 
 
135
 
 
 
 
 
 
 
 
 
 
 
 
136
  $results = array(
137
  'total' => $total_search_results,
138
  'results' => $productInfos,
149
 
150
  Mage::app()->getStore()->setCurrentCurrencyCode($currentCurrency);
151
 
152
+ $profiler->endProfile($actionStart, "[FrameController] Ending search action");
153
  $this->returnJson($results);
154
  }
155
 
156
  public function getCartAction() {
157
+ $customerDataHelper = Mage::helper('oct8ne/customerData');
158
+ $cart = $customerDataHelper->getCartData();
 
 
 
 
 
 
 
 
 
 
 
 
159
  $results = array(
160
  'total' => count($cart),
161
+ 'results' => $cart
162
  );
 
163
  $this->returnJson($results);
164
  }
165
 
195
  }
196
 
197
  public function productInfoAction() {
198
+ $profiler = Mage::helper('oct8ne/debug'); /* @var $profiler LetsSyncroLLC_Oct8ne_Helper_Debug */
199
+ $actionStart = $profiler->startProfile("[FrameController] Starting ProductInfoAction");
200
+
201
  $products = $this->getRequest()->getParam('productIds', null);
202
  $product_Ids = explode(',', $products);
203
  if (count($product_Ids) > 0) {
206
  } else {
207
  $result = array();
208
  }
209
+ $profiler->endProfile($actionStart, "[FrameController] Ending ProductInfoAction");
210
+ $this->returnJson($result);
211
+ }
212
+
213
+ public function productSummaryAction() {
214
+ $profiler = Mage::helper('oct8ne/debug'); /* @var $profiler LetsSyncroLLC_Oct8ne_Helper_Debug */
215
+ $actionStart = $profiler->startProfile("[FrameController] Starting ProductSummaryAction");
216
+ $products = $this->getRequest()->getParam('productIds', null);
217
+ $product_Ids = explode(',', $products);
218
+ if (count($product_Ids) > 0) {
219
+ $helper = Mage::helper('oct8ne'); /* @var $helper LetsSyncroLLC_Oct8ne_Helper_Data */
220
+ $result = $helper->getProductsSummaryByIds($product_Ids);
221
+ } else {
222
+ $result = array();
223
+ }
224
+ $profiler->endProfile($actionStart, "[FrameController] Ending ProductSummaryAction");
225
  $this->returnJson($result);
226
  }
227
 
234
  }
235
 
236
  public function imageAction() {
 
237
  $file = $this->getRequest()->getParam('file', null);
238
  if ($file == null) {
239
  $this->returnNoContent();
240
  return;
241
  }
242
 
243
+ $imageHelper = self::getImageHelper(); /* @var $imageHelper LetsSyncroLLC_Oct8ne_Helper_Image_Default */
244
  $width = $this->getRequest()->getParam('width', null);
 
245
  if ($width == null) {
246
+ $newFilePhysicalPath = $imageHelper->getImagePhysicalPath($file);
247
  } else {
248
+ $resizedUrl = ltrim($imageHelper->resizeImg($file, $width), '/');
249
+ $resizedUrl = substr($resizedUrl, strpos($resizedUrl, 'media') + 6);
250
+ $path = Mage::getBaseDir(Mage_Core_Model_Store::URL_TYPE_MEDIA) . DS . $resizedUrl;
251
+ $newFilePhysicalPath = $path;
252
+ }
253
+ $this->returnImage($newFilePhysicalPath);
254
+ }
255
+
256
+ public function getSalesReportAction() {
257
+ if (!$this->checkApiToken()) {
258
+ $this->returnNotAuthorized();
259
+ return false;
260
  }
261
+ $from = $this->getRequest()->getParam('from', null);
262
+ $to = $this->getRequest()->getParam('to', null);
263
+ if (!$from || !$to) {
264
+ $this->returnBadRequest();
265
+ }
266
+ $helper = Mage::helper('oct8ne/reports'); /* @var $helper LetsSyncroLLC_Oct8ne_Helper_Reports */
267
+ $result = $helper->getSales($from, $to);
268
+ $this->returnJson($result);
269
  }
270
 
271
+ // Deprecated in API 2.1
272
  public function getReportDataAction() {
273
  if (!$this->checkApiToken()) {
274
  $this->returnNotAuthorized();
321
  'total' => $result_collection->getSize(),
322
  'results' => $v
323
  );
324
+ $this->returnJson($results);
325
  }
326
 
327
  public function systemCheckAction() {
340
  private function checkApiToken() {
341
  $letssyncromodel = Mage::getModel('oct8ne/letssyncro')->load(1);
342
  $token = $letssyncromodel->getApitoken();
343
+ $apitoken = $this->getRequest()->getParam('apiToken', null);
344
  return ($apitoken == $token);
345
  }
346
 
347
+ private function returnJson($jsonData) {
348
  $response = json_encode($jsonData);
349
+ $callback = $this->getRequest()->getParam('callback', NULL);
350
+ if ($callback) {
351
  $response = $callback . "(" . $response . ");";
352
  }
353
  $this->getResponse()->setHeader('Content-type', 'application/json; charset=UTF8', true);
360
  $response->setHeader('HTTP/1.0', '401', true);
361
  }
362
 
363
+ private function returnBadRequest() {
364
  $response = $this->getResponse();
365
  $response->clearHeaders();
366
+ $response->setHeader('HTTP/1.0', '400', true);
367
  }
368
 
369
  private function returnImage($physicalFilePath) {
397
  );
398
  }
399
 
400
+ //
401
+ // For debugging purposes
402
+ // Usage: $this->returnContent($anyObject)
403
+ //
404
  private function returnContent($object) {
405
  $response = $this->getResponse();
406
  $response->clearHeaders();
408
  print_r($object);
409
  }
410
 
411
+ static private function getImageHelper() {
412
+ $helperName = Mage::getStoreConfig('oct8neData/advancedDataConfig/imageHelperName');
413
+ if (!$helperName) {
414
+ $helperName = 'default';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  }
416
+ $helperName = 'oct8ne/image_' . $helperName;
417
+ return Mage::helper($helperName);
 
418
  }
419
 
420
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/LetsSyncroLLC/Oct8ne/controllers/SetupController.php ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LetsSyncroLLC_Oct8ne_SetupController extends Mage_Core_Controller_Front_Action {
4
+
5
+ public function indexAction() {
6
+ if (!$this->isValidIp()) {
7
+ $this->returnNotAuthorized();
8
+ return false;
9
+ }
10
+
11
+ $response = $this->getResponse();
12
+ $response->clearHeaders();
13
+ $response->setHeader('Content-type', 'text/html; charset=UTF8', true);
14
+ print "<html><body>";
15
+ print "<h2 style='color: orange'>Oct8ne</h2>";
16
+ print "<p>Welcome to oct8ne's setup utility!</p>";
17
+ print "<ul>";
18
+ print "<li><a href='/oct8ne/setup/settings'>View or change Settings</a></li>";
19
+ print "<li><a href='/oct8ne/setup/linkup'>View or change Linkup or Service status</a></li>";
20
+ print "</ul>";
21
+ print "</body></html>";
22
+ }
23
+
24
+ public function settingsAction() {
25
+ if (!$this->isValidIp()) {
26
+ $this->returnNotAuthorized();
27
+ return false;
28
+ }
29
+
30
+ $settings = "";
31
+ $dataList = array();
32
+ $this->addSetting($dataList, $settings, 'oct8neSearch/assistedSearch/elementSelector', "Search element selector", 'CSS selector. Example: "#search"');
33
+ $this->addSetting($dataList, $settings, 'oct8neSearch/searchEngine/engine', "Search engine", 'Allowed: { "magento", "sli" }');
34
+ $this->addSetting($dataList, $settings, 'oct8neSearch/searchEngine/params', "Search engine settings", '"Search engine specific settings"');
35
+ $this->addSetting($dataList, $settings, 'oct8neData/productData/productDataDescription', "Comma-separated product description fields", 'Example: "description, short_description"');
36
+ $this->addSetting($dataList, $settings, 'oct8neData/productData/ignoreExcludedImages', "Ignore images marked as excluded", "1=true, 0=false");
37
+ $this->addSetting($dataList, $settings, 'oct8neData/advancedDataConfig/imageHelperName', "Image helper name", 'Example: "default" to use helper/images/default.php');
38
+ $this->addSetting($dataList, $settings, 'oct8neData/advancedDataConfig/loadCompleteProductInfo', "Load complete product info", "1=true, 0=false");
39
+ $this->addSetting($dataList, $settings, 'oct8neData/advancedDataConfig/imageGalleryPrefetch', "Prefetch image gallery", "1=true, 0=false");
40
+
41
+ $response = $this->getResponse();
42
+ $response->clearHeaders();
43
+ $response->setHeader('Content-type', 'text/html; charset=UTF8', true);
44
+ print "<html><body>";
45
+ print "<h2>Setup &gt; View/change settings</h2>";
46
+ if($this->getRequest()->getParam('done')) {
47
+ print "<h3 style='color: blue'>Settings changed!</h3>";
48
+ }
49
+ print "<datalist id='settings'>";
50
+ foreach ($dataList as $item) {
51
+ print "<option value='{$item}'/>";
52
+ }
53
+ print "</datalist>";
54
+ print "<table border=1 cellspacing=0 cellpadding=3><tr><th>Key</th><th>Current value</th><th>Description</th><th>Example/Allowed values</th></tr>";
55
+ print_r($settings);
56
+ print "</table>";
57
+ print "<hr><form method='post' action='/oct8ne/setup/setsettings'>"
58
+ . "Key: <input type='text' name='setting' list='settings' size='50'> "
59
+ . "New value: <input type='text' name='value'> "
60
+ . "<input type='hidden' name='apitoken' value='" . $this->getRequest()->getParam('apitoken', null) . "'>"
61
+ . "<input type='submit'>"
62
+ . "</form>"
63
+ . "<p><a href='/oct8ne/setup'>Back to menu</a></p>"
64
+ . "</body></html>";
65
+ }
66
+
67
+ public function setSettingsAction() {
68
+ if (!$this->isValidIp()) {
69
+ $this->returnNotAuthorized();
70
+ return false;
71
+ }
72
+
73
+ $setting = $this->getRequest()->getParam('setting');
74
+ if (!$setting) {
75
+ $this->returnBadRequest();
76
+ return false;
77
+ }
78
+ $value = $this->getRequest()->getParam('value');
79
+
80
+ $config = new Mage_Core_Model_Config();
81
+ $config->saveConfig(trim($setting), trim($value), 'default', 0);
82
+
83
+ // Mage::app()->cleanCache();
84
+ Mage::getConfig()->reinit();
85
+ header("Location: /oct8ne/setup/settings?done=1");
86
+ die();
87
+ }
88
+
89
+ public function linkupAction() {
90
+
91
+ if (!$this->isValidIp()) {
92
+ $this->returnNotAuthorized();
93
+ return false;
94
+ }
95
+
96
+ $response = $this->getResponse();
97
+ $response->clearHeaders();
98
+ $response->setHeader('Content-type', 'text/html; charset=UTF8', true);
99
+
100
+ $letssyncromodel = Mage::getModel('oct8ne/letssyncro')->load(1);
101
+ $apiToken = $letssyncromodel->getApitoken();
102
+ $licenseId = $letssyncromodel->getLicenseid();
103
+ $enabled = $letssyncromodel->getEnabled() == '1';
104
+
105
+ print "<html><body>";
106
+ print "<h2>Setup &gt; Linkup/Status</h2>";
107
+ if($this->getRequest()->getParam('done')) {
108
+ print "<h3 style='color: blue'>Linkup/status settings changed!</h3>";
109
+ }
110
+ print "<hr><form method='post' action='/oct8ne/setup/setLinkup'>"
111
+ . "API token: <input type='text' name='apiToken' value='{$apiToken}' required> <br />"
112
+ . "License ID: <input type='text' name='licenseId' value='{$licenseId}' required> <br />"
113
+ . "Enabled: <select name='enabled'>"
114
+ . "<option value='0'" . ($enabled? '': 'selected') . ">No</option>"
115
+ . "<option value='1'" . ($enabled? 'selected': '') . ">Yes</option>"
116
+ . "</select>"
117
+ . "<br /> <br /> "
118
+ . "<input type='submit'>"
119
+ . "</form>"
120
+ . "<p><a href='/oct8ne/setup'>Back to menu</a></p>"
121
+ . "</body></html>";
122
+ }
123
+
124
+ public function setLinkupAction() {
125
+ if (!$this->isValidIp()) {
126
+ $this->returnNotAuthorized();
127
+ return false;
128
+ }
129
+
130
+ $request = $this->getRequest();
131
+ $letssyncromodel = Mage::getModel('oct8ne/letssyncro')->load(1);
132
+ $apiToken = $request->getParam('apiToken');
133
+ $licenseId = $request->getParam('licenseId');
134
+ $enabled = $request->getParam('enabled');
135
+
136
+ $letssyncromodel->setApitoken($apiToken);
137
+ $letssyncromodel->setLicenseid($licenseId);
138
+ $letssyncromodel->setEnabled($enabled);
139
+
140
+ $letssyncromodel->save();
141
+
142
+ header("Location: /oct8ne/setup/linkup?done=1");
143
+ die();
144
+ }
145
+
146
+ private function addSetting(&$dataList, &$str, $setting, $title, $example = NULL) {
147
+ $dataList[] = $setting;
148
+ $result = Mage::getStoreConfig($setting);
149
+ if (is_null($result) || $result == "") {
150
+ $result = "(not set)";
151
+ }
152
+ $str .= "<tr><td>{$setting}</td><td>{$result}</td><td>{$title}</td><td>$example</td>";
153
+ return $str;
154
+ }
155
+
156
+ private function isValidIp() {
157
+ $ip = $_SERVER['REMOTE_ADDR'];
158
+ return $ip == '127.0.0.1' || $ip == '80.28.120.5';
159
+ }
160
+
161
+ private function returnBadRequest() {
162
+ $response = $this->getResponse();
163
+ $response->clearHeaders();
164
+ $response->setHeader('HTTP/1.0', '400', true);
165
+ }
166
+
167
+ private function returnNotAuthorized() {
168
+ $response = $this->getResponse();
169
+ $response->clearHeaders();
170
+ $response->setHeader('HTTP/1.0', '401', true);
171
+ }
172
+ }
app/code/community/LetsSyncroLLC/Oct8ne/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <LetsSyncroLLC_Oct8ne>
5
- <version>2.0.3</version>
6
  </LetsSyncroLLC_Oct8ne>
7
  </modules>
8
 
@@ -19,14 +19,9 @@
19
  <letssyncro>
20
  <table>letssyncro</table>
21
  </letssyncro>
22
-
23
- <orderproducts>
24
- <table>orderproducts</table>
25
- </orderproducts>
26
-
27
- <quoteproducts>
28
- <table>quoteproducts</table>
29
- </quoteproducts>
30
  </entities>
31
  </oct8ne_mysql4>
32
 
@@ -101,28 +96,38 @@
101
  <method>interceptMethod</method>
102
  </LetsSyncroLLC_Oct8ne_Intercept>
103
  </observers>
104
- </controller_front_init_routers>
105
 
106
  <sales_order_place_after>
107
  <observers>
108
- <LetsSyncroLLC_Oct8ne_Order>
109
  <type>singleton</type>
110
  <class>LetsSyncroLLC_Oct8ne_Model_Observer</class>
111
- <method>placeOrderBefore</method>
112
- </LetsSyncroLLC_Oct8ne_Order>
113
  </observers>
114
  </sales_order_place_after>
115
 
116
  <sales_quote_save_after>
117
  <observers>
118
- <LetsSyncroLLC_Oct8ne_Quote>
119
  <type>singleton</type>
120
  <class>LetsSyncroLLC_Oct8ne_Model_Observer</class>
121
- <method>saveQuoteAfter</method>
122
- </LetsSyncroLLC_Oct8ne_Quote>
123
  </observers>
124
  </sales_quote_save_after>
125
 
 
 
 
 
 
 
 
 
 
 
126
  <controller_action_predispatch>
127
  <observers>
128
  <LetsSyncroLLC_Oct8ne_Quote_security_domain_policy>
@@ -170,18 +175,6 @@
170
  </updates>
171
  </layout>
172
  </frontend>
173
-
174
- <admin>
175
- <routers>
176
- <oct8ne>
177
- <use>admin</use>
178
- <args>
179
- <module>LetsSyncroLLC_Oct8ne</module>
180
- <frontName>oct8neAdm</frontName>
181
- </args>
182
- </oct8ne>
183
- </routers>
184
- </admin>
185
 
186
  <adminhtml>
187
  <translate>
@@ -204,16 +197,6 @@
204
  <action>oct8ne/admin/accountconfig</action>
205
  <sort_order>0</sort_order>
206
  </accountconfig>
207
- <!--<dashboard translate="title" module="oct8ne">
208
- <title>Dashboard</title>
209
- <action>oct8ne/admin/dashboard</action>
210
- <sort_order>20</sort_order>
211
- </dashboard>
212
- <syncrodata translate="title" module="oct8ne">
213
- <title>Syncro Data</title>
214
- <action>oct8ne/admin/syncrodata</action>
215
- <sort_order>40</sort_order>
216
- </syncrodata>-->
217
  </children>
218
  </oct8ne>
219
  </menu>
@@ -222,6 +205,24 @@
222
  <resources>
223
  <admin>
224
  <children>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  <oct8ne translate="title" module="oct8ne">
226
  <title>Oct8ne</title>
227
  <sort_order>1000</sort_order>
@@ -231,16 +232,6 @@
231
  <action>oct8ne/admin/accountconfig</action>
232
  <sort_order>0</sort_order>
233
  </accountconfig>
234
- <!--<dashboard translate="title" module="oct8ne">
235
- <title>Dashboard</title>
236
- <action>oct8ne/admin/dashboard</action>
237
- <sort_order>20</sort_order>
238
- </dashboard>
239
- <syncrodata translate="title" module="oct8ne">
240
- <title>Syncro Data</title>
241
- <action>oct8ne/admin/syncrodata</action>
242
- <sort_order>40</sort_order>
243
- </syncrodata>-->
244
  </children>
245
  </oct8ne>
246
  </children>
@@ -256,6 +247,20 @@
256
  <theme>oct8ne</theme>
257
  </oct8nedesign>
258
  </design>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  </default>
260
  </config>
261
 
2
  <config>
3
  <modules>
4
  <LetsSyncroLLC_Oct8ne>
5
+ <version>2.1.0</version>
6
  </LetsSyncroLLC_Oct8ne>
7
  </modules>
8
 
19
  <letssyncro>
20
  <table>letssyncro</table>
21
  </letssyncro>
22
+ <order>
23
+ <table>letssyncro_orders</table>
24
+ </order>
 
 
 
 
 
25
  </entities>
26
  </oct8ne_mysql4>
27
 
96
  <method>interceptMethod</method>
97
  </LetsSyncroLLC_Oct8ne_Intercept>
98
  </observers>
99
+ </controller_front_init_routers>
100
 
101
  <sales_order_place_after>
102
  <observers>
103
+ <LetsSyncroLLC_Oct8ne_Orderplaced>
104
  <type>singleton</type>
105
  <class>LetsSyncroLLC_Oct8ne_Model_Observer</class>
106
+ <method>orderSaved</method>
107
+ </LetsSyncroLLC_Oct8ne_Orderplaced>
108
  </observers>
109
  </sales_order_place_after>
110
 
111
  <sales_quote_save_after>
112
  <observers>
113
+ <LetsSyncroLLC_Oct8ne_Cartupdated>
114
  <type>singleton</type>
115
  <class>LetsSyncroLLC_Oct8ne_Model_Observer</class>
116
+ <method>cartUpdated</method>
117
+ </LetsSyncroLLC_Oct8ne_Cartupdated>
118
  </observers>
119
  </sales_quote_save_after>
120
 
121
+ <sales_quote_merge_before>
122
+ <observers>
123
+ <LetsSyncroLLC_Oct8ne_Cartmerged>
124
+ <type>singleton</type>
125
+ <class>LetsSyncroLLC_Oct8ne_Model_Observer</class>
126
+ <method>cartMerged</method>
127
+ </LetsSyncroLLC_Oct8ne_Cartmerged>
128
+ </observers>
129
+ </sales_quote_merge_before>
130
+
131
  <controller_action_predispatch>
132
  <observers>
133
  <LetsSyncroLLC_Oct8ne_Quote_security_domain_policy>
175
  </updates>
176
  </layout>
177
  </frontend>
 
 
 
 
 
 
 
 
 
 
 
 
178
 
179
  <adminhtml>
180
  <translate>
197
  <action>oct8ne/admin/accountconfig</action>
198
  <sort_order>0</sort_order>
199
  </accountconfig>
 
 
 
 
 
 
 
 
 
 
200
  </children>
201
  </oct8ne>
202
  </menu>
205
  <resources>
206
  <admin>
207
  <children>
208
+ <system>
209
+ <children>
210
+ <config>
211
+ <children>
212
+ <oct8neSearch>
213
+ <title>Oct8ne Search</title>
214
+ </oct8neSearch>
215
+ </children>
216
+ <children>
217
+ <oct8neData>
218
+ <title>Oct8ne Data</title>
219
+ </oct8neData>
220
+ </children>
221
+ </config>
222
+
223
+ </children>
224
+ </system>
225
+
226
  <oct8ne translate="title" module="oct8ne">
227
  <title>Oct8ne</title>
228
  <sort_order>1000</sort_order>
232
  <action>oct8ne/admin/accountconfig</action>
233
  <sort_order>0</sort_order>
234
  </accountconfig>
 
 
 
 
 
 
 
 
 
 
235
  </children>
236
  </oct8ne>
237
  </children>
247
  <theme>oct8ne</theme>
248
  </oct8nedesign>
249
  </design>
250
+ <oct8neData>
251
+ <productData>
252
+ <ignoreExcludedImages>0</ignoreExcludedImages>
253
+ </productData>
254
+ <advancedDataConfig>
255
+ <imageGalleryPrefetch>1</imageGalleryPrefetch>
256
+ </advancedDataConfig>
257
+ </oct8neData>
258
+ <oct8neSearch>
259
+ <searchEngine>
260
+ <engine>magento</engine>
261
+ </searchEngine>
262
+ </oct8neSearch>
263
+
264
  </default>
265
  </config>
266
 
app/code/community/LetsSyncroLLC/Oct8ne/etc/system.xml CHANGED
@@ -1,17 +1,108 @@
1
  <?xml version="1.0"?>
2
  <config>
 
 
 
 
 
 
 
3
  <sections>
4
- <design>
 
 
 
 
 
5
  <groups>
6
- <oct8nedesign translate="label">
7
- <label>Oct8ne Design</label>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  <frontend_type>text</frontend_type>
9
  <sort_order>1</sort_order>
10
  <show_in_default>1</show_in_default>
11
  <show_in_website>1</show_in_website>
12
  <show_in_store>1</show_in_store>
13
  <fields>
14
- <elementselector translate="label">
15
  <label>Search Element Selector</label>
16
  <comment>CSS selector matching your site's main search text box. Example: #main-body .search</comment>
17
  <frontend_type>text</frontend_type>
@@ -19,10 +110,42 @@
19
  <show_in_default>1</show_in_default>
20
  <show_in_website>1</show_in_website>
21
  <show_in_store>1</show_in_store>
22
- </elementselector>
23
  </fields>
24
- </oct8nedesign>
25
  </groups>
26
- </design>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  </sections>
28
  </config>
1
  <?xml version="1.0"?>
2
  <config>
3
+ <tabs><!--creates tabs on the adminhtml page-->
4
+ <oct8ne_tab module="oct8ne">
5
+ <label>OCT8NE</label>
6
+ <sort_order>999999</sort_order><!--the order of the tab-->
7
+ </oct8ne_tab>
8
+ </tabs>
9
+
10
  <sections>
11
+ <oct8neData>
12
+ <label>Data</label>
13
+ <tab>oct8ne_tab</tab>
14
+ <show_in_default>1</show_in_default>
15
+ <show_in_website>1</show_in_website>
16
+ <show_in_store>1</show_in_store>
17
  <groups>
18
+ <productData translate="label">
19
+ <label>Products</label>
20
+ <frontend_type>text</frontend_type>
21
+ <sort_order>10</sort_order>
22
+ <show_in_default>1</show_in_default>
23
+ <show_in_website>1</show_in_website>
24
+ <show_in_store>1</show_in_store>
25
+ <fields>
26
+ <productDataDescription translate="label">
27
+ <label>Description Attributes</label>
28
+ <comment>Type the attributes containing the product descriptions, separated by commas. By default, "description,short_description".</comment>
29
+ <frontend_type>text</frontend_type>
30
+ <sort_order>10</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>1</show_in_website>
33
+ <show_in_store>1</show_in_store>
34
+ </productDataDescription>
35
+ <ignoreExcludedImages translate="label">
36
+ <label>Ignore Excluded Images</label>
37
+ <comment>Oct8ne should ignore the images marked as 'excluded' in the product definition.</comment>
38
+ <source_model>Mage_Adminhtml_Model_System_Config_Source_Yesno</source_model>
39
+ <frontend_type>select</frontend_type>
40
+ <sort_order>20</sort_order>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>1</show_in_website>
43
+ <show_in_store>1</show_in_store>
44
+ </ignoreExcludedImages>
45
+ </fields>
46
+ </productData>
47
+ <advancedDataConfig translate="label">
48
+ <label>Advanced</label>
49
+ <frontend_type>text</frontend_type>
50
+ <sort_order>20</sort_order>
51
+ <show_in_default>1</show_in_default>
52
+ <show_in_website>1</show_in_website>
53
+ <show_in_store>1</show_in_store>
54
+ <fields>
55
+ <imageHelperName translate="label">
56
+ <label>Image Helper Name</label>
57
+ <comment>Enter the image helper name. By default, we'll use the Default image helper.</comment>
58
+ <frontend_type>text</frontend_type>
59
+ <sort_order>10</sort_order>
60
+ <show_in_default>1</show_in_default>
61
+ <show_in_website>1</show_in_website>
62
+ <show_in_store>1</show_in_store>
63
+ </imageHelperName>
64
+ <loadCompleteProductInfo translate="label">
65
+ <label>ProductInfo Full Load</label>
66
+ <comment>The productInfo structure will be loaded using load() core method instead of optimized queries. Useful when you are using a lot of custom fields or non-standard configurations in your products.</comment>
67
+ <source_model>Mage_Adminhtml_Model_System_Config_Source_Yesno</source_model>
68
+ <frontend_type>select</frontend_type>
69
+ <sort_order>20</sort_order>
70
+ <show_in_default>1</show_in_default>
71
+ <show_in_website>1</show_in_website>
72
+ <show_in_store>1</show_in_store>
73
+ </loadCompleteProductInfo>
74
+ <imageGalleryPrefetch translate="label">
75
+ <label>Image Gallery Prefetch</label>
76
+ <comment>Oct8ne should try to prefetch the image gallery to speed up product loading. Only applies if you selected "No" in ProductInfo Full Load.</comment>
77
+ <source_model>Mage_Adminhtml_Model_System_Config_Source_Yesno</source_model>
78
+ <frontend_type>select</frontend_type>
79
+ <sort_order>30</sort_order>
80
+ <show_in_default>1</show_in_default>
81
+ <show_in_website>1</show_in_website>
82
+ <show_in_store>1</show_in_store>
83
+ </imageGalleryPrefetch>
84
+ </fields>
85
+ </advancedDataConfig>
86
+ </groups>
87
+ </oct8neData>
88
+
89
+ <oct8neSearch>
90
+ <label>Search</label>
91
+ <tab>oct8ne_tab</tab>
92
+ <show_in_default>1</show_in_default>
93
+ <show_in_website>1</show_in_website>
94
+ <show_in_store>1</show_in_store>
95
+
96
+ <groups>
97
+ <assistedSearch translate="label">
98
+ <label>Assisted Search Integration</label>
99
  <frontend_type>text</frontend_type>
100
  <sort_order>1</sort_order>
101
  <show_in_default>1</show_in_default>
102
  <show_in_website>1</show_in_website>
103
  <show_in_store>1</show_in_store>
104
  <fields>
105
+ <elementSelector translate="label">
106
  <label>Search Element Selector</label>
107
  <comment>CSS selector matching your site's main search text box. Example: #main-body .search</comment>
108
  <frontend_type>text</frontend_type>
110
  <show_in_default>1</show_in_default>
111
  <show_in_website>1</show_in_website>
112
  <show_in_store>1</show_in_store>
113
+ </elementSelector>
114
  </fields>
115
+ </assistedSearch>
116
  </groups>
117
+
118
+ <groups>
119
+ <searchEngine translate="label">
120
+ <label>Search engine</label>
121
+ <frontend_type>text</frontend_type>
122
+ <sort_order>2</sort_order>
123
+ <show_in_default>1</show_in_default>
124
+ <show_in_website>1</show_in_website>
125
+ <show_in_store>1</show_in_store>
126
+ <fields>
127
+ <engine translate="label">
128
+ <label>Search engine</label>
129
+ <comment>Select the search engine used by the platform. By default, we'll use Magento's integrated search.</comment>
130
+ <frontend_type>select</frontend_type>
131
+ <source_model>oct8ne/searchEngines</source_model>
132
+ <sort_order>10</sort_order>
133
+ <show_in_default>1</show_in_default>
134
+ <show_in_website>1</show_in_website>
135
+ <show_in_store>1</show_in_store>
136
+ </engine>
137
+ <params translate="label">
138
+ <label>Search Engine Parameters</label>
139
+ <comment>Enter the search engine configuration parameters. Example: "setting1=value1;setting2=value2"</comment>
140
+ <frontend_type>text</frontend_type>
141
+ <sort_order>20</sort_order>
142
+ <show_in_default>1</show_in_default>
143
+ <show_in_website>1</show_in_website>
144
+ <show_in_store>1</show_in_store>
145
+ </params>
146
+ </fields>
147
+ </searchEngine>
148
+ </groups>
149
+ </oct8neSearch>
150
  </sections>
151
  </config>
app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-install-2.1.0.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+
6
+
7
+ // *******************************************
8
+ // Create and populate table letssyncro
9
+ // *******************************************
10
+
11
+ $installer->run("
12
+ DROP TABLE IF EXISTS {$this->getTable('letssyncro')};
13
+ CREATE TABLE {$this->getTable('letssyncro')} (
14
+ `letssyncro_id` int(5) NOT NULL auto_increment,
15
+ `email` varchar(100) NULL,
16
+ `password` varchar(100) NULL,
17
+ `urlapi` varchar(100) NOT NULL,
18
+ `licenseid` varchar(32) NULL,
19
+ `apitoken` varchar(32) NULL,
20
+ `enabled` varchar(1) NULL,
21
+ PRIMARY KEY (`letssyncro_id`)
22
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
23
+ ");
24
+
25
+ try {
26
+
27
+ $linkupUrl = Mage::helper('oct8ne/url')->getOct8neLinkupServiceUrl();
28
+ $installer->run("
29
+ INSERT INTO {$this->getTable('letssyncro')}
30
+ (`letssyncro_id`, `email`, `password`, `urlapi`, `licenseid`, `apitoken`, `enabled`) VALUES
31
+ (1, '', '', '{$linkupUrl}', '', '', '0');
32
+ ");
33
+ } catch (\Exception $e) {
34
+ // the insert may fail if we run it more than once (duplicate key)
35
+ // we need this check to prevent errors during the rename of the module
36
+ }
37
+
38
+ // ***************
39
+ // Drop old tables
40
+ // ***************
41
+ $installer->run("
42
+ DROP TABLE IF EXISTS {$this->getTable('orderproducts')}
43
+ ");
44
+
45
+ $installer->run("
46
+ DROP TABLE IF EXISTS {$this->getTable('quoteproducts')}
47
+ ");
48
+
49
+ // *******************************************
50
+ // Create table for orders and quotes
51
+ // *******************************************
52
+
53
+ $ordersTable = $this->getTable('letssyncro_orders');
54
+ $installer->run("
55
+ CREATE TABLE IF NOT EXISTS {$ordersTable} (
56
+ `quote_id` int(11) unsigned NOT NULL,
57
+ `order_id` int(11) unsigned,
58
+ `store_id` int(11) unsigned NOT NULL,
59
+ `customer_id` int(11) unsigned,
60
+ `session_id` varchar(32) NOT NULL,
61
+ `price` decimal(12,2) NOT NULL,
62
+ `final_price` decimal (12,2) NOT NULL,
63
+ `currency` varchar(3) NOT NULL default 'USD',
64
+ `products_count` int(11) unsigned NOT NULL,
65
+ `items_count` int(11) unsigned NOT NULL,
66
+ `last_action` varchar(1) NOT NULL,
67
+ `utc_created` datetime NOT NULL default '0000-00-00 00:00:00',
68
+ `utc_last_modified` datetime NOT NULL default '0000-00-00 00:00:00',
69
+ PRIMARY KEY (`quote_id`),
70
+ INDEX `{$ordersTable}_modified`(`utc_last_modified`)
71
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
72
+ );
73
+
74
+ $installer->endSetup();
app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-1-2.1.0.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+
6
+ // ***************
7
+ // Drop old tables
8
+ // ***************
9
+ $installer->run("
10
+ DROP TABLE IF EXISTS {$this->getTable('orderproducts')}
11
+ ");
12
+
13
+ $installer->run("
14
+ DROP TABLE IF EXISTS {$this->getTable('quoteproducts')}
15
+ ");
16
+
17
+ // *******************************************
18
+ // Create tables for orders and quotes
19
+ // *******************************************
20
+
21
+ $ordersTable = $this->getTable('letssyncro_orders');
22
+ $installer->run("
23
+
24
+ CREATE TABLE IF NOT EXISTS {$ordersTable} (
25
+ `order_id` int(11) unsigned NOT NULL,
26
+ `session_id` varchar(32) NOT NULL,
27
+ `quote_id` int(11) unsigned NOT NULL,
28
+ `store_id` int(11) unsigned NOT NULL,
29
+ `price` decimal(12,2) NOT NULL,
30
+ `final_price` decimal (12,2) NOT NULL,
31
+ `currency` varchar(3) NOT NULL default 'USD',
32
+ `products_count` int(11) unsigned NOT NULL,
33
+ `items_count` int(11) unsigned NOT NULL,
34
+ `utc_created` datetime NOT NULL default '0000-00-00 00:00:00',
35
+ PRIMARY KEY (`order_id`),
36
+ INDEX `{$ordersTable}_creation`(`utc_created`)
37
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
38
+ );
39
+
40
+ $quoteTable = $this->getTable('letssyncro_quotes');
41
+ $installer->run("
42
+ CREATE TABLE IF NOT EXISTS {$quoteTable} (
43
+ `quote_id` int(11) unsigned NOT NULL,
44
+ `session_id` varchar(32) NOT NULL,
45
+ `store_id` int(11) unsigned NOT NULL,
46
+ `price` decimal(12,2) NOT NULL,
47
+ `currency` varchar(3) NOT NULL default 'USD',
48
+ `products_count` int(11) unsigned NOT NULL,
49
+ `items_count` int(11) unsigned NOT NULL,
50
+ `utc_created` datetime NOT NULL default '0000-00-00 00:00:00',
51
+ `utc_last_modified` datetime NOT NULL default '0000-00-00 00:00:00',
52
+ PRIMARY KEY (`quote_id`),
53
+ INDEX `{$quoteTable}_modified`(`utc_last_modified`)
54
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
55
+ ");
56
+
57
+
58
+
59
+ $installer->endSetup();
app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-1.1.6-1.1.7.php CHANGED
@@ -1,9 +1,9 @@
1
  <?php
2
-
3
  $installer = $this;
4
-
5
  $installer->startSetup();
6
-
7
  $installer->run("
8
  ALTER TABLE {$this->getTable('orderproducts')}
9
  ADD `qty` int(11) unsigned NOT NULL,
@@ -34,4 +34,4 @@ CREATE TABLE IF NOT EXISTS {$this->getTable('quoteproducts')} (
34
 
35
  ");
36
 
37
- $installer->endSetup();
1
  <?php
2
+
3
  $installer = $this;
4
+
5
  $installer->startSetup();
6
+
7
  $installer->run("
8
  ALTER TABLE {$this->getTable('orderproducts')}
9
  ADD `qty` int(11) unsigned NOT NULL,
34
 
35
  ");
36
 
37
+ $installer->endSetup();
app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-1.1.7-2.0.0.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+
6
+ // Nothing to do: v2.0 doesn't need to change the database
7
+
8
+ $installer->endSetup();
app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-2.0.0-2.0.3.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+
6
+ // Nothing to do
7
+
8
+ $installer->endSetup();
app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-2.0.0.php DELETED
@@ -1,6 +0,0 @@
1
- <?php
2
-
3
- $installer = $this;
4
- $installer->startSetup();
5
-
6
- // Nothing to do: v2.0 doesn't need to change the database
 
 
 
 
 
 
app/code/community/LetsSyncroLLC/Oct8ne/sql/oct8ne_setup/mysql4-upgrade-2.0.3-2.1.0.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+
6
+ // ***************
7
+ // Drop old tables
8
+ // ***************
9
+ //$installer->run("
10
+ // DROP TABLE IF EXISTS {$this->getTable('orderproducts')}
11
+ //");
12
+ //
13
+ //$installer->run("
14
+ // DROP TABLE IF EXISTS {$this->getTable('quoteproducts')}
15
+ //");
16
+
17
+ // *******************************************
18
+ // Create table for orders and quotes
19
+ // *******************************************
20
+
21
+ $ordersTable = $this->getTable('letssyncro_orders');
22
+ $installer->run("
23
+ CREATE TABLE IF NOT EXISTS {$ordersTable} (
24
+ `quote_id` int(11) unsigned NOT NULL,
25
+ `order_id` int(11) unsigned,
26
+ `store_id` int(11) unsigned NOT NULL,
27
+ `customer_id` int(11) unsigned,
28
+ `session_id` varchar(32) NOT NULL,
29
+ `price` decimal(12,2) NOT NULL,
30
+ `final_price` decimal (12,2) NOT NULL,
31
+ `currency` varchar(3) NOT NULL default 'USD',
32
+ `products_count` int(11) unsigned NOT NULL,
33
+ `items_count` int(11) unsigned NOT NULL,
34
+ `last_action` varchar(1) NOT NULL,
35
+ `utc_created` datetime NOT NULL default '0000-00-00 00:00:00',
36
+ `utc_last_modified` datetime NOT NULL default '0000-00-00 00:00:00',
37
+ PRIMARY KEY (`quote_id`),
38
+ INDEX `{$ordersTable}_modified`(`utc_last_modified`)
39
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"
40
+ );
41
+
42
+ $installer->endSetup();
app/design/frontend/base/default/template/oct8ne/letssyncro.phtml CHANGED
@@ -21,9 +21,10 @@ if (is_null(Mage::registry('oct8ne')) && !$disable) {
21
  $loginurl = Mage::helper('customer')->getLoginUrl();
22
  $currency = Mage::app()->getStore()->getCurrentCurrencyCode();
23
  $store = Mage::app()->getStore()->getId();
24
- $elementselector = Mage::getStoreConfig('design/oct8nedesign/elementselector') ? Mage::getStoreConfig('design/oct8nedesign/elementselector') : false;
 
25
 
26
- //en el cas de la cerca
27
  $currentProduct = "";
28
  $request = Mage::app()->getRequest();
29
  if (($request->getModuleName() == "catalog" && ($request->getActionName() == "view" && $request->getControllerName() == "product"))) {
21
  $loginurl = Mage::helper('customer')->getLoginUrl();
22
  $currency = Mage::app()->getStore()->getCurrentCurrencyCode();
23
  $store = Mage::app()->getStore()->getId();
24
+
25
+ $elementselector = Mage::getStoreConfig('oct8neSearch/assistedSearch/elementSelector');
26
 
27
+ //en el cas de la cerca
28
  $currentProduct = "";
29
  $request = Mage::app()->getRequest();
30
  if (($request->getModuleName() == "catalog" && ($request->getActionName() == "view" && $request->getControllerName() == "product"))) {
app/etc/modules/LetsSyncroLLC_Oct8ne.xml CHANGED
@@ -4,7 +4,7 @@
4
  <LetsSyncroLLC_Oct8ne>
5
  <active>true</active>
6
  <codePool>community</codePool>
7
- <version>2.0.3</version>
8
  <depends>
9
  <Mage_Eav/>
10
  <Mage_Dataflow/>
4
  <LetsSyncroLLC_Oct8ne>
5
  <active>true</active>
6
  <codePool>community</codePool>
7
+ <version>2.1.0</version>
8
  <depends>
9
  <Mage_Eav/>
10
  <Mage_Dataflow/>
package.xml CHANGED
@@ -1,18 +1,28 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LetsSyncroLLC_Oct8ne</name>
4
- <version>2.0.3</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/gpl-license.php">GPL</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Oct8ne extension</summary>
10
  <description>Agent-assisted search, proprietary co-viewing technology, &amp; live chat to engage in personal selling &amp; service.</description>
11
- <notes>Minor bugs fixed</notes>
 
 
 
 
 
 
 
 
 
 
12
  <authors><author><name>Oct8ne</name><user>Oct8ne</user><email>xavier.gonzalez@oct8ne.com</email></author></authors>
13
- <date>2015-05-13</date>
14
- <time>14:16:04</time>
15
- <contents><target name="magecommunity"><dir name="LetsSyncroLLC"><dir name="Oct8ne"><dir name="Block"><file name="Accountconfig.php" hash="436dc6ed540632eb4b0f6917bbd62cbe"/><dir name="Customer"><file name="Notifier.php" hash="58785a446c6c6a69db0348b81852028b"/></dir><dir name="Html"><file name="Head.php" hash="7fec049acbd3391ce0176982eede105b"/></dir><file name="Index.php" hash="d4cc07e7e6412cb9f3cedf2508f56461"/><dir name="Mage"><dir name="Product"><file name="View.php" hash="ca15ba7c5cc756cc18af5c9c48fbe492"/></dir></dir></dir><dir name="Helper"><file name="CustomerData.php" hash="8a34a58756c97f3dd043abc8e8bc6a2c"/><file name="Data.php" hash="78689487b28dae699d3d0cc1ab783649"/><file name="Image.php" hash="a03be23a4397774c69557f2bcc44e863"/><file name="Search.php" hash="4a7207bbff2db493d3a6c0526fb53eb7"/><file name="Url.php" hash="c1ea68e020ccf7c3622028a3ca6fb4c7"/><file name="Version.php" hash="09b28379399279f137a16ffcc0fb5ce6"/><file name="Wishlist.php" hash="527bb806bf2c6ecea035a1bcdbe78270"/></dir><dir name="Model"><file name="Cron.php" hash="11fbdce80ef509a89cbc055960c627dd"/><file name="Letssyncro.php" hash="a7755ee759fa31f004207823314a907d"/><dir name="Mage"><file name="Onepage.php" hash="400ea1de621a7d2e6b0e04db55b60027"/><file name="Request.php" hash="feee181c817bc4a1ed8d662104ddb1af"/><file name="Rewrite.php" hash="5699a8b1707724c4ad01fd6998cf12d6"/><file name="Url.php" hash="82a05832eaea74fedfd2c5b081dc5cc6"/></dir><dir name="Mysql4"><dir name="LetsSyncro"><file name="Collection.php" hash="1820b31106065627aa81007f966de6b7"/></dir><file name="Letssyncro.php" hash="81b49a4f7770d408eacd230a41434cbf"/><dir name="Orderproducts"><file name="Collection.php" hash="06e0828b6dbb87a110fcda58ce04e90c"/></dir><file name="Orderproducts.php" hash="96bf9e4f859a44d7ecb44e6319a16e62"/><dir name="Quoteproducts"><file name="Collection.php" hash="1b3154c09f9b8b3f525937e18d63c5b5"/></dir><file name="Quoteproducts.php" hash="32e565482455445dbc9d0e5f9a4dfdad"/></dir><file name="Observer.php" hash="3b297d91a8f6509fa08031b348ead85c"/><file name="Orderproducts.php" hash="9edf0ab5159b046d0d33c2766087183f"/><file name="Quoteproducts.php" hash="3b6baf23d5ab4136c52fe24d470a3fd0"/></dir><dir name="controllers"><file name="AccountController.php" hash="c900a756947b61498e5edd2e39b1d0bf"/><file name="AdminController.php" hash="c5206f6bbbdc7d98d93e99d948aa241d"/><file name="FrameController.php" hash="930e002722e93e599076e570379acf96"/><file name="IndexController.php" hash="5a63469c2dead9b78a262fd580a3e43b"/></dir><dir name="etc"><file name="config.xml" hash="400dd4961ff84402f473390278130953"/><file name="system.xml" hash="8421c301f81fe34f9abea301dce209fb"/></dir><dir name="sql"><dir name="oct8ne_setup"><file name="mysql4-install-2.0.0.php" hash="7cd9ed6b373a104ec7a27b1b2f26b570"/><file name="mysql4-upgrade-1.0.0-1.1.0.php" hash="0944f9c420562fa8071b04eff2abdb15"/><file name="mysql4-upgrade-1.1.6-1.1.7.php" hash="bfdad124cbf44578af8b3aff95bb78bf"/><file name="mysql4-upgrade-2.0.0.php" hash="c54894921ab155a55058b4f94070e051"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="oct8ne"><dir name="layout"><file name="oct8ne.xml" hash="664f6b6c51799aba0fa905cbc80eb703"/></dir><dir name="template"><dir name="page"><file name="1column.phtml" hash="3fbf17f71254a75cbf3261eab5a727ab"/><file name="2columns-left.phtml" hash="3fbf17f71254a75cbf3261eab5a727ab"/><file name="2columns-right.phtml" hash="3fbf17f71254a75cbf3261eab5a727ab"/><file name="3columns.phtml" hash="3fbf17f71254a75cbf3261eab5a727ab"/></dir></dir></dir></dir><dir name="base"><dir name="default"><dir name="layout"><file name="oct8ne.xml" hash="4b6f167fdbaf25f864934c0e8ecdda51"/></dir><dir name="template"><dir name="oct8ne"><dir name="frame"><file name="clean-page.phtml" hash="86c6580270709b8adb8a624130704cb5"/><dir name="productview"><file name="additional.phtml" hash="d0f80a4f31b31154af12197301cbc524"/><file name="addto.phtml" hash="358f19e35ff76f853cfad50ad35329fc"/><file name="addtocart.phtml" hash="06ac8be9a7197e87e8c5972c27804cc9"/><file name="attributes.phtml" hash="def5531385ad60aac88274bd91f76f52"/><file name="description.phtml" hash="09674e0a56d36f27c93d3a52c3a880c4"/><file name="media.phtml" hash="b23c4e9ef29e00d2f592d822fec8e52c"/><file name="media.phtml.ORIGINAL" hash="071f4d92269b2cbfa1a14271afbf0dbe"/><dir name="options"><file name="js.phtml" hash="7d9917d908ca99033c3473ecc10d895d"/><dir name="type"><file name="date.phtml" hash="41a612891cda695e3023d15a460c4325"/><file name="default.phtml" hash="b6f6d8e715f2a1d59913f313654fc38a"/><file name="file.phtml" hash="5e336ccdfa66b78264e5a0e859600d74"/><file name="select.phtml" hash="162f029fc825b78676cce70633805e62"/><file name="text.phtml" hash="c2c2940fb278d952e0e0d5d232ba5ed9"/></dir><dir name="wrapper"><file name="bottom.phtml" hash="182b49972e67cc834b8e1094a3984f5b"/></dir><file name="wrapper.phtml" hash="b635f6abf10b920afb6000b462134db6"/></dir><file name="options.phtml" hash="60d92d70da66f28300788027aa6f3056"/><file name="price.phtml" hash="06e90ec3368d07d62c3895f706069f96"/><file name="price_clone.phtml" hash="fb1ca9b19f97b0498f529b96c5c0e372"/><file name="tierprices.phtml" hash="4ac50d3c9f54d11fa5041a361485da74"/><dir name="type"><file name="configurable.phtml" hash="b9a427816f9c8a3d0d7179e8d5382683"/><file name="default.phtml" hash="e7f000d4b7fbc62f4e155e429f976126"/><file name="grouped.phtml" hash="9ce42ac44794853963bf68e9f2e911b0"/><dir name="options"><file name="configurable.phtml" hash="2636b369c1ceacd1b131f77ade2c996f"/></dir><file name="simple.phtml" hash="b9a427816f9c8a3d0d7179e8d5382683"/><file name="virtual.phtml" hash="b9a427816f9c8a3d0d7179e8d5382683"/></dir></dir><file name="productview.phtml" hash="da287c78285ecb003bbee37491d3a2f2"/></dir><file name="letssyncro.phtml" hash="d5e92999805e58e11abf1b3b6d29d341"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="LetsSyncroLLC_Oct8ne.xml" hash="82fbed9c7a4de60cffb3aa6d9fd37374"/></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="LetsSyncroLLC_Oct8ne.csv" hash="686df4107da7e35e243b629c5ee57963"/></dir><dir name="es_ES"><file name="LetsSyncroLLC_Oct8ne.csv" hash="eb0b3ddaae1e2e52005e9ab23cb37163"/></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><file name="oct8ne.css" hash="4255fddac8c054bbe32621cdccf844b8"/></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="images"><file name="LetsSyncro_Logo.png" hash="2104af20cc380d0c745531e1dca2f97c"/></dir></dir></dir></dir></target></contents>
16
  <compatible/>
17
  <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LetsSyncroLLC_Oct8ne</name>
4
+ <version>2.1.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/gpl-license.php">GPL</license>
7
  <channel>community</channel>
8
  <extends/>
9
  <summary>Oct8ne extension</summary>
10
  <description>Agent-assisted search, proprietary co-viewing technology, &amp; live chat to engage in personal selling &amp; service.</description>
11
+ <notes>- New pluggable search system.&#xD;
12
+ - New pluggable image helpers to support specific scenarios.&#xD;
13
+ - New image fallback system.&#xD;
14
+ - New product description fallback system.&#xD;
15
+ - Debug &amp; instrumentation helpers.&#xD;
16
+ - Custom settings to support different scenarios.&#xD;
17
+ - New sales data gathering system.&#xD;
18
+ - API 2.1:&#xD;
19
+ o New getProductsSummary method&#xD;
20
+ o New simplified data structures&#xD;
21
+ o Automatic API tester (beta)</notes>
22
  <authors><author><name>Oct8ne</name><user>Oct8ne</user><email>xavier.gonzalez@oct8ne.com</email></author></authors>
23
+ <date>2015-07-14</date>
24
+ <time>09:48:36</time>
25
+ <contents><target name="magecommunity"><dir name="LetsSyncroLLC"><dir name="Oct8ne"><dir name="Block"><file name="Accountconfig.php" hash="6a1e95bd440f283ae9f19a01bc678cd9"/><dir name="Customer"><file name="Notifier.php" hash="58785a446c6c6a69db0348b81852028b"/></dir><dir name="Html"><file name="Head.php" hash="7fec049acbd3391ce0176982eede105b"/></dir><file name="Index.php" hash="d4cc07e7e6412cb9f3cedf2508f56461"/><dir name="Mage"><dir name="Product"><file name="View.php" hash="ca15ba7c5cc756cc18af5c9c48fbe492"/></dir></dir></dir><dir name="Helper"><file name="CustomerData.php" hash="38658993e66fee8d5e3170658fa71556"/><file name="Data.php" hash="4e7af56ca41c49ba61227c38a895cdd2"/><file name="Debug.php" hash="147f2d06848b4596a0409b471cf0769a"/><dir name="Image"><file name="Default.php" hash="9fe7a2f21d294e34bce79d86a2ad8732"/></dir><file name="Reports.php" hash="6df3362a381e507a69fbf27162174f1b"/><dir name="Search"><file name="Base.php" hash="58ed2efec43d92934fb039187be35271"/><file name="Magento.php" hash="0ae593bd70db8952c897682082594c10"/><file name="Sli.php" hash="604025dfbf1de98d4d471d5cc461ddf6"/></dir><file name="Url.php" hash="c1ea68e020ccf7c3622028a3ca6fb4c7"/><file name="Version.php" hash="392d8d155afefc4ee944feb13ff65715"/><file name="Wishlist.php" hash="2f0530713db912cb33ac2ce2e8e550f5"/></dir><dir name="Model"><file name="Cron.php" hash="11fbdce80ef509a89cbc055960c627dd"/><file name="Letssyncro.php" hash="a7755ee759fa31f004207823314a907d"/><dir name="Mage"><file name="Onepage.php" hash="400ea1de621a7d2e6b0e04db55b60027"/><file name="Request.php" hash="feee181c817bc4a1ed8d662104ddb1af"/><file name="Rewrite.php" hash="5699a8b1707724c4ad01fd6998cf12d6"/><file name="Url.php" hash="82a05832eaea74fedfd2c5b081dc5cc6"/></dir><dir name="Mysql4"><dir name="LetsSyncro"><file name="Collection.php" hash="1820b31106065627aa81007f966de6b7"/></dir><file name="Letssyncro.php" hash="81b49a4f7770d408eacd230a41434cbf"/><dir name="Order"><file name="Collection.php" hash="431a18fb0f8a2d29ea44a1b617b48382"/></dir><file name="Order.php" hash="1fd857af382915617c1d64d438a842ab"/></dir><file name="Observer.php" hash="bdfb77a7082ac8c27756b5bf7f4779df"/><file name="Order.php" hash="5ea076e3f76f9a28a5ab6eee1f157b69"/><file name="Orderproducts.php" hash="9edf0ab5159b046d0d33c2766087183f"/><file name="Quoteproducts.php" hash="3b6baf23d5ab4136c52fe24d470a3fd0"/><file name="SearchEngines.php" hash="1c65dab5b3dadcb78f145d9deb981e8b"/></dir><dir name="controllers"><file name="AccountController.php" hash="c900a756947b61498e5edd2e39b1d0bf"/><file name="AdminController.php" hash="c5206f6bbbdc7d98d93e99d948aa241d"/><file name="FrameController.php" hash="f68e735597645fcc66f8bd94a4ace43e"/><file name="IndexController.php" hash="5a63469c2dead9b78a262fd580a3e43b"/><file name="SetupController.php" hash="b91c72f12d124862349744861e5516d5"/></dir><dir name="etc"><file name="config.xml" hash="4eac2c38a9f03807cc25f2701c0d2904"/><file name="system.xml" hash="0dcbd9bb7e4d44a731eecd35d358ed06"/></dir><dir name="sql"><dir name="oct8ne_setup"><file name="mysql4-install-2.0.0.php" hash="7cd9ed6b373a104ec7a27b1b2f26b570"/><file name="mysql4-install-2.1.0.php" hash="0c268a08bbfc48a072fdfb75c7013a43"/><file name="mysql4-upgrade-1-2.1.0.php" hash="5883e47d9718350d49146e33ba8fbd84"/><file name="mysql4-upgrade-1.0.0-1.1.0.php" hash="0944f9c420562fa8071b04eff2abdb15"/><file name="mysql4-upgrade-1.1.6-1.1.7.php" hash="eecd1f66e51507306abf5e4fa5d70584"/><file name="mysql4-upgrade-1.1.7-2.0.0.php" hash="3c7e1655fb0b45dd5dc01aca98929679"/><file name="mysql4-upgrade-2.0.0-2.0.3.php" hash="0288d291dec83584d97052e62b64a738"/><file name="mysql4-upgrade-2.0.3-2.1.0.php" hash="4a06d9802360e45a08d417168c260f15"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="default"><dir name="oct8ne"><dir name="layout"><file name="oct8ne.xml" hash="664f6b6c51799aba0fa905cbc80eb703"/></dir><dir name="template"><dir name="page"><file name="1column.phtml" hash="3fbf17f71254a75cbf3261eab5a727ab"/><file name="2columns-left.phtml" hash="3fbf17f71254a75cbf3261eab5a727ab"/><file name="2columns-right.phtml" hash="3fbf17f71254a75cbf3261eab5a727ab"/><file name="3columns.phtml" hash="3fbf17f71254a75cbf3261eab5a727ab"/></dir></dir></dir></dir><dir name="base"><dir name="default"><dir name="layout"><file name="oct8ne.xml" hash="4b6f167fdbaf25f864934c0e8ecdda51"/></dir><dir name="template"><dir name="oct8ne"><dir name="frame"><file name="clean-page.phtml" hash="86c6580270709b8adb8a624130704cb5"/><dir name="productview"><file name="additional.phtml" hash="d0f80a4f31b31154af12197301cbc524"/><file name="addto.phtml" hash="358f19e35ff76f853cfad50ad35329fc"/><file name="addtocart.phtml" hash="06ac8be9a7197e87e8c5972c27804cc9"/><file name="attributes.phtml" hash="def5531385ad60aac88274bd91f76f52"/><file name="description.phtml" hash="09674e0a56d36f27c93d3a52c3a880c4"/><file name="media.phtml" hash="b23c4e9ef29e00d2f592d822fec8e52c"/><file name="media.phtml.ORIGINAL" hash="071f4d92269b2cbfa1a14271afbf0dbe"/><dir name="options"><file name="js.phtml" hash="7d9917d908ca99033c3473ecc10d895d"/><dir name="type"><file name="date.phtml" hash="41a612891cda695e3023d15a460c4325"/><file name="default.phtml" hash="b6f6d8e715f2a1d59913f313654fc38a"/><file name="file.phtml" hash="5e336ccdfa66b78264e5a0e859600d74"/><file name="select.phtml" hash="162f029fc825b78676cce70633805e62"/><file name="text.phtml" hash="c2c2940fb278d952e0e0d5d232ba5ed9"/></dir><dir name="wrapper"><file name="bottom.phtml" hash="182b49972e67cc834b8e1094a3984f5b"/></dir><file name="wrapper.phtml" hash="b635f6abf10b920afb6000b462134db6"/></dir><file name="options.phtml" hash="60d92d70da66f28300788027aa6f3056"/><file name="price.phtml" hash="06e90ec3368d07d62c3895f706069f96"/><file name="price_clone.phtml" hash="fb1ca9b19f97b0498f529b96c5c0e372"/><file name="tierprices.phtml" hash="4ac50d3c9f54d11fa5041a361485da74"/><dir name="type"><file name="configurable.phtml" hash="b9a427816f9c8a3d0d7179e8d5382683"/><file name="default.phtml" hash="e7f000d4b7fbc62f4e155e429f976126"/><file name="grouped.phtml" hash="9ce42ac44794853963bf68e9f2e911b0"/><dir name="options"><file name="configurable.phtml" hash="2636b369c1ceacd1b131f77ade2c996f"/></dir><file name="simple.phtml" hash="b9a427816f9c8a3d0d7179e8d5382683"/><file name="virtual.phtml" hash="b9a427816f9c8a3d0d7179e8d5382683"/></dir></dir><file name="productview.phtml" hash="da287c78285ecb003bbee37491d3a2f2"/></dir><file name="letssyncro.phtml" hash="eb7f45eaf7ec0f6518accc417ecf4df7"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="LetsSyncroLLC_Oct8ne.xml" hash="9d7e348d4a79c4d032e1617c7d3a9a37"/></dir></target><target name="magelocale"><dir><dir name="en_US"><file name="LetsSyncroLLC_Oct8ne.csv" hash="686df4107da7e35e243b629c5ee57963"/></dir><dir name="es_ES"><file name="LetsSyncroLLC_Oct8ne.csv" hash="eb0b3ddaae1e2e52005e9ab23cb37163"/></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><file name="oct8ne.css" hash="4255fddac8c054bbe32621cdccf844b8"/></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="images"><file name="LetsSyncro_Logo.png" hash="2104af20cc380d0c745531e1dca2f97c"/></dir></dir></dir></dir></target></contents>
26
  <compatible/>
27
  <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
28
  </package>