Gemgento_Rails_Connect - Version 0.0.1

Version Notes

Initial release

Download this release

Release Info

Developer gemgento
Extension Gemgento_Rails_Connect
Version 0.0.1
Comparing to
See all releases


Version 0.0.1

Files changed (39) hide show
  1. app/code/community/Gemgento/Catalog/Model/Category/Api.php +81 -0
  2. app/code/community/Gemgento/Catalog/Model/Category/Api/V2.php +134 -0
  3. app/code/community/Gemgento/Catalog/Model/Product/Action.php +51 -0
  4. app/code/community/Gemgento/Catalog/etc/api.xml +21 -0
  5. app/code/community/Gemgento/Catalog/etc/config.xml +19 -0
  6. app/code/community/Gemgento/Catalog/etc/wsdl.xml +104 -0
  7. app/code/community/Gemgento/Catalog/etc/wsi.xml +58 -0
  8. app/code/community/Gemgento/Checkout/Model/Api/Resource/Customer.php +13 -0
  9. app/code/community/Gemgento/Checkout/Model/Cart/Api.php +116 -0
  10. app/code/community/Gemgento/Checkout/Model/Cart/Api/V2.php +13 -0
  11. app/code/community/Gemgento/Checkout/Model/Cart/Payment/Api.php +38 -0
  12. app/code/community/Gemgento/Checkout/Model/Cart/Payment/Api/V2.php +45 -0
  13. app/code/community/Gemgento/Checkout/etc/api.xml +24 -0
  14. app/code/community/Gemgento/Checkout/etc/config.xml +21 -0
  15. app/code/community/Gemgento/Checkout/etc/wsdl.xml +12 -0
  16. app/code/community/Gemgento/Checkout/etc/wsi.xml +35 -0
  17. app/code/community/Gemgento/Customer/Model/Customer/Api.php +38 -0
  18. app/code/community/Gemgento/Customer/Model/Customer/Api/V2.php +19 -0
  19. app/code/community/Gemgento/Customer/etc/config.xml +18 -0
  20. app/code/community/Gemgento/Order/Model/Resource/Setup.php +5 -0
  21. app/code/community/Gemgento/Order/etc/config.xml +51 -0
  22. app/code/community/Gemgento/Order/sql/gemgento_order_setup/install-0.0.1.php +67 -0
  23. app/code/community/Gemgento/ProductSearch/Helper/Data.php +92 -0
  24. app/code/community/Gemgento/ProductSearch/Model/Api.php +63 -0
  25. app/code/community/Gemgento/ProductSearch/Model/Api/V2.php +7 -0
  26. app/code/community/Gemgento/ProductSearch/etc/api.xml +34 -0
  27. app/code/community/Gemgento/ProductSearch/etc/config.xml +19 -0
  28. app/code/community/Gemgento/ProductSearch/etc/wsdl.xml +41 -0
  29. app/code/community/Gemgento/ProductSearch/etc/wsi.xml +0 -0
  30. app/code/community/Gemgento/Push/Model/Observer.php +661 -0
  31. app/code/community/Gemgento/Push/etc/adminhtml.xml +22 -0
  32. app/code/community/Gemgento/Push/etc/config.xml +219 -0
  33. app/code/community/Gemgento/Push/etc/system.xml +57 -0
  34. app/code/community/Gemgento/Sales/Model/Service/Quote.php +137 -0
  35. app/code/community/Gemgento/Sales/etc/config.xml +17 -0
  36. app/code/community/Gemgento/Tool/CreateCustomerAttribute.php +60 -0
  37. app/code/community/Gemgento/Tool/CreateProductAttribute.php +40 -0
  38. app/etc/modules/Gemgento.xml +71 -0
  39. package.xml +20 -0
