Passed
Push — master ( 677585...094812 )
by Aimeos
02:37
created

Standard::getListItems()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 9
c 2
b 0
f 0
nc 2
nop 2
dl 0
loc 16
rs 9.9666
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2020-2021
6
 * @package Controller
7
 * @subpackage Common
8
 */
9
10
11
namespace Aimeos\Controller\Common\Product\Import\Csv\Processor\Supplier;
12
13
14
/**
15
 * Supplier 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/supplier/name
25
	 * Name of the supplier processor implementation
26
	 *
27
	 * Use "Myname" if your class is named "\Aimeos\Controller\Common\Product\Import\Csv\Processor\Supplier\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 $cache;
36
	private $listTypes;
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/supplier/listtypes
52
		 * Names of the supplier list types that are updated or removed
53
		 *
54
		 * Aimeos offers associated items like "bought together" suppliers that
55
		 * are automatically generated by other job controllers. These relations
56
		 * shouldn't normally be overwritten or deleted by default during the
57
		 * import and this confiuration option enables you to specify the list
58
		 * types that should be updated or removed if not available in the import
59
		 * file.
60
		 *
61
		 * Contrary, if you don't generate any relations automatically in the
62
		 * shop and want to import those relations too, you can set the option
63
		 * to null to update all associated items.
64
		 *
65
		 * @param array|null List of supplier list type names or null for all
66
		 * @since 2020.07
67
		 * @category Developer
68
		 * @category User
69
		 * @see controller/common/product/import/csv/domains
70
		 * @see controller/common/product/import/csv/processor/attribute/listtypes
71
		 * @see controller/common/product/import/csv/processor/supplier/listtypes
72
		 * @see controller/common/product/import/csv/processor/media/listtypes
73
		 * @see controller/common/product/import/csv/processor/price/listtypes
74
		 * @see controller/common/product/import/csv/processor/text/listtypes
75
		 */
76
		$key = 'controller/common/product/import/csv/processor/supplier/listtypes';
77
		$this->listTypes = $context->config()->get( $key, ['default', 'promotion'] );
78
79
		if( $this->listTypes === null )
80
		{
81
			$this->listTypes = [];
82
			$manager = \Aimeos\MShop::create( $context, 'product/lists/type' );
83
84
			$search = $manager->filter()->slice( 0, 0x7fffffff );
85
			$search->setConditions( $search->compare( '==', 'product.lists.type.domain', 'supplier' ) );
86
87
			foreach( $manager->search( $search ) as $item ) {
88
				$this->listTypes[$item->getCode()] = $item->getCode();
89
			}
90
		}
91
		else
92
		{
93
			$this->listTypes = array_flip( $this->listTypes );
94
		}
95
96
		$this->cache = $this->getCache( 'supplier' );
97
	}
98
99
100
	/**
101
	 * Saves the supplier related data to the storage
102
	 *
103
	 * @param \Aimeos\MShop\Product\Item\Iface $product Product item with associated items
104
	 * @param array $data List of CSV fields with position as key and data as value
105
	 * @return array List of data which has not been imported
106
	 */
107
	public function process( \Aimeos\MShop\Product\Item\Iface $product, array $data ) : array
108
	{
109
		$context = $this->context();
110
		$logger = $context->logger();
111
		$manager = \Aimeos\MShop::create( $context, 'product' );
112
		$separator = $context->config()->get( 'controller/common/product/import/csv/separator', "\n" );
113
114
		$listItems = $product->getListItems( 'supplier', null, null, false );
115
116
		foreach( $this->getMappedChunk( $data, $this->getMapping() ) as $list )
117
		{
118
			if( $this->checkEntry( $list ) === false ) {
119
				continue;
120
			}
121
122
			$listtype = $this->val( $list, 'product.lists.type', 'default' );
123
			$this->addType( 'product/lists/type', 'supplier', $listtype );
124
125
			foreach( explode( $separator, $this->val( $list, 'supplier.code', '' ) ) as $code )
126
			{
127
				$code = trim( $code );
128
129
				if( ( $supid = $this->cache->get( $code ) ) === null )
130
				{
131
					$msg = 'No supplier for code "%1$s" available when importing product with code "%2$s"';
132
					$logger->warning( sprintf( $msg, $code, $product->getCode() ), 'import/csv/product' );
133
					continue;
134
				}
135
136
				if( ( $listItem = $product->getListItem( 'supplier', $listtype, $supid ) ) === null ) {
137
					$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

137
					$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...
138
				} else {
139
					unset( $listItems[$listItem->getId()] );
140
				}
141
142
				$listItem = $listItem->fromArray( $list )->setRefId( $supid );
143
				$product->addListItem( 'supplier', $listItem );
144
			}
145
		}
146
147
		$product->deleteListItems( $listItems->toArray() );
148
149
		return $this->object()->process( $product, $data );
150
	}
151
152
153
	/**
154
	 * Checks if an entry can be used for updating a media item
155
	 *
156
	 * @param array $list Associative list of key/value pairs from the mapping
157
	 * @return bool True if valid, false if not
158
	 */
159
	protected function checkEntry( array $list ) : bool
160
	{
161
		if( $this->val( $list, 'supplier.code' ) === null ) {
162
			return false;
163
		}
164
165
		if( ( $type = $this->val( $list, 'product.lists.type' ) ) && !isset( $this->listTypes[$type] ) )
166
		{
167
			$msg = sprintf( 'Invalid type "%1$s" (%2$s)', $type, 'product list' );
168
			throw new \Aimeos\Controller\Common\Exception( $msg );
169
		}
170
171
		return true;
172
	}
173
}
174