Passed
Pull Request — master (#61)
by David
02:40
created

ObjectBeanPropertyDescriptor   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 189
c 0
b 0
f 0
rs 10
wmc 18
lcom 1
cbo 5

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getForeignKey() 0 4 1
A getClassName() 0 4 1
A getPhpType() 0 4 1
A getParamAnnotation() 0 6 1
A isCompulsory() 0 14 3
A hasDefault() 0 4 1
A assignToDefaultCode() 0 4 1
A isPrimaryKey() 0 10 1
B getGetterSetterCode() 0 33 5
A getJsonSerializeCode() 0 8 1
A getCloneRule() 0 4 1
1
<?php
2
3
namespace TheCodingMachine\TDBM\Utils;
4
5
use Doctrine\DBAL\Schema\Column;
6
use Doctrine\DBAL\Schema\Table;
7
use Doctrine\DBAL\Schema\ForeignKeyConstraint;
8
use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
9
10
/**
11
 * This class represent a property in a bean that points to another table.
12
 */
13
class ObjectBeanPropertyDescriptor extends AbstractBeanPropertyDescriptor
14
{
15
    /**
16
     * @var ForeignKeyConstraint
17
     */
18
    private $foreignKey;
19
20
    /**
21
     * @var SchemaAnalyzer
22
     */
23
    private $schemaAnalyzer;
24
25
    /**
26
     * ObjectBeanPropertyDescriptor constructor.
27
     * @param Table $table
28
     * @param ForeignKeyConstraint $foreignKey
29
     * @param SchemaAnalyzer $schemaAnalyzer
30
     * @param NamingStrategyInterface $namingStrategy
31
     */
32
    public function __construct(Table $table, ForeignKeyConstraint $foreignKey, SchemaAnalyzer $schemaAnalyzer, NamingStrategyInterface $namingStrategy)
33
    {
34
        parent::__construct($table, $namingStrategy);
35
        $this->foreignKey = $foreignKey;
36
        $this->schemaAnalyzer = $schemaAnalyzer;
37
    }
38
39
    /**
40
     * Returns the foreignkey the column is part of, if any. null otherwise.
41
     *
42
     * @return ForeignKeyConstraint|null
43
     */
44
    public function getForeignKey()
45
    {
46
        return $this->foreignKey;
47
    }
48
49
    /**
50
     * Returns the name of the class linked to this property or null if this is not a foreign key.
51
     *
52
     * @return null|string
53
     */
54
    public function getClassName(): ?string
55
    {
56
        return $this->namingStrategy->getBeanClassName($this->foreignKey->getForeignTableName());
57
    }
58
59
    /**
60
     * Returns the PHP type for the property (it can be a scalar like int, bool, or class names, like \DateTimeInterface, App\Bean\User....)
61
     *
62
     * @return string
63
     */
64
    public function getPhpType(): string
65
    {
66
        return $this->getClassName();
67
    }
68
69
70
    /**
71
     * Returns the param annotation for this property (useful for constructor).
72
     *
73
     * @return string
74
     */
75
    public function getParamAnnotation()
76
    {
77
        $str = '     * @param %s %s';
78
79
        return sprintf($str, $this->getClassName(), $this->getVariableName());
80
    }
81
82
    /**
83
     * Returns true if the property is compulsory (and therefore should be fetched in the constructor).
84
     *
85
     * @return bool
86
     */
87
    public function isCompulsory()
88
    {
89
        // Are all columns nullable?
90
        $localColumnNames = $this->foreignKey->getUnquotedLocalColumns();
91
92
        foreach ($localColumnNames as $name) {
93
            $column = $this->table->getColumn($name);
94
            if ($column->getNotnull()) {
95
                return true;
96
            }
97
        }
98
99
        return false;
100
    }
101
102
    /**
103
     * Returns true if the property has a default value.
104
     *
105
     * @return bool
106
     */
107
    public function hasDefault()
108
    {
109
        return false;
110
    }
111
112
    /**
113
     * Returns the code that assigns a value to its default value.
114
     *
115
     * @return string
116
     *
117
     * @throws \TDBMException
118
     */
119
    public function assignToDefaultCode()
120
    {
121
        throw new \TDBMException('Foreign key based properties cannot be assigned a default value.');
122
    }
123
124
    /**
125
     * Returns true if the property is the primary key.
126
     *
127
     * @return bool
128
     */
129
    public function isPrimaryKey()
130
    {
131
        $fkColumns = $this->foreignKey->getUnquotedLocalColumns();
132
        sort($fkColumns);
133
134
        $pkColumns = $this->table->getPrimaryKey()->getUnquotedColumns();
135
        sort($pkColumns);
136
137
        return $fkColumns == $pkColumns;
138
    }
139
140
    /**
141
     * Returns the PHP code for getters and setters.
142
     *
143
     * @return string
144
     */
145
    public function getGetterSetterCode()
146
    {
147
        $tableName = $this->table->getName();
148
        $getterName = $this->getGetterName();
149
        $setterName = $this->getSetterName();
150
        $isNullable = !$this->isCompulsory();
151
152
        $referencedBeanName = $this->namingStrategy->getBeanClassName($this->foreignKey->getForeignTableName());
153
154
        $str = '    /**
155
     * Returns the '.$referencedBeanName.' object bound to this object via the '.implode(' and ', $this->foreignKey->getUnquotedLocalColumns()).' column.
156
     *
157
     * @return '.$referencedBeanName.($isNullable?'|null':'').'
158
     */
159
    public function '.$getterName.'(): '.($isNullable?'?':'').$referencedBeanName.'
160
    {
161
        return $this->getRef('.var_export($this->foreignKey->getName(), true).', '.var_export($tableName, true).');
162
    }
163
164
    /**
165
     * The setter for the '.$referencedBeanName.' object bound to this object via the '.implode(' and ', $this->foreignKey->getUnquotedLocalColumns()).' column.
166
     *
167
     * @param '.$referencedBeanName.($isNullable?'|null':'').' $object
168
     */
169
    public function '.$setterName.'('.($isNullable?'?':'').$referencedBeanName.' $object) : void
170
    {
171
        $this->setRef('.var_export($this->foreignKey->getName(), true).', $object, '.var_export($tableName, true).');
172
    }
173
174
';
175
176
        return $str;
177
    }
178
179
    /**
180
     * Returns the part of code useful when doing json serialization.
181
     *
182
     * @return string
183
     */
184
    public function getJsonSerializeCode()
185
    {
186
        return '        if (!$stopRecursion) {
187
            $object = $this->'.$this->getGetterName().'();
188
            $array['.var_export($this->namingStrategy->getJsonProperty($this), true).'] = $object ? $object->jsonSerialize(true) : null;
189
        }
190
';
191
    }
192
193
    /**
194
     * The code to past in the __clone method.
195
     * @return null|string
196
     */
197
    public function getCloneRule(): ?string
198
    {
199
        return null;
200
    }
201
}
202