Passed
Push — ft/pagefield ( db2ad6...f2722b )
by Ben
10:27
created

PresentSections   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Test Coverage

Coverage 95.24%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 19
eloc 43
c 1
b 0
f 0
dl 0
loc 122
ccs 40
cts 42
cp 0.9524
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A __invoke() 0 8 1
B toCollection() 0 30 8
A addModelToCollection() 0 21 6
A addSetToCollection() 0 4 1
A pushToSet() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Thinktomorrow\Chief\PageBuilder;
6
7
use Illuminate\Support\Collection;
8
use Thinktomorrow\Chief\Concerns\Viewable\ViewableContract;
9
use Thinktomorrow\Chief\Modules\Module;
10
use Thinktomorrow\Chief\Relations\ActsAsChild;
11
use Thinktomorrow\Chief\Relations\ActsAsParent;
12
use Thinktomorrow\Chief\Sets\Set;
13
use Thinktomorrow\Chief\Sets\StoredSetReference;
14
15
class PresentSections
16
{
17
    /** @var ActsAsParent */
18
    private $parent;
19
20
    /**
21
     * Original collection of children
22
     *
23
     * @var array
24
     */
25
    private $children;
26
27
    /**
28
     * Resulting sets
29
     *
30
     * @var array
31
     */
32
    private $sets;
33
34
    /**
35
     * Keep track of current pageset index key
36
     *
37
     * @var string
38
     */
39
    private $current_index = null;
40
41
    /**
42
     * Keep track of current pageset type. This is mainly to bundle
43
     * individual selected pages together.
44
     *
45
     * @var string
46
     */
47
    private $current_type = null;
48
49
    private $withSnippets = false;
50
51 10
    public function __construct()
52
    {
53 10
        $this->sets = collect([]);
0 ignored issues
show
Documentation Bug introduced by
It seems like collect(array()) of type Tightenco\Collect\Support\Collection is incompatible with the declared type array of property $sets.

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...
54 10
    }
55
56
    // pages can be adopted as children individually or as a pageset. They are presented in one module file
57
    // with the collection of all pages combined. But only if they are sorted right after each other
58 10
    public function __invoke(ActsAsParent $parent, Collection $children): Collection
59
    {
60 10
        $this->parent = $parent;
61 10
        $this->children = $children;
0 ignored issues
show
Documentation Bug introduced by
It seems like $children of type Illuminate\Support\Collection is incompatible with the declared type array of property $children.

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...
62
63 10
        $this->withSnippets = $parent->withSnippets;
0 ignored issues
show
Bug introduced by
Accessing withSnippets on the interface Thinktomorrow\Chief\Relations\ActsAsParent suggest that you code against a concrete implementation. How about adding an instanceof check?
Loading history...
64
65 10
        return $this->toCollection();
66
    }
67
68 10
    public function toCollection(): Collection
69
    {
70 10
        foreach ($this->children as $i => $child) {
71 10
            if ($child instanceof StoredSetReference) {
72 1
                $this->addSetToCollection($i, $child->toSet($this->parent));
73 1
                continue;
74
            }
75
76
            // A module is something we will add as is, without combining them together
77 9
            if ($child instanceof Module) {
78 7
                $this->sets[$i] = $child;
79 7
                $this->current_type = null;
80 7
                continue;
81
            }
82
83 5
            // A model that is not a module will be rendered as a set by default. You can set a 'dontRenderAsSet' property to avoid this behavior
84
            // and allow for the model to be rendered as a single element.
85
            if (property_exists($child, 'dontRenderAsSet') && $child->dontRenderAsSet) {
86
                $this->sets[$i] = $child;
87 10
                $this->current_type = null;
88 7
                continue;
89 10
            }
90 10
91
            $this->addModelToCollection($i, $child);
92
        }
93 1
94
        return $this->sets->values()->map(function (ViewableContract $child) {
95 1
            return ($this->withSnippets && method_exists($child, 'withSnippets'))
96 1
                ? $child->withSnippets()->setViewParent($this->parent)->renderView()
97 1
                : $child->setViewParent($this->parent)->renderView();
98
        });
99 5
    }
100
101
    private function addSetToCollection($index, Set $set)
102
    {
103 5
        $this->sets[$index] = $set;
104
        $this->current_type = null;
105
    }
106
107 5
    private function addModelToCollection($index, ActsAsChild $model)
108
    {
109
        // Only published pages you fool!
110
        // TODO: check for assistant instead of method existence
111 5
        if (method_exists($model, 'isPublished') && !$model->isPublished()) {
112 5
            return;
113 5
        }
114
115 3
        $key = $model->viewKey();
0 ignored issues
show
Bug introduced by
The method viewKey() does not exist on Thinktomorrow\Chief\Relations\ActsAsChild. Since it exists in all sub-types, consider adding an abstract or default implementation to Thinktomorrow\Chief\Relations\ActsAsChild. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

115
        /** @scrutinizer ignore-call */ 
116
        $key = $model->viewKey();
Loading history...
116
117
        // Set the current collection to the model key identifier: for pages this is the collection key, for
118
        // other managed models this is the registered key.
119 5
        if ($this->current_type == null || $this->current_type != $key) {
120 5
            $this->current_type = $key;
121
            $this->current_index = $index;
122 5
        } // If current pageset index is null, let's make sure it is set to the current index
123
        elseif (is_null($this->current_index)) {
0 ignored issues
show
introduced by
The condition is_null($this->current_index) is always false.
Loading history...
124 5
            $this->current_index = $index;
125 5
        }
126
127
        $this->pushToSet($model, $key);
128 5
    }
129 5
130
    private function pushToSet($model, string $setKey)
131
    {
132
        if (!isset($this->sets[$this->current_index])) {
133
            $this->sets[$this->current_index] = new Set([], $setKey);
134
        }
135
136
        $this->sets[$this->current_index]->push($model);
137
    }
138
}
139