1 | <?php |
||||||
2 | /** |
||||||
3 | * Server module for HiPanel |
||||||
4 | * |
||||||
5 | * @link https://github.com/hiqdev/hipanel-module-server |
||||||
6 | * @package hipanel-module-server |
||||||
7 | * @license BSD-3-Clause |
||||||
8 | * @copyright Copyright (c) 2015-2019, HiQDev (http://hiqdev.com/) |
||||||
9 | */ |
||||||
10 | |||||||
11 | namespace hipanel\modules\server\grid; |
||||||
12 | |||||||
13 | use hipanel\base\Model; |
||||||
14 | use hipanel\grid\BoxedGridView; |
||||||
15 | use hipanel\grid\MainColumn; |
||||||
16 | use hipanel\grid\RefColumn; |
||||||
17 | use hipanel\grid\XEditableColumn; |
||||||
18 | use hipanel\helpers\StringHelper; |
||||||
19 | use hipanel\helpers\Url; |
||||||
20 | use hipanel\modules\finance\models\Sale; |
||||||
21 | use hipanel\modules\hosting\controllers\AccountController; |
||||||
0 ignored issues
–
show
|
|||||||
22 | use hipanel\modules\hosting\controllers\IpController; |
||||||
0 ignored issues
–
show
The type
hipanel\modules\hosting\controllers\IpController was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths
Loading history...
|
|||||||
23 | use hipanel\modules\server\menus\ServerActionsMenu; |
||||||
24 | use hipanel\modules\server\models\Consumption; |
||||||
25 | use hipanel\modules\server\models\HardwareSale; |
||||||
26 | use hipanel\modules\server\models\Server; |
||||||
27 | use hipanel\modules\server\widgets\DiscountFormatter; |
||||||
28 | use hipanel\modules\server\widgets\Expires; |
||||||
29 | use hipanel\modules\server\widgets\OSFormatter; |
||||||
30 | use hipanel\modules\server\widgets\ResourceConsumptionTable; |
||||||
31 | use hipanel\modules\server\widgets\State; |
||||||
32 | use hipanel\widgets\ArraySpoiler; |
||||||
33 | use hipanel\widgets\gridLegend\ColorizeGrid; |
||||||
34 | use hipanel\widgets\gridLegend\GridLegend; |
||||||
35 | use hipanel\widgets\Label; |
||||||
36 | use hiqdev\yii2\menus\grid\MenuColumn; |
||||||
37 | use Tuck\Sort\Sort; |
||||||
38 | use Yii; |
||||||
39 | use yii\data\ArrayDataProvider; |
||||||
40 | use yii\helpers\ArrayHelper; |
||||||
41 | use yii\helpers\Html; |
||||||
42 | |||||||
43 | class ServerGridView extends BoxedGridView |
||||||
44 | { |
||||||
45 | use ColorizeGrid; |
||||||
0 ignored issues
–
show
|
|||||||
46 | |||||||
47 | public $controllerUrl = '@server'; |
||||||
48 | |||||||
49 | /** |
||||||
50 | * @var array |
||||||
51 | */ |
||||||
52 | public $osImages; |
||||||
53 | |||||||
54 | public function init() |
||||||
55 | { |
||||||
56 | parent::init(); |
||||||
57 | |||||||
58 | $this->view->registerCss(' |
||||||
59 | .tariff-chain { |
||||||
60 | list-style: none; |
||||||
61 | background-color: transparent; |
||||||
62 | } |
||||||
63 | .tariff-chain > li { |
||||||
64 | display: inline-block; |
||||||
65 | } |
||||||
66 | .tariff-chain > li + li:before { |
||||||
67 | font: normal normal normal 14px/1 FontAwesome; |
||||||
68 | content: "\f178\00a0"; |
||||||
69 | padding: 0 5px; |
||||||
70 | color: #ccc; |
||||||
71 | } |
||||||
72 | .inactiveLink { |
||||||
73 | pointer-events: none; |
||||||
74 | cursor: default; |
||||||
75 | } |
||||||
76 | '); |
||||||
77 | } |
||||||
78 | |||||||
79 | protected function formatTariff($model) |
||||||
80 | { |
||||||
81 | $user = Yii::$app->user; |
||||||
82 | $models = []; |
||||||
83 | $html = ''; |
||||||
84 | if ($user->can('sale.read') && isset($model->sales)) { |
||||||
0 ignored issues
–
show
The method
can() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||||||
85 | foreach ($model->sales as $sale) { |
||||||
86 | $models[] = $sale; |
||||||
87 | } |
||||||
88 | } elseif ($user->can('plan.read')) { |
||||||
89 | if (!empty($model->parent_tariff)) { |
||||||
90 | $title = $model->parent_tariff; |
||||||
91 | } else { |
||||||
92 | $title = $model->tariff; |
||||||
93 | } |
||||||
94 | |||||||
95 | $models[] = new Sale(['tariff' => $title, 'tariff_id' => $model->tariff_id]); |
||||||
96 | } else { |
||||||
97 | $models[] = new Sale([ |
||||||
98 | 'tariff' => $model->tariff, |
||||||
99 | 'tariff_id' => $model->tariff_id, |
||||||
100 | ]); |
||||||
101 | } |
||||||
102 | |||||||
103 | foreach ($models as $model) { |
||||||
0 ignored issues
–
show
|
|||||||
104 | if ($model->tariff) { |
||||||
105 | $tariff = $model->tariff_id ? Html::a($model->tariff, [ |
||||||
106 | '@plan/view', |
||||||
107 | 'id' => $model->tariff_id, |
||||||
108 | ]) : $model->tariff; |
||||||
109 | $client = $model->seller ? '(' . Html::a($model->seller, [ |
||||||
110 | '@client/view', 'id' => $model->seller_id, |
||||||
111 | ]) . ')' : ''; |
||||||
112 | |||||||
113 | $html .= Html::tag('li', $tariff . ' ' . $client); |
||||||
114 | } |
||||||
115 | } |
||||||
116 | |||||||
117 | return Html::tag('ul', $html, [ |
||||||
118 | 'class' => 'tariff-chain ' . ($user->can('support') ?: 'inactiveLink'), |
||||||
0 ignored issues
–
show
Are you sure
$user->can('support') ?: 'inactiveLink' of type string|true can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
119 | 'style' => 'margin: 0; padding: 0;', |
||||||
120 | ]); |
||||||
121 | } |
||||||
122 | |||||||
123 | public function columns() |
||||||
124 | { |
||||||
125 | $canAdmin = Yii::$app->user->can('admin'); |
||||||
0 ignored issues
–
show
The method
can() does not exist on null .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed.
Loading history...
|
|||||||
126 | $canSupport = Yii::$app->user->can('support'); |
||||||
127 | |||||||
128 | return array_merge(parent::columns(), [ |
||||||
129 | 'server' => [ |
||||||
130 | 'class' => MainColumn::class, |
||||||
131 | 'attribute' => 'name', |
||||||
132 | 'filterAttribute' => 'name_like', |
||||||
133 | 'note' => Yii::$app->user->can('server.set-label') ? 'label' : 'note', |
||||||
134 | 'noteOptions' => [ |
||||||
135 | 'url' => Yii::$app->user->can('server.set-label') ? Url::to('set-label') : (Yii::$app->user->can('server.set-note') ? Url::to('set-note') : ''), |
||||||
136 | ], |
||||||
137 | 'badges' => function ($model) use ($canSupport) { |
||||||
138 | $badges = ''; |
||||||
139 | if ($canSupport) { |
||||||
140 | if ($model->wizzarded) { |
||||||
141 | $badges .= Label::widget(['label' => 'W', 'tag' => 'sup', 'color' => 'success']); |
||||||
142 | } |
||||||
143 | } |
||||||
144 | $badges .= Label::widget(['label' => Yii::t('hipanel:server', $model->type_label), 'tag' => 'sup', 'color' => 'info']); |
||||||
145 | |||||||
146 | return $badges; |
||||||
147 | }, |
||||||
148 | ], |
||||||
149 | 'dc' => [ |
||||||
150 | 'attribute' => 'dc', |
||||||
151 | 'filter' => false, |
||||||
152 | ], |
||||||
153 | 'state' => [ |
||||||
154 | 'class' => RefColumn::class, |
||||||
155 | 'filterOptions' => ['class' => 'narrow-filter'], |
||||||
156 | 'i18nDictionary' => 'hipanel:server', |
||||||
157 | 'format' => 'raw', |
||||||
158 | 'gtype' => 'state,device', |
||||||
159 | 'visible' => $canSupport, |
||||||
160 | 'value' => function ($model) { |
||||||
161 | $html = State::widget(compact('model')); |
||||||
162 | if ($model->status_time) { |
||||||
163 | $html .= ' ' . Html::tag('nobr', Yii::t('hipanel:server', 'since {date}', ['date' => Yii::$app->formatter->asDate($model->status_time)])); |
||||||
164 | } |
||||||
165 | |||||||
166 | return $html; |
||||||
167 | }, |
||||||
168 | ], |
||||||
169 | 'panel' => [ |
||||||
170 | 'attribute' => 'panel', |
||||||
171 | 'format' => 'html', |
||||||
172 | 'contentOptions' => ['class' => 'text-uppercase'], |
||||||
173 | 'value' => function ($model) use ($canSupport) { |
||||||
174 | $value = $model->getPanel() ? Yii::t('hipanel:server:panel', $model->getPanel()) : Yii::t('hipanel:server:panel', 'No control panel'); |
||||||
175 | if ($canSupport) { |
||||||
176 | $value .= $model->wizzarded ? Label::widget([ |
||||||
177 | 'label' => 'W', 'tag' => 'sup', 'color' => 'success', |
||||||
178 | ]) : ''; |
||||||
179 | } |
||||||
180 | |||||||
181 | return $value; |
||||||
182 | }, |
||||||
183 | ], |
||||||
184 | 'os' => [ |
||||||
185 | 'attribute' => 'os', |
||||||
186 | 'format' => 'raw', |
||||||
187 | 'value' => function ($model) { |
||||||
188 | return OSFormatter::widget([ |
||||||
189 | 'osimages' => $this->osImages, |
||||||
190 | 'imageName' => $model->osimage, |
||||||
191 | ]); |
||||||
192 | }, |
||||||
193 | ], |
||||||
194 | 'os_and_panel' => [ |
||||||
195 | 'attribute' => 'os', |
||||||
196 | 'format' => 'raw', |
||||||
197 | 'value' => function ($model) { |
||||||
198 | $html = OSFormatter::widget([ |
||||||
199 | 'osimages' => $this->osImages, |
||||||
200 | 'imageName' => $model->osimage, |
||||||
201 | ]); |
||||||
202 | $html .= ' ' . ($model->panel ?: ''); |
||||||
203 | |||||||
204 | return $html; |
||||||
205 | }, |
||||||
206 | ], |
||||||
207 | 'discount' => [ |
||||||
208 | 'attribute' => 'discount', |
||||||
209 | 'label' => Yii::t('hipanel:server', 'Discount'), |
||||||
210 | 'format' => 'raw', |
||||||
211 | 'headerOptions' => ['style' => 'width: 1em'], |
||||||
212 | 'value' => function ($model) { |
||||||
213 | return DiscountFormatter::widget([ |
||||||
214 | 'current' => $model->discounts['fee']['current'], |
||||||
215 | 'next' => $model->discounts['fee']['next'], |
||||||
216 | ]); |
||||||
217 | }, |
||||||
218 | ], |
||||||
219 | 'expires' => [ |
||||||
220 | 'filter' => false, |
||||||
221 | 'format' => 'raw', |
||||||
222 | 'headerOptions' => ['style' => 'width: 1em'], |
||||||
223 | 'visible' => $canSupport, |
||||||
224 | 'value' => function ($model) { |
||||||
225 | return Expires::widget(compact('model')); |
||||||
226 | }, |
||||||
227 | ], |
||||||
228 | 'tariff' => [ |
||||||
229 | 'format' => 'raw', |
||||||
230 | 'filterAttribute' => 'tariff_like', |
||||||
231 | 'value' => function ($model) { |
||||||
232 | return $this->formatTariff($model); |
||||||
233 | }, |
||||||
234 | ], |
||||||
235 | 'tariff_and_discount' => [ |
||||||
236 | 'attribute' => 'tariff', |
||||||
237 | 'filterAttribute' => 'tariff_like', |
||||||
238 | 'format' => 'raw', |
||||||
239 | 'value' => function ($model) { |
||||||
240 | return $this->formatTariff($model) . ' ' . DiscountFormatter::widget([ |
||||||
241 | 'current' => $model->discounts['fee']['current'], |
||||||
242 | 'next' => $model->discounts['fee']['next'], |
||||||
243 | ]); |
||||||
244 | }, |
||||||
245 | ], |
||||||
246 | 'ip' => [ |
||||||
247 | 'filter' => false, |
||||||
248 | ], |
||||||
249 | 'mac' => [ |
||||||
250 | 'filter' => false, |
||||||
251 | ], |
||||||
252 | 'ips' => [ |
||||||
253 | 'format' => 'raw', |
||||||
254 | 'attribute' => 'ips', |
||||||
255 | 'filter' => false, |
||||||
256 | 'contentOptions' => [ |
||||||
257 | 'class' => 'text-center', |
||||||
258 | 'style' => 'width:1%; white-space:nowrap;', |
||||||
259 | ], |
||||||
260 | 'value' => function ($model) { |
||||||
261 | return ArraySpoiler::widget([ |
||||||
262 | 'data' => ArrayHelper::getColumn($model->ips, 'ip'), |
||||||
263 | 'delimiter' => '<br />', |
||||||
264 | 'visibleCount' => 1, |
||||||
265 | 'formatter' => function ($ip, $idx) use ($model) { |
||||||
266 | if ($idx === 0) { |
||||||
267 | return Html::a($ip, IpController::getSearchUrl(['server_in' => $model->name]), [ |
||||||
268 | 'class' => 'text-bold', |
||||||
269 | 'target' => '_blank', |
||||||
270 | ]); |
||||||
271 | } |
||||||
272 | |||||||
273 | return $ip; |
||||||
274 | }, |
||||||
275 | 'button' => [ |
||||||
276 | 'label' => Yii::t('hipanel:server', '') . ' +' . (count($model->ips) - 1), |
||||||
277 | 'tag' => 'button', |
||||||
278 | 'type' => 'button', |
||||||
279 | 'class' => 'btn btn-xs btn-flat', |
||||||
280 | 'style' => 'font-size: 10px', |
||||||
281 | 'popoverOptions' => [ |
||||||
282 | 'html' => true, |
||||||
283 | 'placement' => 'bottom', |
||||||
284 | 'title' => Yii::t('hipanel:server', 'IPs'), |
||||||
285 | 'template' => ' |
||||||
286 | <div class="popover" role="tooltip"> |
||||||
287 | <div class="arrow"></div> |
||||||
288 | <h3 class="popover-title"></h3> |
||||||
289 | <div class="popover-content" style="min-width: 15rem; height: 15rem; overflow-x: scroll;"></div> |
||||||
290 | </div> |
||||||
291 | ', |
||||||
292 | ], |
||||||
293 | ], |
||||||
294 | ]); |
||||||
295 | }, |
||||||
296 | ], |
||||||
297 | 'sale_time' => [ |
||||||
298 | 'attribute' => 'sale_time', |
||||||
299 | 'format' => 'datetime', |
||||||
300 | ], |
||||||
301 | 'note' => [ |
||||||
302 | 'class' => XEditableColumn::class, |
||||||
303 | 'pluginOptions' => [ |
||||||
304 | 'url' => Url::to('set-note'), |
||||||
305 | ], |
||||||
306 | 'widgetOptions' => [ |
||||||
307 | 'linkOptions' => [ |
||||||
308 | 'data-type' => 'textarea', |
||||||
309 | ], |
||||||
310 | ], |
||||||
311 | 'visible' => Yii::$app->user->can('server.set-note'), |
||||||
312 | ], |
||||||
313 | 'label' => [ |
||||||
314 | 'class' => XEditableColumn::class, |
||||||
315 | 'pluginOptions' => [ |
||||||
316 | 'url' => Url::to('set-label'), |
||||||
317 | ], |
||||||
318 | 'widgetOptions' => [ |
||||||
319 | 'linkOptions' => [ |
||||||
320 | 'data-type' => 'textarea', |
||||||
321 | ], |
||||||
322 | ], |
||||||
323 | 'visible' => Yii::$app->user->can('server.set-label'), |
||||||
324 | ], |
||||||
325 | 'type' => [ |
||||||
326 | 'format' => 'html', |
||||||
327 | 'filter' => false, |
||||||
328 | 'value' => function ($model) { |
||||||
329 | return Html::tag('span', $model->type_label, ['class' => 'label label-default']); |
||||||
330 | }, |
||||||
331 | ], |
||||||
332 | 'detailed_type' => [ |
||||||
333 | 'label' => Yii::t('hipanel', 'Type'), |
||||||
334 | 'format' => 'html', |
||||||
335 | 'filter' => false, |
||||||
336 | 'value' => function ($model) { |
||||||
337 | return Html::tag('span', $model->type_label, ['class' => 'label label-default']); |
||||||
338 | }, |
||||||
339 | 'contentOptions' => function ($model) { |
||||||
340 | return GridLegend::create($this->findOrFailGridLegend($model))->gridColumnOptions('actions'); |
||||||
341 | }, |
||||||
342 | ], |
||||||
343 | 'rack' => [ |
||||||
344 | 'class' => BindingColumn::class, |
||||||
345 | ], |
||||||
346 | 'net' => [ |
||||||
347 | 'class' => BindingColumn::class, |
||||||
348 | ], |
||||||
349 | 'kvm' => [ |
||||||
350 | 'class' => BindingColumn::class, |
||||||
351 | ], |
||||||
352 | 'pdu' => [ |
||||||
353 | 'class' => BindingColumn::class, |
||||||
354 | ], |
||||||
355 | 'ipmi' => [ |
||||||
356 | 'class' => BindingColumn::class, |
||||||
357 | ], |
||||||
358 | 'location' => [ |
||||||
359 | 'class' => BindingColumn::class, |
||||||
360 | ], |
||||||
361 | 'nums' => [ |
||||||
362 | 'label' => '', |
||||||
363 | 'format' => 'raw', |
||||||
364 | 'value' => function ($model) { |
||||||
365 | $ips_num = $model->ips_num; |
||||||
366 | $ips = $ips_num ? Html::a("$ips_num ips", IpController::getSearchUrl(['server' => $model->name])) : 'no ips'; |
||||||
367 | $act_acs_num = $model->acs_num - $model->del_acs_num; |
||||||
368 | $del_acs_num = $model->del_acs_num; |
||||||
369 | $acs_num = $act_acs_num . ($del_acs_num ? "+$del_acs_num" : ''); |
||||||
370 | $acs = $acs_num ? Html::a("$acs_num acc", AccountController::getSearchUrl(['server' => $model->name])) : 'no acc'; |
||||||
371 | |||||||
372 | return Html::tag('nobr', $ips) . ' ' . Html::tag('nobr', $acs); |
||||||
373 | }, |
||||||
374 | ], |
||||||
375 | 'monthly_fee' => [ |
||||||
376 | 'label' => Yii::t('hipanel:finance', 'Monthly fee'), |
||||||
377 | 'format' => 'html', |
||||||
378 | 'filter' => false, |
||||||
379 | 'value' => function ($model) { |
||||||
380 | return $this->getMonthlyFee($model); |
||||||
381 | }, |
||||||
382 | 'visible' => Yii::$app->user->can('consumption.read'), |
||||||
383 | ], |
||||||
384 | 'traffic' => [ |
||||||
385 | 'label' => Yii::t('hipanel:server', 'Traffic'), |
||||||
386 | 'format' => 'html', |
||||||
387 | 'filter' => false, |
||||||
388 | 'value' => function ($model) { |
||||||
389 | return isset($model->consumptions['overuse,server_traf_max']) ? $this->getFormattedConsumptionFor($model->consumptions['overuse,server_traf_max']) : null; |
||||||
390 | }, |
||||||
391 | 'visible' => Yii::$app->user->can('consumption.read'), |
||||||
392 | ], |
||||||
393 | 'additional_services' => [ |
||||||
394 | 'label' => Yii::t('hipanel:server', 'Additional services'), |
||||||
395 | 'format' => 'raw', |
||||||
396 | 'filter' => false, |
||||||
397 | 'contentOptions' => ['class' => 'no-padding'], |
||||||
398 | 'value' => function ($model) { |
||||||
399 | return $this->getAdditionalServices($model); |
||||||
400 | }, |
||||||
401 | 'visible' => Yii::$app->user->can('consumption.read'), |
||||||
402 | ], |
||||||
403 | 'type_of_sale' => [ |
||||||
404 | 'label' => Yii::t('hipanel:server', 'Type of sale'), |
||||||
405 | 'format' => 'raw', |
||||||
406 | 'filter' => false, |
||||||
407 | 'value' => function (Server $model) { |
||||||
408 | return $this->getTypeOfSale($model); |
||||||
409 | }, |
||||||
410 | 'visible' => Yii::$app->user->can('consumption.read'), |
||||||
411 | ], |
||||||
412 | 'actions' => [ |
||||||
413 | 'class' => MenuColumn::class, |
||||||
414 | 'menuClass' => ServerActionsMenu::class, |
||||||
415 | 'contentOptions' => [ |
||||||
416 | 'class' => 'text-center', |
||||||
417 | 'style' => 'width:1%; white-space:nowrap;', |
||||||
418 | ], |
||||||
419 | ], |
||||||
420 | 'hwsummary' => [ |
||||||
421 | 'filterAttribute' => 'hwsummary_like', |
||||||
422 | 'label' => Yii::t('hipanel:server', 'Hardware Summary'), |
||||||
423 | ], |
||||||
424 | 'hwcomment' => [ |
||||||
425 | 'filter' => false, |
||||||
426 | 'label' => Yii::t('hipanel:server', 'Hardware Comment'), |
||||||
427 | ], |
||||||
428 | ]); |
||||||
429 | } |
||||||
430 | |||||||
431 | private function getFormattedConsumptionFor(Consumption $consumption): string |
||||||
432 | { |
||||||
433 | $result = ''; |
||||||
434 | $widget = Yii::createObject(['class' => ResourceConsumptionTable::class, 'model' => $consumption]); |
||||||
435 | |||||||
436 | if ($limit = $widget->getFormatted($consumption, $consumption->limit)) { |
||||||
0 ignored issues
–
show
The property
limit does not exist on hipanel\modules\server\models\Consumption . Since you implemented __get , consider adding a @property annotation.
Loading history...
|
|||||||
437 | $result .= sprintf('%s: %s<br />', |
||||||
438 | Html::tag('b', Yii::t('hipanel:server', 'included')), |
||||||
439 | $limit |
||||||
440 | ); |
||||||
441 | } |
||||||
442 | if ($price = $consumption->getFormattedPrice()) { |
||||||
443 | $result .= sprintf('%s: %s', |
||||||
444 | Html::tag('b', Yii::t('hipanel:server', 'price')), |
||||||
445 | $price |
||||||
446 | ); |
||||||
447 | } |
||||||
448 | |||||||
449 | return $result; |
||||||
450 | } |
||||||
451 | |||||||
452 | private function getMonthlyFee($model): string |
||||||
453 | { |
||||||
454 | $unionConsumption = new Consumption(); |
||||||
455 | $prices = []; |
||||||
456 | if ($model->consumptions) { |
||||||
457 | array_walk($model->consumptions, function (Consumption $consumption) use (&$prices) { |
||||||
458 | if ($consumption->type && $consumption->hasFormattedAttributes() && StringHelper::startsWith($consumption->type, 'monthly,')) { |
||||||
459 | if ($consumption->price) { |
||||||
0 ignored issues
–
show
The property
price does not exist on hipanel\modules\server\models\Consumption . Since you implemented __get , consider adding a @property annotation.
Loading history...
|
|||||||
460 | $consumption->setAttribute('prices', [$consumption->currency => $consumption->price]); |
||||||
0 ignored issues
–
show
The property
currency does not exist on hipanel\modules\server\models\Consumption . Since you implemented __get , consider adding a @property annotation.
Loading history...
|
|||||||
461 | } |
||||||
462 | foreach ($consumption->prices as $currency => $price) { |
||||||
0 ignored issues
–
show
The property
prices does not exist on hipanel\modules\server\models\Consumption . Since you implemented __get , consider adding a @property annotation.
Loading history...
|
|||||||
463 | $prices[$currency] += $price; |
||||||
464 | } |
||||||
465 | } |
||||||
466 | }); |
||||||
467 | } |
||||||
468 | $unionConsumption->setAttribute('prices', $prices); |
||||||
469 | |||||||
470 | return $unionConsumption->getFormattedPrice(); |
||||||
471 | } |
||||||
472 | |||||||
473 | private function getAdditionalServices($model): string |
||||||
474 | { |
||||||
475 | $additional = new class() extends Model { |
||||||
476 | /** |
||||||
477 | * @var string |
||||||
478 | */ |
||||||
479 | public $typeLabel; |
||||||
480 | |||||||
481 | /** |
||||||
482 | * @var string |
||||||
483 | */ |
||||||
484 | public $value; |
||||||
485 | }; |
||||||
486 | $models = []; |
||||||
487 | foreach (['overuse,support_time', 'overuse,backup_du', 'monthly,win_license'] as $type) { |
||||||
488 | if (isset($model->consumptions[$type]) && $model->consumptions[$type]->hasFormattedAttributes()) { |
||||||
489 | $consumption = $model->consumptions[$type]; |
||||||
490 | $models[] = new $additional([ |
||||||
491 | 'typeLabel' => Yii::t('hipanel.server.consumption.type', $consumption->typeLabel), |
||||||
492 | 'value' => $this->getFormattedConsumptionFor($consumption), |
||||||
493 | ]); |
||||||
494 | } |
||||||
495 | } |
||||||
496 | |||||||
497 | return \yii\grid\GridView::widget([ |
||||||
498 | 'layout' => '{items}', |
||||||
499 | 'showOnEmpty' => false, |
||||||
500 | 'emptyText' => '', |
||||||
501 | 'tableOptions' => ['class' => 'table table-striped table-condensed'], |
||||||
502 | 'headerRowOptions' => [ |
||||||
503 | 'style' => 'display: none;', |
||||||
504 | ], |
||||||
505 | 'dataProvider' => new ArrayDataProvider(['allModels' => $models, 'pagination' => false]), |
||||||
506 | 'columns' => [ |
||||||
507 | [ |
||||||
508 | 'attribute' => 'typeLabel', |
||||||
509 | ], |
||||||
510 | [ |
||||||
511 | 'attribute' => 'value', |
||||||
512 | 'format' => 'html', |
||||||
513 | ], |
||||||
514 | ], |
||||||
515 | ]); |
||||||
516 | } |
||||||
517 | |||||||
518 | private function getTypeOfSale(Server $model): string |
||||||
519 | { |
||||||
520 | $html = ''; |
||||||
521 | $badgeColors = [ |
||||||
522 | 'leasing' => 'bg-orange', |
||||||
523 | 'rent' => 'bg-purple', |
||||||
524 | 'sold' => 'bg-olive', |
||||||
525 | ]; |
||||||
526 | |||||||
527 | if (empty($model->hardwareSales)) { |
||||||
528 | return $html; |
||||||
529 | } |
||||||
530 | |||||||
531 | $salesByType = [ |
||||||
532 | HardwareSale::USAGE_TYPE_LEASING => [], |
||||||
533 | HardwareSale::USAGE_TYPE_COLO => [], |
||||||
534 | HardwareSale::USAGE_TYPE_RENT => [], |
||||||
535 | ]; |
||||||
536 | foreach ($model->hardwareSales as $sale) { |
||||||
537 | $salesByType[$sale->usage_type][] = $sale; |
||||||
538 | } |
||||||
539 | |||||||
540 | foreach ($salesByType as $usageType => $sales) { |
||||||
541 | $html .= ArraySpoiler::widget([ |
||||||
542 | 'data' => Sort::by($sales, function (HardwareSale $sale) { |
||||||
543 | $order = ['CHASSIS', 'MOTHERBOARD', 'CPU', 'RAM', 'HDD', 'SSD']; |
||||||
544 | $type = substr($sale->part, 0, strpos($sale->part, ':')); |
||||||
545 | $key = array_search($type, $order, true); |
||||||
546 | if ($key !== false) { |
||||||
547 | return $key; |
||||||
548 | } |
||||||
549 | |||||||
550 | return INF; |
||||||
551 | }), |
||||||
552 | 'delimiter' => '<br/>', |
||||||
553 | 'visibleCount' => 0, |
||||||
554 | 'button' => [ |
||||||
555 | 'label' => (function () use ($usageType, $sales) { |
||||||
556 | if ($usageType === HardwareSale::USAGE_TYPE_LEASING) { |
||||||
557 | /** @var \DateTime $maxLeasingDate */ |
||||||
558 | $maxLeasingDate = array_reduce($sales, function (\DateTime $max, HardwareSale $item) { |
||||||
559 | $date = $item->saleTime(); |
||||||
560 | |||||||
561 | return $date > $max ? $date : $max; |
||||||
562 | }, new \DateTime()); |
||||||
563 | |||||||
564 | return Yii::t('hipanel:server', $usageType) . ' ' . \count($sales) |
||||||
565 | . '<br />' . $maxLeasingDate->format('d.m.Y'); |
||||||
566 | } |
||||||
567 | |||||||
568 | return Yii::t('hipanel:server', $usageType) . ' ' . \count($sales); |
||||||
569 | })(), |
||||||
570 | 'tag' => 'button', |
||||||
571 | 'type' => 'button', |
||||||
572 | 'class' => "btn btn-xs {$badgeColors[$usageType]}", |
||||||
573 | 'popoverOptions' => [ |
||||||
574 | 'html' => true, |
||||||
575 | 'placement' => 'bottom', |
||||||
576 | 'title' => Yii::t('hipanel:server', 'Parts') . ' ' |
||||||
577 | . Html::a( |
||||||
578 | Yii::t('hipanel:server', 'To new tab {icon}', ['icon' => '<i class="fa fa-external-link"></i>']), |
||||||
579 | Url::toSearch('part', ['dst_name_in' => $model->name]), |
||||||
580 | ['class' => 'pull-right', 'target' => '_blank'] |
||||||
581 | ), |
||||||
582 | 'template' => ' |
||||||
583 | <div class="popover" role="tooltip"> |
||||||
584 | <div class="arrow"></div> |
||||||
585 | <h3 class="popover-title"></h3> |
||||||
586 | <div class="popover-content" style="height: 25rem; overflow-x: scroll;"></div> |
||||||
587 | </div> |
||||||
588 | ', |
||||||
589 | ], |
||||||
590 | ], |
||||||
591 | 'formatter' => function (HardwareSale $item) { |
||||||
592 | $additionalInfo = null; |
||||||
593 | $title = $item->part; |
||||||
594 | if (isset($item->serialno)) { |
||||||
595 | $title .= ': ' . $item->serialno; |
||||||
596 | } |
||||||
597 | |||||||
598 | if (isset($item->leasing_till)) { |
||||||
599 | $additionalInfo = Yii::t('hipanel:server', '{since} — {till}', [ |
||||||
600 | 'since' => Yii::$app->formatter->asDate($item->leasing_since, 'short'), |
||||||
601 | 'till' => Yii::$app->formatter->asDate($item->leasing_till, 'short'), |
||||||
602 | ]); |
||||||
603 | } |
||||||
604 | |||||||
605 | if (isset($item->sale_time)) { |
||||||
606 | $additionalInfo = Yii::t('hipanel:server', 'since {date}', [ |
||||||
607 | 'date' => Yii::$app->formatter->asDate($item->sale_time, 'short'), |
||||||
608 | ]); |
||||||
609 | } |
||||||
610 | |||||||
611 | return Html::a( |
||||||
612 | $title, |
||||||
613 | ['@part/view', 'id' => $item['part_id']], |
||||||
614 | ['class' => 'text-nowrap', 'target' => '_blank'] |
||||||
615 | ) . ($additionalInfo ? " ($additionalInfo)" : ''); |
||||||
616 | }, |
||||||
617 | ]); |
||||||
618 | } |
||||||
619 | |||||||
620 | return $html; |
||||||
621 | } |
||||||
622 | } |
||||||
623 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths