Passed
Push — master ( 957e75...f11089 )
by Aimeos
04:27
created

Standard::checkEntry()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 9
c 2
b 0
f 0
nc 4
nop 1
dl 0
loc 19
rs 8.8333
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2015-2024
6
 * @package Controller
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\Controller\Jobs\Common\Product\Import\Csv\Processor\Price;
12
13
14
/**
15
 * Price 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/price/name
25
	 * Name of the price processor implementation
26
	 *
27
	 * Use "Myname" if your class is named "\Aimeos\Controller\Jobs\Common\Product\Import\Csv\Processor\Price\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 ?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\Product\Import\Csv\Processor\Iface $object Decorated processor
44
	 */
45
	public function __construct( \Aimeos\MShop\ContextIface $context, array $mapping,
46
			\Aimeos\Controller\Jobs\Common\Product\Import\Csv\Processor\Iface $object = null )
47
	{
48
		parent::__construct( $context, $mapping, $object );
49
50
		$config = $context->config();
51
52
		/** controller/jobs/product/import/csv/price/listtypes
53
		 * Names of the product list types for prices that are updated or removed
54
		 *
55
		 * If you want to associate price items manually via the administration
56
		 * interface to products and don't want these to be touched during the
57
		 * import, you can specify the product list types for these prices
58
		 * that shouldn't be updated or removed.
59
		 *
60
		 * @param array|null List of product list type names or null for all
61
		 * @since 2015.05
62
		 * @see controller/jobs/product/import/csv/domains
63
		 * @see controller/jobs/product/import/csv/separator
64
		 * @see controller/jobs/product/import/csv/attribute/listtypes
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/product/listtypes
68
		 * @see controller/jobs/product/import/csv/supplier/listtypes
69
		 * @see controller/jobs/product/import/csv/text/listtypes
70
		 */
71
		$default = $config->get( 'controller/jobs/product/import/csv/processor/price/listtypes' );
72
		$this->listTypes = $config->get( 'controller/jobs/product/import/csv/price/listtypes', $default );
73
74
		if( $this->listTypes === null )
75
		{
76
			$this->listTypes = [];
77
			$manager = \Aimeos\MShop::create( $context, 'product/lists/type' );
78
79
			$search = $manager->filter()->slice( 0, 0x7fffffff );
80
			$search->setConditions( $search->compare( '==', 'product.lists.type.domain', 'price' ) );
81
82
			foreach( $manager->search( $search ) as $item ) {
83
				$this->listTypes[$item->getCode()] = $item->getCode();
84
			}
85
		}
86
		else
87
		{
88
			$this->listTypes = array_combine( $this->listTypes, $this->listTypes );
89
		}
90
91
92
		$manager = \Aimeos\MShop::create( $context, 'price/type' );
93
94
		$search = $manager->filter()->slice( 0, 0x7fffffff );
95
		$search->setConditions( $search->compare( '==', 'price.type.domain', 'product' ) );
96
97
		foreach( $manager->search( $search ) as $item ) {
98
			$this->types[$item->getCode()] = $item->getCode();
99
		}
100
	}
101
102
103
	/**
104
	 * Saves the product 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
		$manager = \Aimeos\MShop::create( $this->context(), 'product' );
113
		$refManager = \Aimeos\MShop::create( $this->context(), 'price' );
114
115
		$listMap = [];
116
		$map = $this->getMappedChunk( $data, $this->getMapping() );
117
		$listItems = $product->getListItems( 'price', $this->listTypes, null, false );
118
119
		foreach( $listItems as $listItem )
120
		{
121
			if( ( $refItem = $listItem->getRefItem() ) !== null ) {
122
				$listMap[$refItem->getType()][$listItem->getType()][] = $listItem;
123
			}
124
		}
125
126
		foreach( $map as $pos => $list )
127
		{
128
			if( $this->checkEntry( $list ) === false ) {
129
				continue;
130
			}
131
132
			$type = trim( $this->val( $list, 'price.type', 'default' ) );
133
			$listtype = trim( $this->val( $list, 'product.lists.type', 'default' ) );
134
			$listConfig = $this->getListConfig( trim( $this->val( $list, 'product.lists.config', '' ) ) );
135
136
			$this->addType( 'product/lists/type', 'price', $listtype );
137
			$this->addType( 'price/type', 'product', $type );
138
139
			if( isset( $listMap[$type][$listtype] ) && !empty( $listMap[$type][$listtype] ) ) {
140
				$listItem = array_shift( $listMap[$type][$listtype] );
141
			} else {
142
				$listItem = $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

142
				/** @scrutinizer ignore-call */ 
143
    $listItem = $manager->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...
143
			}
144
145
			if( ( $refItem = $listItem->getRefItem() ) === null ) {
146
				$refItem = $refManager->create();
147
			}
148
149
			$listItem = $listItem->setType( $listtype )->setPosition( $pos )->fromArray( $list )->setConfig( $listConfig );
150
151
			$label = $this->val( $list, 'price.currencyid', '' ) . ' ' . $this->val( $list, 'price.value', '' );
152
			$refItem = $refItem->setType( $type )->setLabel( $label )->fromArray( $list );
153
154
			$product->addListItem( 'price', $listItem, $refItem );
155
156
			unset( $listItems[$listItem->getId()] );
157
		}
158
159
		$product->deleteListItems( $listItems->toArray(), true );
160
161
		return $this->object()->process( $product, $data );
162
	}
163
164
165
	/**
166
	 * Checks if an entry can be used for updating a price item
167
	 *
168
	 * @param array $list Associative list of key/value pairs from the mapping
169
	 * @return bool True if valid, false if not
170
	 */
171
	protected function checkEntry( array $list ) : bool
172
	{
173
		if( $this->val( $list, 'price.value' ) === null && $this->val( $list, 'price.currencyid' ) === null ) {
174
			return false;
175
		}
176
177
		if( ( $type = trim( $this->val( $list, 'product.lists.type', '' ) ) ) && !isset( $this->listTypes[$type] ) )
178
		{
179
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'product list' );
180
			throw new \Aimeos\Controller\Jobs\Exception( $msg );
181
		}
182
183
		if( ( $type = trim( $this->val( $list, 'price.type', '' ) ) ) && !isset( $this->types[$type] ) )
184
		{
185
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'price' );
186
			throw new \Aimeos\Controller\Jobs\Exception( $msg );
187
		}
188
189
		return true;
190
	}
191
}
192