Completed
Pull Request — master (#25)
by
unknown
02:59
created

Standard::process()   B

Complexity

Conditions 7
Paths 15

Size

Total Lines 53
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 7
eloc 29
c 1
b 1
f 0
nc 15
nop 2
dl 0
loc 53
rs 8.5226

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