shoppingfeeder - Version 1.4.0

Version Notes

Version 1.4.0 brings optimisations and a very exciting update enabling "Facebook Audience Pixel Tracking".

ShoppingFeeder now help you list and manage your product listings on Facebook Dynamic Product Ads.

Download this release

Release Info

Developer ShoppingFeeder
Extension shoppingfeeder
Version 1.4.0
Comparing to
See all releases


Code changes from version 1.3.12 to 1.4.0

app/code/community/ShoppingFeeder/Service/Block/Adminhtml/Service.php CHANGED
@@ -16,19 +16,19 @@ class ShoppingFeeder_Service_Block_Adminhtml_Service extends
16
  $this->_controller = 'adminhtml_service';
17
  $this->_headerText = Mage::helper('shoppingfeeder_service')->__('Manage Service');
18
  parent::__construct();
19
- if (Mage::helper('shoppingfeeder_service/Admin')->isActionAllowed('save'))
20
- {
21
- $this->_updateButton('add', 'label',
22
- Mage::helper('shoppingfeeder_service')->__('Add New News'));
23
- } else {
24
- $this->_removeButton('add');
25
- }
26
- $this->addButton(
27
- 'news_flush_images_cache',
28
- array(
29
- 'label' => Mage::helper('shoppingfeeder_service')->__('Flush Images Cache'),
30
- 'onclick' => 'setLocation(\'' . $this->getUrl('*/*/flush') . '\')',
31
- )
32
- );
33
  }
34
  }
16
  $this->_controller = 'adminhtml_service';
17
  $this->_headerText = Mage::helper('shoppingfeeder_service')->__('Manage Service');
18
  parent::__construct();
19
+ // if (Mage::helper('shoppingfeeder_service/Admin')->isActionAllowed('save'))
20
+ // {
21
+ // $this->_updateButton('add', 'label',
22
+ // Mage::helper('shoppingfeeder_service')->__('Add New News'));
23
+ // } else {
24
+ // $this->_removeButton('add');
25
+ // }
26
+ // $this->addButton(
27
+ // 'news_flush_images_cache',
28
+ // array(
29
+ // 'label' => Mage::helper('shoppingfeeder_service')->__('Flush Images Cache'),
30
+ // 'onclick' => 'setLocation(\'' . $this->getUrl('*/*/flush') . '\')',
31
+ // )
32
+ // );
33
  }
34
  }
app/code/community/ShoppingFeeder/Service/Block/Tracking/Fb.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ *
4
+ * ShoppingFeeder XML generation code
5
+ *
6
+ * @category ShoppingFeeder
7
+ * @package ShoppingFeeder_Service
8
+ * @copyright Copyright (c) 2014 Kevin Tucker (http://www.shoppingfeeder.com)
9
+ *
10
+ */
11
+
12
+ class ShoppingFeeder_Service_Block_Tracking_Fb extends Mage_Core_Block_Template
13
+ {
14
+ protected function _toHtml() {
15
+ $trackFb = Mage::getStoreConfig('shoppingfeeder/fb_track_config/fb_track');
16
+
17
+ if (!$trackFb) {
18
+ return '';
19
+ }
20
+
21
+ return parent::_toHtml();
22
+ }
23
+
24
+ /**
25
+ * return the price of the product
26
+ *
27
+ * @return string
28
+ */
29
+ public function getProductPrice()
30
+ {
31
+ $price = $this->getData('product')->getPrice();
32
+ $specialPrice = $this->getData('product')->getSpecialPrice();
33
+
34
+ return number_format(((!is_null($specialPrice) && $specialPrice < $price) ? $specialPrice : $price), 2);
35
+ }
36
+
37
+ /**
38
+ * Return the current currency code
39
+ *
40
+ * @return string
41
+ */
42
+ public function getCurrency()
43
+ {
44
+ return Mage::app()->getStore()->getCurrentCurrencyCode();
45
+ }
46
+
47
+ /**
48
+ * Return the FB pixel ID
49
+ *
50
+ * @return string
51
+ */
52
+ public function getPixelId()
53
+ {
54
+ return Mage::getStoreConfig('shoppingfeeder/fb_track_config/fb_track_code');
55
+ }
56
+ }
app/code/community/ShoppingFeeder/Service/Model/Observer.php CHANGED
@@ -16,7 +16,19 @@ class ShoppingFeeder_Service_Model_Observer extends Varien_Object
16
  /* @var Mage_Sales_Model_Order $order */
17
  $order = $observer->getEvent()->getOrder();
18
 
19
- Mage::log('salesOrderPlaceAfter Order ID: '.$order->getRealOrderId());
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
  $this->_notifyShoppingFeeder($order);
22
  }
@@ -43,6 +55,154 @@ class ShoppingFeeder_Service_Model_Observer extends Varien_Object
43
  }
44
  }
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  protected function _notifyShoppingFeeder(Mage_Sales_Model_Order $order)
47
  {
48
  Mage::log('_notifyShoppingFeeder Order ID: '.$order->getRealOrderId());
16
  /* @var Mage_Sales_Model_Order $order */
17
  $order = $observer->getEvent()->getOrder();
18
 
19
+ //Mage::log('salesOrderPlaceAfter Order ID: '.$order->getRealOrderId());
20
+
21
+ //set the order for JS tracking code
22
+ $orderItems = array();
23
+ foreach ($order->getAllItems() as $item)
24
+ {
25
+ $orderItems[] = '\''.$item->getId().'\'';
26
+ }
27
+ $orderInfo = array(
28
+ 'items' => $orderItems,
29
+ 'value' => $order->getGrandTotal()
30
+ );
31
+ Mage::getModel('core/session')->setOrderForJsTracking($orderInfo);
32
 
33
  $this->_notifyShoppingFeeder($order);
34
  }
55
  }
56
  }
57
 
