Atosho - Version 1.0.0

Version Notes

First public version of the Atosho product and order integration extension.

Download this release

Release Info

Developer Atosho
Extension Atosho
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

app/code/community/Atosho/AtoshoPayment/Model/AtoshoPayment.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Our test CC module adapter
5
+ */
6
+ class Atosho_AtoshoPayment_Model_AtoshoPayment extends Mage_Payment_Model_Method_Abstract {
7
+ /**
8
+ * unique internal payment method identifier
9
+ *
10
+ * @var string [a-z0-9_]
11
+ */
12
+ protected $_code = 'atoshopayment';
13
+
14
+ /**
15
+ * Here are examples of flags that will determine functionality availability
16
+ * of this module to be used by frontend and backend.
17
+ *
18
+ * @see all flags and their defaults in Mage_Payment_Model_Method_Abstract
19
+ *
20
+ * It is possible to have a custom dynamic logic by overloading
21
+ * public function can* for each flag respectively
22
+ */
23
+ protected $_canAuthorize = true; //
24
+ protected $_canCancelInvoice = false;
25
+ protected $_canCapture = false;
26
+ protected $_canCapturePartial = false;
27
+ protected $_canCreateBillingAgreement = false;
28
+ protected $_canFetchTransactionInfo = false;
29
+ protected $_canManageRecurringProfiles = false;
30
+ protected $_canOrder = false; //
31
+ protected $_canRefund = false;
32
+ protected $_canRefundInvoicePartial = false;
33
+ protected $_canReviewPayment = false;
34
+ // This setting prevents the payment method from being displayed on the front-end.
35
+ protected $_canUseCheckout = false;
36
+ protected $_canUseForMultishipping = false;
37
+ protected $_canUseInternal = true; //
38
+ protected $_canVoid = false;
39
+ protected $_isGateway = false;
40
+ protected $_isInitializeNeeded = false;
41
+
42
+ /**
43
+ * Check whether payment method can be used
44
+ * @param Mage_Sales_Model_Quote
45
+ * @return bool
46
+ */
47
+ public function isAvailable($quote = null) {
48
+ return true;
49
+ }
50
+
51
+ }
52
+ ?>
app/code/community/Atosho/AtoshoPayment/etc/config.xml ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Atosho_AtoshoPayment>
5
+ <version>1.0.0</version>
6
+ </Atosho_AtoshoPayment>
7
+ </modules>
8
+ <global>
9
+ <blocks>
10
+ <atoshopayment>
11
+ <class>Atosho_AtoshoPayment_Block</class>
12
+ </atoshopayment>
13
+ </blocks>
14
+ <models>
15
+ <atoshopayment>
16
+ <class>Atosho_AtoshoPayment_Model</class>
17
+ </atoshopayment>
18
+ </models>
19
+ <resources>
20
+ <atoshopayment_setup>
21
+ <setup>
22
+ <module>Atosho_AtoshoPayment</module>
23
+ </setup>
24
+ <connection>
25
+ <use>core_setup</use>
26
+ </connection>
27
+ </atoshopayment_setup>
28
+ <atoshopayment_write>
29
+ <connection>
30
+ <use>core_write</use>
31
+ </connection>
32
+ </atoshopayment_write>
33
+ <atoshopayment_read>
34
+ <connection>
35
+ <use>core_read</use>
36
+ </connection>
37
+ </atoshopayment_read>
38
+ </resources>
39
+ </global>
40
+ <default>
41
+ <payment>
42
+ <atoshopayment>
43
+ <active>1</active>
44
+ <model>atoshopayment/atoshoPayment</model>
45
+ <order_status>pending</order_status>
46
+ <title>Atosho</title>
47
+ <payment_action>authorize</payment_action>
48
+ <allowspecific>0</allowspecific>
49
+ </atoshopayment>
50
+ </payment>
51
+ </default>
52
+ </config>
app/code/community/Atosho/AtoshoPayment/etc/system.xml ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <payment>
5
+ <groups>
6
+ <atoshopayment translate="label" module="payment">
7
+ <label>Atosho</label>
8
+ <sort_order>670</sort_order>
9
+ <show_in_default>1</show_in_default>
10
+ <show_in_website>1</show_in_website>
11
+ <show_in_store>1</show_in_store>
12
+ <fields>
13
+ <active translate="label">
14
+ <label>Enabled</label>
15
+ <frontend_type>select</frontend_type>
16
+ <source_model>adminhtml/system_config_source_yesno</source_model>
17
+ <sort_order>0</sort_order>
18
+ <show_in_default>1</show_in_default>
19
+ <show_in_website>1</show_in_website>
20
+ <show_in_store>1</show_in_store>
21
+ </active>
22
+ <title translate="label">
23
+ <label>Title</label>
24
+ <frontend_type>text</frontend_type>
25
+ <sort_order>1</sort_order>
26
+ <show_in_default>1</show_in_default>
27
+ <show_in_website>1</show_in_website>
28
+ <show_in_store>1</show_in_store>
29
+ </title>
30
+ <order_status translate="label">
31
+ <label>New order status</label>
32
+ <frontend_type>select</frontend_type>
33
+ <source_model>adminhtml/system_config_source_order_status_new</source_model>
34
+ <sort_order>2</sort_order>
35
+ <show_in_default>1</show_in_default>
36
+ <show_in_website>1</show_in_website>
37
+ <show_in_store>1</show_in_store>
38
+ </order_status>
39
+ </fields>
40
+ </atoshopayment>
41
+ </groups>
42
+ </payment>
43
+ </sections>
44
+ </config>
app/code/community/Atosho/Integration/controllers/FeedController.php ADDED
@@ -0,0 +1,764 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Atosho_Integration_FeedController extends Mage_Core_Controller_Front_Action {
3
+ public function errorHandler($errno, $errstr, $errfile, $errline) {
4
+ $params = Mage::app()->getRequest()->getParams();
5
+ if ($errno & E_ERROR || isset($params['debug'])) {
6
+ echo $errno.PHP_EOL.$errstr.PHP_EOL.$errfile.' ('.$errline.')'.PHP_EOL;
7
+ if ($errno == E_ERROR) {
8
+ exit(1);
9
+ }
10
+ }
11
+ }
12
+
13
+ public function versionAction() {
14
+ set_error_handler(array($this, 'errorHandler'));
15
+
16
+ $writer = new XMLWriter();
17
+ $writer->openURI('php://output');
18
+ $writer->startDocument('1.0', 'UTF-8');
19
+ $writer->setIndent(true);
20
+ $writer->setIndentString("\t");
21
+ $writer->startElement('version');
22
+ $writer->writeElement('php', phpversion());
23
+ $writer->writeElement('magento', Mage::getVersion());
24
+ $writer->writeElement('module', Mage::getConfig()->cleanCache()->getModuleConfig('Atosho_Integration')->version);
25
+ $writer->endElement();
26
+ $writer->endDocument();
27
+ $writer->flush();
28
+ }
29
+
30
+
31
+ public function infoAction() {
32
+ set_error_handler(array($this, 'errorHandler'));
33
+
34
+ $params = Mage::app()->getRequest()->getParams();
35
+
36
+ $product = Mage::getModel('catalog/product');
37
+
38
+ $productCollection = $product->getCollection()
39
+ ->addAttributeToFilter('status', true)
40
+ ->addAttributeToFilter('type_id', array('configurable', 'simple'));
41
+
42
+ if (isset($params['store'])) {
43
+ $productCollection->addStoreFilter($params['store']);
44
+ }
45
+ $info['products'] = $productCollection->count();
46
+
47
+ $configurableCollection = $product->getCollection()
48
+ ->addAttributeToFilter('type_id', 'configurable')
49
+ ->addAttributeToFilter('status', true);
50
+ if (isset($params['store'])) {
51
+ $configurableCollection->addStoreFilter($params['store']);
52
+ }
53
+ if (isset($params['full'])) {
54
+ $configurableIds = $configurableCollection->getAllIds();
55
+ }
56
+ $info['configurable'] = $configurableCollection->count();
57
+
58
+ $simpleCollection = $product->getCollection()
59
+ ->addAttributeToFilter('type_id', 'simple')
60
+ ->addAttributeToFilter('status', true);
61
+ if (isset($params['store'])) {
62
+ $simpleCollection->addStoreFilter($params['store']);
63
+ }
64
+
65
+ if (isset($params['full'])) {
66
+ $info['variant'] = 0;
67
+ $info['simple'] = 0;
68
+ $simpleIds = $simpleCollection->getAllIds();
69
+ $parentResource = Mage::getResourceSingleton('catalog/product_type_configurable');
70
+ foreach ($simpleIds as $id) {
71
+ $parentIds = $parentResource->getParentIdsByChild($id);
72
+ if (count($parentIds) == 0) {
73
+ ++$info['simple'];
74
+ }
75
+ foreach ($parentIds as $parentId) {
76
+ if (in_array($parentId, $configurableIds)) {
77
+ ++$info['variant'];
78
+ break;
79
+ }
80
+ }
81
+ }
82
+ $info['products'] = $info['configurable'] + $info['simple'];
83
+ }
84
+ else {
85
+ $info['simple'] = $simpleCollection->count();
86
+ }
87
+ $writer = new XMLWriter();
88
+ $writer->openURI('php://output');
89
+ $writer->startDocument('1.0', 'UTF-8');
90
+ $writer->setIndent(true);
91
+ $writer->setIndentString("\t");
92
+ $writer->startElement('info');
93
+ foreach ($info as $name => $value) {
94
+ $writer->writeElement($name, $value);
95
+ }
96
+ $writer->endElement();
97
+ $writer->endDocument();
98
+ $writer->flush();
99
+ }
100
+
101
+
102
+ public function storesAction() {
103
+ set_error_handler(array($this, 'errorHandler'));
104
+
105
+ $product = Mage::getModel('catalog/product');
106
+
107
+ $structure = array();
108
+ $websites = Mage::getModel('core/website')->getCollection();
109
+ foreach ($websites as $website) {
110
+ $websiteData = $website->getData();
111
+ $websiteData['basecurrency'] = $website->getBaseCurrencyCode();
112
+ $websiteData['products'] = $product->getCollection()->addWebsiteFilter($website->getId())->count();
113
+ $websiteData['active_products'] = $product->getCollection()->addWebsiteFilter($website->getId())->addAttributeToFilter('status', 1)->count();
114
+ $structure[$website->getId()] = $websiteData;
115
+ $groups = $website->getGroups();
116
+ foreach ($groups as $group) {
117
+ $structure[$website->getId()]['groups'][$group->getId()] = $group->getData();
118
+ $stores = $group->getStores();
119
+ foreach ($stores as $store) {
120
+ $storeData = $store->getData();
121
+ $storeData['baseurl'] = $store->getBaseUrl();
122
+ $structure[$website->getId()]['groups'][$group->getId()]['stores'][$store->getId()] = $storeData;
123
+ }
124
+ }
125
+ }
126
+ print_r($structure);
127
+ }
128
+
129
+
130
+ public function attributesetsAction() {
131
+ set_error_handler(array($this, 'errorHandler'));
132
+
133
+ $attributeSetCollection = Mage::getResourceModel('eav/entity_attribute_set_collection')
134
+ ->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
135
+ ->load();
136
+
137
+ foreach ($attributeSetCollection as $attributeSet) {
138
+ //print_r($attributes);
139
+ echo '<h3>'.$attributeSet->attribute_set_name.'</h3>';
140
+ foreach ($attributeSet->getData() as $key => $value) {
141
+ echo $key.': '.var_export($value, true).'<br/>';
142
+ }
143
+ $attributes = Mage::getModel('catalog/product_attribute_api')->items($attributeSet->getId());
144
+ echo '<ul>';
145
+ foreach ($attributes as $attribute) {
146
+ echo '<li>'.$attribute['code'].'</li>';
147
+ }
148
+ echo '</ul>';
149
+ }
150
+ }
151
+
152
+
153
+ public function attributesAction() {
154
+ set_error_handler(array($this, 'errorHandler'));
155
+
156
+ $params = Mage::app()->getRequest()->getParams();
157
+
158
+ $attributeCollection = Mage::getResourceModel('eav/entity_attribute_collection');
159
+ if (isset($params['user'])) $attributeCollection->addFieldToFilter('is_user_defined', 1);
160
+ if (isset($params['system'])) $attributeCollection->addFieldToFilter('is_user_defined', 0);
161
+ $attributeCollection
162
+ ->setEntityTypeFilter(Mage::getModel('catalog/product')->getResource()->getTypeId())
163
+ ->addSetInfo()
164
+ ->getData();
165
+
166
+ foreach ($attributeCollection as $attribute) {
167
+ echo '<h2>'.$attribute->attribute_code.'</h2>';
168
+ $attribute->getStoreLabels();
169
+ foreach ($attribute->getData() as $key => $value) {
170
+ echo $key.': '.var_export($value, true).'<br/>';
171
+ }
172
+ }
173
+ }
174
+
175
+
176
+ public function attributevaluesAction() {
177
+ set_error_handler(array($this, 'errorHandler'));
178
+
179
+ $params = Mage::app()->getRequest()->getParams();
180
+ if (!isset($params['store'])) {
181
+ $params['store'] = Mage::app()->getDefaultStoreView()->getId();
182
+ }
183
+ Mage::app()->setCurrentStore($params['store']);
184
+
185
+ $product = Mage::getModel('catalog/product');
186
+ $productResource = $product->getResource();
187
+
188
+ $attributeCollection = Mage::getResourceModel('eav/entity_attribute_collection');
189
+ if (isset($params['user'])) $attributeCollection->addFieldToFilter('is_user_defined', 1);
190
+ if (isset($params['system'])) $attributeCollection->addFieldToFilter('is_user_defined', 0);
191
+ $attributeCollection
192
+ ->addFieldToFilter('attribute_code', array('neq' => 'cost'))
193
+ ->setEntityTypeFilter($productResource->getTypeId())
194
+ ->addSetInfo()
195
+ ->getData();
196
+
197
+ $this->userAttributes = array();
198
+ foreach ($attributeCollection as $attribute) {
199
+ if (in_array($attribute['frontend_input'], array('select', 'multiselect'))) {
200
+ echo '<h2>'.$attribute['attribute_code'].'</h2>';
201
+ $attribute = $attribute->setEntity($productResource);
202
+ $options = $attribute->getSource()->getAllOptions(false);
203
+ foreach ($options as $option) {
204
+ if (isset($option['value'])) echo '('.$option['value'].') ';
205
+ echo $option['label'].'<br/>';
206
+ }
207
+ }
208
+ }
209
+ }
210
+
211
+
212
+ public function cleancacheAction() {
213
+ echo (int)Mage::app()->getCache()->clean();
214
+ }
215
+
216
+
217
+ public function categoriesAction() {
218
+ set_error_handler(array($this, 'errorHandler'));
219
+
220
+ $params = Mage::app()->getRequest()->getParams();
221
+ if (!isset($params['store'])) {
222
+ $params['store'] = null;
223
+ }
224
+ $cat = Mage::getModel('catalog/category_api');
225
+ $categories = $cat->tree(null, $params['store']);
226
+
227
+ function categoriesRecursive($categories, $writer) {
228
+ foreach ($categories as $category) {
229
+ $writer->startElement('category');
230
+ $writer->writeElement('id', $category['category_id']);
231
+ $writer->writeElement('name', $category['name']);
232
+ if (isset($category['children']) && !empty($category['children'])) {
233
+ $writer->startElement('children');
234
+ categoriesRecursive($category['children'], $writer);
235
+ $writer->endElement();
236
+ }
237
+ $writer->endElement();
238
+ }
239
+ }
240
+
241
+ $writer = new XMLWriter();
242
+ $writer->openURI('php://output');
243
+ $writer->startDocument('1.0', 'UTF-8');
244
+ $writer->setIndent(true);
245
+ $writer->setIndentString("\t");
246
+
247
+ $writer->startElement('categories');
248
+
249
+ categoriesRecursive(array($categories), $writer);
250
+
251
+ $writer->endElement();
252
+ $writer->endDocument();
253
+ $writer->flush();
254
+ }
255
+
256
+
257
+ public function productlistAction() {
258
+ set_error_handler(array($this, 'errorHandler'));
259
+
260
+ $params = Mage::app()->getRequest()->getParams();
261
+ if (!isset($params['store'])) {
262
+ $params['store'] = Mage::app()->getDefaultStoreView()->getId();
263
+ }
264
+ Mage::app()->setCurrentStore($params['store']);
265
+
266
+ $this->generateProductList();
267
+
268
+ $writer = new XMLWriter();
269
+ $writer->openURI('php://output');
270
+ $writer->startDocument('1.0', 'UTF-8');
271
+ $writer->setIndent(true);
272
+ $writer->setIndentString("\t");
273
+
274
+ $writer->startElement('productlist');
275
+ foreach ($this->skus as $id => $product) {
276
+ if (!isset($params['activeonly']) || $product['status'] == 1) {
277
+ $writer->startElement('product');
278
+ $writer->writeAttribute('id', $id);
279
+ $writer->writeAttribute('sku', $product['sku']);
280
+ $writer->writeAttribute('type', $product['type']);
281
+ $writer->writeAttribute('status', (int) ($product['status'] == 1) );
282
+ $writer->endElement();
283
+ }
284
+ }
285
+ $writer->endElement();
286
+
287
+ $writer->endDocument();
288
+ $writer->flush();
289
+ }
290
+
291
+
292
+ public function productAction() {
293
+ set_error_handler(array($this, 'errorHandler'));
294
+
295
+ $this->errors = array();
296
+
297
+ $this->prepare();
298
+ $this->generateProductList();
299
+
300
+ $product = Mage::getModel('catalog/product');
301
+
302
+ $params = Mage::app()->getRequest()->getParams();
303
+ if (isset($params['id'])) {
304
+ $p = $this->loadProduct($product, $params['id']);
305
+ } elseif (isset($params['sku'])) {
306
+ $id = $product->getIdBySku($params['sku']);
307
+ $p = $this->loadProduct($product, $id);
308
+ }
309
+
310
+ if (!isset($p)) {
311
+ echo 'Product does not exist.';
312
+ return;
313
+ }
314
+
315
+ // XML
316
+ $writer = new XMLWriter();
317
+ $writer->openURI('php://output');
318
+ $writer->startDocument('1.0', 'UTF-8');
319
+ $writer->setIndent(true);
320
+ $writer->setIndentString("\t");
321
+ if (count($this->errors) > 0) {
322
+ $writer->writeComment(print_r($this->errors, true));
323
+ }
324
+ $this->writeProduct($writer, $p);
325
+ $writer->endDocument();
326
+ $writer->flush();
327
+ }
328
+
329
+
330
+ public function productsAction() {
331
+ set_error_handler(array($this, 'errorHandler'));
332
+
333
+ $this->errors = array();
334
+
335
+ $params = Mage::app()->getRequest()->getParams();
336
+
337
+ $this->prepare();
338
+ $this->generateProductList();
339
+
340
+ if (isset($params['ids'])) {
341
+ $productIds = explode(',', $params['ids']);
342
+ }
343
+ elseif (isset($params['skus'])) {
344
+ foreach ($params['skus'] as $sku) {
345
+ foreach ($this->skus as $id => $product) {
346
+ if ($sku == $product['sku']) {
347
+ $productIds[] = $id;
348
+ continue 2;
349
+ }
350
+ }
351
+ echo 'Product SKU "'.$sku.'" could not be found.';
352
+ exit;
353
+ }
354
+ }
355
+ else {
356
+ $productIds = array_keys($this->skus);
357
+ }
358
+
359
+ $product = Mage::getModel('catalog/product');
360
+ $products = array();
361
+
362
+ // Process each product
363
+ foreach ($productIds as $id) {
364
+ // if (isset($params['activeonly']) && $params['activeonly'] && $productInfo['status'] != 1) {
365
+ // continue;
366
+ // }
367
+ $p = $this->loadProduct($product, $id);
368
+ if ($p == null) {
369
+ echo 'Product ID '.$id.' does not exist.';
370
+ return;
371
+ }
372
+
373
+ $products[$product->getId()] = $p;
374
+ //echo memory_get_usage(false).PHP_EOL;
375
+ }
376
+
377
+ // XML
378
+ $writer = new XMLWriter();
379
+ $writer->openURI('php://output');
380
+ $writer->startDocument('1.0', 'UTF-8');
381
+ $writer->setIndent(true);
382
+ $writer->setIndentString("\t");
383
+
384
+ $writer->writeComment('Peak: '.memory_get_peak_usage());
385
+
386
+ if (count($this->errors) > 0) {
387
+ $writer->writeComment(print_r($this->errors, true));
388
+ }
389
+
390
+ $writer->startElement('products');
391
+
392
+ foreach ($products as $p) {
393
+ $this->writeProduct($writer, $p);
394
+ }
395
+
396
+ $writer->endElement();
397
+ $writer->endDocument();
398
+ $writer->flush();
399
+ //print_r($products);
400
+ }
401
+
402
+
403
+ protected function generateProductList() {
404
+ $params = Mage::app()->getRequest()->getParams();
405
+
406
+ // Get all IDs and matching SKUs
407
+ $this->skus = array();
408
+ $productCollection = Mage::getModel('catalog/product')->getCollection()
409
+ ->addAttributeToFilter('type_id', array('in' => array('simple', 'configurable')))
410
+ ->addAttributeToSelect('sku')
411
+ ->addAttributeToSelect('status');
412
+ if (isset($params['store'])) $productCollection->addStoreFilter($params['store']);
413
+ if (isset($params['attributeset'])) $productCollection->addAttributeToFilter('attribute_set_id', $params['attributeset']);
414
+ if (isset($params['category'])) {
415
+ $category = Mage::getModel('catalog/category')->load($params['category']);
416
+ $productCollection->addCategoryFilter($category);
417
+ }
418
+ foreach ($productCollection as $product) {
419
+ $this->skus[$product->getId()] = array(
420
+ 'sku' => $product->getData('sku'),
421
+ 'status' => $product->getData('status'),
422
+ 'type' => $product->getData('type_id'),
423
+ );
424
+ }
425
+ $productCollection->clear();
426
+ }
427
+
428
+
429
+ protected function prepare() {
430
+ $params = Mage::app()->getRequest()->getParams();
431
+
432
+ if (!isset($params['store'])) {
433
+ $defaultStoreId = Mage::app()->getDefaultStoreView()->getId();
434
+ Mage::app()->setCurrentStore($defaultStoreId);
435
+ $params['store'] = $defaultStoreId;
436
+ } else {
437
+ Mage::app()->setCurrentStore($params['store']);
438
+ }
439
+
440
+ $taxHelper = Mage::helper('tax');
441
+ $this->isvatincluded = (int)$taxHelper->priceIncludesTax();
442
+ $this->currency = Mage::app()->getStore()->getCurrentCurrencyCode();
443
+
444
+ $this->mediaUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA);
445
+ $this->parentResource = Mage::getResourceSingleton('catalog/product_type_configurable');
446
+
447
+ // Get attributes
448
+ $product = Mage::getModel('catalog/product');
449
+ $productResource = $product->getResource();
450
+
451
+ $attributeCollection = Mage::getResourceModel('eav/entity_attribute_collection');
452
+ $attributeCollection
453
+ ->addFieldToFilter('is_user_defined', 1)
454
+ ->addFieldToFilter('attribute_code', array('neq' => 'cost'))
455
+ ->setEntityTypeFilter($productResource->getTypeId())
456
+ ->addSetInfo()
457
+ ->getData();
458
+
459
+ $this->userAttributes = array();
460
+ foreach ($attributeCollection as $attribute) {
461
+ $a = array(
462
+ 'attribute_code' => $attribute['attribute_code'],
463
+ 'backend_type' => $attribute['backend_type'],
464
+ 'frontend_input' => $attribute['frontend_input'],
465
+ );
466
+
467
+ if ($attribute['is_global'] && $attribute['is_configurable'] && $attribute['frontend_input'] == 'select') {
468
+ // TODO: Get labels for the right store
469
+ $a['variant'] = true;
470
+ } else {
471
+ // TODO: check that it's "visible" in any way
472
+ $a['variant'] = false;
473
+ }
474
+ if (in_array($attribute['frontend_input'], array('select', 'multiselect'))) {
475
+ $attribute = $attribute->setEntity($productResource);
476
+ if (isset($params['store'])) $attribute->setStoreId($params['store']);
477
+ $options = $attribute->getSource()->getAllOptions(false);
478
+ foreach ($options as $option) {
479
+ $a['options'][$option['value']] = $option['label'];
480
+ }
481
+ }
482
+ $this->userAttributes[$attribute['attribute_code']] = $a;
483
+ }
484
+ $attributeCollection->clear();
485
+ }
486
+
487
+
488
+ protected function loadProduct(&$product, $id) {
489
+ $params = Mage::app()->getRequest()->getParams();
490
+
491
+ $product->reset();
492
+
493
+ if (isset($params['store'])) $product->setStoreId($params['store']);
494
+
495
+ $product->load($id);
496
+
497
+ // For debug purposes
498
+ if (isset($params['debug'])) {
499
+ var_dump($product);
500
+ exit; // in case code after here should fail and we get nothing
501
+ }
502
+ if (!$product->getId()) {
503
+ return null;
504
+ }
505
+ $p = array();
506
+
507
+ $p['active'] = (int)($product->getData('status')==1);
508
+ $sku = $product->getData('sku');
509
+ $p['sku'] = $sku;
510
+
511
+ if (strlen($sku) == 0) {
512
+ return null;
513
+ }
514
+
515
+ // Detect product type
516
+ if ($product->getData('type_id') == 'configurable') {
517
+ $p['type'] = 'master';
518
+ }
519
+ elseif ($product->getData('type_id') == 'simple') {
520
+ $parentIds = $this->parentResource->getParentIdsByChild($product->getId());
521
+ if (count($parentIds) == 0) {
522
+ $p['type'] = 'simple';
523
+ }
524
+ elseif (count($parentIds) > 0) {
525
+ $p['type'] = 'variant';
526
+
527
+ // If multiple parents, sort array to pick the first one
528
+ if (count($parentIds) > 1) {
529
+ sort($parentIds);
530
+ $error = 'Product '.$product->getId().' has multiple parents: '.implode(', ', $parentIds);
531
+ $this->errors[] = $error;
532
+ }
533
+ $parentId = reset($parentIds);
534
+ if (isset($this->skus[$parentId])) {
535
+ // Disable child product if parent is disabled
536
+ if ($this->skus[$parentId]['status'] != 1) {
537
+ //$this->errors[] = 'Product '.$product->getId().' ('.$sku.') has been disabled because its parent ('.$this->skus[$parentId]['sku'].') is disabled.';
538
+ $p['active'] = 0;
539
+ // if (isset($params['activeonly']) && $params['activeonly']) {
540
+ // continue;
541
+ // }
542
+ }
543
+ $p['parentsku'] = $this->skus[$parentId]['sku'];
544
+ } else {
545
+ $this->errors[] = 'Product '.$product->getId().' has a bad parent id ('.$parentId.')';
546
+ }
547
+ }
548
+ }
549
+
550
+ $p['title'] = $product->getData('name');
551
+ $p['description'] = $product->getData('description');
552
+
553
+ $p['weight'] = $product->getData('weight');
554
+
555
+ $finalPrice = $product->getFinalPrice();
556
+ $price = $product->getPrice();
557
+ if ($finalPrice == $price) {
558
+ $p['price'] = $price;
559
+ } else {
560
+ $p['originalprice'] = $price;
561
+ $p['price'] = $finalPrice;
562
+ }
563
+
564
+ $p['isvatincluded'] = $this->isvatincluded;
565
+ $p['currency'] = $this->currency;
566
+
567
+ // Stock
568
+ $stockItem = $product->getStockItem();
569
+ $quantity = (int)$stockItem->getQty();
570
+ $isInStock = $stockItem->getIsInStock();
571
+ // If not in stock, ignore stock quantity
572
+ // TODO: check isSalable
573
+ $p['quantity'] = $quantity * $isInStock;
574
+ $p['enablestocklimitation'] = $stockItem->getManageStock();
575
+
576
+ // Images
577
+ $images = array();
578
+ if (!in_array($product->getImage(), array('no_selection', ''))) {
579
+ $images[$product->getImage()] = $this->mediaUrl.'catalog/product'.$product->getImage();
580
+ }
581
+ foreach ($product->getMediaGalleryImages() as $image) {
582
+ if (!$image['disabled']) {
583
+ $images[$image['file']] = $this->mediaUrl.'catalog/product'.$image['file'];
584
+ }
585
+ }
586
+
587
+ if ($p['type'] == 'variant') {
588
+ $parentImages = array();
589
+ $p['reusefrommaster'] = true;
590
+ $parentProduct = Mage::getModel('catalog/product');
591
+ $parentProduct->load($parentId);
592
+ $parentImages[$parentProduct->getImage()] = $this->mediaUrl.'catalog/product'.$parentProduct->getImage();
593
+ foreach ($parentProduct->getMediaGalleryImages() as $image) {
594
+ if (!$image['disabled']) {
595
+ $parentImages[$image['file']] = $this->mediaUrl.'catalog/product'.$image['file'];
596
+ }
597
+ }
598
+
599
+ foreach ($images as $file => $url) {
600
+ if (!isset($parentImages[$file])) {
601
+ $p['images'][$file] = $url;
602
+ }
603
+ }
604
+ $parentProduct->reset();
605
+ }
606
+ else {
607
+ $p['images'] = $images;
608
+ }
609
+
610
+ // Attributes
611
+ if (strlen($product->getData('short_description')) > 0) {
612
+ $p['attributes']['short_description'] = $product->getData('short_description');
613
+ }
614
+ foreach ($this->userAttributes as $name => $attribute) {
615
+ $value = $product->getData($name);
616
+ if ($value !== null) {
617
+ if ($attribute['frontend_input'] == 'select') {
618
+ $value = $product->getAttributeText($attribute['attribute_code']);
619
+ }
620
+ elseif ($attribute['frontend_input'] == 'multiselect') {
621
+ $value = $product->getAttributeText($attribute['attribute_code']);
622
+ if ($value === false) {
623
+ continue;
624
+ }
625
+ elseif (is_array($value)) {
626
+ $value = implode("\r\n", $value);
627
+ }
628
+ }
629
+
630
+ if ($attribute['variant']) {
631
+ $p['variants'][$name] = $value;
632
+ } else {
633
+ $p['attributes'][$name] = $value;
634
+ }
635
+ }
636
+ }
637
+
638
+ // Categories
639
+ $categories = $product->getCategoryIds();
640
+ if (!empty($categories)) {
641
+ $p['categories'] = $categories;
642
+ }
643
+
644
+ // Options
645
+ if (isset($params['options'])) {
646
+ foreach ($product->getOptions() as $option) {
647
+ $p['options'][$option->getTitle()] = array(
648
+ 'type' => $option->getType(),
649
+ 'required' => $option->getRequired(),
650
+ );
651
+
652
+ foreach ($option->getValues() as $value) {
653
+ $valueArray = array(
654
+ 'title' => $value->getTitle(),
655
+ 'price' => $value->getPrice(),
656
+ 'pricetype' => $value->getPriceType(),
657
+ 'sku' => $value->getSku(),
658
+ );
659
+ $p['options'][$option->getTitle()]['values'][] = $valueArray;
660
+ }
661
+ }
662
+ }
663
+
664
+ return $p;
665
+ }
666
+
667
+
668
+ protected function writeProduct(&$writer, $p) {
669
+ if (isset($p['options'])) {
670
+ $writer->writeComment(print_r($p['options'], true));
671
+ }
672
+
673
+ $writer->startElement('product');
674
+
675
+ if (!$p['active']) $writer->writeElement('active', $p['active']);
676
+ $writer->writeElement('sku', $p['sku']);
677
+ $writer->writeElement('type', $p['type']);
678
+ if (isset($p['parentsku'])) $writer->writeElement('parentsku', $p['parentsku']);
679
+ $writer->writeElement('title', $p['title']);
680
+ $writer->writeElement('description', $p['description']);
681
+ if (isset($p['brand'])) $writer->writeElement('brand', $p['brand']);
682
+ if (isset($p['weight'])) {
683
+ $writer->startElement('weight');
684
+ //$writer->writeAttribute('unit', '?');
685
+ $writer->text($p['weight']);
686
+ $writer->endElement();
687
+ }
688
+
689
+ $writer->startElement('pricing');
690
+ $writer->writeAttribute('currency', $p['currency']);
691
+ $writer->writeAttribute('isvatincluded', $p['isvatincluded']);
692
+ $writer->writeElement('price', $p['price']);
693
+ if (isset($p['originalprice'])) $writer->writeElement('originalprice', $p['originalprice']);
694
+ $writer->endElement();
695
+
696
+ $writer->startElement('stock');
697
+ if ($p['enablestocklimitation']) {
698
+ $writer->writeElement('quantity', $p['quantity']);
699
+ }
700
+ else {
701
+ $writer->writeElement('enablestocklimitation', $p['enablestocklimitation']);
702
+ }
703
+ $writer->endElement();
704
+
705
+ $writer->startElement('images');
706
+ if (isset($p['reusefrommaster'])) $writer->writeAttribute('reusefrommaster', $p['reusefrommaster']);
707
+ if (isset($p['images'])) {
708
+ foreach ($p['images'] as $image) {
709
+ $writer->startElement('image');
710
+ $writer->writeAttribute('url', $image);
711
+ $writer->endElement();
712
+ }
713
+ }
714
+ $writer->endElement();
715
+
716
+ if (isset($p['attributes'])) {
717
+ $writer->startElement('attributes');
718
+ foreach ($p['attributes'] as $name => $value) {
719
+ $writer->startElement('attribute');
720
+ $writer->writeAttribute('name', $name);
721
+ if (is_array($value)) {
722
+ $writer->writecomment($name.': '.print_r($value, true));
723
+ }
724
+ $writer->text($value);
725
+ $writer->endElement();
726
+ }
727
+ $writer->endElement();
728
+ }
729
+
730
+ if (isset($p['variants'])) {
731
+ $writer->startElement('variants');
732
+ foreach ($p['variants'] as $name => $value) {
733
+ $writer->startElement('variant');
734
+ $writer->writeAttribute('name', $name);
735
+ $writer->text($value);
736
+ $writer->endElement();
737
+ }
738
+ $writer->endElement();
739
+ }
740
+
741
+ if (isset($p['categories'])) {
742
+ $writer->startElement('categories');
743
+ foreach ($p['categories'] as $id) {
744
+ $writer->startElement('category');
745
+ $writer->writeAttribute('id', $id);
746
+ $writer->endElement();
747
+ }
748
+ $writer->endElement();
749
+ }
750
+
751
+ $writer->endElement();
752
+ }
753
+
754
+
755
+ public function getAction() {
756
+ print_r($_GET);
757
+ }
758
+
759
+
760
+ public function paramsAction() {
761
+ print_r(Mage::app()->getRequest()->getParams());
762
+ }
763
+ }
764
+ ?>
app/code/community/Atosho/Integration/etc/config.xml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Atosho_Integration>
5
+ <version>1.0.0</version>
6
+ </Atosho_Integration>
7
+ </modules>
8
+ <frontend>
9
+ <routers>
10
+ <atosho>
11
+ <use>standard</use>
12
+ <args>
13
+ <module>Atosho_Integration</module>
14
+ <frontName>atosho</frontName>
15
+ </args>
16
+ </atosho>
17
+ </routers>
18
+ </frontend>
19
+ </config>
app/code/community/Atosho/Shipping/Model/Carrier/Atosho.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Atosho_Shipping_Model_Carrier_Atosho extends Mage_Shipping_Model_Carrier_Abstract {
4
+
5
+ protected $_code = 'atosho';
6
+
7
+ protected $_isFixed = true;
8
+
9
+ // The URL of the REST Web service to call when retrieving shipping price.
10
+ protected $atosho_url_shipping_price = 'http://api.atosho.com/v1/shipping/magento';
11
+
12
+ // Timeout to set when calling Atosho Web services (seconds).
13
+ protected $atosho_timeout = 100;
14
+
15
+ /**
16
+ * Collect rates for this shipping method based on information in $request
17
+ *
18
+ * @param Mage_Shipping_Model_Rate_Request $request
19
+ * @return Mage_Shipping_Model_Rate_Result
20
+ */
21
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request) {
22
+ if (!isset($_SERVER['HTTP_SOAPACTION'])) {
23
+ return false;
24
+ }
25
+ $result = Mage::getModel('shipping/rate_result');
26
+
27
+ $method = Mage::getModel('shipping/rate_result_method');
28
+
29
+ $method->setCarrier('atosho');
30
+ $method->setCarrierTitle($this->getConfigData('title'));
31
+
32
+ $method->setMethod('atosho');
33
+ //$method->setMethodTitle('Atosho Shipping');
34
+ //$method->setMethodDescription('Default shipping method for Atosho orders');
35
+
36
+ // Call an Atosho REST Web service to get the shipping price.
37
+
38
+ // Initialize a Zend HTTP client.
39
+ $client = new Zend_Http_Client($this->atosho_url_shipping_price, array('timeout' => $this->atosho_timeout));
40
+
41
+ // Set parameters.
42
+ $items = $request->getAllItems();
43
+ $skus = array();
44
+ $quantities = array();
45
+ foreach ($items as $item) {
46
+ $skus[] = $item->getProduct()->getSku();
47
+ $quantities[] = $item->getQty();
48
+ }
49
+ $parameters = array(
50
+ 'baseurl' => Mage::app()->getStore()->getBaseUrl(),
51
+ 'country' => $request->getDestCountryId(),
52
+ 'currency' => $request->getBaseCurrency()->getCode(),
53
+ 'address' => $request->getDestStreet(),
54
+ 'postalcode' => $request->getDestPostcode(),
55
+ 'city' => $request->getDestCity(),
56
+ 'price' => $request->getOrderSubtotal(),
57
+ 'skus' => $skus,
58
+ 'quantities' => $quantities,
59
+ );
60
+ $client->setParameterPost($parameters);
61
+
62
+ // Call the Web service.
63
+ $response = $client->request('POST');
64
+ if ($response->isSuccessful()) {
65
+ $response_object = json_decode($response->getBody());
66
+ if (!isset($response_object))
67
+ return false;
68
+ if (!isset($response_object->price))
69
+ return false;
70
+ $method->setPrice($response_object->price);
71
+ $method->setCost($response_object->price);
72
+ }
73
+ else {
74
+ return false;
75
+ }
76
+
77
+ $result->append($method);
78
+
79
+ return $result;
80
+ }
81
+
82
+ /**
83
+ * This method is used when viewing / listing Shipping Methods with Codes programmatically
84
+ */
85
+ public function getAllowedMethods() {
86
+ return array($this->_code => $this->getConfigData('title'));
87
+ }
88
+ }
app/code/community/Atosho/Shipping/etc/config.xml ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Atosho_Shipping>
5
+ <version>1.0.0</version>
6
+ </Atosho_Shipping>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <atosho_shipping>
11
+ <class>Atosho_Shipping_Model</class>
12
+ </atosho_shipping>
13
+ </models>
14
+ <resources>
15
+ <atosho_shipping_setup>
16
+ <setup>
17
+ <module>Atosho_Shipping</module>
18
+ </setup>
19
+ <connection>
20
+ <use>core_setup</use>
21
+ </connection>
22
+ </atosho_shipping_setup>
23
+ <atosho_shipping_write>
24
+ <connection>
25
+ <use>core_write</use>
26
+ </connection>
27
+ </atosho_shipping_write>
28
+ <atosho_shipping_read>
29
+ <connection>
30
+ <use>core_read</use>
31
+ </connection>
32
+ </atosho_shipping_read>
33
+ </resources>
34
+ </global>
35
+ <default>
36
+ <carriers>
37
+ <atosho>
38
+ <active>1</active>
39
+ <model>atosho_shipping/carrier_atosho</model>
40
+ <title>Atosho</title>
41
+ </atosho>
42
+ </carriers>
43
+ </default>
44
+ </config>
app/code/community/Atosho/Shipping/etc/system.xml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <carriers>
5
+ <groups>
6
+ <atosho translate="label" module="shipping">
7
+ <label>Atosho</label>
8
+ <frontend_type>text</frontend_type>
9
+ <sort_order>20</sort_order>
10
+ <show_in_default>1</show_in_default>
11
+ <show_in_website>1</show_in_website>
12
+ <show_in_store>1</show_in_store>
13
+ <fields>
14
+ <active translate="label">
15
+ <label>Enabled</label>
16
+ <frontend_type>select</frontend_type>
17
+ <source_model>adminhtml/system_config_source_yesno</source_model>
18
+ <sort_order>1</sort_order>
19
+ <show_in_default>1</show_in_default>
20
+ <show_in_website>1</show_in_website>
21
+ <show_in_store>1</show_in_store>
22
+ </active>
23
+ <title translate="label">
24
+ <label>Title</label>
25
+ <frontend_type>text</frontend_type>
26
+ <sort_order>2</sort_order>
27
+ <show_in_default>1</show_in_default>
28
+ <show_in_website>1</show_in_website>
29
+ <show_in_store>1</show_in_store>
30
+ </title>
31
+ </fields>
32
+ </atosho>
33
+ </groups>
34
+ </carriers>
35
+ </sections>
36
+ </config>
app/etc/modules/Atosho_All.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Atosho_Integration>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Atosho_Integration>
8
+ <Atosho_AtoshoPayment>
9
+ <active>true</active>
10
+ <codePool>community</codePool>
11
+ <depends>
12
+ <Mage_Payment />
13
+ </depends>
14
+ </Atosho_AtoshoPayment>
15
+ <Atosho_Shipping>
16
+ <active>true</active>
17
+ <codePool>community</codePool>
18
+ <depends>
19
+ <Mage_Shipping />
20
+ </depends>
21
+ </Atosho_Shipping>
22
+ </modules>
23
+ </config>
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Atosho</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license>OSL-3.0</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Atosho.com product and order integration</summary>
10
+ <description>Exposes product catalog to Atosho in the form of an XML feed. Creates a new payment method called 'Atosho Payment' which indicates that an order has been paid through Atosho.</description>
11
+ <notes>First public version of the Atosho product and order integration extension.</notes>
12
+ <authors><author><name>Atosho</name><user>Atosho</user><email>magento@atosho.com</email></author></authors>
13
+ <date>2012-05-16</date>
14
+ <time>09:38:20</time>
15
+ <contents><target name="mageetc"><dir name="modules"><file name="Atosho_All.xml" hash="80137c2c28f206ab9a22ffe1f9dbb58b"/></dir></target><target name="magecommunity"><dir name="Atosho"><dir name="Integration"><dir name="controllers"><file name="FeedController.php" hash="054cb35ba393ff32366278e531c26b72"/></dir><dir name="etc"><file name="config.xml" hash="56fbf704a185590c465116229272b3a3"/></dir></dir><dir name="AtoshoPayment"><dir name="Model"><file name="AtoshoPayment.php" hash="7d9afd8abc45ca252ccf36ed7f70c27f"/></dir><dir name="etc"><file name="config.xml" hash="30b5190de1b9b2cb1d3759995ca7c2ff"/><file name="system.xml" hash="ca3e25cb7ceef0da772eb88f91dd32cc"/></dir></dir><dir name="Shipping"><dir name="Model"><dir name="Carrier"><file name="Atosho.php" hash="dcd80ea031ec160eadadac847e80973b"/></dir></dir><dir name="etc"><file name="config.xml" hash="6770b1b833aa1454da307015fdbe5216"/><file name="system.xml" hash="96c2ade90fd06ab5bc3ef787a2af029a"/></dir></dir></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php><extension><name>xmlwriter</name><min></min><max></max></extension></required></dependencies>
18
+ </package>