PluginProbe
ShiftController Employee Shift Scheduling / 4.9.85
ShiftController Employee Shift Scheduling v4.9.85
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / sh4 / shifts / view / widget.php

widget.php in ShiftController Employee Shift Scheduling 4.9.85, at sh4/shifts/view/widget.php

713 lines 16.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if (! defined('ABSPATH')) exit; // Exit if accessed directly
2 #[AllowDynamicProperties]
3 class SH4_Shifts_View_Widget
4 {
5 protected $ui = NULL;
6 protected $t = NULL;
7 protected $shiftTemplates = array();
8 protected $minimalisticWidget = 0;
9
10 public function __construct(
11 HC3_Hooks $hooks,
12 HC3_Ui $ui,
13 HC3_Time $t,
14 HC3_Settings $settings,
15 HC3_Users_Presenter $usersPresenter,
16 SH4_App_Query $appQuery,
17 HC3_Auth $auth,
18
19 SH4_Shifts_View_Common $shiftsViewCommon,
20
21 SH4_ShiftTypes_Query $shiftTypes,
22 SH4_ShiftTypes_Presenter $shiftTypesPresenter,
23 SH4_Employees_Presenter $employeesPresenter,
24
25 SH4_Calendars_Presenter $calendarPresenter,
26
27 SH4_Shifts_Conflicts $conflicts
28 )
29 {
30 $this->self = $hooks->wrap( $this );
31 $this->settings = $hooks->wrap( $settings );
32 $this->auth = $hooks->wrap( $auth );
33 $this->ui = $ui;
34 $this->t = $t;
35
36 $this->conflicts = $hooks->wrap( $conflicts );
37 $this->usersPresenter = $hooks->wrap( $usersPresenter );
38 $this->employeesPresenter = $hooks->wrap( $employeesPresenter );
39 $this->calendarPresenter = $hooks->wrap( $calendarPresenter );
40
41 // $this->shiftTypes = array();
42 $this->shiftTypesPresenter = $hooks->wrap($shiftTypesPresenter);
43 $this->shiftsViewCommon = $hooks->wrap( $shiftsViewCommon );
44
45 $this->shiftTypes = array();
46 if( $settings->get('shifttypes_show_title') ){
47 $this->shiftTypes = $hooks->wrap( $shiftTypes )->findAll();
48 }
49 $this->appQuery = $hooks->wrap($appQuery);
50
51 $this->minimalisticWidget = $settings->get('datetime_minimalistic_week');
52 }
53
54 public function prepare( SH4_Shifts_Model $model, $iknow = array() )
55 {
56 static $cache = array();
57
58 $id = $model->getId();
59
60 if( isset($cache[$id]) ){
61 return $cache[$id];
62 }
63
64 $out = array();
65
66 $calendar = $model->getCalendar();
67 $color = $calendar->getColor();
68
69 $employee = $model->getEmployee();
70
71 $start = $model->getStart();
72 $this->t->setDateTimeDb($start);
73 $startDate = $this->t->formatDateDb();
74
75 $dateView = $this->t->formatDate();
76 $weekdayView = $this->t->getWeekdayName();
77 $dateView = $weekdayView . ', ' . $dateView;
78
79 $startView = $this->t->formatTime();
80 $startInDay = $model->getStartInDay();
81 $endInDay = $model->getEndInDay();
82
83 $end = $model->getEnd();
84 $endView = $this->t->setDateTimeDb($end)->formatTime();
85
86 $breakStartInDay = NULL;
87 $breakEndInDay = NULL;
88 $breakStart = $model->getBreakStart();
89 $breakEnd = $model->getBreakEnd();
90
91 if( $breakStart && $breakEnd ){
92 $this->t->setDateTimeDb( $breakStart );
93 $breakStartTs = $this->t->getTimestamp();
94 $this->t->setStartDay();
95 $startDay = $this->t->getTimestamp();
96 $breakStartInDay = $breakStartTs - $startDay;
97
98 $this->t->setDateTimeDb( $breakEnd );
99 $breakEndTs = $this->t->getTimestamp();
100 $breakEndInDay = $breakEndTs - $startDay;
101 }
102 $shiftKey = $startInDay . '-' . $endInDay . '-' . $breakStartInDay . '-' . $breakEndInDay;
103
104 if( (0 == $startInDay) && (0 == $endInDay) ){
105 $endDate = $this->t->setDateTimeDb($end)->modify('-1 second')->formatDateDb();
106 if( $startDate != $endDate ){
107 $dateView = $this->t->formatDateRange( $startDate, $endDate );
108 // $dateView = $weekdayView . ', ' . $dateView;
109 $iknow = HC3_Functions::removeFromArray( $iknow, 'date' );
110 }
111 }
112
113 if( ! in_array('date', $iknow) ){
114 $out['date'] = $dateView;
115 }
116
117 if( ! in_array('time', $iknow) ){
118 $hasAllDayType = NULL;
119
120 $timeView = NULL;
121 $timeMiscView = NULL;
122 reset( $this->shiftTypes );
123 foreach( $this->shiftTypes as $shiftType ){
124 $thisTimeInDay = $shiftType->getStart() . '-' . $shiftType->getEnd();
125
126 if( '0-86400' == $thisTimeInDay ){
127 $hasAllDayType = $shiftType->getTitle();
128 }
129
130 $thisKey = $shiftType->getStart() . '-' . $shiftType->getEnd() . '-' . $shiftType->getBreakStart() . '-' . $shiftType->getBreakEnd();
131 if( $thisKey == $shiftKey ){
132 // $timeView = $shiftType->getTitle();
133 $timeView = $this->shiftTypesPresenter->presentTitle( $shiftType );
134 $timeMiscView = $startView . ' - ' . $endView;
135 break;
136 }
137 }
138
139 if( ! $timeView ){
140 if( (0 == $startInDay) && ((24*60*60 == $endInDay) OR (0 == $endInDay)) ){
141 $timeView = $hasAllDayType ? $hasAllDayType : '__All Day__';
142 }
143 else {
144 // overnight shift
145 if( $endInDay > 24*60*60 ){
146 $endView = '&gt;' . $endView;
147 }
148
149 $timeView = $startView . ' - ' . $endView;
150 }
151 }
152
153 $out['time'] = $timeView;
154 if( $timeMiscView ){
155 // $out['timemisc'] = $timeMiscView;
156 }
157 }
158
159 if( ! in_array('calendar', $iknow) ){
160 $calendarView = $this->calendarPresenter->presentTitle( $calendar );
161
162 if( $model->isDraft() ){
163 $calendarView
164 ->addAttr('class', 'hc-bg-striped')
165 ;
166 }
167
168 $out['calendar'] = $calendarView;
169 }
170
171 if( ! in_array('employee', $iknow) ){
172 $employeeView = $this->employeesPresenter->presentTitle( $employee );
173 $out['employee'] = $employeeView;
174 }
175
176 $cache[$id] = $out;
177
178 return $out;
179 }
180
181 public function renderTitle( $model )
182 {
183 $prepared = $this->self->prepare( $model );
184
185 $out = array();
186 foreach( $prepared as $k => $v ){
187 $v = strip_tags( $v );
188 $out[] = $v;
189 }
190 $out = join( "\n", $out );
191 return $out;
192 }
193
194 public function render( SH4_Shifts_Model $model, $iknow = array(), $hori = FALSE, $noLink = FALSE, $groupedQty = NULL )
195 {
196 $out = $this->self->prepare( $model, $iknow );
197 if( $this->minimalisticWidget ){
198 $ret = $this->self->renderPreparedMinimalistic( $model, $out, $iknow, $hori, $noLink, $groupedQty );
199 }
200 else {
201 $ret = $this->self->renderPrepared( $model, $out, $iknow, $hori, $noLink, $groupedQty );
202 }
203 return $ret;
204 }
205
206 public function renderCompact( SH4_Shifts_Model $model, $iknow = array(), $groupedQty = NULL )
207 {
208 $id = $model->getId();
209 $calendar = $model->getCalendar();
210 $color = $calendar->getColor();
211 $employee = $model->getEmployee();
212
213 $out = '&nbsp;';
214
215 $label = null;
216
217 $what = $this->settings->get( 'datetime_compact_shift_label' );
218 if( 'abbr2' == $what ){
219 $startInDay = $model->getStartInDay();
220 $endInDay = $model->getEndInDay();
221
222 $breakStartInDay = NULL;
223 $breakEndInDay = NULL;
224 $breakStart = $model->getBreakStart();
225 $breakEnd = $model->getBreakEnd();
226 if( $breakStart && $breakEnd ){
227 $this->t->setDateTimeDb( $breakStart );
228 $breakStartTs = $this->t->getTimestamp();
229 $this->t->setStartDay();
230 $startDay = $this->t->getTimestamp();
231 $breakStartInDay = $breakStartTs - $startDay;
232
233 $this->t->setDateTimeDb( $breakEnd );
234 $breakEndTs = $this->t->getTimestamp();
235 $breakEndInDay = $breakEndTs - $startDay;
236 }
237 $shiftKey = $startInDay . '-' . $endInDay . '-' . $breakStartInDay . '-' . $breakEndInDay;
238
239 reset( $this->shiftTypes );
240 foreach( $this->shiftTypes as $shiftType ){
241 $thisTimeInDay = $shiftType->getStart() . '-' . $shiftType->getEnd();
242
243 if( '0-86400' == $thisTimeInDay ){
244 $hasAllDayType = $shiftType->getTitle();
245 }
246
247 $thisKey = $shiftType->getStart() . '-' . $shiftType->getEnd() . '-' . $shiftType->getBreakStart() . '-' . $shiftType->getBreakEnd();
248 if( $thisKey == $shiftKey ){
249 $label = $this->shiftTypesPresenter->presentTitle( $shiftType );
250 break;
251 }
252 }
253 }
254 else {
255 if( ! in_array('calendar', $iknow) ){
256 $label = $calendar->getTitle();
257 }
258 elseif( ! in_array('employee', $iknow) ){
259 $label = $employee->getTitle();
260 }
261 if( 'none' == $what ){
262 $label = null;
263 }
264 }
265
266 if( null !== $label ){
267 // abbreviation
268 $label = str_replace( '-', ' ', $label );
269 $label = str_replace( '_', ' ', $label );
270 $label = str_replace( ' ', ' ', $label );
271 $label = str_replace( ' ', ' ', $label );
272
273 $label = explode( ' ', $label );
274
275 $finalLabel = array();
276 foreach( $label as $l ){
277 $l = substr( $l, 0, 1 );
278 $finalLabel[] = $l;
279 if( count($finalLabel) >= 2 ){
280 break;
281 }
282 }
283
284 $label = join( '', $finalLabel );
285 }
286 else {
287 $label = '&nbsp;';
288 }
289
290 if( NULL !== $groupedQty ){
291 $label = $groupedQty . 'x';
292 }
293
294 $out = $this->ui->makeBlock( $label )
295 ->padding(1)
296 ->tag('nowrap')
297 ->tag('align', 'center')
298 // ->tag('font-size', 2)
299 ;
300
301 $out
302 ->tag('border')
303 ;
304
305 $conflicts = array();
306 $currentUser = $this->auth->getCurrentUser();
307 $currentUserId = $currentUser->getId();
308 if( $currentUserId ){
309 $conflicts = $this->conflicts->get( $model );
310 }
311
312 if( $conflicts ){
313 $out
314 ->tag('border-color', 'red')
315 ;
316 }
317 else {
318 $out
319 ->tag('border-color', $color)
320 ;
321 }
322
323 if( $model->isDraft() ){
324 $out
325 ->addAttr('style', 'border-style: dashed;')
326 ;
327 }
328
329 $finalOut = array();
330 $finalOut[] = $out;
331
332 $out = $this->ui->makeBlock( $this->ui->makeCollection($finalOut) )
333 ->addAttr('style', 'position: relative;')
334 ;
335
336 $out
337 ->addAttr('class', 'hc-bg-lighten-2')
338 ;
339
340 $out = $this->ui->makeBlock( $out )
341 ->tag('bgcolor', $color)
342 ;
343 if( $model->isDraft() ){
344 $out
345 ->addAttr('class', 'hc-bg-striped')
346 ;
347 $out
348 ->tag('muted', 1)
349 ;
350 }
351
352 $title = $this->self->renderTitle( $model );
353 $out
354 ->addAttr('title', $title)
355 ;
356
357 return $out;
358 }
359
360 public function renderPrepared( SH4_Shifts_Model $model, $out, $iknow = array(), $hori = FALSE, $noLink = FALSE, $groupedQty = NULL )
361 {
362 $colorFont = TRUE;
363 $colorFont = FALSE;
364
365 $id = $model->getId();
366 $calendar = $model->getCalendar();
367
368 if( $calendar->isAvailability() ){
369 $iknow[] = 'calendar';
370 }
371
372 $color = $calendar->getColor();
373 $icons = $this->shiftsViewCommon->icons( $model, $iknow );
374
375 // conflicts
376 $conflicts = array();
377 if( ! in_array('conflicts', $iknow) ){
378 $currentUser = $this->auth->getCurrentUser();
379 $currentUserId = $currentUser->getId();
380 if( $currentUserId ){
381 $conflicts = $this->conflicts->get( $model );
382 }
383 }
384
385 // highlight
386 // $highlight = array('employee', 'time', 'date');
387 $highlight = array('employee', 'time');
388
389 if( $calendar->isShift() ){
390 foreach( $highlight as $hl ){
391 if( ! array_key_exists($hl, $out) ){
392 continue;
393 }
394 $out[$hl] = $this->ui->makeSpan( $out[$hl] )
395 // ->tag('font-size', 4)
396 ->tag('font-style', 'bold')
397 ;
398 }
399 }
400
401 $mute = array('timemisc');
402
403 foreach( $mute as $mt ){
404 if( ! array_key_exists($mt, $out) ){
405 continue;
406 }
407 $out[$mt] = $this->ui->makeSpan( $out[$mt] )
408 ->tag('font-size', 2)
409 ->tag('muted')
410 ;
411 }
412
413 $keys = array_keys($out);
414 $firstKey = array_shift($keys);
415
416 if( NULL !== $groupedQty ){
417 $out[$firstKey] = $groupedQty . ' x ' . $out[$firstKey];
418 }
419
420 // LINK
421 if( $id < 0 ) $noLink = TRUE;
422
423 if( ! $noLink ){
424 $to = 'shifts/' . $id;
425 $out[$firstKey] = $this->ui->makeAhref( $to, $out[$firstKey] )
426 // ->tag('unstyled-link')
427 ->tag('block')
428 ->tag('print')
429 ->addAttr('class', 'sh4-widget-loader')
430 ;
431
432 if( $colorFont ){
433 if( ! $calendar->isAvailability() ){
434 $out[$firstKey]
435 ->tag('color', $color)
436 ->addAttr( 'class', 'hc-underline' );
437 ;
438 }
439 }
440 }
441
442 if( $hori ){
443 $return = $this->ui->makeGrid();
444 $width = '1-' . count($out);
445 foreach( $out as $o ){
446 $return->add( $o, $width, 12 );
447 }
448 $out = $return;
449 }
450 else {
451 $out = $this->ui->makeList($out)->gutter(0);
452 }
453
454 $out = $this->ui->makeBlock( $out )
455 ->padding(1)
456 // ->tag('font-size', 2);
457 ->tag('nowrap')
458 ;
459
460 $out
461 ->tag('border')
462 ;
463
464 // return $out;
465
466 if( $conflicts ){
467 $out
468 ->tag('border-color', 'red')
469 ;
470 }
471 else {
472 $out
473 ->tag('border-color', $color)
474 ;
475 }
476
477 if( $model->isDraft() ){
478 $out
479 ->addAttr('style', 'border-style: dashed;')
480 ;
481 }
482
483 $finalOut = array();
484
485 if( $icons ){
486 $iconsList = array();
487 foreach( $icons as $field => $thisIcons ){
488 $iconsList = array_merge( $iconsList, $thisIcons );
489 }
490
491 $icons = $this->ui->makeListInline( $iconsList )->gutter(1);
492 $icons = $this->ui->makeBlock($icons)
493 ->addAttr('style', 'position: absolute; right:.2em; top:.2em; z-index: 100;')
494 ;
495 $finalOut[] = $icons;
496 }
497
498 $finalOut[] = $out;
499
500 $out = $this->ui->makeBlock( $this->ui->makeCollection($finalOut) )
501 ->addAttr('style', 'position: relative;')
502 ;
503
504 $out
505 ->addAttr('class', 'hc-bg-lighten-2')
506 ;
507
508 $out = $this->ui->makeBlock( $out )
509 // ->tag('bgcolor', $color)
510 ;
511
512 if( ! $calendar->isAvailability() ){
513 $out
514 ->tag('bgcolor', $color)
515 ;
516
517 if( $colorFont ){
518 $out
519 ->tag('color', $color)
520 ;
521 }
522 }
523
524 if( $model->isDraft() ){
525 if( ! $calendar->isAvailability() ){
526 $out
527 ->addAttr('class', 'hc-bg-striped')
528 ;
529 }
530 $out
531 ->tag('muted', 1)
532 ;
533 }
534
535
536 $title = $this->self->renderTitle( $model );
537 $out
538 ->addAttr('title', $title)
539 ;
540
541 return $out;
542 }
543
544 public function renderPreparedMinimalistic( SH4_Shifts_Model $model, $out, $iknow = array(), $hori = FALSE, $noLink = FALSE, $groupedQty = NULL )
545 {
546 $colorFont = false;
547 $title = $this->self->renderTitle( $model );
548
549 $id = $model->getId();
550 $calendar = $model->getCalendar();
551
552 $color = $calendar->getColor();
553 $icons = $this->shiftsViewCommon->icons( $model, $iknow );
554
555 // conflicts
556 $conflicts = array();
557 if( ! in_array('conflicts', $iknow) ){
558 $currentUser = $this->auth->getCurrentUser();
559 $currentUserId = $currentUser->getId();
560 if( $currentUserId ){
561 $conflicts = $this->conflicts->get( $model );
562 }
563 }
564
565 // highlight
566 $highlight = array('employee', 'time');
567
568 if( $calendar->isShift() ){
569 foreach( $highlight as $hl ){
570 if( ! array_key_exists($hl, $out) ){
571 continue;
572 }
573 $out[$hl] = $this->ui->makeSpan( $out[$hl] )
574 // ->tag('font-size', 4)
575 ->tag('font-style', 'bold')
576 ;
577 }
578 }
579
580 $mute = array('timemisc');
581 foreach( $mute as $mt ){
582 if( ! array_key_exists($mt, $out) ){
583 continue;
584 }
585 $out[$mt] = $this->ui->makeSpan( $out[$mt] )
586 ->tag('font-size', 2)
587 ->tag('muted')
588 ;
589 }
590
591 // $filter = array( 'time' => true, 'calendar' => true, 'employee' => true );
592 // $out = array_intersect_key( $out, $filter );
593 // if( isset($out['time']) && isset($out['calendar']) ){
594 // $out['calendar'] = $this->ui->makeListInline( array($out['calendar'], $out['time']) )->gutter(1);
595 // unset( $out['time'] );
596 // }
597
598 $filter = array( 'calendar' => true, 'employee' => true );
599 $out = array_intersect_key( $out, $filter );
600
601 $keys = array_keys($out);
602 $firstKey = array_shift($keys);
603
604 if( NULL !== $groupedQty ){
605 $out[$firstKey] = $groupedQty . ' x ' . $out[$firstKey];
606 }
607
608 // LINK
609 if( $id < 0 ) $noLink = TRUE;
610
611 if( ! $noLink ){
612 $to = 'shifts/' . $id;
613 $out[$firstKey] = $this->ui->makeAhref( $to, $out[$firstKey] )
614 // ->tag('unstyled-link')
615 ->tag('block')
616 ->tag('print')
617 ->addAttr('class', 'sh4-widget-loader')
618 ->setAttr('title', $title)
619 ;
620 }
621
622 $hori = true;
623 if( $hori ){
624 $return = $this->ui->makeGrid();
625 $width = '1-' . count($out);
626 foreach( $out as $o ){
627 $return->add( $o, $width, 12 );
628 }
629 $out = $return;
630 }
631 else {
632 $out = $this->ui->makeList($out)->gutter(0);
633 }
634
635 $out = $this->ui->makeBlock( $out )
636 ->padding(1)
637 // ->tag('font-size', 2);
638 ->tag('nowrap')
639 ;
640
641 $out
642 ->tag('border')
643 ;
644
645 // return $out;
646
647 if( $conflicts ){
648 $out
649 ->tag('border-color', 'red')
650 ;
651 }
652 else {
653 $out
654 ->tag('border-color', $color)
655 ;
656 }
657
658 if( $model->isDraft() ){
659 $out
660 ->addAttr('style', 'border-style: dashed;')
661 ;
662 }
663
664 $finalOut = array();
665
666 if( $icons ){
667 $iconsList = array();
668 foreach( $icons as $field => $thisIcons ){
669 $iconsList = array_merge( $iconsList, $thisIcons );
670 }
671
672 $icons = $this->ui->makeListInline( $iconsList )->gutter(1);
673 $icons = $this->ui->makeBlock($icons)
674 ->addAttr('style', 'position: absolute; right:.2em; top:.2em; z-index: 100;')
675 ;
676 $finalOut[] = $icons;
677 }
678
679 $finalOut[] = $out;
680
681 $out = $this->ui->makeBlock( $this->ui->makeCollection($finalOut) )
682 ->addAttr('style', 'position: relative;')
683 ;
684
685 $out
686 ->addAttr('class', 'hc-bg-lighten-2')
687 ;
688
689 $out = $this->ui->makeBlock( $out )
690 // ->tag('bgcolor', $color)
691 ;
692
693 $out
694 ->tag('bgcolor', $color)
695 ;
696
697 if( $model->isDraft() ){
698 $out
699 ->addAttr('class', 'hc-bg-striped')
700 ;
701 $out
702 ->tag('muted', 1)
703 ;
704 }
705
706 $out
707 // ->tag('font-size', 2)
708 ->setAttr('title', $title)
709 ;
710
711 return $out;
712 }
713 }