Passed
Push — master ( 9078e4...971ad4 )
by Aimeos
17:39 queued 14:54
created

Standard   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 178
Duplicated Lines 0 %

Importance

Changes 7
Bugs 0 Features 0
Metric Value
wmc 38
eloc 70
c 7
b 0
f 0
dl 0
loc 178
rs 9.36

3 Methods

Rating   Name   Duplication   Size   Complexity  
A transform() 0 16 4
C entry() 0 40 13
D map() 0 87 21
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2019-2021
6
 * @package MW
7
 * @subpackage View
8
 */
9
10
11
namespace Aimeos\MW\View\Helper\Jincluded;
12
13
14
/**
15
 * View helper class for generating "included" data used by JSON:API
16
 *
17
 * @package MW
18
 * @subpackage View
19
 */
20
class Standard extends \Aimeos\MW\View\Helper\Base implements Iface
21
{
22
	private $map;
23
24
25
	/**
26
	 * Returns the included data for the JSON:API response
27
	 *
28
	 * @param \Aimeos\MShop\Common\Item\Iface|\Aimeos\MShop\Common\Item\Iface[] $item Object or objects to generate the included data for
29
	 * @param array $fields Associative list of resource types as keys and field names to output as values
30
	 * @param array $fcn Associative list of resource types as keys and anonymous functions for generating the array entries as values
31
	 * @return array List of entries to include in the JSON:API response
32
	 */
33
	public function transform( $item, array $fields, array $fcn = [] )
34
	{
35
		$this->map = [];
36
37
		if( is_map( $item ) || is_array( $item ) )
38
		{
39
			foreach( $item as $entry ) {
40
				$this->entry( $entry, $fields, $fcn );
41
			}
42
		}
43
		else
44
		{
45
			$this->entry( $item, $fields, $fcn );
46
		}
47
48
		return $this->map;
49
	}
50
51
52
	/**
53
	 * Processes a single item to create the included data for the JSON:API response
54
	 *
55
	 * @param \Aimeos\MShop\Common\Item\Iface $item Object to generate the included data for
56
	 * @param array $fields Associative list of resource types as keys and field names to output as values
57
	 * @param array $fcn Associative list of resource types as keys and anonymous functions for generating the array entries as values
58
	 */
59
	protected function entry( \Aimeos\MShop\Common\Item\Iface $item, array $fields, array $fcn = [] )
60
	{
61
		if( $item instanceof \Aimeos\MShop\Common\Item\Tree\Iface )
62
		{
63
			foreach( $item->getChildren() as $catItem )
64
			{
65
				if( $catItem->isAvailable() ) {
66
					$this->map( $catItem, $fields, $fcn );
67
				}
68
			}
69
		}
70
71
		if( $item instanceof \Aimeos\MShop\Common\Item\AddressRef\Iface )
72
		{
73
			foreach( $item->getAddressItems() as $addrItem ) {
74
				$this->map( $addrItem, $fields, $fcn );
75
			}
76
		}
77
78
		if( $item instanceof \Aimeos\MShop\Common\Item\ListsRef\Iface )
79
		{
80
			foreach( $item->getListItems() as $listItem )
81
			{
82
				if( $refItem = $listItem->getRefItem() ) {
83
					$this->map( $refItem, $fields, $fcn );
84
				}
85
			}
86
		}
87
88
		if( $item instanceof \Aimeos\MShop\Common\Item\PropertyRef\Iface )
89
		{
90
			foreach( $item->getPropertyItems() as $propItem ) {
91
				$this->map( $propItem, $fields, $fcn );
92
			}
93
		}
94
95
		if( $item instanceof \Aimeos\MShop\Product\Item\Iface )
96
		{
97
			foreach( $item->getStockItems() as $stockItem ) {
98
				$this->map( $stockItem, $fields, $fcn );
99
			}
100
		}
101
	}
102
103
104
	/**
105
	 * Populates the map class property with the included data for the JSON:API response
106
	 *
107
	 * @param \Aimeos\MShop\Common\Item\Iface $item Object to generate the included data for
108
	 * @param array $fields Associative list of resource types as keys and field names to output as values
109
	 * @param array $fcn Associative list of resource types as keys and anonymous functions for generating the array entries as values
110
	 */
111
	protected function map( \Aimeos\MShop\Common\Item\Iface $item, array $fields, array $fcn = [] )
112
	{
113
		$id = $item->getId();
114
		$type = $item->getResourceType();
115
116
		if( isset( $this->map[$type][$id] ) || !$item->isAvailable() ) {
117
			return;
118
		}
119
120
		$attributes = $item->toArray();
121
122
		if( isset( $fields[$type] ) ) {
123
			$attributes = array_intersect_key( $attributes, $fields[$type] );
124
		}
125
126
		$entry = ['id' => $id, 'type' => $type, 'attributes' => $attributes];
127
128
		if( isset( $fcn[$type] ) && $fcn[$type] instanceof \Closure ) {
129
			$entry = $fcn[$type]( $item, $entry );
130
		}
131
132
		$this->map[$type][$id] = $entry; // first content, avoid infinite loops
133
134
		if( $item instanceof \Aimeos\MShop\Common\Item\Tree\Iface )
135
		{
136
			foreach( $item->getChildren() as $childItem )
137
			{
138
				if( $childItem->isAvailable() )
139
				{
140
					$rtype = $childItem->getResourceType();
141
					$rtype = ( $pos = strrpos( $rtype, '/' ) ) !== false ? substr( $rtype, $pos + 1 ) : $rtype;
142
					$entry['relationships'][$rtype]['data'][] = ['id' => $childItem->getId(), 'type' => $rtype];
143
					$this->map( $childItem, $fields, $fcn );
144
				}
145
			}
146
		}
147
148
		if( $item instanceof \Aimeos\MShop\Common\Item\ListsRef\Iface )
149
		{
150
			foreach( $item->getListItems() as $listItem )
151
			{
152
				if( ( $refItem = $listItem->getRefItem() ) !== null && $refItem->isAvailable() )
153
				{
154
					$ltype = $listItem->getResourceType();
155
					$rtype = $refItem->getResourceType();
156
					$attributes = $listItem->toArray();
157
158
					if( isset( $fields[$ltype] ) ) {
159
						$attributes = array_intersect_key( $attributes, $fields[$ltype] );
160
					}
161
162
					$data = ['id' => $refItem->getId(), 'type' => $rtype, 'attributes' => $attributes];
163
					$entry['relationships'][$rtype]['data'][] = $data;
164
					$this->map( $refItem, $fields, $fcn );
165
				}
166
			}
167
		}
168
169
		if( $item instanceof \Aimeos\MShop\Common\Item\PropertyRef\Iface )
170
		{
171
			foreach( $item->getPropertyItems() as $propItem )
172
			{
173
				if( $propItem->isAvailable() )
174
				{
175
					$propId = $propItem->getId();
176
					$rtype = $propItem->getResourceType();
177
					$entry['relationships'][$rtype]['data'][] = ['id' => $propId, 'type' => $rtype];
178
					$this->map( $propItem, $fields, $fcn );
179
				}
180
			}
181
		}
182
183
		if( $item instanceof \Aimeos\MShop\Product\Item\Iface )
184
		{
185
			foreach( $item->getStockItems() as $stockItem )
186
			{
187
				if( $stockItem->isAvailable() )
188
				{
189
					$stockId = $stockItem->getId();
190
					$rtype = $stockItem->getResourceType();
191
					$entry['relationships'][$rtype]['data'][] = ['id' => $stockId, 'type' => $rtype];
192
					$this->map( $stockItem, $fields, $fcn );
193
				}
194
			}
195
		}
196
197
		$this->map[$type][$id] = $entry; // full content
198
	}
199
}
200