Passed
Pull Request — master (#116)
by David
03:15
created

DirectForeignKeyMethodDescriptor::getForeignKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TheCodingMachine\TDBM\Utils;
6
7
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
8
use Doctrine\DBAL\Schema\Table;
9
use TheCodingMachine\TDBM\AlterableResultIterator;
10
use TheCodingMachine\TDBM\TDBMException;
11
use Zend\Code\Generator\DocBlock\Tag\ReturnTag;
12
use Zend\Code\Generator\MethodGenerator;
13
14
/**
15
 * Represents a method to get a list of beans from a direct foreign key pointing to our bean.
16
 */
17
class DirectForeignKeyMethodDescriptor implements MethodDescriptorInterface
18
{
19
    /**
20
     * @var ForeignKeyConstraint
21
     */
22
    private $fk;
23
24
    private $useAlternateName = false;
25
    /**
26
     * @var Table
27
     */
28
    private $mainTable;
29
    /**
30
     * @var NamingStrategyInterface
31
     */
32
    private $namingStrategy;
33
34
    /**
35
     * @param ForeignKeyConstraint $fk The foreign key pointing to our bean
36
     * @param Table $mainTable The main table that is pointed to
37
     * @param NamingStrategyInterface $namingStrategy
38
     */
39
    public function __construct(ForeignKeyConstraint $fk, Table $mainTable, NamingStrategyInterface $namingStrategy)
40
    {
41
        $this->fk = $fk;
42
        $this->mainTable = $mainTable;
43
        $this->namingStrategy = $namingStrategy;
44
    }
45
46
    /**
47
     * Returns the name of the method to be generated.
48
     *
49
     * @return string
50
     */
51
    public function getName() : string
52
    {
53
        if (!$this->useAlternateName) {
54
            return 'get'.TDBMDaoGenerator::toCamelCase($this->fk->getLocalTableName());
55
        } else {
56
            $methodName = 'get'.TDBMDaoGenerator::toCamelCase($this->fk->getLocalTableName()).'By';
57
58
            $camelizedColumns = array_map([TDBMDaoGenerator::class, 'toCamelCase'], $this->fk->getUnquotedLocalColumns());
59
60
            $methodName .= implode('And', $camelizedColumns);
61
62
            return $methodName;
63
        }
64
    }
65
66
    /**
67
     * Returns the name of the class that will be returned by the getter (short name).
68
     *
69
     * @return string
70
     */
71
    public function getBeanClassName(): string
72
    {
73
        return $this->namingStrategy->getBeanClassName($this->fk->getLocalTableName());
74
    }
75
76
    /**
77
     * Requests the use of an alternative name for this method.
78
     */
79
    public function useAlternativeName(): void
80
    {
81
        $this->useAlternateName = true;
82
    }
83
84
    /**
85
     * Returns the code of the method.
86
     *
87
     * @return MethodGenerator[]
88
     */
89
    public function getCode() : array
90
    {
91
        $beanClass = $this->getBeanClassName();
92
93
        $getter = new MethodGenerator($this->getName());
94
        $getter->setDocBlock(sprintf('Returns the list of %s pointing to this bean via the %s column.', $beanClass, implode(', ', $this->fk->getUnquotedLocalColumns())));
95
        $getter->getDocBlock()->setTag(new ReturnTag([
96
            $beanClass.'[]',
97
            '\\'.AlterableResultIterator::class
98
        ]));
99
        $getter->setReturnType(AlterableResultIterator::class);
100
101
        $code = sprintf(
102
            'return $this->retrieveManyToOneRelationshipsStorage(%s, %s, %s, %s);',
103
            var_export($this->fk->getLocalTableName(), true),
104
            var_export($this->fk->getName(), true),
105
            var_export($this->fk->getLocalTableName(), true),
106
            $this->getFilters($this->fk)
107
        );
108
109
        $getter->setBody($code);
110
111
        return [ $getter ];
112
    }
113
114
    private function getFilters(ForeignKeyConstraint $fk) : string
115
    {
116
        $counter = 0;
117
        $parameters = [];
118
119
        $fkForeignColumns = $fk->getUnquotedForeignColumns();
120
121
        foreach ($fk->getUnquotedLocalColumns() as $columnName) {
122
            $fkColumn = $fkForeignColumns[$counter];
123
            $parameters[] = sprintf('%s => $this->get(%s, %s)', var_export($fk->getLocalTableName().'.'.$columnName, true), var_export($fkColumn, true), var_export($this->fk->getForeignTableName(), true));
124
            ++$counter;
125
        }
126
        $parametersCode = '['.implode(', ', $parameters).']';
127
128
        return $parametersCode;
129
    }
130
131
    /**
132
     * Returns an array of classes that needs a "use" for this method.
133
     *
134
     * @return string[]
135
     */
136
    public function getUsedClasses() : array
137
    {
138
        return [$this->getBeanClassName()];
139
    }
140
141
    /**
142
     * Returns the code to past in jsonSerialize.
143
     *
144
     * @return string
145
     */
146
    public function getJsonSerializeCode() : string
147
    {
148
        return '';
149
    }
150
151
    /**
152
     * @return ForeignKeyConstraint
153
     */
154
    public function getForeignKey(): ForeignKeyConstraint
155
    {
156
        return $this->fk;
157
    }
158
159
    /**
160
     * Returns the table that is pointed to.
161
     * @return Table
162
     */
163
    public function getMainTable(): Table
164
    {
165
        return $this->mainTable;
166
    }
167
}
168