Passed
Push — master ( f0002b...c777f5 )
by Aimeos
08:04 queued 04:27
created

Standard::process()   B

Complexity

Conditions 7
Paths 15

Size

Total Lines 71
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 30
nc 15
nop 2
dl 0
loc 71
rs 8.5066
c 0
b 0
f 0

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), 2018-2023
6
 * @package Controller
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\Controller\Jobs\Common\Catalog\Import\Csv\Processor\Media;
12
13
14
/**
15
 * Media processor for CSV imports
16
 *
17
 * @package Controller
18
 * @subpackage Common
19
 */
20
class Standard
21
	extends \Aimeos\Controller\Jobs\Common\Catalog\Import\Csv\Processor\Base
22
	implements \Aimeos\Controller\Jobs\Common\Catalog\Import\Csv\Processor\Iface
23
{
24
	/** controller/jobs/catalog/import/csv/processor/media/name
25
	 * Name of the media processor implementation
26
	 *
27
	 * Use "Myname" if your class is named "\Aimeos\Controller\Jobs\Common\Catalog\Import\Csv\Processor\Media\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 2018.04
32
	 */
33
34
	private ?array $listTypes = null;
35
	private array $types = [];
36
37
38
	/**
39
	 * Initializes the object
40
	 *
41
	 * @param \Aimeos\MShop\ContextIface $context Context object
42
	 * @param array $mapping Associative list of field position in CSV as key and domain item key as value
43
	 * @param \Aimeos\Controller\Jobs\Common\Catalog\Import\Csv\Processor\Iface $object Decorated processor
44
	 */
45
	public function __construct( \Aimeos\MShop\ContextIface $context, array $mapping,
46
			\Aimeos\Controller\Jobs\Common\Catalog\Import\Csv\Processor\Iface $object = null )
47
	{
48
		parent::__construct( $context, $mapping, $object );
49
50
		/** controller/jobs/catalog/import/csv/processor/media/listtypes
51
		 * Names of the catalog list types for media that are updated or removed
52
		 *
53
		 * If you want to associate media items manually via the administration
54
		 * interface to catalogs and don't want these to be touched during the
55
		 * import, you can specify the catalog list types for these media
56
		 * that shouldn't be updated or removed.
57
		 *
58
		 * @param array|null List of catalog list type names or null for all
59
		 * @since 2018.04
60
		 * @see controller/jobs/catalog/import/csv/domains
61
		 * @see controller/jobs/catalog/import/csv/processor/attribute/listtypes
62
		 * @see controller/jobs/catalog/import/csv/processor/catalog/listtypes
63
		 * @see controller/jobs/catalog/import/csv/processor/catalog/listtypes
64
		 * @see controller/jobs/catalog/import/csv/processor/price/listtypes
65
		 * @see controller/jobs/catalog/import/csv/processor/text/listtypes
66
		 */
67
		$key = 'controller/jobs/catalog/import/csv/processor/media/listtypes';
68
		$this->listTypes = $context->config()->get( $key );
69
70
		if( $this->listTypes === null )
71
		{
72
			$this->listTypes = [];
73
			$manager = \Aimeos\MShop::create( $context, 'catalog/lists/type' );
74
75
			$search = $manager->filter()->slice( 0, 0x7fffffff );
76
			$search->setConditions( $search->compare( '==', 'catalog.lists.type.domain', 'media' ) );
77
78
			foreach( $manager->search( $search ) as $item ) {
79
				$this->listTypes[$item->getCode()] = $item->getCode();
80
			}
81
		}
82
		else
83
		{
84
			$this->listTypes = array_combine( $this->listTypes, $this->listTypes );
85
		}
86
87
88
		$manager = \Aimeos\MShop::create( $context, 'media/type' );
89
90
		$search = $manager->filter()->slice( 0, 0x7fffffff );
91
		$search->setConditions( $search->compare( '==', 'media.type.domain', 'catalog' ) );
92
93
		foreach( $manager->search( $search ) as $item ) {
94
			$this->types[$item->getCode()] = $item->getCode();
95
		}
96
	}
97
98
99
	/**
100
	 * Saves the catalog related data to the storage
101
	 *
102
	 * @param \Aimeos\MShop\Catalog\Item\Iface $catalog Catalog item with associated items
103
	 * @param array $data List of CSV fields with position as key and data as value
104
	 * @return array List of data which hasn't been imported
105
	 */
106
	public function process( \Aimeos\MShop\Catalog\Item\Iface $catalog, array $data ) : array
107
	{
108
		$context = $this->context();
109
		$manager = \Aimeos\MShop::create( $context, 'catalog' );
110
		$refManager = \Aimeos\MShop::create( $context, 'media' );
111
112
		/** controller/jobs/catalog/import/csv/separator
113
		 * Single separator character for multiple entries in one field of the import file
114
		 *
115
		 * The catalog importer is able split the content of a field from the import
116
		 * file into several entries based on the given separator character. Thus,
117
		 * you can create more compact import files and handle a variable range
118
		 * of entries better. The default separator character is a new line.
119
		 *
120
		 * '''Caution:''' The separator character must not be part of any entry
121
		 * in the field. Otherwise, you will get invalid entries and the importer
122
		 * may fail!
123
		 *
124
		 * @param string Single separator character
125
		 * @since 2018.04
126
		 * @see controller/jobs/catalog/import/csv/domains
127
		 * @see controller/jobs/supplier/import/csv/domains
128
		 */
129
		$separator = $context->config()->get( 'controller/jobs/catalog/import/csv/separator', "\n" );
130
131
		$listMap = [];
132
		$map = $this->getMappedChunk( $data, $this->getMapping() );
133
		$listItems = $catalog->getListItems( 'media', $this->listTypes );
134
135
		foreach( $listItems as $listItem )
136
		{
137
			if( ( $refItem = $listItem->getRefItem() ) !== null ) {
138
				$listMap[$refItem->getUrl()][$refItem->getType()][$listItem->getType()] = $listItem;
139
			}
140
		}
141
142
		foreach( $map as $pos => $list )
143
		{
144
			if( $this->checkEntry( $list ) === false ) {
145
				continue;
146
			}
147
148
			$type = trim( $this->val( $list, 'media.type', 'default' ) );
149
			$listtype = trim( $this->val( $list, 'catalog.lists.type', 'default' ) );
150
			$listConfig = $this->getListConfig( trim( $this->val( $list, 'catalog.lists.config', '' ) ) );
151
			$urls = explode( $separator, $this->val( $list, 'media.url', '' ) );
152
153
			foreach( $urls as $url )
154
			{
155
				if( isset( $listMap[$url][$type][$listtype] ) )
156
				{
157
					$listItem = $listMap[$url][$type][$listtype];
158
					$refItem = $listItem->getRefItem();
159
					unset( $listItems[$listItem->getId()] );
160
				}
161
				else
162
				{
163
					$listItem = $manager->createListItem()->setType( $listtype );
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

163
					$listItem = $manager->/** @scrutinizer ignore-call */ createListItem()->setType( $listtype );

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...
164
					$refItem = $refManager->create()->setType( $type );
165
				}
166
167
				$listItem = $listItem->setPosition( $pos++ )->fromArray( $list )->setConfig( $listConfig );
168
				$refItem = $refItem->setLabel( $url )->setPreview( $url )->fromArray( $list )->setUrl( $url );
169
170
				$catalog->addListItem( 'media', $listItem, $refItem );
171
			}
172
		}
173
174
		$catalog->deleteListItems( $listItems->toArray(), true );
175
176
		return $this->object()->process( $catalog, $data );
177
	}
178
179
180
	/**
181
	 * Checks if an entry can be used for updating a media item
182
	 *
183
	 * @param array $list Associative list of key/value pairs from the mapping
184
	 * @return bool True if valid, false if not
185
	 */
186
	protected function checkEntry( array $list ) : bool
187
	{
188
		if( $this->val( $list, 'media.url' ) === null ) {
189
			return false;
190
		}
191
192
		if( ( $type = trim( $this->val( $list, 'catalog.lists.type', '' ) ) ) && !isset( $this->listTypes[$type] ) )
193
		{
194
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'catalog list' );
195
			throw new \Aimeos\Controller\Jobs\Exception( $msg );
196
		}
197
198
		if( ( $type = trim( $this->val( $list, 'media.type', '' ) ) ) && !isset( $this->types[$type] ) )
199
		{
200
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'media' );
201
			throw new \Aimeos\Controller\Jobs\Exception( $msg );
202
		}
203
204
		return true;
205
	}
206
}
207