Completed
Push — master ( 984043...a9b00f )
by Aimeos
02:00
created

Standard::checkEntry()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 8.6666
c 0
b 0
f 0
cc 7
nc 4
nop 1
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\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\Common\Product\Import\Csv\Processor\Base
22
	implements \Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface
23
{
24
	/** controller/common/product/import/csv/processor/price/name
25
	 * Name of the price processor implementation
26
	 *
27
	 * Use "Myname" if your class is named "\Aimeos\Controller\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
	 * @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\Product\Import\Csv\Processor\Iface $object Decorated processor
45
	 */
46
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, array $mapping,
47
			\Aimeos\Controller\Common\Product\Import\Csv\Processor\Iface $object = null )
48
	{
49
		parent::__construct( $context, $mapping, $object );
50
51
		/** controller/common/product/import/csv/processor/price/listtypes
52
		 * Names of the product list types for prices that are updated or removed
53
		 *
54
		 * If you want to associate price items manually via the administration
55
		 * interface to products and don't want these to be touched during the
56
		 * import, you can specify the product list types for these prices
57
		 * that shouldn't be updated or removed.
58
		 *
59
		 * @param array|null List of product list type names or null for all
60
		 * @since 2015.05
61
		 * @category Developer
62
		 * @category User
63
		 * @see controller/common/product/import/csv/domains
64
		 * @see controller/common/product/import/csv/processor/attribute/listtypes
65
		 * @see controller/common/product/import/csv/processor/catalog/listtypes
66
		 * @see controller/common/product/import/csv/processor/media/listtypes
67
		 * @see controller/common/product/import/csv/processor/product/listtypes
68
		 * @see controller/common/product/import/csv/processor/text/listtypes
69
		 */
70
		$key = 'controller/common/product/import/csv/processor/price/listtypes';
71
		$this->listTypes = $context->getConfig()->get( $key );
72
73
		if( $this->listTypes === null )
74
		{
75
			$this->listTypes = [];
76
			$manager = \Aimeos\MShop\Factory::createManager( $context, 'product/lists/type' );
77
78
			$search = $manager->createSearch()->setSlice( 0, 0x7fffffff );
79
			$search->setConditions( $search->compare( '==', 'product.lists.type.domain', 'price' ) );
80
81
			foreach( $manager->searchItems( $search ) as $item ) {
82
				$this->listTypes[$item->getCode()] = $item->getCode();
83
			}
84
		}
85
86
87
		$manager = \Aimeos\MShop\Factory::createManager( $context, 'price/type' );
88
89
		$search = $manager->createSearch()->setSlice( 0, 0x7fffffff );
90
		$search->setConditions( $search->compare( '==', 'price.type.domain', 'product' ) );
91
92
		foreach( $manager->searchItems( $search ) as $item ) {
93
			$this->types[$item->getCode()] = $item->getCode();
94
		}
95
	}
96
97
98
	/**
99
	 * Saves the product related data to the storage
100
	 *
101
	 * @param \Aimeos\MShop\Product\Item\Iface $product Product item with associated items
102
	 * @param array $data List of CSV fields with position as key and data as value
103
	 * @return array List of data which hasn't been imported
104
	 */
105
	public function process( \Aimeos\MShop\Product\Item\Iface $product, array $data )
106
	{
107
		$listManager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'product/lists' );
108
		$manager = \Aimeos\MShop\Factory::createManager( $this->getContext(), 'price' );
109
110
		$listMap = [];
111
		$map = $this->getMappedChunk( $data, $this->getMapping() );
112
		$listItems = $product->getListItems( 'price', $this->listTypes );
113
114
		foreach( $listItems as $listItem )
115
		{
116
			if( ( $refItem = $listItem->getRefItem() ) !== null ) {
117
				$listMap[ $refItem->getValue() ][ $refItem->getType() ][ $listItem->getType() ] = $listItem;
118
			}
119
		}
120
121
		foreach( $map as $pos => $list )
122
		{
123
			if( $this->checkEntry( $list ) === false ) {
124
				continue;
125
			}
126
127
			$value = trim( isset( $list['price.value'] ) ? $list['price.value'] : '0.00' );
128
			$type = trim( isset( $list['price.type'] ) ? $list['price.type'] : 'default' );
129
			$typecode = trim( isset( $list['product.lists.type'] ) ? $list['product.lists.type'] : 'default' );
130
131
			if( isset( $listMap[$value][$type][$typecode] ) )
132
			{
133
				$listItem = $listMap[$value][$type][$typecode];
134
				$refItem = $listItem->getRefItem();
135
				unset( $listItems[ $listItem->getId() ] );
136
			}
137
			else
138
			{
139
				$listItem = $listManager->createItem( $typecode, 'price' );
0 ignored issues
show
Unused Code introduced by
The call to Iface::createItem() has too many arguments starting with $typecode.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
140
				$refItem = $manager->createItem( $type, 'product' );
0 ignored issues
show
Unused Code introduced by
The call to Iface::createItem() has too many arguments starting with $type.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
141
			}
142
143
144
			$refItem->fromArray( $this->addItemDefaults( $list ) );
145
			$listItem->fromArray( $this->addListItemDefaults( $list, $pos ) );
146
147
			$product->addListItem( 'price', $listItem, $refItem );
148
		}
149
150
		$product->deleteListItems( $listItems, true );
151
152
		return $this->getObject()->process( $product, $data );
153
	}
154
155
156
	/**
157
	 * Adds the text item default values and returns the resulting array
158
	 *
159
	 * @param array $list Associative list of domain item keys and their values, e.g. "price.status" => 1
160
	 * @return array Given associative list enriched by default values if they were not already set
161
	 */
162
	protected function addItemDefaults( array $list )
163
	{
164
		if( !isset( $list['price.label'] ) ) {
165
			$list['price.label'] = $list['price.currencyid'] . ' ' . $list['price.value'];
166
		}
167
168
		if( !isset( $list['price.status'] ) ) {
169
			$list['price.status'] = 1;
170
		}
171
172
		return $list;
173
	}
174
175
176
	/**
177
	 * Checks if an entry can be used for updating a media item
178
	 *
179
	 * @param array $list Associative list of key/value pairs from the mapping
180
	 * @return boolean True if valid, false if not
181
	 */
182
	protected function checkEntry( array $list )
183
	{
184
		if( !isset( $list['price.value'] ) || trim( $list['price.value'] ) === '' ) {
185
			return false;
186
		}
187
188
		if( isset( $list['product.lists.type'] ) && !in_array( trim( $list['product.lists.type'] ), $this->listTypes ) )
189
		{
190
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $list['product.lists.type'], 'product list' );
191
			throw new \Aimeos\Controller\Common\Exception( $msg );
192
		}
193
194
		if( isset( $list['price.type'] ) && !in_array( trim( $list['price.type'] ), $this->types ) )
195
		{
196
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $list['price.type'], 'price' );
197
			throw new \Aimeos\Controller\Common\Exception( $msg );
198
		}
199
200
		return true;
201
	}
202
}
203