ParentsRecursiveService   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
wmc 13
lcom 2
cbo 4
dl 0
loc 98
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 8 2
A alongParents() 0 18 3
A alongParentsInternal() 0 19 5
A parentWasProcessed() 0 10 3
1
<?php
2
/*
3
 * 2018 Romain CANON <[email protected]>
4
 *
5
 * This file is part of the TYPO3 Configuration Object project.
6
 * It is free software; you can redistribute it and/or modify it
7
 * under the terms of the GNU General Public License, either
8
 * version 3 of the License, or any later version.
9
 *
10
 * For the full copyright and license information, see:
11
 * http://www.gnu.org/licenses/gpl-3.0.html
12
 */
13
14
namespace Romm\ConfigurationObject\Service\Items\Parents;
15
16
use Romm\ConfigurationObject\Core\Core;
17
use TYPO3\CMS\Core\SingletonInterface;
18
use TYPO3\CMS\Core\Utility\GeneralUtility;
19
20
class ParentsRecursiveService implements SingletonInterface
21
{
22
    /**
23
     * @var ParentsRecursiveService
24
     */
25
    private static $instance;
26
27
    /**
28
     * @var callable
29
     */
30
    protected $callback;
31
32
    /**
33
     * @var object[]
34
     */
35
    protected $processedParents = [];
36
37
    /**
38
     * @return ParentsRecursiveService
39
     */
40
    public static function get()
41
    {
42
        if (null === self::$instance) {
43
            self::$instance = GeneralUtility::makeInstance(static::class);
44
        }
45
46
        return self::$instance;
47
    }
48
49
    /**
50
     * Will loop along each parent of the given root object, and every parent of
51
     * the parents: the given callback is called with a single parameter which
52
     * is the current parent.
53
     *
54
     * When the callback returns `false`, the loop breaks.
55
     *
56
     * @param callable     $callback
57
     * @param ParentsTrait $rootObject
0 ignored issues
show
introduced by
The type ParentsTrait for parameter $rootObject is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?
Loading history...
58
     * @param object[]     $parents
59
     */
60
    public function alongParents(callable $callback, $rootObject, array $parents)
61
    {
62
        $flag = false;
63
64
        if (null === $this->callback) {
65
            $flag = true;
66
67
            $this->callback = $callback;
68
            $this->processedParents = [$rootObject];
0 ignored issues
show
Documentation Bug introduced by
It seems like array($rootObject) of type array<integer,object<Rom...rents\\ParentsTrait>"}> is incompatible with the declared type array<integer,object> of property $processedParents.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
69
        }
70
71
        $this->alongParentsInternal($callback, $parents);
72
73
        if (true === $flag) {
74
            $this->callback = null;
75
            $this->processedParents = [];
76
        }
77
    }
78
79
    /**
80
     * @param callable $callback
81
     * @param array    $parents
82
     */
83
    protected function alongParentsInternal(callable $callback, array $parents)
84
    {
85
        foreach ($parents as $parent) {
86
            if (false === $this->parentWasProcessed($parent)) {
87
                $this->processedParents[] = $parent;
88
89
                $result = call_user_func($callback, $parent);
90
91
                if (false === $result) {
92
                    break;
93
                }
94
95
                if (Core::get()->getParentsUtility()->classUsesParentsTrait($parent)) {
96
                    /** @var ParentsTrait $parent */
97
                    $parent->alongParents($callback);
98
                }
99
            }
100
        }
101
    }
102
103
    /**
104
     * @param object $parent
105
     * @return bool
106
     */
107
    protected function parentWasProcessed($parent)
108
    {
109
        foreach ($this->processedParents as $processedParent) {
110
            if ($processedParent === $parent) {
111
                return true;
112
            }
113
        }
114
115
        return false;
116
    }
117
}
118