shopgate_module - Version 2.9.27

Version Notes

Shopgate Modul

Download this release

Release Info

Developer Stephan Recknagel
Extension shopgate_module
Version 2.9.27
Comparing to
See all releases


Code changes from version 2.9.26 to 2.9.27

Files changed (44) hide show
  1. app/code/community/Shopgate/Framework/Helper/Export.php +2 -1
  2. app/code/community/Shopgate/Framework/Helper/Import/Order.php +22 -9
  3. app/code/community/Shopgate/Framework/Model/Config.php +3 -0
  4. app/code/community/Shopgate/Framework/Model/Export/Product/Xml.php +212 -158
  5. app/code/community/Shopgate/Framework/Model/Export/Settings.php +6 -1
  6. app/code/community/Shopgate/Framework/Model/Mobile/Redirect.php +136 -4
  7. app/code/community/Shopgate/Framework/Model/Observer.php +8 -1
  8. app/code/community/Shopgate/Framework/Model/Payment/Pp/Wspp.php +1 -1
  9. app/code/community/Shopgate/Framework/Model/Payment/Router.php +19 -11
  10. app/code/community/Shopgate/Framework/Model/Shopgate/Plugin.php +20 -4
  11. app/code/community/Shopgate/Framework/changelog.txt +16 -3
  12. app/code/community/Shopgate/Framework/controllers/FrameworkController.php +2 -7
  13. app/code/community/Shopgate/Framework/etc/config.xml +1 -1
  14. app/code/community/Shopgate/Framework/sql/shopgate_setup/mysql4-upgrade-2.9.4-2.9.5.php +8 -0
  15. lib/Shopgate/assets/js_header.html +5 -5
  16. lib/Shopgate/assets/link_tag.html +1 -1
  17. lib/Shopgate/changelog.txt +19 -1
  18. lib/Shopgate/classes/apis.php +33 -35
  19. lib/Shopgate/classes/configuration.php +36 -8
  20. lib/Shopgate/classes/core.php +168 -77
  21. lib/Shopgate/classes/helper/redirect/KeywordsManager.php +253 -0
  22. lib/Shopgate/classes/helper/redirect/KeywordsManagerInterface.php +54 -0
  23. lib/Shopgate/classes/helper/redirect/LinkBuilder.php +154 -0
  24. lib/Shopgate/classes/helper/redirect/LinkBuilderInterface.php +96 -0
  25. lib/Shopgate/classes/helper/redirect/MobileRedirect.php +322 -0
  26. lib/Shopgate/classes/helper/redirect/MobileRedirectInterface.php +97 -0
  27. lib/Shopgate/classes/helper/redirect/Redirector.php +123 -0
  28. lib/Shopgate/classes/helper/redirect/RedirectorInterface.php +78 -0
  29. lib/Shopgate/classes/helper/redirect/SettingsManager.php +209 -0
  30. lib/Shopgate/classes/helper/redirect/SettingsManagerInterface.php +97 -0
  31. lib/Shopgate/classes/helper/redirect/TagsGenerator.php +249 -0
  32. lib/Shopgate/classes/helper/redirect/TagsGeneratorInterface.php +66 -0
  33. lib/Shopgate/classes/helper/redirect/TemplateParser.php +82 -0
  34. lib/Shopgate/classes/helper/redirect/TemplateParserInterface.php +54 -0
  35. lib/Shopgate/classes/models/redirect/DeeplinkSuffix.php +55 -0
  36. lib/Shopgate/classes/models/redirect/DeeplinkSuffixValue.php +53 -0
  37. lib/Shopgate/classes/models/redirect/DeeplinkSuffixValueDisabled.php +32 -0
  38. lib/Shopgate/classes/models/redirect/DeeplinkSuffixValueUnset.php +32 -0
  39. lib/Shopgate/classes/models/redirect/HtmlTag.php +39 -0
  40. lib/Shopgate/classes/models/redirect/HtmlTagAttribute.php +47 -0
  41. lib/Shopgate/classes/models/redirect/HtmlTagVariable.php +39 -0
  42. lib/Shopgate/classes/redirect.php +73 -18
  43. lib/Shopgate/shopgate.php +33 -19
  44. package.xml +4 -4
app/code/community/Shopgate/Framework/Helper/Export.php CHANGED
@@ -65,7 +65,7 @@ class Shopgate_Framework_Helper_Export extends Mage_Core_Helper_Abstract
65
  *
66
  * @param Mage_Catalog_Model_Product $product
67
  *
68
- * @return float
69
  */
70
  public function calcProductPriceRule(Mage_Catalog_Model_Product $product)
71
  {
@@ -486,6 +486,7 @@ class Shopgate_Framework_Helper_Export extends Mage_Core_Helper_Abstract
486
 
487
  $counter = 0;
488
  foreach ($attributeCodes as $attributeCode) {
 
489
  if (!empty($attributeCode)) {
490
  /** @var Mage_Catalog_Model_Resource_Eav_Attribute $attribute */
491
  $attribute = $product->getResource()->getAttribute($attributeCode);
65
  *
66
  * @param Mage_Catalog_Model_Product $product
67
  *
68
+ * @return float|null
69
  */
70
  public function calcProductPriceRule(Mage_Catalog_Model_Product $product)
71
  {
486
 
487
  $counter = 0;
488
  foreach ($attributeCodes as $attributeCode) {
489
+ $attributeCode = trim($attributeCode);
490
  if (!empty($attributeCode)) {
491
  /** @var Mage_Catalog_Model_Resource_Eav_Attribute $attribute */
492
  $attribute = $product->getResource()->getAttribute($attributeCode);
app/code/community/Shopgate/Framework/Helper/Import/Order.php CHANGED
@@ -145,14 +145,25 @@ class Shopgate_Framework_Helper_Import_Order extends Mage_Core_Helper_Abstract
145
  )
146
  ) {
147
  $comment = '';
148
- $customFieldSet = array(
149
- $this->_getHelper()
150
- ->__('[SHOPGATE] Custom fields:') => $shopgateOrder->getCustomFields(),
151
- $this->_getHelper()
152
- ->__('Shipping Address fields:') => $shopgateOrder->getDeliveryAddress()->getCustomFields(),
153
- $this->_getHelper()
154
- ->__('Billing Address fields:') => $shopgateOrder->getInvoiceAddress()->getCustomFields()
155
- );
 
 
 
 
 
 
 
 
 
 
 
156
 
157
  foreach ($customFieldSet as $title => $set) {
158
  $comment .= '<strong>' . $title . '</strong><br/>';
@@ -163,7 +174,9 @@ class Shopgate_Framework_Helper_Import_Order extends Mage_Core_Helper_Abstract
163
  }
164
  }
165
 
166
- $order->addStatusHistoryComment($comment, false);
 
 
167
  }
168
 
169
  return $order;
145
  )
146
  ) {
147
  $comment = '';
148
+ $customFieldSet = array();
149
+
150
+ $oderCustomFields = $shopgateOrder->getCustomFields();
151
+ if (!empty($oderCustomFields)) {
152
+ $label = $this->_getHelper()->__('[SHOPGATE] Custom fields:');
153
+ $customFieldSet[$label] = $oderCustomFields;
154
+ }
155
+
156
+ $deliveryCustomFields = $shopgateOrder->getDeliveryAddress()->getCustomFields();
157
+ if (!empty($deliveryCustomFields)) {
158
+ $label = $this->_getHelper()->__('Shipping Address fields:');
159
+ $customFieldSet[$label] = $deliveryCustomFields;
160
+ }
161
+
162
+ $invoiceCustomFields = $shopgateOrder->getInvoiceAddress()->getCustomFields();
163
+ if (!empty($invoiceCustomFields)) {
164
+ $label = $this->_getHelper()->__('Billing Address fields:');
165
+ $customFieldSet[$label] = $invoiceCustomFields;
166
+ }
167
 
168
  foreach ($customFieldSet as $title => $set) {
169
  $comment .= '<strong>' . $title . '</strong><br/>';
174
  }
175
  }
176
 
177
+ if (!empty($comment)) {
178
+ $order->addStatusHistoryComment($comment, false);
179
+ }
180
  }
181
 
182
  return $order;
app/code/community/Shopgate/Framework/Model/Config.php CHANGED
@@ -901,6 +901,9 @@ class Shopgate_Framework_Model_Config extends ShopgateConfig
901
  if ($type == 'array' && is_array($value)) {
902
  return implode(",", $value);
903
  }
 
 
 
904
 
905
  return $value;
906
  }
901
  if ($type == 'array' && is_array($value)) {
902
  return implode(",", $value);
903
  }
904
+ if (is_bool($value)) {
905
+ $value = (int)$value;
906
+ }
907
 
908
  return $value;
909
  }
app/code/community/Shopgate/Framework/Model/Export/Product/Xml.php CHANGED
@@ -179,7 +179,8 @@ class Shopgate_Framework_Model_Export_Product_Xml
179
  */
180
  public function setName()
181
  {
182
- $parentName = Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_PARENT_PRODUCT_NAME);
 
183
 
184
  if ($parentName && $this->_parent != null) {
185
  $name = $this->_parent->getName();
@@ -199,12 +200,12 @@ class Shopgate_Framework_Model_Export_Product_Xml
199
  $request = new Varien_Object(
200
  array(
201
  'country_id' => Mage::getStoreConfig(
202
- "tax/defaults/country",
203
- $this->_getConfig()->getStoreViewId()
204
- ),
205
  'customer_class_id' => Mage::getModel("tax/calculation")->getDefaultCustomerTaxClass(
206
- $this->_getConfig()->getStoreViewId()
207
- ),
208
  'product_class_id' => $product->getTaxClassId()
209
  )
210
  );
@@ -220,30 +221,32 @@ class Shopgate_Framework_Model_Export_Product_Xml
220
  */
221
  public function setTaxPercent()
222
  {
223
- if ($this->item->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
224
- && $this->item->getPriceType() == Mage_Bundle_Model_Product_Price::PRICE_TYPE_DYNAMIC
225
- ) {
226
- $childIds = $this->item->getTypeInstance()->getChildrenIds($this->item->getId());
227
- $taxRates = array();
228
- foreach ($childIds as $childOption) {
229
- foreach ($childOption as $childId) {
230
- $product = Mage::getModel('catalog/product')
231
- ->setStoreId($this->_getConfig()->getStoreViewId())
232
- ->load($childId);
233
-
234
- $taxRates[] = $this->_getTaxRate($product);
235
- }
236
- }
237
-
238
- parent::setTaxPercent(max($taxRates));
239
- } else {
240
- if(!($this->item->getTaxClassId() == Shopgate_Framework_Model_Export_Product_Xml::DEFAULT_TAX_CLASS_ID_NONE && $this->_parent)) {
 
 
241
  $taxPercent = $this->_getTaxRate($this->item);
242
- if(!empty($taxPercent)) {
243
  parent::setTaxPercent($this->_getTaxRate($this->item));
244
  }
245
  }
246
- }
247
  }
248
 
249
  /**
@@ -251,31 +254,33 @@ class Shopgate_Framework_Model_Export_Product_Xml
251
  */
252
  public function setTaxClass()
253
  {
254
- if ($this->item->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
255
- && $this->item->getPriceType() == Mage_Bundle_Model_Product_Price::PRICE_TYPE_DYNAMIC
256
- ) {
257
- $childIds = $this->item->getTypeInstance()->getChildrenIds($this->item->getId());
258
- $taxRates = array();
259
- foreach ($childIds as $childOption) {
260
- foreach ($childOption as $childId) {
261
- $product = Mage::getModel('catalog/product')
262
- ->setStoreId($this->_getConfig()->getStoreViewId())
263
- ->load($childId);
264
-
265
- $taxClassId = $product->getTaxClassId();
266
- $taxRates[$taxClassId] = $this->_getTaxRate($product);
267
- }
268
- }
269
-
270
- parent::setTaxClass(array_search(max($taxRates), $taxRates));
271
- } else {
272
- if(!($this->item->getTaxClassId() == Shopgate_Framework_Model_Export_Product_Xml::DEFAULT_TAX_CLASS_ID_NONE && $this->_parent)) {
 
 
273
  $taxClassId = $this->item->getTaxClassId();
274
- if(!empty($taxClassId)) {
275
  parent::setTaxClass($taxClassId);
276
  }
277
  }
278
- }
279
  }
280
 
281
  /**
@@ -293,7 +298,10 @@ class Shopgate_Framework_Model_Export_Product_Xml
293
  public function setDescription()
294
  {
295
  if (Mage::getStoreConfig(
296
- Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_VARIATION_DESCRIPTION) == 1 && $this->_parent) {
 
 
 
297
  $description = "";
298
  } else {
299
  $description = $this->_getExportHelper()->createFullDescription($this->item, $this->_parent);
@@ -381,10 +389,11 @@ class Shopgate_Framework_Model_Export_Product_Xml
381
  */
382
  public function setPrice()
383
  {
384
- $useParent = false;
385
 
386
  if (Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_USE_ROOT_PRICES)
387
- && $this->_parent != null && $this->_parent->isConfigurable()
 
388
  ) {
389
  $useParent = true;
390
  }
@@ -441,9 +450,9 @@ class Shopgate_Framework_Model_Export_Product_Xml
441
  ->getConfigurableAttributes($this->_parent);
442
 
443
  foreach ($superAttributes as $superAttribute) {
444
- $code = $superAttribute->getProductAttribute()->getAttributeCode();
445
- $index = $this->item->getData($code);
446
- $isPercent = false;
447
 
448
  if ($superAttribute->hasData('prices')) {
449
  foreach ($superAttribute->getPrices() as $saPrice) {
@@ -473,7 +482,7 @@ class Shopgate_Framework_Model_Export_Product_Xml
473
  );
474
  $calculatedPrices = $this->_parent->getConfigurablePrice();
475
 
476
- $price += $calculatedPrices;
477
  $finalPrice += $calculatedPrices;
478
  }
479
  }
@@ -484,15 +493,23 @@ class Shopgate_Framework_Model_Export_Product_Xml
484
  && Mage::getStoreConfig('catalog/baseprice/disable_ext') == 0
485
  ) {
486
  $format = "{{baseprice}} / {{reference_amount}} {{reference_unit_short}}";
487
- $basePrice = Mage::helper("baseprice")->getBasePriceLabel($this->item, $format);
488
- $basePrice = strip_tags($basePrice);
489
- $basePrice = htmlentities($basePrice, null, "UTF-8");
490
- $priceModel->setBasePrice($basePrice);
 
 
 
 
 
 
 
 
491
  }
492
 
493
  $isGross = Mage::getStoreConfig(
494
- self::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
495
- $this->_getConfig()->getStoreViewId()
496
  );
497
 
498
  if ($this->item->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
@@ -516,8 +533,10 @@ class Shopgate_Framework_Model_Export_Product_Xml
516
  } else {
517
  $priceModel->setType(Shopgate_Model_Catalog_Price::DEFAULT_PRICE_TYPE_NET);
518
  }
519
- $this->_createTierPriceNode($priceModel);
520
- $this->_createGroupPriceNode($priceModel);
 
 
521
 
522
  parent::setPrice($priceModel);
523
  }
@@ -537,7 +556,11 @@ class Shopgate_Framework_Model_Export_Product_Xml
537
  $tierPrice->setFromQuantity($tier['price_qty']);
538
  $tierPrice->setReduction($price->getSalePrice() - $tier['website_price']);
539
  $tierPrice->setReductionType(Shopgate_Model_Catalog_TierPrice::DEFAULT_TIER_PRICE_TYPE_FIXED);
540
- if ($this->item->isSuper() && Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_USE_ROOT_PRICES)) {
 
 
 
 
541
  $tierPrice->setAggregateChildren(true);
542
  }
543
 
@@ -565,7 +588,11 @@ class Shopgate_Framework_Model_Export_Product_Xml
565
  $tierPrice->setReduction($price->getSalePrice() - $group['website_price']);
566
  $tierPrice->setReductionType(Shopgate_Model_Catalog_TierPrice::DEFAULT_TIER_PRICE_TYPE_FIXED);
567
  $tierPrice->setCustomerGroupUid($group['cust_group']);
568
- if ($this->item->isSuper() && Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_USE_ROOT_PRICES)) {
 
 
 
 
569
  $tierPrice->setAggregateChildren(true);
570
  }
571
 
@@ -655,15 +682,15 @@ class Shopgate_Framework_Model_Export_Product_Xml
655
  $stock->setIsSaleable(1);
656
  }
657
 
658
- $stock->setBackorders((int)$stockItem->getBackorders());
659
- $stock->setMaximumOrderQuantity((int)$stockItem->getMaxSaleQty());
660
- $stock->setMinimumOrderQuantity((int)$stockItem->getMinSaleQty());
661
- if (method_exists($stockItem, 'getStockQty')) {
662
- $stockQuantity = $stockItem->getStockQty();
663
- } else {
664
- $stockQuantity = $this->_getExportHelper()->getParentStockQuantity($this->item);
665
- }
666
- $stock->setStockQuantity((int)$stockQuantity);
667
  $stock->setAvailabilityText(
668
  $this->_getExportHelper()->getAvailableText(
669
  $this->item,
@@ -696,6 +723,7 @@ class Shopgate_Framework_Model_Export_Product_Xml
696
 
697
  /**
698
  * getting images as array
 
699
  * @return array
700
  */
701
  public function getProductImages()
@@ -717,6 +745,7 @@ class Shopgate_Framework_Model_Export_Product_Xml
717
  }
718
 
719
  $images = $this->_compareImageObject($images);
 
720
  return $images;
721
  }
722
 
@@ -725,11 +754,12 @@ class Shopgate_Framework_Model_Export_Product_Xml
725
  * get product images
726
  *
727
  * @param bool $parent
 
728
  * @return array
729
  */
730
  protected function _getProductImages($parent = false)