58
+ /**
59
+ * @param Varien_Event_Observer $observer
60
+ */
61
+ public function generateBlocksAfter($observer)
62
+ {
63
+ try{
64
+ $actionName = $observer->getEvent()->getAction()->getFullActionName();
65
+ // var_dump($actionName);
66
+ // exit();
67
+ $block = Mage::app()->getFrontController()->getAction()->getLayout()->getBlock('shoppingfeeder_service_tracking_fb');
68
+
69
+ if ($actionName == 'catalog_product_view' || $actionName == 'checkout_cart_index')
70
+ {
71
+ $product = Mage::registry('current_product');
72
+ if (is_null($product))
73
+ {
74
+ $product = Mage::getModel('core/session')->getProductToShoppingCart();
75
+ }
76
+
77
+ //if we still don't have a product, don't do anything
78
+ if (is_null($product))
79
+ {
80
+ return;
81
+ }
82
+
83
+ $category = Mage::registry('current_category');
84
+ $currentCategoryPath = null;
85
+ if (!is_null($category))
86
+ {
87
+ $currentCategoryPath = $category->getPath();
88
+ }
89
+
90
+ $startTime = microtime(true);
91
+
92
+ $storeRootCategoryId = Mage::app()->getStore()->getRootCategoryId();
93
+ $storeRootCategoryName = Mage::getModel('catalog/category')->load($storeRootCategoryId)->getName();
94
+ if (is_null($currentCategoryPath))
95
+ {
96
+ /** @var Mage_Catalog_Model_Resource_Category_Collection $categoryCollection */
97
+ $categoryCollection = $product->getCategoryCollection()->addAttributeToSelect('name');
98
+
99
+ $depth = 0;
100
+ foreach($categoryCollection as $cat1){
101
+ $pathIds = explode('/', $cat1->getPath());
102
+ unset($pathIds[0]);
103
+
104
+ $collection = Mage::getModel('catalog/category')->getCollection()
105
+ ->setStoreId(Mage::app()->getStore()->getId())
106
+ ->addAttributeToSelect('name')
107
+ ->addAttributeToSelect('is_active')
108
+ ->addFieldToFilter('entity_id', array('in' => $pathIds));
109
+
110
+ $pathByName = array();
111
+ /** @var Mage_Catalog_Model_Category $cat */
112
+ foreach($collection as $cat){
113
+ if ($cat->getName() != $storeRootCategoryName)
114
+ {
115
+ $pathByName[] = $cat->getName();
116
+ }
117
+ }
118
+
119
+ //take the longest (generally more detailed) path
120
+ $thisDepth = count($pathByName);
121
+ if ($thisDepth > $depth)
122
+ {
123
+ $depth = $thisDepth;
124
+ $pathToUse = implode(' > ', $pathByName);
125
+ }
126
+ }
127
+ }
128
+ else
129
+ {
130
+ $pathIds = explode('/', $currentCategoryPath);
131
+ unset($pathIds[0]);
132
+
133
+ $collection = Mage::getModel('catalog/category')->getCollection()
134
+ ->setStoreId(Mage::app()->getStore()->getId())
135
+ ->addAttributeToSelect('name')
136
+ ->addAttributeToSelect('is_active')
137
+ ->addFieldToFilter('entity_id', array('in' => $pathIds));
138
+
139
+ $pathByName = array();
140
+ /** @var Mage_Catalog_Model_Category $cat */
141
+ foreach($collection as $cat){
142
+ if ($cat->getName() != $storeRootCategoryName)
143
+ {
144
+ $pathByName[] = $cat->getName();
145
+ }
146
+ }
147
+ $pathToUse = implode(' > ', $pathByName);
148
+ }
149
+
150
+ if ($product)
151
+ {
152
+ $block->setData('product', $product);
153
+ $block->setData('category', $pathToUse);
154
+
155
+ if ($actionName == 'catalog_product_view')
156
+ {
157
+ $block->setData('action_type', 'ViewContent');
158
+ }
159
+ elseif ($actionName == 'checkout_cart_index')
160
+ {
161
+ $block->setData('action_type', 'AddToCart');
162
+ //reset the cart product
163
+ Mage::getModel('core/session')->setProductToShoppingCart(null);
164
+ }
165
+ }
166
+ }
167
+
168
+
169
+ elseif ($actionName == 'checkout_onepage_success' || $actionName == 'checkout_multishipping_success')
170
+ {
171
+ Mage::log('After template action: '.$actionName);
172
+ $orderInfo = Mage::getModel('core/session')->getOrderForJsTracking();
173
+ if (!is_null($orderInfo) && $block)
174
+ {
175
+ $block->setData('order', $orderInfo);
176
+ $block->setData('action_type', 'Purchase');
177
+ Mage::getModel('core/session')->setOrderForJsTracking(null);
178
+ }
179
+ }
180
+ }
181
+ catch (Exception $e)
182
+ {
183
+
184
+ }
185
+ }
186
+
187
+ /**
188
+ * @param Varien_Event_Observer $observer
189
+ */
190
+ public function setAddToCartProduct($observer)
191
+ {
192
+ try{
193
+
194
+ //add the cart product to the session
195
+ $product = Mage::getModel('catalog/product')
196
+ ->load(Mage::app()->getRequest()->getParam('product', 0));
197
+
198
+ Mage::getModel('core/session')->setProductToShoppingCart($product);
199
+ }
200
+ catch (Exception $e)
201
+ {
202
+
203
+ }
204
+ }
205
+
206
  protected function _notifyShoppingFeeder(Mage_Sales_Model_Order $order)
