Completed
Push — master ( f2cd2d...a3e1ac )
by Aimeos
02:52
created

Standard::checkMatch()   B

Complexity

Conditions 7
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 8.2222
c 0
b 0
f 0
cc 7
eloc 8
nc 2
nop 2
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2016
6
 * @package Controller
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\Controller\Common\Product\Import\Csv\Processor\Attribute;
12
13
14
/**
15
 * Attribute processor for CSV imports
16
 *
17
 * @package Controller
18
 * @subpackage Common
19
 */
20
class Standard
21
	extends \Aimeos\Controller\Common\Product\Import\Csv\Processor\Base
0 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
Coding Style introduced by
Expected 0 spaces between "Base" and comma; 1 found
Loading history...
22
	implements \Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
23
{
24
	/** controller/common/product/import/csv/processor/attribute/name
25
	 * Name of the attribute processor implementation
26
	 *
27
	 * Use "Myname" if your class is named "\Aimeos\Controller\Common\Product\Import\Csv\Processor\Attribute\Myname".
28
	 * The name is case-sensitive and you should avoid camel case names like "MyName".
29
	 *
30
	 * @param string Last part of the processor class name
31
	 * @since 2015.10
32
	 * @category Developer
33
	 */
34
35
	private $cache;
36
	private $listTypes;
37
38
39
	/**
40
	 * Initializes the object
41
	 *
42
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
43
	 * @param array $mapping Associative list of field position in CSV as key and domain item key as value
44
	 * @param \Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface $object Decorated processor
45
	 */
46
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $mapping,
47
		\Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface $object = null )
48
	{
49
		parent::__construct( $context, $mapping, $object );
50
51
		/** controller/common/product/import/csv/processor/attribute/listtypes
52
		 * Names of the product list types for attributes that are updated or removed
53
		 *
54
		 * If you want to associate attribute items manually via the administration
55
		 * interface to products and don't want these to be touched during the
56
		 * import, you can specify the product list types for these attributes
57
		 * that shouldn't be updated or removed.
58
		 *
59
		 * @param array|null List of product list type names or null for all
60
		 * @since 2015.05
61
		 * @category Developer
62
		 * @category User
63
		 * @see controller/common/product/import/csv/domains
64
		 * @see controller/common/product/import/csv/processor/catalog/listtypes
65
		 * @see controller/common/product/import/csv/processor/media/listtypes
66
		 * @see controller/common/product/import/csv/processor/product/listtypes
67
		 * @see controller/common/product/import/csv/processor/price/listtypes
68
		 * @see controller/common/product/import/csv/processor/text/listtypes
69
		 */
70
		$this->listTypes = $context->getConfig()->get( 'controller/common/product/import/csv/processor/attribute/listtypes');
71
72
		$this->cache = $this->getCache( 'attribute' );
73
	}
74
75
76
	/**
77
	 * Saves the attribute related data to the storage
78
	 *
79
	 * @param \Aimeos\MShop\Product\Item\Iface $product Product item with associated items
80
	 * @param array $data List of CSV fields with position as key and data as value
81
	 * @return array List of data which hasn't been imported
82
	 */
83
	public function process( \Aimeos\MShop\Product\Item\Iface $product, array $data )
84
	{
85
		$context = $this->getContext();
86
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'attribute' );
87
		$listManager = \Aimeos\MShop\Factory::createManager( $context, 'product/lists' );
88
		$separator = $context->getConfig()->get( 'controller/common/product/import/csv/separator', "\n" );
89
90
		$manager->begin();
91
92
		try
93
		{
94
			$listMap = array();
95
			$map = $this->getMappedChunk( $data );
96
			$listItems = $product->getListItems( 'attribute', $this->listTypes );
97
98
			foreach( $listItems as $listItem )
99
			{
100
				if( ( $refItem = $listItem->getRefItem() ) !== null ) {
101
					$listMap[ $refItem->getCode() ][ $refItem->getType() ] = $listItem;
102
				}
103
			}
104
105
			foreach( $map as $pos => $list )
106
			{
107
				if( $this->checkEntry( $list ) === false ) {
108
					continue;
109
				}
110
111
				$codes = explode( $separator, $list['attribute.code'] );
112
113
				foreach( $codes as $code )
114
				{
115
					$attrItem = $this->getAttributeItem( $code, $list['attribute.type'] );
116
					$attrItem->fromArray( $list );
117
					$attrItem->setCode( $code );
118
					$manager->saveItem( $attrItem );
119
120
					$typecode = $this->getValue( $list, 'product.lists.type', 'default' );
121
					$list['product.lists.typeid'] = $this->getTypeId( 'product/lists/type', 'attribute', $typecode );
122
					$list['product.lists.refid'] = $attrItem->getId();
123
					$list['product.lists.parentid'] = $product->getId();
124
					$list['product.lists.domain'] = 'attribute';
125
126
					if( isset( $listMap[$code][ $list['attribute.type'] ] ) )
127
					{
128
						$listItem = $listMap[$code][ $list['attribute.type'] ];
129
						unset( $listItems[ $listItem->getId() ] );
130
					}
131
					else
132
					{
133
						$listItem = $listManager->createItem();
134
					}
135
136
					$listItem->fromArray( $this->addListItemDefaults( $list, $pos ) );
137
					$listManager->saveItem( $listItem );
138
				}
139
			}
140
141
			$listManager->deleteItems( array_keys( $listItems ) );
142
			$remaining = $this->getObject()->process( $product, $data );
143
144
			$manager->commit();
145
		}
146
		catch( \Exception $e )
147
		{
148
			$manager->rollback();
149
			throw $e;
150
		}
151
152
		return $remaining;
153
	}
154
155
156
	/**
157
	 * Checks if the entry from the mapped data is valid
158
	 *
159
	 * @param array $list Associative list of key/value pairs from the mapped data
160
	 * @return boolean True if the entry is valid, false if not
161
	 */
162
	protected function checkEntry( array $list )
163
	{
164
		if( !isset( $list['attribute.code'] ) || $list['attribute.code'] === '' || $list['attribute.type'] === ''
165
			|| isset( $list['product.lists.type'] ) && $this->listTypes !== null
166
			&& !in_array( $list['product.lists.type'], (array) $this->listTypes )
167
		) {
168
			return false;
169
		}
170
171
		return true;
172
	}
173
174
175
	/**
176
	 * Returns the attribute item for the given code and type
177
	 *
178
	 * @param string $code Attribute code
179
	 * @param string $type Attribute type
180
	 * @return \Aimeos\MShop\Attribute\Item\Iface Attribute item object
181
	 */
182
	protected function getAttributeItem( $code, $type )
183
	{
184
		if( ( $item = $this->cache->get( $code, $type ) ) === null )
185
		{
186
			$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'attribute' );
187
188
			$item = $manager->createItem();
189
			$item->setTypeId( $this->getTypeId( 'attribute/type', 'product', $type ) );
190
			$item->setDomain( 'product' );
191
			$item->setLabel( $type . ' ' . $code );
192
			$item->setCode( $code );
193
			$item->setStatus( 1 );
194
195
			$manager->saveItem( $item );
196
197
			$this->cache->set( $item );
198
		}
199
200
		return $item;
201
	}
202
}
203