Completed
Pull Request — master (#325)
by Paul
09:55
created

WidgetMap::setReplaced()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 7
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace Victoire\Bundle\WidgetMapBundle\Entity;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use Doctrine\Common\Collections\Collection;
7
use Doctrine\ORM\Mapping as ORM;
8
use Victoire\Bundle\CoreBundle\Entity\View;
9
use Victoire\Bundle\WidgetBundle\Entity\Widget;
10
11
/**
12
 * @ORM\Table("vic_widget_map")
13
 * @ORM\Entity()
14
 */
15
class WidgetMap
16
{
17
    const ACTION_CREATE = 'create';
18
    const ACTION_OVERWRITE = 'overwrite';
19
    const ACTION_DELETE = 'delete';
20
21
    const POSITION_BEFORE = 'before';
22
    const POSITION_AFTER = 'after';
23
24
    /**
25
     * @var int
26
     *
27
     * @ORM\Column(name="id", type="integer")
28
     * @ORM\Id
29
     * @ORM\GeneratedValue(strategy="AUTO")
30
     */
31
    protected $id;
32
33
    /**
34
     * @var string
35
     *
36
     * @ORM\Column(name="action", type="string", length=255)
37
     */
38
    protected $action = null;
39
40
    /**
41
     * @var View
42
     *
43
     * @ORM\ManyToOne(targetEntity="\Victoire\Bundle\CoreBundle\Entity\View", inversedBy="widgetMaps")
44
     * @ORM\JoinColumn(name="view_id", referencedColumnName="id", onDelete="cascade")
45
     */
46
    protected $view;
47
48
    /**
49
     * @var Widget
50
     *
51
     * @ORM\ManyToOne(targetEntity="\Victoire\Bundle\WidgetBundle\Entity\Widget", inversedBy="widgetMaps")
52
     * @ORM\JoinColumn(name="widget_id", referencedColumnName="id", onDelete="SET NULL")
53
     */
54
    protected $widget;
55
56
    /**
57
     * @ORM\ManyToOne(targetEntity="\Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap", inversedBy="substitutes")
58
     * @ORM\JoinColumn(name="replaced_id", referencedColumnName="id")
59
     */
60
    protected $replaced;
61
62
    /**
63
     * @var ArrayCollection
64
     * @ORM\OneToMany(targetEntity="\Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap", mappedBy="replaced")
65
     */
66
    protected $substitutes;
67
68
    /**
69
     * @var string
70
     *
71
     * @ORM\Column(name="asynchronous", type="boolean")
72
     */
73
    protected $asynchronous = false;
74
75
    /**
76
     * @ORM\ManyToOne(targetEntity="\Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap", inversedBy="children")
77
     * @ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
78
     */
79
    protected $parent;
80
81
    /**
82
     * @var string
83
     *
84
     * @ORM\Column(name="position", type="string", nullable=true)
85
     */
86
    protected $position;
87
88
    /**
89
     * @var Collection
90
     * @ORM\OneToMany(targetEntity="\Victoire\Bundle\WidgetMapBundle\Entity\WidgetMap", mappedBy="parent")
91
     */
92
    protected $children;
93
94
    /**
95
     * @var string
96
     *
97
     * @ORM\Column(name="slot", type="string", length=255, nullable=true)
98
     */
99
    protected $slot;
100
101
    public function __construct()
102
    {
103
        $this->children = new ArrayCollection();
104
        $this->substitutes = new ArrayCollection();
105
    }
106
107
    /**
108
     * @return int
109
     */
110
    public function getId()
111
    {
112
        return $this->id;
113
    }
114
115
    public function setId($id)
116
    {
117
        $this->id = $id;
118
    }
119
120
    /**
121
     * @return string
122
     */
123
    public function isAsynchronous()
124
    {
125
        return $this->asynchronous;
126
    }
127
128
    /**
129
     * @param boolean|string $asynchronous
130
     */
131
    public function setAsynchronous($asynchronous)
132
    {
133
        $this->asynchronous = $asynchronous;
0 ignored issues
show
Documentation Bug introduced by
It seems like $asynchronous can also be of type boolean. However, the property $asynchronous is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
134
    }
135
136
    /**
137
     * Set the action.
138
     *
139
     * @param string $action
140
     *
141
     * @throws \Exception The action is not valid
142
     */
143
    public function setAction($action)
144
    {
145
        //test validity of the action
146
        if ($action !== self::ACTION_CREATE && $action !== self::ACTION_OVERWRITE && $action !== self::ACTION_DELETE) {
147
            throw new \Exception('The action of the widget map is not valid. Action: ['.$action.']');
148
        }
149
150
        $this->action = $action;
151
    }
152
153
    /**
154
     * Get the action.
155
     *
156
     * @return string The action
157
     */
158
    public function getAction()
159
    {
160
        return $this->action;
161
    }
162
163
    /**
164
     * @return Widget
165
     */
166
    public function getWidget()
167
    {
168
        return $this->widget;
169
    }
170
171
    /**
172
     * @param Widget $widget
173
     *
174
     * @return $this
175
     */
176
    public function setWidget(Widget $widget)
177
    {
178
        $this->widget = $widget;
179
180
        return $this;
181
    }
182
183
    /**
184
     * @return View
185
     */
186
    public function getView()
187
    {
188
        return $this->view;
189
    }
190
191
    /**
192
     * @param View $view
193
     */
194
    public function setView(View $view)
195
    {
196
        $this->view = $view;
197
    }
198
199
    /**
200
     * @return mixed
201
     */
202
    public function getReplaced()
203
    {
204
        return $this->replaced;
205
    }
206
207
    /**
208
     * @param mixed $replaced
209
     */
210
    public function setReplaced($replaced)
211
    {
212
        if ($replaced) {
213
            $replaced->addSubstitute($this);
214
        }
215
        $this->replaced = $replaced;
216
    }
217
218
    /**
219
     * @return string
220
     */
221
    public function getSlot()
222
    {
223
        return $this->slot;
224
    }
225
226
    /**
227
     * @param string $slot
228
     */
229
    public function setSlot($slot)
230
    {
231
        $this->slot = $slot;
232
    }
233
234
    /**
235
     * @return mixed
236
     */
237
    public function getChildren(View $view = null)
238
    {
239
        $positions = [self::POSITION_BEFORE, self::POSITION_AFTER];
240
        $children = [];
241
        $widgetMap = $this;
242
        foreach ($positions as $position) {
243
            $children[$position] = null;
244
            if (($childs = $widgetMap->getChilds($position)) && !empty($childs)) {
245 View Code Duplication
                foreach ($childs as $_child) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
246
                    // found child must belongs to the given view or one of it's templates
247
                    if ($view) {
248
                        // if child has a view
249
                        // and child view is same as given view or the child view is a template of given view
250
                        if ($_child->getView() && ($view == $_child->getView() || $_child->getView()->isTemplateOf($view))
251
                        ) {
252
                            // if child is a substitute in view
253
                            if ($substitute = $_child->getSubstituteForView($view)) {
254
                                // if i'm not the parent of the substitute or i does not have the same position, child is not valid
255
                                if ($substitute->getParent() != $this || $substitute->getPosition() != $position) {
256
                                    $_child = null;
257
                                }
258
                            }
259
                            $children[$position] = $_child;
260
                        }
261
                    } else {
262
                        $children[$position] = $_child;
263
                    }
264
                }
265
            }
266
            // If I am replaced and my replacement has children for the position
267
            if (!$children[$position]
268
                && ($replaced = $this->getReplaced())
269
                && !empty($this->getReplaced()->getChilds($position))) {
270 View Code Duplication
                foreach ($this->getReplaced()->getChilds($position) as $_child) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
271
                    if ($view) {
272
                        // if child view is same as given view or the child view is a template of given view
273
                        if ($_child->getView() && ($view == $_child->getView() || $_child->getView()->isTemplateOf($view))) {
274
275
                            // if child is a substitute in view
276
                            if ($substitute = $_child->getSubstituteForView($view)) {
277
                                // if i'm not the parent of the substitute or i does not have the same position, child is not valid
278
                                if ($substitute->getParent() != $this || $substitute->getPosition() != $position) {
279
                                    $_child = null;
280
                                }
281
                            }
282
                            $children[$position] = $_child;
283
                        }
284
                    } else {
285
                        $children[$position] = $_child;
286
                    }
287
                }
288
            }
289
        }
290
291
        return $children;
292
    }