207
  {
208
  Mage::log('_notifyShoppingFeeder Order ID: '.$order->getRealOrderId());
app/code/community/ShoppingFeeder/Service/Model/Offers.php CHANGED
@@ -1,443 +1,443 @@
1
- <?php
2
-
3
- class ShoppingFeeder_Service_Model_Offers extends Mage_Core_Model_Abstract
4
- {
5
- public function __construct()
6
- {
7
- $this->_init('shoppingfeeder_service/offers');
8
- }
9
-
10
- private function hasParent($product)
11
- {
12
- $parents = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
13
- return !empty($parents);
14
- }
15
-
16
- private function getProductInfo(Mage_Catalog_Model_Product $product, Mage_Catalog_Model_Product $parent = null, $variantOptions = null, $lastUpdate = null, $priceCurrency, $priceCurrencyRate)
17
- {
18
- /** @var Mage_Catalog_Model_Product_Type_Configurable $configModel */
19
- $configModel = Mage::getModel('catalog/product_type_configurable');
20
-
21
- $p = array();
22
-
23
- $isVariant = !is_null($parent);
24
-
25
- /**
26
- * We only want to pull variants (children of configurable products) that are children, not as standalone products
27
- */
28
- //if this product's parent is visible in catalog and search, Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
29
- //we will find this product when we fetch all the children of this parent through a normal iteration, so return nothing
30
- if (!$isVariant && $this->hasParent($product))
31
- {
32
- return array();
33
- }
34
-
35
- if ($isVariant)
36
- {
37
- $variant = $product;
38
- $product = $parent;
39
- }
40
-
41
- $data = $product->getData();
42
-
43
- /* @var Mage_CatalogInventory_Model_Stock_Item $stockItem */
44
- $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
45
-
46
- $attributes = $product->getAttributes();
47
- $manufacturer = '';
48
- $brand = '';
49
-
50
- $usefulAttributes = array();
51
-
52
- /**
53
- * @var Mage_Eav_Model_Entity_Attribute_Abstract $attribute
54
- */
55
- // var_dump("");
56
- // var_dump("");
57
- // var_dump("");
58
- foreach ($attributes as $attribute)
59
- {
60
- $attributeCode = $attribute->getAttributeCode();
61
- $attributeLabel = $attribute->getData('frontend_label');
62
- $value = $attribute->getFrontend()->getValue($product);
63
-
64
- // var_dump($attributeCode. ' : '.print_r($value, true));
65
- // var_dump($attributeLabel. ' : '.print_r($value, true));
66
-
67
- if (preg_match('/^manufacturer$/i', $attributeCode) || preg_match('/^manufacturer$/i', $attributeLabel))
68
- {
69
- $manufacturer = $value;
70
- }
71
-
72
- if (preg_match('/^brand$/i', $attributeCode) || preg_match('/^brand$/i', $attributeLabel))
73
- {
74
- $brand = $value;
75
- }
76
-
77
- /*
78
- if (preg_match('/age/i', $attributeCode) || preg_match('/age/i', $attributeLabel))
79
- {
80
- $usefulAttributes['age'] = $value;
81
- }
82
- if (preg_match('/color|colour/i', $attributeCode) || preg_match('/color|colour/i', $attributeLabel))
83
- {
84
- $usefulAttributes['colour'] = $value;
85
- }
86
- if (preg_match('/size/i', $attributeCode) || preg_match('/size/i', $attributeLabel))
87
- {
88
- $usefulAttributes['size'] = $value;
89
- }
90
- if (preg_match('/gender|sex/i', $attributeCode) || preg_match('/gender|sex/i', $attributeLabel))
91
- {
92
- $usefulAttributes['gender'] = $value;
93
- }
94
- if (preg_match('/material/i', $attributeCode) || preg_match('/material/i', $attributeLabel))
95
- {
96
- $usefulAttributes['material'] = $value;
97
- }
98
- if (preg_match('/pattern/i', $attributeCode) || preg_match('/pattern/i', $attributeLabel))
99
- {
100
- $usefulAttributes['pattern'] = $value;
101
- }
102
- */
103
- if (!is_null($product->getData($attributeCode)) && ((string)$attribute->getFrontend()->getValue($product) != ''))
104
- {
105
- $usefulAttributes[$attributeCode] = $value;
106
- }
107
- }
108
- // exit();
109
-
110
- //category path
111
- $categories = $product->getCategoryIds();
112
-
113
- $categoryPathsToEvaluate = array();
114
- $maxDepth = 0;
115
- $categoryPathToUse = '';
116
-
117
- $storeRootCategoryId = Mage::app()->getStore()->getRootCategoryId();
118
- $storeRootCategoryName = Mage::getModel('catalog/category')->load($storeRootCategoryId)->getName();
119
-
120
- if (!empty($categories))
121
- {
122
- /** @var Mage_Catalog_Model_Resource_Category_Collection $categoryCollection */
123
- $categoryCollection = $product->getCategoryCollection()->addAttributeToSelect('name');
124
-
125
- $depth = 0;
126
- foreach($categoryCollection as $cat1){
127
- $pathIds = explode('/', $cat1->getPath());
128
- unset($pathIds[0]);
129
-
130
- $collection = Mage::getModel('catalog/category')->getCollection()
131
- ->setStoreId(Mage::app()->getStore()->getId())
132
- ->addAttributeToSelect('name')
133
- ->addAttributeToSelect('is_active')
134
- ->addFieldToFilter('entity_id', array('in' => $pathIds));
135
-
136
- $pathByName = array();
137
- /** @var Mage_Catalog_Model_Category $cat */
138
- foreach($collection as $cat){
139
- if ($cat->getName() != $storeRootCategoryName)
140
- {
141
- $pathByName[] = $cat->getName();
142
- }
143
- }
144
-
145
- //take the longest (generally more detailed) path
146
- $thisDepth = count($pathByName);
147
- if ($thisDepth > $depth)
148
- {
149
- $depth = $thisDepth;
150
- $categoryPathToUse = implode(' > ', $pathByName);
151
- }
152
- }
153
-
154
- // //we will get all the category paths and then use the most refined, deepest one
155
- // foreach ($categories as $rootCategoryId)
156
- // {
157
- // $depth = 0;
158
- // $category_path = '';
159
- //
160
- // $mageCategoryPath = Mage::getModel('catalog/category')->load($rootCategoryId)->getPath();
161
- // $allCategoryIds = explode('/', $mageCategoryPath);
162
- // unset($allCategoryIds[0]);
163
- //
164
- // $categoryPath = '';
165
- // /**
166
- // * @var Mage_Catalog_Model_Category $category
167
- // */
168
- // foreach ($allCategoryIds as $categoryId)
169
- // {
170
- // $depth++;
171
- // $category = Mage::getModel('catalog/category')->load($categoryId);
172
- // $category_name = $category->getName();
173
- // if ($category_name != $storeRootCategoryName)
174
- // {
175
- // if (!empty($categoryPath))
176
- // {
177
- // $categoryPath.= ' > ';
178
- // }
179
- // $categoryPath.= $category_name;
180
- // }
181
- // }
182
- //
183
- // $categoryPathsToEvaluate[$rootCategoryId]['path'] = $categoryPath;
184
- // $categoryPathsToEvaluate[$rootCategoryId]['depth'] = $depth;
185
- //
186
- // if ($maxDepth < $depth)
187
- // {
188
- // $maxDepth = $depth;
189
- // $categoryPathToUse = $categoryPath;
190
- // }
191
- // }
192
- }
193
-
194
- if ($isVariant && isset($variant))
195
- {
196
- $p['internal_variant_id'] = $variant->getId();
197
-
198
- $variantOptionsTitle = array();
199
- $variantPrice = $variantOptions['basePrice'];
200
-
201
- $urlHashParts = array();
202
-
203
- // Collect options applicable to the configurable product
204
- if (isset($variantOptions['refactoredOptions'][$variant->getId()]))
205
- {
206
- foreach ($variantOptions['refactoredOptions'][$variant->getId()] as $attributeCode => $option) {
207
- $variantOptionsTitle[] = $option['value'];
208
-
209
- //add these configured attributes to the set of parent's attributes
210
- $usefulAttributes[$attributeCode] = $option['value'];
211
-
212
- $variantPrice += $option['price'];
213
-
214
- $urlHashParts[] = $option['attributeId'].'='.$option['valueId'];
215
- }
216
- }
217
-
218
- $variantOptionsTitle = implode(' / ', $variantOptionsTitle);
219
- $title = $data['name'] . ' - ' . $variantOptionsTitle;
220
- $sku = $variant->getData('sku');
221
- $price = $variantPrice;
222
- $variantImage = $variant->getImage();
223
-
224
- if (!is_null($variantImage) && !empty($variantImage) && $variantImage!='no_selection')
225
- {
226
- $imageFile = $variant->getImage();
227
- // $imageUrl = $p['image_url'] = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).
228
- // 'catalog/product/'.preg_replace('/^\//', '', $imageFile);
229
- $imageUrl = $p['image_url'] = $variant->getMediaConfig()->getMediaUrl($imageFile);
230
- $imageLocalPath = $variant->getMediaConfig()->getMediaPath($imageFile);
231
- }
232
- else
233
- {
234
- $imageFile = $product->getImage();
235
- // $imageUrl = $p['image_url'] = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).
236
- // 'catalog/product/'.preg_replace('/^\//', '', $imageFile);
237
- $imageUrl = $p['image_url'] = $product->getMediaConfig()->getMediaUrl($imageFile);
238
- $imageLocalPath = $product->getMediaConfig()->getMediaPath($imageFile);
239
- }
240
- $productUrl = $product->getProductUrl().'#'.implode('&', $urlHashParts);
241
- }
242
- else
243
- {
244
- $p['internal_variant_id'] = '';
245
- $title = $data['name'];
246
- $sku = $data['sku'];
247
- $price = $product->getPrice();
248
- $imageFile = $product->getImage();
249
- // $imageUrl = $p['image_url'] = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).
250
- // 'catalog/product/'.preg_replace('/^\//', '', $imageFile);
251
- $imageUrl = $p['image_url'] = $product->getMediaConfig()->getMediaUrl($imageFile);
252
- $imageLocalPath = $product->getMediaConfig()->getMediaPath($imageFile);
253
- $productUrl = $product->getProductUrl();
254
- }
255
-
256
- //if we have previously captured this product and it hasn't changed, don't send through full payload
257
- $wasPreviouslyCaptured = !is_null($lastUpdate) && isset($usefulAttributes['updated_at']) && strtotime($usefulAttributes['updated_at']) < $lastUpdate;
258
- if ($wasPreviouslyCaptured)
259
- {
260
- $p['internal_id'] = $product->getId();
261
- $p['internal_update_time'] = date("c", strtotime($usefulAttributes['updated_at']));
262
- }
263
- else
264
- {
265
- $p['category'] = $categoryPathToUse;
266
- $p['title'] = $title;
267
- $p['brand'] = ($brand=='No') ? (($manufacturer == 'No') ? '' : $manufacturer) : $brand;
268
- $p['manufacturer'] = ($manufacturer=='No') ? $brand : $manufacturer;
269
- $p['mpn'] = isset($data['model']) ? $data['model'] : $data['sku'];
270
- $p['internal_id'] = $product->getId();
271
- $p['description'] = $data['description'];
272
- $p['short_description'] = $data['short_description'];
273
- $p['weight'] = isset($data['weight']) ? $data['weight'] : 0.00;
274
- $p['sku'] = $sku;
275
- $p['gtin'] = '';
276
-
277
- //$priceModel = $product->getPriceModel();
278
-
279
- //do a currency conversion. if the currency is in base currency, it will be 1.0
280
- $price = $price * $priceCurrencyRate;
281
- $salePrice = $product->getSpecialPrice() * $priceCurrencyRate;
282
-
283
- $p['currency'] = $priceCurrency;
284
- $p['price'] = $price;// Mage::helper('checkout')->convertPrice($priceModel->getPrice($product), false);
285
- $p['sale_price'] = '';
286
- $p['sale_price_effective_date'] = '';
287
- if ($salePrice != $p['price'])
288
- {
289
- $p['sale_price'] = $salePrice;
290
- if ($product->getSpecialFromDate()!=null && $product->getSpecialToDate()!=null)
291
- {
292
- $p['sale_price_effective_date'] = date("c", strtotime(date("Y-m-d 23:59:59", strtotime($product->getSpecialFromDate())))).'/'.date("c", strtotime(date("Y-m-d 23:59:59", strtotime($product->getSpecialToDate()))));
293
- }
294
- }
295
-
296
- $p['delivery_cost'] = 0.00;
297
- $p['tax'] = 0.00;
298
- $p['url'] = $productUrl;
299
- $p['internal_update_time'] = isset($usefulAttributes['updated_at']) ? date("c", strtotime($usefulAttributes['updated_at'])) : '';
300
-
301
- $p['image_url'] = $imageUrl;
302
- if (file_exists($imageLocalPath))
303
- {
304
- $p['image_modified_time'] = date("c", filemtime($imageLocalPath));
305
- }
306
- $p['availability'] = ($stockItem->getIsInStock())?'in stock':'out of stock';
307
- $p['quantity'] = $stockItem->getQty();
308
- $p['condition'] = '';
309
- $p['availability_date'] = '';
310
- $p['attributes'] = $usefulAttributes;
311
- $imageGallery = array();
312
- foreach ($product->getMediaGalleryImages() as $image)
313
- {
314
- $galleryImage = array();
315
- $galleryImage['url'] = $image['url'];
316
- if (file_exists($image['path']))
317
- {
318
- $galleryImage['image_modified_time'] = date("c", filemtime($image['path']));
319
- }
320
- $imageGallery[] = $galleryImage;
321
- }
322
- $p['extra_images'] = $imageGallery;
323
- }
324
-
325
- return $p;
326
- }
327
-
328
- public function getItems($page = null, $numPerPage = 1000, $lastUpdate = null, $store = null, $priceCurrency = null, $priceCurrencyRate = null, $allowVariants = true)
329
- {
330
- /* @var Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection $collection */
331
- $collection = Mage::getModel('catalog/product')->getCollection()
332
- ->addAttributeToSelect('*')
333
- ->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
334
- ->addAttributeToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH);
335
-
336
- /**
337
- * For per-store system
338
- */
339
- if (!is_null($store))
340
- {
341
- $collection->addStoreFilter(Mage::app()->getStore($store)->getId());
342
- }
343
-
344
- if (!is_null($page))
345
- {
346
- $offset = ($page * $numPerPage) - $numPerPage;
347
- $productIds = $collection->getAllIds($numPerPage, $offset);
348
- }
349
- else
350
- {
351
- $productIds = $collection->getAllIds();
352
- }
353
-
354
- $products = array();
355
- foreach ($productIds as $productId)
356
- {
357
- Mage::getModel('catalog/product')->reset();
358
- /** @var Mage_Catalog_Model_Product $product */
359
- $product = Mage::getModel('catalog/product')->load($productId);
360
-
361
- /**
362
- * Get variants, if there are any
363
- * If there are variants that are visible in the catalog, we will skip them when we iterate normally
364
- */
365
-
366
- //if we have a configurable product, capture the variants
367
- if ($product->getTypeId() == 'configurable' && $allowVariants)
368
- {
369
- /** @var Mage_Catalog_Model_Product_Type_Configurable $configModel */
370
- $configModel = Mage::getModel('catalog/product_type_configurable');
371
-
372
- //$children = $configModel->getChildrenIds($product->getId());
373
- $children = $configModel->getUsedProducts(null,$product);
374
-
375
- if (count($children) > 0)
376
- {
377
- $parent = $product;
378
-
379
- //get variant options
380
- $layout = Mage::getSingleton('core/layout');
381
- $block = $layout->createBlock('catalog/product_view_type_configurable');
382
- $block->setProduct($parent);
383
- $variantOptions = Mage::helper('core')->jsonDecode($block->getJsonConfig());
384
-
385
- $variantAttributes = array();
386
- foreach ($variantOptions['attributes'] as $attributeId => $options)
387
- {
388
- $code = $options['code'];
389
- foreach ($options['options'] as $option)
390
- {
391
- $value = $option['label'];
392
- $price = $option['price'];
393
- $valueId = $option['id'];
394
- foreach ($option['products'] as $productId)
395
- {
396
- //$children[] = $productId;
397
- $variantAttributes[$productId][$code]['value'] = $value;
398
- $variantAttributes[$productId][$code]['price'] = $price;
399
- $variantAttributes[$productId][$code]['valueId'] = $valueId;
400
- $variantAttributes[$productId][$code]['attributeId'] = $attributeId;
401
- }
402
- }
403
- }
404
- $variantOptions['refactoredOptions'] = $variantAttributes;
405
-
406
-
407
- foreach ($children as $variant)
408
- {
409
- /** @var Mage_Catalog_Model_Product $variant */
410
- //$variant = Mage::getModel('catalog/product')->load($variantId);
411
-
412
- $productData = $this->getProductInfo($variant, $parent, $variantOptions, $lastUpdate, $priceCurrency, $priceCurrencyRate);
413
- if (!empty($productData))
414
- {
415
- $products[] = $productData;
416
- }
417
- }
418
- }
419
- }
420
- else
421
- {
422
- $productData = $this->getProductInfo($product, null, null, $lastUpdate, $priceCurrency, $priceCurrencyRate);
423
- if (!empty($productData))
424
- {
425
- $products[] = $productData;
426
- }
427
- }
428
- }
429
-
430
- return $products;
431
- }
432
-
433
- public function getItem($itemId, $store = null, $priceCurrency = null, $priceCurrencyRate = null)
434
- {
435
- $products = array();
436
-
437
- $product = Mage::getModel('catalog/product')->load($itemId);
438
-
439
- $products[] = $this->getProductInfo($product, null, null, null, $priceCurrency, $priceCurrencyRate);
440
-
441
- return $products;
442
- }
443
  }
