Completed
Push — extensions-support ( 02f578...4c74a5 )
by Guido
03:38
created

NestedSet::level()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 10
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 10
loc 10
ccs 5
cts 5
cp 1
rs 9.4285
cc 1
eloc 5
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\Extensions\ExtensibleClassMetadata;
9
use LaravelDoctrine\Fluent\Extensions\Extension;
10
use LaravelDoctrine\Fluent\Fluent;
11
12
class NestedSet implements Buildable, Extension
13
{
14
    const MACRO_METHOD = 'nestedSet';
15
16
    /**
17
     * @var Fluent
18
     */
19
    protected $builder;
20
21
    /**
22
     * @var string
23
     */
24
    protected $left;
25
26
    /**
27
     * @var string
28
     */
29
    protected $right;
30
31
    /**
32
     * @var string
33
     */
34
    protected $level;
35
36
    /**
37
     * @var string
38
     */
39
    protected $root;
40
41
    /**
42
     * @var string
43
     */
44
    protected $parent;
45
46
    /**
47
     * @param Fluent $builder
48
     */
49 30
    public function __construct(Fluent $builder)
50
    {
51 30
        $this->builder = $builder;
52 30
    }
53
54
    /**
55
     * Enable extension
56
     */
57 83
    public static function enable()
58
    {
59 83
        TreeLeft::enable();
60 83
        TreeRight::enable();
61 83
        TreeLevel::enable();
62 83
        TreeRoot::enable();
63 83
        TreeParent::enable();
64 83
    }
65
66
    /**
67
     * @param string        $field
68
     * @param string        $type
69
     * @param callable|null $callback
70
     *
71
     * @return $this
72
     * @throws InvalidMappingException
73
     */
74 23 View Code Duplication
    public function left($field = 'left', $type = 'integer', callable $callback = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75
    {
76 23
        $this->validateNumericField($type, $field);
77
78 22
        $this->mapField($type, $field, $callback);
79
80 22
        $this->left = $field;
81
82 22
        return $this;
83
    }
84
85
    /**
86
     * @param string        $field
87
     * @param string        $type
88
     * @param callable|null $callback
89
     *
90
     * @return $this
91
     * @throws InvalidMappingException
92
     */
93 23 View Code Duplication
    public function right($field = 'right', $type = 'integer', callable $callback = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
94
    {
95 23
        $this->validateNumericField($type, $field);
96
97 22
        $this->mapField($type, $field, $callback);
98
99 22
        $this->right = $field;
100
101 22
        return $this;
102
    }
103
104
    /**
105
     * @param string        $field
106
     * @param string        $type
107
     * @param callable|null $callback
108
     *
109
     * @return $this
110
     * @throws InvalidMappingException
111
     */
112 6 View Code Duplication
    public function level($field = 'level', $type = 'integer', callable $callback = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113
    {
114 6
        $this->validateNumericField($type, $field);
115
116 5
        $this->mapField($type, $field, $callback);
117
118 5
        $this->level = $field;
119
120 5
        return $this;
121
    }
122
123
    /**
124
     * @param string        $field
125
     * @param callable|null $callback
126
     *
127
     * @return $this
128
     */
129 3
    public function root($field = 'root', callable $callback = null)
130
    {
131 3
        $this->addSelfReferencingRelation($field, $callback);
132
133 3
        $this->root = $field;
134
135 3
        return $this;
136
    }
137
138
    /**
139
     * @param string        $field
140
     * @param callable|null $callback
141
     *
142
     * @return $this
143
     */
144 22
    public function parent($field = 'parent', callable $callback = null)
145
    {
146 22
        $this->addSelfReferencingRelation($field, $callback);
147
148 22
        $this->parent = $field;
149
150 22
        return $this;
151
    }
152
153
    /**
154
     * Execute the build process
155
     */
156 21
    public function build()
157
    {
158 21
        $this->addDefaults();
159
160
        /** @var ExtensibleClassMetadata $classMetadata */
161 21
        $classMetadata = $this->builder->getBuilder()->getClassMetadata();
162 21
        $classMetadata->appendExtension($this->getExtensionName(), [
163 21
            'strategy' => 'nested',
164 21
            'left'     => $this->left,
165 21
            'right'    => $this->right,
166 21
            'level'    => $this->level,
167 21
            'root'     => $this->root,
168 21
            'parent'   => $this->parent,
169 21
        ]);
170 21
    }
171
172
    /**
173
     * Return the name of the actual extension.
174
     *
175
     * @return string
176
     */
177 21
    protected function getExtensionName()
178
    {
179 21
        return FluentDriver::EXTENSION_NAME;
180
    }
181
182
    /**
183
     * @param string        $type
184
     * @param string        $field
185
     * @param callable|null $callback
186
     * @param bool|false    $nullable
187
     */
188 24
    protected function mapField($type, $field, callable $callback = null, $nullable = false)
189
    {
190 24
        $this->builder->field($type, $field, $callback)->nullable($nullable);
191 24
    }
192
193
    /**
194
     * Add default values to all required fields.
195
     *
196
     * @return void
197
     */
198 21
    protected function addDefaults()
199
    {
200 21
        if (!$this->parent) {
201 18
            $this->parent();
202 18
        }
203
204 21
        if (!$this->left) {
205 15
            $this->left();
206 15
        }
207
208 21
        if (!$this->right) {
209 15
            $this->right();
210 15
        }
211 21
    }
212
213
    /**
214
     * @param string $type
215
     * @param string $field
216
     * @throws InvalidMappingException
217
     */
218 27
    protected function validateNumericField($type, $field)
219
    {
220 27
        if (!in_array($type, ['integer', 'bigint', 'smallint'])) {
221 3
            throw new InvalidMappingException("Invalid type [$type] for the [$field] field. Must be a (small, big) integer type.");
222
        }
223 24
    }
224
225
    /**
226
     * Returns the name of the mapped class.
227
     *
228
     * @return string
229
     */
230 23
    protected function myself()
231
    {
232 23
        return $this->builder->getBuilder()->getClassMetadata()->name;
233
    }
234
235
    /**
236
     * @param string        $field
237
     * @param callable|null $callback
238
     */
239 23
    protected function addSelfReferencingRelation($field, callable $callback = null)
240
    {
241 23
        $this->builder->belongsTo($this->myself(), $field, $callback)->nullable();
242 23
    }
243
}
244