Completed
Push — master ( 21d9a3...b1017c )
by Nekrasov
02:14
created

WidgetGroup::wrap()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Arrilot\Widgets;
4
5
use Arrilot\Widgets\Contracts\ApplicationWrapperContract;
6
use Arrilot\Widgets\Misc\ViewExpressionTrait;
7
8
class WidgetGroup
9
{
10
    use ViewExpressionTrait;
11
12
    /**
13
     * The widget group name.
14
     *
15
     * @var string
16
     */
17
    protected $name;
18
19
    /**
20
     * The application wrapper.
21
     *
22
     * @var ApplicationWrapperContract
23
     */
24
    protected $app;
25
26
    /**
27
     * The array of widgets to display in this group.
28
     *
29
     * @var array
30
     */
31
    protected $widgets = [];
32
33
    /**
34
     * The position of a widget in this group.
35
     *
36
     * @var int
37
     */
38
    protected $position = 100;
39
40
    /**
41
     * The separator to display between widgets in the group.
42
     *
43
     * @var string
44
     */
45
    protected $separator = '';
46
47
    /**
48
     * The number of widgets in the group.
49
     *
50
     * @var int
51
     */
52
    protected $count = 0;
53
54
    /**
55
     * A callback that defines extra markup that wraps every widget in the group.
56
     *
57
     * @var callable
58
     */
59
    protected $wrapCallback;
60
61
    /**
62
     * @param $name
63
     * @param ApplicationWrapperContract $app
64
     */
65
    public function __construct($name, ApplicationWrapperContract $app)
66
    {
67
        $this->name = $name;
68
69
        $this->app = $app;
70
    }
71
72
    /**
73
     * Display all widgets from this group in correct order.
74
     *
75
     * @return string
76
     */
77
    public function display()
78
    {
79
        ksort($this->widgets);
80
81
        $output = '';
82
        $index = 0;
83
        foreach ($this->widgets as $position => $widgets) {
84
            foreach ($widgets as $widget) {
85
                $output .= $this->performWrap($this->displayWidget($widget), $index, $this->count);
86
                $index++;
87
                if ($this->count !== $index) {
88
                    $output .= $this->separator;
89
                }
90
            }
91
        }
92
93
        return $this->convertToViewExpression($output);
94
    }
95
96
    /**
97
     * Set widget position.
98
     *
99
     * @param int $position
100
     *
101
     * @return $this
102
     */
103
    public function position($position)
104
    {
105
        $this->position = $position;
106
107
        return $this;
108
    }
109
110
    /**
111
     * Add a widget to the group.
112
     */
113
    public function addWidget()
114
    {
115
        $this->addWidgetWithType('sync', func_get_args());
116
    }
117
118
    /**
119
     * Add an async widget to the group.
120
     */
121
    public function addAsyncWidget()
122
    {
123
        $this->addWidgetWithType('async', func_get_args());
124
    }
125
126
    /**
127
     * Getter for position.
128
     *
129
     * @return int
130
     */
131
    public function getPosition()
132
    {
133
        return $this->position;
134
    }
135
136
    /**
137
     * Set a separator to display between widgets in the group.
138
     *
139
     * @param string $separator
140
     *
141
     * @return $this
142
     */
143
    public function setSeparator($separator)
144
    {
145
        $this->separator = $separator;
146
147
        return $this;
148
    }
149
150
    /**
151
     * Setter for $this->wrapCallback.
152
     *
153
     * @param callable $callable
154
     *
155
     * @return $this
156
     */
157
    public function wrap(callable $callable)
158
    {
159
        $this->wrapCallback = $callable;
160
161
        return $this;
162
    }
163
164
    /**
165
     * Check if there are any widgets in the group.
166
     *
167
     * @return bool
168
     */
169
    public function any()
170
    {
171
        return !$this->isEmpty();
172
    }
173
174
    /**
175
     * Check if there are no widgets in the group.
176
     *
177
     * @return bool
178
     */
179
    public function isEmpty()
180
    {
181
        return empty($this->widgets);
182
    }
183
184
    /**
185
     * Count the number of widgets in this group.
186
     *
187
     * @return int
188
     */
189
    public function count()
190
    {
191
        $count = 0;
192
        foreach ($this->widgets as $position => $widgets) {
193
            $count += count($widgets);
194
        }
195
196
        return $count;
197
    }
198
199
    /**
200
     * Add a widget with a given type to the array.
201
     *
202
     * @param string $type
203
     * @param array  $arguments
204
     */
205
    protected function addWidgetWithType($type, array $arguments = [])
206
    {
207
        if (!isset($this->widgets[$this->position])) {
208
            $this->widgets[$this->position] = [];
209
        }
210
211
        $this->widgets[$this->position][] = [
212
            'arguments' => $arguments,
213
            'type'      => $type,
214
        ];
215
216
        $this->count++;
217
218
        $this->resetPosition();
219
    }
220
221
    /**
222
     * Display a widget according to its type.
223
     *
224
     * @param $widget
225
     *
226
     * @return mixed
227
     */
228
    protected function displayWidget($widget)
229
    {
230
        $factory = $this->app->make($widget['type'] === 'sync' ? 'arrilot.widget' : 'arrilot.async-widget');
231
232
        return call_user_func_array([$factory, 'run'], $widget['arguments']);
233
    }
234
235
    /**
236
     * Reset the position property back to the default.
237
     * So it does not affect the next widget.
238
     */
239
    protected function resetPosition()
240
    {
241
        $this->position = 100;
242
    }
243
244
    /**
245
     * Wraps widget content in a special markup defined by $this->wrap().
246
     *
247
     * @param string $content
248
     * @param int $index
249
     * @param int $total
250
     *
251
     * @return string
252
     */
253
    protected function performWrap($content, $index, $total)
254
    {
255
        if (is_null($this->wrapCallback)) {
256
            return $content;
257
        }
258
259
        $callback = $this->wrapCallback;
260
261
        return $callback($content, $index, $total);
262
    }
263
}
264