Standard::__construct()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 54
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 17
c 0
b 0
f 0
nc 4
nop 3
dl 0
loc 54
rs 9.7

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2026
6
 * @package Controller
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\Controller\Jobs\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\Jobs\Common\Product\Import\Csv\Processor\Base
22
	implements \Aimeos\Controller\Jobs\Common\Product\Import\Csv\Processor\Iface
23
{
24
	/** controller/jobs/product/import/csv/processor/attribute/name
25
	 * Name of the attribute processor implementation
26
	 *
27
	 * Use "Myname" if your class is named "\Aimeos\Controller\Jobs\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
	 */
33
34
	private \Aimeos\Controller\Jobs\Common\Product\Import\Csv\Cache\Attribute\Standard $cache;
35
	private ?array $listTypes = null;
36
	private array $types = [];
37
38
39
	/**
40
	 * Initializes the object
41
	 *
42
	 * @param \Aimeos\MShop\ContextIface $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\Jobs\Common\Product\Import\Csv\Processor\Iface $object Decorated processor
45
	 */
46
	public function __construct( \Aimeos\MShop\ContextIface $context, array $mapping,
47
		?\Aimeos\Controller\Jobs\Common\Product\Import\Csv\Processor\Iface $object = null )
48
	{
49
		parent::__construct( $context, $mapping, $object );
50
51
		$config = $context->config();
52
53
		/** controller/jobs/product/import/csv/attribute/listtypes
54
		 * Names of the product list types for attributes that are updated or removed
55
		 *
56
		 * If you want to associate attribute items manually via the administration
57
		 * interface to products and don't want these to be touched during the
58
		 * import, you can specify the product list types for these attributes
59
		 * that shouldn't be updated or removed.
60
		 *
61
		 * @param array|null List of product list type names or null for all
62
		 * @since 2015.05
63
		 * @see controller/jobs/product/import/csv/domains
64
		 * @see controller/jobs/product/import/csv/separator
65
		 * @see controller/jobs/product/import/csv/catalog/listtypes
66
		 * @see controller/jobs/product/import/csv/media/listtypes
67
		 * @see controller/jobs/product/import/csv/price/listtypes
68
		 * @see controller/jobs/product/import/csv/product/listtypes
69
		 * @see controller/jobs/product/import/csv/supplier/listtypes
70
		 * @see controller/jobs/product/import/csv/text/listtypes
71
		 */
72
		$default = $config->get( 'controller/jobs/product/import/csv/processor/attribute/listtypes' );
73
		$this->listTypes = $config->get( 'controller/jobs/product/import/csv/attribute/listtypes', $default );
74
75
		if( $this->listTypes === null )
76
		{
77
			$this->listTypes = [];
78
			$manager = \Aimeos\MShop::create( $context, 'product/lists/type' );
79
			$search = $manager->filter()->slice( 0, 0x7fffffff );
80
81
			foreach( $manager->search( $search ) as $item ) {
82
				$this->listTypes[$item->getCode()] = $item->getCode();
83
			}
84
		}
85
		else
86
		{
87
			$this->listTypes = array_combine( $this->listTypes, $this->listTypes );
88
		}
89
90
91
		$manager = \Aimeos\MShop::create( $context, 'attribute/type' );
92
		$search = $manager->filter()->slice( 0, 0x7fffffff );
93
94
		foreach( $manager->search( $search ) as $item ) {
95
			$this->types[$item->getCode()] = $item->getCode();
96
		}
97
98
99
		$this->cache = $this->getCache( 'attribute' );
100
	}
101
102
103
	/**
104
	 * Saves the attribute related data to the storage
105
	 *
106
	 * @param \Aimeos\MShop\Product\Item\Iface $product Product item with associated items
107
	 * @param array $data List of CSV fields with position as key and data as value
108
	 * @return array List of data which hasn't been imported
109
	 */
110
	public function process( \Aimeos\MShop\Product\Item\Iface $product, array $data ) : array
111
	{
112
		$context = $this->context();
113
		$manager = \Aimeos\MShop::create( $context, 'product' );
114
115
		/** controller/jobs/product/import/csv/separator
116
		 * Separator between multiple values in one CSV field
117
		 *
118
		 * In Aimeos, fields of some CSV columns can contain multiple values which
119
		 * are split and imported as separate values. This setting configures the
120
		 * character that is used for splitting the values and by default, a new
121
		 * line character (\n) is used.
122
		 *
123
		 * @param string Unique character or characters in field values
124
		 * @since 2015.05
125
		 * @see controller/jobs/product/import/csv/domains
126
		 * @see controller/jobs/product/import/csv/attribute/listtypes
127
		 * @see controller/jobs/product/import/csv/media/listtypes
128
		 * @see controller/jobs/product/import/csv/price/listtypes
129
		 * @see controller/jobs/product/import/csv/product/listtypes
130
		 * @see controller/jobs/product/import/csv/supplier/listtypes
131
		 * @see controller/jobs/product/import/csv/text/listtypes
132
		 */
133
		$separator = $context->config()->get( 'controller/jobs/product/import/csv/separator', "\n" );
134
135
		$pos = 0;
136
		$listMap = [];
137
		$map = $this->getMappedChunk( $data, $this->getMapping() );
138
		$listItems = $product->getListItems( 'attribute', $this->listTypes, null, false );
139
140
		foreach( $listItems as $listItem )
141
		{
142
			if( $refItem = $listItem->getRefItem() ) {
143
				$listMap[$refItem->getCode()][$refItem->getType()][$listItem->getType()] = $listItem;
144
			}
145
		}
146
147
		foreach( $map as $list )
148
		{
149
			if( $this->checkEntry( $list ) === false ) {
150
				continue;
151
			}
152
153
			$attrType = trim( $this->val( $list, 'attribute.type', '' ) );
154
			$listtype = trim( $this->val( $list, 'product.lists.type', 'default' ) );
155
			$this->addType( 'product/lists/type', 'attribute', $listtype );
156
157
			$listConfig = $this->getListConfig( trim( $this->val( $list, 'product.lists.config', '' ) ) );
158
			unset( $list['product.lists.config'] );
159
160
			$codes = explode( $separator, trim( $this->val( $list, 'attribute.code', '' ) ) );
161
			unset( $list['attribute.code'], $list['product.lists.config'] );
162
163
			foreach( $codes as $code )
164
			{
165
				$code = trim( $code );
166
167
				$attrItem = $this->getAttributeItem( $code, $attrType );
168
				$attrItem = $attrItem->fromArray( $list )->setCode( $code );
169
170
				$listItem = $listMap[$code][$attrType][$listtype] ?? $manager->createListItem();
0 ignored issues
show
Bug introduced by
The method createListItem() does not exist on Aimeos\MShop\Common\Manager\Iface. Did you maybe mean create()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

170
				$listItem = $listMap[$code][$attrType][$listtype] ?? $manager->/** @scrutinizer ignore-call */ createListItem();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
171
				$listItem = $listItem->setPosition( $pos )->fromArray( $list )->setConfig( $listConfig );
172
173
				$product->addListItem( 'attribute', $listItem->setType( $listtype ), $attrItem );
174
				unset( $listItems[$listItem->getId()] );
175
			}
176
		}
177
178
		$product->deleteListItems( $listItems );
179
180
		return $this->object()->process( $product, $data );
181
	}
182
183
184
	/**
185
	 * Checks if the entry from the mapped data is valid
186
	 *
187
	 * @param array $list Associative list of key/value pairs from the mapped data
188
	 * @return bool True if the entry is valid, false if not
189
	 */
190
	protected function checkEntry( array $list ) : bool
191
	{
192
		if( $this->val( $list, 'attribute.code' ) === null ) {
193
			return false;
194
		}
195
196
		if( ( $type = trim( $this->val( $list, 'product.lists.type', 'default' ) ) ) && !isset( $this->listTypes[$type] ) )
197
		{
198
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'product list' );
199
			throw new \Aimeos\Controller\Jobs\Exception( $msg );
200
		}
201
202
		if( ( $type = trim( $this->val( $list, 'attribute.type', '' ) ) ) && !isset( $this->types[$type] ) )
203
		{
204
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'attribute' );
205
			throw new \Aimeos\Controller\Jobs\Exception( $msg );
206
		}