1
+ <?php
2
+
3
+ class ShoppingFeeder_Service_Model_Offers extends Mage_Core_Model_Abstract
4
+ {
5
+ public function __construct()
6
+ {
7
+ $this->_init('shoppingfeeder_service/offers');
8
+ }
9
+
10
+ private function hasParent($product)
11
+ {
12
+ $parents = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
13
+ return !empty($parents);
14
+ }
15
+
16
+ private function getProductInfo(Mage_Catalog_Model_Product $product, Mage_Catalog_Model_Product $parent = null, $variantOptions = null, $lastUpdate = null, $priceCurrency, $priceCurrencyRate)
17
+ {
18
+ /** @var Mage_Catalog_Model_Product_Type_Configurable $configModel */
19
+ $configModel = Mage::getModel('catalog/product_type_configurable');
20
+
21
+ $p = array();
22
+
23
+ $isVariant = !is_null($parent);
24
+
25
+ /**
26
+ * We only want to pull variants (children of configurable products) that are children, not as standalone products
27
+ */
28
+ //if this product's parent is visible in catalog and search, Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
29
+ //we will find this product when we fetch all the children of this parent through a normal iteration, so return nothing
30
+ if (!$isVariant && $this->hasParent($product))
31
+ {
32
+ return array();
33
+ }
34
+
35
+ if ($isVariant)
36
+ {
37
+ $variant = $product;
38
+ $product = $parent;
39
+ }
40
+
41
+ $data = $product->getData();
42
+
43
+ /* @var Mage_CatalogInventory_Model_Stock_Item $stockItem */
44
+ $stockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
45
+
46
+ $attributes = $product->getAttributes();
47
+ $manufacturer = '';
48
+ $brand = '';
49
+
50
+ $usefulAttributes = array();
51
+
52
+ /**
53
+ * @var Mage_Eav_Model_Entity_Attribute_Abstract $attribute
54
+ */
55
+ // var_dump("");
56
+ // var_dump("");
57
+ // var_dump("");
58
+ foreach ($attributes as $attribute)
59
+ {
60
+ $attributeCode = $attribute->getAttributeCode();
61
+ $attributeLabel = $attribute->getData('frontend_label');
62
+ $value = $attribute->getFrontend()->getValue($product);
63
+
64
+ // var_dump($attributeCode. ' : '.print_r($value, true));
65
+ // var_dump($attributeLabel. ' : '.print_r($value, true));
66
+
67
+ if (preg_match('/^manufacturer$/i', $attributeCode) || preg_match('/^manufacturer$/i', $attributeLabel))
68
+ {
69
+ $manufacturer = $value;
70
+ }
71
+
72
+ if (preg_match('/^brand$/i', $attributeCode) || preg_match('/^brand$/i', $attributeLabel))
73
+ {
74
+ $brand = $value;
75
+ }
76
+
77
+ /*
78
+ if (preg_match('/age/i', $attributeCode) || preg_match('/age/i', $attributeLabel))
79
+ {
80
+ $usefulAttributes['age'] = $value;
81
+ }
82
+ if (preg_match('/color|colour/i', $attributeCode) || preg_match('/color|colour/i', $attributeLabel))
83
+ {
84
+ $usefulAttributes['colour'] = $value;
85
+ }
86
+ if (preg_match('/size/i', $attributeCode) || preg_match('/size/i', $attributeLabel))
87
+ {
88
+ $usefulAttributes['size'] = $value;
89
+ }
90
+ if (preg_match('/gender|sex/i', $attributeCode) || preg_match('/gender|sex/i', $attributeLabel))
91
+ {
92
+ $usefulAttributes['gender'] = $value;
93
+ }
94
+ if (preg_match('/material/i', $attributeCode) || preg_match('/material/i', $attributeLabel))
95
+ {
96
+ $usefulAttributes['material'] = $value;
97
+ }
98
+ if (preg_match('/pattern/i', $attributeCode) || preg_match('/pattern/i', $attributeLabel))
99
+ {
100
+ $usefulAttributes['pattern'] = $value;
101
+ }
102
+ */
103
+ if (!is_null($product->getData($attributeCode)) && ((string)$attribute->getFrontend()->getValue($product) != ''))
104
+ {
105
+ $usefulAttributes[$attributeCode] = $value;
106
+ }
107
+ }
108
+ // exit();
109
+
110
+ //category path
111
+ $categories = $product->getCategoryIds();
112
+
113
+ $categoryPathsToEvaluate = array();
114
+ $maxDepth = 0;
115
+ $categoryPathToUse = '';
116
+
117
+ $storeRootCategoryId = Mage::app()->getStore()->getRootCategoryId();
118
+ $storeRootCategoryName = Mage::getModel('catalog/category')->load($storeRootCategoryId)->getName();
119
+
120
+ if (!empty($categories))
121
+ {
122
+ /** @var Mage_Catalog_Model_Resource_Category_Collection $categoryCollection */
123
+ $categoryCollection = $product->getCategoryCollection()->addAttributeToSelect('name');
124
+
125
+ $depth = 0;
126
+ foreach($categoryCollection as $cat1){
127
+ $pathIds = explode('/', $cat1->getPath());
128
+ unset($pathIds[0]);
129
+
130
+ $collection = Mage::getModel('catalog/category')->getCollection()
131
+ ->setStoreId(Mage::app()->getStore()->getId())
132
+ ->addAttributeToSelect('name')
133
+ ->addAttributeToSelect('is_active')
134
+ ->addFieldToFilter('entity_id', array('in' => $pathIds));
135
+
136
+ $pathByName = array();
137
+ /** @var Mage_Catalog_Model_Category $cat */
138
+ foreach($collection as $cat){
139
+ if ($cat->getName() != $storeRootCategoryName)
140
+ {
141
+ $pathByName[] = $cat->getName();
142
+ }
143
+ }
144
+
145
+ //take the longest (generally more detailed) path
146
+ $thisDepth = count($pathByName);
147
+ if ($thisDepth > $depth)
148
+ {
149
+ $depth = $thisDepth;
150
+ $categoryPathToUse = implode(' > ', $pathByName);
151
+ }
152
+ }
153
+
154
+ // //we will get all the category paths and then use the most refined, deepest one
155
+ // foreach ($categories as $rootCategoryId)
156
+ // {
157
+ // $depth = 0;
158
+ // $category_path = '';
159
+ //
160
+ // $mageCategoryPath = Mage::getModel('catalog/category')->load($rootCategoryId)->getPath();
161
+ // $allCategoryIds = explode('/', $mageCategoryPath);
162
+ // unset($allCategoryIds[0]);
163
+ //
164
+ // $categoryPath = '';
165
+ // /**
166
+ // * @var Mage_Catalog_Model_Category $category
167
+ // */
168
+ // foreach ($allCategoryIds as $categoryId)
169
+ // {
170
+ // $depth++;
171
+ // $category = Mage::getModel('catalog/category')->load($categoryId);
172
+ // $category_name = $category->getName();
173
+ // if ($category_name != $storeRootCategoryName)
174
+ // {
175
+ // if (!empty($categoryPath))
176
+ // {
177
+ // $categoryPath.= ' > ';
178
+ // }
179
+ // $categoryPath.= $category_name;
180
+ // }
181
+ // }
182
+ //
183
+ // $categoryPathsToEvaluate[$rootCategoryId]['path'] = $categoryPath;
184
+ // $categoryPathsToEvaluate[$rootCategoryId]['depth'] = $depth;
185
+ //
186
+ // if ($maxDepth < $depth)
187
+ // {
188
+ // $maxDepth = $depth;
189
+ // $categoryPathToUse = $categoryPath;
190
+ // }
191
+ // }
192
+ }
193
+
194
+ if ($isVariant && isset($variant))
195
+ {
196
+ $p['internal_variant_id'] = $variant->getId();
197
+
198
+ $variantOptionsTitle = array();
199
+ $variantPrice = $variantOptions['basePrice'];
200
+
201
+ $urlHashParts = array();
202
+
203
+ // Collect options applicable to the configurable product
204
+ if (isset($variantOptions['refactoredOptions'][$variant->getId()]))
205
+ {
206
+ foreach ($variantOptions['refactoredOptions'][$variant->getId()] as $attributeCode => $option) {
207
+ $variantOptionsTitle[] = $option['value'];
208
+
209
+ //add these configured attributes to the set of parent's attributes
210
+ $usefulAttributes[$attributeCode] = $option['value'];
211
+
212
+ $variantPrice += $option['price'];
213
+
214
+ $urlHashParts[] = $option['attributeId'].'='.$option['valueId'];
215
+ }
216
+ }
217
+
218
+ $variantOptionsTitle = implode(' / ', $variantOptionsTitle);
219
+ $title = $data['name'] . ' - ' . $variantOptionsTitle;
220
+ $sku = $variant->getData('sku');
221
+ $price = $variantPrice;
222
+ $variantImage = $variant->getImage();
223
+
224
+ if (!is_null($variantImage) && !empty($variantImage) && $variantImage!='no_selection')
225
+ {
226
+ $imageFile = $variant->getImage();
227
+ // $imageUrl = $p['image_url'] = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).
228
+ // 'catalog/product/'.preg_replace('/^\//', '', $imageFile);
229
+ $imageUrl = $p['image_url'] = $variant->getMediaConfig()->getMediaUrl($imageFile);
230
+ $imageLocalPath = $variant->getMediaConfig()->getMediaPath($imageFile);
231
+ }
232
+ else
233
+ {
234
+ $imageFile = $product->getImage();
235
+ // $imageUrl = $p['image_url'] = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).
236
+ // 'catalog/product/'.preg_replace('/^\//', '', $imageFile);
237
+ $imageUrl = $p['image_url'] = $product->getMediaConfig()->getMediaUrl($imageFile);
238
+ $imageLocalPath = $product->getMediaConfig()->getMediaPath($imageFile);
239
+ }
240
+ $productUrl = $product->getProductUrl().'#'.implode('&', $urlHashParts);
241
+ }
242
+ else
243
+ {
244
+ $p['internal_variant_id'] = '';
245
+ $title = $data['name'];
246
+ $sku = $data['sku'];
247
+ $price = $product->getPrice();
248
+ $imageFile = $product->getImage();
249
+ // $imageUrl = $p['image_url'] = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).
250
+ // 'catalog/product/'.preg_replace('/^\//', '', $imageFile);
251
+ $imageUrl = $p['image_url'] = $product->getMediaConfig()->getMediaUrl($imageFile);
252
+ $imageLocalPath = $product->getMediaConfig()->getMediaPath($imageFile);
253
+ $productUrl = $product->getProductUrl();
254
+ }
255
+
256
+ //if we have previously captured this product and it hasn't changed, don't send through full payload
257
+ $wasPreviouslyCaptured = !is_null($lastUpdate) && isset($usefulAttributes['updated_at']) && strtotime($usefulAttributes['updated_at']) < $lastUpdate;
258
+ if ($wasPreviouslyCaptured)
259
+ {
260
+ $p['internal_id'] = $product->getId();
261
+ $p['internal_update_time'] = date("c", strtotime($usefulAttributes['updated_at']));
262
+ }
263
+ else
264
+ {
265
+ $p['category'] = $categoryPathToUse;
266
+ $p['title'] = $title;
267
+ $p['brand'] = ($brand=='No') ? (($manufacturer == 'No') ? '' : $manufacturer) : $brand;
268
+ $p['manufacturer'] = ($manufacturer=='No') ? $brand : $manufacturer;
269
+ $p['mpn'] = isset($data['model']) ? $data['model'] : $data['sku'];
270
+ $p['internal_id'] = $product->getId();
271
+ $p['description'] = $data['description'];
272
+ $p['short_description'] = $data['short_description'];
273
+ $p['weight'] = isset($data['weight']) ? $data['weight'] : 0.00;
274
+ $p['sku'] = $sku;
275
+ $p['gtin'] = '';
276
+
277
+ //$priceModel = $product->getPriceModel();
278
+
279
+ //do a currency conversion. if the currency is in base currency, it will be 1.0
280
+ $price = $price * $priceCurrencyRate;
281
+ $salePrice = $product->getSpecialPrice() * $priceCurrencyRate;
282
+
283
+ $p['currency'] = $priceCurrency;
284
+ $p['price'] = $price;// Mage::helper('checkout')->convertPrice($priceModel->getPrice($product), false);
285
+ $p['sale_price'] = '';
286
+ $p['sale_price_effective_date'] = '';
287
+ if ($salePrice != $p['price'])
288
+ {
289
+ $p['sale_price'] = $salePrice;
290
+ if ($product->getSpecialFromDate()!=null && $product->getSpecialToDate()!=null)
291
+ {
292
+ $p['sale_price_effective_date'] = date("c", strtotime(date("Y-m-d 23:59:59", strtotime($product->getSpecialFromDate())))).'/'.date("c", strtotime(date("Y-m-d 23:59:59", strtotime($product->getSpecialToDate()))));
293
+ }
294
+ }
295
+
296
+ $p['delivery_cost'] = 0.00;
297
+ $p['tax'] = 0.00;
298
+ $p['url'] = $productUrl;
299
+ $p['internal_update_time'] = isset($usefulAttributes['updated_at']) ? date("c", strtotime($usefulAttributes['updated_at'])) : '';
300
+
301
+ $p['image_url'] = $imageUrl;
302
+ if (file_exists($imageLocalPath))
303
+ {
304
+ $p['image_modified_time'] = date("c", filemtime($imageLocalPath));
305
+ }
306
+ $p['availability'] = ($stockItem->getIsInStock())?'in stock':'out of stock';
307
+ $p['quantity'] = $stockItem->getQty();
308
+ $p['condition'] = '';
309
+ $p['availability_date'] = '';
310
+ $p['attributes'] = $usefulAttributes;
311
+ $imageGallery = array();
312
+ foreach ($product->getMediaGalleryImages() as $image)
313
+ {
314
+ $galleryImage = array();
315
+ $galleryImage['url'] = $image['url'];
316
+ if (file_exists($image['path']))
317
+ {
318
+ $galleryImage['image_modified_time'] = date("c", filemtime($image['path']));
319
+ }
320
+ $imageGallery[] = $galleryImage;
321
+ }
322
+ $p['extra_images'] = $imageGallery;
323
+ }
324
+
325
+ return $p;
326
+ }
327
+
328
+ public function getItems($page = null, $numPerPage = 1000, $lastUpdate = null, $store = null, $priceCurrency = null, $priceCurrencyRate = null, $allowVariants = true)
329
+ {
330
+ /* @var Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection $collection */
331
+ $collection = Mage::getModel('catalog/product')->getCollection()
332
+ ->addAttributeToSelect('*')
333
+ ->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_ENABLED)
334
+ ->addAttributeToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH);
335
+
336
+ /**
337
+ * For per-store system
338
+ */
339
+ if (!is_null($store))
340
+ {
341
+ $collection->addStoreFilter(Mage::app()->getStore($store)->getId());
342
+ }
343
+
344
+ if (!is_null($page))
345
+ {
346
+ $offset = ($page * $numPerPage) - $numPerPage;
347
+ $productIds = $collection->getAllIds($numPerPage, $offset);
348
+ }
349
+ else
350
+ {
351
+ $productIds = $collection->getAllIds();
352
+ }
353
+
354
+ $products = array();
355
+ foreach ($productIds as $productId)
356
+ {
357
+ Mage::getModel('catalog/product')->reset();
358
+ /** @var Mage_Catalog_Model_Product $product */
359
+ $product = Mage::getModel('catalog/product')->load($productId);
360
+
361
+ /**
362
+ * Get variants, if there are any
363
+ * If there are variants that are visible in the catalog, we will skip them when we iterate normally
364
+ */
365
+
366
+ //if we have a configurable product, capture the variants
367
+ if ($product->getTypeId() == 'configurable' && $allowVariants)
368
+ {
369
+ /** @var Mage_Catalog_Model_Product_Type_Configurable $configModel */
370
+ $configModel = Mage::getModel('catalog/product_type_configurable');
371
+
372
+ //$children = $configModel->getChildrenIds($product->getId());
373
+ $children = $configModel->getUsedProducts(null,$product);
374
+
375
+ if (count($children) > 0)
376
+ {
377
+ $parent = $product;
378
+
379
+ //get variant options
380
+ $layout = Mage::getSingleton('core/layout');
381
+ $block = $layout->createBlock('catalog/product_view_type_configurable');
382
+ $block->setProduct($parent);
383
+ $variantOptions = Mage::helper('core')->jsonDecode($block->getJsonConfig());
384
+
385
+ $variantAttributes = array();
386
+ foreach ($variantOptions['attributes'] as $attributeId => $options)
387
+ {
388
+ $code = $options['code'];
389
+ foreach ($options['options'] as $option)
390
+ {
391
+ $value = $option['label'];
392
+ $price = $option['price'];
393
+ $valueId = $option['id'];
394
+ foreach ($option['products'] as $productId)
395
+ {
396
+ //$children[] = $productId;
397
+ $variantAttributes[$productId][$code]['value'] = $value;
398
+ $variantAttributes[$productId][$code]['price'] = $price;
399
+ $variantAttributes[$productId][$code]['valueId'] = $valueId;
400
+ $variantAttributes[$productId][$code]['attributeId'] = $attributeId;
401
+ }
402
+ }
403
+ }
404
+ $variantOptions['refactoredOptions'] = $variantAttributes;
405
+
406
+
407
+ foreach ($children as $variant)
408
+ {
409
+ /** @var Mage_Catalog_Model_Product $variant */
410
+ //$variant = Mage::getModel('catalog/product')->load($variantId);
411
+
412
+ $productData = $this->getProductInfo($variant, $parent, $variantOptions, $lastUpdate, $priceCurrency, $priceCurrencyRate);
413
+ if (!empty($productData))
414
+ {
415
+ $products[] = $productData;
416
+ }
417
+ }
418
+ }
419
+ }
420
+ else
421
+ {
422
+ $productData = $this->getProductInfo($product, null, null, $lastUpdate, $priceCurrency, $priceCurrencyRate);
423
+ if (!empty($productData))
424
+ {
425
+ $products[] = $productData;
426
+ }
427
+ }
428
+ }
429
+
430
+ return $products;
431
+ }
432
+
433
+ public function getItem($itemId, $store = null, $priceCurrency = null, $priceCurrencyRate = null)
434
+ {
435
+ $products = array();
436
+
437
+ $product = Mage::getModel('catalog/product')->load($itemId);
438
+
439
+ $products[] = $this->getProductInfo($product, null, null, null, $priceCurrency, $priceCurrencyRate);
440
+
441
+ return $products;
442
+ }
443
  }
