1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31: 32: 33:
34: class Mage_ImportExport_Model_Import_Entity_Customer_Address extends Mage_ImportExport_Model_Import_Entity_Abstract
35: {
36: 37: 38:
39: const COL_NAME_PREFIX = '_address_';
40:
41: 42: 43:
44: const COL_NAME_DEFAULT_BILLING = '_address_default_billing_';
45: const COL_NAME_DEFAULT_SHIPPING = '_address_default_shipping_';
46:
47: 48: 49:
50: const ERROR_INVALID_REGION = 'invalidRegion';
51:
52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63:
64: protected $_attributes = array();
65:
66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81:
82: protected $_countryRegions = array();
83:
84: 85: 86: 87: 88:
89: protected $_customer;
90:
91: 92: 93: 94: 95:
96: protected static $_defaultAddressAttrMapping = array(
97: self::COL_NAME_DEFAULT_BILLING => 'default_billing',
98: self::COL_NAME_DEFAULT_SHIPPING => 'default_shipping'
99: );
100:
101: 102: 103: 104: 105:
106: protected $_entityTable;
107:
108: 109: 110: 111: 112:
113: protected $_indexValueAttributes = array('country_id');
114:
115: 116: 117: 118: 119:
120: protected $_messageTemplates = array(self::ERROR_INVALID_REGION => 'Region is invalid');
121:
122: 123: 124: 125: 126:
127: protected $_particularAttributes = array(self::COL_NAME_DEFAULT_BILLING, self::COL_NAME_DEFAULT_SHIPPING);
128:
129: 130: 131: 132: 133:
134: protected $_regions = array();
135:
136: 137: 138: 139: 140: 141:
142: public function __construct(Mage_ImportExport_Model_Import_Entity_Customer $customer)
143: {
144: parent::__construct();
145:
146: $this->_initAttributes()->_initCountryRegions();
147:
148: $this->_entityTable = Mage::getModel('customer/address')->getResource()->getEntityTable();
149: $this->_customer = $customer;
150:
151: foreach ($this->_messageTemplates as $errorCode => $message) {
152: $this->_customer->addMessageTemplate($errorCode, $message);
153: }
154: }
155:
156: 157: 158: 159: 160:
161: protected function _importData()
162: {
163:
164: $customer = Mage::getModel('customer/customer');
165:
166: $resource = Mage::getModel('customer/address');
167: $strftimeFormat = Varien_Date::convertZendToStrftime(Varien_Date::DATETIME_INTERNAL_FORMAT, true, true);
168: $table = $resource->getResource()->getEntityTable();
169: $nextEntityId = Mage::getResourceHelper('importexport')->getNextAutoincrement($table);
170: $customerId = null;
171: $regionColName = self::getColNameForAttrCode('region');
172: $countryColName = self::getColNameForAttrCode('country_id');
173:
174: $regionIdAttr = Mage::getSingleton('eav/config')->getAttribute($this->getEntityTypeCode(), 'region_id');
175: $regionIdTable = $regionIdAttr->getBackend()->getTable();
176: $regionIdAttrId = $regionIdAttr->getId();
177: $isAppendMode = Mage_ImportExport_Model_Import::BEHAVIOR_APPEND == $this->_customer->getBehavior();
178:
179: while ($bunch = $this->_dataSourceModel->getNextBunch()) {
180: $entityRows = array();
181: $attributes = array();
182: $defaults = array();
183:
184: foreach ($bunch as $rowNum => $rowData) {
185: if (!empty($rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_EMAIL])
186: && !empty($rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_WEBSITE])
187: ) {
188: $customerId = $this->_customer->getCustomerId(
189: $rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_EMAIL],
190: $rowData[Mage_ImportExport_Model_Import_Entity_Customer::COL_WEBSITE]
191: );
192: }
193: if (!$customerId || !$this->_isRowWithAddress($rowData) || !$this->validateRow($rowData, $rowNum)) {
194: continue;
195: }
196:
197:
198: $addressCollection = Mage::getResourceModel('customer/address_collection');
199: $addressCollection->addAttributeToFilter('parent_id', $customerId);
200:
201: $addressAttributes = array();
202: foreach ($this->_attributes as $attrAlias => $attrParams) {
203: if (isset($rowData[$attrAlias]) && strlen($rowData[$attrAlias])) {
204: if ('select' == $attrParams['type']) {
205: $value = $attrParams['options'][strtolower($rowData[$attrAlias])];
206: } elseif ('datetime' == $attrParams['type']) {
207: $value = gmstrftime($strftimeFormat, strtotime($rowData[$attrAlias]));
208: } else {
209: $value = $rowData[$attrAlias];
210: }
211: $addressAttributes[$attrParams['id']] = $value;
212: $addressCollection->addAttributeToFilter($attrParams['code'], $value);
213: }
214: }
215:
216:
217: if ($isAppendMode && $addressCollection->getSize()) {
218: continue;
219: }
220:
221: $entityId = $nextEntityId++;
222:
223:
224: $entityRows[] = array(
225: 'entity_id' => $entityId,
226: 'entity_type_id' => $this->_entityTypeId,
227: 'parent_id' => $customerId,
228: 'created_at' => now(),
229: 'updated_at' => now()
230: );
231:
232: foreach ($this->_attributes as $attrAlias => $attrParams) {
233: if (isset($addressAttributes[$attrParams['id']])) {
234: $attributes[$attrParams['table']][$entityId][$attrParams['id']]
235: = $addressAttributes[$attrParams['id']];
236: }
237: }
238:
239: foreach (self::getDefaultAddressAttrMapping() as $colName => $customerAttrCode) {
240: if (!empty($rowData[$colName])) {
241: $attribute = $customer->getAttribute($customerAttrCode);
242: $defaults[$attribute->getBackend()->getTable()][$customerId][$attribute->getId()] = $entityId;
243: }
244: }
245:
246: if (!empty($rowData[$regionColName])) {
247: $countryNormalized = strtolower($rowData[$countryColName]);
248: $regionNormalized = strtolower($rowData[$regionColName]);
249:
250: if (isset($this->_countryRegions[$countryNormalized][$regionNormalized])) {
251: $regionId = $this->_countryRegions[$countryNormalized][$regionNormalized];
252: $attributes[$regionIdTable][$entityId][$regionIdAttrId] = $regionId;
253:
254: $tbl = $this->_attributes[$regionColName]['table'];
255: $regionColNameId = $this->_attributes[$regionColName]['id'];
256: $attributes[$tbl][$entityId][$regionColNameId] = $this->_regions[$regionId];
257: }
258: }
259: }
260: $this->_saveAddressEntity($entityRows)
261: ->_saveAddressAttributes($attributes)
262: ->_saveCustomerDefaults($defaults);
263: }
264: return true;
265: }
266:
267: 268: 269: 270: 271:
272: protected function _initAttributes()
273: {
274: $addrCollection = Mage::getResourceModel('customer/address_attribute_collection')
275: ->addSystemHiddenFilter()
276: ->addExcludeHiddenFrontendFilter();
277:
278: foreach ($addrCollection as $attribute) {
279: $this->_attributes[self::getColNameForAttrCode($attribute->getAttributeCode())] = array(
280: 'id' => $attribute->getId(),
281: 'code' => $attribute->getAttributeCode(),
282: 'table' => $attribute->getBackend()->getTable(),
283: 'is_required' => $attribute->getIsRequired(),
284: 'rules' => $attribute->getValidateRules() ? unserialize($attribute->getValidateRules()) : null,
285: 'type' => Mage_ImportExport_Model_Import::getAttributeType($attribute),
286: 'options' => $this->getAttributeOptions($attribute)
287: );
288: }
289: return $this;
290: }
291:
292: 293: 294: 295: 296:
297: protected function _initCountryRegions()
298: {
299: foreach (Mage::getResourceModel('directory/region_collection') as $regionRow) {
300: $countryNormalized = strtolower($regionRow['country_id']);
301: $regionCode = strtolower($regionRow['code']);
302: $regionName = strtolower($regionRow['default_name']);
303: $this->_countryRegions[$countryNormalized][$regionCode] = $regionRow['region_id'];
304: $this->_countryRegions[$countryNormalized][$regionName] = $regionRow['region_id'];
305: $this->_regions[$regionRow['region_id']] = $regionRow['default_name'];
306: }
307: return $this;
308: }
309:
310: 311: 312: 313: 314: 315:
316: protected function _isRowWithAddress(array $rowData)
317: {
318: foreach (array_keys($this->_attributes) as $colName) {
319: if (isset($rowData[$colName]) && strlen($rowData[$colName])) {
320: return true;
321: }
322: }
323: return false;
324: }
325:
326: 327: 328: 329: 330: 331:
332: protected function _saveAddressAttributes(array $attributesData)
333: {
334: foreach ($attributesData as $tableName => $data) {
335: $tableData = array();
336:
337: foreach ($data as $addressId => $attrData) {
338: foreach ($attrData as $attributeId => $value) {
339: $tableData[] = array(
340: 'entity_id' => $addressId,
341: 'entity_type_id' => $this->_entityTypeId,
342: 'attribute_id' => $attributeId,
343: 'value' => $value
344: );
345: }
346: }
347: $this->_connection->insertMultiple($tableName, $tableData);
348: }
349: return $this;
350: }
351:
352: 353: 354: 355: 356: 357:
358: protected function _saveAddressEntity(array $entityRows)
359: {
360: if ($entityRows) {
361: if (Mage_ImportExport_Model_Import::BEHAVIOR_APPEND != $this->_customer->getBehavior()) {
362: $customersToClean = array();
363:
364: foreach ($entityRows as $entityData) {
365: $customersToClean[$entityData['parent_id']] = true;
366: }
367: $this->_connection->delete(
368: $this->_entityTable,
369: $this->_connection->quoteInto('`parent_id` IN (?)', array_keys($customersToClean))
370: );
371: }
372: $this->_connection->insertMultiple($this->_entityTable, $entityRows);
373: }
374: return $this;
375: }
376:
377: 378: 379: 380: 381: 382:
383: protected function _saveCustomerDefaults(array $defaults)
384: {
385: foreach ($defaults as $tableName => $data) {
386: $tableData = array();
387:
388: foreach ($data as $customerId => $attrData) {
389: foreach ($attrData as $attributeId => $value) {
390: $tableData[] = array(
391: 'entity_id' => $customerId,
392: 'entity_type_id' => $this->_customer->getEntityTypeId(),
393: 'attribute_id' => $attributeId,
394: 'value' => $value
395: );
396: }
397: }
398: $this->_connection->insertOnDuplicate($tableName, $tableData, array('value'));
399: }
400: return $this;
401: }
402:
403: 404: 405: 406: 407: 408: 409:
410: public static function getColNameForAttrCode($attrCode)
411: {
412: return self::COL_NAME_PREFIX . $attrCode;
413: }
414:
415: 416: 417: 418: 419: 420:
421: public static function getDefaultAddressAttrMapping()
422: {
423: return self::$_defaultAddressAttrMapping;
424: }
425:
426: 427: 428: 429: 430:
431: public function getEntityTypeCode()
432: {
433: return 'customer_address';
434: }
435:
436: 437: 438: 439: 440: 441:
442: public function isAttributeParticular($attrCode)
443: {
444: return isset($this->_attributes[$attrCode]) || in_array($attrCode, $this->_particularAttributes);
445: }
446:
447: 448: 449: 450: 451: 452: 453:
454: public function validateRow(array $rowData, $rowNum)
455: {
456: $rowIsValid = true;
457:
458: if ($this->_isRowWithAddress($rowData)) {
459: foreach ($this->_attributes as $colName => $attrParams) {
460: if (isset($rowData[$colName]) && strlen($rowData[$colName])) {
461: $rowIsValid &= $this->_customer->isAttributeValid($colName, $attrParams, $rowData, $rowNum);
462: } elseif ($attrParams['is_required']) {
463: $this->_customer->addRowError(
464: Mage_ImportExport_Model_Import_Entity_Customer::ERROR_VALUE_IS_REQUIRED, $rowNum, $colName
465: );
466: $rowIsValid = false;
467: }
468: }
469:
470: if ($rowIsValid) {
471: $regionColName = self::getColNameForAttrCode('region');
472: $countryColName = self::getColNameForAttrCode('country_id');
473: $countryRegions = isset($this->_countryRegions[strtolower($rowData[$countryColName])])
474: ? $this->_countryRegions[strtolower($rowData[$countryColName])]
475: : array();
476:
477: if (!empty($rowData[$regionColName])
478: && !empty($countryRegions)
479: && !isset($countryRegions[strtolower($rowData[$regionColName])])
480: ) {
481: $this->_customer->addRowError(self::ERROR_INVALID_REGION, $rowNum);
482:
483: $rowIsValid = false;
484: }
485: }
486: }
487: return $rowIsValid;
488: }
489: }
490: