Passed
Branch dev_2x (3e8772)
by Adrian
01:42
created

ManyToOneObserver   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 6
eloc 38
c 1
b 0
f 0
dl 0
loc 72
rs 10
1
<?php
2
declare(strict_types=1);
3
4
namespace Sirius\Orm\CodeGenerator\Observer\Relation;
5
6
use Nette\PhpGenerator\ClassType;
7
use Sirius\Orm\Blueprint\Mapper;
8
use Sirius\Orm\Blueprint\Relation;
9
use Sirius\Orm\Blueprint\Relation\ManyToMany;
10
use Sirius\Orm\Blueprint\Relation\ManyToOne;
11
use Sirius\Orm\CodeGenerator\Observer\Base;
12
use Sirius\Orm\Contract\Relation\ToOneInterface;
13
use Sirius\Orm\Helpers\Str;
14
15
class ManyToOneObserver extends Base implements ToOneInterface
16
{
17
18
    /**
19
     * @var ManyToOne
20
     */
21
    protected $relation;
22
23
    public function with(Relation $relation)
24
    {
25
        $clone         = clone($this);
26
        $clone->relation = $relation;
27
28
        return $clone;
29
    }
30
31
    public function observe(string $key, $object)
32
    {
33
        if ($key == $this->relation->getMapper()->getName() . '_base_entity') {
34
            return $this->observeBaseEntity($object);
35
        }
36
37
        return $object;
38
    }
39
40
    public function __toString()
41
    {
42
        return sprintf(
43
            'Observer for relation %s for mapper %s',
44
            $this->relation->getName(),
45
            $this->relation->getMapper()->getName()
46
        );
47
    }
48
49
    public function observeBaseEntity(ClassType $class)
50
    {
51
        $mapper        = $this->relation->getMapper();
52
        $name          = $this->relation->getName();
53
        $foreignMapper = $mapper->getOrm()->getMapper($this->relation->getForeignMapper());
54
        $type          = $foreignMapper->getEntityNamespace()
55
                         . '\\' . $foreignMapper->getEntityClass();
56
57
        /** @scrutinizer ignore-deprecated */ $class->getNamespace()->addUse($type, null, $type);
58
59
        $cast = $class->addMethod(Str::methodName($name . ' Attribute', 'cast'));
60
        $cast->setVisibility(ClassType::VISIBILITY_PROTECTED);
61
        $cast->addParameter('value');
62
        $cast->addBody('
63
if ($value === null) {
64
    return $value;
65
}        
66
        ');
67
        $cast->addBody(sprintf('return $value instanceOf %s ? $value : new %s((array) $value);', $type, $type));
68
69
        if ($mapper->getEntityStyle() === Mapper::ENTITY_STYLE_PROPERTIES) {
70
            $class->addComment(sprintf('@property %s|null $%s', $type, $name));
71
        } else {
72
            $setter = $class->addMethod(Str::methodName($name, 'set'));
73
            $setter->setVisibility(ClassType::VISIBILITY_PUBLIC);
74
            $setter->addParameter('value')
75
                   ->setType($type)
76
                   ->setNullable(true);
77
            $setter->addBody('$this->set(\'' . $name . '\', $value);');
78
79
            $getter = $class->addMethod(Str::methodName($name, 'get'));
80
            $getter->setVisibility(ClassType::VISIBILITY_PUBLIC);
81
            $getter->addBody('return $this->get(\'' . $name . '\');');
82
            $getter->setReturnType($type)
83
                   ->setReturnNullable(true);
84
        }
85
86
        return $class;
87
    }
88
}
89