app/code/community/ShoppingFeeder/Service/controllers/VersionController.php CHANGED
@@ -1,23 +1,23 @@
1
- <?php
2
-
3
- //IMPORTANT - "Controller" directory is not autoloaded
4
- require_once(Mage::getModuleDir('Controller','ShoppingFeeder_Service').DS.'Controller'.DS.'FrontAuth.php');
5
-
6
- class ShoppingFeeder_Service_VersionController extends Mage_Core_Controller_Front_Action
7
- {
8
- protected static $_version = '1.3.12';
9
-
10
- public function indexAction()
11
- {
12
- $responseData = array(
13
- 'status' => 'success',
14
- 'data' => array(
15
- 'version' => self::$_version
16
- )
17
- );
18
-
19
- header('Content-type: application/json; charset=UTF-8');
20
- echo json_encode($responseData);
21
- exit();
22
- }
23
  }
1
+ <?php
2
+
3
+ //IMPORTANT - "Controller" directory is not autoloaded
4
+ require_once(Mage::getModuleDir('Controller','ShoppingFeeder_Service').DS.'Controller'.DS.'FrontAuth.php');
5
+
6
+ class ShoppingFeeder_Service_VersionController extends Mage_Core_Controller_Front_Action
7
+ {
8
+ protected static $_version = '1.4.0';
9
+
10
+ public function indexAction()
11
+ {
12
+ $responseData = array(
13
+ 'status' => 'success',
14
+ 'data' => array(
15
+ 'version' => self::$_version
16
+ )
17
+ );
18
+
19
+ header('Content-type: application/json; charset=UTF-8');
20
+ echo json_encode($responseData);
21
+ exit();
22
+ }
23
  }