app/code/community/Gemgento/Catalog/Model/Category/Api.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_Catalog_Model_Category_Api extends Mage_Catalog_Model_Category_Api {
4
+
5
+ /**
6
+ * Initilize and return category model
7
+ *
8
+ * @param int $categoryId
9
+ * @param string|int $store
10
+ * @return Mage_Catalog_Model_Category
11
+ */
12
+ protected function _initCategory($categoryId, $store = null) {
13
+ $category = Mage::getModel('catalog/category')
14
+ ->setStoreId(( $store == null ? $this->_getStoreId($store) : $store))
15
+ ->load($categoryId);
16
+
17
+ if (!$category->getId()) {
18
+ $this->_fault('not_exists');
19
+ }
20
+
21
+ return $category;
22
+ }
23
+
24
+ /**
25
+ * Retrieve list of assigned products to category
26
+ *
27
+ * @param int $categoryId
28
+ * @param string|int $storeId
29
+ * @return array
30
+ */
31
+ public function assignedProducts($categoryId, $storeId = 0) {
32
+ $category = $this->_initCategory($categoryId, $storeId);
33
+ $positions = $category->getProductsPosition();
34
+ $collection = $category->setStoreId($storeId)->getProductCollection();
35
+ $result = array();
36
+
37
+ foreach ($collection as $product) {
38
+ $result[] = array(
39
+ 'product_id' => $product->getId(),
40
+ 'type' => $product->getTypeId(),
41
+ 'set' => $product->getAttributeSetId(),
42
+ 'sku' => $product->getSku(),
43
+ 'position' => $positions[$product->getId()]
44
+ );
45
+ }
46
+
47
+ return $result;
48
+ }
49
+
50
+ /**
51
+ * Update category production positions
52
+ *
53
+ * @param array $productPositions
54
+ * @return Boolean
55
+ */
56
+ public function updateProductPositions($categoryId, $productPositions, $storeId = 0) {
57
+ $category = $this->_initCategory($categoryId, $storeId);
58
+ $positions = $category->getProductsPosition();
59
+
60
+ foreach($productPositions as $productPosition) {
61
+ if (!isset($positions[$productPosition->productId])) {
62
+ $this->_fault('product_not_assigned');
63
+ }
64
+
65
+ $positions[$productPosition->productId] = $productPosition->position;
66
+ }
67
+
68
+ $category->setPostedProducts($positions);
69
+
70
+ try {
71
+ $category->save();
72
+ } catch (Mage_Core_Exception $e) {
73
+ $this->_fault('data_invalid', $e->getMessage());
74
+ }
75
+
76
+ return true;
77
+ }
78
+
79
+ }
80
+
81
+ // Class Mage_Catalog_Model_Category_Api End
app/code/community/Gemgento/Catalog/Model/Category/Api/V2.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Gemgento_Catalog_Model_Category_Api_V2 extends Gemgento_Catalog_Model_Category_Api
3
+ {
4
+ /**
5
+ * Retrieve category data
6
+ *
7
+ * @param int $categoryId
8
+ * @param string|int $store
9
+ * @param array $attributes
10
+ * @return array
11
+ */
12
+ public function info($categoryId, $store = null, $attributes = null)
13
+ {
14
+ $category = $this->_initCategory($categoryId, $store);
15
+
16
+ // Basic category data
17
+ $result = array();
18
+ $result['category_id'] = $category->getId();
19
+
20
+ $result['is_active'] = $category->getIsActive();
21
+ $result['position'] = $category->getPosition();
22
+ $result['level'] = $category->getLevel();
23
+
24
+ foreach ($category->getAttributes() as $attribute) {
25
+ if ($this->_isAllowedAttribute($attribute, $attributes)) {
26
+ $result[$attribute->getAttributeCode()] = $category->getDataUsingMethod($attribute->getAttributeCode());
27
+ }
28
+ }
29
+ $result['parent_id'] = $category->getParentId();
30
+ $result['children'] = $category->getChildren();
31
+ $result['all_children'] = $category->getAllChildren();
32
+
33
+ return $result;
34
+ }
35
+
36
+ /**
37
+ * Create new category
38
+ *
39
+ * @param int $parentId
40
+ * @param array $categoryData
41
+ * @return int
42
+ */
43
+ public function create($parentId, $categoryData, $store = null)
44
+ {
45
+ $parent_category = $this->_initCategory($parentId, $store);
46
+
47
+ /* @var $category Mage_Catalog_Model_Category */
48
+ $category = Mage::getModel('catalog/category')
49
+ ->setStoreId($this->_getStoreId($store));
50
+
51
+ $category->addData(array('path'=>implode('/',$parent_category->getPathIds())));
52
+
53
+ $category ->setAttributeSetId($category->getDefaultAttributeSetId());
54
+
55
+
56
+ foreach ($category->getAttributes() as $attribute) {
57
+ $_attrCode = $attribute->getAttributeCode();
58
+ if ($this->_isAllowedAttribute($attribute)
59
+ && isset($categoryData->$_attrCode)) {
60
+ $category->setData(
61
+ $attribute->getAttributeCode(),
62
+ $categoryData->$_attrCode
63
+ );
64
+ }
65
+ }
66
+ $category->setParentId($parent_category->getId());
67
+ try {
68
+ $validate = $category->validate();
69
+ if ($validate !== true) {
70
+ foreach ($validate as $code => $error) {
71
+ if ($error === true) {
72
+ Mage::throwException(Mage::helper('catalog')->__('Attribute "%s" is required.', $code));
73
+ }
74
+ else {
75
+ Mage::throwException($error);
76
+ }
77
+ }
78
+ }
79
+
80
+ $category->save();
81
+ }
82
+ catch (Mage_Core_Exception $e) {
83
+ $this->_fault('data_invalid', $e->getMessage());
84
+ }
85
+
86
+ return $category->getId();
87
+ }
88
+
89
+ /**
90
+ * Update category data
91
+ *
92
+ * @param int $categoryId
93
+ * @param array $categoryData
94
+ * @param string|int $store
95
+ * @return boolean
96
+ */
97
+ public function update($categoryId, $categoryData, $store = null)
98
+ {
99
+ $category = $this->_initCategory($categoryId, $store);
100
+
101
+ foreach ($category->getAttributes() as $attribute) {
102
+ $_attrCode = $attribute->getAttributeCode();
103
+ if ($this->_isAllowedAttribute($attribute)
104
+ && isset($categoryData->$_attrCode)) {
105
+ $category->setData(
106
+ $attribute->getAttributeCode(),
107
+ $categoryData->$_attrCode
108
+ );
109
+ }
110
+ }
111
+
112
+ try {
113
+ $validate = $category->validate();
114
+ if ($validate !== true) {
115
+ foreach ($validate as $code => $error) {
116
+ if ($error === true) {
117
+ Mage::throwException(Mage::helper('catalog')->__('Attribute "%s" is required.', $code));
118
+ }
119
+ else {
120
+ Mage::throwException($error);
121
+ }
122
+ }
123
+ }
124
+ $category->save();
125
+ } catch (Mage_Core_Exception $e) {
126
+ $this->_fault('data_invalid', $e->getMessage());
127
+ } catch (Mage_Eav_Model_Entity_Attribute_Exception $e) {
128
+ $this->_fault('data_invalid', $e->getMessage());
129
+ }
130
+
131
+ return true;
132
+ }
133
+ }
134
+
app/code/community/Gemgento/Catalog/Model/Product/Action.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Catalog Product Mass Action processing model
4
+ *
5
+ * @category Gemgento
6
+ * @package Gemgento_Catalog
7
+ * @author Gemgento Team
8
+ */
9
+ class Gemgento_Catalog_Model_Product_Action extends Mage_Catalog_Model_Product_Action
10
+ {
11
+
12
+ /**
13
+ * Update attribute values for entity list per store
14
+ *
15
+ * @param array $productIds
16
+ * @param array $attrData
17
+ * @param int $storeId
18
+ * @return Mage_Catalog_Model_Product_Action
19
+ */
20
+ public function updateAttributes($productIds, $attrData, $storeId)
21
+ {
22
+ Mage::dispatchEvent('catalog_product_attribute_update_before', array(
23
+ 'attributes_data' => &$attrData,
24
+ 'product_ids' => &$productIds,
25
+ 'store_id' => &$storeId
26
+ ));
27
+
28
+ $this->_getResource()->updateAttributes($productIds, $attrData, $storeId);
29
+ $this->setData(array(
30
+ 'product_ids' => array_unique($productIds),
31
+ 'attributes_data' => $attrData,
32
+ 'store_id' => $storeId
33
+ ));
34
+
35
+ $curr_date = date("Y-m-d H:i:s");
36
+
37
+ foreach ($productIds as $productId) {
38
+ $product = Mage::getModel('catalog/product')->load($productId);
39
+ $productInfoData = $product->getData();
40
+ $productInfoData['updated_at'] = $curr_date;
41
+ $product->setData($productInfoData);
42
+ $product->save();
43
+ }
44
+
45
+ // register mass action indexer event
46
+ Mage::getSingleton('index/indexer')->processEntityAction(
47
+ $this, Mage_Catalog_Model_Product::ENTITY, Mage_Index_Model_Event::TYPE_MASS_ACTION
48
+ );
49
+ return $this;
50
+ }
51
+ }
app/code/community/Gemgento/Catalog/etc/api.xml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <api>
4
+ <resources>
5
+ <catalog_category translate="title" module="catalog">
6
+ <model>catalog/category_api</model>
7
+ <title>Category API</title>
8
+ <methods>
9
+ <assignedProducts translate="title" module="catalog">
10
+ <title>Retrieve list of assigned products</title>
11
+ <acl>catalog/category/product</acl>
12
+ </assignedProducts>
13
+ <updateProductPositions translate="title" module="catalog">
14
+ <title>Update category product positions</title>
15
+ <acl>catalog/category</acl>
16
+ </updateProductPositions>
17
+ </methods>
18
+ </catalog_category>
19
+ </resources>
20
+ </api>
21
+ </config>
app/code/community/Gemgento/Catalog/etc/config.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Gemgento_Catalog>
5
+ <version>0.0.1</version>
6
+ </Gemgento_Catalog>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <catalog>
11
+ <rewrite>
12
+ <category_api>Gemgento_Catalog_Model_Category_Api</category_api>
13
+ <category_api_v2>Gemgento_Catalog_Model_Category_Api_V2</category_api_v2>
14
+ <product_action>Gemgento_Catalog_Model_Product_Action</product_action>
15
+ </rewrite>
16
+ </catalog>
17
+ </models>
18
+ </global>
19
+ </config>
app/code/community/Gemgento/Catalog/etc/wsdl.xml ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <definitions xmlns:typens="urn:Magento" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" name="Magento" targetNamespace="urn:Magento">
3
+ <types>
4
+ <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
5
+ <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"/>
6
+ <complexType name="catalogAssignedProduct">
7
+ <all>
8
+ <element name="product_id" type="xsd:int"/>
9
+ <element name="type" type="xsd:string"/>
10
+ <element name="set" type="xsd:int"/>
11
+ <element name="sku" type="xsd:string"/>
12
+ <element name="position" type="xsd:string"/>
13
+ </all>
14
+ </complexType>
15
+ <complexType name="catalogAssignedProductArray">
16
+ <complexContent>
17
+ <restriction base="soapenc:Array">
18
+ <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:catalogAssignedProduct[]"/>
19
+ </restriction>
20
+ </complexContent>
21
+ </complexType>
22
+ <complexType name="catalogCategoryInfo">
23
+ <all>
24
+ <element name="category_id" type="xsd:string"/>
25
+ <element name="is_active" type="xsd:int"/>
26
+ <element name="position" type="xsd:string"/>
27
+ <element name="level" type="xsd:string"/>
28
+ <element name="parent_id" type="xsd:string"/>
29
+ <element name="all_children" type="xsd:string"/>
30
+ <element name="children" type="xsd:string"/>
31
+ <element name="created_at" type="xsd:string" minOccurs="0"/>
32
+ <element name="updated_at" type="xsd:string" minOccurs="0"/>
33
+ <element name="name" type="xsd:string" minOccurs="0"/>
34
+ <element name="url_key" type="xsd:string" minOccurs="0"/>
35
+ <element name="description" type="xsd:string" minOccurs="0"/>
36
+ <element name="meta_title" type="xsd:string" minOccurs="0"/>
37
+ <element name="meta_keywords" type="xsd:string" minOccurs="0"/>
38
+ <element name="meta_description" type="xsd:string" minOccurs="0"/>
39
+ <element name="path" type="xsd:string" minOccurs="0"/>
40
+ <element name="url_path" type="xsd:string" minOccurs="0"/>
41
+ <element name="children_count" type="xsd:int" minOccurs="0"/>
42
+ <element name="display_mode" type="xsd:string" minOccurs="0"/>
43
+ <element name="is_anchor" type="xsd:int" minOccurs="0"/>
44
+ <element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0"/>
45
+ <element name="custom_design" type="xsd:string" minOccurs="0"/>
46
+ <element name="custom_design_apply" type="xsd:string" minOccurs="0"/>
47
+ <element name="custom_design_from" type="xsd:string" minOccurs="0"/>
48
+ <element name="custom_design_to" type="xsd:string" minOccurs="0"/>
49
+ <element name="page_layout" type="xsd:string" minOccurs="0"/>
50
+ <element name="custom_layout_update" type="xsd:string" minOccurs="0"/>
51
+ <element name="default_sort_by" type="xsd:string" minOccurs="0"/>
52
+ <element name="landing_page" type="xsd:int" minOccurs="0"/>
53
+ <element name="image" type="xsd:string" minOccurs="0"/>
54
+ <element name="include_in_menu" type="xsd:string" minOccurs="0"/>
55
+ </all>
56
+ </complexType>
57
+
58
+ <complexType name="categoryProductPositionEntityArray">
59
+ <complexContent>
60
+ <restriction base="soapenc:Array">
61
+ <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:categoryProductPositionEntity[]"/>
62
+ </restriction>
63
+ </complexContent>
64
+ </complexType>
65
+ <complexType name="categoryProductPositionEntity">
66
+ <all>
67
+ <element name="productId" type="xsd:ind" />
68
+ <element name="position" type="xsd:int"/>
69
+ </all>
70
+ </complexType>
71
+ </schema>
72
+ </types>
73
+
74
+ <message name="catalogCategoryUpdateProductPositionsRequest">
75
+ <part name="sessionId" type="xsd:string"/>
76
+ <part name="categoryId" type="xsd:int" />
77
+ <part name="productPositions" type="typens:categoryProductPositionEntityArray"/>
78
+ <part name="storeId" type="xsd:int" />
79
+ </message>
80
+ <message name="catalogCategoryUpdateProductPositionsResponse">
81
+ <part name="response" type="xsd:boolean" />
82
+ </message>
83
+
84
+ <portType name="{{var wsdl.handler}}PortType">
85
+ <operation name="catalogCategoryUpdateProductPositions">
86
+ <documentation>Update category product positions.</documentation>
87
+ <input message="typens:catalogCategoryUpdateProductPositionsRequest" />
88
+ <output message="typens:catalogCategoryUpdateProductPositionsResponse" />
89
+ </operation>
90
+ </portType>
91
+
92
+ <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
93
+ <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
94
+ <operation name="catalogCategoryUpdateProductPositions">
95
+ <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
96
+ <input>
97
+ <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
98
+ </input>
99
+ <output>
100
+ <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
101
+ </output>
102
+ </operation>
103
+ </binding>
104
+ </definitions>
app/code/community/Gemgento/Catalog/etc/wsi.xml ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
5
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
6
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
7
+ name="{{var wsdl.name}}"
8
+ targetNamespace="urn:{{var wsdl.name}}">
9
+ <wsdl:types>
10
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
11
+ <xsd:complexType name="complexMultiFilter">
12
+ <xsd:sequence>
13
+ <xsd:element name="product_id" type="xsd:int"/>
14
+ <xsd:element name="type" type="xsd:string"/>
15
+ <xsd:element name="set" type="xsd:int"/>
16
+ <xsd:element name="sku" type="xsd:string"/>
17
+ <xsd:element name="position" type="xsd:int"/>
18
+ </xsd:sequence>
19
+ </xsd:complexType>
20
+ <xsd:complexType name="catalogCategoryInfo">
21
+ <xsd:sequence>
22
+ <xsd:element name="category_id" type="xsd:string" />
23
+ <xsd:element name="is_active" type="xsd:int" />
24
+ <xsd:element name="position" type="xsd:string" />
25
+ <xsd:element name="level" type="xsd:string" />
26
+ <xsd:element name="parent_id" type="xsd:string" />
27
+ <xsd:element name="all_children" type="xsd:string" />
28
+ <xsd:element name="children" type="xsd:string" />
29
+ <xsd:element name="created_at" type="xsd:string" minOccurs="0" />
30
+ <xsd:element name="updated_at" type="xsd:string" minOccurs="0" />
31
+ <xsd:element name="name" type="xsd:string" minOccurs="0" />
32
+ <xsd:element name="url_key" type="xsd:string" minOccurs="0" />
33
+ <xsd:element name="description" type="xsd:string" minOccurs="0" />
34
+ <xsd:element name="meta_title" type="xsd:string" minOccurs="0" />
35
+ <xsd:element name="meta_keywords" type="xsd:string" minOccurs="0" />
36
+ <xsd:element name="meta_description" type="xsd:string" minOccurs="0" />
37
+ <xsd:element name="path" type="xsd:string" minOccurs="0" />
38
+ <xsd:element name="url_path" type="xsd:string" minOccurs="0" />
39
+ <xsd:element name="children_count" type="xsd:int" minOccurs="0" />
40
+ <xsd:element name="display_mode" type="xsd:string" minOccurs="0" />
41
+ <xsd:element name="is_anchor" type="xsd:int" minOccurs="0" />
42
+ <xsd:element name="available_sort_by" type="typens:ArrayOfString" minOccurs="0" />
43
+ <xsd:element name="custom_design" type="xsd:string" minOccurs="0" />
44
+ <xsd:element name="custom_design_apply" type="xsd:string" minOccurs="0" />
45
+ <xsd:element name="custom_design_from" type="xsd:string" minOccurs="0" />
46
+ <xsd:element name="custom_design_to" type="xsd:string" minOccurs="0" />
47
+ <xsd:element name="page_layout" type="xsd:string" minOccurs="0" />
48
+ <xsd:element name="custom_layout_update" type="xsd:string" minOccurs="0" />
49
+ <xsd:element name="default_sort_by" type="xsd:string" minOccurs="0" />
50
+ <xsd:element name="landing_page" type="xsd:int" minOccurs="0" />
51
+ <xsd:element name="image" type="xsd:int" minOccurs="0" />
52
+ <xsd:element name="include_in_menu" type="xsd:int" minOccurs="0" />
53
+ </xsd:sequence>
54
+ </xsd:complexType>
55
+
56
+ </xsd:schema>
57
+ </wsdl:types>
58
+ </wsdl:definitions>
app/code/community/Gemgento/Checkout/Model/Api/Resource/Customer.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_Checkout_Model_Api_Resource_Customer extends Mage_Checkout_Model_Api_Resource_Customer
4
+ {
5
+ protected function _prepareGuestQuote(Mage_Sales_Model_Quote $quote)
6
+ {
7
+ $quote->setCustomerId(null)
8
+ ->setCustomerEmail($quote->getCustomerEmail())
9
+ ->setCustomerIsGuest(true)
10
+ ->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
11
+ return $this;
12
+ }
13
+ }
app/code/community/Gemgento/Checkout/Model/Cart/Api.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_Checkout_Model_Cart_Api extends Mage_Checkout_Model_Cart_Api {
4
+
5
+ protected function _preparePaymentData($data) {
6
+ if (!(is_array($data) && is_null($data[0]))) {
7
+ return array();
8
+ }
9
+
10
+ return $data;
11
+ }
12
+
13
+ /**
14
+ * Create new quote for shopping cart
15
+ *
16
+ * @param int|string $store
17
+ * @return int
18
+ */
19
+ public function create($store = null, $gemgentoId = null) {
20
+ $storeId = $this->_getStoreId($store);
21
+
22
+ try {
23
+ /* @var $quote Mage_Sales_Model_Quote */
24
+ $quote = Mage::getModel('sales/quote');
25
+ $quote->setStoreId($storeId)
26
+ ->setIsActive(true)
27
+ ->setIsMultiShipping(false)
28
+ ->setGemgentoId($gemgentoId)
29
+ ->save();
30
+ } catch (Mage_Core_Exception $e) {
31
+ $this->_fault('create_quote_fault', $e->getMessage());
32
+ }
33
+ return (int) $quote->getId();
34
+ }
35
+
36
+ /**
37
+ * Create an order from the shopping cart (quote)
38
+ *
39
+ * @param $quoteId
40
+ * @param $store
41
+ * @param $paymentData array
42
+ * @param $agreements array
43
+ * @return string
44
+ */
45
+ public function createOrder($quoteId, $store = null, $agreements = null, $paymentData = null, $remoteIp = null) {
46
+ $requiredAgreements = Mage::helper('checkout')->getRequiredAgreementIds();
47
+
48
+ if (!empty($requiredAgreements)) {
49
+ $diff = array_diff($agreements, $requiredAgreements);
50
+ if (!empty($diff)) {
51
+ $this->_fault('required_agreements_are_not_all');
52
+ }
53
+ }
54
+
55
+ $quote = $this->_getQuote($quoteId, $store);
56
+ if ($quote->getIsMultiShipping()) {
57
+ $this->_fault('invalid_checkout_type');
58
+ }
59
+ if ($quote->getCheckoutMethod() == Mage_Checkout_Model_Api_Resource_Customer::MODE_GUEST && !Mage::helper('checkout')->isAllowedGuestCheckout($quote, $quote->getStoreId())) {
60
+ $this->_fault('guest_checkout_is_not_enabled');
61
+ }
62
+
63
+ // set the customers ip
64
+ if ($remoteIp == null) {
65
+ $remoteIp = Mage::helper('core/http')->getRemoteAddr();
66
+ }
67
+
68
+ $quote->setRemoteIp($remoteIp)->save();
69
+
70
+ /** @var $customerResource Mage_Checkout_Model_Api_Resource_Customer */
71
+ $customerResource = Mage::getModel("checkout/api_resource_customer");
72
+ $isNewCustomer = $customerResource->prepareCustomerForQuote($quote);
73
+
74
+ try {
75
+ $quote->collectTotals();
76
+ /** @var $service Mage_Sales_Model_Service_Quote */
77
+ $service = Mage::getModel('sales/service_quote', $quote);
78
+
79
+ // cc_number and cc_cid are lost because API is stateless, need to add them back
80
+ if ($paymentData != null) {
81
+ $paymentData = $this->_preparePaymentData($paymentData);
82
+ $service->getQuote()->getPayment()->importData($paymentData);
83
+ }
84
+
85
+ $service->submitAll();
86
+
87
+ if ($isNewCustomer) {
88
+ try {
89
+ $customerResource->involveNewCustomer($quote);
90
+ } catch (Exception $e) {
91
+ Mage::logException($e);
92
+ }
93
+ }
94
+
95
+ $order = $service->getOrder();
96
+ if ($order) {
97
+ Mage::dispatchEvent('checkout_type_onepage_save_order_after', array('order' => $order, 'quote' => $quote));
98
+
99
+ try {
100
+ $order->sendNewOrderEmail();
101
+ } catch (Exception $e) {
102
+ Mage::logException($e);
103
+ }
104
+ }
105
+
106
+ Mage::dispatchEvent(
107
+ 'checkout_submit_all_after', array('order' => $order, 'quote' => $quote)
108
+ );
109
+ } catch (Mage_Core_Exception $e) {
110
+ $this->_fault('create_order_fault', $e->getMessage());
111
+ }
112
+
113
+ return $order->getIncrementId();
114
+ }
115
+
116
+ }
app/code/community/Gemgento/Checkout/Model/Cart/Api/V2.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_Checkout_Model_Cart_Api_V2 extends Gemgento_Checkout_Model_Cart_Api {
4
+
5
+ protected function _preparePaymentData($data) {
6
+ if (null !== ($_data = get_object_vars($data))) {
7
+ return parent::_preparePaymentData($_data);
8
+ }
9
+
10
+ return array();
11
+ }
12
+
13
+ }
app/code/community/Gemgento/Checkout/Model/Cart/Payment/Api.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Checkout
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Shopping cart api
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Checkout
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+
35
+ class Gemgento_Checkout_Model_Cart_Payment_Api extends Mage_Checkout_Model_Cart_Payment_Api
36
+ {
37
+
38
+ }
app/code/community/Gemgento/Checkout/Model/Cart/Payment/Api/V2.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * DISCLAIMER
17
+ *
18
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
19
+ * versions in the future. If you wish to customize Magento for your
20
+ * needs please refer to http://www.magentocommerce.com for more information.
21
+ *
22
+ * @category Mage
23
+ * @package Mage_Checkout
24
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ */
27
+
28
+ /**
29
+ * Shopping cart api
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Checkout
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class Gemgento_Checkout_Model_Cart_Payment_Api_V2 extends Gemgento_Checkout_Model_Cart_Payment_Api {
36
+
37
+ protected function _preparePaymentData($data) {
38
+ if (null !== ($_data = get_object_vars($data))) {
39
+ return parent::_preparePaymentData($_data);
40
+ }
41
+
42
+ return array();
43
+ }
44
+
45
+ }
app/code/community/Gemgento/Checkout/etc/api.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <api>
4
+ <resources>
5
+ <cart translate="title" module="checkout">
6
+ <model>checkout/cart_api</model>
7
+ <title>Shopping Cart</title>
8
+ <acl>cart</acl>
9
+ <methods>
10
+ <create translate="title" module="checkout">
11
+ <title>Create shopping cart</title>
12
+ <method>create</method>
13
+ <acl>cart/create</acl>
14
+ </create>
15
+ <order translate="title" module="checkout">
16
+ <title>Create an order from shopping cart</title>
17
+ <method>createOrder</method>
18
+ <acl>cart/order</acl>
19
+ </order>
20
+ </methods>
21
+ </cart>
22
+ </resources>
23
+ </api>
24
+ </config>
app/code/community/Gemgento/Checkout/etc/config.xml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Gemgento_Catalog>
5
+ <version>0.0.1</version>
6
+ </Gemgento_Catalog>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <checkout>
11
+ <rewrite>
12
+ <api_resource_customer>Gemgento_Checkout_Model_Api_Resource_Customer</api_resource_customer>
13
+ <cart_api>Gemgento_Checkout_Model_Cart_Api</cart_api>
14
+ <cart_api_v2>Gemgento_Checkout_Model_Cart_Api_V2</cart_api_v2>
15
+ <cart_payment_api>Gemgento_Checkout_Model_Cart_Payment_Api</cart_payment_api>
16
+ <cart_payment_api_v2>Gemgento_Checkout_Model_Cart_Payment_Api_V2</cart_payment_api_v2>
17
+ </rewrite>
18
+ </checkout>
19
+ </models>
20
+ </global>
21
+ </config>
app/code/community/Gemgento/Checkout/etc/wsdl.xml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <definitions xmlns:typens="urn:Magento" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/" name="Magento" targetNamespace="urn:Magento">
3
+ <message name="shoppingCartCreateRequest">
4
+ <part name="gemgentoId" type="xsd:int" minOccurs="0"/>
5
+ </message>
6
+
7
+ <message name="shoppingCartOrderRequest">
8
+ <part name="paymentData" type="typens:shoppingCartPaymentMethodEntity" minOccurs="0"/>
9
+ <part name="remoteIp" type="xsd:string" minOccurs="0"/>
10
+ </message>
11
+
12
+ </definitions>
app/code/community/Gemgento/Checkout/etc/wsi.xml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
5
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
6
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
7
+ name="{{var wsdl.name}}"
8
+ targetNamespace="urn:{{var wsdl.name}}">
9
+ <wsdl:types>
10
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
11
+ <xsd:element name="shoppingCartCreateRequestParam">
12
+ <xsd:complexType>
13
+ <xsd:sequence>
14
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
15
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
16
+ <xsd:element minOccurs="0" maxOccurs="1" name="gemgentoId" type="xsd:int" />
17
+ </xsd:sequence>
18
+ </xsd:complexType>
19
+ </xsd:element>
20
+
21
+ <xsd:element name="shoppingCartOrderRequestParam">
22
+ <xsd:complexType>
23
+ <xsd:sequence>
24
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
25
+ <xsd:element minOccurs="1" maxOccurs="1" name="quoteId" type="xsd:int" />
26
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
27
+ <xsd:element minOccurs="0" maxOccurs="1" name="agreements" type="typens:ArrayOfString" />
28
+ <xsd:element minOccurs="0" maxOccurs="1" name="paymentData" type="typens:shoppingCartPaymentMethodEntity" />
29
+ <xsd:element minOccurs="0" maxOccurs="1" name="remoteIp" type="xsd:string" />
30
+ </xsd:sequence>
31
+ </xsd:complexType>
32
+ </xsd:element>
33
+ </xsd:schema>
34
+ </wsdl:types>
35
+ </wsdl:definitions>
app/code/community/Gemgento/Customer/Model/Customer/Api.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_Customer_Model_Customer_Api extends Mage_Customer_Model_Customer_Api
4
+ {
5
+
6
+ /**
7
+ * Update customer data
8
+ *
9
+ * @param int $customerId
10
+ * @param array $customerData
11
+ * @return boolean
12
+ */
13
+ public function update($customerId, $customerData)
14
+ {
15
+ $customerData = $this->_prepareData($customerData);
16
+
17
+ $customer = Mage::getModel('customer/customer')->load($customerId);
18
+
19
+ if (!$customer->getId()) {
20
+ $this->_fault('not_exists');
21
+ }
22
+
23
+ foreach ($this->getAllowedAttributes($customer) as $attributeCode=>$attribute) {
24
+ print($attributeCode . '\n');
25
+ if (isset($customerData[$attributeCode])) {
26
+ $customer->setData($attributeCode, $customerData[$attributeCode]);
27
+ }
28
+ }
29
+
30
+ if (isset($customerData['password']) && $customerData['password'] !== '') {
31
+ $customer->setPassword($customerData['password']);
32
+ }
33
+
34
+ $customer->save();
35
+ return true;
36
+ }
37
+
38
+ } // Class Mage_Customer_Model_Customer_Api End
app/code/community/Gemgento/Customer/Model/Customer/Api/V2.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_Customer_Model_Customer_Api_V2 extends Gemgento_Customer_Model_Customer_Api
4
+ {
5
+ /**
6
+ * Prepare data to insert/update.
7
+ * Creating array for stdClass Object
8
+ *
9
+ * @param stdClass $data
10
+ * @return array
11
+ */
12
+ protected function _prepareData($data)
13
+ {
14
+ if (null !== ($_data = get_object_vars($data))) {
15
+ return parent::_prepareData($_data);
16
+ }
17
+ return array();
18
+ }
19
+ }
app/code/community/Gemgento/Customer/etc/config.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Gemgento_Catalog>
5
+ <version>0.0.1</version>
6
+ </Gemgento_Catalog>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <customer>
11
+ <rewrite>
12
+ <customer_api>Gemgento_Customer_Model_Customer_Api</customer_api>
13
+ <customer_api_v2>Gemgento_Customer_Model_Customer_Api_V2</customer_api_v2>
14
+ </rewrite>
15
+ </customer>
16
+ </models>
17
+ </global>
18
+ </config>
app/code/community/Gemgento/Order/Model/Resource/Setup.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_Order_Model_Resource_Setup extends Mage_Sales_Model_Resource_Setup {
4
+ // nothing here
5
+ }
app/code/community/Gemgento/Order/etc/config.xml ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <config>
3
+ <modules>
4
+ <Gemgento_Order>
5
+ <version>0.0.1</version>
6
+ </Gemgento_Order>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <order>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>Gemgento_Order</module>
14
+ <frontName>order</frontName>
15
+ </args>
16
+ </order>
17
+ </routers>
18
+ </frontend>
19
+ <global>
20
+ <models>
21
+ <order>
22
+ <class>Gemgento_Order_Model</class>
23
+ <resourceModel>order_resource</resourceModel>
24
+ </order>
25
+ <order_resource>
26
+ <class>Gemgento_Order_Model_Resource</class>
27
+ <deprecatedNote>order_mysql4</deprecatedNote>
28
+ </order_resource>
29
+ </models>
30
+ <resources>
31
+ <gemgento_order_setup>
32
+ <setup>
33
+ <module>Gemgento_Order</module>
34
+ <class>Gemgento_Order_Model_Resource_Setup</class>
35
+ </setup>
36
+ </gemgento_order_setup>
37
+ </resources>
38
+ <fieldsets>
39
+ <sales_convert_quote>
40
+ <gemgento_id>
41
+ <to_order>*</to_order>
42
+ </gemgento_id>
43
+ </sales_convert_quote>
44
+ <sales_convert_order>
45
+ <gemgento_id>
46
+ <to_quote>*</to_quote>
47
+ </gemgento_id>
48
+ </sales_convert_order>
49
+ </fieldsets>
50
+ </global>
51
+ </config>
app/code/community/Gemgento/Order/sql/gemgento_order_setup/install-0.0.1.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ $installer->startSetup();
5
+
6
+ // add gemgento_id to quotes and orders
7
+ $entitiesToAlter = array('quote', 'order');
8
+ $attribute = array(
9
+ 'type' => Varien_Db_Ddl_Table::TYPE_INTEGER,
10
+ 'default' => NULL
11
+ );
12
+
13
+ foreach ($entitiesToAlter as $entityName) {
14
+ $installer->addAttribute($entityName, 'gemgento_id', $attribute);
15
+ }
16
+
17
+ // add gemgento_id to customers
18
+ $vCustomerEntityType = $installer->getEntityTypeId('customer');
19
+ $vCustAttributeSetId = $installer->getDefaultAttributeSetId($vCustomerEntityType);
20
+ $vCustAttributeGroupId = $installer->getDefaultAttributeGroupId($vCustomerEntityType, $vCustAttributeSetId);
21
+
22
+ $installer->addAttribute('customer', 'gemgento_id', array(
23
+ 'label' => 'Gemgento Id',
24
+ 'input' => 'text',
25
+ 'type' => 'int',
26
+ 'forms' => array('customer_account_edit','customer_account_create','adminhtml_customer','checkout_register'),
27
+ 'required' => 0,
28
+ 'user_defined' => 1,
29
+ ));
30
+
31
+ $installer->addAttributeToGroup($vCustomerEntityType, $vCustAttributeSetId, $vCustAttributeGroupId, 'gemgento_id', 0);
32
+
33
+ $oAttribute = Mage::getSingleton('eav/config')->getAttribute('customer', 'gemgento_id');
34
+ $oAttribute->setData('used_in_forms', array('customer_account_edit','customer_account_create','adminhtml_customer','checkout_register'));
35
+ $oAttribute->save();
36
+
37
+
38
+ // add gemgento_id to products
39
+ $attrCode = 'gemgento_id';
40
+
41
+ $objCatalogEavSetup = Mage::getResourceModel('catalog/eav_mysql4_setup', 'core_setup');
42
+ $attrIdTest = $objCatalogEavSetup->getAttributeId(Mage_Catalog_Model_Product::ENTITY, $attrCode);
43
+
44
+ if ($attrIdTest === false) {
45
+ $objCatalogEavSetup->addAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode, array(
46
+ 'group' => 'General',
47
+ 'type' => 'varchar',
48
+ 'backend' => '',
49
+ 'frontend' => '',
50
+ 'label' => 'Gemgento Id',
51
+ 'note' => 'The product id in Gemgento',
52
+ 'input' => 'text',
53
+ 'class' => '',
54
+ 'source' => '',
55
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
56
+ 'visible' => true,
57
+ 'required' => false,
58
+ 'user_defined' => true,
59
+ 'default' => NULL,
60
+ 'visible_on_front' => false,
61
+ 'unique' => false,
62
+ 'is_configurable' => false,
63
+ 'used_for_promo_rules' => false
64
+ ));
65
+ }
66
+
67
+ $installer->endSetup();
app/code/community/Gemgento/ProductSearch/Helper/Data.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_ProductSearch_Helper_Data extends Mage_CatalogSearch_Helper_Data {
4
+
5
+ public function GemgentoApiSetQueryText($queryText) {
6
+
7
+ $this->_queryText = $queryText;
8
+ if ($this->_queryText === null) {
9
+ $this->_queryText = '';
10
+ } else {
11
+ if (is_array($this->_queryText)) {
12
+ $this->_queryText = null;
13
+ }
14
+ $this->_queryText = trim($this->_queryText);
15
+ $this->_queryText = Mage::helper('core/string')->cleanString($this->_queryText);
16
+
17
+ if (Mage::helper('core/string')->strlen($this->_queryText) > $this->getMaxQueryLength()) {
18
+ $this->_queryText = Mage::helper('core/string')->substr(
19
+ $this->_queryText, 0, $this->getMaxQueryLength()
20
+ );
21
+ $this->_isMaxLength = true;
22
+ }
23
+ }
24
+ return $this;
25
+ }
26
+
27
+ public function getQueryText() {
28
+ if (!$this->_queryText) {
29
+ $this->_queryText = $this->_getRequest()->getParam($this->getQueryParamName());
30
+ if ($this->_queryText === null) {
31
+ $this->_queryText = '';
32
+ } else {
33
+ if (is_array($this->_queryText)) {
34
+ $this->_queryText = null;
35
+ }
36
+ $this->_queryText = trim($this->_queryText);
37
+ $this->_queryText = Mage::helper('core/string')->cleanString($this->_queryText);
38
+
39
+ if (Mage::helper('core/string')->strlen($this->_queryText) > $this->getMaxQueryLength()) {
40
+ $this->_queryText = Mage::helper('core/string')->substr(
41
+ $this->_queryText, 0, $this->getMaxQueryLength()
42
+ );
43
+ $this->_isMaxLength = true;
44
+ }
45
+ }
46
+ }
47
+ return $this->_queryText;
48
+ }
49
+
50
+ public function getRequest() {
51
+ return $this->_getRequest();
52
+ }
53
+
54
+ public function setQueryText() {
55
+ $this->getRequest()->setParam($this->getQueryParamName(), $this->getQueryText());
56
+ return $this;
57
+ }
58
+
59
+ public function gemgentoCustomSearchInit() {
60
+ $query = Mage::helper('catalogsearch')->getQuery();
61
+
62
+ $query->setStoreId(Mage::app()->getStore()->getId());
63
+
64
+ if ($query->getQueryText()) {
65
+ if (Mage::helper('catalogsearch')->isMinQueryLength()) {
66
+ $query->setId(0)
67
+ ->setIsActive(1)
68
+ ->setIsProcessed(1);
69
+ } else {
70
+ if ($query->getId()) {
71
+ $query->setPopularity($query->getPopularity() + 1);
72
+ } else {
73
+ $query->setPopularity(1);
74
+ }
75
+
76
+ if ($query->getRedirect()) {
77
+ $query->save();
78
+ $this->getResponse()->setRedirect($query->getRedirect());
79
+ return;
80
+ } else {
81
+ $query->prepare();
82
+ }
83
+ }
84
+ if (!Mage::helper('catalogsearch')->isMinQueryLength()) {
85
+ $query->save();
86
+ }
87
+ }
88
+ }
89
+
90
+ }
91
+
92
+ ?>
app/code/community/Gemgento/ProductSearch/Model/Api.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_ProductSearch_Model_Api extends Mage_Catalog_Model_Api_Resource {
4
+
5
+ public function results($query, $limit = null, $page = 0) {
6
+ $result = array();
7
+
8
+ if ($limit !== null && !is_numeric($limit)) {
9
+ $this->_fault('invalid_limit', 'The supplied limit for the search results is invalid!');
10
+ return $result;
11
+ } elseif (!is_numeric($page)) {
12
+ $this->_fault('invalid_page', 'The supplied page for the search results is invalid!');
13
+ return $result;
14
+ }
15
+
16
+ $productList = $this->_performSearch($query, $limit, $page);
17
+
18
+ if ($productList) {
19
+ foreach ($productList as $product) {
20
+ $result[] = $product->getId();
21
+ }
22
+ }
23
+
24
+ return $result;
25
+ }
26
+
27
+ private function _performSearch($query, $limit = null, $page = 0) {
28
+ $currentStoreId = Mage::app()->getStore()->getId();
29
+ // Use default Store if Store has not been set already
30
+ if (!$currentStoreId) {
31
+ Mage::app()->getStore()->setId(Mage::app()->getDefaultStoreView()->getStoreId());
32
+ }
33
+
34
+ //Set the search parameter
35
+ Mage::helper('productSearch')->getRequest()->setParam('q', $query);
36
+
37
+ //Save or get the query data from the database
38
+ Mage::helper('productSearch')->gemgentoCustomSearchInit();
39
+
40
+ // Preform the search
41
+ $productList = Mage::getModel('catalogsearch/fulltext')->getCollection()
42
+ ->addAttributeToSelect('*')
43
+ ->addSearchFilter(Mage::helper('catalogsearch')->getQuery()->getQueryText())
44
+ ->addStoreFilter()
45
+ ->addUrlRewrite()
46
+ ->addFieldToFilter('visibility', array(
47
+ Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH, // visible both in search and in catalog...
48
+ Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH // visible in search...
49
+ ))
50
+ ->setPage($page, $limit);
51
+
52
+ // Sort result set by relevance if possible
53
+ $currentSearchType = Mage::getStoreConfig('catalog/search/search_type', $currentStoreId);
54
+ if ($currentSearchType && ($currentSearchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_FULLTEXT || $currentSearchType == Mage_CatalogSearch_Model_Fulltext::SEARCH_TYPE_COMBINE)) {
55
+ $productList->getSelect()->order(array('relevance DESC'));
56
+ }
57
+
58
+ return $productList;
59
+ }
60
+
61
+ }
62
+
63
+ ?>
app/code/community/Gemgento/ProductSearch/Model/Api/V2.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_ProductSearch_Model_Api_V2 extends Gemgento_ProductSearch_Model_Api {
4
+ //empty
5
+ }
6
+
7
+ ?>
app/code/community/Gemgento/ProductSearch/etc/api.xml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <api>
3
+ <resources>
4
+ <productSearch translate="title" module="productSearch">
5
+ <title>Gemgento Product Search</title>
6
+ <model>productSearch/api</model>
7
+ <acl>gemgento/productSearch</acl>
8
+ <methods>
9
+ <results translate="title" module="productSearch">
10
+ <title>Perform a search and return resulting product Ids</title>
11
+ <acl>gemgento/productSearch</acl>
12
+ </results>
13
+ </methods>
14
+ </productSearch>
15
+ </resources>
16
+ <v2>
17
+ <resources_function_prefix>
18
+ <productSearch>productSearch</productSearch>
19
+ </resources_function_prefix>
20
+ </v2>
21
+ <acl> Access Control Results to our resources, this tree structure is displayed in "Resource Roles" panel when you open role to edit
22
+ <resources>
23
+ <gemgento translate="title" module="productSearch">
24
+ <title>Gemgento</title>
25
+ <productSearch translate="title" module="productSearch">
26
+ <title>Product Search</title>
27
+ </productSearch>
28
+ </gemgento>
29
+ <all>
30
+ </all>
31
+ </resources>
32
+ </acl>
33
+ </api>
34
+ </config>
app/code/community/Gemgento/ProductSearch/etc/config.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <modules>
3
+ <Gemgento_ProductSearch>
4
+ <version>0.0.1</version>
5
+ </Gemgento_ProductSearch>
6
+ </modules>
7
+ <global>
8
+ <models>
9
+ <productSearch>
10
+ <class>Gemgento_ProductSearch_Model</class>
11
+ </productSearch>
12
+ </models>
13
+ <helpers>
14
+ <productSearch>
15
+ <class>Gemgento_ProductSearch_Helper</class>
16
+ </productSearch>
17
+ </helpers>
18
+ </global>
19
+ </config>
app/code/community/Gemgento/ProductSearch/etc/wsdl.xml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
3
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
4
+ name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
5
+ <types>
6
+ <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
7
+ <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
8
+ </schema>
9
+ </types>
10
+ <message name="productSearchResultsRequest">
11
+ <part name="sessionId" type="xsd:string"/>
12
+ <part name="query" type="xsd:string"/>
13
+ </message>
14
+ <message name="productSearchResultsResponse">
15
+ <part name="result" type="soapenc:Array" />
16
+ </message>
17
+ <portType name="{{var wsdl.handler}}PortType">
18
+ <operation name="productSearchResults">
19
+ <documentation>Perform a search.</documentation>
20
+ <input message="typens:productSearchResultsRequest" />
21
+ <output message="typens:productSearchResultsResponse" />
22
+ </operation>
23
+ </portType>
24
+ <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
25
+ <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
26
+ <operation name="productSearchResults">
27
+ <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
28
+ <input>
29
+ <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
30
+ </input>
31
+ <output>
32
+ <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
33
+ </output>
34
+ </operation>
35
+ </binding>
36
+ <service name="{{var wsdl.name}}Service">
37
+ <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
38
+ <soap:address location="{{var wsdl.url}}" />
39
+ </port>
40
+ </service>
41
+ </definitions>
app/code/community/Gemgento/ProductSearch/etc/wsi.xml ADDED
File without changes
app/code/community/Gemgento/Push/Model/Observer.php ADDED
@@ -0,0 +1,661 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Gemgento_Push_Model_Observer {
4
+
5
+ var $_complexProductTypes = array('configurable', 'bundle', 'grouped');
6
+ protected $_ignoredAttributeCodes = array(
7
+ 'global' => array('entity_id', 'attribute_set_id', 'entity_type_id')
8
+ );
9
+
10
+ public function __construct() {
11
+
12
+ }
13
+
14
+ /**
15
+ * Send customer address data to Gemgento.
16
+ *
17
+ * @param \Varien_Event_Observer $observer
18
+ */
19
+ public function address_save($observer) {
20
+
21
+ if (!is_object(Mage::getSingleton('admin/session')->getUser())) {
22
+ return; # if event was not triggered by admin, stop here
23
+ }
24
+
25
+ $data = $observer->getEvent()->getCustomerAddress()->debug();
26
+ self::push('PUT', 'addresses', $data['entity_id'], $data);
27
+ }
28
+
29
+ /**
30
+ * Delete customer address data in Gemgento.
31
+ *
32
+ * @param \Varien_Event_Observer $observer
33
+ */
34
+ public function address_delete($observer) {
35
+ $data = $observer->getEvent()->getCustomerAddress()->debug();
36
+ self::push('DELETE', 'addresses', $data['entity_id'], $data);
37
+ }
38
+
39
+ /**
40
+ * Send product data to Gemgento
41
+ *
42
+ * @param \Varien_Event_Observer $observer
43
+ */
44
+ public function product_save($observer) {
45
+
46
+ if (!is_object(Mage::getSingleton('admin/session')->getUser())) {
47
+ return; # if event was not triggered by admin, stop here
48
+ }
49
+
50
+ $product = $observer->getProduct();
51
+
52
+ // Basic product data
53
+ $data = array(
54
+ 'product_id' => $product->getId(),
55
+ 'gemgento_id' => $product->getGemgentoId(),
56
+ 'sku' => $product->getSku(),
57
+ 'set' => $product->getAttributeSetId(),
58
+ 'type' => $product->getTypeId(),
59
+ 'websites' => $product->getWebsiteIds(),
60
+ 'stores' => $product->getStoreIds(),
61
+ 'additional_attributes' => array(),
62
+ 'simple_product_ids' => array(),
63
+ 'configurable_product_ids' => Mage::getResourceSingleton('catalog/product_type_configurable')->getParentIdsByChild($product->getId())
64
+ );
65
+
66
+ if ($product->getTypeId() == 'configurable') {
67
+ $conf = Mage::getModel('catalog/product_type_configurable')->setProduct($product);
68
+ $simple_collection = $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions();
69
+ foreach ($simple_collection as $simple_product) {
70
+ $data['simple_product_ids'][] = $simple_product->getId();
71
+ }
72
+ }
73
+
74
+ // load attribute values for each store
75
+ foreach ($data['stores'] as $storeId) {
76
+ $product = Mage::getModel('catalog/product')->setStoreId($storeId)->load($data['product_id']);
77
+ $data['additional_attributes'][$storeId] = array();
78
+
79
+ foreach ($product->getTypeInstance(true)->getEditableAttributes($product) as $attribute) {
80
+ $data['additional_attributes'][$storeId][$attribute->getAttributeCode()] = $product->getData($attribute->getAttributeCode());
81
+ }
82
+
83
+ $data['additional_attributes'][$storeId]['category_ids'] = $product->getCategoryIds();
84
+
85
+ if (isset($data['additional_attributes'][$storeId]['media_gallery']) && isset($data['additional_attributes'][$storeId]['media_gallery']['images'])) {
86
+
87
+ # loop through each image
88
+ foreach ($data['additional_attributes'][$storeId]['media_gallery']['images'] as $index => $image) {
89
+ $types = array();
90
+
91
+ # load the type(s) for each image
92
+ foreach ($product->getMediaAttributes() as $mediaAttribute) {
93
+ if ($product->getData($mediaAttribute->getAttributeCode()) == $image['file']) {
94
+ $types[] = $mediaAttribute->getAttributeCode();
95
+ }
96
+ }
97
+
98
+ #set the image types in the result array
99
+ $data['additional_attributes'][$storeId]['media_gallery']['images'][$index]['types'] = $types;
100
+ }
101
+ }
102
+ }
103
+
104
+ $id = $data['gemgento_id'];
105
+
106
+ if ($id == NULL || $id == '') {
107
+ $id = 0;
108
+ }
109
+
110
+ self::push('PUT', 'products', $id, $data);
111
+ }
112
+
113
+ /**
114
+ * Delete product in Gemgento
115
+ *
116
+ * @param \Varien_Event_Observer $observer
117
+ */
118
+ public function product_delete($observer) {
119
+ $product = $observer->getProduct();
120
+
121
+ $data = array(
122
+ 'product_id' => $product->getId(),
123
+ 'gemgento_id' => $product->getGemgentoId()
124
+ );
125
+
126
+ $id = $data['gemgento_id'];
127
+
128
+ if ($id == NULL || $id == '') {
129
+ $id = 0;
130
+ }
131
+
132
+ self::push('DELETE', 'products', $id, $data);
133
+ }
134
+
135
+ /**
136
+ * Send stock data to Gemgento
137
+ *
138
+ * @param \Varien_Event_Observer $observer
139
+ */
140
+ public function stock_save($observer) {
141
+ $product_id = $observer->getEvent()->getItem()->getProductId();
142
+ $product = Mage::getModel('catalog/product')->load($product_id);
143
+ $data = array(
144
+ 'product_id' => $product_id,
145
+ 'inventories' => array()
146
+ );
147
+
148
+ $stock = array(); // stock data for all websites
149
+ $stockCollection = Mage::getResourceModel('cataloginventory/stock_item_collection')->addProductsFilter(array($product))->load();
150
+ $maxWebsite_id = 0;
151
+
152
+ foreach ($stockCollection as $stockItem) {
153
+ $tmpStock = $stockItem->getData();
154
+
155
+ if ($maxWebsite_id < $tmpStock['website_id']) {
156
+ $maxWebsite_id = $tmpStock['website_id'];
157
+ }
158
+ if (in_array($product->getTypeId(), $this->_complexProductTypes)) {
159
+ $this->_filterComplexProductValues($tmpStock);
160
+ }
161
+ $stock[$tmpStock['website_id']] = $tmpStock;
162
+ }
163
+
164
+ foreach ($stock as $key => $value) {
165
+ if (isset($values['website_id']) && ($value['website_id'] == $maxWebsite_id || empty($value['website_id']))) {
166
+ unset($stock[$key]);
167
+ }
168
+ }
169
+
170
+ $data['inventories'] = $stock;
171
+
172
+ self::push('PUT', 'inventory', $data['product_id'], $data);
173
+ }
174
+
175
+ /**
176
+ * Send category data to Gemgento
177
+ *
178
+ * @param \Varien_Event_Observer $observer
179
+ */
180
+ public function category_save($observer) {
181
+ $category = $observer->getEvent()->getCategory();
182
+
183
+ // basic category data
184
+ $data = array(
185
+ 'category_id' => $category->getId(),
186
+ 'is_active' => $category->getIsActive(),
187
+ 'position' => $category->getPosition(),
188
+ 'level' => $category->getLevel(),
189
+ 'store_ids' => $category->getStoreIds(),
190
+ 'products' => array()
191
+ );
192
+
193
+ // additional category attributes
194
+ foreach ($category->getAttributes() as $attribute) {
195
+ $data[$attribute->getAttributeCode()] = $category->getData($attribute->getAttributeCode());
196
+ }
197
+
198
+ // store specific product listings
199
+ foreach ($data['store_ids'] as $storeId) {
200
+ Mage::getModel('catalog/category')->setStoreId($storeId)->load($data['category_id']);
201
+ $data['products']["0{$storeId}"] = array();
202
+ $positions = $category->getProductsPosition();
203
+ $collection = $category->getProductCollection();
204
+
205
+ foreach ($collection as $product) {
206
+ $data['products']["0{$storeId}"][] = array(
207
+ 'product_id' => $product->getId(),
208
+ 'position' => $positions[$product->getId()]
209
+ );
210
+ }
211
+ }
212
+
213
+ self::push('PUT', 'categories', $data['category_id'], $data);
214
+ }
215
+
216
+ /**
217
+ * Delete category in Gemgento
218
+ *
219
+ * @param \Varien_Event_Observer $observer
220
+ */
221
+ public function category_delete($observer) {
222
+ $category = $observer->getEvent()->getCategory();
223
+
224
+ self::push('DELETE', 'categories', $category->getId(), array());
225
+ }
226
+
227
+ /**
228
+ * Change category position.
229
+ *
230
+ * @param \Varien_Event_Observer $observer
231
+ */
232
+ public function category_move($observer) {
233
+ $category = $observer->getEvent()->getCategory();
234
+
235
+ // basic category data
236
+ $data = array(
237
+ 'category_id' => $category->getId(),
238
+ 'is_active' => $category->getIsActive(),
239
+ 'position' => $category->getPosition(),
240
+ 'level' => $category->getLevel(),
241
+ 'store_ids' => $category->getStoreIds(),
242
+ 'products' => array()
243
+ );
244
+
245
+ // additional category attributes
246
+ foreach ($category->getAttributes() as $attribute) {
247
+ $data[$attribute->getAttributeCode()] = $category->getData($attribute->getAttributeCode());
248
+ }
249
+
250
+ self::push('PUT', 'categories', $data['category_id'], $data);
251
+ }
252
+
253
+ /**
254
+ * Send attribute set data to Gemgento
255
+ *
256
+ * @param \Varien_Event_Observer $observer
257
+ */
258
+ public function attribute_set_save($observer) {
259
+ $attribute_set = $observer->getEvent()->getObject();
260
+ $attributes = Mage::getModel('catalog/product')->getResource()
261
+ ->loadAllAttributes()
262
+ ->getSortedAttributes($attribute_set->getId());
263
+
264
+ $data = array(
265
+ 'set_id' => $attribute_set->getId(),
266
+ 'name' => $attribute_set->getAttributeSetName(),
267
+ 'attributes' => array()
268
+ );
269
+
270
+ foreach ($attributes as $attribute) {
271
+ $data['attributes'][] = $attribute->getAttributeId();
272
+ }
273
+
274
+ self::push('PUT', 'product_attribute_sets', $data['set_id'], $data);
275
+ }
276
+
277
+ /**
278
+ * Delete attribute set data in Gemgento
279
+ *
280
+ * @param \Varien_Event_Observer $observer
281
+ */
282
+ public function attribute_set_delete($observer) {
283
+ $attribute_set = $observer->getEvent()->getObject();
284
+
285
+ self::push('DELETE', 'product_attribute_sets', $attribute_set->getId(), array());
286
+ }
287
+
288
+ /**
289
+ * Send attribute data to Gemgento
290
+ *
291
+ * @param \Varien_Event_Observer $observer
292
+ */
293
+ public function attribute_save($observer) {
294
+ $model = $observer->getEvent()->getAttribute();
295
+
296
+ if ($model->getAttributeCode() === NULL) {
297
+ return NULL;
298
+ }
299
+
300
+ if ($model->isScopeGlobal()) {
301
+ $scope = 'global';
302
+ } elseif ($model->isScopeWebsite()) {
303
+ $scope = 'website';
304
+ } else {
305
+ $scope = 'store';
306
+ }
307
+
308
+ $frontendLabels = array();
309
+ $options = array();
310
+
311
+ foreach ($model->getStoreLabels() as $store_id => $label) {
312
+ $frontendLabels[] = array(
313
+ 'store_id' => $store_id,
314
+ 'label' => $label
315
+ );
316
+
317
+ $store_options = $model->setStoreId($store_id)->getSource()->getAllOptions();
318
+
319
+ if (sizeof($store_options) == 1 && $store_options[0]['label'] === '') {
320
+ $store_options = array();
321
+ }
322
+
323
+ $options[] = array(
324
+ 'store_id' => $store_id,
325
+ 'options' => $store_options
326
+ );
327
+ }
328
+
329
+ $data = array(
330
+ 'attribute_id' => $model->getId(),
331
+ 'attribute_code' => $model->getAttributeCode(),
332
+ 'frontend_input' => $model->getFrontendInput(),
333
+ 'default_value' => $model->getDefaultValue(),
334
+ 'is_unique' => $model->getIsUnique(),
335
+ 'is_required' => $model->getIsRequired(),
336
+ 'apply_to' => $model->getApplyTo(),
337
+ 'is_configurable' => $model->getIsConfigurable(),
338
+ 'is_searchable' => $model->getIsSearchable(),
339
+ 'is_visible_in_advanced_search' => $model->getIsVisibleInAdvancedSearch(),
340
+ 'is_comparable' => $model->getIsComparable(),
341
+ 'is_used_for_promo_rules' => $model->getIsUsedForPromoRules(),
342
+ 'is_visible_on_front' => $model->getIsVisibleOnFront(),
343
+ 'used_in_product_listing' => $model->getUsedInProductListing(),
344
+ 'frontend_label' => $frontendLabels,
345
+ 'options' => $options
346
+ );
347
+
348
+ if ($model->getFrontendInput() != 'price') {
349
+ $data['scope'] = $scope;
350
+ }
351
+
352
+ // set additional fields to different types
353
+ switch ($model->getFrontendInput()) {
354
+ case 'text':
355
+ $data['additional_fields'] = array(
356
+ 'frontend_class' => $model->getFrontendClass(),
357
+ 'is_html_allowed_on_front' => $model->getIsHtmlAllowedOnFront(),
358
+ 'used_for_sort_by' => $model->getUsedForSortBy()
359
+ );
360
+ break;
361
+ case 'textarea':
362
+ $data['additional_fields'] = array(
363
+ 'is_wysiwyg_enabled' => $model->getIsWysiwygEnabled(),
364
+ 'is_html_allowed_on_front' => $model->getIsHtmlAllowedOnFront(),
365
+ );
366
+ break;
367
+ case 'date':
368
+ case 'boolean':
369
+ $data['additional_fields'] = array(
370
+ 'used_for_sort_by' => $model->getUsedForSortBy()
371
+ );
372
+ break;
373
+ case 'multiselect':
374
+ $data['additional_fields'] = array(
375
+ 'is_filterable' => $model->getIsFilterable(),
376
+ 'is_filterable_in_search' => $model->getIsFilterableInSearch(),
377
+ 'position' => $model->getPosition()
378
+ );
379
+ break;
380
+ case 'select':
381
+ case 'price':
382
+ $data['additional_fields'] = array(
383
+ 'is_filterable' => $model->getIsFilterable(),
384
+ 'is_filterable_in_search' => $model->getIsFilterableInSearch(),
385
+ 'position' => $model->getPosition(),
386
+ 'used_for_sort_by' => $model->getUsedForSortBy()
387
+ );
388
+ break;
389
+ default:
390
+ $data['additional_fields'] = array();
391
+ break;
392
+ }
393
+
394
+ self::push('PUT', 'product_attributes', $data['attribute_id'], $data);
395
+ }
396
+
397
+ /**
398
+ * Delete attribute in Gemgento
399
+ *
400
+ * @param \Varien_Event_Observer $observer
401
+ */
402
+ public function attribute_delete($observer) {
403
+ $attribute = $observer->getEvent()->getAttribute();
404
+
405
+ self::push('DELETE', 'product_attributes', $attribute->getId(), array());
406
+ }
407
+
408
+ /**
409
+ * Send customer data to Gemgento
410
+ *
411
+ * @param \Varien_Event_Observer $observer
412
+ */
413
+ public function customer_save($observer) {
414
+
415
+ if (!is_object(Mage::getSingleton('admin/session')->getUser())) {
416
+ return; # if event was not triggered by admin, stop here
417
+ }
418
+
419
+ $customer = $observer->getEvent()->getCustomer();
420
+ $data = array();
421
+
422
+ foreach ($customer->getAttributes() as $attribute) {
423
+ $data[$attribute->getAttributeCode()] = $customer->getData($attribute->getAttributeCode());
424
+ }
425
+
426
+ self::push('PUT', 'users', $data['entity_id'], $data);
427
+ }
428
+
429
+ /**
430
+ * Delete customer in Gemgento
431
+ *
432
+ * @param \Varien_Event_Observer $observer
433
+ */
434
+ public function customer_delete($observer) {
435
+ $customer = $observer->getEvent()->getCustomer();
436
+
437
+ self::push('DELETE', 'users', $customer->getId(), array());
438
+ }
439
+
440
+ /**
441
+ * Send order data to Gemgento
442
+ *
443
+ * @param \Varien_Event_Observer $observer
444
+ */
445
+ public function order_save($observer) {
446
+ $order = $observer->getEvent()->getOrder();
447
+ $data = array();
448
+
449
+ $data = $this->_getAttributes($order, 'order');
450
+
451
+ $data['order_id'] = $order->getId();
452
+ $data['gemgento_id'] = $order->getGemgentoId();
453
+ $data['store_id'] = $order->getStoreId();
454
+ $data['shipping_address'] = $this->_getAttributes($order->getShippingAddress(), 'order_address');
455
+ $data['billing_address'] = $this->_getAttributes($order->getBillingAddress(), 'order_address');
456
+ $data['items'] = array();
457
+
458
+ foreach ($order->getAllItems() as $item) {
459
+ if ($item->getGiftMessageId() > 0) {
460
+ $item->setGiftMessage(
461
+ Mage::getSingleton('giftmessage/message')->load($item->getGiftMessageId())->getMessage()
462
+ );
463
+ }
464
+
465
+ $data['items'][] = $this->_getAttributes($item, 'order_item');
466
+ }
467
+
468
+ // $data['payment'] = $this->_getAttributes($order->getPayment(), 'order_payment');
469
+
470
+ $data['status_history'] = array();
471
+
472
+ foreach ($order->getAllStatusHistory() as $history) {
473
+ $data['status_history'][] = $this->_getAttributes($history, 'order_status_history');
474
+ }
475
+
476
+ $id = $data['gemgento_id'];
477
+
478
+ if ($id == NULL || $id == '') {
479
+ $id = 0;
480
+ }
481
+
482
+ self::push('PUT', 'orders', $id, $data);
483
+ }
484
+
485
+ /**
486
+ * Send store data to Gemgento
487
+ *
488
+ * @param \Varien_Event_Observer $observer
489
+ */
490
+ public function store_save($observer) {
491
+ $store = $observer->getEvent()->getStore();
492
+
493
+ $data = array();
494
+ $data['store_id'] = $store->getId();
495
+ $data['code'] = $store->getCode();
496
+ $data['website_id'] = $store->getWebsiteId();
497
+ $data['group_id'] = $store->getGroupId();
498
+ $data['name'] = $store->getName();
499
+ $data['sort_order'] = $store->getSortOrder();
500
+ $data['is_active'] = $store->getIsActive();
501
+
502
+ self::push('PUT', 'stores', $data['store_id'], $data);
503
+ }
504
+
505
+ /**
506
+ * Send request to Gemgento
507
+ *
508
+ * @param string $action HTTP verb
509
+ * @param string $path the Gemgento URL relative path
510
+ * @param integer $id ID of the model
511
+ * @param array $data paramters to send
512
+ */
513
+ private function push($action, $path, $id, $data) {
514
+ $data_string = json_encode(Array('data' => $data));
515
+ $parts = parse_url($this->gemgento_url() . $path . '/' . $id);
516
+
517
+ $fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80, $errno, $errstr, 30);
518
+
519
+ $out = "$action " . $parts['path'] . " HTTP/1.1\r\n";
520
+ $out.= "Host: " . $parts['host'] . "\r\n";
521
+
522
+ if ($this->gemgento_user() !== NULL && $this->gemgento_password() !== NULL) {
523
+ $out.= "Authorization: Basic " . base64_encode($this->gemgento_user() . ":" . $this->gemgento_password()) . "\r\n";
524
+ }
525
+
526
+ $out.= "Content-Type: application/json\r\n";
527
+ $out.= "Content-Length: " . strlen($data_string) . "\r\n";
528
+ $out.= "Connection: Close\r\n\r\n";
529
+ $out.= $data_string;
530
+
531
+ fwrite($fp, $out);
532
+ fclose($fp);
533
+ }
534
+
535
+ /**
536
+ * Get the Gemgento URL from configuration
537
+ *
538
+ * @return string
539
+ */
540
+ private function gemgento_url() {
541
+ $url = Mage::getStoreConfig("gemgento_push/settings/gemgento_url");
542
+
543
+ if (substr($url, -1) != '/') {
544
+ $url .= '/';
545
+ }
546
+
547
+ return $url;
548
+ }
549
+
550
+ /**
551
+ * Get the Gemgento HTTP auth user from configuration
552
+ *
553
+ * @return string
554
+ */
555
+ private function gemgento_user() {
556
+ $user = Mage::getStoreConfig("gemgento_push/settings/gemgento_user");
557
+
558
+ if ($user === NULL || $user == '') {
559
+ return null;
560
+ } else {
561
+ return $user;
562
+ }
563
+ }
564
+
565
+ /**
566
+ * Get the Gemgento HTTP auth password from configuration
567
+ *
568
+ * @return string
569
+ */
570
+ private function gemgento_password() {
571
+ $user = Mage::getStoreConfig("gemgento_push/settings/gemgento_password");
572
+
573
+ if ($user === NULL || $user == '') {
574
+ return null;
575
+ } else {
576
+ return $user;
577
+ }
578
+ }
579
+
580
+ private function _filterComplexProductValues(&$productData) {
581
+ $validKeys = array(
582
+ 'item_id',
583
+ 'website_id',
584
+ 'product_id',
585
+ 'stock_id',
586
+ 'manage_stock',
587
+ 'use_config_manage_stock',
588
+ 'enable_qty_increments',
589
+ 'use_config_enable_qty_increments',
590
+ 'qty_increments',
591
+ 'use_config_qty_increments',
592
+ 'stock_availability',
593
+ 'is_in_stock',
594
+ );
595
+ foreach ($productData as $key => $value) {
596
+ if (!in_array($key, $validKeys)) {
597
+ unset($productData[$key]);
598
+ }
599
+ }
600
+ }
601
+
602
+ /**
603
+ * Retrieve entity attributes values
604
+ *
605
+ * @param Mage_Core_Model_Abstract $object
606
+ * @param array $attributes
607
+ * @return Mage_Sales_Model_Api_Resource
608
+ */
609
+ protected function _getAttributes($object, $type, array $attributes = null) {
610
+ $result = array();
611
+
612
+ if (!is_object($object)) {
613
+ return $result;
614
+ }
615
+
616
+ foreach ($object->getData() as $attribute => $value) {
617
+ if ($this->_isAllowedAttribute($attribute, $type, $attributes)) {
618
+ $result[$attribute] = $value;
619
+ }
620
+ }
621
+
622
+ if (isset($this->_attributesMap['global'])) {
623
+ foreach ($this->_attributesMap['global'] as $alias => $attributeCode) {
624
+ $result[$alias] = $object->getData($attributeCode);
625
+ }
626
+ }
627
+
628
+ if (isset($this->_attributesMap[$type])) {
629
+ foreach ($this->_attributesMap[$type] as $alias => $attributeCode) {
630
+ $result[$alias] = $object->getData($attributeCode);
631
+ }
632
+ }
633
+
634
+ return $result;
635
+ }
636
+
637
+ /**
638
+ * Check is attribute allowed to usage
639
+ *
640
+ * @param Mage_Eav_Model_Entity_Attribute_Abstract $attribute
641
+ * @param string $entityType
642
+ * @param array $attributes
643
+ * @return boolean
644
+ */
645
+ protected function _isAllowedAttribute($attributeCode, $type, array $attributes = null) {
646
+ if (!empty($attributes) && !(in_array($attributeCode, $attributes))) {
647
+ return false;
648
+ }
649
+
650
+ if (in_array($attributeCode, $this->_ignoredAttributeCodes['global'])) {
651
+ return false;
652
+ }
653
+
654
+ if (isset($this->_ignoredAttributeCodes[$type]) && in_array($attributeCode, $this->_ignoredAttributeCodes[$type])) {
655
+ return false;
656
+ }
657
+
658
+ return true;
659
+ }
660
+
661
+ }
app/code/community/Gemgento/Push/etc/adminhtml.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <gemgento_push>
12
+ <title>Gemgento Push</title> <!-- Used in resources tree -->
13
+ </gemgento_push>
14
+ </children>
15
+ </config>
16
+ </children>
17
+ </system>
18
+ </children>
19
+ </admin>
20
+ </resources>
21
+ </acl>
22
+ </config>
app/code/community/Gemgento/Push/etc/config.xml ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Gemgento_Push>
5
+ <version>0.0.1</version>
6
+ </Gemgento_Push>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <gemgento_push>
11
+ <class>Gemgento_Push_Model</class>
12
+ </gemgento_push>
13
+ </models>
14
+ <events>
15
+
16
+ <!-- ADDRESSES -->
17
+ <customer_address_save_after>
18
+ <observers>
19
+ <push>
20
+ <type>singleton</type>
21
+ <class>Gemgento_Push_Model_Observer</class>
22
+ <method>address_save</method>
23
+ </push>
24
+ </observers>
25
+ </customer_address_save_after>
26
+
27
+ <customer_address_delete_before>
28
+ <observers>
29
+ <push>
30
+ <type>singleton</type>
31
+ <class>Gemgento_Push_Model_Observer</class>
32
+ <method>address_delete</method>
33
+ </push>
34
+ </observers>
35
+ </customer_address_delete_before>
36
+
37
+ <!-- PRODUCTS -->
38
+ <catalog_product_save_after>
39
+ <observers>
40
+ <push>
41
+ <type>singleton</type>
42
+ <class>Gemgento_Push_Model_Observer</class>
43
+ <method>product_save</method>
44
+ </push>
45
+ </observers>
46
+ </catalog_product_save_after>
47
+
48
+ <catalog_product_delete_before>
49
+ <observers>
50
+ <push>
51
+ <type>singleton</type>
52
+ <class>Gemgento_Push_Model_Observer</class>
53
+ <method>product_delete</method>
54
+ </push>
55
+ </observers>
56
+ </catalog_product_delete_before>
57
+
58
+ <!-- STOCK -->
59
+ <cataloginventory_stock_item_save_after>
60
+ <observers>
61
+ <push>
62
+ <type>singleton</type>
63
+ <class>Gemgento_Push_Model_Observer</class>
64
+ <method>stock_save</method>
65
+ </push>
66
+ </observers>
67
+ </cataloginventory_stock_item_save_after>
68
+
69
+ <!-- CATEGORY -->
70
+ <catalog_category_save_after>
71
+ <observers>
72
+ <push>
73
+ <type>singleton</type>
74
+ <class>Gemgento_Push_Model_Observer</class>
75
+ <method>category_save</method>
76
+ </push>
77
+ </observers>
78
+ </catalog_category_save_after>
79
+
80
+ <catalog_category_delete_before>
81
+ <observers>
82
+ <push>
83
+ <type>singleton</type>
84
+ <class>Gemgento_Push_Model_Observer</class>
85
+ <method>category_delete</method>
86
+ </push>
87
+ </observers>
88
+ </catalog_category_delete_before>
89
+
90
+ <catalog_category_tree_move_after>
91
+ <observers>
92
+ <push>
93
+ <type>singleton</type>
94
+ <class>Gemgento_Push_Model_Observer</class>
95
+ <method>category_move</method>
96
+ </push>
97
+ </observers>
98
+ </catalog_category_tree_move_after>
99
+
100
+ <!-- ATTRIBUTE SET -->
101
+ <eav_entity_attribute_set_save_after>
102
+ <observers>
103
+ <push>
104
+ <type>singleton</type>
105
+ <class>Gemgento_Push_Model_Observer</class>
106
+ <method>attribute_set_save</method>
107
+ </push>
108
+ </observers>
109
+ </eav_entity_attribute_set_save_after>
110
+
111
+ <eav_entity_attribute_set_delete_before>
112
+ <observers>
113
+ <push>
114
+ <type>singleton</type>
115
+ <class>Gemgento_Push_Model_Observer</class>
116
+ <method>attribute_set_delete</method>
117
+ </push>
118
+ </observers>
119
+ </eav_entity_attribute_set_delete_before>
120
+
121
+ <!-- ATTRIBUTE -->
122
+ <catalog_entity_attribute_save_after>
123
+ <observers>
124
+ <push>
125
+ <type>singleton</type>
126
+ <class>Gemgento_Push_Model_Observer</class>
127
+ <method>attribute_save</method>
128
+ </push>
129
+ </observers>
130
+ </catalog_entity_attribute_save_after>
131
+
132
+ <eav_entity_attribute_save_after>
133
+ <observers>
134
+ <push>
135
+ <type>singleton</type>
136
+ <class>Gemgento_Push_Model_Observer</class>
137
+ <method>attribute_save</method>
138
+ </push>
139
+ </observers>
140
+ </eav_entity_attribute_save_after>
141
+
142
+ <catalog_entity_attribute_delete_before>
143
+ <observers>
144
+ <push>
145
+ <type>singleton</type>
146
+ <class>Gemgento_Push_Model_Observer</class>
147
+ <method>attribute_delete</method>
148
+ </push>
149
+ </observers>
150
+ </catalog_entity_attribute_delete_before>
151
+
152
+ <eav_entity_attribute_delete_before>
153
+ <observers>
154
+ <push>
155
+ <type>singleton</type>
156
+ <class>Gemgento_Push_Model_Observer</class>
157
+ <method>attribute_delete</method>
158
+ </push>
159
+ </observers>
160
+ </eav_entity_attribute_delete_before>
161
+
162
+ <!-- CUSTOMER -->
163
+ <customer_save_after>
164
+ <observers>
165
+ <push>
166
+ <type>singleton</type>
167
+ <class>Gemgento_Push_Model_Observer</class>
168
+ <method>customer_save</method>
169
+ </push>
170
+ </observers>
171
+ </customer_save_after>
172
+
173
+ <customer_delete_before>
174
+ <observers>
175
+ <push>
176
+ <type>singleton</type>
177
+ <class>Gemgento_Push_Model_Observer</class>
178
+ <method>customer_delete</method>
179
+ </push>
180
+ </observers>
181
+ </customer_delete_before>
182
+
183
+ <!-- ORDER -->
184
+ <sales_order_save_after>
185
+ <observers>
186
+ <push>
187
+ <type>singleton</type>
188
+ <class>Gemgento_Push_Model_Observer</class>
189
+ <method>order_save</method>
190
+ </push>
191
+ </observers>
192
+ </sales_order_save_after>
193
+
194
+ <!-- STORE -->
195
+ <store_save_after>
196
+ <observers>
197
+ <push>
198
+ <type>singleton</type>
199
+ <class>Gemgento_Push_Model_Observer</class>
200
+ <method>store_save</method>
201
+ </push>
202
+ </observers>
203
+ </store_save_after>
204
+ </events>
205
+ </global>
206
+
207
+ <default>
208
+ <gemgento_push>
209
+ <config>
210
+ <gemgento_url>http://localhost:3000/</gemgento_url>
211
+ <gemgento_user></gemgento_user>
212
+ <gemgento_password></gemgento_password>
213
+ </config>
214
+ </gemgento_push>
215
+ </default>
216
+
217
+ </config>
218
+
219
+
app/code/community/Gemgento/Push/etc/system.xml ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <gemgento translate="label">
5
+ <label>Gemgento</label>
6
+ <sort_order>150</sort_order>
7
+ </gemgento>
8
+ </tabs>
9
+ <sections>
10
+ <gemgento_push>
11
+ <label>Push Settings</label>
12
+ <tab>gemgento</tab>
13
+ <frontend_type>text</frontend_type>
14
+ <show_in_default>1</show_in_default>
15
+ <show_in_website>1</show_in_website>
16
+ <show_in_store>1</show_in_store>
17
+ <sort_order>10</sort_order>
18
+ <groups>
19
+ <settings translate="label">
20
+ <label>Gemgento URL</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>10</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>1</show_in_website>
25
+ <show_in_store>1</show_in_store>
26
+ <expanded>1</expanded>
27
+ <fields>
28
+ <gemgento_url translate="label">
29
+ <label>Gemgento Url</label>
30
+ <frontend_type>text</frontend_type>
31
+ <sort_order>1</sort_order>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>1</show_in_website>
34
+ <show_in_store>1</show_in_store>
35
+ </gemgento_url>
36
+ <gemgento_user translate="label">
37
+ <label>Gemgento HTTP Auth User</label>
38
+ <frontend_type>text</frontend_type>
39
+ <sort_order>2</sort_order>
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>1</show_in_website>
42
+ <show_in_store>1</show_in_store>
43
+ </gemgento_user>
44
+ <gemgento_password translate="label">
45
+ <label>Gemgento HTTP Auth Password</label>
46
+ <frontend_type>password</frontend_type>
47
+ <sort_order>3</sort_order>
48
+ <show_in_default>1</show_in_default>
49
+ <show_in_website>1</show_in_website>
50
+ <show_in_store>1</show_in_store>
51
+ </gemgento_password>
52
+ </fields>
53
+ </settings>
54
+ </groups>
55
+ </gemgento_push>
56
+ </sections>
57
+ </config>
app/code/community/Gemgento/Sales/Model/Service/Quote.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Sales
23
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Quote submit service model
29
+ */
30
+ class Gemgento_Sales_Model_Service_Quote extends Mage_Sales_Model_Service_Quote
31
+ {
32
+ /**
33
+ * Submit the quote. Quote submit process will create the order based on quote data
34
+ *
35
+ * @return Mage_Sales_Model_Order
36
+ */
37
+ public function submitOrder()
38
+ {
39
+ $this->_deleteNominalItems();
40
+ $this->_validate();
41
+ $quote = $this->_quote;
42
+ $isVirtual = $quote->isVirtual();
43
+
44
+ $transaction = Mage::getModel('core/resource_transaction');
45
+ if ($quote->getCustomerId()) {
46
+ $transaction->addObject($quote->getCustomer());
47
+ }
48
+ $transaction->addObject($quote);
49
+
50
+ $quote->reserveOrderId();
51
+ if ($isVirtual) {
52
+ $order = $this->_convertor->addressToOrder($quote->getBillingAddress());
53
+ } else {
54
+ $order = $this->_convertor->addressToOrder($quote->getShippingAddress());
55
+ }
56
+ $order->setBillingAddress($this->_convertor->addressToOrderAddress($quote->getBillingAddress()));
57
+ if ($quote->getBillingAddress()->getCustomerAddress()) {
58
+ $order->getBillingAddress()->setCustomerAddress($quote->getBillingAddress()->getCustomerAddress());
59
+ }
60
+ if (!$isVirtual) {
61
+ $order->setShippingAddress($this->_convertor->addressToOrderAddress($quote->getShippingAddress()));
62
+ if ($quote->getShippingAddress()->getCustomerAddress()) {
63
+ $order->getShippingAddress()->setCustomerAddress($quote->getShippingAddress()->getCustomerAddress());
64
+ }
65
+ }
66
+ $order->setPayment($this->_convertor->paymentToOrderPayment($quote->getPayment()));
67
+ $payment = $order->getPayment();
68
+ $payment_details = array(
69
+ 'cc_exp_month' => $payment->getDataUsingMethod('cc_exp_month'),
70
+ 'cc_exp_year' => $payment->getDataUsingMethod('cc_exp_year'),
71
+ 'cc_last4' => $payment->getDataUsingMethod('cc_last4'),
72
+ 'cc_owner' => $payment->getDataUsingMethod('cc_owner'),
73
+ 'cc_type' => $payment->getDataUsingMethod('cc_type')
74
+ );
75
+
76
+ foreach ($this->_orderData as $key => $value) {
77
+ $order->setData($key, $value);
78
+ }
79
+
80
+ foreach ($quote->getAllItems() as $item) {
81
+ $orderItem = $this->_convertor->itemToOrderItem($item);
82
+ if ($item->getParentItem()) {
83
+ $orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
84
+ }
85
+ $order->addItem($orderItem);
86
+ }
87
+
88
+ $order->setQuote($quote);
89
+
90
+ $transaction->addObject($order);
91
+ $transaction->addCommitCallback(array($order, 'place'));
92
+ $transaction->addCommitCallback(array($order, 'save'));
93
+
94
+ /**
95
+ * We can use configuration data for declare new order status
96
+ */
97
+ Mage::dispatchEvent('checkout_type_onepage_save_order', array('order'=>$order, 'quote'=>$quote));
98
+ Mage::dispatchEvent('sales_model_service_quote_submit_before', array('order'=>$order, 'quote'=>$quote));
99
+ try {
100
+ $transaction->save();
101
+ $this->_inactivateQuote();
102
+ Mage::dispatchEvent('sales_model_service_quote_submit_success', array('order'=>$order, 'quote'=>$quote));
103
+ $this->enforceCcPaymentData($order, $payment_details);
104
+ } catch (Exception $e) {
105
+
106
+ if (!Mage::getSingleton('customer/session')->isLoggedIn()) {
107
+ // reset customer ID's on exception, because customer not saved
108
+ $quote->getCustomer()->setId(null);
109
+ }
110
+
111
+ //reset order ID's on exception, because order not saved
112
+ $order->setId(null);
113
+ /** @var $item Mage_Sales_Model_Order_Item */
114
+ foreach ($order->getItemsCollection() as $item) {
115
+ $item->setOrderId(null);
116
+ $item->setItemId(null);
117
+ }
118
+
119
+ Mage::dispatchEvent('sales_model_service_quote_submit_failure', array('order'=>$order, 'quote'=>$quote));
120
+ throw $e;
121
+ }
122
+ Mage::dispatchEvent('sales_model_service_quote_submit_after', array('order'=>$order, 'quote'=>$quote));
123
+ $this->_order = $order;
124
+ return $order;
125
+ }
126
+
127
+ private function enforceCcPaymentData($order, $payment_details) {
128
+ $order_payment = $order->getPayment();
129
+ $order_payment->setCcExpMonth($payment_details['cc_exp_month']);
130
+ $order_payment->setCcExpYear($payment_details['cc_exp_year']);
131
+ $order_payment->setCcLast4($payment_details['cc_last4']);
132
+ $order_payment->setCcOwner($payment_details['cc_owner']);
133
+ $order_payment->setCcType($payment_details['cc_type']);
134
+ $order_payment->save();
135
+ }
136
+
137
+ }
app/code/community/Gemgento/Sales/etc/config.xml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Gemgento_Sales>
5
+ <version>0.0.1</version>
6
+ </Gemgento_Sales>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <sales>
11
+ <rewrite>
12
+ <service_quote>Gemgento_Sales_Model_Service_Quote</service_quote>
13
+ </rewrite>
14
+ </sales>
15
+ </models>
16
+ </global>
17
+ </config>
app/code/community/Gemgento/Tool/CreateCustomerAttribute.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once '../../../../Mage.php';
4
+
5
+ Mage::app();
6
+
7
+ $installer = new Mage_Customer_Model_Entity_Setup('core_setup');
8
+
9
+ $installer->startSetup();
10
+
11
+ // add gemgento_id to customers
12
+ $vCustomerEntityType = $installer->getEntityTypeId('customer');
13
+ $vCustAttributeSetId = $installer->getDefaultAttributeSetId($vCustomerEntityType);
14
+ $vCustAttributeGroupId = $installer->getDefaultAttributeGroupId($vCustomerEntityType, $vCustAttributeSetId);
15
+
16
+ $installer->addAttribute('customer', 'gemgento_id', array(
17
+ 'label' => 'Gemgento Id',
18
+ 'input' => 'text',
19
+ 'type' => 'int',
20
+ 'forms' => array('customer_account_edit', 'customer_account_create', 'adminhtml_customer', 'checkout_register'),
21
+ 'required' => 0,
22
+ 'user_defined' => 1,
23
+ ));
24
+
25
+ $installer->addAttributeToGroup($vCustomerEntityType, $vCustAttributeSetId, $vCustAttributeGroupId, 'gemgento_id', 0);
26
+
27
+ $oAttribute = Mage::getSingleton('eav/config')->getAttribute('customer', 'gemgento_id');
28
+ $oAttribute->setData('used_in_forms', array('customer_account_edit', 'customer_account_create', 'adminhtml_customer', 'checkout_register'));
29
+ $oAttribute->save();
30
+
31
+ // Add gemgento_id to products
32
+ $attrCode = 'gemgento_id';
33
+
34
+ $objCatalogEavSetup = Mage::getResourceModel('catalog/eav_mysql4_setup', 'core_setup');
35
+ $attrIdTest = $objCatalogEavSetup->getAttributeId(Mage_Catalog_Model_Product::ENTITY, $attrCode);
36
+
37
+ if ($attrIdTest === false) {
38
+ $objCatalogEavSetup->addAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode, array(
39
+ 'group' => 'General',
40
+ 'type' => Varien_Db_Ddl_Table::TYPE_INTEGER,
41
+ 'backend' => '',
42
+ 'frontend' => '',
43
+ 'label' => 'Gemgento Id',
44
+ 'note' => 'The product id in Gemgento',
45
+ 'input' => 'text',
46
+ 'class' => '',
47
+ 'source' => '',
48
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
49
+ 'visible' => true,
50
+ 'required' => false,
51
+ 'user_defined' => true,
52
+ 'default' => '0',
53
+ 'visible_on_front' => false,
54
+ 'unique' => false,
55
+ 'is_configurable' => false,
56
+ 'used_for_promo_rules' => false
57
+ ));
58
+ }
59
+
60
+ $installer->endSetup();
app/code/community/Gemgento/Tool/CreateProductAttribute.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once '../../../../Mage.php';
4
+
5
+ Mage::app();
6
+
7
+ $installer = new Mage_Customer_Model_Entity_Setup('core_setup');
8
+
9
+ $installer->startSetup();
10
+
11
+ // Add gemgento_id to products
12
+ $attrCode = 'gemgento_id';
13
+
14
+ $objCatalogEavSetup = Mage::getResourceModel('catalog/eav_mysql4_setup', 'core_setup');
15
+ $attrIdTest = $objCatalogEavSetup->getAttributeId(Mage_Catalog_Model_Product::ENTITY, $attrCode);
16
+
17
+ if ($attrIdTest === false) {
18
+ $objCatalogEavSetup->addAttribute(Mage_Catalog_Model_Product::ENTITY, $attrCode, array(
19
+ 'group' => 'General',
20
+ 'type' => Varien_Db_Ddl_Table::TYPE_INTEGER,
21
+ 'backend' => '',
22
+ 'frontend' => '',
23
+ 'label' => 'Gemgento Id',
24
+ 'note' => 'The product id in Gemgento',
25
+ 'input' => 'text',
26
+ 'class' => '',
27
+ 'source' => '',
28
+ 'global' => Mage_Catalog_Model_Resource_Eav_Attribute::SCOPE_GLOBAL,
29
+ 'visible' => true,
30
+ 'required' => false,
31
+ 'user_defined' => true,
32
+ 'default' => '0',
33
+ 'visible_on_front' => false,
34
+ 'unique' => false,
35
+ 'is_configurable' => false,
36
+ 'used_for_promo_rules' => false
37
+ ));
38
+ }
39
+
40
+ $installer->endSetup();
app/etc/modules/Gemgento.xml ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <modules>
3
+ <Gemgento_ProductSearch>
4
+ <active>true</active>
5
+ <codePool>community</codePool>
6
+ </Gemgento_ProductSearch>
7
+
8
+ <Gemgento_Catalog>
9
+ <active>true</active>
10
+ <codePool>community</codePool>
11
+ <depends>
12
+ <Mage_Catalog/>
13
+ </depends>
14
+ </Gemgento_Catalog>
15
+
16
+ <Gemgento_Customer>
17
+ <active>true</active>
18
+ <codePool>community</codePool>
19
+ <depends>
20
+ <Mage_Customer/>
21
+ </depends>
22
+ </Gemgento_Customer>
23
+
24
+ <Gemgento_Paygate>
25
+ <active>true</active>
26
+ <codePool>community</codePool>
27
+ <depends>
28
+ <Mage_Paygate/>
29
+ </depends>
30
+ </Gemgento_Paygate>
31
+
32
+ <Gemgento_Sales>
33
+ <active>true</active>
34
+ <codePool>community</codePool>
35
+ <depends>
36
+ <Mage_Sales/>
37
+ </depends>
38
+ </Gemgento_Sales>
39
+
40
+ <Gemgento_Payment>
41
+ <active>true</active>
42
+ <codePool>community</codePool>
43
+ <depends>
44
+ <Mage_Payment/>
45
+ </depends>
46
+ </Gemgento_Payment>
47
+
48
+ <Gemgento_Checkout>
49
+ <active>true</active>
50
+ <codePool>community</codePool>
51
+ <depends>
52
+ <Mage_Checkout/>
53
+ </depends>
54
+ </Gemgento_Checkout>
55
+
56
+ <Gemgento_Push>
57
+ <active>true</active>
58
+ <codePool>community</codePool>
59
+ </Gemgento_Push>
60
+
61
+ <Bubble_Api>
62
+ <active>true</active>
63
+ <codePool>community</codePool>
64
+ </Bubble_Api>
65
+
66
+ <Gemgento_Order>
67
+ <active>true</active>
68
+ <codePool>community</codePool>
69
+ </Gemgento_Order>
70
+ </modules>
71
+ </config>
package.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Gemgento_Rails_Connect</name>
4
+ <version>0.0.1</version>
5
+ <stability>stable</stability>
6
+ <license>http://www.binpress.com/license/view/l/ffbc66b48e5106eab8c9fa340677a4c2</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Gemgento is Magento with a Ruby on Rails front end.</summary>
10
+ <description>This extension pushes data from Magento to your gemgento Rails application. You will need a gemgento license to use this extension. After you have followed the installation instructions for gemgento, download this extension and install it in your Magento store. &#xD;
11
+ &#xD;
12
+ In addition to Rails front end, Gemgento provides a rich set of ruby-based functionality to interact with your Magento store including drag and drop merchandising, sales reports, and product imports. For more information visit us at http://www.gemgento.com and read our guides at http://www.gemgento.com/guides.</description>
13
+ <notes>Initial release</notes>
14
+ <authors><author><name>gemgento</name><user>gemgento</user><email>support@gemgento.com</email></author></authors>
15
+ <date>2014-07-07</date>
16
+ <time>13:34:53</time>
17
+ <contents><target name="magecommunity"><dir name="Gemgento"><dir name="Catalog"><dir name="Model"><dir name="Category"><dir name="Api"><file name="V2.php" hash="353c898891f0e28afa375a1637106c06"/></dir><file name="Api.php" hash="cf5fbcccd2b69174d9c17e2e4274b6a5"/></dir><dir name="Product"><file name="Action.php" hash="0e3321a2428e42495e0d44dfefc3cfc1"/></dir></dir><dir name="etc"><file name="api.xml" hash="b2d39038823ffb8382bf3f8d5d67353c"/><file name="config.xml" hash="cf8b42ed1eaa8de92286c0616eb26c91"/><file name="wsdl.xml" hash="1dcbba392ddb6dbd5d9dcbb3307a8901"/><file name="wsi.xml" hash="ab4a90805fb56d6a5f9443e4ad7418d7"/></dir></dir><dir name="Checkout"><dir name="Model"><dir name="Api"><dir name="Resource"><file name="Customer.php" hash="724fde2e2efe008b00eb165cc9fb9f66"/></dir></dir><dir name="Cart"><dir name="Api"><file name="V2.php" hash="3c1436c0a22e0349d0348756e06e8ea0"/></dir><file name="Api.php" hash="97a3f82f431ca7a5ffd927ca6d670d97"/><dir name="Payment"><dir name="Api"><file name="V2.php" hash="43a72af5dda683071cf06d6cfa46ea64"/></dir><file name="Api.php" hash="9c209c4a4b99790865523cf166ea14af"/></dir></dir></dir><dir name="etc"><file name="api.xml" hash="0237a258bb99e76c2a9653729f50b942"/><file name="config.xml" hash="a9a2b52e08b8a61b3159d552ecb5764e"/><file name="wsdl.xml" hash="150cf5ae365cbfafc31fd1bc0cf18b3f"/><file name="wsi.xml" hash="696f8d6a71f8eb9dee964dd824a4d640"/></dir></dir><dir name="Customer"><dir name="Model"><dir name="Customer"><dir name="Api"><file name="V2.php" hash="c22f358834deca98fe8b44c1aa45275e"/></dir><file name="Api.php" hash="e623952cbe0e37dad4b708b65a2b9c92"/></dir></dir><dir name="etc"><file name="config.xml" hash="a82e4983211056b56b92a9c88a42c195"/></dir></dir><dir name="Order"><dir name="Model"><dir name="Resource"><file name="Setup.php" hash="a2f80e759ecec9c8e7615a90c269b06e"/></dir></dir><dir name="etc"><file name="config.xml" hash="7b9b42dbae10e38d32ad9bb8e3088fdf"/></dir><dir name="sql"><dir name="gemgento_order_setup"><file name="install-0.0.1.php" hash="bc97a162fde879929e8c58121fa63e19"/></dir></dir></dir><dir name="ProductSearch"><dir name="Helper"><file name="Data.php" hash="dd8bdf6445813c422137830b162594b4"/></dir><dir name="Model"><dir name="Api"><file name="V2.php" hash="033c4d750abf8a420695d8270b7057a1"/></dir><file name="Api.php" hash="0ce4343cfac92fe8248c0dc06674f41e"/></dir><dir name="etc"><file name="api.xml" hash="50ddbcb4a6dddc0d67c86106d02a23bd"/><file name="config.xml" hash="883bd59fc44a13a92f7b04755f35cf86"/><file name="wsdl.xml" hash="ddaf8a4cfb77ff50b51c65e46b55965d"/><file name="wsi.xml" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir></dir><dir name="Push"><dir name="Model"><file name="Observer.php" hash="bed5ef9b819fd03d7303378c5644deba"/></dir><dir name="etc"><file name="adminhtml.xml" hash="928ee746bd9cc9fa5330b003ca77edc5"/><file name="config.xml" hash="7d7261e5c331a514847338254c665c93"/><file name="system.xml" hash="3a87dc6a20d170d9966489d47ea0df20"/></dir></dir><dir name="Sales"><dir name="Model"><dir name="Service"><file name="Quote.php" hash="05e706d1118a5e4d582caf4b6dae7f68"/></dir></dir><dir name="etc"><file name="config.xml" hash="8d31cb7fa92fe2e1630506b779a1f1ff"/></dir></dir><dir name="Tool"><file name="CreateCustomerAttribute.php" hash="67cb55c085ae2727c40b15078513057a"/><file name="CreateProductAttribute.php" hash="bebf5a953d352ccf0357958ec16675e8"/></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Gemgento.xml" hash="7db84befffca4a79bb723d62636e205b"/></dir></target></contents>
18
+ <compatible/>
19
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><package><name>Mage_Core_Modules</name><channel>community</channel><min>1.6.0</min><max>1.9.0.1</max></package></required></dependencies>
20
+ </package>