Completed
Push — master ( b7cc2d...e2c111 )
by Peter
14:18 queued 10:45
created

RelatedDecorator::write()   C

Complexity

Conditions 7
Paths 19

Size

Total Lines 50
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 7.0011

Importance

Changes 4
Bugs 1 Features 0
Metric Value
c 4
b 1
f 0
dl 0
loc 50
ccs 34
cts 35
cp 0.9714
rs 6.7273
cc 7
eloc 27
nc 19
nop 4
crap 7.0011
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 http://maslosoft.com/mangan/
12
 */
13
14
namespace Maslosoft\Mangan\Decorators;
15
16
use InvalidArgumentException;
17
use Maslosoft\Mangan\Criteria;
18
use Maslosoft\Mangan\EntityManager;
19
use Maslosoft\Mangan\Finder;
20
use Maslosoft\Mangan\Interfaces\Decorators\Property\DecoratorInterface;
21
use Maslosoft\Mangan\Interfaces\Transformators\TransformatorInterface;
22
use Maslosoft\Mangan\Meta\ManganMeta;
23
use Maslosoft\Mangan\Sort;
24
25
/**
26
 * RelatedRecorator
27
 *
28
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
29
 */
30
class RelatedDecorator implements DecoratorInterface
31
{
32
33 3
	public function read($model, $name, &$dbValue, $transformatorClass = TransformatorInterface::class)
34
	{
35 3
		$fieldMeta = ManganMeta::create($model)->field($name);
36 3
		$relMeta = $fieldMeta->related;
37 3
		$relModel = new $relMeta->class;
38 3
		$criteria = new Criteria(null, $relModel);
39 3
		if (empty($relMeta->join))
40 3
		{
41
			throw new InvalidArgumentException(sprintf('Parameter `join` is required for Related annotation, model `%s`, field `%s`', get_class($model), $name));
42
		}
43 3
		foreach ($relMeta->join as $source => $rel)
44
		{
45 3
			assert($model->$source !== null);
46 3
			$criteria->addCond($rel, '==', $model->$source);
47 3
		}
48 3
		$criteria->setSort(new Sort($relMeta->sort));
49 3
		if ($relMeta->single)
50 3
		{
51 1
			$model->$name = (new Finder($relModel))->find($criteria);
52 1
		}
53
		else
54
		{
55 2
			$model->$name = (new Finder($relModel))->findAll($criteria);
56
		}
57 3
	}
58
59 3
	public function write($model, $name, &$dbValues, $transformatorClass = TransformatorInterface::class)
60
	{
61 3
		if (!empty($model->$name))
62 3
		{
63
			// Store empty field to trigger decorator read
64 3
			$dbValues[$name] = null;
65
66 3
			$fieldMeta = ManganMeta::create($model)->field($name);
67 3
			$relMeta = $fieldMeta->related;
68 3
			if ($relMeta->single)
69 3
			{
70
				$models = [
71
					$model->$name
72 1
				];
73 1
			}
74
			else
75
			{
76 2
				$models = $model->$name;
77
			}
78 3
			$order = 0;
79 3
			foreach ($models as $relModel)
80
			{
81 3
				$fields = [];
82 3
				foreach ($relMeta->join as $source => $rel)
83
				{
84 3
					$fields[] = $rel;
85 3
					assert(isset($model->$source));
86 3
					$relModel->$rel = $model->$source;
87 3
				}
88 3
				if (!empty($relMeta->orderField))
89 3
				{
90 1
					$fields[] = $relMeta->orderField;
91 1
					$fields = array_unique($fields);
92 1
					$relModel->order = $order;
93 1
					$order++;
94 1
				}
95 3
				$em = new EntityManager($relModel);
96 3
				if ($relMeta->updatable)
97 3
				{
98
					// Update whole model
99 3
					$em->update();
100 3
				}
101
				else
102
				{
103
					// Update only relation info
104
					$em->update($fields);
105
				}
106 3
			}
107 3
		}
108 3
	}
109
110
}
111