Passed
Push — master ( cd805e...12ab2c )
by Aimeos
02:12
created

Standard::process()   C

Complexity

Conditions 12
Paths 57

Size

Total Lines 72
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 12
eloc 43
c 4
b 0
f 0
nc 57
nop 2
dl 0
loc 72
rs 6.9666

How to fix   Long Method    Complexity   

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-2018
6
 * @package Controller
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\Controller\Common\Product\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\Common\Product\Import\Csv\Processor\Base
22
	implements \Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface
23
{
24
	/** controller/common/product/import/csv/processor/media/name
25
	 * Name of the media processor implementation
26
	 *
27
	 * Use "Myname" if your class is named "\Aimeos\Controller\Common\Product\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 2015.10
32
	 * @category Developer
33
	 */
34
35
	private $listTypes;
36
	private $types = [];
37
	private $mimes = [];
38
39
40
	/**
41
	 * Initializes the object
42
	 *
43
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object
44
	 * @param array $mapping Associative list of field position in CSV as key and domain item key as value
45
	 * @param \Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface $object Decorated processor
46
	 */
47
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $mapping,
48
			\Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface $object = null )
49
	{
50
		parent::__construct( $context, $mapping, $object );
51
52
		$this->mimes = array_flip( $context->getConfig()->get( 'controller/common/media/standard/extensions', [] ) );
53
54
		/** controller/common/product/import/csv/processor/media/listtypes
55
		 * Names of the product list types for media that are updated or removed
56
		 *
57
		 * If you want to associate media items manually via the administration
58
		 * interface to products and don't want these to be touched during the
59
		 * import, you can specify the product list types for these media
60
		 * that shouldn't be updated or removed.
61
		 *
62
		 * @param array|null List of product list type names or null for all
63
		 * @since 2015.05
64
		 * @category Developer
65
		 * @category User
66
		 * @see controller/common/product/import/csv/domains
67
		 * @see controller/common/product/import/csv/processor/attribute/listtypes
68
		 * @see controller/common/product/import/csv/processor/catalog/listtypes
69
		 * @see controller/common/product/import/csv/processor/product/listtypes
70
		 * @see controller/common/product/import/csv/processor/price/listtypes
71
		 * @see controller/common/product/import/csv/processor/text/listtypes
72
		 */
73
		$key = 'controller/common/product/import/csv/processor/media/listtypes';
74
		$this->listTypes = $context->getConfig()->get( $key );
75
76
		if( $this->listTypes === null )
77
		{
78
			$this->listTypes = [];
79
			$manager = \Aimeos\MShop::create( $context, 'product/lists/type' );
80
81
			$search = $manager->createSearch()->setSlice( 0, 0x7fffffff );
82
			$search->setConditions( $search->compare( '==', 'product.lists.type.domain', 'media' ) );
83
84
			foreach( $manager->searchItems( $search ) as $item ) {
85
				$this->listTypes[$item->getCode()] = $item->getCode();
86
			}
87
		}
88
		else
89
		{
90
			$this->listTypes = array_flip( $this->listTypes );
91
		}
92
93
94
		$manager = \Aimeos\MShop::create( $context, 'media/type' );
95
96
		$search = $manager->createSearch()->setSlice( 0, 0x7fffffff );
97
		$search->setConditions( $search->compare( '==', 'media.type.domain', 'product' ) );
98
99
		foreach( $manager->searchItems( $search ) as $item ) {
100
			$this->types[$item->getCode()] = $item->getCode();
101
		}
102
	}
103
104
105
	/**
106
	 * Saves the product related data to the storage
107
	 *
108
	 * @param \Aimeos\MShop\Product\Item\Iface $product Product item with associated items
109
	 * @param array $data List of CSV fields with position as key and data as value
110
	 * @return array List of data which hasn't been imported
111
	 */
112
	public function process( \Aimeos\MShop\Product\Item\Iface $product, array $data )
