Completed
Push — master ( 325f51...2c9b99 )
by Aimeos
12:01
created

mshoplib/src/MShop/Common/Manager/ListRef/Base.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Metaways Infosystems GmbH, 2014
6
 * @copyright Aimeos (aimeos.org), 2015-2017
7
 * @package MShop
8
 * @subpackage Common
9
 */
10
11
12
namespace Aimeos\MShop\Common\Manager\ListRef;
13
14
15
/**
16
 * Abstract class for managers working with referenced list items.
17
 *
18
 * @package MShop
19
 * @subpackage Common
20
 */
21
abstract class Base
22
	extends \Aimeos\MShop\Common\Manager\Base
23
	implements \Aimeos\MShop\Common\Manager\ListRef\Iface
24
{
25
	private $typeIds = [];
26
27
	/**
28
	 * Updates the list items to the referenced items for the given domain and type
29
	 *
30
	 * @param \Aimeos\MShop\Common\Item\ListRef\Iface $item Item including references to other domain items
31
	 * @param array $map Associative list of reference ID as key and list of list item properties as key/value pairs
32
	 * @param string $domain Domain name of the referenced items
33
	 * @param string $type List type for the referenced items
34
	 */
35
	public function updateListItems( \Aimeos\MShop\Common\Item\ListRef\Iface $item, array $map, $domain, $type )
36
	{
37
		$listManager =  $this->getObject()->getSubManager( 'lists' );
38
39
		if( !isset( $this->typeIds[$domain][$type] ) )
40
		{
41
			$typeManager = $listManager->getSubManager( 'type' );
42
			$this->typeIds[$domain][$type] = $typeManager->findItem( $type, [], $domain )->getId();
43
		}
44
45
		$listItem = $listManager->createItem();
46
		$listItem->setTypeId( $this->typeIds[$domain][$type] );
47
		$listItem->setParentId( $item->getId() );
48
		$listItem->setDomain( $domain );
49
		$listItem->setStatus( 1 );
50
51
		$pos = 0;
52
		$listRef = $ids = [];
53
		$listItems = $item->getListItems( $domain, $type );
54
55
		foreach( $listItems as $id => $listItem ) {
56
			$listRef[$listItem->getRefId()] = $id;
57
		}
58
59
		foreach( $map as $id => $values )
60
		{
61
			$copy = $listItem;
62
63
			if( !isset( $listRef[$id] ) )
64
			{
65
				$copy->setId( null );
66
				$copy->setRefId( $id );
67
			}
68
			else
69
			{
70
				$copy = $listItems[$listRef[$id]];
71
				$ids[] = $listRef[$id];
72
			}
73
74
			if( is_array( $values ) ) {
75
				$copy->fromArray( $values );
76
			}
77
78
			$copy->setPosition( $pos++ );
79
			$listManager->saveItem( $copy, false );
80
		}
81
82
		$listManager->deleteItems( array_diff( $listRef, $ids ) );
83
	}
84
85
86
	/**
87
	 * Creates a new item for the specific manager.
88
	 *
89
	 * @param array $values Associative list of key/value pairs
90
	 * @param array $listItems List of items implementing \Aimeos\MShop\Common\Item\Lists\Iface
91
	 * @param array $refItems List of items implementing \Aimeos\MShop\Common\Item\Iface
92
	 * @return \Aimeos\MShop\Common\Item\Iface New item
93
	 */
94
	abstract protected function createItemBase( array $values = [], array $listItems = [], array $refItems = [] );
95
96
97
	/**
98
	 * Creates the items with address item, list items and referenced items.
99
	 *
100
	 * @param array $map Associative list of IDs as keys and the associative array of values
101
	 * @param array|null $domains List of domains to fetch list items and referenced items for or null for all
102
	 * @param string $prefix Domain prefix
103
	 * @param array $local Associative list of IDs as keys and the associative array of items as values
104
	 * @param array $local2 Associative list of IDs as keys and the associative array of items as values
105
	 * @return array List of items implementing \Aimeos\MShop\Common\Item\Iface
106
	 */
107
	protected function buildItems( array $map, $domains, $prefix, array $local = [], array $local2 = [] )
108
	{
109
		$items = $listItemMap = $refItemMap = $refIdMap = [];
110
111
		if( $domains === null || count( $domains ) > 0 )
112
		{
113
			$listItems = $this->getListItems( array_keys( $map ), $domains, $prefix );
114
115
			foreach( $listItems as $listItem )
116
			{
117
				$domain = $listItem->getDomain();
118
				$parentid = $listItem->getParentId();
119
120
				$listItemMap[$parentid][$domain][$listItem->getId()] = $listItem;
121
				$refIdMap[$domain][$listItem->getRefId()][] = $parentid;
122
			}
123
124
			$refItemMap = $this->getRefItems( $refIdMap );
125
		}
126
127
		foreach( $map as $id => $values )
128
		{
129
			$listItems = [];
130
			if( isset( $listItemMap[$id] ) ) {
131
				$listItems = $listItemMap[$id];
132
			}
133
134
			$refItems = [];
135
			if( isset( $refItemMap[$id] ) ) {
136
				$refItems = $refItemMap[$id];
137
			}
138
139
			$localItems = [];
140
			if( isset( $local[$id] ) ) {
141
				$localItems = $local[$id];
142
			}
143
144
			$localItems2 = [];
145
			if( isset( $local2[$id] ) ) {
146
				$localItems2 = $local2[$id];
147
			}
148
149
			$items[$id] = $this->createItemBase( $values, $listItems, $refItems, $localItems, $localItems2 );
150
		}
151
152
		return $items;
153
	}
154
155
156
	/**
157
	 * Returns the list items that belong to the given IDs.
158
	 *
159
	 * @param array $ids List of IDs
160
	 * @param array|null $domains List of domain names whose referenced items should be attached or null for all
161
	 * @param string $prefix Domain prefix
162
	 * @return array List of items implementing \Aimeos\MShop\Common\Lists\Item\Iface
163
	 */
164
	protected function getListItems( array $ids, $domains, $prefix )
165
	{
166
		$manager = $this->getObject()->getSubManager( 'lists' );
167
168
		$search = $manager->createSearch();
169
170
		$expr = [ $search->compare( '==', $prefix . '.lists.parentid', $ids ) ];
171
172
		if( $domains !== null ) {
173
			$expr[] = $search->compare( '==', $prefix . '.lists.domain', $domains );
174
		}
175
176
		$search->setConditions( $search->combine( '&&', $expr ) );
177
		$search->setSlice( 0, 0x7fffffff );
178
179
		return $manager->searchItems( $search );
180
	}
181
182
183
	/**
184
	 * Returns the referenced items for the given IDs.
185
	 *
186
	 * @param array $refIdMap Associative list of domain/ref-ID/parent-item-ID key/value pairs
187
	 * @return array Associative list of parent-item-ID/domain/items key/value pairs
188
	 */
189
	protected function getRefItems( array $refIdMap )
190
	{
191
		$items = [];
192
		$context = $this->getContext();
193
194
		foreach( $refIdMap as $domain => $list )
195
		{
196
			try
197
			{
198
				$manager = \Aimeos\MShop\Factory::createManager( $context, $domain );
199
200
				$search = $manager->createSearch();
201
				$search->setConditions( $search->compare( '==', str_replace( '/', '.', $domain ) . '.id', array_keys( $list ) ) );
202
				$search->setSlice( 0, 0x7fffffff );
203
204
				foreach( $manager->searchItems( $search ) as $id => $item )
205
				{
206
					foreach( $list[$id] as $parentId ) {
207
						$items[$parentId][$domain][$id] = $item;
208
					}
209
				}
210
			}
211
			catch( \Aimeos\MShop\Exception $e )
212
			{
213
				$logger = $context->getLogger();
214
				$logger->log( sprintf( 'Item referenced in domain "%1$s" not found: %2$s', $domain, $e->getMessage() ) );
215
				$logger->log( $e->getTraceAsString() );
216
			}
217
		}
218
219
		return $items;
220
	}
221
222
223
	/**
224
	 * Adds new, updates existing and deletes removed referenced items
225
	 *
226
	 * @param \Aimeos\MShop\Common\Item\ListRef\Iface $item Item with referenced items
227
	 * @param string $domain Domain of the calling manager
228
	 * @return \Aimeos\MShop\Common\Item\ListRef\Iface $item with updated referenced items
229
	 */
230
	protected function saveRefItems( \Aimeos\MShop\Common\Item\ListRef\Iface $item, $domain )
231
	{
232
		$rmListIds = $rmIds = [];
233
		$context = $this->getContext();
234
		$listManager = \Aimeos\MShop\Factory::createManager( $context, $domain . '/lists' );
235
236
		foreach( $item->getDeletedItems() as $listItem )
0 ignored issues
show
The method getDeletedItems() does not seem to exist on object<Aimeos\MShop\Common\Item\ListRef\Iface>.

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...
237
		{
238
			$rmListIds[] = $listItem->getId();
239
240
			if( ( $refItem = $listItem->getRefItem() ) !== null ) {
241
				$rmIds[$listItem->getDomain()][] = $refItem->getId();
242
			}
243
		}
244
245
		foreach( $rmIds as $refDomain => $ids ) {
246
			\Aimeos\MShop\Factory::createManager( $context, $refDomain )->deleteItems( $ids );
247
		}
248
249
		$listManager->deleteItems( $rmListIds );
250
251
		foreach( $item->getListItems( null, null, null, false ) as $listItem )
252
		{
253
			if( ( $refItem = $listItem->getRefItem() ) !== null )
254
			{
255
				if( $refItem instanceof \Aimeos\MShop\Common\Item\Domain\Iface ) {
256
					$refItem->setDomain( $domain );
257
				}
258
259
				$manager = \Aimeos\MShop\Factory::createManager( $context, $listItem->getDomain() );
260
				$refItem = $manager->saveItem( $refItem );
261
262
				$listItem->setRefId( $refItem->getId() );
263
			}
264
265
			if( $listItem->getParentId() != $item->getId() ) {
266
				$listItem->setId( null ); //create new list item if copied
267
			}
268
269
			$listItem->setParentId( $item->getId() );
270
			$listManager->saveItem( $listItem );
271
		}
272
273
		return $item;
274
	}
275
}
276