app/code/community/ShoppingFeeder/Service/etc/config.xml CHANGED
@@ -9,7 +9,7 @@
9
  <config>
10
  <modules>
11
  <ShoppingFeeder_Service>
12
- <version>1.3.12</version>
13
  </ShoppingFeeder_Service>
14
  </modules>
15
  <global>
@@ -65,6 +65,13 @@
65
  </args>
66
  </shoppingfeeder>
67
  </routers>
 
 
 
 
 
 
 
68
  <events>
69
  <catalog_controller_product_view>
70
  <observers>
@@ -72,8 +79,28 @@
72
  <class>shoppingfeeder_service/observer</class>
73
  <method>productView</method>
74
  </shoppingfeeder_notify_catalog_controller_product_view>
 
 
 
 
75
  </observers>
76
  </catalog_controller_product_view>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  </events>
78
  </frontend>
79
  <admin>
9
  <config>
10
  <modules>
11
  <ShoppingFeeder_Service>
12
+ <version>1.4.0</version>
13
  </ShoppingFeeder_Service>
14
  </modules>
15
  <global>
65
  </args>
66
  </shoppingfeeder>
67
  </routers>
68
+ <layout>
69
+ <updates>
70
+ <shoppingfeeder_service>
71
+ <file>shoppingfeeder_service.xml</file>
72
+ </shoppingfeeder_service>
73
+ </updates>
74
+ </layout>
75
  <events>
