Completed
Push — master ( 480c88...01d8db )
by Valentin
08:43
created

AddInit::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 1
nc 1
nop 5
1
<?php
2
declare(strict_types=1);
3
4
namespace Cycle\ORM\Promise\Visitor;
5
6
use Cycle\ORM\Promise\Expressions;
7
use PhpParser\Builder;
8
use PhpParser\Node;
9
use PhpParser\NodeVisitorAbstract;
10
11
/**
12
 * Add constructor
13
 */
14
class AddInit extends NodeVisitorAbstract
15
{
16
    /** @var string */
17
    private $property;
18
19
    /** @var string */
20
    private $type;
21
22
    /** @var array */
23
    private $dependencies;
24
25
    /** @var string */
26
    private $unsetPropertiesConst;
27
28
    /** @var string */
29
    private $initMethod;
30
31
    public function __construct(
32
        string $property,
33
        string $propertyType,
34
        array $dependencies,
35
        string $unsetPropertiesConst,
36
        string $initMethod
37
    ) {
38
        $this->property = $property;
39
        $this->type = $propertyType;
40
        $this->dependencies = $dependencies;
41
        $this->unsetPropertiesConst = $unsetPropertiesConst;
42
        $this->initMethod = $initMethod;
43
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function leaveNode(Node $node)
49
    {
50
        if ($node instanceof Node\Stmt\Class_) {
51
            $method = new Builder\Method($this->initMethod);
52
            $method->makePublic();
53
            $method->addParam((new Builder\Param('orm'))->setType('ORMInterface'));
54
            $method->addParam((new Builder\Param('role'))->setType('string'));
55
            $method->addParam((new Builder\Param('scope'))->setType('array'));
56
            $method->addStmt($this->unsetProperties());
57
            $method->addStmt($this->assignResolverProperty());
58
59
            $node->stmts[] = $method->getNode();
60
        }
61
62
        return null;
63
    }
64
65
    private function unsetProperties(): Node\Stmt\Foreach_
66
    {
67
        $prop = new Node\Expr\ClassConstFetch(new Node\Name('self'), $this->unsetPropertiesConst);
68
        $foreach = new Node\Stmt\Foreach_($prop, new Node\Expr\Variable('property'));
69
        $foreach->stmts[] = Expressions::unsetFunc('this', '{$property}');
70
71
        return $foreach;
72
    }
73
74
    private function assignResolverProperty(): Node\Stmt\Expression
75
    {
76
        $prop = new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), $this->property);
77
        $instance = new Node\Expr\New_(new Node\Name($this->type), $this->packResolverPropertyArgs());
78
79
        return new Node\Stmt\Expression(new Node\Expr\Assign($prop, $instance));
80
    }
81
82
    private function packResolverPropertyArgs(): array
83
    {
84
        $args = [];
85
        foreach ($this->dependencies as $name => $type) {
86
            $args[] = new Node\Arg(new Node\Expr\Variable($name));
87
        }
88
89
        return $args;
90
    }
91
}