Passed
Push — master ( 875047...0bbe95 )
by Aimeos
02:24
created

Standard   A

Complexity

Total Complexity 37

Size/Duplication

Total Lines 175
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 37
eloc 66
c 2
b 0
f 0
dl 0
loc 175
rs 9.44

3 Methods

Rating   Name   Duplication   Size   Complexity  
A transform() 0 25 5
C entry() 0 49 16
C map() 0 65 16
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2019
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_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
		$result = [];
49
50
		foreach( $this->map as $list )
51
		{
52
			foreach( $list as $entry ) {
53
				$result[] = $entry;
54
			}
55
		}
56
57
		return $result;
58
	}
59
60
61
	/**
62
	 * Processes a single item to create the included data for the JSON:API response
63
	 *
64
	 * @param \Aimeos\MShop\Common\Item\Iface $item Object to generate the included data for
65
	 * @param array $fields Associative list of resource types as keys and field names to output as values
66
	 * @param array $fcn Associative list of resource types as keys and anonymous functions for generating the array entries as values
67
	 */
68
	protected function entry( \Aimeos\MShop\Common\Item\Iface $item, array $fields, array $fcn = [] )
69
	{
70
		if( $item instanceof \Aimeos\MShop\Common\Item\Tree\Iface )
71
		{
72
			foreach( $item->getChildren() as $catItem )
73
			{
74
				if( $catItem->isAvailable() ) {
75
					$this->map( $catItem, $fields, $fcn );
76
				}
77
			}
78
		}
79
80
		if( $item instanceof \Aimeos\MShop\Common\Item\AddressRef\Iface )
81
		{
82
			foreach( $item->getAddressItems() as $addrItem ) {
83
				$this->map( $addrItem, $fields, $fcn );
84
			}
85
		}
86
87
		if( $item instanceof \Aimeos\MShop\Common\Item\ListRef\Iface )
88
		{
89
			foreach( $item->getListItems() as $listItem )
90
			{
91
				if( ( $refItem = $listItem->getRefItem() ) !== null ) {
92
					$this->map( $refItem, $fields, $fcn );
93
				}
94
			}
95
		}
96
97
		if( $item instanceof \Aimeos\MShop\Common\Item\PropertyRef\Iface )
98
		{
99
			foreach( $item->getPropertyItems() as $propItem ) {
100
				$this->map( $propItem, $fields, $fcn );
101
			}
102
		}
103
104
		if( $item instanceof \Aimeos\MShop\Product\Item\Iface )
105
		{
106
			foreach( $item->getCatalogItems() as $catItem )
107
			{
108
				if( $catItem->isAvailable() ) {
109
					$this->map( $catItem, $fields, $fcn );
110
				}
111
			}
112
113
			foreach( $item->getSupplierItems() as $supItem )
114
			{
115
				if( $supItem->isAvailable() ) {
116
					$this->map( $supItem, $fields, $fcn );
117
				}
118
			}
119
		}
120
	}
121
122
123
	/**
124
	 * Populates the map class property with the included data for the JSON:API response
125
	 *
126
	 * @param \Aimeos\MShop\Common\Item\Iface $item Object to generate the included data for
127
	 * @param array $fields Associative list of resource types as keys and field names to output as values
128
	 * @param array $fcn Associative list of resource types as keys and anonymous functions for generating the array entries as values
129
	 */
130
	protected function map( \Aimeos\MShop\Common\Item\Iface $item, array $fields, array $fcn = [] )
131
	{
132
		$id = $item->getId();
133
		$type = $item->getResourceType();
134
135
		if( isset( $this->map[$type][$id] ) || !$item->isAvailable() ) {
136
			return;
137
		}
138
139
		$attributes = $item->toArray();
140
141
		if( isset( $fields[$type] ) ) {
142
			$attributes = array_intersect_key( $attributes, $fields[$type] );
143
		}
144
145
		$entry = ['id' => $id, 'type' => $type, 'attributes' => $attributes];
146
147
		if( isset( $fcn[$type] ) && $fcn[$type] instanceof \Closure ) {
148
			$entry = $fcn[$type]( $item, $entry );
149
		}
150
151
		$this->map[$type][$id] = $entry; // first content, avoid infinite loops
152
153
		if( $item instanceof \Aimeos\MShop\Common\Item\Tree\Iface )
154
		{
155
			foreach( $item->getChildren() as $childItem )
156
			{
157
				if( $childItem->isAvailable() )
158
				{
159
					$rtype = $childItem->getResourceType();
160
					$entry['relationships'][$rtype]['data'][] = ['id' => $childItem->getId(), 'type' => $rtype];
161
					$this->map( $childItem, $fields, $fcn );
162
				}
163
			}
164
		}
165
166
		if( $item instanceof \Aimeos\MShop\Common\Item\ListRef\Iface )
167
		{
168
			foreach( $item->getListItems() as $listItem )
169
			{
170
				if( ( $refItem = $listItem->getRefItem() ) !== null && $refItem->isAvailable() )
171
				{
172
					$rtype = $refItem->getResourceType();
173
					$data = ['id' => $refItem->getId(), 'type' => $rtype, 'attributes' => $listItem->toArray()];
174
					$entry['relationships'][$rtype]['data'][] = $data;
175
					$this->map( $refItem, $fields, $fcn );
176
				}
177
			}
178
		}
179
180
		if( $item instanceof \Aimeos\MShop\Common\Item\PropertyRef\Iface )
181
		{
182
			foreach( $item->getPropertyItems() as $propItem )
183
			{
184
				if( $propItem->isAvailable() )
185
				{
186
					$propId = $propItem->getId();
187
					$rtype = $propItem->getResourceType();
188
					$entry['relationships'][$rtype]['data'][] = ['id' => $propId, 'type' => $rtype];
189
					$this->map( $propItem, $fields, $fcn );
190
				}
191
			}
192
		}
193
194
		$this->map[$type][$id] = $entry; // full content
195
	}
196
}
197