76
  <catalog_controller_product_view>
77
  <observers>
79
  <class>shoppingfeeder_service/observer</class>
80
  <method>productView</method>
81
  </shoppingfeeder_notify_catalog_controller_product_view>
82
+ <!--<shoppingfeeder_fbtrack_view>-->
83
+ <!--<class>shoppingfeeder_service/observer</class>-->
84
+ <!--<method>productViewTrack</method>-->
85
+ <!--</shoppingfeeder_fbtrack_view>-->
86
  </observers>
87
  </catalog_controller_product_view>
88
+ <controller_action_layout_generate_blocks_after>
89
+ <observers>
90
+ <shoppingfeeder_fbtrack_view>
91
+ <class>shoppingfeeder_service/observer</class>
92
+ <method>generateBlocksAfter</method>
93
+ </shoppingfeeder_fbtrack_view>
94
+ </observers>
95
+ </controller_action_layout_generate_blocks_after>
96
+ <checkout_cart_product_add_after>
97
+ <observers>
98
+ <shoppingfeeder_fbtrack_add_to_cart>
99
+ <class>shoppingfeeder_service/observer</class>
100
+ <method>setAddToCartProduct</method>
101
+ </shoppingfeeder_fbtrack_add_to_cart>
102
+ </observers>
103
+ </checkout_cart_product_add_after>
104
  </events>
105
  </frontend>
106
  <admin>
app/code/community/ShoppingFeeder/Service/etc/system.xml CHANGED
@@ -20,9 +20,9 @@
20
 
21
  <groups>
22
  <service translate="label">
23
- <label>Configuration</label>
24
  <frontend_type>text</frontend_type>
25
- <sort_order>10</sort_order>
26
  <show_in_default>1</show_in_default>
27
  <show_in_website>1</show_in_website>
28
  <show_in_store>1</show_in_store>
@@ -51,7 +51,7 @@
51
  <label>ShoppingFeeder API Secret</label>
52
  <frontend_type>text</frontend_type>
53
  <source_model>adminhtml/system_config_source_yesno</source_model>
54
- <sort_order>1</sort_order>
55
  <show_in_default>1</show_in_default>
56
  <show_in_website>1</show_in_website>
57
  <show_in_store>1</show_in_store>
@@ -61,13 +61,44 @@
61
  <label>Enable Order Tracking</label>
62
  <frontend_type>select</frontend_type>
63
  <source_model>adminhtml/system_config_source_yesno</source_model>
64
- <sort_order>2</sort_order>
65
  <show_in_default>1</show_in_default>
66
  <show_in_website>1</show_in_website>
67
  <show_in_store>1</show_in_store>
68
  </tracking>
69
  </fields>
70
  </service>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  </groups>
72
  </shoppingfeeder>
73
  </sections>
20
 
21
  <groups>
22
  <service translate="label">
23
+ <label>Basic Configuration</label>
24
  <frontend_type>text</frontend_type>
25
+ <sort_order>1</sort_order>
26
  <show_in_default>1</show_in_default>
27
  <show_in_website>1</show_in_website>
28
  <show_in_store>1</show_in_store>
51
  <label>ShoppingFeeder API Secret</label>
52
  <frontend_type>text</frontend_type>
53
  <source_model>adminhtml/system_config_source_yesno</source_model>
54
+ <sort_order>2</sort_order>
55
  <show_in_default>1</show_in_default>
56
  <show_in_website>1</show_in_website>
57
  <show_in_store>1</show_in_store>
61
  <label>Enable Order Tracking</label>
62
  <frontend_type>select</frontend_type>
63
  <source_model>adminhtml/system_config_source_yesno</source_model>
64
+ <sort_order>3</sort_order>
65
  <show_in_default>1</show_in_default>
66
  <show_in_website>1</show_in_website>
67
  <show_in_store>1</show_in_store>
68
  </tracking>
69
  </fields>
70
  </service>
71
+ <fb_track_config translate="label">
72
+ <label>Facebook Audience Tracking Pixel Configuration</label>
73
+ <frontend_type>text</frontend_type>
74
+ <sort_order>2</sort_order>
75
+ <show_in_default>1</show_in_default>
76
+ <show_in_website>1</show_in_website>
77
+ <show_in_store>1</show_in_store>
78
+ <expanded>1</expanded>
79
+ <fields>
80
+ <fb_track translate="label">
81
+ <label>Enable Facebook Audience Tracking Pixel</label>
82
+ <frontend_type>select</frontend_type>
83
+ <source_model>adminhtml/system_config_source_yesno</source_model>
84
+ <sort_order>4</sort_order>
85
+ <show_in_default>1</show_in_default>
86
+ <show_in_website>1</show_in_website>
87
+ <show_in_store>1</show_in_store>
88
+ </fb_track>
89
+ <fb_track_code translate="label">
90
+ <label>Facebook Audience Tracking Pixel Code</label>
91
+ <frontend_type>text</frontend_type>
92
+ <source_model>adminhtml/system_config_source_yesno</source_model>
93
+ <sort_order>5</sort_order>
94
+ <show_in_default>1</show_in_default>
95
+ <show_in_website>1</show_in_website>
96
+ <show_in_store>1</show_in_store>
97
+ <validate>required-entry</validate>
98
+ <depends><fb_track>1</fb_track></depends>
99
+ </fb_track_code>
100
+ </fields>
101
+ </fb_track_config>
102
  </groups>
103
  </shoppingfeeder>
104
  </sections>
