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

PivotTableMethodsDescriptor::getRemoteFk()   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
declare(strict_types=1);
3
4
namespace TheCodingMachine\TDBM\Utils;
5
6
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
7
use Doctrine\DBAL\Schema\Table;
8
use function sprintf;
9
use Zend\Code\Generator\DocBlock\Tag\ParamTag;
10
use Zend\Code\Generator\DocBlock\Tag\ReturnTag;
11
use Zend\Code\Generator\MethodGenerator;
12
use Zend\Code\Generator\ParameterGenerator;
13
14
class PivotTableMethodsDescriptor implements MethodDescriptorInterface
15
{
16
    /**
17
     * @var Table
18
     */
19
    private $pivotTable;
20
21
    private $useAlternateName = false;
22
23
    /**
24
     * @var ForeignKeyConstraint
25
     */
26
    private $localFk;
27
28
    /**
29
     * @var ForeignKeyConstraint
30
     */
31
    private $remoteFk;
32
    /**
33
     * @var NamingStrategyInterface
34
     */
35
    private $namingStrategy;
36
    /**
37
     * @var string
38
     */
39
    private $beanNamespace;
40
41
    /**
42
     * @param Table $pivotTable The pivot table
43
     * @param ForeignKeyConstraint $localFk
44
     * @param ForeignKeyConstraint $remoteFk
45
     * @param NamingStrategyInterface $namingStrategy
46
     */
47
    public function __construct(Table $pivotTable, ForeignKeyConstraint $localFk, ForeignKeyConstraint $remoteFk, NamingStrategyInterface $namingStrategy, string $beanNamespace)
48
    {
49
        $this->pivotTable = $pivotTable;
50
        $this->localFk = $localFk;
51
        $this->remoteFk = $remoteFk;
52
        $this->namingStrategy = $namingStrategy;
53
        $this->beanNamespace = $beanNamespace;
54
    }
55
56
    /**
57
     * Requests the use of an alternative name for this method.
58
     */
59
    public function useAlternativeName(): void
60
    {
61
        $this->useAlternateName = true;
62
    }
63
64
    /**
65
     * Returns the name of the method to be generated.
66
     *
67
     * @return string
68
     */
69
    public function getName() : string
70
    {
71
        if (!$this->useAlternateName) {
72
            return 'get'.TDBMDaoGenerator::toCamelCase($this->remoteFk->getForeignTableName());
73
        } else {
74
            return 'get'.TDBMDaoGenerator::toCamelCase($this->remoteFk->getForeignTableName()).'By'.TDBMDaoGenerator::toCamelCase($this->pivotTable->getName());
75
        }
76
    }
77
78
    /**
79
     * Returns the name of the class that will be returned by the getter (short name).
80
     *
81
     * @return string
82
     */
83
    public function getBeanClassName(): string
84
    {
85
        return $this->namingStrategy->getBeanClassName($this->remoteFk->getForeignTableName());
86
    }
87
88
    /**
89
     * Returns the plural name.
90
     *
91
     * @return string
92
     */
93
    private function getPluralName() : string
94
    {
95
        if (!$this->useAlternateName) {
96
            return TDBMDaoGenerator::toCamelCase($this->remoteFk->getForeignTableName());
97
        } else {
98
            return TDBMDaoGenerator::toCamelCase($this->remoteFk->getForeignTableName()).'By'.TDBMDaoGenerator::toCamelCase($this->pivotTable->getName());
99
        }
100
    }
101
102
    /**
103
     * Returns the singular name.
104
     *
105
     * @return string
106
     */
107
    private function getSingularName() : string
108
    {
109
        if (!$this->useAlternateName) {
110
            return TDBMDaoGenerator::toCamelCase(TDBMDaoGenerator::toSingular($this->remoteFk->getForeignTableName()));
111
        } else {
112
            return TDBMDaoGenerator::toCamelCase(TDBMDaoGenerator::toSingular($this->remoteFk->getForeignTableName())).'By'.TDBMDaoGenerator::toCamelCase($this->pivotTable->getName());
113
        }
114
    }
115
116
    /**
117
     * Returns the code of the method.
118
     *
119
     * @return MethodGenerator[]
120
     */
121
    public function getCode() : array
122
    {
123
        $singularName = $this->getSingularName();
124
        $pluralName = $this->getPluralName();
125
        $remoteBeanName = $this->getBeanClassName();
126
        $variableName = TDBMDaoGenerator::toVariableName($remoteBeanName);
127
        $fqcnRemoteBeanName = '\\'.$this->beanNamespace.'\\'.$remoteBeanName;
128
        $pluralVariableName = $variableName.'s';
129
130
        $getter = new MethodGenerator('get'.$pluralName);
131
        $getter->setDocBlock(sprintf('Returns the list of %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
132
        $getter->getDocBlock()->setTag(new ReturnTag([ $fqcnRemoteBeanName.'[]' ]));
133
        $getter->setReturnType('array');
134
        $getter->setBody(sprintf('return $this->_getRelationships(%s);', var_export($this->remoteFk->getLocalTableName(), true)));
135
136
137
        $adder = new MethodGenerator('add'.$singularName);
138
        $adder->setDocBlock(sprintf('Adds a relationship with %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
139
        $adder->getDocBlock()->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]));
140
        $adder->setReturnType('void');
141
        $adder->setParameter(new ParameterGenerator($variableName, $fqcnRemoteBeanName));
142
        $adder->setBody(sprintf('$this->addRelationship(%s, $%s);', var_export($this->remoteFk->getLocalTableName(), true), $variableName));
143
144
        $remover = new MethodGenerator('remove'.$singularName);
145
        $remover->setDocBlock(sprintf('Deletes the relationship with %s associated to this bean via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
146
        $remover->getDocBlock()->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]));
147
        $remover->setReturnType('void');
148
        $remover->setParameter(new ParameterGenerator($variableName, $fqcnRemoteBeanName));
149
        $remover->setBody(sprintf('$this->_removeRelationship(%s, $%s);', var_export($this->remoteFk->getLocalTableName(), true), $variableName));
150
151
        $has = new MethodGenerator('has'.$singularName);
152
        $has->setDocBlock(sprintf('Returns whether this bean is associated with %s via the %s pivot table.', $remoteBeanName, $this->pivotTable->getName()));
153
        $has->getDocBlock()->setTag(new ParamTag($variableName, [ $fqcnRemoteBeanName ]));
154
        $has->getDocBlock()->setTag(new ReturnTag([ 'bool' ]));
155
        $has->setReturnType('bool');
156
        $has->setParameter(new ParameterGenerator($variableName, $fqcnRemoteBeanName));
157
        $has->setBody(sprintf('return $this->hasRelationship(%s, $%s);', var_export($this->remoteFk->getLocalTableName(), true), $variableName));
158
159
        $setter = new MethodGenerator('set'.$pluralName);
160
        $setter->setDocBlock(sprintf('Sets all relationships with %s associated to this bean via the %s pivot table.
161
Exiting relationships will be removed and replaced by the provided relationships.', $remoteBeanName, $this->pivotTable->getName()));
162
        $setter->getDocBlock()->setTag(new ParamTag($pluralVariableName, [ $fqcnRemoteBeanName.'[]' ]));
163
        $setter->getDocBlock()->setTag(new ReturnTag([ 'void' ]));
164
        $setter->setReturnType('void');
165
        $setter->setParameter(new ParameterGenerator($pluralVariableName, 'array'));
166
        $setter->setBody(sprintf('$this->setRelationships(%s, $%s);', var_export($this->remoteFk->getLocalTableName(), true), $pluralVariableName));
167
168
        return [ $getter, $adder, $remover, $has, $setter ];
169
    }
170
171
    /**
172
     * Returns an array of classes that needs a "use" for this method.
173
     *
174
     * @return string[]
175
     */
176
    public function getUsedClasses() : array
177
    {
178
        return [$this->getBeanClassName()];
179
    }
180
181
    /**
182
     * Returns the code to past in jsonSerialize.
183
     *
184
     * @return string
185
     */
186
    public function getJsonSerializeCode() : string
187
    {
188
        $remoteBeanName = $this->getBeanClassName();
189
        $variableName = '$'.TDBMDaoGenerator::toVariableName($remoteBeanName);
190
191
        return 'if (!$stopRecursion) {
192
    $array[\''.lcfirst($this->getPluralName()).'\'] = array_map(function ('.$remoteBeanName.' '.$variableName.') {
193
        return '.$variableName.'->jsonSerialize(true);
194
    }, $this->'.$this->getName().'());
195
}
196
';
197
    }
198
199
    /**
200
     * @return Table
201
     */
202
    public function getPivotTable(): Table
203
    {
204
        return $this->pivotTable;
205
    }
206
207
    /**
208
     * @return ForeignKeyConstraint
209
     */
210
    public function getLocalFk(): ForeignKeyConstraint
211
    {
212
        return $this->localFk;
213
    }
214
215
    /**
216
     * @return ForeignKeyConstraint
217
     */
218
    public function getRemoteFk(): ForeignKeyConstraint
219
    {
220
        return $this->remoteFk;
221
    }
222
}
223