293
294
    /**
295
     * @return Collection
296
     */
297
    public function getChildrenRaw()
298
    {
299
        return $this->children;
300
    }
301
302
    public function hasChild($position, View $view = null)
303
    {
304
        foreach ($this->getChildren($view) as $child) {
305
            if ($child && $child->getPosition() === $position) {
306
                return true;
307
            }
308
        }
309
310
        return false;
311
    }
312
313
    /**
314
     * @return WidgetMap|null
315
     */
316
    public function getChild($position)
317
    {
318
        $child = null;
319
        foreach ($this->children as $_child) {
320
            if ($_child && $_child->getPosition() == $position) {
321
                $child = $_child;
322
            }
323
        }
324
325
        return $child;
326
    }
327
328
    /**
329
     * @return [WidgetMap]
0 ignored issues
show
Documentation introduced by
The doc-type [WidgetMap] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
330
     */
331
    public function getChilds($position)
332
    {
333
        $childs = [];
334
        foreach ($this->children as $_child) {
335
            if ($_child && $_child->getPosition() == $position) {
336
                $childs[] = $_child;
337
            }
338
        }
339
340
        return $childs;
341
    }
342
343
    /**
344
     * @param mixed $children
345
     */
346
    public function setChildren($children)
347
    {
348
        $this->children = $children;
349
    }