app/design/frontend/base/default/layout/shoppingfeeder_service.xml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ *
4
+ /**
5
+ *
6
+ * Facebook Dynamic Product Ads tracking code by ShoppingFeeder
7
+ * Get ShoppingFeeder Feed Management & Channel Marketing Service now: http://www.shoppingfeeder.com
8
+ *
9
+ * @category design
10
+ * @package base_default_layout_shoppingfeeder
11
+ * @copyright Copyright (c) 2015 Kevin Tucker (ShoppingFeeder)
12
+ *
13
+ */
14
+
15
+ -->
16
+ <layout version="0.1.0">
17
+
18
+ <!--
19
+ Default layout, loads most of the pages
20
+ -->
21
+
22
+ <default>
23
+ <!-- ShoppingFeeder_Service -->
24
+ <reference name="before_body_end">
25
+ <block type="shoppingfeeder_service/tracking_fb" name="shoppingfeeder_service_tracking_fb" as="shoppingfeeder_service_tracking_fb" template="shoppingfeeder/fbtrack.phtml" />
26
+ </reference>
27
+ </default>
28
+ </layout>
app/design/frontend/base/default/template/shoppingfeeder/fbtrack.phtml ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ *
4
+ * Facebook Dynamic Product Ads tracking code by ShoppingFeeder
5
+ * Get ShoppingFeeder Feed Management & Channel Marketing Service now: http://www.shoppingfeeder.com
6
+ *
7
+ * @category design
8
+ * @package base_default_template_shoppingfeeder_fbtrack
9
+ * @copyright Copyright (c) 2015 Kevin Tucker (ShoppingFeeder)
10
+ *
11
+ */
12
+ ?>
13
+
14
+ <!-- Custom Audience Pixel Code -->
15
+ <script>
16
+ !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
17
+ n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
18
+ n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
19
+ t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
20
+ document,'script','//connect.facebook.net/en_US/fbevents.js');
21
+ // Insert Your Custom Audience Pixel ID below.
22
+ fbq('init', '<?php echo $this->getPixelId();?>');
23
+
24
+ <?php if ($this->getData('product') !== null):?>
25
+ fbq('track', '<?php echo addslashes($this->getData('action_type'));?>', {
26
+ content_name: '<?php echo addslashes($this->getData('product')->name);?>',
27
+ content_category: '<?php echo addslashes($this->getData('category'));?>',
28
+ content_ids: ['<?php echo addslashes($this->getData('product')->getId());?>'],
29
+ content_type: 'product',
30
+ value: <?php echo $this->getProductPrice();?>,
31
+ currency: '<?php echo $this->getCurrency();?>'
32
+ });
33
+ <?php endif;?>
34
+ <?php if ($this->getData('order') !== null):?>
35
+ fbq('track', '<?php echo addslashes($this->getData('action_type'));?>', {
36
+ content_ids: [<?php echo implode(',', $this->getData('order')['items']);?>],
37
+ content_type: 'product',
38
+ value: <?php echo $this->getData('order')['value'];?>,
39
+ currency: '<?php echo $this->getCurrency();?>'
40
+ });
41
+ <?php endif;?>
42
+
43
+ </script>
44
+ <!-- End Custom Audience Pixel Code -->
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>shoppingfeeder</name>
4
- <version>1.3.12</version>
5
  <stability>stable</stability>
6
  <license>GNU General Public License (GPL)</license>
7
  <channel>community</channel>
@@ -16,11 +16,13 @@ Use ShoppingFeeder to import your Shopify product catalogue, export it to numero
16
  Export to Google, Shopping.com, Nextag, kelkoo, PriceCheck, Shopmania, Fruugo and more!&#xD;
17
  &#xD;
18
  To set up your ShoppingFeeder account and install this extension seamlessly, create an account at: &lt;a href="http://www.shoppingfeeder.com/register"&gt;http://www.shoppingfeeder.com/register&lt;/a&gt;</description>
19
- <notes>Timezone fix for special price from date and to date</notes>
 
 
20
  <authors><author><name>ShoppingFeeder</name><user>shoppingfeeder</user><email>support@shoppingfeeder.com</email></author></authors>
21
  <date>2015-10-12</date>
22
- <time>07:41:30</time>
23
- <contents><target name="mageetc"><dir name="modules"><file name="ShoppingFeeder_Service.xml" hash="90b374109c2d1281ddf527f24fa7d914"/></dir></target><target name="magecommunity"><dir name="ShoppingFeeder"><dir name="Service"><dir name="Block"><dir name="Adminhtml"><file name="Service.php" hash="e94d54bc342dc2941753ad635c0454a3"/></dir><file name="Service.php" hash="48874f0e80ce70686b81eb5380e9f498"/></dir><dir name="Controller"><file name="FrontAuth.php" hash="28ed32e1bf3250362911a26869f0e6d7"/></dir><dir name="Helper"><file name="Data.php" hash="17589bd08352e497806bef9884972300"/></dir><dir name="Model"><file name="Auth.php" hash="2cff17b0750ff70695b32524627b2aaf"/><file name="Observer.php" hash="fe8d86049e9fef786b13cec3b3a902ed"/><file name="Offers.php" hash="3670c5bcd2759cdf0c6bbd0f8a5f5f1d"/><file name="Orders.php" hash="cc3c9f38ae41c11ab7dda0bcb8dd001f"/></dir><dir name="controllers"><file name="AttributesController.php" hash="e937c492f770bc8381a003a080cf878b"/><file name="FeedController.php" hash="92b70af3a048ece99d262480c51aa862"/><file name="OrdersController.php" hash="e0dcf407e15ca212b43ee0015c918675"/><file name="StoresController.php" hash="a29fa0e97299ce764fd66360cbf6632a"/><file name="TestController.php" hash="5138a844cb7cbc8e792df664057bdf9b"/><file name="VersionController.php" hash="dba7a0ad6947602fe39fc5d6dc7bbde5"/></dir><dir name="data"><file name="cacert.pem" hash="380df856e8f789c1af97d0da9a243769"/></dir><dir name="etc"><file name="config.xml" hash="904c264fccc67ddc348476f1b53438bd"/><file name="system.xml" hash="9681c74fa8886143197932690616e2dd"/></dir></dir></dir></target></contents>
24
  <compatible/>
25
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
26
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>shoppingfeeder</name>
4
+ <version>1.4.0</version>
5
  <stability>stable</stability>
6
  <license>GNU General Public License (GPL)</license>
7
  <channel>community</channel>
16
  Export to Google, Shopping.com, Nextag, kelkoo, PriceCheck, Shopmania, Fruugo and more!&#xD;
17
  &#xD;
18
  To set up your ShoppingFeeder account and install this extension seamlessly, create an account at: &lt;a href="http://www.shoppingfeeder.com/register"&gt;http://www.shoppingfeeder.com/register&lt;/a&gt;</description>
19
+ <notes>Version 1.4.0 brings optimisations and a very exciting update enabling "Facebook Audience Pixel Tracking".&#xD;
20
+ &#xD;
21
+ ShoppingFeeder now help you list and manage your product listings on Facebook Dynamic Product Ads.</notes>
22
  <authors><author><name>ShoppingFeeder</name><user>shoppingfeeder</user><email>support@shoppingfeeder.com</email></author></authors>
23
  <date>2015-10-12</date>
24
+ <time>12:07:55</time>
25
+ <contents><target name="mageetc"><dir name="modules"><file name="ShoppingFeeder_Service.xml" hash="90b374109c2d1281ddf527f24fa7d914"/></dir></target><target name="magecommunity"><dir name="ShoppingFeeder"><dir name="Service"><dir name="Block"><dir name="Adminhtml"><file name="Service.php" hash="8feb1712d6aa6a6897be8f80ba5d3f0b"/></dir><file name="Service.php" hash="48874f0e80ce70686b81eb5380e9f498"/><dir name="Tracking"><file name="Fb.php" hash="060687f842c896df73feb233b68b069b"/></dir></dir><dir name="Controller"><file name="FrontAuth.php" hash="28ed32e1bf3250362911a26869f0e6d7"/></dir><dir name="Helper"><file name="Data.php" hash="17589bd08352e497806bef9884972300"/></dir><dir name="Model"><file name="Auth.php" hash="2cff17b0750ff70695b32524627b2aaf"/><file name="Observer.php" hash="1a8d4d6a5333328313ab376151e9df10"/><file name="Offers.php" hash="e387d6b513a9e6c1611f9ef74aa3782a"/><file name="Orders.php" hash="cc3c9f38ae41c11ab7dda0bcb8dd001f"/></dir><dir name="controllers"><file name="AttributesController.php" hash="e937c492f770bc8381a003a080cf878b"/><file name="FeedController.php" hash="92b70af3a048ece99d262480c51aa862"/><file name="OrdersController.php" hash="e0dcf407e15ca212b43ee0015c918675"/><file name="StoresController.php" hash="a29fa0e97299ce764fd66360cbf6632a"/><file name="TestController.php" hash="5138a844cb7cbc8e792df664057bdf9b"/><file name="VersionController.php" hash="122addf6d3a99fd34348448682dda505"/></dir><dir name="data"><file name="cacert.pem" hash="380df856e8f789c1af97d0da9a243769"/></dir><dir name="etc"><file name="config.xml" hash="8b8d53817319b7dcaffd44f0aa578532"/><file name="system.xml" hash="0c4b7f9ba0e97dc471216ea8149ac0e4"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="shoppingfeeder_service.xml" hash="4f3a5b5018c0328da4f9490d4c6042fd"/></dir><dir name="template"><dir name="shoppingfeeder"><file name="fbtrack.phtml" hash="a7d90e8f55037c9c5bdab515151db364"/></dir></dir></dir></dir></dir></target></contents>
26
  <compatible/>
27
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
28
  </package>