Completed
Push — extensions-support ( 75d97d...972b2b )
by Patrick
03:46
created

Tree::right()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 1
eloc 4
nc 1
nop 3
crap 1
1
<?php
2
3
namespace LaravelDoctrine\Fluent\Extensions\Gedmo;
4
5
use Gedmo\Exception\InvalidMappingException;
6
use Gedmo\Tree\Mapping\Driver\Fluent as FluentDriver;
7
use LaravelDoctrine\Fluent\Buildable;
8
use LaravelDoctrine\Fluent\Builders\Builder;
9
use LaravelDoctrine\Fluent\Extensions\ExtensibleClassMetadata;
10
use LaravelDoctrine\Fluent\Extensions\Extension;
11
use LaravelDoctrine\Fluent\Fluent;
12
13
class Tree implements Buildable, Extension
14
{
15
    const MACRO_METHOD = 'tree';
16
17
    /**
18
     * List of tree strategies available
19
     *
20
     * @var array
21
     */
22
    private $strategies = [
23
        'nested',
24
        'closure',
25
        'materializedPath',
26
    ];
27
28
    /**
29
     * @var ExtensibleClassMetadata
30
     */
31
    protected $classMetadata;
32
33
    /**
34
     * @var string
35
     */
36
    protected $strategy;
37
38
    /**
39
     * @var string
40
     */
41
    protected $left;
42
43
    /**
44
     * @var string
45
     */
46
    protected $right;
47
48
    /**
49
     * @var string
50
     */
51
    protected $level;
52
53
    /**
54
     * @var string
55
     */
56
    protected $root;
57
58
    /**
59
     * @var bool
60
     */
61
    protected $activateLocking = false;
62
63
    /**
64
     * @var int
65
     */
66
    protected $lockingTimeout = 3;
67
68
    /**
69
     * @var string
70
     */
71
    protected $closure;
72
73
    /**
74
     * @var bool
75
     */
76
    private $autoComplete = false;
77
78
    /**
79
     * @param ExtensibleClassMetadata $classMetadata
80
     * @param string                  $strategy
81
     * @param bool                    $autoComplete
82
     */
83 9
    public function __construct(ExtensibleClassMetadata $classMetadata, $strategy = 'nested', $autoComplete = false)
84
    {
85 9
        $this->classMetadata = $classMetadata;
86 9
        $this->strategy      = $strategy;
87 9
        $this->autoComplete  = $autoComplete;
88 9
    }
89
90
    /**
91
     * Enable extension
92
     */
93 82
    public static function enable()
94
    {
95
        Builder::macro(self::MACRO_METHOD, function (Fluent $fluent, $strategy = 'nested', $callback = null, $autoComplete = false) {
96 2
            $tree = new static($fluent->getBuilder()->getClassMetadata(), $strategy, $autoComplete);
0 ignored issues
show
Compatibility introduced by
$fluent->getBuilder()->getClassMetadata() of type object<Doctrine\ORM\Mapping\ClassMetadata> is not a sub-type of object<LaravelDoctrine\F...xtensibleClassMetadata>. It seems like you assume a child class of the class Doctrine\ORM\Mapping\ClassMetadata to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
97
98 2
            if (is_callable($callback)) {
99 1
                call_user_func($callback, $tree);
100 1
            }
101
102 2
            return $tree;
103 82
        });
104
105 82
        Builder::macro('nestedSet', function (Fluent $fluent, $callback = null) {
106 1
            return $fluent->tree('nested', $callback, true);
107 82
        });
108
109 82
        TreeLeft::enable();
110 82
        TreeRight::enable();
111 82
        TreeLevel::enable();
112 82
        TreeRoot::enable();
113 82
        TreeParent::enable();
114 82
        TreePath::enable();
115 82
        TreePathSource::enable();
116 82
        TreePathHash::enable();
117 82
        TreeLockTime::enable();
118 82
    }
119
120
    /**
121
     * @param  string $field
122
     * @param  string $type
123
     * @param  null   $name
124
     * @return $this
125
     */
126 3
    public function root($field = 'root', $type = 'integer', $name = null)
127
    {
128 3
        $this->mapField($field, $type, $name, true);
129
130 3
        $this->root = $field;
131
132 3
        return $this;
133
    }
134
135
    /**
136
     * @param  string $field
137
     * @param  string $type
138
     * @param  null   $name
139
     * @return $this
140
     */
141 3
    public function left($field = 'left', $type = 'integer', $name = null)
142
    {
143 3
        $this->mapField($field, $type, $name);
144
145 3
        $this->left = $field;
146
147 3
        return $this;
148
    }
149
150
    /**
151
     * @param  string $field
152
     * @param  string $type
153
     * @param  null   $name
154
     * @return $this
155
     */
156 3
    public function right($field = 'right', $type = 'integer', $name = null)
157
    {
158 3
        $this->mapField($field, $type, $name);
159
160 3
        $this->right = $field;
161
162 3
        return $this;
163
    }
164
165
    /**
166
     * @param  string $field
167
     * @param  string $type
168
     * @param  null   $name
169
     * @return $this
170
     */
171 3
    public function level($field = 'level', $type = 'integer', $name = null)
172
    {
173 3
        $this->mapField($field, $type, $name);
174
175 3
        $this->level = $field;
176
177 3
        return $this;
178
    }
179
180
    /**
181
     * Execute the build process
182
     */
183 6
    public function build()
184
    {
185 6
        if (!in_array($this->strategy, $this->strategies)) {
186 1
            throw new InvalidMappingException("Tree type: $this->strategy is not available.");
187
        }
188
189 5
        if ($this->autoComplete) {
190 2
            if (!$this->root) {
191 2
                $this->root('root');
192 2
            }
193
194 2
            if (!$this->level) {
195 2
                $this->level('level');
196 2
            }
197
198 2
            if (!$this->left) {
199 1
                $this->left('left');
200 1
            }
201
202 2
            if (!$this->right) {
203 1
                $this->right('right');
204 1
            }
205 2
        }
206
207 5
        $this->classMetadata->appendExtension($this->getExtensionName(), [
208 5
            'root'             => $this->root,
209 5
            'level'            => $this->level,
210 5
            'right'            => $this->right,
211 5
            'left'             => $this->left,
212 5
            'strategy'         => $this->strategy,
213 5
            'activate_locking' => $this->activateLocking,
214 5
            'locking_timeout'  => $this->lockingTimeout,
215 5
            'closure'          => $this->closure
216 5
        ]);
217 5
    }
218
219
    /**
220
     * Return the name of the actual extension.
221
     *
222
     * @return string
223
     */
224 5
    public function getExtensionName()
225
    {
226 5
        return FluentDriver::EXTENSION_NAME;
227
    }
228
229
    /**
230
     * @param  bool $activateLocking
231
     * @return Tree
232
     */
233 1
    public function activateLocking($activateLocking = true)
234
    {
235 1
        $this->activateLocking = $activateLocking;
236
237 1
        return $this;
238
    }
239
240
    /**
241
     * @param  string $strategy
242
     * @return Tree
243
     */
244 2
    public function strategy($strategy)
245
    {
246 2
        $this->strategy = $strategy;
247
248 2
        return $this;
249
    }
250
251
    /**
252
     * @param  int  $lockingTimeout
253
     * @return Tree
254
     */
255 2
    public function lockingTimeout($lockingTimeout)
256
    {
257 2
        if ($lockingTimeout < 1) {
258 1
            throw new InvalidMappingException("Tree Locking Timeout must be at least of 1 second.");
259
        }
260
261 1
        $this->lockingTimeout = $lockingTimeout;
262
263 1
        return $this;
264
    }
265
266
    /**
267
     * @param  string $closure
268
     * @return Tree
269
     */
270 1
    public function closure($closure)
271
    {
272 1
        $this->closure = $closure;
273
274 1
        return $this;
275
    }
276
277
    /**
278
     * @param      $field
279
     * @param      $type
280
     * @param      $name
281
     * @param bool $nullable
282
     */
283 3
    private function mapField($field, $type, $name, $nullable = false)
284
    {
285 3
        $this->classMetadata->mapField([
286 3
            'type'       => $type,
287 3
            'fieldName'  => $field,
288 3
            'columnName' => $name,
289
            'nullable'   => $nullable
290 3
        ]);
291 3
    }
292
}
293