731
  {
732
- $images = array();
733
  $product = $this->item;
734
  if ($parent) {
735
  $product = $this->_parent;
@@ -739,15 +769,21 @@ class Shopgate_Framework_Model_Export_Product_Xml
739
  if (!empty($mediaGallery)) {
740
  foreach ($mediaGallery as $image) {
741
  if ($image->getFile()) {
742
- $imageConfig = Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_FIRST_PRODUCT_IMAGE);
 
 
743
  if ($imageConfig == 'thumbnail' && $image->getFile() == $product->getThumbnail()) {
744
  $position = -1;
745
- } else if ($imageConfig == 'base' && $image->getFile() == $product->getImage()) {
746
- $position = -1;
747
- } else if ($imageConfig == 'small' && $image->getFile() == $product->getSmallImage()) {
748
- $position = -1;
749
  } else {
750
- $position = $image->getPosition();
 
 
 
 
 
 
 
 
751
  }
752
  $_image = array(
753
  'url' => $image->getUrl(),
@@ -773,6 +809,7 @@ class Shopgate_Framework_Model_Export_Product_Xml
773
  * compare images
774
  *
775
  * @param $images array
 
776
  * @return array
777
  */
778
  protected function _compareImageObject($images)
@@ -783,6 +820,7 @@ class Shopgate_Framework_Model_Export_Product_Xml
783
  $imageUrls[$_imageObject['url']] = $_imageObject;
784
  }
785
  }
 
786
  return array_values($imageUrls);
787
  }
788
 
@@ -795,7 +833,7 @@ class Shopgate_Framework_Model_Export_Product_Xml
795
  $result = array();
796
  if ($this->_getExportHelper()->isProductVisibleInCategories($this->item)) {
797
  $itemsOrderOption = Mage::getStoreConfig(
798
- Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_ITEM_SORT
799
 
800
  );
801
  $linkedCategories = Mage::getResourceSingleton('shopgate/product')->getCategoryIdsAndPosition($this->item);
@@ -806,12 +844,14 @@ class Shopgate_Framework_Model_Export_Product_Xml
806
 
807
  switch ($itemsOrderOption) {
808
  case Shopgate_Framework_Model_System_Config_Source_Item_Sort::SORT_TYPE_LAST_UPDATED:
809
- $sortIndex = Mage::getModel('core/date')->timestamp(strtotime($this->item->getUpdatedAt()));
810
  $categoryItemObject->setSortOrder($sortIndex);
811
  break;
812
  case Shopgate_Framework_Model_System_Config_Source_Item_Sort::SORT_TYPE_NEWEST:
813
- $sortIndex = Mage::getModel('core/date')->timestamp(strtotime($this->item->getCreatedAt()));
814
- $categoryItemObject->setSortOrder(Shopgate_Framework_Model_Export_Product_Csv::MAX_TIMESTAMP - $sortIndex);
 
 
815
  break;
816
  case Shopgate_Framework_Model_System_Config_Source_Item_Sort::SORT_TYPE_PRICE_DESC:
817
  $sortIndex = round($this->item->getFinalPrice() * 100, 0);
@@ -846,7 +886,7 @@ class Shopgate_Framework_Model_Export_Product_Xml
846
  }
847
 
848
  if (empty($this->_forcedProductAttributeCodes)) {
849
- $forcedProperties = explode(
850
  ",",
851
  Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_FORCE_PROPERTY_EXPORT)
852
  );
@@ -855,45 +895,53 @@ class Shopgate_Framework_Model_Export_Product_Xml
855
 
856
  $result = array();
857
 
858
- $cacheKey = 'product_type_' . $this->item->getTypeId() . '_attributes_' . $this->item->getAttributeSetId();
859
-
860
- $cache = Mage::app()->getCacheInstance();
861
- $value = $cache->load($cacheKey);
862
-
863
- if ($value !== false) {
864
- $attributes = unserialize($value);
865
- } else {
866
- $attributes = $this->item->getAttributes();
867
- $attrCache = array();
868
- foreach ($attributes as $attribute) {
869
- $code = $attribute->getAttributeCode();
870
-
871
- /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
872
- if ($attribute && $attribute->getIsVisibleOnFront() || in_array($code, $this->_forcedProductAttributeCodes)) {
873
- if (in_array($code, $this->_ignoredProductAttributeCodes) && !in_array($code, $this->_forcedProductAttributeCodes)) {
874
- continue;
875
- }
876
-
877
- $attrCache[$code] = array(
878
- 'id' => $attribute->getId(),
879
- 'label' => $attribute->getStoreLabel($this->_getConfig()->getStoreViewId())
880
- );
881
- }
882
- }
883
- $attributes = $attrCache;
 
 
 
 
 
 
 
 
884
  $cache->save(
885
- serialize($attrCache),
886
- $cacheKey,
887
- array(
888
- 'shopgate_export',
889
- Mage_Core_Model_Mysql4_Collection_Abstract::CACHE_TAG,
890
- Mage_Catalog_Model_Resource_Eav_Attribute::CACHE_TAG
891
- ),
892
- 60
893
  );
894
- }
895
 
896
- foreach ($attributes as $code => $data) {
897
  $value = $this->item->getResource()->getAttribute($code)->getFrontend()->getValue($this->item);
898
  if (!empty($value) && !is_array($value)) {
899
  $propertyItemObject = new Shopgate_Model_Catalog_Property();
@@ -1145,6 +1193,8 @@ class Shopgate_Framework_Model_Export_Product_Xml
1145
  }
1146
 
1147
  /**
 
 
1148
  * @param $value Mage_Core_Model_Abstract
1149
  *
1150
  * @return float
@@ -1152,9 +1202,12 @@ class Shopgate_Framework_Model_Export_Product_Xml
1152
  protected function _getOptionValuePrice($value)
1153
  {
1154
  if ($value->getPriceType() == 'percent') {
1155
- $rulePrice = Mage::helper("shopgate/export")->calcProductPriceRule($this->item);
1156
- $price = $rulePrice * ($value->getPrice() / 100);
1157
- return $price;
 
 
 
1158
  }
1159
 
1160
  return $value->getPrice();
@@ -1170,9 +1223,6 @@ class Shopgate_Framework_Model_Export_Product_Xml
1170
  return $this->_getOptionValuePrice($value);
1171
  }
1172
 
1173
- /**
1174
- *
1175
- */
1176
  public function setChildren()
1177
  {
1178
  $children = array();
@@ -1180,8 +1230,8 @@ class Shopgate_Framework_Model_Export_Product_Xml
1180
  $childProductIds = $this->item->getTypeInstance()->getUsedProductIds();
1181
  foreach ($childProductIds as $child) {
1182
  $configChild = Mage::getModel('catalog/product')
1183
- ->setStoreId($this->_getConfig()->getStoreViewId())
1184
- ->load($child);
1185
  if ($configChild->getStatus() != Mage_Catalog_Model_Product_Status::STATUS_DISABLED) {
1186
  $childProducts[] = $configChild;
1187
  }
@@ -1192,8 +1242,8 @@ class Shopgate_Framework_Model_Export_Product_Xml
1192
  $childProductIds = $this->item->getTypeInstance()->getAssociatedProductIds();
1193
  foreach ($childProductIds as $child) {
1194
  $configChild = Mage::getModel('catalog/product')
1195
- ->setStoreId($this->_getConfig()->getStoreViewId())
1196
- ->load($child);
1197
  if ($configChild->getStatus() != Mage_Catalog_Model_Product_Status::STATUS_DISABLED) {
1198
  $childProducts[] = $configChild;
1199
  }
@@ -1255,7 +1305,7 @@ class Shopgate_Framework_Model_Export_Product_Xml
1255
  }
1256
 
1257
  /**
1258
- *
1259
  */
1260
  public function setFireMethodsForChildren()
1261
  {
@@ -1322,8 +1372,10 @@ class Shopgate_Framework_Model_Export_Product_Xml
1322
  protected function _setBundleOptions($inputs = array())
1323
  {
1324
  $bundleOptions = $this->item->getPriceModel()->getOptions($this->item);
1325
- $isGross = Mage::getStoreConfig(self::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
1326
- $this->_getConfig()->getStoreViewId());
 
 
1327
  $stock = parent::getStock();
1328
  $selectionQuantities = array();
1329
 
@@ -1342,33 +1394,31 @@ class Shopgate_Framework_Model_Export_Product_Xml
1342
  $bundleOption->setSelections(array());
1343
  }
1344
 
1345
- $optionPrices = array();
1346
- $cheapestOptionId = null;
1347
- $cheapestPrice = null;
1348
 
1349
- // fetch id of cheapest option
1350
- foreach ($bundleOption->getSelections() as $selection) {
1351
- $selectionPrice = $this->item
1352
- ->getPriceModel()
1353
- ->getSelectionFinalPrice($this->item, $selection, 1, $selection->getSelectionQty());
1354
 
1355
- $selectionPrice = Mage::helper('tax')->getPrice($selection, $selectionPrice, $isGross);
1356
 
1357
- if ($cheapestPrice === null
1358
- || $cheapestPrice > $selectionPrice
1359
- ) {
1360
- $cheapestPrice = $selectionPrice;
1361
- $cheapestOptionId = $selection->getSelectionId();
1362
- }
1363
 
1364
- $optionPrices[$selection->getSelectionId()] = $selectionPrice;
1365
- }
1366
 
1367
  foreach ($bundleOption->getSelections() as $selection) {
1368
  $option = new Shopgate_Model_Catalog_Option();
1369
  /** @var $selection Mage_Catalog_Model_Product */
1370
 
1371
- $selectionId = $selection->getSelectionId();
1372
  $qty = max(1, (int)$selection->getSelectionQty());
1373
  $selectionPrice = $optionPrices[$selectionId];
1374
 
@@ -1402,15 +1452,15 @@ class Shopgate_Framework_Model_Export_Product_Xml
1402
  $option->setLabel($selectionName);
1403
  $option->setSortOrder($selection->getPosition());
1404
 
1405
- // reset selection price, in this case the bundle parent is already configured
1406
- // with the price of the cheapest bundle configuration
1407
- if ($this->item->getPriceType() == Mage_Bundle_Model_Product_Price::PRICE_TYPE_DYNAMIC) {
1408
  if ($cheapestOptionId == $selection->getSelectionId() && $selection->getOption()->getRequired()) {
1409
  $selectionPrice = 0;
1410
  } elseif ($selection->getOption()->getRequired()) {
1411
- $selectionPrice = $selectionPrice-$optionPrices[$cheapestOptionId];
1412
  }
1413
- }
1414
 
1415
  $option->setAdditionalPrice($selectionPrice);
1416
  $optionValues[] = $option;
@@ -1450,15 +1500,19 @@ class Shopgate_Framework_Model_Export_Product_Xml
1450
 
1451
  /**
1452
  * @param $price
 
1453
  * @return float
1454
  */
1455
  protected function _formatPrice($price)
1456
  {
1457
  if (Mage::app()->getStore()->getCurrentCurrency() && Mage::app()->getStore()->getBaseCurrency()) {
1458
- $value = Mage::app()->getStore()->getBaseCurrency()->convert($price, Mage::app()->getStore()->getCurrentCurrency());
 
 
1459
  } else {
1460
  $value = $price;
1461
  }
 
1462
  return $value;
1463
  }
1464
  }
179
  */
180
  public function setName()
181
  {
182
+ $parentName =
183
+ Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_PARENT_PRODUCT_NAME);
184
 
185
  if ($parentName && $this->_parent != null) {
186
  $name = $this->_parent->getName();
200
  $request = new Varien_Object(
201
  array(
202
  'country_id' => Mage::getStoreConfig(
203
+ "tax/defaults/country",
204
+ $this->_getConfig()->getStoreViewId()
205
+ ),
206
  'customer_class_id' => Mage::getModel("tax/calculation")->getDefaultCustomerTaxClass(
207
+ $this->_getConfig()->getStoreViewId()
208
+ ),
209
  'product_class_id' => $product->getTaxClassId()
210
  )
211
  );
221
  */
222
  public function setTaxPercent()
223
  {
224
+ if ($this->item->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
225
+ && $this->item->getPriceType() == Mage_Bundle_Model_Product_Price::PRICE_TYPE_DYNAMIC
226
+ ) {
227
+ $childIds = $this->item->getTypeInstance()->getChildrenIds($this->item->getId());
228
+ $taxRates = array();
229
+ foreach ($childIds as $childOption) {
230
+ foreach ($childOption as $childId) {
231
+ $product = Mage::getModel('catalog/product')
232
+ ->setStoreId($this->_getConfig()->getStoreViewId())
233
+ ->load($childId);
234
+
235
+ $taxRates[] = $this->_getTaxRate($product);
236
+ }
237
+ }
238
+
239
+ parent::setTaxPercent(max($taxRates));
240
+ } else {
241
+ if (!($this->item->getTaxClassId() == Shopgate_Framework_Model_Export_Product_Xml::DEFAULT_TAX_CLASS_ID_NONE
242
+ && $this->_parent)
243
+ ) {
244
  $taxPercent = $this->_getTaxRate($this->item);
245
+ if (!empty($taxPercent)) {
246
  parent::setTaxPercent($this->_getTaxRate($this->item));
247
  }
248
  }
249
+ }
250
  }
251
 
252
  /**
254
  */
255
  public function setTaxClass()
256
  {
257
+ if ($this->item->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
258
+ && $this->item->getPriceType() == Mage_Bundle_Model_Product_Price::PRICE_TYPE_DYNAMIC
259
+ ) {
260
+ $childIds = $this->item->getTypeInstance()->getChildrenIds($this->item->getId());
261
+ $taxRates = array();
262
+ foreach ($childIds as $childOption) {
263
+ foreach ($childOption as $childId) {
264
+ $product = Mage::getModel('catalog/product')
265
+ ->setStoreId($this->_getConfig()->getStoreViewId())
266
+ ->load($childId);
267
+
268
+ $taxClassId = $product->getTaxClassId();
269
+ $taxRates[$taxClassId] = $this->_getTaxRate($product);
270
+ }
271
+ }
272
+
273
+ parent::setTaxClass(array_search(max($taxRates), $taxRates));
274
+ } else {
275
+ if (!($this->item->getTaxClassId() == Shopgate_Framework_Model_Export_Product_Xml::DEFAULT_TAX_CLASS_ID_NONE
276
+ && $this->_parent)
277
+ ) {
278
  $taxClassId = $this->item->getTaxClassId();
279
+ if (!empty($taxClassId)) {
280
  parent::setTaxClass($taxClassId);
281
  }
282
  }
283
+ }
284
  }
285
 
286
  /**
298
  public function setDescription()
299
  {
300
  if (Mage::getStoreConfig(
301
+ Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_VARIATION_DESCRIPTION
302
+ ) == 1
303
+ && $this->_parent
304
+ ) {
305
  $description = "";
306
  } else {
307
  $description = $this->_getExportHelper()->createFullDescription($this->item, $this->_parent);
389
  */
390
  public function setPrice()
391
  {
392
+ $useParent = false;
393
 
394
  if (Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_USE_ROOT_PRICES)
395
+ && $this->_parent != null
396
+ && $this->_parent->isConfigurable()
397
  ) {
398
  $useParent = true;
399
  }
450
  ->getConfigurableAttributes($this->_parent);
451
 
452
  foreach ($superAttributes as $superAttribute) {
453
+ $code = $superAttribute->getProductAttribute()->getAttributeCode();
454
+ $index = $this->item->getData($code);
455
+ $isPercent = false;
456
 
457
  if ($superAttribute->hasData('prices')) {
458
  foreach ($superAttribute->getPrices() as $saPrice) {
482
  );
483
  $calculatedPrices = $this->_parent->getConfigurablePrice();
484
 
485
+ $price += $calculatedPrices;
486
  $finalPrice += $calculatedPrices;
487
  }
488
  }
493
  && Mage::getStoreConfig('catalog/baseprice/disable_ext') == 0
494
  ) {
495
  $format = "{{baseprice}} / {{reference_amount}} {{reference_unit_short}}";
496
+ $basePriceSuccess = true;
497
+ try {
498
+ $basePrice = Mage::helper("baseprice")->getBasePriceLabel($this->item, $format);
499
+ } catch (Exception $e) {
500
+ $basePriceSuccess = false;
501
+ $this->log('error in DerModPro_BasePrice for item uid:' . $this->item->getId());
502
+ }
503
+ if ($basePriceSuccess) {
504
+ $basePrice = strip_tags($basePrice);
505
+ $basePrice = htmlentities($basePrice, null, "UTF-8");
506
+ $priceModel->setBasePrice($basePrice);
507
+ }
508
  }
509
 
510
  $isGross = Mage::getStoreConfig(
511
+ self::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
512
+ $this->_getConfig()->getStoreViewId()
513
  );
514
 
515
  if ($this->item->getTypeId() == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
533
  } else {
534
  $priceModel->setType(Shopgate_Model_Catalog_Price::DEFAULT_PRICE_TYPE_NET);
535
  }
536
+ if (!$useParent) {
537
+ $this->_createTierPriceNode($priceModel);
538
+ $this->_createGroupPriceNode($priceModel);
539
+ }
540
 
541
  parent::setPrice($priceModel);
542
  }
556
  $tierPrice->setFromQuantity($tier['price_qty']);
557
  $tierPrice->setReduction($price->getSalePrice() - $tier['website_price']);
558
  $tierPrice->setReductionType(Shopgate_Model_Catalog_TierPrice::DEFAULT_TIER_PRICE_TYPE_FIXED);
559
+ if ($this->item->isSuper()
560
+ && Mage::getStoreConfig(
561
+ Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_USE_ROOT_PRICES
562
+ )
563
+ ) {
564
  $tierPrice->setAggregateChildren(true);
565
  }
566
 
588
  $tierPrice->setReduction($price->getSalePrice() - $group['website_price']);
589
  $tierPrice->setReductionType(Shopgate_Model_Catalog_TierPrice::DEFAULT_TIER_PRICE_TYPE_FIXED);
590
  $tierPrice->setCustomerGroupUid($group['cust_group']);
591
+ if ($this->item->isSuper()
592
+ && Mage::getStoreConfig(
593
+ Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_USE_ROOT_PRICES
594
+ )
595
+ ) {
596
  $tierPrice->setAggregateChildren(true);
597
  }
598
 
682
  $stock->setIsSaleable(1);
683
  }
684
 
685
+ $stock->setBackorders((int)$stockItem->getBackorders());
686
+ $stock->setMaximumOrderQuantity((int)$stockItem->getMaxSaleQty());
687
+ $stock->setMinimumOrderQuantity((int)$stockItem->getMinSaleQty());
688
+ if (method_exists($stockItem, 'getStockQty')) {
689
+ $stockQuantity = $stockItem->getStockQty();
690
+ } else {
691
+ $stockQuantity = $this->_getExportHelper()->getParentStockQuantity($this->item);
692
+ }
693
+ $stock->setStockQuantity((int)$stockQuantity);
694
  $stock->setAvailabilityText(
695
  $this->_getExportHelper()->getAvailableText(
696
  $this->item,
723
 
724
  /**
725
  * getting images as array
726
+ *
727
  * @return array
728
  */
729
  public function getProductImages()
745
  }
746
 
747
  $images = $this->_compareImageObject($images);
748
+
749
  return $images;
750
  }
751
 
754
  * get product images
755
  *
756
  * @param bool $parent
757
+ *
758
  * @return array
759
  */
760
  protected function _getProductImages($parent = false)
761
  {
762
+ $images = array();
763
  $product = $this->item;
764
  if ($parent) {
765
  $product = $this->_parent;
769
  if (!empty($mediaGallery)) {
770
  foreach ($mediaGallery as $image) {
771
  if ($image->getFile()) {
772
+ $imageConfig = Mage::getStoreConfig(
773
+ Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_FIRST_PRODUCT_IMAGE
774
+ );
775
  if ($imageConfig == 'thumbnail' && $image->getFile() == $product->getThumbnail()) {
776
  $position = -1;
 
 
 
 
777
  } else {
778
+ if ($imageConfig == 'base' && $image->getFile() == $product->getImage()) {
779
+ $position = -1;
780
+ } else {
781
+ if ($imageConfig == 'small' && $image->getFile() == $product->getSmallImage()) {
782
+ $position = -1;
783
+ } else {
784
+ $position = $image->getPosition();
785
+ }
786
+ }
787
  }
788
  $_image = array(
789
  'url' => $image->getUrl(),
809
  * compare images
810
  *
811
  * @param $images array
812
+ *
813
  * @return array
814
  */
815
  protected function _compareImageObject($images)
820
  $imageUrls[$_imageObject['url']] = $_imageObject;
821
  }
822
  }
823
+
824
  return array_values($imageUrls);
825
  }
826
 
833
  $result = array();
834
  if ($this->_getExportHelper()->isProductVisibleInCategories($this->item)) {
835
  $itemsOrderOption = Mage::getStoreConfig(
836
+ Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_ITEM_SORT
837
 
838
  );
839
  $linkedCategories = Mage::getResourceSingleton('shopgate/product')->getCategoryIdsAndPosition($this->item);
844
 
845
  switch ($itemsOrderOption) {
846
  case Shopgate_Framework_Model_System_Config_Source_Item_Sort::SORT_TYPE_LAST_UPDATED:
847
+ $sortIndex = Mage::getModel('core/date')->timestamp(strtotime($this->item->getUpdatedAt()));
848
  $categoryItemObject->setSortOrder($sortIndex);
849
  break;
850
  case Shopgate_Framework_Model_System_Config_Source_Item_Sort::SORT_TYPE_NEWEST:
851
+ $sortIndex = Mage::getModel('core/date')->timestamp(strtotime($this->item->getCreatedAt()));
852
+ $categoryItemObject->setSortOrder(
853
+ Shopgate_Framework_Model_Export_Product_Csv::MAX_TIMESTAMP - $sortIndex
854
+ );
855
  break;
856
  case Shopgate_Framework_Model_System_Config_Source_Item_Sort::SORT_TYPE_PRICE_DESC:
857
  $sortIndex = round($this->item->getFinalPrice() * 100, 0);
886
  }
887
 
888
  if (empty($this->_forcedProductAttributeCodes)) {
889
+ $forcedProperties = explode(
890
  ",",
891
  Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EXPORT_FORCE_PROPERTY_EXPORT)
892
  );
895
 
896
  $result = array();
897
 
898
+ $cacheKey = 'product_type_' . $this->item->getTypeId() . '_attributes_' . $this->item->getAttributeSetId();
899
+
900
+ $cache = Mage::app()->getCacheInstance();
901
+ $value = $cache->load($cacheKey);
902
+
903
+ if ($value !== false) {
904
+ $attributes = unserialize($value);
905
+ } else {
906
+ $attributes = $this->item->getAttributes();
907
+ $attrCache = array();
908
+ foreach ($attributes as $attribute) {
909
+ $code = $attribute->getAttributeCode();
910
+
911
+ /* @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
912
+ if ($attribute && $attribute->getIsVisibleOnFront()
913
+ || in_array(
914
+ $code, $this->_forcedProductAttributeCodes
915
+ )
916
+ ) {
917
+ if (in_array($code, $this->_ignoredProductAttributeCodes)
918
+ && !in_array(
919
+ $code, $this->_forcedProductAttributeCodes
920
+ )
921
+ ) {
922
+ continue;
923
+ }
924
+
925
+ $attrCache[$code] = array(
926
+ 'id' => $attribute->getId(),
927
+ 'label' => $attribute->getStoreLabel($this->_getConfig()->getStoreViewId())
928
+ );
929
+ }
930
+ }
931
+ $attributes = $attrCache;
932
  $cache->save(
933
+ serialize($attrCache),
934
+ $cacheKey,
935
+ array(
936
+ 'shopgate_export',
937
+ Mage_Core_Model_Mysql4_Collection_Abstract::CACHE_TAG,
938
+ Mage_Catalog_Model_Resource_Eav_Attribute::CACHE_TAG
939
+ ),
940
+ 60
941
  );
942
+ }
943
 
944
+ foreach ($attributes as $code => $data) {
945
  $value = $this->item->getResource()->getAttribute($code)->getFrontend()->getValue($this->item);
946
  if (!empty($value) && !is_array($value)) {
947
  $propertyItemObject = new Shopgate_Model_Catalog_Property();
1193
  }
1194
 
1195
  /**
1196
+ * Calculates percentage using catalog price rule base price
1197
+ *
1198
  * @param $value Mage_Core_Model_Abstract
1199
  *
1200
  * @return float
1202
  protected function _getOptionValuePrice($value)
1203
  {
1204
  if ($value->getPriceType() == 'percent') {
1205
+ $rulePrice = Mage::helper('shopgate/export')->calcProductPriceRule($this->item);
1206
+ if ($rulePrice) {
1207
+ return $rulePrice * ($value->getPrice() / 100);
1208
+ } else {
1209
+ return $this->item->getFinalPrice() * ($value->getPrice() / 100);
1210
+ }
1211
  }
1212
 
1213
  return $value->getPrice();
1223
  return $this->_getOptionValuePrice($value);
1224
  }
1225
 
 
 
 
1226
  public function setChildren()
1227
  {
1228
  $children = array();
1230
  $childProductIds = $this->item->getTypeInstance()->getUsedProductIds();
1231
  foreach ($childProductIds as $child) {
1232
  $configChild = Mage::getModel('catalog/product')
1233
+ ->setStoreId($this->_getConfig()->getStoreViewId())
1234
+ ->load($child);
1235
  if ($configChild->getStatus() != Mage_Catalog_Model_Product_Status::STATUS_DISABLED) {
1236
  $childProducts[] = $configChild;
1237
  }
1242
  $childProductIds = $this->item->getTypeInstance()->getAssociatedProductIds();
1243
  foreach ($childProductIds as $child) {
1244
  $configChild = Mage::getModel('catalog/product')
1245
+ ->setStoreId($this->_getConfig()->getStoreViewId())
1246
+ ->load($child);
1247
  if ($configChild->getStatus() != Mage_Catalog_Model_Product_Status::STATUS_DISABLED) {
1248
  $childProducts[] = $configChild;
1249
  }
1305
  }
1306
 
1307
  /**
1308
+ * Calls array methods one at a time
1309
  */
1310
  public function setFireMethodsForChildren()
1311
  {
1372
  protected function _setBundleOptions($inputs = array())
1373
  {
1374
  $bundleOptions = $this->item->getPriceModel()->getOptions($this->item);
1375
+ $isGross = Mage::getStoreConfig(
1376
+ self::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
1377
+ $this->_getConfig()->getStoreViewId()
1378
+ );
1379
  $stock = parent::getStock();
1380
  $selectionQuantities = array();
1381
 
1394
  $bundleOption->setSelections(array());
1395
  }
1396
 
1397
+ $optionPrices = array();
1398
+ $cheapestOptionId = null;
1399
+ $cheapestPrice = null;
1400
 
1401
+ // fetch id of cheapest option
1402
+ foreach ($bundleOption->getSelections() as $selection) {
1403
+ $selectionPrice = $this->item
1404
+ ->getPriceModel()
1405
+ ->getSelectionFinalPrice($this->item, $selection, 1, $selection->getSelectionQty(), false);
1406
 
1407
+ $selectionPrice = Mage::helper('tax')->getPrice($selection, $selectionPrice, $isGross);
1408
 
1409
+ if ($cheapestPrice === null || $cheapestPrice > $selectionPrice) {
1410
+ $cheapestPrice = $selectionPrice;
1411
+ $cheapestOptionId = $selection->getSelectionId();
1412
+ }
 
 
1413
 
1414
+ $optionPrices[$selection->getSelectionId()] = $selectionPrice;
1415
+ }
1416
 
1417
  foreach ($bundleOption->getSelections() as $selection) {
1418
  $option = new Shopgate_Model_Catalog_Option();
1419
  /** @var $selection Mage_Catalog_Model_Product */
1420
 
1421
+ $selectionId = $selection->getSelectionId();
1422
  $qty = max(1, (int)$selection->getSelectionQty());
1423
  $selectionPrice = $optionPrices[$selectionId];
1424
 
1452
  $option->setLabel($selectionName);
1453
  $option->setSortOrder($selection->getPosition());
1454
 
1455
+ // reset selection price, in this case the bundle parent is already configured
1456
+ // with the price of the cheapest bundle configuration
1457
+ if ($this->item->getPriceType() == Mage_Bundle_Model_Product_Price::PRICE_TYPE_DYNAMIC) {
1458
  if ($cheapestOptionId == $selection->getSelectionId() && $selection->getOption()->getRequired()) {
1459
  $selectionPrice = 0;
1460
  } elseif ($selection->getOption()->getRequired()) {
1461
+ $selectionPrice = $selectionPrice - $optionPrices[$cheapestOptionId];
1462
  }
1463
+ }
1464
 
1465
  $option->setAdditionalPrice($selectionPrice);
1466
  $optionValues[] = $option;
1500
 
1501
  /**
1502
  * @param $price
1503
+ *
1504
  * @return float
1505
  */
1506
  protected function _formatPrice($price)
1507
  {
1508
  if (Mage::app()->getStore()->getCurrentCurrency() && Mage::app()->getStore()->getBaseCurrency()) {
1509
+ $value = Mage::app()->getStore()->getBaseCurrency()->convert(
1510
+ $price, Mage::app()->getStore()->getCurrentCurrency()
1511
+ );
1512
  } else {
1513
  $value = $price;
1514
  }
1515
+
1516
  return $value;
1517
  }
1518
  }
app/code/community/Shopgate/Framework/Model/Export/Settings.php CHANGED
@@ -166,7 +166,12 @@ class Shopgate_Framework_Model_Export_Settings extends Shopgate_Framework_Model_
166
  $shopgatePaymentMethod = array();
167
  $shopgatePaymentMethod['id'] = $code;
168
  $shopgatePaymentMethod['title'] = $methodConfig['title'];
169
- $shopgatePaymentMethod['is_active'] = (int)$methodInstance->isAvailable($emptyQuote);
 
 
 
 
 
170
  $shopgatePaymentMethods[] = $shopgatePaymentMethod;
171
  }
172
  $this->_defaultSettings["payment_methods"] = $shopgatePaymentMethods;
166
  $shopgatePaymentMethod = array();
167
  $shopgatePaymentMethod['id'] = $code;
168
  $shopgatePaymentMethod['title'] = $methodConfig['title'];
169
+ $shopgatePaymentMethod['is_active'] = 0;
170
+ if (isset($methodConfig['active']) && $methodConfig['active'] == 1) {
171
+ $shopgatePaymentMethod['is_active'] = 1;
172
+ } elseif ((int)$methodInstance->isAvailable($emptyQuote) == 1) {
173
+ $shopgatePaymentMethod['is_active'] = 1;
174
+ }
175
  $shopgatePaymentMethods[] = $shopgatePaymentMethod;
176
  }
177
  $this->_defaultSettings["payment_methods"] = $shopgatePaymentMethods;
app/code/community/Shopgate/Framework/Model/Mobile/Redirect.php CHANGED
@@ -241,11 +241,10 @@ class Shopgate_Framework_Model_Mobile_Redirect extends Mage_Core_Model_Abstract
241
  if ($value !== false) {
242
  $jsHeader = unserialize($value);
243
  } else {
244
- $builder = new ShopgateBuilder($this->_config);
245
- $shopgateRedirect = $builder->buildRedirect();
246
 
247
  if (!in_array(
248
- Mage::app()->getRequest()->getControllerName(),
249
  array(
250
  self::CATEGORY,
251
  self::PRODUCT,
@@ -271,7 +270,7 @@ class Shopgate_Framework_Model_Mobile_Redirect extends Mage_Core_Model_Abstract
271
  ',',
272
  Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_DISABLE_REDIRECT_CONTROLLERS)
273
  );
274
- $controllerName = Mage::app()->getRequest()->getControllerName();
275
  if (in_array($controllerName, $disabledControllers)) {
276
  $shopgateRedirect->suppressRedirect();
277
  }
@@ -332,4 +331,137 @@ class Shopgate_Framework_Model_Mobile_Redirect extends Mage_Core_Model_Abstract
332
  }
333
  return $jsHeader;
334
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  }
241
  if ($value !== false) {
242
  $jsHeader = unserialize($value);
243
  } else {
244
+ $shopgateRedirect = $this->_createMobileRedirect($type, $objId);
 
245
 
246
  if (!in_array(
247
+ $type,
248
  array(
249
  self::CATEGORY,
250
  self::PRODUCT,
270
  ',',
271
  Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_DISABLE_REDIRECT_CONTROLLERS)
272
  );
273
+ $controllerName = $type;
274
  if (in_array($controllerName, $disabledControllers)) {
275
  $shopgateRedirect->suppressRedirect();
276
  }
331
  }
332
  return $jsHeader;
333
  }
334
+
335
+
336
+
337
+ /**
338
+ * Get cached header js for redirect or load and save to cache
339
+ *
340
+ * @param $type string
341
+ * @param $objId string|int
342
+ * @param $automaticRedirect
343
+ * @return mixed|string|void
344
+ */
345
+ protected function _createMobileRedirect($type, $objId)
346
+ {
347
+ $builder = new ShopgateBuilder($this->_config);
348
+ $redirectObj = $builder->buildMobileRedirect($_SERVER['HTTP_USER_AGENT'], $_GET, $_COOKIE);
349
+
350
+ try {
351
+ $storeId = $this->_config->getStoreViewId();
352
+ $siteName = Mage::app()->getWebsite()->getName();
353
+ $mobileUrl = $this->_config->getCname();
354
+ $shopUrl = Mage::getStoreConfig("web/unsecure/base_url", $storeId);
355
+
356
+ switch ($type) {
357
+ case self::CATEGORY:
358
+ $pageTitle = Mage::getModel('catalog/category')->setStoreId($storeId)->load($objId)->getName();
359
+ break;
360
+ case self::PRODUCT:
361
+ $pageTitle = Mage::getModel('catalog/product')->setStoreId($storeId)->load($objId)->getName();
362
+ break;
363
+ case self::PAGE:
364
+ $pageTitle = Mage::getModel('cms/page')->setStoreId($storeId)->load($objId)->getTitle();
365
+ break;
366
+ default:
367
+ $pageTitle = $siteName;
368
+ break;
369
+ }
370
+ if (empty($pageTitle)) {
371
+ $pageTitle = $siteName;
372
+ }
373
+
374
+ empty($siteName) ?: $redirectObj->addSiteParameter(
375
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_SITENAME, $siteName);
376
+ empty($shopUrl) ?: $redirectObj->addSiteParameter(
377
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_DESKTOP_URL, $shopUrl);
378
+ empty($mobileUrl) ?: $redirectObj->addSiteParameter(
379
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_MOBILE_WEB_URL, $mobileUrl);
380
+ empty($pageTitle) ?: $redirectObj->addSiteParameter(
381
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_TITLE, $pageTitle);
382
+
383
+ if ($type == self::PRODUCT) {
384
+
385
+ /** @var Mage_Catalog_Model_Product $product */
386
+ $product = Mage::getModel('catalog/product')->setStoreId($storeId)->load($objId);
387
+
388
+ $categoryId = Mage::app()->getRequest()->getParam('category');
389
+ if (!empty($categoryId)) {
390
+ $categoryName = Mage::getModel('catalog/category')->load($categoryId)->getName();
391
+ }
392
+
393
+ $name = $product->getData('name');
394
+ $availableText = $product->isInStock() ? 'instock' : 'oos';
395
+
396
+ $eanAttCode = Mage::getStoreConfig(Shopgate_Framework_Model_Config::XML_PATH_SHOPGATE_EAN_ATTR_CODE, $storeId);
397
+ if (is_object($eanAttCode)) {
398
+ $ean = $product->getData($eanAttCode);
399
+ }
400
+
401
+ $image = $product->getMediaGalleryImages()->getFirstItem();
402
+ if (is_object($image)) {
403
+ $imageUrl = $image->getData('url');
404
+ }
405
+
406
+ $description = $product->getData('short_description');
407
+ if (strlen($description) > 140) {
408
+ $description = substr($description, 0, 136) . ' ...';
409
+ }
410
+
411
+ $price = $product->getData('price');
412
+ $defaultCurrency = Mage::getStoreConfig("currency/options/default", $storeId);
413
+ $baseCurrency = Mage::getStoreConfig("currency/options/base", $storeId);
414
+ if ($defaultCurrency != $baseCurrency) {
415
+ $price = Mage::helper('directory')->currencyConvert($price, $baseCurrency, $defaultCurrency);
416
+ }
417
+ $priceIsGross = Mage::getStoreConfig("tax/calculation/price_includes_tax", $storeId);
418
+ $request = new Varien_Object(
419
+ array(
420
+ 'country_id' => Mage::getStoreConfig("tax/defaults/country", $storeId),
421
+ 'region_id' => Mage::getStoreConfig("tax/defaults/region", $storeId),
422
+ 'postcode' => Mage::getStoreConfig("tax/defaults/postcode", $storeId),
423
+ 'customer_class_id' => Mage::getModel("tax/calculation")->getDefaultCustomerTaxClass($storeId),
424
+ 'product_class_id' => $product->getTaxClassId(),
425
+ 'store' => Mage::app()->getStore($storeId)
426
+ )
427
+ );
428
+
429
+ /** @var Mage_Tax_Model_Calculation $model */
430
+ $taxRate = Mage::getSingleton('tax/calculation')->getRate($request) / 100;
431
+ if ($priceIsGross) {
432
+ $priceNet = round($price / (1 + $taxRate), 2);
433
+ $priceGross = round($price, 2);
434
+ } else {
435
+ $priceNet = round($price, 2);
436
+ $priceGross = round($price * (1 + $taxRate), 2);
437
+ }
438
+
439
+ empty($imageUrl) ?: $redirectObj->addSiteParameter(
440
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_IMAGE, $imageUrl);
441
+ empty($name) ?: $redirectObj->addSiteParameter(
442
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_NAME, $name);
443
+ empty($description) ?: $redirectObj->addSiteParameter(
444
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_DESCRIPTION_SHORT, $description);
445
+ empty($ean) ?: $redirectObj->addSiteParameter(
446
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_EAN, $ean);
447
+ empty($availableText) ?: $redirectObj->addSiteParameter(
448
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_AVAILABILITY, $availableText);
449
+ empty($categoryName) ?: $redirectObj->addSiteParameter(
450
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_CATEGORY, $categoryName);
451
+ empty($priceGross) ?: $redirectObj->addSiteParameter(
452
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_PRICE, $priceGross);
453
+ empty($priceGross) ?: $redirectObj->addSiteParameter(
454
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_CURRENCY, $defaultCurrency);
455
+ empty($priceNet) ?: $redirectObj->addSiteParameter(
456
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_PRETAX_PRICE, $priceNet);
457
+ empty($priceNet) ?: $redirectObj->addSiteParameter(
458
+ Shopgate_Helper_Redirect_TagsGenerator::SITE_PARAMETER_PRODUCT_PRETAX_CURRENCY, $defaultCurrency);
459
+
460
+ }
461
+ } catch (Exception $e) {
462
+ ShopgateLogger::getInstance()->log('error on tag creation for type:' . $type . ' object ID:' . $objId);
463
+ }
464
+
465
+ return $redirectObj;
466
+ }
467
  }
app/code/community/Shopgate/Framework/Model/Observer.php CHANGED
@@ -365,7 +365,8 @@ class Shopgate_Framework_Model_Observer
365
  $cancellationItems = array();
366
  $qtyCancelled = 0;
367
 
368
- $rd = $shopgateOrder->getShopgateOrderObject();
 
369
  $orderItems = $order->getItemsCollection();
370
  $rdItem = false;
371
 
@@ -373,6 +374,12 @@ class Shopgate_Framework_Model_Observer
373
  /** @var $orderItem Mage_Sales_Model_Order_Item */
374
  if ($rd instanceof ShopgateOrder) {
375
  $rdItem = $this->_findItemByProductId($rd->getItems(), $orderItem->getData('product_id'));
 
 
 
 
 
 
376
  }
377
 
378
  if ($orderItem->getProductType() != Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE &&
365
  $cancellationItems = array();
366
  $qtyCancelled = 0;
367
 
368
+ $rd = $shopgateOrder->getShopgateOrderObject();
369
+
370
  $orderItems = $order->getItemsCollection();
371
  $rdItem = false;
372
 
374
  /** @var $orderItem Mage_Sales_Model_Order_Item */
375
  if ($rd instanceof ShopgateOrder) {
376
  $rdItem = $this->_findItemByProductId($rd->getItems(), $orderItem->getData('product_id'));
377
+ } else {
378
+ throw new ShopgateLibraryException(
379
+ ShopgateLibraryException::UNKNOWN_ERROR_CODE,
380
+ "! (#{$orderNumber}) unable to unserialize shopgate order object",
381
+ true
382
+ );
383
  }
384
 
385
  if ($orderItem->getProductType() != Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE &&
app/code/community/Shopgate/Framework/Model/Payment/Pp/Wspp.php CHANGED
@@ -113,7 +113,7 @@ class Shopgate_Framework_Model_Payment_Pp_Wspp
113
  public function manipulateOrderWithPaymentData($order)
114
  {
115
  $paymentInfos = $this->getShopgateOrder()->getPaymentInfos();
116
- $paypalIpnData = json_decode($paymentInfos['paypal_ipn_data'], true);
117
  $paypalIpnData = array_merge($paymentInfos['credit_card'], $paypalIpnData);
118
  $paymentStatus = $this->_getPaymentHelper()->filterPaymentStatus($paypalIpnData['payment_status']);
119
 
113
  public function manipulateOrderWithPaymentData($order)
114
  {
115
  $paymentInfos = $this->getShopgateOrder()->getPaymentInfos();
116
+ $paypalIpnData = $paymentInfos['paypal_ipn_data'];
117
  $paypalIpnData = array_merge($paymentInfos['credit_card'], $paypalIpnData);
118
  $paymentStatus = $this->_getPaymentHelper()->filterPaymentStatus($paypalIpnData['payment_status']);
119
 
app/code/community/Shopgate/Framework/Model/Payment/Router.php CHANGED
@@ -82,20 +82,16 @@ class Shopgate_Framework_Model_Payment_Router extends Shopgate_Framework_Model_P
82
 
83
  /**
84
  * Using payment_method as example - AUTHN_CC.
85
- * If 2nd part, replaces _Router with _Cc,
86
- * else finishes with 1st part to build _Cc_Authn
87
  *
88
  * @return string
89
  */
90
  protected function getClassFromMethod()
91
  {
92
- $endPart = ucfirst(strtolower($this->_getMethodPart()));
93
- $current = get_class($this);
94
- if (strstr($current, 'Router') !== false) {
95
- return str_replace('Router', $endPart, $current);
96
- } else {
97
- return $current . '_' . $endPart;
98
- }
99
  }
100
 
101
  /**
@@ -124,7 +120,7 @@ class Shopgate_Framework_Model_Payment_Router extends Shopgate_Framework_Model_P
124
  protected function _checkAllPossibleModels()
125
  {
126
  $combinations = $this->_getModelCombinations();
127
- $class = str_replace('_Router', '', get_class());
128
  foreach ($combinations as $combination) {
129
  $className = $class . $combination;
130
  $model = Mage::getModel($className, $this->getShopgateOrder());
@@ -171,7 +167,7 @@ class Shopgate_Framework_Model_Payment_Router extends Shopgate_Framework_Model_P
171
  for ($i = 0; $i < sizeof($arr); $i++) {
172
  $arrcopy = $arr;
173
  $elem = array_splice($arrcopy, $i, 1); // removes and returns the i'th element
174
- $temp = $temp_string . "_" . ucfirst($elem[0]);
175
  if (sizeof($arrcopy) > 0) {
176
  $this->depthPicker($arrcopy, $temp, $collect);
177
  } else {
@@ -180,4 +176,16 @@ class Shopgate_Framework_Model_Payment_Router extends Shopgate_Framework_Model_P
180
  }
181
  }
182
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  }
82
 
83
  /**
84
  * Using payment_method as example - AUTHN_CC.
85
+ * Adds _cc to an already resolved shopgate/payment_authn
 
86
  *
87
  * @return string
88
  */
89
  protected function getClassFromMethod()
90
  {
91
+ $endPart = strtolower($this->_getMethodPart());
92
+ $current = $this->getCurrentClassShortName();
93
+
94
+ return $current . '_' . $endPart;
 
 
 
95
  }
96
 
97
  /**
120
  protected function _checkAllPossibleModels()
121
  {
122
  $combinations = $this->_getModelCombinations();
123
+ $class = $this->getCurrentClassShortName();
124
  foreach ($combinations as $combination) {
125
  $className = $class . $combination;
126
  $model = Mage::getModel($className, $this->getShopgateOrder());
167
  for ($i = 0; $i < sizeof($arr); $i++) {
168
  $arrcopy = $arr;
169
  $elem = array_splice($arrcopy, $i, 1); // removes and returns the i'th element
170
+ $temp = $temp_string . "_" . $elem[0];
171
  if (sizeof($arrcopy) > 0) {
172
  $this->depthPicker($arrcopy, $temp, $collect);
173
  } else {
176
  }
177
  }
178
 
179
+ /**
180
+ * Resolves current class name to magento's
181
+ * short class. Truncates Router as well.
182
+ *
183
+ * @return string
184
+ */
185
+ private function getCurrentClassShortName()
186
+ {
187
+ $class = str_replace('Shopgate_Framework_Model_', 'shopgate/', get_class($this));
188
+ $class = preg_replace('/_Router$/', '', $class);
189
+ return strtolower($class);
190
+ }
191
  }
app/code/community/Shopgate/Framework/Model/Shopgate/Plugin.php CHANGED
@@ -91,6 +91,13 @@ class Shopgate_Framework_Model_Shopgate_Plugin extends ShopgatePlugin
91
  $this->_defaultTax = Mage::getModel("tax/calculation")->getDefaultCustomerTaxClass(
92
  $this->_getConfig()->getStoreViewId()
93
  );
 
 
 
 
 
 
 
94
  return true;
95
  }
96
 
@@ -245,10 +252,19 @@ class Shopgate_Framework_Model_Shopgate_Plugin extends ShopgatePlugin
245
  } catch (Exception $e) {
246
  switch ($e->getCode()) {
247
  case Mage_Customer_Model_Customer::EXCEPTION_EMAIL_NOT_CONFIRMED:
248
- throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_CUSTOMER_ACCOUNT_NOT_CONFIRMED);
 
 
 
 
249
  break;
250
  case Mage_Customer_Model_Customer::EXCEPTION_INVALID_EMAIL_OR_PASSWORD:
251
- throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_WRONG_USERNAME_OR_PASSWORD);
 
 
 
 
 
252
  break;
253
  default:
254
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_CUSTOMER_UNKNOWN_ERROR);
@@ -773,9 +789,9 @@ class Shopgate_Framework_Model_Shopgate_Plugin extends ShopgatePlugin
773
  continue;
774
  }
775
  if ($this->useTaxClasses) {
776
- $itemAmount = $item->getUnitAmount();
777
- } else {
778
  $itemAmount = $item->getUnitAmountWithTax();
 
 
779
  }
780
 
781
  $obj = new Varien_Object();
91
  $this->_defaultTax = Mage::getModel("tax/calculation")->getDefaultCustomerTaxClass(
92
  $this->_getConfig()->getStoreViewId()
93
  );
94
+
95
+ $netCountries = $this->_getConfig()->getNetMarketCountries();
96
+ $country = Mage::getStoreConfig("tax/defaults/country", $this->_getConfig()->getStoreViewId());
97
+ if (!in_array($country, $netCountries)) {
98
+ $this->setUseTaxClasses(true);
99
+ }
100
+
101
  return true;
102
  }
103
 
252
  } catch (Exception $e) {
253
  switch ($e->getCode()) {
254
  case Mage_Customer_Model_Customer::EXCEPTION_EMAIL_NOT_CONFIRMED:
255
+ throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_CUSTOMER_ACCOUNT_NOT_CONFIRMED,
256
+ null,
257
+ false,
258
+ false
259
+ );
260
  break;
261
  case Mage_Customer_Model_Customer::EXCEPTION_INVALID_EMAIL_OR_PASSWORD:
262
+ throw new ShopgateLibraryException(
263
+ ShopgateLibraryException::PLUGIN_WRONG_USERNAME_OR_PASSWORD,
264
+ null,
265
+ false,
266
+ false
267
+ );
268
  break;
269
  default:
270
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_CUSTOMER_UNKNOWN_ERROR);
789
  continue;
790
  }
791
  if ($this->useTaxClasses) {
 
 
792
  $itemAmount = $item->getUnitAmountWithTax();
793
+ } else {
794
+ $itemAmount = $item->getUnitAmount();
795
  }
796
 
797
  $obj = new Varien_Object();
app/code/community/Shopgate/Framework/changelog.txt CHANGED
@@ -1,9 +1,22 @@
1
- '''English'''
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  '''Version 2.9.26'''
3
  * Store deletion will not cause shopgate plugin to redirect to 404 page
4
  * Exclude unsupported input types from item export
5
- * Added basic support to 1400-1500 versions
6
- * 1600+ versions are fully supported
7
  * Fix custom description attribute codes
8
  * Shopgate payment orders import with status Processing when shipping is not blocked
9
  * Shopgate payment orders import with Shopgate configuration status when shipping is blocked
1
+ '''Version 2.9.27'''
2
+ * Cleaned up tax export/coupon logic
3
+ * Fixed a bug with custom option percent type calculations
4
+ * Improved recognition of active payment methods in get_settings
5
+ * Custom fields are only added to the order comments in case they are not empty
6
+ * Skip baseprice if DerModPro_BasePrice throws an error
7
+ * Deactivating export of variant prices now includes tierprices
8
+ * Added support for payment model overwriting via config.xml
9
+ * Fixed bug on updating from plugin version 2.8.0
10
+ * Support html_tags for App Linking on the Desktop Website
11
+ * Set_settings: solved issue with saving bools to config
12
+ * Fixed bug in bundled product price option export
13
+ * Add_order: fixed problem with credit card payment (PayPal Website Payments Pro)
14
+ * Improved mobile redirect class to allow better rewrites/adaptions
15
+
16
  '''Version 2.9.26'''
17
  * Store deletion will not cause shopgate plugin to redirect to 404 page
18
  * Exclude unsupported input types from item export
19
+ * Added support to Creativestyle_AmazonPayments in Mage v1.4.0.0+
 
20
  * Fix custom description attribute codes
21
  * Shopgate payment orders import with status Processing when shipping is not blocked
22
  * Shopgate payment orders import with Shopgate configuration status when shipping is blocked
app/code/community/Shopgate/Framework/controllers/FrameworkController.php CHANGED
@@ -86,13 +86,8 @@ class Shopgate_Framework_FrameworkController extends Mage_Core_Controller_Front_
86
  }
87
  Mage::app()->loadArea("adminhtml");
88
  Mage::app()->getTranslator()->init("adminhtml", true);
89
- $netCountries = $config->getNetMarketCountries();
90
- $country = Mage::getStoreConfig("tax/defaults/country", $config->getStoreViewId());
91
- $builder = new ShopgateBuilder($config);
92
- $plugin = Mage::getModel('shopgate/shopgate_plugin', $builder);
93
- if (in_array($country, $netCountries)) {
94
- $plugin->setUseTaxClasses(true);
95
- }
96
  $plugin->handleRequest(Mage::app()->getRequest()->getParams());
97
  } catch (ShopgateLibraryException $e) {
98
  $response = new ShopgatePluginApiResponseAppJson(
86
  }
87
  Mage::app()->loadArea("adminhtml");
88
  Mage::app()->getTranslator()->init("adminhtml", true);
89
+ $builder = new ShopgateBuilder($config);
90
+ $plugin = Mage::getModel('shopgate/shopgate_plugin', $builder);
 
 
 
 
 
91
  $plugin->handleRequest(Mage::app()->getRequest()->getParams());
92
  } catch (ShopgateLibraryException $e) {
93
  $response = new ShopgatePluginApiResponseAppJson(
app/code/community/Shopgate/Framework/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Shopgate_Framework>
5
- <version>2.9.26</version>
6
  </Shopgate_Framework>
7
  </modules>
8
  <phpunit>
2
  <config>
3
  <modules>
4
  <Shopgate_Framework>
5
+ <version>2.9.27</version>
6
  </Shopgate_Framework>
7
  </modules>
8
  <phpunit>
app/code/community/Shopgate/Framework/sql/shopgate_setup/mysql4-upgrade-2.9.4-2.9.5.php CHANGED
@@ -23,6 +23,14 @@
23
 
24
  $this->startSetup();
25
 
 
 
 
 
 
 
 
 
26
  $this->run("
27
  ALTER TABLE `{$this->getTable('shopgate_customer')}`
28
  MODIFY COLUMN id int(10) unsigned NOT NULL AUTO_INCREMENT
23
 
24
  $this->startSetup();
25
 
26
+ $this->run("CREATE TABLE IF NOT EXISTS `{$this->getTable('shopgate/customer')}` (
27
+ `id` int(10) unsigned NOT NULL,
28
+ `customer_id` int(10) unsigned NOT NULL,
29
+ `token` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
30
+ PRIMARY KEY (`id`)
31
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
32
+ ");
33
+
34
  $this->run("
35
  ALTER TABLE `{$this->getTable('shopgate_customer')}`
36
  MODIFY COLUMN id int(10) unsigned NOT NULL AUTO_INCREMENT
lib/Shopgate/assets/js_header.html CHANGED
@@ -1,11 +1,11 @@
1
  <!-- BEGIN SHOPGATE -->
2
- {$link_tag}
3
  <script type="text/javascript">
4
  var _shopgate = new Object();
5
- _shopgate.shop_number = "{$shop_number}";
6
- _shopgate.redirect = "{$redirect_code}";
7
- {$additional_parameters}
8
- _shopgate.host = (("https:" == document.location.protocol) ? "{$ssl_url}" : "{$non_ssl_url}");
9
 
10
  document.write(unescape("%3Cscript src='" + _shopgate.host + "/mobile_header/" + _shopgate.shop_number + ".js' type='text/javascript' %3E%3C/script%3E"));
11
  </script>
1
  <!-- BEGIN SHOPGATE -->
2
+ {link_tags}
3
  <script type="text/javascript">
4
  var _shopgate = new Object();
5
+ _shopgate.shop_number = "{shop_number}";
6
+ _shopgate.redirect = "{redirect_code}";
7
+ {additional_parameters}
8
+ _shopgate.host = (("https:" == document.location.protocol) ? "{ssl_url}" : "{non_ssl_url}");
9
 
10
  document.write(unescape("%3Cscript src='" + _shopgate.host + "/mobile_header/" + _shopgate.shop_number + ".js' type='text/javascript' %3E%3C/script%3E"));
11
  </script>
lib/Shopgate/assets/link_tag.html CHANGED
@@ -1 +1 @@
1
- <link rel="alternate" media="only screen and (max-width: 640px)" href="{$mobile_url}"/>
1
+ <link rel="alternate" media="only screen and (max-width: 640px)" href="{mobile_url}"/>
lib/Shopgate/changelog.txt CHANGED
@@ -1,3 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  '''Version 2.9.33'''
2
  * changed the initial value of the ShopgateDeliveryNote::$shipping_service_id entry to null
3
  * added payment method constant for Paypal Plus
@@ -37,7 +55,7 @@
37
  * added sort order for options and option values
38
 
39
  '''Version 2.9.22'''
40
- * CSV exports: the methods ShopgatePlugin::createCategoriesCsv(), ::createItemsCsv() und ::createReviewsCsv() are now deprecated and not abstract anymore
41
  * removed German changelog
42
  * ShopgateMerchantApi::cancelOrder(): changed default value of parameter "$cancelCompleteOrder" from false to true
43
 
1
+ '''Version 2.9.37'''
2
+ * added outputting open graph and other tags with the mobile redirect if activated in the configuration
3
+ * added a replacement class tree for ShopgateMobileRedirect
4
+ * ShopgateMobileRedirect is now deprecated
5
+
6
+ '''Version 2.9.36'''
7
+ * added a fallback in case that json_encode returns false (failure)
8
+ * added new constant ShopgateLibraryException::CART_ITEM_INVALID_PRODUCT_COMBINATION
9
+ * added a fallback in case that json_encode or json_decode return false (failure)
10
+ * added escaping to the mobile redirect of search queries
11
+
12
+ '''Version 2.9.35'''
13
+ * improved logging of Exception messages
14
+ * deprecated methods now disable themselves when called but not implemented
15
+
16
+ '''Version 2.9.34'''
17
+ * the method ShopgatePlugin::redeemCoupons() is now deprecated and not abstract anymore
18
+
19
  '''Version 2.9.33'''
20
  * changed the initial value of the ShopgateDeliveryNote::$shipping_service_id entry to null
21
  * added payment method constant for Paypal Plus
55
  * added sort order for options and option values
56
 
57
  '''Version 2.9.22'''
58
+ * CSV exports: the methods ShopgatePlugin::createCategoriesCsv(), ::createItemsCsv() and ::createReviewsCsv() are now deprecated and not abstract anymore
59
  * removed German changelog
60
  * ShopgateMerchantApi::cancelOrder(): changed default value of parameter "$cancelCompleteOrder" from false to true
61
 
lib/Shopgate/classes/apis.php CHANGED
@@ -153,7 +153,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
153
  }
154
 
155
  try {
156
- if(!in_array($this->params['action'], $this->authlessActionWhitelist)) {
157
  $this->authService->checkAuthentication();
158
  }
159
 
@@ -166,7 +166,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
166
  $this->setEnablePrintErrorsToLog($this->config->getErrorLogPath());
167
  }
168
 
169
- if(!empty($this->params['use_shutdown_handler'])){
170
  register_shutdown_function('ShopgateShutdownHandler');
171
  }
172
 
@@ -243,9 +243,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
243
  $error = ShopgateLibraryException::MERCHANT_API_ERROR_RECEIVED;
244
  $errortext = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::MERCHANT_API_ERROR_RECEIVED).': "'.$e->getCode() . ' - ' . $e->getMessage().'"';
245
  } catch (Exception $e) {
246
- $message = "\n".get_class($e)."\n";
247
- $message .= 'with code: '.$e->getCode()."\n";
248
- $message .= 'and message: \''.$e->getMessage()."'\n";
249
 
250
  // new ShopgateLibraryException to build proper error message and perform logging
251
  $se = new ShopgateLibraryException($message, null, false, true, $e);
@@ -263,7 +261,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
263
  trigger_error('No response object defined. This should _never_ happen.', E_USER_ERROR);
264
  }
265
 
266
- if(!$this->preventResponseOutput) {
267
  $this->response->setData($this->responseData);
268
  if (empty($this->params['error_reporting']) && ob_get_contents()) {
269
  ob_clean();
@@ -475,7 +473,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
475
  $cart = new ShopgateCart($this->params['cart']);
476
  $couponData = $this->plugin->redeemCoupons($cart);
477
 
478
- if(!is_array($couponData)) {
479
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_WRONG_RESPONSE_FORMAT, 'Plugin Response: '.var_export($couponData, true));
480
  }
481
 
@@ -487,7 +485,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
487
  }
488
 
489
  $responseData = array("external_coupons" => array());
490
- foreach($couponData as $coupon) {
491
  if (!is_object($coupon) || !($coupon instanceof ShopgateExternalCoupon)) {
492
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_WRONG_RESPONSE_FORMAT, 'Plugin Response: '.var_export($coupon, true));
493
  }
@@ -797,7 +795,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
797
  $this->responseData['orders'] = $resOrders;
798
  }
799
 
800
- protected function syncFavouriteList(){
801
  if (!isset($this->params['customer_token'])) {
802
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_NO_CUSTOMER_TOKEN);
803
  }
@@ -902,7 +900,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
902
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_NO_USER_DATA, "missing user_data", true);
903
  }
904
 
905
- if(!$this->config->getEnableGetCustomer()) {
906
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION, "Action 'get_customer' is not activated but is needed by register_customer", true);
907
  }
908
 
@@ -912,9 +910,9 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
912
 
913
  $userData = $this->params["user_data"];
914
 
915
- if(isset($userData['addresses']) && is_array($userData['addresses'])) {
916
  $addresses = array();
917
- foreach($userData['addresses'] as $address) {
918
  $addresses[] = new ShopgateAddress($address);
919
  }
920
  $customer->setAddresses($addresses);
@@ -939,7 +937,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
939
  * @throws ShopgateLibraryException
940
  * @see http://wiki.shopgate.com/Shopgate_Plugin_API_get_media_csv
941
  */
942
- protected function getMediaCsv(){
943
  if (isset($this->params['limit']) && isset($this->params['offset'])) {
944
  $this->plugin->setExportLimit((int) $this->params['limit']);
945
  $this->plugin->setExportOffset((int) $this->params['offset']);
@@ -1202,9 +1200,9 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
1202
  $files[] = $this->config->getRedirectSkipKeywordCachePath();
1203
 
1204
  $errorFiles = array();
1205
- foreach($files as $file){
1206
- if(@file_exists($file) && is_file($file)){
1207
- if(!@unlink($file)){
1208
  $errorFiles[] = $file;
1209
  }
1210
  }
@@ -1227,11 +1225,11 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
1227
  * @see http://wiki.shopgate.com/Shopgate_Plugin_API_receive_authorization
1228
  */
1229
  protected function receiveAuthorization() {
1230
- if($this->config->getSmaAuthServiceClassName() != ShopgateConfigInterface::SHOPGATE_AUTH_SERVICE_CLASS_NAME_OAUTH) {
1231
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_INVALID_ACTION, '=> "receive_authorization" action can only be called for plugins with SMA-AuthService set to "OAuth" type', true);
1232
  }
1233
 
1234
- if(empty($this->params['code'])) {
1235
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_NO_AUTHORIZATION_CODE);
1236
  }
1237
 
@@ -1249,7 +1247,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
1249
 
1250
  // load all shop info via the MerchantAPI and store it in the config (via OAuth and a valid access token)
1251
  $shopInfo = $this->merchantApi->getShopInfo()->getData();
1252
- if(empty($shopInfo)) {
1253
  throw new ShopgateLibraryException(ShopgateLibraryException::MERCHANT_API_INVALID_RESPONSE, '-> "shop info" not set. Response data: '.var_export($shopInfo, true));
1254
  }
1255
 
@@ -1294,7 +1292,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
1294
 
1295
  // the access token needs to be requested first (compute a request target url for this)
1296
  $merchantApiUrl = $this->config->getApiUrl();
1297
- if($this->config->getServer() == 'custom') {
1298
  // defaults to https://<subdomain>.<hostname>/api[controller]/<merchant-action-name> for custom server
1299
  $requestServerHost = explode('/api/', $merchantApiUrl);
1300
  $requestServerHost[0] = str_replace('://api.', "://{$subdomain}.", $requestServerHost[0]);
@@ -1328,7 +1326,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
1328
  'safe_mode'
1329
  );
1330
 
1331
- foreach($settings as $setting) {
1332
  $settingDetails[$setting] = (!empty($allSettings[$setting]))
1333
  ? $allSettings[$setting]
1334
  : 'undefined'
@@ -1422,7 +1420,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
1422
  /**
1423
  * enable error reporting to show exeption on request
1424
  */
1425
- private function setEnableErrorReporting(){
1426
  @error_reporting(E_ERROR | E_CORE_ERROR | E_USER_ERROR);
1427
  @ini_set('display_errors', 1);
1428
  }
@@ -1430,7 +1428,7 @@ class ShopgatePluginApi extends ShopgateObject implements ShopgatePluginApiInter
1430
  /**
1431
  * @param $errorFile
1432
  */
1433
- private function setEnablePrintErrorsToLog($errorFile){
1434
  $logFileHandler = @fopen($errorFile, 'a');
1435
  @fclose($logFileHandler);
1436
  @chmod($errorFile,0777);
@@ -1501,7 +1499,7 @@ class ShopgateMerchantApi extends ShopgateObject implements ShopgateMerchantApiI
1501
  * @throws ShopgateLibraryException in case the connection can't be established, the response is invalid or an error occured.
1502
  */
1503
  protected function sendRequest($parameters = array(), $curlOptOverride = array()) {
1504
- if(!empty($this->shopNumber)) {
1505
  $parameters['shop_number'] = $this->shopNumber;
1506
  }
1507
  $parameters = !empty($parameters)
@@ -1630,7 +1628,7 @@ class ShopgateMerchantApi extends ShopgateObject implements ShopgateMerchantApiI
1630
  ######################################################################
1631
  ## Mobile Redirect ##
1632
  ######################################################################
1633
- /*
1634
  * This method is deprecated, please use getMobileRedirectUserAgents().
1635
  * @deprecated
1636
  */
@@ -1651,7 +1649,7 @@ class ShopgateMerchantApi extends ShopgateObject implements ShopgateMerchantApiI
1651
  $response = $this->sendRequest($request, array(CURLOPT_TIMEOUT => 1));
1652
 
1653
  $responseData = $response->getData();
1654
- if(!isset($responseData["keywords"]) || !isset($responseData["skip_keywords"])) {
1655
  throw new ShopgateLibraryException(ShopgateLibraryException::MERCHANT_API_INVALID_RESPONSE, "\"keyword\" or \"skip_keyword\" is not set. Response: " . var_export($responseData, true));
1656
  }
1657
 
@@ -1881,9 +1879,9 @@ class ShopgateAuthenticationServiceShopgate extends ShopgateObject implements Sh
1881
  }
1882
 
1883
  public function checkAuthentication() {
1884
- if(defined('SHOPGATE_DEBUG') && SHOPGATE_DEBUG === 1) return;
1885
 
1886
- if (empty($_SERVER[self::PHP_X_SHOPGATE_AUTH_USER]) || empty($_SERVER[self::PHP_X_SHOPGATE_AUTH_TOKEN])){
1887
  throw new ShopgateLibraryException(ShopgateLibraryException::AUTHENTICATION_FAILED, 'No authentication data present.');
1888
  }
1889
 
@@ -1958,7 +1956,7 @@ class ShopgateAuthenticationServiceOAuth extends ShopgateObject implements Shopg
1958
  */
1959
  public function setup(ShopgateConfigInterface $config) {
1960
  // needs to check if an old config is present without any access token
1961
- if($config->getCustomerNumber() && $config->getShopNumber() && $config->getApiKey() && !$config->getOauthAccessToken()) {
1962
  // needs to load the non-oauth-url since the new access token needs to be generated using the classic shopgate merchant api authentication
1963
  $apiUrls = $config->getApiUrls();
1964
  $apiUrl = $config->getServer() == 'custom' ? str_replace('/api/merchant2', '/api/merchant', $config->getApiUrl()) : $apiUrls[$config->getServer()][ShopgateConfigInterface::SHOPGATE_AUTH_SERVICE_CLASS_NAME_SHOPGATE];
@@ -1985,7 +1983,7 @@ class ShopgateAuthenticationServiceOAuth extends ShopgateObject implements Shopg
1985
  // save all shop config data to plugin-config using the configs save method
1986
  $config->load($shopgateSettingsNew);
1987
  $config->save(array_keys($shopgateSettingsNew), true);
1988
- } elseif(!$this->accessToken && $config->getOauthAccessToken()) {
1989
  // this would mean the data was somehow not in sync (should no be happening by default)
1990
  $this->accessToken = $config->getOauthAccessToken();
1991
  } else {
@@ -2008,9 +2006,9 @@ class ShopgateAuthenticationServiceOAuth extends ShopgateObject implements Shopg
2008
  }
2009
 
2010
  public function checkAuthentication() {
2011
- if(defined('SHOPGATE_DEBUG') && SHOPGATE_DEBUG === 1) return;
2012
 
2013
- if (empty($_SERVER[self::PHP_X_SHOPGATE_AUTH_USER]) || empty($_SERVER[self::PHP_X_SHOPGATE_AUTH_TOKEN])){
2014
  throw new ShopgateLibraryException(ShopgateLibraryException::AUTHENTICATION_FAILED, 'No authentication data present.');
2015
  }
2016
 
@@ -2072,12 +2070,12 @@ class ShopgateAuthenticationServiceOAuth extends ShopgateObject implements Shopg
2072
  curl_close($curl);
2073
 
2074
  // check the curl-result
2075
- if(!$response) {
2076
  // exception without logging - this might cause spamming your logs and we will know when our API is offline anyways
2077
  throw new ShopgateLibraryException(ShopgateLibraryException::SHOPGATE_OAUTH_NO_CONNECTION, null, false, false);
2078
  }
2079
 
2080
- if(empty($response)) {
2081
  // exception without logging - this might cause spamming your logs and we will know when our API is offline anyways
2082
  throw new ShopgateLibraryException(ShopgateLibraryException::MERCHANT_API_INVALID_RESPONSE, 'Response: '.$response, true, false);
2083
  }
@@ -2086,7 +2084,7 @@ class ShopgateAuthenticationServiceOAuth extends ShopgateObject implements Shopg
2086
 
2087
  // check for valid access token
2088
  $this->accessToken = !empty($decodedResponse['access_token']) ? $decodedResponse['access_token'] : '';
2089
- if(empty($this->accessToken)) {
2090
  throw new ShopgateLibraryException(
2091
  ShopgateLibraryException::SHOPGATE_OAUTH_MISSING_ACCESS_TOKEN,
2092
  ((!empty($decodedResponse['error']) && !empty($decodedResponse['error_description']))
153
  }
154
 
155
  try {
156
+ if (!in_array($this->params['action'], $this->authlessActionWhitelist)) {
157
  $this->authService->checkAuthentication();
158
  }
159
 
166
  $this->setEnablePrintErrorsToLog($this->config->getErrorLogPath());
167
  }
168
 
169
+ if (!empty($this->params['use_shutdown_handler'])) {
170
  register_shutdown_function('ShopgateShutdownHandler');
171
  }
172
 
243
  $error = ShopgateLibraryException::MERCHANT_API_ERROR_RECEIVED;
244
  $errortext = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::MERCHANT_API_ERROR_RECEIVED).': "'.$e->getCode() . ' - ' . $e->getMessage().'"';
245
  } catch (Exception $e) {
246
+ $message = get_class($e) . " with code: {$e->getCode()} and message: '{$e->getMessage()}'";
 
 
247
 
248
  // new ShopgateLibraryException to build proper error message and perform logging
249
  $se = new ShopgateLibraryException($message, null, false, true, $e);
261
  trigger_error('No response object defined. This should _never_ happen.', E_USER_ERROR);
262
  }
263
 
264
+ if (!$this->preventResponseOutput) {
265
  $this->response->setData($this->responseData);
266
  if (empty($this->params['error_reporting']) && ob_get_contents()) {
267
  ob_clean();
473
  $cart = new ShopgateCart($this->params['cart']);
474
  $couponData = $this->plugin->redeemCoupons($cart);
475
 
476
+ if (!is_array($couponData)) {
477
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_WRONG_RESPONSE_FORMAT, 'Plugin Response: '.var_export($couponData, true));
478
  }
479
 
485
  }
486
 
487
  $responseData = array("external_coupons" => array());
488
+ foreach ($couponData as $coupon) {
489
  if (!is_object($coupon) || !($coupon instanceof ShopgateExternalCoupon)) {
490
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_WRONG_RESPONSE_FORMAT, 'Plugin Response: '.var_export($coupon, true));
491
  }
795
  $this->responseData['orders'] = $resOrders;
796
  }
797
 
798
+ protected function syncFavouriteList() {
799
  if (!isset($this->params['customer_token'])) {
800
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_NO_CUSTOMER_TOKEN);
801
  }
900
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_NO_USER_DATA, "missing user_data", true);
901
  }
902
 
903
+ if (!$this->config->getEnableGetCustomer()) {
904
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION, "Action 'get_customer' is not activated but is needed by register_customer", true);
905
  }
906
 
910
 
911
  $userData = $this->params["user_data"];
912
 
913
+ if (isset($userData['addresses']) && is_array($userData['addresses'])) {
914
  $addresses = array();
915
+ foreach ($userData['addresses'] as $address) {
916
  $addresses[] = new ShopgateAddress($address);
917
  }
918
  $customer->setAddresses($addresses);
937
  * @throws ShopgateLibraryException
938
  * @see http://wiki.shopgate.com/Shopgate_Plugin_API_get_media_csv
939
  */
940
+ protected function getMediaCsv() {
941
  if (isset($this->params['limit']) && isset($this->params['offset'])) {
942
  $this->plugin->setExportLimit((int) $this->params['limit']);
943
  $this->plugin->setExportOffset((int) $this->params['offset']);
1200
  $files[] = $this->config->getRedirectSkipKeywordCachePath();
1201
 
1202
  $errorFiles = array();
1203
+ foreach ($files as $file) {
1204
+ if (@file_exists($file) && is_file($file)) {
1205
+ if (!@unlink($file)) {
1206
  $errorFiles[] = $file;
1207
  }
1208
  }
1225
  * @see http://wiki.shopgate.com/Shopgate_Plugin_API_receive_authorization
1226
  */
1227
  protected function receiveAuthorization() {
1228
+ if ($this->config->getSmaAuthServiceClassName() != ShopgateConfigInterface::SHOPGATE_AUTH_SERVICE_CLASS_NAME_OAUTH) {
1229
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_INVALID_ACTION, '=> "receive_authorization" action can only be called for plugins with SMA-AuthService set to "OAuth" type', true);
1230
  }
1231
 
1232
+ if (empty($this->params['code'])) {
1233
  throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_NO_AUTHORIZATION_CODE);
1234
  }
1235
 
1247
 
1248
  // load all shop info via the MerchantAPI and store it in the config (via OAuth and a valid access token)
1249
  $shopInfo = $this->merchantApi->getShopInfo()->getData();
1250
+ if (empty($shopInfo)) {
1251
  throw new ShopgateLibraryException(ShopgateLibraryException::MERCHANT_API_INVALID_RESPONSE, '-> "shop info" not set. Response data: '.var_export($shopInfo, true));
1252
  }
1253
 
1292
 
1293
  // the access token needs to be requested first (compute a request target url for this)
1294
  $merchantApiUrl = $this->config->getApiUrl();
1295
+ if ($this->config->getServer() == 'custom') {
1296
  // defaults to https://<subdomain>.<hostname>/api[controller]/<merchant-action-name> for custom server
1297
  $requestServerHost = explode('/api/', $merchantApiUrl);
1298
  $requestServerHost[0] = str_replace('://api.', "://{$subdomain}.", $requestServerHost[0]);
1326
  'safe_mode'
1327
  );
1328
 
1329
+ foreach ($settings as $setting) {
1330
  $settingDetails[$setting] = (!empty($allSettings[$setting]))
1331
  ? $allSettings[$setting]
1332
  : 'undefined'
1420
  /**
1421
  * enable error reporting to show exeption on request
1422
  */
1423
+ private function setEnableErrorReporting() {
1424
  @error_reporting(E_ERROR | E_CORE_ERROR | E_USER_ERROR);
1425
  @ini_set('display_errors', 1);
1426
  }
1428
  /**
1429
  * @param $errorFile
1430
  */
1431
+ private function setEnablePrintErrorsToLog($errorFile) {
1432
  $logFileHandler = @fopen($errorFile, 'a');
1433
  @fclose($logFileHandler);
1434
  @chmod($errorFile,0777);
1499
  * @throws ShopgateLibraryException in case the connection can't be established, the response is invalid or an error occured.
1500
  */
1501
  protected function sendRequest($parameters = array(), $curlOptOverride = array()) {
1502
+ if (!empty($this->shopNumber)) {
1503
  $parameters['shop_number'] = $this->shopNumber;
1504
  }
1505
  $parameters = !empty($parameters)
1628
  ######################################################################
1629
  ## Mobile Redirect ##
1630
  ######################################################################
1631
+ /**
1632
  * This method is deprecated, please use getMobileRedirectUserAgents().
1633
  * @deprecated
1634
  */
1649
  $response = $this->sendRequest($request, array(CURLOPT_TIMEOUT => 1));
1650
 
1651
  $responseData = $response->getData();
1652
+ if (!isset($responseData["keywords"]) || !isset($responseData["skip_keywords"])) {
1653
  throw new ShopgateLibraryException(ShopgateLibraryException::MERCHANT_API_INVALID_RESPONSE, "\"keyword\" or \"skip_keyword\" is not set. Response: " . var_export($responseData, true));
1654
  }
1655
 
1879
  }
1880
 
1881
  public function checkAuthentication() {
1882
+ if (defined('SHOPGATE_DEBUG') && SHOPGATE_DEBUG === 1) return;
1883
 
1884
+ if (empty($_SERVER[self::PHP_X_SHOPGATE_AUTH_USER]) || empty($_SERVER[self::PHP_X_SHOPGATE_AUTH_TOKEN])) {
1885
  throw new ShopgateLibraryException(ShopgateLibraryException::AUTHENTICATION_FAILED, 'No authentication data present.');
1886
  }
1887
 
1956
  */
1957
  public function setup(ShopgateConfigInterface $config) {
1958
  // needs to check if an old config is present without any access token
1959
+ if ($config->getCustomerNumber() && $config->getShopNumber() && $config->getApiKey() && !$config->getOauthAccessToken()) {
1960
  // needs to load the non-oauth-url since the new access token needs to be generated using the classic shopgate merchant api authentication
1961
  $apiUrls = $config->getApiUrls();
1962
  $apiUrl = $config->getServer() == 'custom' ? str_replace('/api/merchant2', '/api/merchant', $config->getApiUrl()) : $apiUrls[$config->getServer()][ShopgateConfigInterface::SHOPGATE_AUTH_SERVICE_CLASS_NAME_SHOPGATE];
1983
  // save all shop config data to plugin-config using the configs save method
1984
  $config->load($shopgateSettingsNew);
1985
  $config->save(array_keys($shopgateSettingsNew), true);
1986
+ } elseif (!$this->accessToken && $config->getOauthAccessToken()) {
1987
  // this would mean the data was somehow not in sync (should no be happening by default)
1988
  $this->accessToken = $config->getOauthAccessToken();
1989
  } else {
2006
  }
2007
 
2008
  public function checkAuthentication() {
2009
+ if (defined('SHOPGATE_DEBUG') && SHOPGATE_DEBUG === 1) return;
2010
 
2011
+ if (empty($_SERVER[self::PHP_X_SHOPGATE_AUTH_USER]) || empty($_SERVER[self::PHP_X_SHOPGATE_AUTH_TOKEN])) {
2012
  throw new ShopgateLibraryException(ShopgateLibraryException::AUTHENTICATION_FAILED, 'No authentication data present.');
2013
  }
2014
 
2070
  curl_close($curl);
2071
 
2072
  // check the curl-result
2073
+ if (!$response) {
2074
  // exception without logging - this might cause spamming your logs and we will know when our API is offline anyways
2075
  throw new ShopgateLibraryException(ShopgateLibraryException::SHOPGATE_OAUTH_NO_CONNECTION, null, false, false);
2076
  }
2077
 
2078
+ if (empty($response)) {
2079
  // exception without logging - this might cause spamming your logs and we will know when our API is offline anyways
2080
  throw new ShopgateLibraryException(ShopgateLibraryException::MERCHANT_API_INVALID_RESPONSE, 'Response: '.$response, true, false);
2081
  }
2084
 
2085
  // check for valid access token
2086
  $this->accessToken = !empty($decodedResponse['access_token']) ? $decodedResponse['access_token'] : '';
2087
+ if (empty($this->accessToken)) {
2088
  throw new ShopgateLibraryException(
2089
  ShopgateLibraryException::SHOPGATE_OAUTH_MISSING_ACCESS_TOKEN,
2090
  ((!empty($decodedResponse['error']) && !empty($decodedResponse['error_description']))
lib/Shopgate/classes/configuration.php CHANGED
@@ -484,6 +484,11 @@ class ShopgateConfig extends ShopgateContainer implements ShopgateConfigInterfac
484
  * @var array<int, string> an array with a list of get params which are allowed to passthrough to the mobile device on redirect
485
  */
486
  protected $redirectable_get_params = array();
 
 
 
 
 
487
 
488
  /**
489
  * @var int execution time limit for file export in seconds
@@ -598,6 +603,7 @@ class ShopgateConfig extends ShopgateContainer implements ShopgateConfigInterfac
598
 
599
  $this->is_shopgate_adapter = false;
600
  $this->redirectable_get_params = array('gclid', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content');
 
601
 
602
  $this->default_memory_limit = ShopgateConfigInterface::DEFAULT_MEMORY_LIMIT;
603
  $this->default_execution_time = ShopgateConfigInterface::DEFAULT_EXECUTION_TIME;
@@ -1371,17 +1377,15 @@ class ShopgateConfig extends ShopgateContainer implements ShopgateConfigInterfac
1371
  public function getRedirectableGetParams() {
1372
  return $this->redirectable_get_params;
1373
  }
 
 
 
 
1374
 
1375
- /**
1376
- * @return int
1377
- */
1378
  public function getDefaultExecutionTime() {
1379
  return $this->default_execution_time;
1380
  }
1381
 
1382
- /**
1383
- * @return int
1384
- */
1385
  public function getDefaultMemoryLimit() {
1386
  return $this->default_memory_limit;
1387
  }
@@ -1854,7 +1858,11 @@ class ShopgateConfig extends ShopgateContainer implements ShopgateConfigInterfac
1854
  }
1855
 
1856
  public function setRedirectableGetParams($value) {
1857
- return $this->redirectable_get_params = $value;
 
 
 
 
1858
  }
1859
 
1860
  /**
@@ -2956,7 +2964,17 @@ interface ShopgateConfigInterface {
2956
  * @return bool True if the plugin is an adapter between Shopgate's and a third-party-API and servers multiple shops on both ends.
2957
  */
2958
  public function getIsShopgateAdapter();
2959
-
 
 
 
 
 
 
 
 
 
 
2960
  /**
2961
  * @return int maximum execution time in seconds
2962
  */
@@ -3428,6 +3446,16 @@ interface ShopgateConfigInterface {
3428
  * @param bool $value True if the plugin is an adapter between Shopgate's and a third-party-API and servers multiple shops on both ends.
3429
  */
3430
  public function setIsShopgateAdapter($value);
 
 
 
 
 
 
 
 
 
 
3431
 
3432
  /**
3433
  * @param $default_execution_time int set value for maximum execution time in seconds
484
  * @var array<int, string> an array with a list of get params which are allowed to passthrough to the mobile device on redirect
485
  */
486
  protected $redirectable_get_params = array();
487
+
488
+ /**
489
+ * @var string A JSON encoded string containing the HTML tags to be placed on the desktop website.
490
+ */
491
+ protected $html_tags;
492
 
493
  /**
494
  * @var int execution time limit for file export in seconds
603
 
604
  $this->is_shopgate_adapter = false;
605
  $this->redirectable_get_params = array('gclid', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content');
606
+ $this->html_tags = '';
607
 
608
  $this->default_memory_limit = ShopgateConfigInterface::DEFAULT_MEMORY_LIMIT;
609
  $this->default_execution_time = ShopgateConfigInterface::DEFAULT_EXECUTION_TIME;
1377
  public function getRedirectableGetParams() {
1378
  return $this->redirectable_get_params;
1379
  }
1380
+
1381
+ public function getHtmlTags() {
1382
+ return $this->html_tags;
1383
+ }
1384
 
 
 
 
1385
  public function getDefaultExecutionTime() {
1386
  return $this->default_execution_time;
1387
  }
1388
 
 
 
 
1389
  public function getDefaultMemoryLimit() {
1390
  return $this->default_memory_limit;
1391
  }
1858
  }
1859
 
1860
  public function setRedirectableGetParams($value) {
1861
+ $this->redirectable_get_params = $value;
1862
+ }
1863
+
1864
+ public function setHtmlTags($value) {
1865
+ $this->html_tags = $value;
1866
  }
1867
 
1868
  /**
2964
  * @return bool True if the plugin is an adapter between Shopgate's and a third-party-API and servers multiple shops on both ends.
2965
  */
2966
  public function getIsShopgateAdapter();
2967
+
2968
+ /**
2969
+ * @return array<int, string> an array with a list of get params which are allowed to passthrough to the mobile device on redirect
2970
+ */
2971
+ public function getRedirectableGetParams();
2972
+
2973
+ /**
2974
+ * @return string A JSON encoded string containing the HTML tags to be placed on the desktop website.
2975
+ */
2976
+ public function getHtmlTags();
2977
+
2978
  /**
2979
  * @return int maximum execution time in seconds
2980
  */
3446
  * @param bool $value True if the plugin is an adapter between Shopgate's and a third-party-API and servers multiple shops on both ends.
3447
  */
3448
  public function setIsShopgateAdapter($value);
3449
+
3450
+ /**
3451
+ * @param array<int, string> $value an array with a list of get params which are allowed to passthrough to the mobile device on redirect
3452
+ */
3453
+ public function setRedirectableGetParams($value);
3454
+
3455
+ /**
3456
+ * @param string $value A JSON encoded string containing the HTML tags to be placed on the desktop website.
3457
+ */
3458
+ public function setHtmlTags($value);
3459
 
3460
  /**
3461
  * @param $default_execution_time int set value for maximum execution time in seconds
lib/Shopgate/classes/core.php CHANGED
@@ -24,7 +24,7 @@
24
  ###################################################################################
25
  # define constants
26
  ###################################################################################
27
- define('SHOPGATE_LIBRARY_VERSION', '2.9.33');
28
  define('SHOPGATE_LIBRARY_ENCODING' , 'UTF-8');
29
  define('SHOPGATE_BASE_DIR', realpath(dirname(__FILE__).'/../'));
30
 
@@ -69,9 +69,9 @@ function shopgateGetErrorType($type) {
69
  * register shutdown handler
70
  * @see http://de1.php.net/manual/en/function.register-shutdown-function.php
71
  */
72
- function ShopgateShutdownHandler(){
73
 
74
- if (function_exists("error_get_last")){
75
  if (!is_null($e = error_get_last())) {
76
  $type = shopgateGetErrorType($e['type']);
77
  ShopgateLogger::getInstance()->log("{$e['message']} \n {$e['file']} : [{$e['line']}] , Type: {$type}", ShopgateLogger::LOGTYPE_ERROR);
@@ -236,7 +236,8 @@ class ShopgateLibraryException extends Exception {
236
  const CART_ITEM_INPUT_VALIDATION_FAILED = 303;
237
  const CART_ITEM_REQUESTED_QUANTITY_UNDER_MINIMUM_QUANTITY = 304;
238
  const CART_ITEM_REQUESTED_QUANTITY_OVER_MAXIMUM_QUANTITY = 305;
239
-
 
240
  //Helper class exception
241
  const SHOPGATE_HELPER_FUNCTION_NOT_FOUND_EXCEPTION = 310;
242
 
@@ -342,6 +343,7 @@ class ShopgateLibraryException extends Exception {
342
  self::CART_ITEM_INPUT_VALIDATION_FAILED => 'product input validation failed',
343
  self::CART_ITEM_REQUESTED_QUANTITY_UNDER_MINIMUM_QUANTITY => 'requested quantity is lower than required minimum quantity',
344
  self::CART_ITEM_REQUESTED_QUANTITY_OVER_MAXIMUM_QUANTITY => 'requested quantity is higher than allowed maximum quantity',
 
345
 
346
  // Authentication errors
347
  self::AUTHENTICATION_FAILED => 'authentication failed',
@@ -374,29 +376,33 @@ class ShopgateLibraryException extends Exception {
374
  $code = self::UNKNOWN_ERROR_CODE;
375
  }
376
 
377
- if ($appendAdditionalInformationToMessage){
378
- $message .= ': '.$additionalInformation;
379
- }
380
-
381
  // Save additional information
382
  $this->additionalInformation = $additionalInformation;
383
-
 
 
 
 
 
 
 
384
 
385
  // in case of multiple errors the message should not have any other text attached to it
386
  if ($code == self::MULTIPLE_ERRORS) {
387
- $message = $additionalInformation;
 
388
  }
389
 
390
  // Call default Exception class constructor
391
- if (method_exists($this, 'getPrevious')) {
392
- // The "previous" argument was introduced 5.3
393
  parent::__construct($message, $code, $previous);
394
  } else {
395
  parent::__construct($message, $code);
396
  }
397
 
398
  // Log the error
399
- $logMessage = $this->buildLogMessage($additionalInformation);
400
  if (empty($writeLog)) {
401
  $this->message .= ' (logging disabled for this message)';
402
  } else {
@@ -443,67 +449,57 @@ class ShopgateLibraryException extends Exception {
443
  * @deprecated
444
  */
445
  public static function buildLogMessageFor($code, $additionalInformation) {
446
- $logMessage = self::getMessageFor($code);
447
-
448
- // Set additional information
449
- if (!empty($additionalInformation)) {
450
- $logMessage .= ' - Additional information: "'.$additionalInformation.'"';
451
- }
452
-
453
- $logMessage .= "\n\t";
454
-
455
- // Add tracing information to the message
456
- $btrace = debug_backtrace();
457
- for ($i = 1; $i < 6; $i++) {
458
- if (empty($btrace[$i+1])) break;
459
-
460
- $class = (isset($btrace[$i+1]['class'])) ? $btrace[$i+1]['class'].'::' : 'Unknown class - ';
461
- $function = (isset($btrace[$i+1]['function'])) ? $btrace[$i+1]['function'] : 'Unknown function';
462
- $file = ' in '.((isset($btrace[$i]['file'])) ? basename($btrace[$i]['file']) : 'Unknown file');
463
- $line = (isset($btrace[$i]['line'])) ? $btrace[$i]['line'] : 'Unknown line';
464
- $logMessage .= $class.$function.'()'.$file.':'.$line."\n\t";
465
- }
466
-
467
- return $logMessage;
468
  }
469
 
470
  /**
471
- * Builds the message that would be logged if a ShopgateLibraryException was thrown with the same parameters and returns it.
472
  *
473
- * This is a convenience method for cases where logging is desired but the script should not abort. By using this function an empty
474
- * try-catch-statement can be avoided. Just pass the returned string to ShopgateLogger::log().
475
- *
476
- * @param string $additionalInformation More detailed information on what exactly went wrong.
477
  * @return string
478
  */
479
- public function buildLogMessage($additionalInformation) {
480
- $logMessage = self::getMessageFor($this->getCode());
481
 
482
- // Set additional information
483
- if (!empty($additionalInformation)) {
484
- $logMessage .= ' - Additional information: "'.$additionalInformation.'"';
485
  }
486
 
487
  $logMessage .= "\n";
488
 
489
  // Add tracing information to the message
490
- if (method_exists($this, 'getPrevious') && $this->getPrevious()) {
491
- $trace = $this->getPrevious()->getTraceAsString();
492
- } else {
493
- $trace = $this->getTraceAsString();
494
- }
495
- $lines = explode("\n", $trace);
 
 
 
496
  $i = 0;
497
- foreach ($lines as $line) {
498
  $i++;
499
  if ($i > 20) {
500
  $logMessage .= "\t(...)";
501
  break;
502
  }
503
- $logMessage .= "\t$line\n";
504
  }
505
  return $logMessage;
506
  }
 
 
 
 
 
 
 
 
 
 
 
 
507
  }
508
 
509
  /**
@@ -1077,16 +1073,81 @@ class ShopgateBuilder {
1077
  * Builds the Shopgate Library object graph for Shopgate mobile redirect and returns the instance.
1078
  *
1079
  * @return ShopgateMobileRedirect
 
 
1080
  */
1081
  public function buildRedirect() {
1082
  $merchantApi = $this->buildMerchantApi();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1083
  $redirect = new ShopgateMobileRedirect(
1084
  $this->config,
1085
- $merchantApi
 
1086
  );
1087
 
1088
  return $redirect;
1089
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1090
  }
1091
 
1092
  /**
@@ -1144,8 +1205,8 @@ abstract class ShopgateObject {
1144
  * @return null|Shopgate_Helper_DataStructure|Shopgate_Helper_Pricing|Shopgate_Helper_String returns the requested helper instance or null
1145
  * @throws ShopgateLibraryException
1146
  */
1147
- protected function getHelper($helperName){
1148
- if(array_key_exists($helperName,$this->helperClassInstances)) {
1149
  $helperClassName = "Shopgate_Helper_" . $helperName;
1150
  if (!isset($this->helperClassInstances[$helperClassName])) {
1151
  $this->helperClassInstances[$helperClassName] = new $helperClassName();
@@ -1206,12 +1267,15 @@ abstract class ShopgateObject {
1206
  public function jsonEncode($value) {
1207
  // if json_encode exists use that
1208
  if (extension_loaded('json') && function_exists('json_encode')) {
1209
- return json_encode($value);
 
 
 
1210
  }
1211
 
1212
  // if not check if external class is loaded
1213
  if (!class_exists('sgServicesJSON')) {
1214
- require_once dirname(__FILE__).'/../vendors/JSON.php';
1215
  }
1216
 
1217
  // encode via external class
@@ -1231,7 +1295,10 @@ abstract class ShopgateObject {
1231
  public function jsonDecode($json, $assoc = false) {
1232
  // if json_decode exists use that
1233
  if (extension_loaded('json') && function_exists('json_decode')) {
1234
- return json_decode($json, $assoc);
 
 
 
1235
  }
1236
 
1237
  // if not check if external class is loaded
@@ -1330,7 +1397,7 @@ abstract class ShopgateObject {
1330
  * @param int $depth
1331
  * @param array $refChain
1332
  */
1333
- protected function user_print_r($subject, $ignore = array(), $depth = 1, $refChain = array()){
1334
  static $maxDepth = 5;
1335
  if ($depth > 20) return;
1336
  if (is_object($subject)) {
@@ -1351,7 +1418,7 @@ abstract class ShopgateObject {
1351
  } else
1352
  echo $key;
1353
  echo '] => ';
1354
- if($depth == $maxDepth){
1355
  return;
1356
  }
1357
  $this->user_print_r($val, $ignore, $depth + 1, $refChain);
@@ -1363,7 +1430,7 @@ abstract class ShopgateObject {
1363
  foreach ($subject as $key => $val) {
1364
  if (is_array($ignore) && !in_array($key, $ignore, 1)) {
1365
  echo str_repeat(" ", $depth * 4) . '[' . $key . '] => ';
1366
- if($depth==$maxDepth){
1367
  return;
1368
  }
1369
  $this->user_print_r($val, $ignore, $depth + 1, $refChain);
@@ -1609,9 +1676,9 @@ abstract class ShopgatePlugin extends ShopgateObject {
1609
 
1610
  // find all settings that start with "enable_" in the config-value-name and collect all active ones
1611
  $searchKeyPart = 'enable_';
1612
- foreach($configValues as $key => $val) {
1613
- if(substr($key, 0, strlen($searchKeyPart)) == $searchKeyPart) {
1614
- if($val) {
1615
  $enabledActionsList[$key] = $val;
1616
  }
1617
  }
@@ -1907,7 +1974,7 @@ abstract class ShopgatePlugin extends ShopgateObject {
1907
  *
1908
  * @see http://wiki.shopgate.com/CSV_File_Items/
1909
  */
1910
- protected function useTaxClasses(){
1911
  $this->useTaxClasses = true;
1912
  }
1913
 
@@ -1952,13 +2019,13 @@ abstract class ShopgatePlugin extends ShopgateObject {
1952
  'item_name' => "",
1953
  );
1954
 
1955
- if($this->useTaxClasses){
1956
  $tax = array(
1957
  'unit_amount_net' => "",
1958
  'tax_class' => "",
1959
  'old_unit_amount_net' => "",
1960
  );
1961
- }else{
1962
  $tax = array(
1963
  'unit_amount' => "",
1964
  'tax_percent' => "",
@@ -2188,10 +2255,10 @@ abstract class ShopgatePlugin extends ShopgateObject {
2188
  private final function getCreateCsvLoaders($subjectName) {
2189
  $actions = array();
2190
  $subjectName = trim($subjectName);
2191
- if(!empty($subjectName)) {
2192
  $methodName = 'buildDefault'.$this->camelize($subjectName, true).'Row';
2193
- if(method_exists($this, $methodName)) {
2194
- foreach(array_keys($this->{$methodName}() ) as $sKey) {
2195
  $actions[] = $subjectName."Export" . $this->camelize($sKey, true);
2196
  }
2197
  }
@@ -2241,6 +2308,17 @@ abstract class ShopgatePlugin extends ShopgateObject {
2241
  protected function getCreateReviewsCsvLoaders() {
2242
  return $this->getCreateCsvLoaders("review");
2243
  }
 
 
 
 
 
 
 
 
 
 
 
2244
 
2245
  #################################################################################
2246
  ## Following methods are the callbacks that need to be implemented by plugins. ##
@@ -2300,11 +2378,11 @@ abstract class ShopgatePlugin extends ShopgateObject {
2300
  'item_count' => 0,
2301
  );
2302
 
2303
- if($this->config->getEnableGetReviewsCsv()) {
2304
  $shopInfo['review_count'] = 0;
2305
  }
2306
 
2307
- if($this->config->getEnableGetMediaCsv()) {
2308
  $shopInfo['media_count'] = array();
2309
  }
2310
 
@@ -2385,8 +2463,18 @@ abstract class ShopgatePlugin extends ShopgateObject {
2385
  * @param ShopgateCart $cart The ShopgateCart object containing the coupons that should be redeemed.
2386
  * @return array('external_coupons' => ShopgateExternalCoupon[])
2387
  * @throws ShopgateLibraryException if an error occurs.
 
 
2388
  */
2389
- public abstract function redeemCoupons(ShopgateCart $cart);
 
 
 
 
 
 
 
 
2390
 
2391
  /**
2392
  * Checks the content of a cart to be valid and returns necessary changes if applicable.
@@ -2455,6 +2543,7 @@ abstract class ShopgatePlugin extends ShopgateObject {
2455
  * @deprecated Use createItems().
2456
  */
2457
  protected function createItemsCsv(){
 
2458
  throw new ShopgateLibraryException(
2459
  ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION,
2460
  'The requested action is not disabled but has not been implemented in this plugin.',
@@ -2490,6 +2579,7 @@ abstract class ShopgatePlugin extends ShopgateObject {
2490
  * @deprecated Use createCategories().
2491
  */
2492
  protected function createCategoriesCsv() {
 
2493
  throw new ShopgateLibraryException(
2494
  ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION,
2495
  'The requested action is not disabled but has not been implemented in this plugin.',
@@ -2512,6 +2602,7 @@ abstract class ShopgatePlugin extends ShopgateObject {
2512
  * @deprecated Use createReviews().
2513
  */
2514
  protected function createReviewsCsv() {
 
2515
  throw new ShopgateLibraryException(
2516
  ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION,
2517
  'The requested action is not disabled but has not been implemented in this plugin.',
@@ -2916,10 +3007,10 @@ abstract class ShopgateContainer extends ShopgateObject {
2916
  * @param $whitelist
2917
  * @return bool
2918
  */
2919
- public function compare($obj,$obj2,$whitelist){
2920
 
2921
- foreach($whitelist as $acceptedField){
2922
- if($obj->{$this->camelize('get_'.$acceptedField)}() != $obj2->{$this->camelize('get_'.$acceptedField)}()){
2923
  return false;
2924
  }
2925
  }
24
  ###################################################################################
25
  # define constants
26
  ###################################################################################
27
+ define('SHOPGATE_LIBRARY_VERSION', '2.9.38');
28
  define('SHOPGATE_LIBRARY_ENCODING' , 'UTF-8');
29
  define('SHOPGATE_BASE_DIR', realpath(dirname(__FILE__).'/../'));
30
 
69
  * register shutdown handler
70
  * @see http://de1.php.net/manual/en/function.register-shutdown-function.php
71
  */
72
+ function ShopgateShutdownHandler() {
73
 
74
+ if (function_exists("error_get_last")) {
75
  if (!is_null($e = error_get_last())) {
76
  $type = shopgateGetErrorType($e['type']);
77
  ShopgateLogger::getInstance()->log("{$e['message']} \n {$e['file']} : [{$e['line']}] , Type: {$type}", ShopgateLogger::LOGTYPE_ERROR);
236
  const CART_ITEM_INPUT_VALIDATION_FAILED = 303;
237
  const CART_ITEM_REQUESTED_QUANTITY_UNDER_MINIMUM_QUANTITY = 304;
238
  const CART_ITEM_REQUESTED_QUANTITY_OVER_MAXIMUM_QUANTITY = 305;
239
+ const CART_ITEM_INVALID_PRODUCT_COMBINATION = 306;
240
+
241
  //Helper class exception
242
  const SHOPGATE_HELPER_FUNCTION_NOT_FOUND_EXCEPTION = 310;
243
 
343
  self::CART_ITEM_INPUT_VALIDATION_FAILED => 'product input validation failed',
344
  self::CART_ITEM_REQUESTED_QUANTITY_UNDER_MINIMUM_QUANTITY => 'requested quantity is lower than required minimum quantity',
345
  self::CART_ITEM_REQUESTED_QUANTITY_OVER_MAXIMUM_QUANTITY => 'requested quantity is higher than allowed maximum quantity',
346
+ self::CART_ITEM_INVALID_PRODUCT_COMBINATION => 'products can not be ordered together',
347
 
348
  // Authentication errors
349
  self::AUTHENTICATION_FAILED => 'authentication failed',
376
  $code = self::UNKNOWN_ERROR_CODE;
377
  }
378
 
 
 
 
 
379
  // Save additional information
380
  $this->additionalInformation = $additionalInformation;
381
+
382
+ if ($appendAdditionalInformationToMessage) {
383
+ $message .= ': ' . $this->additionalInformation;
384
+ }
385
+
386
+ // We ALWAYS want to append the additional information for logging. So if it has already been appended here,
387
+ // it doesn't have to be appended again later.
388
+ $appendAdditionalInformationToLog = !$appendAdditionalInformationToMessage;
389
 
390
  // in case of multiple errors the message should not have any other text attached to it
391
  if ($code == self::MULTIPLE_ERRORS) {
392
+ $message = $this->additionalInformation;
393
+ $appendAdditionalInformationToLog = false;
394
  }
395
 
396
  // Call default Exception class constructor
397
+ if (method_exists(get_parent_class(), 'getPrevious')) {
398
+ // The "previous" argument was introduced in PHP 5.3
399
  parent::__construct($message, $code, $previous);
400
  } else {
401
  parent::__construct($message, $code);
402
  }
403
 
404
  // Log the error
405
+ $logMessage = $this->buildLogMessage($appendAdditionalInformationToLog);
406
  if (empty($writeLog)) {
407
  $this->message .= ' (logging disabled for this message)';
408
  } else {
449
  * @deprecated
450
  */
451
  public static function buildLogMessageFor($code, $additionalInformation) {
452
+ $e = new ShopgateLibraryException($code, $additionalInformation, false, false);
453
+ return $e->buildLogMessage();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
454
  }
455
 
456
  /**
457
+ * Builds the message that will be logged to the error log.
458
  *
 
 
 
 
459
  * @return string
460
  */
461
+ protected function buildLogMessage($appendAdditionalInformation = true) {
462
+ $logMessage = $this->getMessage();
463
 
464
+ if ($appendAdditionalInformation && !empty($this->additionalInformation)) {
465
+ $logMessage .= ': ' . $this->additionalInformation;
 
466
  }
467
 
468
  $logMessage .= "\n";
469
 
470
  // Add tracing information to the message
471
+
472
+ $previous = $this->getPreviousException();
473
+ $trace = $previous ? $previous->getTraceAsString() : $this->getTraceAsString();
474
+ $line = $previous ? $previous->getLine() : $this->getLine();
475
+ $file = $previous ? $previous->getFile() : $this->getFile();
476
+ $class = $previous ? get_class($previous) : get_class($this);
477
+
478
+ $traceLines = explode("\n", $trace);
479
+ array_unshift($traceLines, "## $file($line): throw $class");
480
  $i = 0;
481
+ foreach ($traceLines as $traceLine) {
482
  $i++;
483
  if ($i > 20) {
484
  $logMessage .= "\t(...)";
485
  break;
486
  }
487
+ $logMessage .= "\t$traceLine\n";
488
  }
489
  return $logMessage;
490
  }
491
+
492
+ /**
493
+ * Exception::getPrevious() was introduced in PHP 5.3
494
+ * @return Exception|null
495
+ */
496
+ protected function getPreviousException() {
497
+ if (method_exists(get_parent_class(), 'getPrevious')) {
498
+ return parent::getPrevious();
499
+ }
500
+ return null;
501
+ }
502
+
503
  }
504
 
505
  /**
1073
  * Builds the Shopgate Library object graph for Shopgate mobile redirect and returns the instance.
1074
  *
1075
  * @return ShopgateMobileRedirect
1076
+ *
1077
+ * @deprecated Will be removed in 3.0.0. Use SopgateBuilder::buildMobileRedirect() instead.
1078
  */
1079
  public function buildRedirect() {
1080
  $merchantApi = $this->buildMerchantApi();
1081
+ $settingsManager = new Shopgate_Helper_Redirect_SettingsManager(
1082
+ $this->config,
1083
+ $_GET,
1084
+ $_COOKIE
1085
+ );
1086
+
1087
+ $templateParser = new Shopgate_Helper_Redirect_TemplateParser();
1088
+
1089
+ $linkBuilder = new Shopgate_Helper_Redirect_LinkBuilder(
1090
+ $settingsManager,
1091
+ $templateParser
1092
+ );
1093
+
1094
+ $tagsGenerator = new Shopgate_Helper_Redirect_TagsGenerator(
1095
+ $linkBuilder,
1096
+ $templateParser
1097
+ );
1098
+
1099
  $redirect = new ShopgateMobileRedirect(
1100
  $this->config,
1101
+ $merchantApi,
1102
+ $tagsGenerator
1103
  );
1104
 
1105
  return $redirect;
1106
  }
1107
+
1108
+ /**
1109
+ * Builds the Shopgate Library object graph for Shopgate mobile redirect and returns the instance.
1110
+ *
1111
+ * @param string $userAgent The requesting entity's user agent, e.g. $_SERVER['HTTP_USER_AGENT']
1112
+ * @param array $get [string, mixed] A copy of $_GET or the query string in the form of $_GET.
1113
+ * @param array $cookie [string, mixed] A copy of $_COOKIE or the request cookies in the form of $_COOKIE.
1114
+ *
1115
+ * @return Shopgate_Helper_Redirect_MobileRedirect
1116
+ */
1117
+ public function buildMobileRedirect($userAgent, array $get, array $cookie) {
1118
+ $settingsManager = new Shopgate_Helper_Redirect_SettingsManager($this->config, $get, $cookie);
1119
+ $templateParser = new Shopgate_Helper_Redirect_TemplateParser();
1120
+
1121
+ $linkBuilder = new Shopgate_Helper_Redirect_LinkBuilder(
1122
+ $settingsManager,
1123
+ $templateParser
1124
+ );
1125
+
1126
+ $redirector = new Shopgate_Helper_Redirect_Redirector(
1127
+ $settingsManager,
1128
+ new Shopgate_Helper_Redirect_KeywordsManager(
1129
+ $this->buildMerchantApi(),
1130
+ $this->config->getRedirectKeywordCachePath(),
1131
+ $this->config->getRedirectSkipKeywordCachePath()
1132
+ ),
1133
+ $linkBuilder,
1134
+ $userAgent
1135
+ );
1136
+
1137
+ $tagsGenerator = new Shopgate_Helper_Redirect_TagsGenerator(
1138
+ $linkBuilder,
1139
+ $templateParser
1140
+ );
1141
+
1142
+ return new Shopgate_Helper_Redirect_MobileRedirect(
1143
+ $redirector,
1144
+ $tagsGenerator,
1145
+ $settingsManager,
1146
+ $templateParser,
1147
+ dirname(__FILE__) . '/../assets/js_header.html',
1148
+ $this->config->getShopNumber()
1149
+ );
1150
+ }
1151
  }
1152
 
1153
  /**
1205
  * @return null|Shopgate_Helper_DataStructure|Shopgate_Helper_Pricing|Shopgate_Helper_String returns the requested helper instance or null
1206
  * @throws ShopgateLibraryException
1207
  */
1208
+ protected function getHelper($helperName) {
1209
+ if (array_key_exists($helperName,$this->helperClassInstances)) {
1210
  $helperClassName = "Shopgate_Helper_" . $helperName;
1211
  if (!isset($this->helperClassInstances[$helperClassName])) {
1212
  $this->helperClassInstances[$helperClassName] = new $helperClassName();
1267
  public function jsonEncode($value) {
1268
  // if json_encode exists use that
1269
  if (extension_loaded('json') && function_exists('json_encode')) {
1270
+ $encodedValue = json_encode($value);
1271
+ if (!empty($encodedValue)) {
1272
+ return $encodedValue;
1273
+ }
1274
  }
1275
 
1276
  // if not check if external class is loaded
1277
  if (!class_exists('sgServicesJSON')) {
1278
+ require_once dirname(__FILE__) . '/../vendors/JSON.php';
1279
  }
1280
 
1281
  // encode via external class
1295
  public function jsonDecode($json, $assoc = false) {
1296
  // if json_decode exists use that
1297
  if (extension_loaded('json') && function_exists('json_decode')) {
1298
+ $decodedValue = json_decode($json, $assoc);
1299
+ if (!empty($decodedValue)) {
1300
+ return $decodedValue;
1301
+ }
1302
  }
1303
 
1304
  // if not check if external class is loaded
1397
  * @param int $depth
1398
  * @param array $refChain
1399
  */
1400
+ protected function user_print_r($subject, $ignore = array(), $depth = 1, $refChain = array()) {
1401
  static $maxDepth = 5;
1402
  if ($depth > 20) return;
1403
  if (is_object($subject)) {
1418
  } else
1419
  echo $key;
1420
  echo '] => ';
1421
+ if ($depth == $maxDepth) {
1422
  return;
1423
  }
1424
  $this->user_print_r($val, $ignore, $depth + 1, $refChain);
1430
  foreach ($subject as $key => $val) {
1431
  if (is_array($ignore) && !in_array($key, $ignore, 1)) {
1432
  echo str_repeat(" ", $depth * 4) . '[' . $key . '] => ';
1433
+ if ($depth==$maxDepth) {
1434
  return;
1435
  }
1436
  $this->user_print_r($val, $ignore, $depth + 1, $refChain);
1676
 
1677
  // find all settings that start with "enable_" in the config-value-name and collect all active ones
1678
  $searchKeyPart = 'enable_';
1679
+ foreach ($configValues as $key => $val) {
1680
+ if (substr($key, 0, strlen($searchKeyPart)) == $searchKeyPart) {
1681
+ if ($val) {
1682
  $enabledActionsList[$key] = $val;
1683
  }
1684
  }
1974
  *
1975
  * @see http://wiki.shopgate.com/CSV_File_Items/
1976
  */
1977
+ protected function useTaxClasses() {
1978
  $this->useTaxClasses = true;
1979
  }
1980
 
2019
  'item_name' => "",
2020
  );
2021
 
2022
+ if ($this->useTaxClasses) {
2023
  $tax = array(
2024
  'unit_amount_net' => "",
2025
  'tax_class' => "",
2026
  'old_unit_amount_net' => "",
2027
  );
2028
+ } else {
2029
  $tax = array(
2030
  'unit_amount' => "",
2031
  'tax_percent' => "",
2255
  private final function getCreateCsvLoaders($subjectName) {
2256
  $actions = array();
2257
  $subjectName = trim($subjectName);
2258
+ if (!empty($subjectName)) {
2259
  $methodName = 'buildDefault'.$this->camelize($subjectName, true).'Row';
2260
+ if (method_exists($this, $methodName)) {
2261
+ foreach (array_keys($this->{$methodName}() ) as $sKey) {
2262
  $actions[] = $subjectName."Export" . $this->camelize($sKey, true);
2263
  }
2264
  }
2308
  protected function getCreateReviewsCsvLoaders() {
2309
  return $this->getCreateCsvLoaders("review");
2310
  }
2311
+
2312
+ /**
2313
+ * disables an API method in the local config
2314
+ *
2315
+ * @param string $actionName
2316
+ */
2317
+ public function disableAction($actionName) {
2318
+ $shopgateSettingsNew = array('enable_' . $actionName => 0);
2319
+ $this->config->load($shopgateSettingsNew);
2320
+ $this->config->save(array_keys($shopgateSettingsNew), true);
2321
+ }
2322
 
2323
  #################################################################################
2324
  ## Following methods are the callbacks that need to be implemented by plugins. ##
2378
  'item_count' => 0,
2379
  );
2380
 
2381
+ if ($this->config->getEnableGetReviewsCsv()) {
2382
  $shopInfo['review_count'] = 0;
2383
  }
2384
 
2385
+ if ($this->config->getEnableGetMediaCsv()) {
2386
  $shopInfo['media_count'] = array();
2387
  }
2388
 
2463
  * @param ShopgateCart $cart The ShopgateCart object containing the coupons that should be redeemed.
2464
  * @return array('external_coupons' => ShopgateExternalCoupon[])
2465
  * @throws ShopgateLibraryException if an error occurs.
2466
+ *
2467
+ * @deprecated no longer supported.
2468
  */
2469
+ public function redeemCoupons(ShopgateCart $cart){
2470
+ $this->disableAction('redeem_coupons');
2471
+ throw new ShopgateLibraryException(
2472
+ ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION,
2473
+ 'The requested action is disabled and no longer supported.',
2474
+ true,
2475
+ false
2476
+ );
2477
+ }
2478
 
2479
  /**
2480
  * Checks the content of a cart to be valid and returns necessary changes if applicable.
2543
  * @deprecated Use createItems().
2544
  */
2545
  protected function createItemsCsv(){
2546
+ $this->disableAction('get_items_csv');
2547
  throw new ShopgateLibraryException(
2548
  ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION,
2549
  'The requested action is not disabled but has not been implemented in this plugin.',
2579
  * @deprecated Use createCategories().
2580
  */
2581
  protected function createCategoriesCsv() {
2582
+ $this->disableAction('get_categories_csv');
2583
  throw new ShopgateLibraryException(
2584
  ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION,
2585
  'The requested action is not disabled but has not been implemented in this plugin.',
2602
  * @deprecated Use createReviews().
2603
  */
2604
  protected function createReviewsCsv() {
2605
+ $this->disableAction('get_reviews_csv');
2606
  throw new ShopgateLibraryException(
2607
  ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION,
2608
  'The requested action is not disabled but has not been implemented in this plugin.',
3007
  * @param $whitelist
3008
  * @return bool
3009
  */
3010
+ public function compare($obj,$obj2,$whitelist) {
3011
 
3012
+ foreach ($whitelist as $acceptedField) {
3013
+ if ($obj->{$this->camelize('get_'.$acceptedField)}() != $obj2->{$this->camelize('get_'.$acceptedField)}()) {
3014
  return false;
3015
  }
3016
  }
lib/Shopgate/classes/helper/redirect/KeywordsManager.php ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Helper_Redirect_KeywordsManager implements Shopgate_Helper_Redirect_KeywordsManagerInterface
25
+ {
26
+ /** @var ShopgateMerchantApi */
27
+ protected $merchantApi;
28
+
29
+ /** @var string */
30
+ protected $whitelistCacheFilePath;
31
+
32
+ /** @var string */
33
+ protected $blacklistCacheFilePath;
34
+
35
+ /** @var string[] */
36
+ protected $whitelist;
37
+
38
+ /** @var string[] */
39
+ protected $blacklist;
40
+
41
+ /** @var int */
42
+ protected $cacheTimeout;
43
+
44
+ /** @var bool */
45
+ protected $disableUpdate;
46
+
47
+ /**
48
+ * @param ShopgateMerchantApi $merchantApi
49
+ * @param string $whitelistCacheFilePath
50
+ * @param string $blacklistCacheFilePath
51
+ * @param int $cacheTimeout
52
+ * @param bool $disableUpdate
53
+ */
54
+ public function __construct(
55
+ ShopgateMerchantApi $merchantApi,
56
+ $whitelistCacheFilePath,
57
+ $blacklistCacheFilePath,
58
+ $cacheTimeout = self::DEFAULT_CACHE_TIME,
59
+ $disableUpdate = false
60
+ ) {
61
+ $this->merchantApi = $merchantApi;
62
+ $this->whitelistCacheFilePath = $whitelistCacheFilePath;
63
+ $this->blacklistCacheFilePath = $blacklistCacheFilePath;
64
+ $this->cacheTimeout = $cacheTimeout;
65
+ $this->disableUpdate = $disableUpdate;
66
+
67
+ $this->whitelist = array();
68
+ $this->blacklist = array();
69
+
70
+ $this->init();
71
+ }
72
+
73
+ public function toRegEx()
74
+ {
75
+ return
76
+ '/' .
77
+
78
+ // positive lookahead for the whitelist
79
+ '(?=' . implode('|', array_map(array($this, 'prepareKeyword'), $this->whitelist)) . ')' .
80
+
81
+ // negative lookahead for the blacklist
82
+ '(?!' . implode('|', array_map(array($this, 'prepareKeyword'), $this->blacklist)) . ')' .
83
+
84
+ // modfiers: case-insensitive
85
+ '/i';
86
+ }
87
+
88
+ public function getWhitelist()
89
+ {
90
+ return $this->whitelist;
91
+ }
92
+
93
+ public function getBlacklist()
94
+ {
95
+ return $this->blacklist;
96
+ }
97
+
98
+ public function update()
99
+ {
100
+ $this->initFromApi();
101
+ $newUpdateTimestamp = time();
102
+
103
+ // update the cache files
104
+ $this->saveAllKeywordsToFiles($newUpdateTimestamp);
105
+ }
106
+
107
+ /**
108
+ * Initializes the whitelist and blacklist from the Shopgate Merchant API or cache files.
109
+ */
110
+ protected function init()
111
+ {
112
+ try {
113
+ $lastUpdate = $this->initFromFiles();
114
+ } catch (ShopgateLibraryException $e) {
115
+ // If this fails with an exception we have a most likely permanent problem.
116
+ // In that case the lists _MUST NOT_ be fetched from the API as chances are high this would happen for
117
+ // every request to the merchant's desktop site.
118
+ return;
119
+ }
120
+
121
+ if ($this->disableUpdate || !$this->expired($lastUpdate)) {
122
+ return;
123
+ }
124
+
125
+ try {
126
+ $this->update();
127
+ } catch (Exception $e) {
128
+ // if fetching from API fails, try again in 5 minutes; meanwhile use the cached keywords
129
+ $this->saveAllKeywordsToFiles($newUpdateTimestamp = (time() - ($this->cacheTimeout * 3600)) + 300);
130
+ }
131
+ }
132
+
133
+ /**
134
+ * @return int The timestamp of the earlier last update from both files.
135
+ *
136
+ * @throws ShopgateLibraryException
137
+ */
138
+ protected function initFromFiles()
139
+ {
140
+ $whitelistMeta = $this->loadKeywordsFromFile($this->whitelistCacheFilePath);
141
+ $blacklistMeta = $this->loadKeywordsFromFile($this->blacklistCacheFilePath);
142
+
143
+ $this->whitelist = $whitelistMeta['keywords'];
144
+ $this->blacklist = $blacklistMeta['keywords'];
145
+
146
+ return min($whitelistMeta['lastUpdate'], $blacklistMeta['lastUpdate']);
147
+ }
148
+
149
+ /**
150
+ * @throws ShopgateLibraryException
151
+ */
152
+ protected function initFromApi()
153
+ {
154
+ $response = $this->merchantApi->getMobileRedirectUserAgents();
155
+ $this->whitelist = $response['keywords'];
156
+ $this->blacklist = $response['skip_keywords'];
157
+ }
158
+
159
+ /**
160
+ * @param string $filePath
161
+ *
162
+ * @return array An array with indices 'lastUpdate' (int, timestamp) and 'keywords' (string[]).
163
+ * @throws ShopgateLibraryException
164
+ */
165
+ protected function loadKeywordsFromFile($filePath)
166
+ {
167
+ $defaultReturn = array(
168
+ 'lastUpdate' => 0,
169
+ 'keywords' => array()
170
+ );
171
+
172
+ $cacheFile = @fopen($filePath, 'a+');
173
+ if (empty($cacheFile)) {
174
+ // exception without logging
175
+ throw new ShopgateLibraryException(ShopgateLibraryException::FILE_READ_WRITE_ERROR,
176
+ 'Could not read file "' . $filePath . '".', false, false);
177
+ }
178
+
179
+ $keywordsFromFile = explode("\n", @fread($cacheFile, filesize($filePath)));
180
+ @fclose($cacheFile);
181
+
182
+ return (empty($keywordsFromFile))
183
+ ? $defaultReturn
184
+ : array(
185
+ 'lastUpdate' => (int)array_shift($keywordsFromFile), // strip timestamp in first line
186
+ 'keywords' => $keywordsFromFile,
187
+ );
188
+ }
189
+
190
+ /**
191
+ * Saves the internal black and white lists to files.
192
+ *
193
+ * @param int $lastUpdate The timestamp to use or null to use time().
194
+ */
195
+ protected function saveAllKeywordsToFiles($lastUpdate = null)
196
+ {
197
+ if ($lastUpdate === null) {
198
+ $lastUpdate = time();
199
+ }
200
+
201
+ $this->saveKeywordsToFile($this->whitelist, $this->whitelistCacheFilePath, $lastUpdate);
202
+ $this->saveKeywordsToFile($this->blacklist, $this->blacklistCacheFilePath, $lastUpdate);
203
+ }
204
+
205
+ /**
206
+ * Saves redirect keywords to file.
207
+ *
208
+ * @param string[] $keywords The list of keywords to write to the file.
209
+ * @param string $cacheFilePath The path to the file.
210
+ * @param int $lastUpdate The timestamp to use or null to use time().
211
+ */
212
+ protected function saveKeywordsToFile($keywords, $cacheFilePath, $lastUpdate = null)
213
+ {
214
+ if ($lastUpdate === null) {
215
+ $lastUpdate = time();
216
+ }
217
+
218
+ // add timestamp to first line
219
+ array_unshift($keywords, $lastUpdate);
220
+
221
+ // save without logging - this could end up in spamming the logs
222
+ @file_put_contents($cacheFilePath, implode("\n", $keywords));
223
+ }
224
+
225
+ /**
226
+ * @param int $lastUpdate The timestamp to be examined.
227
+ * @param int $now The time of "now" or null to use time().
228
+ *
229
+ * @return bool
230
+ */
231
+ protected function expired($lastUpdate, $now = null)
232
+ {
233
+ if ($now === null) {
234
+ $now = time();
235
+ }
236
+
237
+ return ($now - ($lastUpdate + ($this->cacheTimeout * 3600)) > 0);
238
+ }
239
+
240
+ /**
241
+ * A callback for array_map that prepares keywords for the regex.
242
+ *
243
+ * Currently this means the keyword is made lower-case and preg_quote()'ed with a slash (/) as escape character.
244
+ *
245
+ * @param string $keyword
246
+ *
247
+ * @return string
248
+ */
249
+ protected function prepareKeyword($keyword)
250
+ {
251
+ return preg_quote(strtolower($keyword), '/');
252
+ }
253
+ }
lib/Shopgate/classes/helper/redirect/KeywordsManagerInterface.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ interface Shopgate_Helper_Redirect_KeywordsManagerInterface
25
+ {
26
+ /**
27
+ * @var int (hours) the default time to be set for updating the cache
28
+ */
29
+ const DEFAULT_CACHE_TIME = 24;
30
+
31
+ /**
32
+ * Returns a regular expression matching everything on the whitelist and not matching anything on the black list.
33
+ *
34
+ * @return string
35
+ */
36
+ public function toRegEx();
37
+
38
+ /**
39
+ * @return string[] A list of keywords that identify a smartphone user.
40
+ */
41
+ public function getWhitelist();
42
+
43
+ /**
44
+ * @return string[] A list keywords that identify a smartphone user but should be ignored in the redirect.
45
+ */
46
+ public function getBlacklist();
47
+
48
+ /**
49
+ * Updates the keyword cache from the merchant API regardless of expiry etc.
50
+ *
51
+ * @throws ShopgateLibraryException in case the request to the Shopgate Merchant API fails.
52
+ */
53
+ public function update();
54
+ }
lib/Shopgate/classes/helper/redirect/LinkBuilder.php ADDED
@@ -0,0 +1,154 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Helper_Redirect_LinkBuilder implements Shopgate_Helper_Redirect_LinkBuilderInterface
25
+ {
26
+ /** @var string[] [string, string] A list of templates indexed by their page type. */
27
+ protected $defaultTemplatesByPageType;
28
+
29
+ /** @var Shopgate_Helper_Redirect_SettingsManagerInterface */
30
+ protected $settingsManager;
31
+
32
+ /** @var Shopgate_Helper_Redirect_TemplateParserInterface */
33
+ protected $templateParser;
34
+
35
+ /**
36
+ * @param Shopgate_Helper_Redirect_SettingsManagerInterface $settingsManager
37
+ * @param Shopgate_Helper_Redirect_TemplateParserInterface $templateParser
38
+ */
39
+ public function __construct(
40
+ Shopgate_Helper_Redirect_SettingsManagerInterface $settingsManager,
41
+ Shopgate_Helper_Redirect_TemplateParserInterface $templateParser
42
+ ) {
43
+ $this->settingsManager = $settingsManager;
44
+ $this->templateParser = $templateParser;
45
+
46
+ // default templates
47
+ $this->defaultTemplatesByPageType = $this->settingsManager->getDefaultTemplatesByPageType();
48
+ }
49
+
50
+ public function buildDefault(array $parameters = array())
51
+ {
52
+ return $this->appendRedirectableGetParameters($this->getUrlFor(self::LINK_TYPE_DEFAULT, $parameters));
53
+ }
54
+
55
+ public function buildHome(array $parameters = array())
56
+ {
57
+ return $this->appendRedirectableGetParameters($this->getUrlFor(self::LINK_TYPE_HOME, $parameters));
58
+ }
59
+
60
+ public function buildProduct($uid, array $parameters = array())
61
+ {
62
+ return $this->buildScriptFor(self::LINK_TYPE_PRODUCT, 'product_uid', $uid);
63
+ }
64
+
65
+ public function buildCategory($uid, array $parameters = array())
66
+ {
67
+ return $this->buildScriptFor(self::LINK_TYPE_CATEGORY, 'category_uid', $uid);
68
+ }
69
+
70
+ public function buildCms($pageUid, array $parameters = array())
71
+ {
72
+ return $this->buildScriptFor(self::LINK_TYPE_CMS, 'page_uid', $pageUid);
73
+ }
74
+
75
+ public function buildBrand($brandName)
76
+ {
77
+ return $this->buildScriptFor(self::LINK_TYPE_BRAND, 'brand_name', $brandName);
78
+ }
79
+
80
+ public function buildSearch($searchQuery, array $parameters = array())
81
+ {
82
+ return $this->buildScriptFor(self::LINK_TYPE_SEARCH, 'search_query', $searchQuery);
83
+ }
84
+
85
+ public function getUrlFor($pageType, array $variables, array $parameters = array(), $overrideTemplate = null)
86
+ {
87
+ /** @var Shopgate_Model_Redirect_HtmlTagVariable[] $variables */
88
+
89
+ $template = empty($this->defaultTemplatesByPageType[$pageType])
90
+ ? ''
91
+ : $this->defaultTemplatesByPageType[$pageType];
92
+
93
+ if ($overrideTemplate !== null) {
94
+ $template = $overrideTemplate;
95
+ }
96
+
97
+ if (strstr($template, '{baseUrl}') !== false) {
98
+ $parameters['baseUrl'] = $this->settingsManager->getMobileUrl();
99
+ }
100
+
101
+ foreach ($variables as $variable) {
102
+ if (!isset($parameters[$variable->getName()])) {
103
+ return '';
104
+ }
105
+
106
+ $parameter = !isset($parameters[$variable->getName()])
107
+ ? ''
108
+ : $parameters[$variable->getName()];
109
+
110
+ $template = $this->templateParser->process($template, $variable, $parameter);
111
+ }
112
+
113
+ return $template;
114
+ }
115
+
116
+ /**
117
+ * @param string $url
118
+ *
119
+ * @return string
120
+ */
121
+ protected function appendRedirectableGetParameters($url)
122
+ {
123
+ $concat = (parse_url($url, PHP_URL_QUERY) === null)
124
+ ? '?'
125
+ : '&';
126
+
127
+ return
128
+ $url . (
129
+ $this->settingsManager->getRedirectableGetParameters()
130
+ ? $concat . $this->settingsManager->getRedirectableGetParameters()
131
+ : ''
132
+ );
133
+ }
134
+
135
+ /**
136
+ * @param string $pageType
137
+ * @param string $variableName
138
+ * @param string $variableValue
139
+ *
140
+ * @return string
141
+ */
142
+ protected function buildScriptFor($pageType, $variableName, $variableValue)
143
+ {
144
+ $variables = $this->templateParser->getVariables($this->defaultTemplatesByPageType[$pageType]);
145
+
146
+ return $this->appendRedirectableGetParameters(
147
+ $this->getUrlFor(
148
+ $pageType,
149
+ $variables,
150
+ array($variableName => $variableValue)
151
+ )
152
+ );
153
+ }
154
+ }
lib/Shopgate/classes/helper/redirect/LinkBuilderInterface.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ interface Shopgate_Helper_Redirect_LinkBuilderInterface
25
+ {
26
+ const LINK_TYPE_DEFAULT = 'default';
27
+ const LINK_TYPE_HOME = 'home';
28
+ const LINK_TYPE_PRODUCT = 'product';
29
+ const LINK_TYPE_CATEGORY = 'category';
30
+ const LINK_TYPE_CMS = 'cms';
31
+ const LINK_TYPE_BRAND = 'brand';
32
+ const LINK_TYPE_SEARCH = 'search';
33
+
34
+ /**
35
+ * @param Shopgate_Model_Redirect_DeeplinkSuffix[] $parameters
36
+ *
37
+ * @return string
38
+ */
39
+ public function buildDefault(array $parameters = array());
40
+
41
+ /**
42
+ * @param Shopgate_Model_Redirect_DeeplinkSuffix[] $parameters
43
+ *
44
+ * @return string
45
+ */
46
+ public function buildHome(array $parameters = array());
47
+
48
+ /**
49
+ * @param string $uid
50
+ * @param Shopgate_Model_Redirect_DeeplinkSuffix[] $parameters
51
+ *
52
+ * @return string
53
+ */
54
+ public function buildProduct($uid, array $parameters = array());
55
+
56
+ /**
57
+ * @param string $uid
58
+ * @param Shopgate_Model_Redirect_DeeplinkSuffix[] $parameters
59
+ *
60
+ * @return string
61
+ */
62
+ public function buildCategory($uid, array $parameters = array());
63
+
64
+ /**
65
+ * @param string $pageUid
66
+ * @param Shopgate_Model_Redirect_DeeplinkSuffix[] $parameters
67
+ *
68
+ * @return string
69
+ */
70
+ public function buildCms($pageUid, array $parameters = array());
71
+
72
+ /**
73
+ * @param string $brandName
74
+ *
75
+ * @return string
76
+ */
77
+ public function buildBrand($brandName);
78
+
79
+ /**
80
+ * @param string $searchQuery
81
+ * @param Shopgate_Model_Redirect_DeeplinkSuffix[] $parameters
82
+ *
83
+ * @return string
84
+ */
85
+ public function buildSearch($searchQuery, array $parameters = array());
86
+
87
+ /**
88
+ * @param string $pageType
89
+ * @param Shopgate_Model_Redirect_HtmlTagVariable[] $variables
90
+ * @param array $parameters [string, string]
91
+ * @param string $overrideTemplate Set to null to not override the default template
92
+ *
93
+ * @return string
94
+ */
95
+ public function getUrlFor($pageType, array $variables, array $parameters = array(), $overrideTemplate = null);
96
+ }
lib/Shopgate/classes/helper/redirect/MobileRedirect.php ADDED
@@ -0,0 +1,322 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Helper_Redirect_MobileRedirect
25
+ extends ShopgateObject
26
+ implements Shopgate_Helper_Redirect_MobileRedirectInterface
27
+ {
28
+ /** @var Shopgate_Helper_Redirect_RedirectorInterface */
29
+ protected $redirector;
30
+
31
+ /** @var Shopgate_Helper_Redirect_TagsGeneratorInterface */
32
+ protected $tagsGenerator;
33
+
34
+ /** @var Shopgate_Helper_Redirect_SettingsManagerInterface */
35
+ protected $settingsManager;
36
+
37
+ /** @var Shopgate_Helper_Redirect_TemplateParserInterface */
38
+ protected $templateParser;
39
+
40
+ /** @var string */
41
+ protected $jsTemplateFilePath;
42
+
43
+ /** @var string */
44
+ protected $shopNumber;
45
+
46
+ /** @var bool */
47
+ protected $suppressRedirectHttp;
48
+
49
+ /** @var bool */
50
+ protected $suppressRedirectJavascript;
51
+
52
+ /**
53
+ * @var array [string, mixed] Parameters that should be replaced in the HTML tags, indexed by their name.
54
+ */
55
+ protected $siteParameters;
56
+
57
+ /**
58
+ * @var array [string, string] An array with the page names as indices and the "old" JS redirect types as values, if different.
59
+ */
60
+ protected $pageTypeToRedirectMapping;
61
+
62
+ /**
63
+ * ShopgateMobileRedirect constructor.
64
+ *
65
+ * @param Shopgate_Helper_Redirect_RedirectorInterface $redirector
66
+ * @param Shopgate_Helper_Redirect_TagsGeneratorInterface $tagsGenerator
67
+ * @param Shopgate_Helper_Redirect_SettingsManagerInterface $settingsManager
68
+ * @param Shopgate_Helper_Redirect_TemplateParserInterface $templateParser
69
+ * @param string $jsTemplateFilePath
70
+ * @param string $shopNumber
71
+ */
72
+ public function __construct(
73
+ Shopgate_Helper_Redirect_RedirectorInterface $redirector,
74
+ Shopgate_Helper_Redirect_TagsGeneratorInterface $tagsGenerator,
75
+ Shopgate_Helper_Redirect_SettingsManagerInterface $settingsManager,
76
+ Shopgate_Helper_Redirect_TemplateParserInterface $templateParser,
77
+ $jsTemplateFilePath,
78
+ $shopNumber
79
+ ) {
80
+ $this->redirector = $redirector;
81
+ $this->tagsGenerator = $tagsGenerator;
82
+ $this->settingsManager = $settingsManager;
83
+ $this->templateParser = $templateParser;
84
+ $this->jsTemplateFilePath = $jsTemplateFilePath;
85
+ $this->shopNumber = $shopNumber;
86
+
87
+ $this->suppressRedirectHttp = false;
88
+ $this->suppressRedirectJavascript = false;
89
+ $this->siteParameters = array();
90
+
91
+ $this->pageTypeToRedirectMapping = array(
92
+ Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_HOME => 'start',
93
+ Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_PRODUCT => 'item',
94
+ );
95
+
96
+ try {
97
+ $htmlTags = $this->settingsManager->getHtmlTags();
98
+ $this->tagsGenerator->setHtmlTagsFromJson($htmlTags);
99
+ } catch (ShopgateLibraryException $e) {
100
+ $this->tagsGenerator->setHtmlTagsFromJson($this->getFallBackTags());
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Suppresses the redirect via JavaScript without disabling the mobile header.
106
+ *
107
+ * @deprecated Use suppressRedirectTypes() instead.
108
+ */
109
+ public function suppressRedirect()
110
+ {
111
+ $this->suppressRedirectJavascript = true;
112
+ }
113
+
114
+ public function supressRedirectTechniques($http = false, $javascript = false)
115
+ {
116
+ $this->suppressRedirectHttp = $http;
117
+ $this->suppressRedirectJavascript = $javascript;
118
+ }
119
+
120
+ public function addSiteParameter($name, $value)
121
+ {
122
+ $this->siteParameters[$name] = $value;
123
+ }
124
+
125
+ public function redirect($url, $sendVary = true)
126
+ {
127
+ if ($this->suppressRedirectHttp) {
128
+ return;
129
+ }
130
+
131
+ $this->redirector->redirect($url, $sendVary);
132
+ }
133
+
134
+ public function buildScriptDefault()
135
+ {
136
+ $this->redirector->redirectDefault();
137
+
138
+ return $this->buildTags(Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_DEFAULT);
139
+ }
140
+
141
+ public function buildScriptShop()
142
+ {
143
+ $this->redirector->redirectHome();
144
+
145
+ return $this->buildTags(Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_HOME);
146
+ }
147
+
148
+ public function buildScriptItem($itemNumber)
149
+ {
150
+ $this->redirector->redirectProduct($itemNumber);
151
+
152
+ return $this->buildTags(
153
+ Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_PRODUCT,
154
+ array('product_uid' => $itemNumber)
155
+ );
156
+ }
157
+
158
+ public function buildScriptItemPublic($itemNumberPublic)
159
+ {
160
+ return $this->buildScriptItem($itemNumberPublic);
161
+ }
162
+
163
+ public function buildScriptCategory($categoryNumber)
164
+ {
165
+ $this->redirector->redirectCategory($categoryNumber);
166
+
167
+ return $this->buildTags(
168
+ Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_CATEGORY,
169
+ array('category_uid' => $categoryNumber)
170
+ );
171
+ }
172
+
173
+ public function buildScriptCms($cmsPage)
174
+ {
175
+ $this->redirector->redirectCms($cmsPage);
176
+
177
+ return $this->buildTags(
178
+ Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_CMS,
179
+ array('page_uid' => $cmsPage)
180
+ );
181
+ }
182
+
183
+ public function buildScriptBrand($manufacturerName)
184
+ {
185
+ $this->redirector->redirectBrand($manufacturerName);
186
+
187
+ return $this->buildTags(
188
+ Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_BRAND,
189
+ array('brand_name' => $manufacturerName)
190
+ );
191
+ }
192
+
193
+ public function buildScriptSearch($searchQuery)
194
+ {
195
+ $this->redirector->redirectSearch($searchQuery);
196
+
197
+ return $this->buildTags(
198
+ Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_SEARCH,
199
+ array('search_query' => $searchQuery)
200
+ );
201
+ }
202
+
203
+ /**
204
+ * @param string $pageType
205
+ * @param array $parameters [string, string]
206
+ *
207
+ * @return string
208
+ */
209
+ protected function buildTags($pageType, $parameters = array())
210
+ {
211
+ $parameters = $this->siteParameters + $parameters;
212
+
213
+ $parameters['link_tags'] = $this->tagsGenerator->getTagsFor($pageType, $parameters);
214
+ $parameters['redirect_code'] = $this->getRedirectCode($pageType);
215
+ $parameters['shop_number'] = $this->shopNumber;
216
+ $parameters += $this->settingsManager->getShopgateStaticUrl();
217
+
218
+ // pre-process the additional parameters to add in the correct JS variables
219
+ $variable = new Shopgate_Model_Redirect_HtmlTagVariable();
220
+ $variable->setName('additional_parameters');
221
+ $jsTemplate = $this->templateParser->process(
222
+ @file_get_contents($this->jsTemplateFilePath),
223
+ $variable,
224
+ $this->getAdditionalParameters($pageType)
225
+ );
226
+
227
+ // process all variables left in the template (and those added with the processing of 'additional_parameters'.
228
+ $variables = $this->templateParser->getVariables($jsTemplate);
229
+ foreach ($variables as $variable) {
230
+ $replacement = !empty($parameters[$variable->getName()])
231
+ ? $parameters[$variable->getName()]
232
+ : '';
233
+
234
+ $jsTemplate = $this->templateParser->process($jsTemplate, $variable, $replacement);
235
+ }
236
+
237
+ return $jsTemplate;
238
+ }
239
+
240
+ /**
241
+ * @return string
242
+ */
243
+ protected function getFallBackTags()
244
+ {
245
+ return $this->jsonEncode(
246
+ array(
247
+ 'html_tags' => array(
248
+ array(
249
+ 'name' => 'link',
250
+ 'attributes' => array(
251
+ array(
252
+ 'name' => 'rel',
253
+ 'value' => 'alternate',
254
+ ),
255
+ array(
256
+ 'name' => 'media',
257
+ 'value' => 'only screen and (max-width: 640px)',
258
+ ),
259
+ array(
260
+ 'name' => 'href',
261
+ 'value' => '{deeplink_suffix}',
262
+ 'deeplink_suffix' => $this->settingsManager->getDefaultTemplatesByPageType(),
263
+ ),
264
+ ),
265
+ ),
266
+ ),
267
+ )
268
+ );
269
+ }
270
+
271
+ /**
272
+ * @param string $pageType
273
+ *
274
+ * @return string
275
+ */
276
+ protected function getAdditionalParameters($pageType)
277
+ {
278
+ $additionalParameters = '';
279
+
280
+ $defaultRedirect = $this->settingsManager->isDefaultRedirectDisabled() ? 'false' : 'true';
281
+ $jsRedirect = $this->suppressRedirectJavascript ? 'false' : 'true';
282
+
283
+ $additionalParameters .= "_shopgate.is_default_redirect_disabled = {$defaultRedirect};\n";
284
+ $additionalParameters .= " _shopgate.redirect_to_webapp = {$jsRedirect};\n";
285
+
286
+ switch ($pageType) {
287
+ case Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_CATEGORY:
288
+ $additionalParameters .= '_shopgate.category_number = "{category_uid}";';
289
+ break;
290
+
291
+ case Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_PRODUCT:
292
+ $additionalParameters .= '_shopgate.item_number = "{product_uid}";';
293
+ break;
294
+
295
+ case Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_CMS:
296
+ $additionalParameters .= '_shopgate.cms_page = "{page_uid}";';
297
+ break;
298
+
299
+ case Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_BRAND:
300
+ $additionalParameters .= '_shopgate.brand_name = "{brand_name}";';
301
+ break;
302
+
303
+ case Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_SEARCH:
304
+ $additionalParameters .= '_shopgate.search_query = "{search_query:escaped}";';
305
+ break;
306
+ }
307
+
308
+ return $additionalParameters . "\n";
309
+ }
310
+
311
+ /**
312
+ * @param string $pageType
313
+ *
314
+ * @return bool
315
+ */
316
+ protected function getRedirectCode($pageType)
317
+ {
318
+ return isset($this->pageTypeToRedirectMapping[$pageType])
319
+ ? $this->pageTypeToRedirectMapping[$pageType]
320
+ : $pageType;
321
+ }
322
+ }
lib/Shopgate/classes/helper/redirect/MobileRedirectInterface.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ interface Shopgate_Helper_Redirect_MobileRedirectInterface
25
+ {
26
+ /**
27
+ * @param bool $http
28
+ * @param bool $javascript
29
+ */
30
+ public function supressRedirectTechniques($http = false, $javascript = false);
31
+
32
+ /**
33
+ * @param string $name One of the Shopgate_Helper_Redirect_TagsGeneratorInterface::SITE_PARAMETER_* constants.
34
+ * @param string $value
35
+ */
36
+ public function addSiteParameter($name, $value);
37
+
38
+ /**
39
+ * @param string $url
40
+ * @param bool $sendVary
41
+ *
42
+ * @post ends script execution in case of http redirect
43
+ */
44
+ public function redirect($url, $sendVary = true);
45
+
46
+ /**
47
+ * @return string
48
+ */
49
+ public function buildScriptDefault();
50
+
51
+ /**
52
+ * @return string
53
+ */
54
+ public function buildScriptShop();
55
+
56
+ /**
57
+ * @param string $itemNumber
58
+ *
59
+ * @return string
60
+ */
61
+ public function buildScriptItem($itemNumber);
62
+
63
+ /**
64
+ * @param string $itemNumberPublic
65
+ *
66
+ * @return string
67
+ */
68
+ public function buildScriptItemPublic($itemNumberPublic);
69
+
70
+ /**
71
+ * @param string $categoryNumber
72
+ *
73
+ * @return string
74
+ */
75
+ public function buildScriptCategory($categoryNumber);
76
+
77
+ /**
78
+ * @param string $cmsPage
79
+ *
80
+ * @return string
81
+ */
82
+ public function buildScriptCms($cmsPage);
83
+
84
+ /**
85
+ * @param string $manufacturerName
86
+ *
87
+ * @return mixed
88
+ */
89
+ public function buildScriptBrand($manufacturerName);
90
+
91
+ /**
92
+ * @param string $searchQuery
93
+ *
94
+ * @return string
95
+ */
96
+ public function buildScriptSearch($searchQuery);
97
+ }
lib/Shopgate/classes/helper/redirect/Redirector.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Helper_Redirect_Redirector implements Shopgate_Helper_Redirect_RedirectorInterface
25
+ {
26
+ /** @var Shopgate_Helper_Redirect_SettingsManagerInterface */
27
+ protected $settingsManager;
28
+
29
+ /** @var Shopgate_Helper_Redirect_KeywordsManagerInterface */
30
+ protected $keywordManager;
31
+
32
+ /** @var Shopgate_Helper_Redirect_LinkBuilderInterface */
33
+ protected $linkBuilder;
34
+
35
+ /** @var string */
36
+ protected $userAgent;
37
+
38
+ /**
39
+ * @param Shopgate_Helper_Redirect_SettingsManagerInterface $settingsManager
40
+ * @param Shopgate_Helper_Redirect_KeywordsManagerInterface $keywordManager
41
+ * @param Shopgate_Helper_Redirect_LinkBuilderInterface $linkBuilder
42
+ * @param string $userAgent
43
+ */
44
+ public function __construct(
45
+ Shopgate_Helper_Redirect_SettingsManagerInterface $settingsManager,
46
+ Shopgate_Helper_Redirect_KeywordsManagerInterface $keywordManager,
47
+ Shopgate_Helper_Redirect_LinkBuilderInterface $linkBuilder,
48
+ $userAgent = ''
49
+ ) {
50
+ $this->settingsManager = $settingsManager;
51
+ $this->keywordManager = $keywordManager;
52
+ $this->linkBuilder = $linkBuilder;
53
+ $this->userAgent = $userAgent;
54
+ }
55
+
56
+ public function redirectDefault()
57
+ {
58
+ if ($this->settingsManager->isDefaultRedirectDisabled()) {
59
+ return;
60
+ }
61
+
62
+ // don't send the "Vary" HTTP header because this doesn't redirect to a different version, it's just a fall back
63
+ $this->redirect($this->linkBuilder->buildDefault(), false);
64
+ }
65
+
66
+ public function redirectHome()
67
+ {
68
+ $this->redirect($this->linkBuilder->buildHome());
69
+ }
70
+
71
+ public function redirectCategory($uid)
72
+ {
73
+ $this->redirect($this->linkBuilder->buildCategory($uid));
74
+ }
75
+
76
+ public function redirectProduct($uid)
77
+ {
78
+ $this->redirect($this->linkBuilder->buildProduct($uid));
79
+ }
80
+
81
+ public function redirectCms($pageUid)
82
+ {
83
+ $this->redirect($this->linkBuilder->buildCms($pageUid));
84
+ }
85
+
86
+ public function redirectBrand($brandName)
87
+ {
88
+ $this->redirect($this->linkBuilder->buildBrand($brandName));
89
+ }
90
+
91
+ public function redirectSearch($searchString)
92
+ {
93
+ $this->redirect($this->linkBuilder->buildSearch($searchString));
94
+ }
95
+
96
+ public function redirect($url, $sendVary = true)
97
+ {
98
+ if ($this->settingsManager->isRedirectDisabled() && !$this->settingsManager->isMobileHeaderDisabled()) {
99
+ $this->settingsManager->setCookie();
100
+
101
+ return;
102
+ }
103
+
104
+ if (!$this->isMobile()) {
105
+ return;
106
+ }
107
+
108
+ if ($sendVary) {
109
+ header('Vary: User-Agent');
110
+ }
111
+
112
+ header("Location: " . $url, true, 301);
113
+ exit;
114
+ }
115
+
116
+ /**
117
+ * @return bool
118
+ */
119
+ protected function isMobile()
120
+ {
121
+ return preg_match($this->keywordManager->toRegEx(), $this->userAgent);
122
+ }
123
+ }
lib/Shopgate/classes/helper/redirect/RedirectorInterface.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ *
24
+ * Offers functions to redirect requesting entities to the mobile website, depending on the type.
25
+ */
26
+ interface Shopgate_Helper_Redirect_RedirectorInterface
27
+ {
28
+ /**
29
+ * @post If enabled, a location header to the mobile default/fallback page is sent to the requesting entity.
30
+ */
31
+ public function redirectDefault();
32
+
33
+ /**
34
+ * @post A location header to the mobile home page is sent to the requesting entity.
35
+ */
36
+ public function redirectHome();
37
+
38
+ /**
39
+ * @param string $uid
40
+ *
41
+ * @post A location header to the mobile category detail page is sent to the requesting entity.
42
+ */
43
+ public function redirectCategory($uid);
44
+
45
+ /**
46
+ * @param string $uid
47
+ *
48
+ * @post A location header to the mobile product page is sent to the requesting entity.
49
+ */
50
+ public function redirectProduct($uid);
51
+
52
+ /**
53
+ * @param string $pageUid
54
+ *
55
+ * @post A location header to the mobile CMS page is sent to the requesting entity.
56
+ */
57
+ public function redirectCms($pageUid);
58
+
59
+ /**
60
+ * @param string $brandName
61
+ *
62
+ * @post A location header to the mobile brand search is sent to the requesting entity.
63
+ */
64
+ public function redirectBrand($brandName);
65
+
66
+ /**
67
+ * @param string $searchString
68
+ *
69
+ * @post A location header to the mobile searchpage is sent to the requesting entity.
70
+ */
71
+ public function redirectSearch($searchString);
72
+
73
+ /**
74
+ * @param string $url The URL to redirect to.
75
+ * @param bool $sendVary True to send the "Vary: User-Agent" header.
76
+ */
77
+ public function redirect($url, $sendVary = true);
78
+ }
lib/Shopgate/classes/helper/redirect/SettingsManager.php ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Helper_Redirect_SettingsManager implements Shopgate_Helper_Redirect_SettingsManagerInterface
25
+ {
26
+ /** @var ShopgateConfigInterface */
27
+ protected $config;
28
+
29
+ /** @var string */
30
+ protected $disableRedirectGetParameterName;
31
+
32
+ /** @var string */
33
+ protected $disableRedirectCookieName;
34
+
35
+ /**
36
+ * @var int Seconds until the disable cookie should expire if set at $this->startTime.
37
+ */
38
+ protected $expiration;
39
+ /**
40
+ * @var array [string, mixed] A copy of $_GET.
41
+ */
42
+ protected $get;
43
+ /**
44
+ * @var array [string, mixed] A reference to $_COOKIE.
45
+ */
46
+ protected $cookie;
47
+
48
+ /**
49
+ * @param ShopgateConfigInterface $config
50
+ * @param array $get [string, mixed] A copy of $_GET.
51
+ * @param array $cookie [string, mixed] A reference to $_COOKIE.
52
+ * @param int $cookieExpiration Seconds until the disable cookie should expire if set at $startTime.
53
+ * @param string $disableRedirectGetParameterName
54
+ * @param string $disableRedirectCookieName
55
+ */
56
+ public function __construct(
57
+ ShopgateConfigInterface $config,
58
+ array $get = array(),
59
+ array &$cookie = array(),
60
+ $cookieExpiration = self::DISABLE_REDIRECT_COOKIE_EXPIRATION_1_WEEK,
61
+ $disableRedirectGetParameterName = self::DEFAULT_DISABLE_REDIRECT_GET_PARAMETER_NAME,
62
+ $disableRedirectCookieName = self::DEFAULT_DISABLE_REDIRECT_COOKIE_NAME
63
+ ) {
64
+ $this->config = $config;
65
+ $this->get = $get;
66
+ $this->cookie = $cookie;
67
+ $this->expiration = $cookieExpiration;
68
+ $this->disableRedirectGetParameterName = $disableRedirectGetParameterName;
69
+ $this->disableRedirectCookieName = $disableRedirectCookieName;
70
+ }
71
+
72
+ public function isDefaultRedirectDisabled()
73
+ {
74
+ return (bool)$this->config->getEnableDefaultRedirect();
75
+ }
76
+
77
+ public function isRedirectDisabled()
78
+ {
79
+ return
80
+ $this->isMobileHeaderDisabled()
81
+ || !empty($this->cookie[$this->disableRedirectCookieName])
82
+ || !empty($this->get[$this->disableRedirectGetParameterName]);
83
+ }
84
+
85
+ public function isMobileHeaderDisabled()
86
+ {
87
+ return !$this->config->getShopNumber() || !$this->config->getShopIsActive();
88
+ }
89
+
90
+ public function setCookie($startTime = null)
91
+ {
92
+ if ($startTime === null) {
93
+ $startTime = time();
94
+ }
95
+
96
+ setcookie(
97
+ $this->disableRedirectCookieName,
98
+ 1,
99
+ $startTime + $this->expiration,
100
+ '/'
101
+ );
102
+ }
103
+
104
+ public function getMobileUrl()
105
+ {
106
+ if ($this->config->getCname()) {
107
+ return $this->fixCname($this->config->getCname());
108
+ }
109
+
110
+ return rtrim('http://' . $this->config->getAlias() . $this->getShopgateUrl(), '/');
111
+ }
112
+
113
+ public function getRedirectableGetParameters()
114
+ {
115
+ return http_build_query(array_intersect_key($this->get, array_flip($this->config->getRedirectableGetParams())));
116
+ }
117
+
118
+ public function getHtmlTags()
119
+ {
120
+ $htmlTags = $this->config->getHtmlTags();
121
+
122
+ if (empty($htmlTags)) {
123
+ throw new ShopgateLibraryException(ShopgateLibraryException::CONFIG_INVALID_VALUE, '', false, false);
124
+ }
125
+
126
+ return $htmlTags;
127
+ }
128
+
129
+ public function getDefaultTemplatesByPageType()
130
+ {
131
+ $templatePageDefault = $this->isDefaultRedirectDisabled() ? false : '{baseUrl}';
132
+
133
+ return array(
134
+ Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_DEFAULT => $templatePageDefault,
135
+ Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_HOME => '{baseUrl}',
136
+ Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_PRODUCT => '{baseUrl}/item/{product_uid:hex}',
137
+ Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_CATEGORY => '{baseUrl}/category/{category_uid:hex}',
138
+ Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_CMS => '{baseUrl}/cms/{page_uid}',
139
+ Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_BRAND => '{baseUrl}/brand?q={brand_name:urlencoded}',
140
+ Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_SEARCH => '{baseUrl}/search?s={search_query:urlencoded}',
141
+ );
142
+ }
143
+
144
+ public function getShopgateStaticUrl()
145
+ {
146
+ $result = array();
147
+
148
+ switch ($this->config->getServer()) {
149
+ default: // fall through to 'live'
150
+ case 'live':
151
+ $result['ssl_url'] = self::SHOPGATE_STATIC_SSL;
152
+ $result['non_ssl_url'] = self::SHOPGATE_STATIC;
153
+ break;
154
+ case 'sl':
155
+ $result['ssl_url'] = self::SHOPGATE_SL_STATIC_SSL;
156
+ $result['non_ssl_url'] = self::SHOPGATE_SL_STATIC;
157
+ break;
158
+ case 'pg':
159
+ $result['ssl_url'] = self::SHOPGATE_PG_STATIC_SSL;
160
+ $result['non_ssl_url'] = self::SHOPGATE_PG_STATIC;
161
+ break;
162
+ case 'custom':
163
+ $result['ssl_url'] = self::SHOPGATE_DEV_STATIC_SSL;
164
+ $result['non_ssl_url'] = self::SHOPGATE_DEV_STATIC;
165
+ break;
166
+ }
167
+
168
+ return $result;
169
+ }
170
+
171
+ /**
172
+ * Returns the URL to be appended to the alias of a shop.
173
+ *
174
+ * The method determines this by the "server" setting in ShopgateConfig. If it's set to
175
+ * "custom", localdev.cc will be used for Shopgate local development and testing.
176
+ *
177
+ * @return string The URL that can be appended to the alias, e.g. ".shopgate.com"
178
+ */
179
+ protected function getShopgateUrl()
180
+ {
181
+ switch ($this->config->getServer()) {
182
+ default: // fall through to "live"
183
+ case 'live':
184
+ return self::SHOPGATE_LIVE_ALIAS;
185
+ case 'sl':
186
+ return self::SHOPGATE_SL_ALIAS;
187
+ case 'pg':
188
+ return self::SHOPGATE_PG_ALIAS;
189
+ case 'custom':
190
+ return self::SHOPGATE_DEV_ALIAS; // for Shopgate development & testing
191
+ }
192
+ }
193
+
194
+ /**
195
+ * Prepends http:// to the CNAME if it doesn't start with http:// or https:// already.
196
+ *
197
+ * @param string $cname
198
+ *
199
+ * @return string
200
+ */
201
+ protected function fixCname($cname)
202
+ {
203
+ if (!preg_match("/^(https?:\/\/\S+)?$/i", $cname)) {
204
+ $cname = "http://" . $cname;
205
+ }
206
+
207
+ return $cname;
208
+ }
209
+ }
lib/Shopgate/classes/helper/redirect/SettingsManagerInterface.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ interface Shopgate_Helper_Redirect_SettingsManagerInterface
25
+ {
26
+ const DISABLE_REDIRECT_COOKIE_EXPIRATION_1_WEEK = 604800;
27
+
28
+ const DEFAULT_DISABLE_REDIRECT_GET_PARAMETER_NAME = 'shopgate_redirect';
29
+ const DEFAULT_DISABLE_REDIRECT_COOKIE_NAME = 'SHOPGATE_MOBILE_WEBPAGE';
30
+
31
+ const SHOPGATE_STATIC = 'http://static.shopgate.com';
32
+ const SHOPGATE_STATIC_SSL = 'https://static-ssl.shopgate.com';
33
+
34
+ const SHOPGATE_PG_STATIC = 'http://static.shopgatepg.com';
35
+ const SHOPGATE_PG_STATIC_SSL = 'https://static-ssl.shopgatepg.com';
36
+
37
+ const SHOPGATE_SL_STATIC = 'http://static.shopgatesl.com';
38
+ const SHOPGATE_SL_STATIC_SSL = 'https://static-ssl.shopgatesl.com';
39
+
40
+ const SHOPGATE_DEV_STATIC = 'http://shopgatedev-public.s3.amazonaws.com';
41
+ const SHOPGATE_DEV_STATIC_SSL = 'https://shopgatedev-public.s3.amazonaws.com';
42
+
43
+ const SHOPGATE_LIVE_ALIAS = '.shopgate.com';
44
+ const SHOPGATE_SL_ALIAS = '.shopgatesl.com';
45
+ const SHOPGATE_PG_ALIAS = '.shopgatepg.com';
46
+ const SHOPGATE_DEV_ALIAS = '.localdev.cc/php/shopgate/index.php';
47
+
48
+ /**
49
+ * @return bool
50
+ */
51
+ public function isDefaultRedirectDisabled();
52
+
53
+ /**
54
+ * @return bool
55
+ */
56
+ public function isRedirectDisabled();
57
+
58
+ /**
59
+ * @return bool
60
+ */
61
+ public function isMobileHeaderDisabled();
62
+
63
+ /**
64
+ * Sends the cookie to disable the mobile redirect is sent to the requesting entity.
65
+ *
66
+ * @param int $startTime Pass null to use time().
67
+ */
68
+ public function setCookie($startTime = null);
69
+
70
+ /**
71
+ * Generates the root mobile Url for the redirect without trailing slashes.
72
+ */
73
+ public function getMobileUrl();
74
+
75
+ /**
76
+ * Filters the GET parameters that should be passed in the redirect and builds the new query string.
77
+ *
78
+ * @return string
79
+ */
80
+ public function getRedirectableGetParameters();
81
+
82
+ /**
83
+ * @return string
84
+ * @throws ShopgateLibraryException in case the configuration value is null.
85
+ */
86
+ public function getHtmlTags();
87
+
88
+ /**
89
+ * @return array [string, string]
90
+ */
91
+ public function getDefaultTemplatesByPageType();
92
+
93
+ /**
94
+ * @return array [string, string] An array with indices 'ssl_url' and 'non_ssl_url' and the corresponding URLs.
95
+ */
96
+ public function getShopgateStaticUrl();
97
+ }
lib/Shopgate/classes/helper/redirect/TagsGenerator.php ADDED
@@ -0,0 +1,249 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Helper_Redirect_TagsGenerator
25
+ extends ShopgateObject
26
+ implements Shopgate_Helper_Redirect_TagsGeneratorInterface
27
+ {
28
+ /** @var Shopgate_Helper_Redirect_LinkBuilderInterface */
29
+ protected $linkBuilder;
30
+
31
+ /** @var Shopgate_Helper_Redirect_TemplateParserInterface */
32
+ protected $templateParser;
33
+
34
+ /** @var Shopgate_Model_Redirect_HtmlTag[] */
35
+ protected $htmlTags;
36
+
37
+ /**
38
+ * @param Shopgate_Helper_Redirect_LinkBuilderInterface $linkBuilder
39
+ * @param Shopgate_Helper_Redirect_TemplateParserInterface $templateParser
40
+ */
41
+ public function __construct(
42
+ Shopgate_Helper_Redirect_LinkBuilderInterface $linkBuilder,
43
+ Shopgate_Helper_Redirect_TemplateParserInterface $templateParser
44
+ ) {
45
+ $this->linkBuilder = $linkBuilder;
46
+ $this->templateParser = $templateParser;
47
+ $this->htmlTags = array();
48
+ }
49
+
50
+ public function setHtmlTags(array $htmlTags)
51
+ {
52
+ $this->htmlTags = $htmlTags;
53
+ }
54
+
55
+ public function setHtmlTagsFromJson($htmlTags)
56
+ {
57
+ $this->htmlTags = array();
58
+ $htmlTags = $this->jsonDecode($htmlTags, true);
59
+
60
+ if (empty($htmlTags) || empty($htmlTags['html_tags'])) {
61
+ return;
62
+ }
63
+
64
+ foreach ($htmlTags['html_tags'] as $tag) {
65
+ if (empty($tag['name'])) {
66
+ continue;
67
+ }
68
+
69
+ $this->htmlTags[] = $this->createHtmlTag($tag);
70
+ }
71
+ }
72
+
73
+ public function getTagsFor($pageType, array $parameters = array())
74
+ {
75
+ $html = '';
76
+
77
+ foreach ($this->htmlTags as $tag) {
78
+ try {
79
+ $attributes = $this->getAttributes($pageType, $tag->getAttributes(), $parameters);
80
+ } catch (ShopgateLibraryException $e) {
81
+ continue; // skip tags with missing/unset variables
82
+ }
83
+
84
+ $html .= "<{$tag->getName()}{$attributes} />\n";
85
+ }
86
+
87
+ return $html;
88
+ }
89
+
90
+ /**
91
+ * @param array $tag
92
+ *
93
+ * @return Shopgate_Model_Redirect_HtmlTag
94
+ */
95
+ protected function createHtmlTag(array $tag)
96
+ {
97
+ $tagModel = new Shopgate_Model_Redirect_HtmlTag();
98
+ $tagModel->setName($tag['name']);
99
+
100
+ if (empty($tag['attributes'])) {
101
+ return $tagModel;
102
+ }
103
+
104
+ $attributes = array();
105
+ foreach ($tag['attributes'] as $attribute) {
106
+ if (empty($attribute['name'])) {
107
+ continue;
108
+ }
109
+
110
+ $attributes[] = $this->createHtmlTagAttribute($attribute);
111
+ }
112
+
113
+ $tagModel->setAttributes($attributes);
114
+
115
+ return $tagModel;
116
+ }
117
+
118
+ /**
119
+ * @param array $attribute
120
+ *
121
+ * @return Shopgate_Model_Redirect_HtmlTagAttribute
122
+ */
123
+ protected function createHtmlTagAttribute(array $attribute)
124
+ {
125
+ $attributeModel = new Shopgate_Model_Redirect_HtmlTagAttribute();
126
+ $attributeModel->setName($attribute['name']);
127
+ $attributeModel->setValue($attribute['value']);
128
+ $attributeModel->setVariables($this->templateParser->getVariables($attribute['value']));
129
+
130
+ if (!empty($attribute['deeplink_suffix'])) {
131
+ $attributeModel->setDeeplinkSuffix($this->createDeeplinkSuffixes($attribute['deeplink_suffix']));
132
+ }
133
+
134
+ return $attributeModel;
135
+ }
136
+
137
+ /**
138
+ * @param array $deeplinkSuffix
139
+ *
140
+ * @return Shopgate_Model_Redirect_DeeplinkSuffix
141
+ */
142
+ protected function createDeeplinkSuffixes(array $deeplinkSuffix)
143
+ {
144
+ $suffixModel = new Shopgate_Model_Redirect_DeeplinkSuffix();
145
+
146
+ foreach ($deeplinkSuffix as $name => $template) {
147
+ $valueModel = new Shopgate_Model_Redirect_DeeplinkSuffixValue();
148
+ $valueModel->setName($name);
149
+ $valueModel->setValue($template);
150
+
151
+ if ($template === false) {
152
+ $valueModel->setDisabled(true);
153
+ } else {
154
+ $valueModel->setVariables($this->templateParser->getVariables($template));
155
+ }
156
+
157
+ $suffixModel->addValue($name, $valueModel);
158
+ }
159
+
160
+ return $suffixModel;
161
+ }
162
+
163
+ /**
164
+ * @param string $pageType
165
+ * @param Shopgate_Model_Redirect_HtmlTagAttribute[] $attributes
166
+ * @param array $parameters [string, string]
167
+ *
168
+ * @return string
169
+ * @throws ShopgateLibraryException in case a variable is in the template but not set in the parameters.
170
+ */
171
+ protected function getAttributes($pageType, $attributes, array $parameters = array())
172
+ {
173
+ $attributesString = '';
174
+ foreach ($attributes as $attribute) {
175
+ if ($attribute->getDeeplinkSuffix()) {
176
+ $parameters['deeplink_suffix'] = $this->getDeeplinkSuffix(
177
+ $pageType,
178
+ $attribute->getDeeplinkSuffix(),
179
+ $parameters
180
+ );
181
+ }
182
+
183
+ $attributesString .= ' ' . $attribute->getName() . '="' .
184
+ $this->getVariables(
185
+ $attribute->getVariables(),
186
+ $attribute->getValue(),
187
+ $parameters
188
+ ) . '"';
189
+ }
190
+
191
+ return $attributesString;
192
+ }
193
+
194
+ /**
195
+ * @param Shopgate_Model_Redirect_HtmlTagVariable[] $variables
196
+ * @param string $template
197
+ * @param array $parameters [string, string]
198
+ *
199
+ * @return string
200
+ * @throws ShopgateLibraryException in case a variable is in the template but not set in the parameters.
201
+ */
202
+ protected function getVariables($variables, $template, array $parameters = array())
203
+ {
204
+ foreach ($variables as $variable) {
205
+ if (!isset($parameters[$variable->getName()])) {
206
+ // don't log, this is caught internally
207
+ throw new ShopgateLibraryException(ShopgateLibraryException::CONFIG_INVALID_VALUE, '', false, false);
208
+ }
209
+
210
+ $parameter = !isset($parameters[$variable->getName()])
211
+ ? ''
212
+ : $parameters[$variable->getName()];
213
+
214
+ $template = $this->templateParser->process(
215
+ $template,
216
+ $variable,
217
+ $parameter
218
+ );
219
+ }
220
+
221
+ return $template;
222
+ }
223
+
224
+ /**
225
+ * @param string $pageType
226
+ * @param Shopgate_Model_Redirect_DeeplinkSuffix $deeplinkSuffix
227
+ * @param array $parameters [string, string]
228
+ *
229
+ * @return string
230
+ * @throws ShopgateLibraryException
231
+ */
232
+ protected function getDeeplinkSuffix(
233
+ $pageType,
234
+ Shopgate_Model_Redirect_DeeplinkSuffix $deeplinkSuffix,
235
+ array $parameters = array()
236
+ ) {
237
+ $value = $deeplinkSuffix->getValue($pageType);
238
+
239
+ if ($value->getUnset()) {
240
+ $value = $deeplinkSuffix->getValue(Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_DEFAULT);
241
+ }
242
+
243
+ if ($value->getDisabled()) {
244
+ throw new ShopgateLibraryException(ShopgateLibraryException::CONFIG_INVALID_VALUE, '', false, false);
245
+ }
246
+
247
+ return $this->linkBuilder->getUrlFor($pageType, $value->getVariables(), $parameters, $value->getValue());
248
+ }
249
+ }
lib/Shopgate/classes/helper/redirect/TagsGeneratorInterface.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ interface Shopgate_Helper_Redirect_TagsGeneratorInterface
25
+ {
26
+ const PAGE_TYPE_DEFAULT = Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_DEFAULT;
27
+ const PAGE_TYPE_HOME = Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_HOME;
28
+ const PAGE_TYPE_PRODUCT = Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_PRODUCT;
29
+ const PAGE_TYPE_CATEGORY = Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_CATEGORY;
30
+ const PAGE_TYPE_CMS = Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_CMS;
31
+ const PAGE_TYPE_BRAND = Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_BRAND;
32
+ const PAGE_TYPE_SEARCH = Shopgate_Helper_Redirect_LinkBuilderInterface::LINK_TYPE_SEARCH;
33
+
34
+ const SITE_PARAMETER_SITENAME = 'sitename';
35
+ const SITE_PARAMETER_DESKTOP_URL = 'desktop_url';
36
+ const SITE_PARAMETER_MOBILE_WEB_URL = 'mobile_web_url';
37
+ const SITE_PARAMETER_TITLE = 'title';
38
+ const SITE_PARAMETER_PRODUCT_IMAGE = 'product_image';
39
+ const SITE_PARAMETER_PRODUCT_NAME = 'product_name';
40
+ const SITE_PARAMETER_PRODUCT_DESCRIPTION_SHORT = 'product_description_short';
41
+ const SITE_PARAMETER_PRODUCT_EAN = 'product_ean';
42
+ const SITE_PARAMETER_PRODUCT_AVAILABILITY = 'product_availability';
43
+ const SITE_PARAMETER_PRODUCT_CATEGORY = 'product_category';
44
+ const SITE_PARAMETER_PRODUCT_PRICE = 'product_price';
45
+ const SITE_PARAMETER_PRODUCT_CURRENCY = 'product_currency';
46
+ const SITE_PARAMETER_PRODUCT_PRETAX_PRICE = 'product_pretax_price';
47
+ const SITE_PARAMETER_PRODUCT_PRETAX_CURRENCY = 'product_pretax_currency';
48
+
49
+ /**
50
+ * @param Shopgate_Model_Redirect_HtmlTag[] $htmlTags
51
+ */
52
+ public function setHtmlTags(array $htmlTags);
53
+
54
+ /**
55
+ * @param string $htmlTags A JSON encoded string containing the HTML tags.
56
+ */
57
+ public function setHtmlTagsFromJson($htmlTags);
58
+
59
+ /**
60
+ * @param string $pageType
61
+ * @param array $parameters [string, string]
62
+ *
63
+ * @return string
64
+ */
65
+ public function getTagsFor($pageType, array $parameters = array());
66
+ }
lib/Shopgate/classes/helper/redirect/TemplateParser.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Helper_Redirect_TemplateParser implements Shopgate_Helper_Redirect_TemplateParserInterface
25
+ {
26
+ public function getVariables($template)
27
+ {
28
+ $matches = array();
29
+ if (!preg_match_all('/{(?<variables>[^}]+)?}/', $template, $matches)) {
30
+ return array();
31
+ }
32
+
33
+ $variables = array();
34
+ foreach ($matches['variables'] as $variable) {
35
+ $parts = explode(':', $variable);
36
+
37
+ $variable = new Shopgate_Model_Redirect_HtmlTagVariable();
38
+ $variable->setName($parts[0]);
39
+
40
+ if (!empty($parts[1])) {
41
+ $variable->setFunctionName($parts[1]);
42
+ }
43
+
44
+ $variables[] = $variable;
45
+ }
46
+
47
+ return $variables;
48
+ }
49
+
50
+ public function process($template, $variable, $replacement)
51
+ {
52
+ $variableString = '{' . $variable->getName();
53
+
54
+ if ($variable->getFunctionName()) {
55
+ $variableString .= ':' . $variable->getFunctionName();
56
+ }
57
+
58
+ $variableString .= '}';
59
+
60
+ return str_replace(
61
+ $variableString,
62
+ $this->filterVariableValue($replacement, $variable->getFunctionName()),
63
+ $template
64
+ );
65
+ }
66
+
67
+ public function filterVariableValue($value, $functionName = '')
68
+ {
69
+ switch ($functionName) {
70
+ case Shopgate_Helper_Redirect_TemplateParserInterface::FUNCTION_NAME_HEX:
71
+ return bin2hex($value);
72
+ case Shopgate_Helper_Redirect_TemplateParserInterface::FUNCTION_NAME_URLENCODED:
73
+ return urlencode($value);
74
+ case Shopgate_Helper_Redirect_TemplateParserInterface::FUNCTION_NAME_BASE64:
75
+ return base64_encode($value);
76
+ case Shopgate_Helper_Redirect_TemplateParserInterface::FUNCTION_NAME_ESCAPED:
77
+ return addslashes($value);
78
+ }
79
+
80
+ return $value;
81
+ }
82
+ }
lib/Shopgate/classes/helper/redirect/TemplateParserInterface.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ interface Shopgate_Helper_Redirect_TemplateParserInterface
25
+ {
26
+ const FUNCTION_NAME_HEX = 'hex';
27
+ const FUNCTION_NAME_URLENCODED = 'urlencoded';
28
+ const FUNCTION_NAME_BASE64 = 'base64';
29
+ const FUNCTION_NAME_ESCAPED = 'escaped';
30
+
31
+ /**
32
+ * @param $template
33
+ *
34
+ * @return Shopgate_Model_Redirect_HtmlTagVariable[]
35
+ */
36
+ public function getVariables($template);
37
+
38
+ /**
39
+ * @param string $template
40
+ * @param Shopgate_Model_Redirect_HtmlTagVariable $variable
41
+ * @param string $replacement
42
+ *
43
+ * @return string
44
+ */
45
+ public function process($template, $variable, $replacement);
46
+
47
+ /**
48
+ * @param string $value
49
+ * @param string $functionName
50
+ *
51
+ * @return string
52
+ */
53
+ public function filterVariableValue($value, $functionName = '');
54
+ }
lib/Shopgate/classes/models/redirect/DeeplinkSuffix.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Model_Redirect_DeeplinkSuffix extends Shopgate_Model_Abstract
25
+ {
26
+ /** @var Shopgate_Model_Redirect_DeeplinkSuffixValue [string, Shopgate_Model_Redirect_DeeplinkSuffixValue] */
27
+ protected $valuesByType;
28
+
29
+ /**
30
+ * @param string $type
31
+ * @param Shopgate_Model_Redirect_DeeplinkSuffixValue $value
32
+ */
33
+ public function addValue($type, Shopgate_Model_Redirect_DeeplinkSuffixValue $value)
34
+ {
35
+ $this->valuesByType[$type] = $value;
36
+ }
37
+
38
+ /**
39
+ * @param string $type
40
+ *
41
+ * @return Shopgate_Model_Redirect_DeeplinkSuffixValue
42
+ */
43
+ public function getValue($type)
44
+ {
45
+ if (!isset($this->valuesByType[$type]) || ($this->valuesByType[$type] === null)) {
46
+ return new Shopgate_Model_Redirect_DeeplinkSuffixValueUnset();
47
+ }
48
+
49
+ if ($this->valuesByType[$type] === false) {
50
+ return new Shopgate_Model_Redirect_DeeplinkSuffixValueDisabled();
51
+ }
52
+
53
+ return $this->valuesByType[$type];
54
+ }
55
+ }
lib/Shopgate/classes/models/redirect/DeeplinkSuffixValue.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ *
24
+ * @method setName(string $value)
25
+ * @method string getName()
26
+ *
27
+ * @method setValue(string $value)
28
+ * @method string getValue()
29
+ *
30
+ * @method setUnset(bool $value)
31
+ * @method bool getUnset()
32
+ *
33
+ * @method setDisabled(bool $value)
34
+ * @method bool getDisabled()
35
+ *
36
+ * @method setVariables(array $value)
37
+ * @method Shopgate_Model_Redirect_HtmlTagVariable[] getVariables()
38
+ */
39
+ class Shopgate_Model_Redirect_DeeplinkSuffixValue extends Shopgate_Model_Abstract
40
+ {
41
+ public function __construct()
42
+ {
43
+ $this->allowedMethods = array(
44
+ 'Name',
45
+ 'Value',
46
+ 'Unset',
47
+ 'Disabled',
48
+ 'Variables',
49
+ );
50
+
51
+ $this->setVariables(array());
52
+ }
53
+ }
lib/Shopgate/classes/models/redirect/DeeplinkSuffixValueDisabled.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Model_Redirect_DeeplinkSuffixValueDisabled extends Shopgate_Model_Redirect_DeeplinkSuffixValue
25
+ {
26
+ public function __construct()
27
+ {
28
+ parent::__construct();
29
+
30
+ $this->setDisabled(true);
31
+ }
32
+ }
lib/Shopgate/classes/models/redirect/DeeplinkSuffixValueUnset.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ */
24
+ class Shopgate_Model_Redirect_DeeplinkSuffixValueUnset extends Shopgate_Model_Redirect_DeeplinkSuffixValue
25
+ {
26
+ public function __construct()
27
+ {
28
+ parent::__construct();
29
+
30
+ $this->setUnset(true);
31
+ }
32
+ }
lib/Shopgate/classes/models/redirect/HtmlTag.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ *
24
+ * @method setName(string $value)
25
+ * @method string getName()
26
+ *
27
+ * @method setAttributes(array $value)
28
+ * @method Shopgate_Model_Redirect_HtmlTagAttribute[] getAttributes()
29
+ */
30
+ class Shopgate_Model_Redirect_HtmlTag extends Shopgate_Model_Abstract
31
+ {
32
+ public function __construct()
33
+ {
34
+ $this->allowedMethods = array(
35
+ 'Name',
36
+ 'Attributes',
37
+ );
38
+ }
39
+ }
lib/Shopgate/classes/models/redirect/HtmlTagAttribute.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ *
24
+ * @method setName(string $value)
25
+ * @method string getName()
26
+ *
27
+ * @method setValue(string $value)
28
+ * @method string getValue()
29
+ *
30
+ * @method setDeeplinkSuffix(Shopgate_Model_Redirect_DeeplinkSuffix $value)
31
+ * @method Shopgate_Model_Redirect_DeeplinkSuffix getDeeplinkSuffix()
32
+ *
33
+ * @method setVariables(array $value)
34
+ * @method Shopgate_Model_Redirect_HtmlTagVariable[] getVariables()
35
+ */
36
+ class Shopgate_Model_Redirect_HtmlTagAttribute extends Shopgate_Model_Abstract
37
+ {
38
+ public function __construct()
39
+ {
40
+ $this->allowedMethods = array(
41
+ 'Name',
42
+ 'Value',
43
+ 'DeeplinkSuffix',
44
+ 'Variables',
45
+ );
46
+ }
47
+ }
lib/Shopgate/classes/models/redirect/HtmlTagVariable.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Shopgate GmbH
5
+ *
6
+ * URHEBERRECHTSHINWEIS
7
+ *
8
+ * Dieses Plugin ist urheberrechtlich geschützt. Es darf ausschließlich von Kunden der Shopgate GmbH
9
+ * zum Zwecke der eigenen Kommunikation zwischen dem IT-System des Kunden mit dem IT-System der
10
+ * Shopgate GmbH über www.shopgate.com verwendet werden. Eine darüber hinausgehende Vervielfältigung, Verbreitung,
11
+ * öffentliche Zugänglichmachung, Bearbeitung oder Weitergabe an Dritte ist nur mit unserer vorherigen
12
+ * schriftlichen Zustimmung zulässig. Die Regelungen der §§ 69 d Abs. 2, 3 und 69 e UrhG bleiben hiervon unberührt.
13
+ *
14
+ * COPYRIGHT NOTICE
15
+ *
16
+ * This plugin is the subject of copyright protection. It is only for the use of Shopgate GmbH customers,
17
+ * for the purpose of facilitating communication between the IT system of the customer and the IT system
18
+ * of Shopgate GmbH via www.shopgate.com. Any reproduction, dissemination, public propagation, processing or
19
+ * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
20
+ * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
21
+ *
22
+ * @author Shopgate GmbH <interfaces@shopgate.com>
23
+ *
24
+ * @method setName(string $value)
25
+ * @method string getName()
26
+ *
27
+ * @method setFunctionName(string $value)
28
+ * @method string getFunctionName()
29
+ */
30
+ class Shopgate_Model_Redirect_HtmlTagVariable extends Shopgate_Model_Abstract
31
+ {
32
+ public function __construct()
33
+ {
34
+ $this->allowedMethods = array(
35
+ 'Name',
36
+ 'FunctionName',
37
+ );
38
+ }
39
+ }
lib/Shopgate/classes/redirect.php CHANGED
@@ -18,9 +18,11 @@
18
  * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
19
  * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
20
  *
21
- * @author Shopgate GmbH <interfaces@shopgate.com>
 
22
  */
23
- class ShopgateMobileRedirect extends ShopgateObject implements ShopgateMobileRedirectInterface {
 
24
  /**
25
  * @var string alias name of shop at Shopgate, e.g. 'yourshop' to redirect to 'http://yourshop.shopgate.com'
26
  */
@@ -156,16 +158,25 @@ class ShopgateMobileRedirect extends ShopgateObject implements ShopgateMobileRed
156
  * @var boolean determines if for a specific case the mobile redirect should be suppressed
157
  */
158
  protected $suppressRedirect;
159
-
 
 
 
160
  /**
161
  * Instantiates the Shopgate mobile redirector.
162
  *
163
- * @param ShopgateConfig $shopgateConfig An instance of the ShopgateConfig
164
- * @param ShopgateMerchantApiInterface $merchantApi An instance of the ShopgateMerchantApi required for keyword updates or null.
165
- */
166
- public function __construct(ShopgateConfig $shopgateConfig, ShopgateMerchantApiInterface $merchantApi = null) {
167
- $this->merchantApi = $merchantApi;
168
- $this->config = $shopgateConfig;
 
 
 
 
 
 
169
  $this->setAlias($shopgateConfig->getAlias());
170
  $this->setCustomMobileUrl($shopgateConfig->getCname());
171
 
@@ -358,6 +369,50 @@ class ShopgateMobileRedirect extends ShopgateObject implements ShopgateMobileRed
358
  $linkTag = '';
359
  if ($this->config->getShopIsActive() && !$this->suppressRedirect) {
360
  $linkTag = $this->loadTemplate($this->linkTagTemplatePath);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  }
362
 
363
  if (!$this->config->getShopNumber()) {
@@ -456,13 +511,13 @@ class ShopgateMobileRedirect extends ShopgateObject implements ShopgateMobileRed
456
  }
457
 
458
  // set parameters
459
- $html = str_replace('{$link_tag}', $linkTag, $html);
460
- $html = str_replace('{$mobile_url}', $mobileRedirectUrl, $html);
461
- $html = str_replace('{$shop_number}', $this->config->getShopNumber(), $html);
462
- $html = str_replace('{$redirect_code}', $redirectCode, $html);
463
- $html = str_replace('{$additional_parameters}', $additionalParameters, $html);
464
- $html = str_replace('{$ssl_url}', $sslUrl, $html);
465
- $html = str_replace('{$non_ssl_url}', $nonSslUrl, $html);
466
 
467
  return $html;
468
  }
@@ -697,7 +752,7 @@ class ShopgateMobileRedirect extends ShopgateObject implements ShopgateMobileRed
697
  }
698
 
699
  public function buildScriptSearch($searchQuery, $autoRedirect = true){
700
- $this->searchQuery = $searchQuery;
701
  $this->redirectType = 'search';
702
 
703
  $this->setAdditionalHttpHeaders();
@@ -743,7 +798,7 @@ class ShopgateMobileRedirect extends ShopgateObject implements ShopgateMobileRed
743
  * browser.
744
  *
745
  * @author Shopgate GmbH, 35510 Butzbach, DE
746
- *
747
  */
748
  interface ShopgateMobileRedirectInterface {
749
  const SHOPGATE_STATIC = 'http://static.shopgate.com';
18
  * transfer to third parties is only permitted where we previously consented thereto in writing. The provisions
19
  * of paragraph 69 d, sub-paragraphs 2, 3 and paragraph 69, sub-paragraph e of the German Copyright Act shall remain unaffected.
20
  *
21
+ * @author Shopgate GmbH <interfaces@shopgate.com>
22
+ * @deprecated Will be removed in 3.0.0. Use Shopgate_Helper_Redirect_MobileRedirect instead.
23
  */
24
+ class ShopgateMobileRedirect extends ShopgateObject implements ShopgateMobileRedirectInterface
25
+ {
26
  /**
27
  * @var string alias name of shop at Shopgate, e.g. 'yourshop' to redirect to 'http://yourshop.shopgate.com'
28
  */
158
  * @var boolean determines if for a specific case the mobile redirect should be suppressed
159
  */
160
  protected $suppressRedirect;
161
+
162
+ /** @var Shopgate_Helper_Redirect_TagsGeneratorInterface */
163
+ protected $tagsGenerator;
164
+
165
  /**
166
  * Instantiates the Shopgate mobile redirector.
167
  *
168
+ * @param ShopgateConfigInterface $shopgateConfig An instance of the ShopgateConfig
169
+ * @param ShopgateMerchantApiInterface $merchantApi An instance of the ShopgateMerchantApi required for keyword updates or null.
170
+ * @param Shopgate_Helper_Redirect_TagsGeneratorInterface $tagsGenerator
171
+ */
172
+ public function __construct(
173
+ ShopgateConfigInterface $shopgateConfig,
174
+ ShopgateMerchantApiInterface $merchantApi = null,
175
+ Shopgate_Helper_Redirect_TagsGeneratorInterface $tagsGenerator = null
176
+ ) {
177
+ $this->tagsGenerator = $tagsGenerator;
178
+ $this->merchantApi = $merchantApi;
179
+ $this->config = $shopgateConfig;
180
  $this->setAlias($shopgateConfig->getAlias());
181
  $this->setCustomMobileUrl($shopgateConfig->getCname());
182
 
369
  $linkTag = '';
370
  if ($this->config->getShopIsActive() && !$this->suppressRedirect) {
371
  $linkTag = $this->loadTemplate($this->linkTagTemplatePath);
372
+
373
+ $htmlTags = $this->config->getHtmlTags();
374
+ if (!empty($htmlTags) && !empty($this->tagsGenerator)) {
375
+ $this->tagsGenerator->setHtmlTagsFromJson($htmlTags);
376
+ $types = array(
377
+ 'item' => array(
378
+ 'pageType' => Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_PRODUCT,
379
+ 'parameters' => array('product_uid' => $this->itemNumber),
380
+ ),
381
+ 'itempublic' => array(
382
+ 'pageType' => Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_PRODUCT,
383
+ 'parameters' => array('product_uid' => $this->itemNumberPublic),
384
+ ),
385
+ 'category' => array(
386
+ 'pageType' => Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_CATEGORY,
387
+ 'parameters' => array('category_uid' => $this->categoryNumber),
388
+ ),
389
+ 'cms' => array(
390
+ 'pageType' => Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_CMS,
391
+ 'parameters' => array('page_uid' => $this->cmsPage),
392
+ ),
393
+ 'brand' => array(
394
+ 'pageType' => Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_BRAND,
395
+ 'parameters' => array('brand_name' => $this->manufacturerName),
396
+ ),
397
+ 'search' => array(
398
+ 'pageType' => Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_SEARCH,
399
+ 'parameters' => array('search_query' => addslashes($this->searchQuery)),
400
+ ),
401
+ 'start' => array(
402
+ 'pageType' => Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_HOME,
403
+ 'parameters' => array(),
404
+ ),
405
+ 'default' => array(
406
+ 'pageType' => Shopgate_Helper_Redirect_TagsGeneratorInterface::PAGE_TYPE_DEFAULT,
407
+ 'parameters' => array(),
408
+ ),
409
+ );
410
+
411
+ $linkTag = $this->tagsGenerator->getTagsFor(
412
+ $types[$this->redirectType]['pageType'],
413
+ $types[$this->redirectType]['parameters']
414
+ );
415
+ }
416
  }
417
 
418
  if (!$this->config->getShopNumber()) {
511
  }
512
 
513
  // set parameters
514
+ $html = str_replace('{link_tags}', $linkTag, $html);
515
+ $html = str_replace('{mobile_url}', $mobileRedirectUrl, $html);
516
+ $html = str_replace('{shop_number}', $this->config->getShopNumber(), $html);
517
+ $html = str_replace('{redirect_code}', $redirectCode, $html);
518
+ $html = str_replace('{additional_parameters}', $additionalParameters, $html);
519
+ $html = str_replace('{ssl_url}', $sslUrl, $html);
520
+ $html = str_replace('{non_ssl_url}', $nonSslUrl, $html);
521
 
522
  return $html;
523
  }
752
  }
753
 
754
  public function buildScriptSearch($searchQuery, $autoRedirect = true){
755
+ $this->searchQuery = addslashes($searchQuery);
756
  $this->redirectType = 'search';
757
 
758
  $this->setAdditionalHttpHeaders();
798
  * browser.
799
  *
800
  * @author Shopgate GmbH, 35510 Butzbach, DE
801
+ * @deprecated Will be removed in 3.0.0. Use Shopgate_Helper_Redirect_MobileRedirect instead.
802
  */
803
  interface ShopgateMobileRedirectInterface {
804
  const SHOPGATE_STATIC = 'http://static.shopgate.com';
lib/Shopgate/shopgate.php CHANGED
@@ -26,7 +26,7 @@ if (!defined('DS')) define('DS', '/');
26
  if( file_exists(dirname(__FILE__).DS.'dev.php') )
27
  require_once(dirname(__FILE__).DS.'dev.php');
28
 
29
- // Library
30
  require_once(dirname(__FILE__).DS.'classes'.DS.'core.php');
31
  require_once(dirname(__FILE__).DS.'classes'.DS.'apis.php');
32
  require_once(dirname(__FILE__).DS.'classes'.DS.'configuration.php');
@@ -36,21 +36,17 @@ require_once(dirname(__FILE__).DS.'classes'.DS.'external_orders.php');
36
  require_once(dirname(__FILE__).DS.'classes'.DS.'items.php');
37
  require_once(dirname(__FILE__).DS.'classes'.DS.'redirect.php');
38
 
39
- /**
40
- * global
41
- */
42
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/Abstract.php');
43
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/AbstractExport.php');
44
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/XmlEmptyObject.php');
45
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/XmlResultObject.php');
46
- /**
47
- * catalog
48
- */
49
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Review.php');
50
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Product.php');
51
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Price.php');
52
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/TierPrice.php');
53
-
54
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Category.php');
55
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/CategoryPath.php');
56
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Shipping.php');
@@ -68,20 +64,38 @@ require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Option.php');
68
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/AttributeGroup.php');
69
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Attribute.php');
70
 
71
- /**
72
- * helper
73
- */
 
 
 
 
 
 
 
 
 
 
 
74
  require_once(dirname(__FILE__).DS.'classes'.DS.'helper/DataStructure.php');
75
  require_once(dirname(__FILE__).DS.'classes'.DS.'helper/Pricing.php');
76
  require_once(dirname(__FILE__).DS.'classes'.DS.'helper/String.php');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
- /**
79
- * media
80
- */
81
- require_once(dirname(__FILE__).DS.'classes'.DS.'models/media/Image.php');
82
-
83
- // Shopgate-Vendors
84
  require_once(dirname(__FILE__).DS.'vendors'.DS.'2d_is.php');
85
-
86
- // External-Vendors
87
  include_once(dirname(__FILE__).DS.'vendors'.DS.'JSON.php');
26
  if( file_exists(dirname(__FILE__).DS.'dev.php') )
27
  require_once(dirname(__FILE__).DS.'dev.php');
28
 
29
+ // core
30
  require_once(dirname(__FILE__).DS.'classes'.DS.'core.php');
31
  require_once(dirname(__FILE__).DS.'classes'.DS.'apis.php');
32
  require_once(dirname(__FILE__).DS.'classes'.DS.'configuration.php');
36
  require_once(dirname(__FILE__).DS.'classes'.DS.'items.php');
37
  require_once(dirname(__FILE__).DS.'classes'.DS.'redirect.php');
38
 
39
+ // models (global / abstract)
 
 
40
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/Abstract.php');
41
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/AbstractExport.php');
42
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/XmlEmptyObject.php');
43
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/XmlResultObject.php');
44
+
45
+ // models (catalog)
 
46
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Review.php');
47
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Product.php');
48
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Price.php');
49
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/TierPrice.php');
 
50
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Category.php');
51
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/CategoryPath.php');
52
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Shipping.php');
64
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/AttributeGroup.php');
65
  require_once(dirname(__FILE__).DS.'classes'.DS.'models/catalog/Attribute.php');
66
 
67
+ // models (media)
68
+ require_once(dirname(__FILE__).DS.'classes'.DS.'models/media/Image.php');
69
+ //require_once(dirname(__FILE__).DS.'classes'.DS.'models/media/Attachment.php');
70
+
71
+ // models (redirect)
72
+ require_once(dirname(__FILE__).DS.'classes'.DS.'models/redirect/DeeplinkSuffix.php');
73
+ require_once(dirname(__FILE__).DS.'classes'.DS.'models/redirect/DeeplinkSuffixValue.php');
74
+ require_once(dirname(__FILE__).DS.'classes'.DS.'models/redirect/DeeplinkSuffixValueUnset.php');
75
+ require_once(dirname(__FILE__).DS.'classes'.DS.'models/redirect/DeeplinkSuffixValueDisabled.php');
76
+ require_once(dirname(__FILE__).DS.'classes'.DS.'models/redirect/HtmlTag.php');
77
+ require_once(dirname(__FILE__).DS.'classes'.DS.'models/redirect/HtmlTagAttribute.php');
78
+ require_once(dirname(__FILE__).DS.'classes'.DS.'models/redirect/HtmlTagVariable.php');
79
+
80
+ // helpers
81
  require_once(dirname(__FILE__).DS.'classes'.DS.'helper/DataStructure.php');
82
  require_once(dirname(__FILE__).DS.'classes'.DS.'helper/Pricing.php');
83
  require_once(dirname(__FILE__).DS.'classes'.DS.'helper/String.php');
84
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/KeywordsManagerInterface.php');
85
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/KeywordsManager.php');
86
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/LinkBuilderInterface.php');
87
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/LinkBuilder.php');
88
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/MobileRedirectInterface.php');
89
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/MobileRedirect.php');
90
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/RedirectorInterface.php');
91
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/Redirector.php');
92
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/SettingsManagerInterface.php');
93
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/SettingsManager.php');
94
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/TagsGeneratorInterface.php');
95
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/TagsGenerator.php');
96
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/TemplateParserInterface.php');
97
+ require_once(dirname(__FILE__).DS.'classes'.DS.'helper/redirect/TemplateParser.php');
98
 
99
+ // vendors
 
 
 
 
 
100
  require_once(dirname(__FILE__).DS.'vendors'.DS.'2d_is.php');
 
 
101
  include_once(dirname(__FILE__).DS.'vendors'.DS.'JSON.php');
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>shopgate_module</name>
4
- <version>2.9.26</version>
5
  <stability>stable</stability>
6
  <license uri="http://wiki.shopgate.com/Magento/de">Shopgate Plugin</license>
7
  <channel>community</channel>
@@ -10,9 +10,9 @@
10
  <description>Shopgate Plugin</description>
11
  <notes>Shopgate Modul</notes>
12
  <authors><author><name>Peter Liebig</name><user>Shopgate</user><email>p.liebig@me.com</email></author><author><name>Stephan Recknagel</name><user>Shopgate</user><email>mail@recknagel.io</email></author><author><name>Andr&#xE9; Kraus</name><user>Shopgate</user><email>andre.kraus83@googlemail.com</email></author></authors>
13
- <date>2015-11-24</date>
14
- <time>13:05:47</time>
15
- <contents><target name="mageetc"><dir name="modules"><file name="Shopgate_Framework.xml" hash="3fb114204bd038da711122083876f161"/></dir></target><target name="magecommunity"><dir name="Shopgate"><dir name="Framework"><dir name="Block"><dir name="Adminhtml"><dir name="OAuth"><dir name="Config"><file name="Connector.php" hash="890d04b08bf692c12b02f29abf813f83"/></dir><dir name="Connect"><dir name="Add"><file name="Form.php" hash="45685099b41a46919a9900d22c30b711"/></dir><file name="Info.php" hash="ee7bbc837bf3f298791b8496f2d6d565"/><file name="Overlay.php" hash="a6496896dccb5898b36e3e65585650f4"/></dir><file name="Connect.php" hash="cc7e43ba447b6338f6c50ccaa5fd073a"/><file name="Data.php" hash="1903e819d5d16abba4c37d7823909260"/><file name="Disconnect.php" hash="2545e56bca73577ba5f73fce0501624a"/><dir name="Manage"><file name="Grid.php" hash="78357b78fed0e8b3535a7e505c8f6425"/></dir><file name="Manage.php" hash="a99e12333f7c27771ca42a0764108639"/></dir></dir><file name="Info.php" hash="3dd73900370546289a6033942a0c0528"/><dir name="Payment"><file name="MobilePayment.php" hash="7de8af7ec46e107c46a73efaf2a02034"/><file name="Shopgate.php" hash="67af406fa04da70461b3580b8adea89d"/></dir><dir name="Totals"><file name="AbstractPaymentFee.php" hash="5e36647f536d1c6daba33cd6e0a5e302"/><file name="CreditmemoPaymentFee.php" hash="4a287f54554d8d45772db386f54a45e7"/><file name="InvoicePaymentFee.php" hash="818164536fe249016af3046aef73f181"/><file name="OrderPaymentFee.php" hash="55c8f62c4da8014c99414ece9cd125c4"/></dir><file name="Version.php" hash="2f45712bb20635ac17d8bdee213819e5"/></dir><dir name="Helper"><dir name="Billsafe"><file name="Order.php" hash="474c2aa15f352224c11c8ab17e921c9d"/></dir><file name="Config.php" hash="b0e489659332274686965e5e8d200d88"/><file name="Coupon.php" hash="519697b13040ddfbc8f460b6034c8779"/><file name="Customer.php" hash="c68047909c0c6e14977336ab6afe2f6b"/><file name="Data.php" hash="bf2db8a0a2c145cdb50f891f6d45ba85"/><file name="Debug.php" hash="82c85038046fc9b2f994df18b7f202a6"/><file name="Export.php" hash="f3b4bc188013333c063d74ee7a607a65"/><dir name="Import"><file name="Order.php" hash="adf21efa29fdba12edfaf0d34e0cb1fb"/></dir><file name="Install.php" hash="57f42693c9a6ddb18b8a25a2a5da7cf8"/><dir name="Payment"><file name="Abstract.php" hash="207f16aab8224761b7d91802b9fb10ee"/><file name="Payone.php" hash="ddced5955ff55105d8b3c91e0fcb0778"/><file name="Wspp.php" hash="4214f1d3332cd189cee3df48108ebd8d"/></dir><file name="Sales.php" hash="a5dfa9e90343a4da4e0791f62b802484"/></dir><dir name="Model"><dir name="Carrier"><file name="Fix.php" hash="31ccd9b4c8ac725e5b2c1dcee096dea8"/></dir><dir name="Cataloginventory"><file name="Stock.php" hash="42ffccc3d644f8b04358a3e76bda32dd"/></dir><dir name="Compiler"><file name="Process.php" hash="740452b7bc234417788db1f1ee892ef5"/></dir><file name="Config.php" hash="517c0cb6067762fcc10496f12ff43e22"/><file name="Customer.php" hash="97ed53ca3f69c7a24fb40cce11f58721"/><dir name="DreamRobot"><file name="Observer.php" hash="7b4e8922a46f5974b8edf359c632a9d3"/></dir><dir name="Export"><file name="Abstract.php" hash="9e86667845e8cebd8e0ccb8879b70b6d"/><dir name="Category"><file name="Csv.php" hash="72f4f58345d95f8f621783bedf2a092e"/><file name="Xml.php" hash="12ab046b9a000636ed4ed5eefb770af2"/></dir><file name="Category.php" hash="5a41141ecec85669674ec818c4661cdc"/><dir name="Customer"><file name="Orders.php" hash="30123a6fe3e391fca911fed042b256c8"/></dir><file name="Customer.php" hash="2711476c9538a22242d1511649ec77f1"/><dir name="Product"><file name="Csv.php" hash="50cd5a66e8034f3584140f91b56fe03d"/><file name="Xml.php" hash="dab076d305d805d4ada6e5649d4fb7d8"/></dir><file name="Product.php" hash="d9c807df57af3f1cced2d9bb433338ec"/><dir name="Review"><file name="Csv.php" hash="5c72f802a2de256ca1ec8dab1b75b291"/><file name="Xml.php" hash="bc16f60d9ed20705422921955a5071fe"/></dir><file name="Review.php" hash="ad6f548035a30da642d2459354acbb40"/><file name="Settings.php" hash="bd868e74806ec79e93c0fb6f4fcfdd3f"/></dir><file name="Feed.php" hash="fb99cd7b2b3d94908848b722df666b67"/><dir name="Mobile"><file name="Redirect.php" hash="8915ada38de387aabb2dc4580368d347"/></dir><dir name="Mysql4"><dir name="Core"><file name="Core.php" hash="fc129d4d929f83e8389367b9c5d6d5e1"/></dir><dir name="Customer"><file name="Collection.php" hash="89d31997abc3c2145f74e02dd5456a7c"/></dir><file name="Customer.php" hash="d5f460b2d5bfa87b8368a8a6c6b51115"/><file name="Product.php" hash="6a99b3d0de44dfbd132ce9caca19034e"/><dir name="Shopgate"><dir name="Order"><file name="Collection.php" hash="e180ba816be47239828bea65cd5f8445"/></dir><file name="Order.php" hash="c297847e39ad01307dba4a69c13445f2"/></dir></dir><file name="Observer.php" hash="e43ed49cd3058d31c64124dc54dd6a6a"/><dir name="Payment"><dir name="Abstract"><file name="AbstractPayol.php" hash="0228e80536a7decbbc0a883a4bde0d0d"/></dir><file name="Abstract.php" hash="873534555f767d24d1b0ab378267e8b9"/><file name="Amazon.php" hash="c90003246111cf066270015b41cb7ff9"/><file name="Authorize.php" hash="6f747fb258e59137cc5dadc179664246"/><file name="Billsafe.php" hash="1c97ec04356ae4ed25c1492a317eaaff"/><dir name="Cc"><file name="Abstract.php" hash="2b291ac14d9e1e3120416d6aeb4c3487"/><file name="Authn.php" hash="5c4c0d849d8d22dab1e6bf374dfc6c79"/><file name="AuthnAbstract.php" hash="59c3e39376e695ac161d228fc9a3fabf"/><dir name="Authncim"><file name="Gateway.php" hash="1f8df3fe0e50f4729bebfc1d4763b015"/><file name="Method.php" hash="aa6916548a71848ad7c83e4f053bc27e"/></dir><file name="Authncim.php" hash="89f1c2a0bb59d08c895da84c14c325ff"/><file name="Chargeitpro.php" hash="6fd3a2fd42df00831d6e363a23a414f1"/><file name="Usaepay.php" hash="00bd8969c1eceb13eacbb37ed9a1f714"/></dir><file name="Cc.php" hash="076a0faf0705c821c5479a2ec4a33c8d"/><file name="Express.php" hash="242b1fc3b238b907ac616680aa446401"/><file name="Factory.php" hash="212e33a78fc1e175d778347c4e4cffee"/><file name="Generic.php" hash="666f06186d1bb96b94af287d221e27c5"/><dir name="Ins"><file name="Payol.php" hash="b6961c4ab1fb9a95ab2d470aeaad8d29"/></dir><file name="Interface.php" hash="151002297bcce208b85bd260c7a25b47"/><dir name="Inv"><file name="Payol.php" hash="6d1c28b2ea2fb2fd63e09712f4533c77"/></dir><file name="MobilePayment.php" hash="59554c65e778831f6add450e0f846f42"/><dir name="Payone"><file name="Abstract.php" hash="e4538042b15ce2ba027a189ae2887861"/><file name="BankAbstract.php" hash="fa4ef2c918868001c5f1df97cb4bc400"/><file name="Cc.php" hash="11e68f50ea43bf73b31c53efea0cbc4d"/><file name="Dbt.php" hash="7f098887ba6f12669a18f62d7885de6d"/><file name="Gp.php" hash="7686149aedae93b0d5eef0b06fc08d7e"/><file name="Idl.php" hash="57d144744565ff644db917cab7ef689e"/><file name="Inv.php" hash="91d893ee5eacdc00ff8fbb3f1b750894"/><file name="Klv.php" hash="f82fb0cc874ea8f1121f282372e4e404"/><file name="Pp.php" hash="1165aa67ef8ccdc93a2eb0b7bf03f3d0"/><file name="Prp.php" hash="76079d7e154c3a982b1d117793942c3a"/><file name="Sue.php" hash="31280f2c8abf21f0a582b656fb0d38ad"/></dir><dir name="Pp"><file name="Abstract.php" hash="e6c5afcb0653d2ec3de3bd5d1442b355"/><file name="Wspp.php" hash="5c4d194c7814416491892f4cbe272d9f"/></dir><file name="Pp.php" hash="c521bbb32aed313c0170dd6e8361f934"/><dir name="Ppal"><file name="Plus.php" hash="a26adaab47adb3f3b84ff872673b4ed1"/></dir><file name="Router.php" hash="1df693718ebb4b71d2ae790678927194"/><file name="Shopgate.php" hash="f0d59e2a4369f7a22e47cf9c3bb9c44a"/><dir name="Simple"><file name="Billsafe.php" hash="d352d66d5101454f4cfec46e4fcaa88a"/><dir name="Cod"><file name="Abstract.php" hash="7bcb77e2906200f8a7576a24d782d541"/><file name="Msp.php" hash="da63e630e339f73b1047f9be2fc13a80"/><file name="Native.php" hash="a18abef66d98a08e988bafa1564dfaa2"/><file name="Phoenix107.php" hash="958990a7ec99a4c102b335e68db4f563"/><file name="Phoenix108.php" hash="912cb903da51a2056f03d75c566dbc7b"/></dir><file name="Cod.php" hash="0688749cd9110544d01e5c1130be3005"/><file name="Invoice.php" hash="a86d8500a0dee3056e56b0ccfb1fae3d"/><dir name="Mws"><file name="Abstract.php" hash="691b330380b702954526ef356088ed7f"/><file name="Mws.php" hash="e919cd10f5be16e404a2aac43211005b"/><file name="Mws15.php" hash="db272b23821ea5010fe0e19023b9ca81"/></dir><file name="Mws.php" hash="e19cdfee86d84d80a234138a5f86c5af"/><dir name="Paypal"><file name="Express.php" hash="e2d33dbc600503d9a7541ab53df60662"/><file name="Standard.php" hash="5281ddc90f8f560b6cffa2e97fe08304"/><file name="Standard1400.php" hash="d80d26e8189b12c9796929dfad77f6c8"/></dir><file name="Paypal.php" hash="03a7c4b8e193d262aa2dbd51cdac3ab8"/><dir name="Prepay"><file name="Abstract.php" hash="89767868690e40bc3d96f8bee4484880"/><file name="Checkmo.php" hash="781dd32522f7bc97c62313cb76429633"/><file name="Native.php" hash="48542e3e9ad2bafb504a200a6529eccc"/><file name="Phoenix.php" hash="7118e404d6f1755cdab35dbc2c8f058d"/></dir><file name="Prepay.php" hash="eb79f9f8469652e91b11fd5d714db84f"/><file name="Shopgate.php" hash="5fb1a053ac9b69e5d38bc9f6631ee8f1"/><dir name="Sue"><file name="Abstract.php" hash="d07d6b3a5702b458ed4e5f4574e3ced9"/><file name="Sue118.php" hash="759f4a7e103f9f9f4457aa1d0694c26d"/><file name="Sue300.php" hash="c804244222e5fe67ead8916c5c1ffef1"/></dir><file name="Sue.php" hash="6802dc052e2088957329689b003a16f8"/></dir><file name="Simple.php" hash="e4f0b3cd8282c2661cb19eabdb77d075"/><file name="Usaepay.php" hash="50e049e1cae29abbd7027cf842878540"/><file name="Wspp.php" hash="23b0420ff59dc0bfa7940bf0f07562fc"/></dir><dir name="Resource"><dir name="Core"><file name="Config.php" hash="0ee7969070ab0dddfdd3bb2cc404cd3c"/></dir><dir name="Customer"><file name="Collection.php" hash="2ddb7db1355100bc9e86f966f1d4612c"/></dir><file name="Customer.php" hash="69848842d4be07be4d66d700a7b6695b"/><file name="Product.php" hash="5c62ef4cfc3f0ebbbe5a9a46d1c25dfa"/><file name="Setup.php" hash="7b5cc0f99c857e9292638c1fbeb43969"/><dir name="Shopgate"><dir name="Connection"><file name="Collection.php" hash="f294d4239cee276b7e3c5e6e2109de66"/><dir name="Grid"><file name="Collection.php" hash="d499139d50dffbfe1b1e868b5aeeee0f"/></dir></dir><dir name="Order"><file name="Collection.php" hash="2c18a4ca248ca8719e7ead85f0c57619"/></dir><file name="Order.php" hash="1942eeb8268781c499f8cad384081b02"/></dir></dir><dir name="Sales"><dir name="Creditmemo"><dir name="Total"><file name="ShopgatePaymentFee.php" hash="614d1e96cd2c97e0fcd7db86ee3aad89"/></dir></dir><dir name="Invoice"><dir name="Total"><file name="ShopgatePaymentFee.php" hash="c4400832de32367067fd5396bcf7bfc8"/></dir></dir><dir name="Quote"><dir name="Address"><dir name="Total"><file name="ShopgatePaymentFee.php" hash="7a309b69fb20fb6fcae5f3b77f5b7ba9"/></dir></dir></dir></dir><dir name="Search"><dir name="Shopgate"><file name="Order.php" hash="94dcf366528641687b89ab0c9f973ef5"/></dir></dir><dir name="Shopgate"><dir name="Cart"><dir name="Validation"><dir name="Stock"><file name="Bundle.php" hash="7cc03239fbefe3a8e71755a178299944"/><file name="Simple.php" hash="9da9891d52c89e0772af5bcea7581ae8"/></dir><file name="Stock.php" hash="03d8139aa9840d707c8e4cb991bca20f"/></dir></dir><file name="Connection.php" hash="ff0da764d444103f5892ef21e23ba353"/><file name="Order.php" hash="89e0e425fc48282c1b46d3078b294be1"/><file name="Plugin.php" hash="909b58f1bb4b0a4228415fc6e7b22ab8"/><dir name="Shipping"><dir name="Mapper"><file name="Carrier.php" hash="ef57904070fdf7921e51e88c3991c029"/><dir name="Method"><file name="Abstract.php" hash="bb402c49f3da66f7bd4baf5b215f989e"/><file name="Interface.php" hash="1bab00e6e0356184c3f213acfce601da"/><file name="Shopgate.php" hash="af8e1ade067d1b9fb0e5b493ad814576"/><file name="Usps.php" hash="14969ce8762a7fa5e5e5d6bc64285f52"/></dir></dir><file name="Mapper.php" hash="b93ac160c4c176c77887a23593ab058c"/></dir></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Attribute.php" hash="8dfc3964b750aebac8db5f584559d5c3"/><dir name="Description"><file name="List.php" hash="c83f37019461ab7adc86a57400f63761"/></dir><file name="Description.php" hash="d0dcebc9d75fdb0bb80f3c3faba6397c"/><file name="Enabledisable.php" hash="7f189c26cd1c2c7f1cd6dc56379798b5"/><dir name="Item"><file name="Sort.php" hash="2dc75f9c1e8baaddbf895945acd2ff19"/></dir><dir name="Product"><file name="Image.php" hash="e9d0e7c5769446290094d2b67e5c468b"/><file name="Names.php" hash="98de8ee7ae9b3c504eb087f5e09d3afd"/><file name="Types.php" hash="007b54c2e095691380c21a5ab62846fc"/></dir><dir name="Redirect"><file name="Types.php" hash="c5d3c44ab1f5ba74224b41836b14afff"/></dir><file name="Server.php" hash="b569e24076ca68c4063729fb708b666a"/><file name="Store.php" hash="cb2998beb43ba8afeeaa5b64a5b5e946"/><dir name="Validation"><file name="Config.php" hash="77382cb829f4b3b50120d7e1359e0051"/></dir><dir name="Variation"><dir name="Export"><file name="Type.php" hash="bb19358c2c2fbee3cb9776f3540faa20"/></dir></dir><dir name="Weight"><file name="Units.php" hash="10af44d670bcfdb559f4196c7006e893"/></dir></dir></dir></dir></dir><dir name="Test"><dir name="Controller"><dir name="FrameworkController"><dir name="fixtures"><file name="testPluginNotActive.yaml" hash="9e25f93814834419e9c83995021860c2"/></dir></dir><file name="FrameworkController.php" hash="32030559addc710d40c99c9fbd0d5856"/></dir><dir name="Helper"><dir name="Data"><dir name="providers"><file name="testCalculateTaxRate.yaml" hash="2b1fb398f41a0d7706ab9701d77ce978"/></dir></dir><file name="Data.php" hash="d641528ef7674e616b6f1ea1d9dea7c6"/></dir></dir><file name="changelog.txt" hash="265a99471b2459b7f9bf58e695c20d88"/><dir name="controllers"><dir name="Adminhtml"><file name="ShopgateController.php" hash="cd2305edb0348a15f956d20d39433778"/></dir><file name="FrameworkController.php" hash="2aec53db3cedaf901ef6199dc000cda2"/></dir><dir name="etc"><file name="adminhtml.xml" hash="d1f345ca5fc8b0619234f9c270fb84a7"/><file name="config.xml" hash="606bdef221be472e078a58fd77c5cfb0"/><file name="system.xml" hash="b715fdbd76766e347c0f30a8122e58ed"/></dir><file name="licence.txt" hash="dec6ca25c420b36a2e400caf1541c923"/><dir name="sql"><dir name="shopgate_setup"><file name="mysql4-install-0.1.0.php" hash="069abba038757da43b2ca6c5a0c82aba"/><file name="mysql4-install-2.1.45.php" hash="eddddf157e55a87edc77361dde564463"/><file name="mysql4-install-2.2.0.php" hash="eddddf157e55a87edc77361dde564463"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="cc637fc1bc511e745f02a56d0b36e3be"/><file name="mysql4-upgrade-1.0.5-1.0.7.php" hash="1e800d9d235b817bf5be698288bc0129"/><file name="mysql4-upgrade-2.1.44-2.1.45.php" hash="134d0b665746c61d364f6fd93d83f46c"/><file name="mysql4-upgrade-2.1.49-2.1.50.php" hash="e0fd395bb9c25c0e544c455186cfe7c9"/><file name="mysql4-upgrade-2.4.28-2.4.29.php" hash="9c8c868ce90e42b56182b23b78d6fbe7"/><file name="mysql4-upgrade-2.4.29-2.4.30.php" hash="ca3ee1e2f337bcea26264a17f603548e"/><file name="mysql4-upgrade-2.7.5-2.8.0.php" hash="34393a58a0b4ec90b4e618d3ff4cc565"/><file name="mysql4-upgrade-2.9.15-2.9.16.php" hash="980e7cc83f912ef4f630ef8d1cb964d1"/><file name="mysql4-upgrade-2.9.4-2.9.5.php" hash="89a34b7b9ad2eec492055e52e7e75049"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="de_DE"><file name="Shopgate_Framework.csv" hash="e842a47237b2e613a22e5584108b8b2a"/></dir><dir name="de_CH"><file name="Shopgate_Framework.csv" hash="e842a47237b2e613a22e5584108b8b2a"/></dir><dir name="de_AT"><file name="Shopgate_Framework.csv" hash="664a8dc7470fd9675ca7a67f2bcd1325"/></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="shopgate"><file name="logo.png" hash="b7139047ecc90b15a5710ab0fe77fc81"/><file name="logo_big.png" hash="b98bfcf09766589506a1cca24ca47972"/><file name="logo_small.png" hash="7abf7f774c592eb582c2856e027af798"/><file name="oauth_connect.js" hash="8e5c77d9ad1354f826445f03c91008f4"/><file name="shopgate_admin.css" hash="0fbc07171267b9fb5dba7004a0858f66"/><file name="target.js" hash="80484a4dae515f708c97545d9959673a"/></dir></dir></dir></dir></target><target name="magelib"><dir name="Shopgate"><dir name="assets"><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/><file name="js_header.html" hash="f9865eae13ed93fd41788aa27b0391ee"/><file name="link_tag.html" hash="4798d67e30ef4a76dd8435326421673d"/><file name="mobile_header.html" hash="17616650e160eaccd24e25729396c5a9"/></dir><file name="changelog.txt" hash="eae57d66fcc7d54725202ac2ecde9076"/><dir name="classes"><file name="apis.php" hash="61ceeade474c9dffa98c9c15691cae7f"/><file name="configuration.php" hash="6b95519eed1c7bde3951e4ea52463181"/><file name="core.php" hash="009ad053c7bbe46d02083ec011b4893f"/><file name="customers.php" hash="3bc00737d0cfd788c24f52b303babd8a"/><file name="external_orders.php" hash="811471d13c2a3c5aa5d1a1eb859f74e6"/><dir name="helper"><file name="DataStructure.php" hash="ece9e9f855756777f543d090f5ecc710"/><file name="Pricing.php" hash="fd4c74999abc3bfa05fd74994a2ce78f"/><file name="String.php" hash="10c9396b2975bf0bde86f171932c3074"/><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/><file name="items.php" hash="7a361efd0a5327c0ad0f0745c1b74cc0"/><dir name="models"><file name="Abstract.php" hash="a32633283eb403a55a166bbad70b3e2f"/><file name="AbstractExport.php" hash="f265f9e906208e1799994d117582be20"/><file name="XmlEmptyObject.php" hash="d6cfdae3bdd858d4f10fcebdb542f533"/><file name="XmlResultObject.php" hash="340804eb0f2ba6bcb6b05311b8bb1f11"/><dir name="catalog"><file name="Attribute.php" hash="28d8f3bc6c416661d1eaa77726ba7009"/><file name="AttributeGroup.php" hash="0270086ec8006ee8231c6b0baa8d6034"/><file name="Category.php" hash="beba58d2796cf7b4ca08ce68de65415b"/><file name="CategoryPath.php" hash="475869aef74c567c8569ee9953210faa"/><file name="Identifier.php" hash="d9a3b16d1fcdec641ca2b0fd77fbd625"/><file name="Input.php" hash="77df45fd89aec19565a5fae7178205bb"/><file name="Manufacturer.php" hash="e45f534f5f6acad118be24ffc63a0460"/><file name="Option.php" hash="fd95fe72bff985ae0b2861da115e2468"/><file name="Price.php" hash="3cb25372ae58bd0c71b342f9ef2dca73"/><file name="Product.php" hash="7e7c49e10b379eae5d0141efe2c91305"/><file name="Property.php" hash="5967f0403a606a27ea4fec71a8402327"/><file name="Relation.php" hash="263cde539af500af911baec4e354079e"/><file name="Review.php" hash="72c94cb1f2a54bafffdb5672d87ecd4d"/><file name="Shipping.php" hash="1fe425496bd9720dc18bd076e56aca9e"/><file name="Stock.php" hash="4e645877e778ec8d02ae98262bfa9663"/><file name="Tag.php" hash="39e7b845ab157d2f707707576e868d64"/><file name="TierPrice.php" hash="9dd757c9c3d193944a5727fbe5cf4704"/><file name="Validation.php" hash="0be71640c1df60ab809347194ec66457"/><file name="Visibility.php" hash="d60c6b8ec486da4afdc46a00d65ad172"/><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/><dir name="media"><file name="Attachment.php" hash="c074ef3426c2506350cbf5ff0133c89d"/><file name="Image.php" hash="c9319f2a82811239313e328eaf7e2094"/><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir></dir><file name="orders.php" hash="aeb0df3eab7b68d1189dc6851fb96a24"/><file name="redirect.php" hash="568c682f66c4434188c604158029db57"/></dir><dir name="config"><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir><file name="index.php" hash="de19abc78063ea9a4112964c79946f1c"/><file name="shopgate.php" hash="f0482cc4027105bb5d423ddde01e7ac7"/><file name="shopgate_license.txt" hash="21fbb2f00b832416916b27c5e3f5d6d1"/><dir name="temp"><dir name="cache"><file name="index.php" hash="7573387748996e2dd9e02a237056f158"/></dir><file name="index.php" hash="7573387748996e2dd9e02a237056f158"/><dir name="logs"><file name="index.php" hash="7573387748996e2dd9e02a237056f158"/></dir></dir><dir name="vendors"><file name="2d_is.php" hash="087decaca87ee85d548d8caaa43f1212"/><file name="BSD_license.txt" hash="2df4dd93533ca2c19f6f2d601bc3e0d5"/><file name="JSON.php" hash="c8398aeb5c3c71aeb1813389d9a030af"/><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir><file name=".htaccess" hash="34479bc8d9df775c38a980ecaf6f3f4b"/></dir></target><target name="mage"><dir name="app"><dir name="design"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="shopgate.xml" hash="608ba89093ef89e1c182cd6085dbf3b1"/></dir><dir name="template"><dir name="shopgate"><file name="mobile_website.phtml" hash="229cbefd12ea77676f8af9c7159528ea"/><dir name="payment"><file name="mobile_payment.phtml" hash="1e18979028fb13e99af7c595c75a5d27"/><file name="shopgate.phtml" hash="1e18979028fb13e99af7c595c75a5d27"/></dir></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="shopgate.xml" hash="8bab300fb25a48cd2c8119ae1942ed54"/></dir><dir name="template"><dir name="shopgate"><dir name="oauth"><dir name="config"><file name="connector.phtml" hash="478c309bdde7834bf20a48b65a4699fb"/></dir><dir name="connect"><file name="info.phtml" hash="4f75dc4311616081873a7d416b96c1c2"/><file name="overlay.phtml" hash="2a17d5b6ff8023568437b194f8a9d482"/></dir><file name="connect.phtml" hash="6956aa22eedf549c4565304b4e4a4ab9"/><file name="data.phtml" hash="09b4c5d83863f104db7a018510cdb315"/><file name="disconnect.phtml" hash="2858cebe9004c9fb5764f79faee46f87"/><file name="manage.phtml" hash="1f99255efbce4dbdc1ee781820d455b8"/></dir><dir name="payment"><file name="mobile_payment.phtml" hash="2892e0dd200db6c0ffa5fa83f87d838c"/><file name="shopgate.phtml" hash="5457030290f8aa08c2711a8bd27c3dee"/></dir></dir></dir></dir></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>shopgate_module</name>
4
+ <version>2.9.27</version>
5
  <stability>stable</stability>
6
  <license uri="http://wiki.shopgate.com/Magento/de">Shopgate Plugin</license>
7
  <channel>community</channel>
10
  <description>Shopgate Plugin</description>
11
  <notes>Shopgate Modul</notes>
12
  <authors><author><name>Peter Liebig</name><user>Shopgate</user><email>p.liebig@me.com</email></author><author><name>Stephan Recknagel</name><user>Shopgate</user><email>mail@recknagel.io</email></author><author><name>Andr&#xE9; Kraus</name><user>Shopgate</user><email>andre.kraus83@googlemail.com</email></author></authors>
13
+ <date>2015-12-08</date>
14
+ <time>14:52:42</time>
15
+ <contents><target name="mageetc"><dir name="modules"><file name="Shopgate_Framework.xml" hash="3fb114204bd038da711122083876f161"/></dir></target><target name="magecommunity"><dir name="Shopgate"><dir name="Framework"><dir name="Block"><dir name="Adminhtml"><dir name="OAuth"><dir name="Config"><file name="Connector.php" hash="890d04b08bf692c12b02f29abf813f83"/></dir><dir name="Connect"><dir name="Add"><file name="Form.php" hash="45685099b41a46919a9900d22c30b711"/></dir><file name="Info.php" hash="ee7bbc837bf3f298791b8496f2d6d565"/><file name="Overlay.php" hash="a6496896dccb5898b36e3e65585650f4"/></dir><file name="Connect.php" hash="cc7e43ba447b6338f6c50ccaa5fd073a"/><file name="Data.php" hash="1903e819d5d16abba4c37d7823909260"/><file name="Disconnect.php" hash="2545e56bca73577ba5f73fce0501624a"/><dir name="Manage"><file name="Grid.php" hash="78357b78fed0e8b3535a7e505c8f6425"/></dir><file name="Manage.php" hash="a99e12333f7c27771ca42a0764108639"/></dir></dir><file name="Info.php" hash="3dd73900370546289a6033942a0c0528"/><dir name="Payment"><file name="MobilePayment.php" hash="7de8af7ec46e107c46a73efaf2a02034"/><file name="Shopgate.php" hash="67af406fa04da70461b3580b8adea89d"/></dir><dir name="Totals"><file name="AbstractPaymentFee.php" hash="5e36647f536d1c6daba33cd6e0a5e302"/><file name="CreditmemoPaymentFee.php" hash="4a287f54554d8d45772db386f54a45e7"/><file name="InvoicePaymentFee.php" hash="818164536fe249016af3046aef73f181"/><file name="OrderPaymentFee.php" hash="55c8f62c4da8014c99414ece9cd125c4"/></dir><file name="Version.php" hash="2f45712bb20635ac17d8bdee213819e5"/></dir><dir name="Helper"><dir name="Billsafe"><file name="Order.php" hash="474c2aa15f352224c11c8ab17e921c9d"/></dir><file name="Config.php" hash="b0e489659332274686965e5e8d200d88"/><file name="Coupon.php" hash="519697b13040ddfbc8f460b6034c8779"/><file name="Customer.php" hash="c68047909c0c6e14977336ab6afe2f6b"/><file name="Data.php" hash="bf2db8a0a2c145cdb50f891f6d45ba85"/><file name="Debug.php" hash="82c85038046fc9b2f994df18b7f202a6"/><file name="Export.php" hash="02c5dbce181e7489b5d75b20c1584aab"/><dir name="Import"><file name="Order.php" hash="e40ed484faf6f9757bee1970bafaed30"/></dir><file name="Install.php" hash="57f42693c9a6ddb18b8a25a2a5da7cf8"/><dir name="Payment"><file name="Abstract.php" hash="207f16aab8224761b7d91802b9fb10ee"/><file name="Payone.php" hash="ddced5955ff55105d8b3c91e0fcb0778"/><file name="Wspp.php" hash="4214f1d3332cd189cee3df48108ebd8d"/></dir><file name="Sales.php" hash="a5dfa9e90343a4da4e0791f62b802484"/></dir><dir name="Model"><dir name="Carrier"><file name="Fix.php" hash="31ccd9b4c8ac725e5b2c1dcee096dea8"/></dir><dir name="Cataloginventory"><file name="Stock.php" hash="42ffccc3d644f8b04358a3e76bda32dd"/></dir><dir name="Compiler"><file name="Process.php" hash="740452b7bc234417788db1f1ee892ef5"/></dir><file name="Config.php" hash="91f218e3c966e1ce01686be32ff5102f"/><file name="Customer.php" hash="97ed53ca3f69c7a24fb40cce11f58721"/><dir name="DreamRobot"><file name="Observer.php" hash="7b4e8922a46f5974b8edf359c632a9d3"/></dir><dir name="Export"><file name="Abstract.php" hash="9e86667845e8cebd8e0ccb8879b70b6d"/><dir name="Category"><file name="Csv.php" hash="72f4f58345d95f8f621783bedf2a092e"/><file name="Xml.php" hash="12ab046b9a000636ed4ed5eefb770af2"/></dir><file name="Category.php" hash="5a41141ecec85669674ec818c4661cdc"/><dir name="Customer"><file name="Orders.php" hash="30123a6fe3e391fca911fed042b256c8"/></dir><file name="Customer.php" hash="2711476c9538a22242d1511649ec77f1"/><dir name="Product"><file name="Csv.php" hash="50cd5a66e8034f3584140f91b56fe03d"/><file name="Xml.php" hash="5fd5e1326f0ab8ba8dbf78c9884a38d6"/></dir><file name="Product.php" hash="d9c807df57af3f1cced2d9bb433338ec"/><dir name="Review"><file name="Csv.php" hash="5c72f802a2de256ca1ec8dab1b75b291"/><file name="Xml.php" hash="bc16f60d9ed20705422921955a5071fe"/></dir><file name="Review.php" hash="ad6f548035a30da642d2459354acbb40"/><file name="Settings.php" hash="960f3d9991ecca41bd9e8b4ba632e9ea"/></dir><file name="Feed.php" hash="fb99cd7b2b3d94908848b722df666b67"/><dir name="Mobile"><file name="Redirect.php" hash="1721d0372eee3d8d80b5af8629dbf1b9"/></dir><dir name="Mysql4"><dir name="Core"><file name="Core.php" hash="fc129d4d929f83e8389367b9c5d6d5e1"/></dir><dir name="Customer"><file name="Collection.php" hash="89d31997abc3c2145f74e02dd5456a7c"/></dir><file name="Customer.php" hash="d5f460b2d5bfa87b8368a8a6c6b51115"/><file name="Product.php" hash="6a99b3d0de44dfbd132ce9caca19034e"/><dir name="Shopgate"><dir name="Order"><file name="Collection.php" hash="e180ba816be47239828bea65cd5f8445"/></dir><file name="Order.php" hash="c297847e39ad01307dba4a69c13445f2"/></dir></dir><file name="Observer.php" hash="c0437e883a28cf8c67ab67517d0788f3"/><dir name="Payment"><dir name="Abstract"><file name="AbstractPayol.php" hash="0228e80536a7decbbc0a883a4bde0d0d"/></dir><file name="Abstract.php" hash="873534555f767d24d1b0ab378267e8b9"/><file name="Amazon.php" hash="c90003246111cf066270015b41cb7ff9"/><file name="Authorize.php" hash="6f747fb258e59137cc5dadc179664246"/><file name="Billsafe.php" hash="1c97ec04356ae4ed25c1492a317eaaff"/><dir name="Cc"><file name="Abstract.php" hash="2b291ac14d9e1e3120416d6aeb4c3487"/><file name="Authn.php" hash="5c4c0d849d8d22dab1e6bf374dfc6c79"/><file name="AuthnAbstract.php" hash="59c3e39376e695ac161d228fc9a3fabf"/><dir name="Authncim"><file name="Gateway.php" hash="1f8df3fe0e50f4729bebfc1d4763b015"/><file name="Method.php" hash="aa6916548a71848ad7c83e4f053bc27e"/></dir><file name="Authncim.php" hash="89f1c2a0bb59d08c895da84c14c325ff"/><file name="Chargeitpro.php" hash="6fd3a2fd42df00831d6e363a23a414f1"/><file name="Usaepay.php" hash="00bd8969c1eceb13eacbb37ed9a1f714"/></dir><file name="Cc.php" hash="076a0faf0705c821c5479a2ec4a33c8d"/><file name="Express.php" hash="242b1fc3b238b907ac616680aa446401"/><file name="Factory.php" hash="212e33a78fc1e175d778347c4e4cffee"/><file name="Generic.php" hash="666f06186d1bb96b94af287d221e27c5"/><dir name="Ins"><file name="Payol.php" hash="b6961c4ab1fb9a95ab2d470aeaad8d29"/></dir><file name="Interface.php" hash="151002297bcce208b85bd260c7a25b47"/><dir name="Inv"><file name="Payol.php" hash="6d1c28b2ea2fb2fd63e09712f4533c77"/></dir><file name="MobilePayment.php" hash="59554c65e778831f6add450e0f846f42"/><dir name="Payone"><file name="Abstract.php" hash="e4538042b15ce2ba027a189ae2887861"/><file name="BankAbstract.php" hash="fa4ef2c918868001c5f1df97cb4bc400"/><file name="Cc.php" hash="11e68f50ea43bf73b31c53efea0cbc4d"/><file name="Dbt.php" hash="7f098887ba6f12669a18f62d7885de6d"/><file name="Gp.php" hash="7686149aedae93b0d5eef0b06fc08d7e"/><file name="Idl.php" hash="57d144744565ff644db917cab7ef689e"/><file name="Inv.php" hash="91d893ee5eacdc00ff8fbb3f1b750894"/><file name="Klv.php" hash="f82fb0cc874ea8f1121f282372e4e404"/><file name="Pp.php" hash="1165aa67ef8ccdc93a2eb0b7bf03f3d0"/><file name="Prp.php" hash="76079d7e154c3a982b1d117793942c3a"/><file name="Sue.php" hash="31280f2c8abf21f0a582b656fb0d38ad"/></dir><dir name="Pp"><file name="Abstract.php" hash="e6c5afcb0653d2ec3de3bd5d1442b355"/><file name="Wspp.php" hash="42ff0a5d004c82401277dbf00cd9e00f"/></dir><file name="Pp.php" hash="c521bbb32aed313c0170dd6e8361f934"/><dir name="Ppal"><file name="Plus.php" hash="a26adaab47adb3f3b84ff872673b4ed1"/></dir><file name="Router.php" hash="1df390aa58b64090fab972ba5993934b"/><file name="Shopgate.php" hash="f0d59e2a4369f7a22e47cf9c3bb9c44a"/><dir name="Simple"><file name="Billsafe.php" hash="d352d66d5101454f4cfec46e4fcaa88a"/><dir name="Cod"><file name="Abstract.php" hash="7bcb77e2906200f8a7576a24d782d541"/><file name="Msp.php" hash="da63e630e339f73b1047f9be2fc13a80"/><file name="Native.php" hash="a18abef66d98a08e988bafa1564dfaa2"/><file name="Phoenix107.php" hash="958990a7ec99a4c102b335e68db4f563"/><file name="Phoenix108.php" hash="912cb903da51a2056f03d75c566dbc7b"/></dir><file name="Cod.php" hash="0688749cd9110544d01e5c1130be3005"/><file name="Invoice.php" hash="a86d8500a0dee3056e56b0ccfb1fae3d"/><dir name="Mws"><file name="Abstract.php" hash="691b330380b702954526ef356088ed7f"/><file name="Mws.php" hash="e919cd10f5be16e404a2aac43211005b"/><file name="Mws15.php" hash="db272b23821ea5010fe0e19023b9ca81"/></dir><file name="Mws.php" hash="e19cdfee86d84d80a234138a5f86c5af"/><dir name="Paypal"><file name="Express.php" hash="e2d33dbc600503d9a7541ab53df60662"/><file name="Standard.php" hash="5281ddc90f8f560b6cffa2e97fe08304"/><file name="Standard1400.php" hash="d80d26e8189b12c9796929dfad77f6c8"/></dir><file name="Paypal.php" hash="03a7c4b8e193d262aa2dbd51cdac3ab8"/><dir name="Prepay"><file name="Abstract.php" hash="89767868690e40bc3d96f8bee4484880"/><file name="Checkmo.php" hash="781dd32522f7bc97c62313cb76429633"/><file name="Native.php" hash="48542e3e9ad2bafb504a200a6529eccc"/><file name="Phoenix.php" hash="7118e404d6f1755cdab35dbc2c8f058d"/></dir><file name="Prepay.php" hash="eb79f9f8469652e91b11fd5d714db84f"/><file name="Shopgate.php" hash="5fb1a053ac9b69e5d38bc9f6631ee8f1"/><dir name="Sue"><file name="Abstract.php" hash="d07d6b3a5702b458ed4e5f4574e3ced9"/><file name="Sue118.php" hash="759f4a7e103f9f9f4457aa1d0694c26d"/><file name="Sue300.php" hash="c804244222e5fe67ead8916c5c1ffef1"/></dir><file name="Sue.php" hash="6802dc052e2088957329689b003a16f8"/></dir><file name="Simple.php" hash="e4f0b3cd8282c2661cb19eabdb77d075"/><file name="Usaepay.php" hash="50e049e1cae29abbd7027cf842878540"/><file name="Wspp.php" hash="23b0420ff59dc0bfa7940bf0f07562fc"/></dir><dir name="Resource"><dir name="Core"><file name="Config.php" hash="0ee7969070ab0dddfdd3bb2cc404cd3c"/></dir><dir name="Customer"><file name="Collection.php" hash="2ddb7db1355100bc9e86f966f1d4612c"/></dir><file name="Customer.php" hash="69848842d4be07be4d66d700a7b6695b"/><file name="Product.php" hash="5c62ef4cfc3f0ebbbe5a9a46d1c25dfa"/><file name="Setup.php" hash="7b5cc0f99c857e9292638c1fbeb43969"/><dir name="Shopgate"><dir name="Connection"><file name="Collection.php" hash="f294d4239cee276b7e3c5e6e2109de66"/><dir name="Grid"><file name="Collection.php" hash="d499139d50dffbfe1b1e868b5aeeee0f"/></dir></dir><dir name="Order"><file name="Collection.php" hash="2c18a4ca248ca8719e7ead85f0c57619"/></dir><file name="Order.php" hash="1942eeb8268781c499f8cad384081b02"/></dir></dir><dir name="Sales"><dir name="Creditmemo"><dir name="Total"><file name="ShopgatePaymentFee.php" hash="614d1e96cd2c97e0fcd7db86ee3aad89"/></dir></dir><dir name="Invoice"><dir name="Total"><file name="ShopgatePaymentFee.php" hash="c4400832de32367067fd5396bcf7bfc8"/></dir></dir><dir name="Quote"><dir name="Address"><dir name="Total"><file name="ShopgatePaymentFee.php" hash="7a309b69fb20fb6fcae5f3b77f5b7ba9"/></dir></dir></dir></dir><dir name="Search"><dir name="Shopgate"><file name="Order.php" hash="94dcf366528641687b89ab0c9f973ef5"/></dir></dir><dir name="Shopgate"><dir name="Cart"><dir name="Validation"><dir name="Stock"><file name="Bundle.php" hash="7cc03239fbefe3a8e71755a178299944"/><file name="Simple.php" hash="9da9891d52c89e0772af5bcea7581ae8"/></dir><file name="Stock.php" hash="03d8139aa9840d707c8e4cb991bca20f"/></dir></dir><file name="Connection.php" hash="ff0da764d444103f5892ef21e23ba353"/><file name="Order.php" hash="89e0e425fc48282c1b46d3078b294be1"/><file name="Plugin.php" hash="c26b04d93db9c86f1831174845f970f0"/><dir name="Shipping"><dir name="Mapper"><file name="Carrier.php" hash="ef57904070fdf7921e51e88c3991c029"/><dir name="Method"><file name="Abstract.php" hash="bb402c49f3da66f7bd4baf5b215f989e"/><file name="Interface.php" hash="1bab00e6e0356184c3f213acfce601da"/><file name="Shopgate.php" hash="af8e1ade067d1b9fb0e5b493ad814576"/><file name="Usps.php" hash="14969ce8762a7fa5e5e5d6bc64285f52"/></dir></dir><file name="Mapper.php" hash="b93ac160c4c176c77887a23593ab058c"/></dir></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Attribute.php" hash="8dfc3964b750aebac8db5f584559d5c3"/><dir name="Description"><file name="List.php" hash="c83f37019461ab7adc86a57400f63761"/></dir><file name="Description.php" hash="d0dcebc9d75fdb0bb80f3c3faba6397c"/><file name="Enabledisable.php" hash="7f189c26cd1c2c7f1cd6dc56379798b5"/><dir name="Item"><file name="Sort.php" hash="2dc75f9c1e8baaddbf895945acd2ff19"/></dir><dir name="Product"><file name="Image.php" hash="e9d0e7c5769446290094d2b67e5c468b"/><file name="Names.php" hash="98de8ee7ae9b3c504eb087f5e09d3afd"/><file name="Types.php" hash="007b54c2e095691380c21a5ab62846fc"/></dir><dir name="Redirect"><file name="Types.php" hash="c5d3c44ab1f5ba74224b41836b14afff"/></dir><file name="Server.php" hash="b569e24076ca68c4063729fb708b666a"/><file name="Store.php" hash="cb2998beb43ba8afeeaa5b64a5b5e946"/><dir name="Validation"><file name="Config.php" hash="77382cb829f4b3b50120d7e1359e0051"/></dir><dir name="Variation"><dir name="Export"><file name="Type.php" hash="bb19358c2c2fbee3cb9776f3540faa20"/></dir></dir><dir name="Weight"><file name="Units.php" hash="10af44d670bcfdb559f4196c7006e893"/></dir></dir></dir></dir></dir><dir name="Test"><dir name="Controller"><dir name="FrameworkController"><dir name="fixtures"><file name="testPluginNotActive.yaml" hash="9e25f93814834419e9c83995021860c2"/></dir></dir><file name="FrameworkController.php" hash="32030559addc710d40c99c9fbd0d5856"/></dir><dir name="Helper"><dir name="Data"><dir name="providers"><file name="testCalculateTaxRate.yaml" hash="2b1fb398f41a0d7706ab9701d77ce978"/></dir></dir><file name="Data.php" hash="d641528ef7674e616b6f1ea1d9dea7c6"/></dir></dir><file name="changelog.txt" hash="9996df3fd46185b5f5941d019932b094"/><dir name="controllers"><dir name="Adminhtml"><file name="ShopgateController.php" hash="cd2305edb0348a15f956d20d39433778"/></dir><file name="FrameworkController.php" hash="2152205bd372d999a56eb378ed810a8d"/></dir><dir name="etc"><file name="adminhtml.xml" hash="d1f345ca5fc8b0619234f9c270fb84a7"/><file name="config.xml" hash="8a43f693000a6007649040d19437f533"/><file name="system.xml" hash="b715fdbd76766e347c0f30a8122e58ed"/></dir><file name="licence.txt" hash="dec6ca25c420b36a2e400caf1541c923"/><dir name="sql"><dir name="shopgate_setup"><file name="mysql4-install-0.1.0.php" hash="069abba038757da43b2ca6c5a0c82aba"/><file name="mysql4-install-2.1.45.php" hash="eddddf157e55a87edc77361dde564463"/><file name="mysql4-install-2.2.0.php" hash="eddddf157e55a87edc77361dde564463"/><file name="mysql4-upgrade-0.1.0-0.1.1.php" hash="cc637fc1bc511e745f02a56d0b36e3be"/><file name="mysql4-upgrade-1.0.5-1.0.7.php" hash="1e800d9d235b817bf5be698288bc0129"/><file name="mysql4-upgrade-2.1.44-2.1.45.php" hash="134d0b665746c61d364f6fd93d83f46c"/><file name="mysql4-upgrade-2.1.49-2.1.50.php" hash="e0fd395bb9c25c0e544c455186cfe7c9"/><file name="mysql4-upgrade-2.4.28-2.4.29.php" hash="9c8c868ce90e42b56182b23b78d6fbe7"/><file name="mysql4-upgrade-2.4.29-2.4.30.php" hash="ca3ee1e2f337bcea26264a17f603548e"/><file name="mysql4-upgrade-2.7.5-2.8.0.php" hash="34393a58a0b4ec90b4e618d3ff4cc565"/><file name="mysql4-upgrade-2.9.15-2.9.16.php" hash="980e7cc83f912ef4f630ef8d1cb964d1"/><file name="mysql4-upgrade-2.9.4-2.9.5.php" hash="dc6770e94c31d2f79915528c0993d546"/></dir></dir></dir></dir></target><target name="magelocale"><dir name="de_DE"><file name="Shopgate_Framework.csv" hash="e842a47237b2e613a22e5584108b8b2a"/></dir><dir name="de_CH"><file name="Shopgate_Framework.csv" hash="e842a47237b2e613a22e5584108b8b2a"/></dir><dir name="de_AT"><file name="Shopgate_Framework.csv" hash="664a8dc7470fd9675ca7a67f2bcd1325"/></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="shopgate"><file name="logo.png" hash="b7139047ecc90b15a5710ab0fe77fc81"/><file name="logo_big.png" hash="b98bfcf09766589506a1cca24ca47972"/><file name="logo_small.png" hash="7abf7f774c592eb582c2856e027af798"/><file name="oauth_connect.js" hash="8e5c77d9ad1354f826445f03c91008f4"/><file name="shopgate_admin.css" hash="0fbc07171267b9fb5dba7004a0858f66"/><file name="target.js" hash="80484a4dae515f708c97545d9959673a"/></dir></dir></dir></dir></target><target name="magelib"><dir name="Shopgate"><dir name="assets"><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/><file name="js_header.html" hash="7ff2c12f8b7c23542f3ff49b451720a8"/><file name="link_tag.html" hash="f7c53599b55d442fd49f970bd41eb2a4"/><file name="mobile_header.html" hash="17616650e160eaccd24e25729396c5a9"/></dir><file name="changelog.txt" hash="884b4bb189210f5d1fec0beed4b691ce"/><dir name="classes"><file name="apis.php" hash="b5140492d42f2758d4432467052f6404"/><file name="configuration.php" hash="80c04dc5fdbee49fb4a279133f57751d"/><file name="core.php" hash="33aa00679cb2e55fc51c36ad6acd6a41"/><file name="customers.php" hash="3bc00737d0cfd788c24f52b303babd8a"/><file name="external_orders.php" hash="811471d13c2a3c5aa5d1a1eb859f74e6"/><dir name="helper"><file name="DataStructure.php" hash="ece9e9f855756777f543d090f5ecc710"/><file name="Pricing.php" hash="fd4c74999abc3bfa05fd74994a2ce78f"/><file name="String.php" hash="10c9396b2975bf0bde86f171932c3074"/><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/><dir name="redirect"><file name="KeywordsManager.php" hash="6cf7278e7aed1a072c9b94fd99e585a5"/><file name="KeywordsManagerInterface.php" hash="32cda83161084b4f5904eeb5f50a6547"/><file name="LinkBuilder.php" hash="8d6c7225dc90fde0c62c65e24e618bd8"/><file name="LinkBuilderInterface.php" hash="a755af7b57fda9b9ff1564a0059529d1"/><file name="MobileRedirect.php" hash="63f2775caac9a2d6004c7908d9be8611"/><file name="MobileRedirectInterface.php" hash="80b8da18c8bf498461c2b8e183bce326"/><file name="Redirector.php" hash="1a06dc19980c8a51ae0cdbed4d04322d"/><file name="RedirectorInterface.php" hash="9a11e4e85b6005029458a035e4295935"/><file name="SettingsManager.php" hash="d1b1722715688da2a095fba8c607f45c"/><file name="SettingsManagerInterface.php" hash="ae16aa5ea4df7f0def80711f8cc14f70"/><file name="TagsGenerator.php" hash="de6e73da61a282d24226065671d67d6b"/><file name="TagsGeneratorInterface.php" hash="1a5c500631331a4ae970d2a442e5d7e2"/><file name="TemplateParser.php" hash="68637447481351705d742c3a7f083fc6"/><file name="TemplateParserInterface.php" hash="d6897cd9e5622d1991bb7aab678e37f8"/></dir></dir><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/><file name="items.php" hash="7a361efd0a5327c0ad0f0745c1b74cc0"/><dir name="models"><file name="Abstract.php" hash="a32633283eb403a55a166bbad70b3e2f"/><file name="AbstractExport.php" hash="f265f9e906208e1799994d117582be20"/><file name="XmlEmptyObject.php" hash="d6cfdae3bdd858d4f10fcebdb542f533"/><file name="XmlResultObject.php" hash="340804eb0f2ba6bcb6b05311b8bb1f11"/><dir name="catalog"><file name="Attribute.php" hash="28d8f3bc6c416661d1eaa77726ba7009"/><file name="AttributeGroup.php" hash="0270086ec8006ee8231c6b0baa8d6034"/><file name="Category.php" hash="beba58d2796cf7b4ca08ce68de65415b"/><file name="CategoryPath.php" hash="475869aef74c567c8569ee9953210faa"/><file name="Identifier.php" hash="d9a3b16d1fcdec641ca2b0fd77fbd625"/><file name="Input.php" hash="77df45fd89aec19565a5fae7178205bb"/><file name="Manufacturer.php" hash="e45f534f5f6acad118be24ffc63a0460"/><file name="Option.php" hash="fd95fe72bff985ae0b2861da115e2468"/><file name="Price.php" hash="3cb25372ae58bd0c71b342f9ef2dca73"/><file name="Product.php" hash="7e7c49e10b379eae5d0141efe2c91305"/><file name="Property.php" hash="5967f0403a606a27ea4fec71a8402327"/><file name="Relation.php" hash="263cde539af500af911baec4e354079e"/><file name="Review.php" hash="72c94cb1f2a54bafffdb5672d87ecd4d"/><file name="Shipping.php" hash="1fe425496bd9720dc18bd076e56aca9e"/><file name="Stock.php" hash="4e645877e778ec8d02ae98262bfa9663"/><file name="Tag.php" hash="39e7b845ab157d2f707707576e868d64"/><file name="TierPrice.php" hash="9dd757c9c3d193944a5727fbe5cf4704"/><file name="Validation.php" hash="0be71640c1df60ab809347194ec66457"/><file name="Visibility.php" hash="d60c6b8ec486da4afdc46a00d65ad172"/><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/><dir name="media"><file name="Attachment.php" hash="c074ef3426c2506350cbf5ff0133c89d"/><file name="Image.php" hash="c9319f2a82811239313e328eaf7e2094"/><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir><dir name="redirect"><file name="DeeplinkSuffix.php" hash="e6aebbb49db1b3b1d0bbb3a5f8e52927"/><file name="DeeplinkSuffixValue.php" hash="809684ff8f7d588d39060f5469e2c3b0"/><file name="DeeplinkSuffixValueDisabled.php" hash="83ff30aeeaf40c070f71b29b7f2bbbd8"/><file name="DeeplinkSuffixValueUnset.php" hash="1275996c7d012acfa3fbd6cbe43b08b3"/><file name="HtmlTag.php" hash="e5494a280dd090e3869445431e6c8c2a"/><file name="HtmlTagAttribute.php" hash="368c63b7c3043f7ae0bee107527152de"/><file name="HtmlTagVariable.php" hash="1484f93ec0e69b3f94313e4cac849e0f"/></dir></dir><file name="orders.php" hash="aeb0df3eab7b68d1189dc6851fb96a24"/><file name="redirect.php" hash="5b0c5d5d7115bb0ddc9ab96e6120ad7b"/></dir><dir name="config"><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir><file name="index.php" hash="de19abc78063ea9a4112964c79946f1c"/><file name="shopgate.php" hash="248033be19931f7eccdc40d12e59d1bf"/><file name="shopgate_license.txt" hash="21fbb2f00b832416916b27c5e3f5d6d1"/><dir name="temp"><dir name="cache"><file name="index.php" hash="7573387748996e2dd9e02a237056f158"/></dir><file name="index.php" hash="7573387748996e2dd9e02a237056f158"/><dir name="logs"><file name="index.php" hash="7573387748996e2dd9e02a237056f158"/></dir></dir><dir name="vendors"><file name="2d_is.php" hash="087decaca87ee85d548d8caaa43f1212"/><file name="BSD_license.txt" hash="2df4dd93533ca2c19f6f2d601bc3e0d5"/><file name="JSON.php" hash="c8398aeb5c3c71aeb1813389d9a030af"/><file name="index.php" hash="bfc5021f1ee9b67f78a0fc9fdab6c558"/></dir><file name=".htaccess" hash="34479bc8d9df775c38a980ecaf6f3f4b"/></dir></target><target name="mage"><dir name="app"><dir name="design"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="shopgate.xml" hash="608ba89093ef89e1c182cd6085dbf3b1"/></dir><dir name="template"><dir name="shopgate"><file name="mobile_website.phtml" hash="229cbefd12ea77676f8af9c7159528ea"/><dir name="payment"><file name="mobile_payment.phtml" hash="1e18979028fb13e99af7c595c75a5d27"/><file name="shopgate.phtml" hash="1e18979028fb13e99af7c595c75a5d27"/></dir></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="shopgate.xml" hash="8bab300fb25a48cd2c8119ae1942ed54"/></dir><dir name="template"><dir name="shopgate"><dir name="oauth"><dir name="config"><file name="connector.phtml" hash="478c309bdde7834bf20a48b65a4699fb"/></dir><dir name="connect"><file name="info.phtml" hash="4f75dc4311616081873a7d416b96c1c2"/><file name="overlay.phtml" hash="2a17d5b6ff8023568437b194f8a9d482"/></dir><file name="connect.phtml" hash="6956aa22eedf549c4565304b4e4a4ab9"/><file name="data.phtml" hash="09b4c5d83863f104db7a018510cdb315"/><file name="disconnect.phtml" hash="2858cebe9004c9fb5764f79faee46f87"/><file name="manage.phtml" hash="1f99255efbce4dbdc1ee781820d455b8"/></dir><dir name="payment"><file name="mobile_payment.phtml" hash="2892e0dd200db6c0ffa5fa83f87d838c"/><file name="shopgate.phtml" hash="5457030290f8aa08c2711a8bd27c3dee"/></dir></dir></dir></dir></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>