1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Charcoal\Ui\Dashboard; |
4
|
|
|
|
5
|
|
|
use InvalidArgumentException; |
6
|
|
|
|
7
|
|
|
// From 'charcoal-user' |
8
|
|
|
use Charcoal\User\AuthAwareInterface; |
9
|
|
|
|
10
|
|
|
// From 'charcoal-ui' |
11
|
|
|
use Charcoal\Ui\UiItemInterface; |
12
|
|
|
|
13
|
|
|
/** |
14
|
|
|
* Provides an implementation of {@see \Charcoal\Ui\Dashboard\DashboardInterface}. |
15
|
|
|
*/ |
16
|
|
|
trait DashboardTrait |
17
|
|
|
{ |
18
|
|
|
/** |
19
|
|
|
* A colletion of widgets. |
20
|
|
|
* |
21
|
|
|
* @var UiItemInterface[] |
22
|
|
|
*/ |
23
|
|
|
private $widgets; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* Store a widget builder instance. |
27
|
|
|
* |
28
|
|
|
* @var object |
29
|
|
|
*/ |
30
|
|
|
protected $widgetBuilder; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* A callback applied to each widget output by {@see self::widgets()}. |
34
|
|
|
* |
35
|
|
|
* @var callable |
36
|
|
|
*/ |
37
|
|
|
private $widgetCallback; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Set a widget builder. |
41
|
|
|
* |
42
|
|
|
* @param object $builder The builder to create customized widget objects. |
43
|
|
|
* @throws InvalidArgumentException If the argument is not a widget builder. |
44
|
|
|
* @return DashboardInterface Chainable |
45
|
|
|
*/ |
46
|
|
|
protected function setWidgetBuilder($builder) |
47
|
|
|
{ |
48
|
|
View Code Duplication |
if (is_object($builder)) { |
|
|
|
|
49
|
|
|
$this->widgetBuilder = $builder; |
50
|
|
|
} else { |
51
|
|
|
throw new InvalidArgumentException( |
52
|
|
|
sprintf( |
53
|
|
|
'Argument must be a widget builder, %s given', |
54
|
|
|
(is_object($builder) ? get_class($builder) : gettype($builder)) |
55
|
|
|
) |
56
|
|
|
); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
return $this; |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Set a callback to be applied to each widget output by {@see self::widgets()}. |
64
|
|
|
* |
65
|
|
|
* @param callable|null $callable A callback to be applied to each widget |
66
|
|
|
* or NULL to disable the callback. |
67
|
|
|
* @throws InvalidArgumentException If the argument is not callable or NULL. |
68
|
|
|
* @return DashboardInterface Chainable |
69
|
|
|
*/ |
70
|
|
|
public function setWidgetCallback($callable) |
71
|
|
|
{ |
72
|
|
|
if ($callable === null) { |
73
|
|
|
$this->widgetCallback = null; |
74
|
|
|
|
75
|
|
|
return $this; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
View Code Duplication |
if (is_callable($callable)) { |
|
|
|
|
79
|
|
|
$this->widgetCallback = $callable; |
80
|
|
|
} else { |
81
|
|
|
throw new InvalidArgumentException( |
82
|
|
|
sprintf( |
83
|
|
|
'Argument must be callable or NULL, %s given', |
84
|
|
|
(is_object($callable) ? get_class($callable) : gettype($callable)) |
85
|
|
|
) |
86
|
|
|
); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
return $this; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Set the dashboard's widgets. |
94
|
|
|
* |
95
|
|
|
* @param array $widgets A collection of widgets. |
96
|
|
|
* @return DashboardInterface Chainable |
97
|
|
|
*/ |
98
|
|
|
public function setWidgets(array $widgets) |
99
|
|
|
{ |
100
|
|
|
$this->widgets = []; |
101
|
|
|
|
102
|
|
|
foreach ($widgets as $widgetIdent => $widget) { |
103
|
|
|
$this->addWidget($widgetIdent, $widget); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
return $this; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* Add a widget to the dashboard. |
111
|
|
|
* |
112
|
|
|
* If a widget with the same $widgetIdent already exists, it will be overridden. |
113
|
|
|
* |
114
|
|
|
* @param string $widgetIdent The widget identifier. |
115
|
|
|
* @param UiItemInterface|array $widget The widget object or structure. |
116
|
|
|
* @throws InvalidArgumentException If the widget is invalid. |
117
|
|
|
* @return DashboardInterface Chainable |
118
|
|
|
*/ |
119
|
|
|
public function addWidget($widgetIdent, $widget) |
120
|
|
|
{ |
121
|
|
|
if (!is_string($widgetIdent)) { |
122
|
|
|
throw new InvalidArgumentException( |
123
|
|
|
'Widget identifier needs to be a string' |
124
|
|
|
); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
if ($widget instanceof UiItemInterface) { |
128
|
|
|
$this->widgets[$widgetIdent] = $widget; |
129
|
|
|
} elseif (is_array($widget)) { |
130
|
|
|
if (!isset($widget['ident'])) { |
131
|
|
|
$widget['ident'] = $widgetIdent; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
$w = $this->widgetBuilder->build($widget); |
135
|
|
|
|
136
|
|
|
$this->widgets[$widgetIdent] = $w; |
137
|
|
|
} else { |
138
|
|
|
throw new InvalidArgumentException( |
139
|
|
|
'Can not add widget: Invalid Widget.' |
140
|
|
|
); |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
return $this; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* Retrieve the dashboard's widgets. |
148
|
|
|
* |
149
|
|
|
* @param callable $widgetCallback A callback applied to each widget. |
150
|
|
|
* @return UiItemInterface[]|Generator |
151
|
|
|
*/ |
152
|
|
|
public function widgets(callable $widgetCallback = null) |
|
|
|
|
153
|
|
|
{ |
154
|
|
|
$widgets = $this->widgets; |
155
|
|
|
uasort($widgets, [ $this, 'sortItemsByPriority' ]); |
156
|
|
|
|
157
|
|
|
$widgetCallback = isset($widgetCallback) ? $widgetCallback : $this->widgetCallback; |
158
|
|
|
foreach ($widgets as $widget) { |
159
|
|
|
if (isset($widget['permissions']) && $this instanceof AuthAwareInterface) { |
160
|
|
|
$widget->setActive($this->hasPermissions($widget['permissions'])); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
if (!$widget->active()) { |
164
|
|
|
continue; |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
if ($widgetCallback) { |
168
|
|
|
$widgetCallback($widget); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
$GLOBALS['widget_template'] = $widget->template(); |
172
|
|
|
|
173
|
|
|
yield $widget; |
174
|
|
|
|
175
|
|
|
$GLOBALS['widget_template'] = ''; |
176
|
|
|
} |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Determine if the dashboard has any widgets. |
181
|
|
|
* |
182
|
|
|
* @return boolean |
183
|
|
|
*/ |
184
|
|
|
public function hasWidgets() |
185
|
|
|
{ |
186
|
|
|
return ($this->numWidgets() > 0); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
/** |
190
|
|
|
* Count the number of widgets attached to the dashboard. |
191
|
|
|
* |
192
|
|
|
* @return integer |
193
|
|
|
*/ |
194
|
|
|
public function numWidgets() |
195
|
|
|
{ |
196
|
|
|
return count($this->widgets); |
197
|
|
|
} |
198
|
|
|
} |
199
|
|
|
|
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.