207
208
		return true;
209
	}
210
211
212
	/**
213
	 * Returns the attribute item for the given code and type
214
	 *
215
	 * @param string $code Attribute code
216
	 * @param string $type Attribute type
217
	 * @return \Aimeos\MShop\Attribute\Item\Iface Attribute item object
218
	 */
219
	protected function getAttributeItem( string $code, string $type ) : \Aimeos\MShop\Attribute\Item\Iface
220
	{
221
		if( ( $item = $this->cache->get( $code, $type ) ) === null )
222
		{
223
			$manager = \Aimeos\MShop::create( $this->context(), 'attribute' );
224
225
			$item = $manager->create();
226
			$item->setType( $type );
227
			$item->setDomain( 'product' );
228
			$item->setLabel( $code );
229
			$item->setCode( $code );
230
			$item->setStatus( 1 );
231
232
			$item = $manager->save( $item );
233
234
			$this->cache->set( $item );
0 ignored issues
show
Bug introduced by
It seems like $item can also be of type Aimeos\Map; however, parameter $item of Aimeos\Controller\Jobs\C...tribute\Standard::set() does only seem to accept Aimeos\MShop\Common\Item\Iface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

234
			$this->cache->set( /** @scrutinizer ignore-type */ $item );
Loading history...
235
		}
236
237
		return $item;
238
	}
239
}
240