350
351
    /**
352
     * @return void
353
     */
354
    public function removeChildren()
355
    {
356
        foreach ($this->children as $child) {
357
            $this->removeChild($child);
358
        }
359
    }
360
361
    /**
362
     * @param WidgetMap $child
363
     */
364
    public function addChild($child)
365
    {
366
        $this->children->add($child);
367
    }
368
369
    /**
370
     * @param WidgetMap $child
371
     */
372
    public function removeChild($child)
373
    {
374
        $this->children->removeElement($child);
375
    }
376
377
    /**
378
     * @return WidgetMap|null
379
     */
380
    public function getParent()
381
    {
382
        return $this->parent;
383
    }
384
385
    /**
386
     * @param null|WidgetMap $parent
387
     */
388
    public function setParent(WidgetMap $parent = null)
389
    {
390
        if ($this->parent) {
391
            $this->parent->removeChild($this);
392
        }
393
        if ($parent) {
394
            $parent->addChild($this);
395
        }
396
        $this->parent = $parent;
397
    }
398
399
    /**
400
     * @return string
401
     */
402
    public function getPosition()
403
    {
404
        return $this->position;
405
    }
406
407
    /**
408
     * @param string $position
409
     */
410
    public function setPosition($position)
411
    {
412
        $this->position = $position;
413
    }
414
415
    /**
416
     * @return ArrayCollection
417
     */
418
    public function getSubstitutes()
419
    {
420
        return $this->substitutes;
421
    }
422
423
    /**
424
     * @return mixed
425
     */
426
    public function getSubstituteForView(View $view)
427
    {
428
        foreach ($this->substitutes as $substitute) {
429
            if ($substitute->getView() == $view) {
430
                return $substitute;
431
            }
432
        }
433
434
        return;
435
    }
436
437
    /**
438
     * @param WidgetMap $substitute
439
     */
440
    public function addSubstitute(WidgetMap $substitute)
441
    {
442
        $this->substitutes->add($substitute);
443
    }
444
445
    /**
446
     * @param [WidgetMap] $substitutes
0 ignored issues
show
Documentation introduced by
The doc-type [WidgetMap] could not be parsed: Unknown type name "" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
447
     */
448
    public function setSubstitutes($substitutes)
449
    {
450
        $this->substitutes = $substitutes;
451
    }
452
}
453