Standard::entry()   C
last analyzed

Complexity

Conditions 15
Paths 96

Size

Total Lines 44
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
eloc 19
c 0
b 0
f 0
nc 96
nop 3
dl 0
loc 44
rs 5.9166

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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