113
	{
114
		$context = $this->getContext();
115
		$manager = \Aimeos\MShop::create( $context, 'media' );
116
		$listManager = \Aimeos\MShop::create( $context, 'product/lists' );
117
		$separator = $context->getConfig()->get( 'controller/common/product/import/csv/separator', "\n" );
118
119
		$listMap = [];
120
		$map = $this->getMappedChunk( $data, $this->getMapping() );
121
		$listItems = $product->getListItems( 'media', $this->listTypes );
122
		$cntl = \Aimeos\Controller\Common\Media\Factory::create( $context );
123
124
		foreach( $listItems as $listItem )
125
		{
126
			if( ( $refItem = $listItem->getRefItem() ) !== null ) {
127
				$listMap[$refItem->getUrl()][$refItem->getType()][$listItem->getType()] = $listItem;
128
			}
129
		}
130
131
		foreach( $map as $pos => $list )
132
		{
133
			if( $this->checkEntry( $list ) === false ) {
134
				continue;
135
			}
136
137
			$type = $this->getValue( $list, 'media.type', 'default' );
138
			$listtype = $this->getValue( $list, 'product.lists.type', 'default' );
139
			$urls = explode( $separator, $this->getValue( $list, 'media.url', '' ) );
140
			$preview = explode( $separator, $this->getValue( $list, 'media.preview', '' ) );
141
			$previews = explode( $separator, $this->getValue( $list, 'media.previews', '' ) );
142
143
			unset( $list['media.preview'], $list['media.previews'], $list['media.url'] );
144
145
			foreach( $urls as $idx => $url )
146
			{
147
				$url = trim( $url );
148
149
				if( isset( $listMap[$url][$type][$listtype] ) )
150
				{
151
					$listItem = $listMap[$url][$type][$listtype];
152
					$refItem = $listItem->getRefItem();
153
					unset( $listItems[$listItem->getId()] );
154
				}
155
				else
156
				{
157
					$listItem = $listManager->createItem()->setType( $listtype );
158
					$refItem = $manager->createItem()->setType( $type );
159
				}
160
161
				$ext = pathinfo( $url, PATHINFO_EXTENSION );
162
				if( isset( $this->mimes[$ext] ) ) {
163
					$refItem->setMimeType( $this->mimes[$ext] );
164
				}
165
166
				$listItem = $listItem->setPosition( $pos++ )->fromArray( $list );
167
				$refItem = $refItem->setLabel( $url )->fromArray( $list )->setUrl( $url );
168
169
				if( isset( $previews[$idx] ) && ( $map = json_decode( $previews[$idx], true ) ) !== null ) {
170
					$refItem->setPreviews( $map );
171
				} elseif( isset( $preview[$idx] ) ) {
172
					$refItem->setPreview( $preview[$idx] );
173
				} elseif( $refItem->isModified() ) {
174
					$refItem = $cntl->scale( $refItem );
175
				}
176
177
				$product->addListItem( 'media', $listItem, $refItem );
178
			}
179
		}
180
181
		$product->deleteListItems( $listItems, true );
182
183
		return $this->getObject()->process( $product, $data );
184
	}
185
186
187
	/**
188
	 * Checks if an entry can be used for updating a media item
189
	 *
190
	 * @param array $list Associative list of key/value pairs from the mapping
191
	 * @return boolean True if valid, false if not
192
	 */
193
	protected function checkEntry( array $list )
194
	{
195
		if( $this->getValue( $list, 'media.url' ) === null ) {
196
			return false;
197
		}
198
199
		if( ( $type = $this->getValue( $list, 'product.lists.type' ) ) && !isset( $this->listTypes[$type] ) )
200
		{
201
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'product list' );
202
			throw new \Aimeos\Controller\Common\Exception( $msg );
203
		}
204
205
		if( ( $type = $this->getValue( $list, 'media.type' ) ) && !isset( $this->types[$type] ) )
206
		{
207
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'media' );
208
			throw new \Aimeos\Controller\Common\Exception( $msg );
209
		}
210
211
		return true;
212
	}
213
}
214