Completed
Push — master ( b4e9b7...cff413 )
by Peter
11:12
created

RelatedOrderingAnnotation::init()   B

Complexity

Conditions 8
Paths 40

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 13.8319

Importance

Changes 0
Metric Value
dl 0
loc 48
ccs 11
cts 20
cp 0.55
rs 7.8901
c 0
b 0
f 0
cc 8
nc 40
nop 0
crap 13.8319
1
<?php
2
3
/**
4
 * This software package is licensed under AGPL or Commercial license.
5
 *
6
 * @package   maslosoft/mangan
7
 * @licence   AGPL or Commercial
8
 * @copyright Copyright (c) Piotr Masełkowski <[email protected]>
9
 * @copyright Copyright (c) Maslosoft
10
 * @copyright Copyright (c) Others as mentioned in code
11
 * @link      https://maslosoft.com/mangan/
12
 */
13
14
namespace Maslosoft\Mangan\Annotations;
15
16
use Maslosoft\Addendum\Helpers\ParamsExpander;
17
use Maslosoft\Mangan\Interfaces\SortInterface;
18
use Maslosoft\Mangan\Meta\ManganPropertyAnnotation;
19
use Maslosoft\Mangan\Meta\RelatedMeta;
20
21
/**
22
 * RelatedOrderingAnnotation
23
 *
24
 * Use this annotation to store order of related documents.
25
 * This should be used on same field as Related or RelatedArray annotations are applied.
26
 * This will apply incrementing values on selected field.
27
 *
28
 * Will also apply sort if not set.
29
 *
30
 * Compact notation:
31
 *
32
 * ```
33
 * @RelatedOrdering('order')
34
 * ```
35
 *
36
 * Compact notation with specified order:
37
 *
38
 * ```
39
 * @RelatedOrdering('order', SortInterface::SortAsc)
40
 * ```
41
 *
42
 * Extended notation:
43
 *
44
 * ```
45
 * @RelatedOrdering('orderField' = 'order', 'direction' = SortInterface::SortAsc)
46
 * ```
47
 *
48
 * @Conflicts('Embedded')
49
 * @Conflicts('EmbeddedArray')
50
 * @Conflicts('DbRef')
51
 * @Conflicts('DbRefArray')
52
 *
53
 * @see      SortInterface
54
 * @template RelatedOrdering('${orderField}')
55
 * @author   Piotr Maselkowski <pmaselkowski at gmail.com>
56
 */
57
class RelatedOrderingAnnotation extends ManganPropertyAnnotation
58
{
59
60
	public $value;
61
62
	public $orderField;
63
64
	public $direction;
65
66 1
	public function init()
67
	{
68 1
		$data = ParamsExpander::expand($this, ['orderField', 'direction']);
69 1
		if (empty($this->getEntity()->related))
70
		{
71
			$relMeta = new RelatedMeta();
72
		}
73
		else
74
		{
75 1
			$relMeta = $this->getEntity()->related;
76
		}
77
78 1
		foreach ($data as $key => $val)
79
		{
80 1
			$relMeta->$key = $val;
81
		}
82
83
		// Ensure array
84 1
		if (!is_array($relMeta->sort))
85
		{
86
			$relMeta->sort = [];
87
		}
88
89
		// Sort might be set by @RelatedAnnotation (defaults to _id)
90
		// or or by many @RelatedOrdering to sort on multiple fields.
91
		// Place current order in front if only sorted by _id
92
		// or append, placing _id at the end.
93 1
		if (count($relMeta->sort) === 1 && array_key_exists('_id', $relMeta->sort))
94
		{
95 1
			$relMeta->sort = array_merge([$relMeta->orderField => $relMeta->direction], $relMeta->sort);
96
		}
97
		else
98
		{
99
			$idSort = null;
100
			if (array_key_exists('_id', $relMeta->sort))
101
			{
102
				$idSort = $relMeta->sort['_id'];
103
				unset($relMeta->sort['_id']);
104
			}
105
			$relMeta->sort = array_merge($relMeta->sort, [$relMeta->orderField => $relMeta->direction]);
106
			if (null !== $idSort)
107
			{
108
				$relMeta->sort = array_merge($relMeta->sort, ['_id' => $idSort]);
109
			}
110
		}
111
112 1
		$this->getEntity()->related = $relMeta;
113 1
	}
114
115
}
116