Completed
Push — FVSv2 ( 1cdbcb...01e32a )
by Patrick
01:36
created

GridSchedule::grayOutUnused()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 3
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
1
<?php
2
namespace Schedules;
3
4
use PhpOffice\PhpSpreadsheet\Spreadsheet;
5
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
6
use PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf;
7
8
require_once('../../api/v1/class.Processor.php');
9
10
class GridSchedule
11
{
12
    use ShiftSchedule;
13
    use \Processor;
14
15
    protected $department;
16
    protected $shifts;
17
    protected $ssheat;
18
19
    public function __construct($department, $shifts)
20
    {
21
        $this->department = $department;
22
        $this->shifts = $shifts;
23
        $this->ssheat = $this->createSpreadSheet();
24
    }
25
26
    protected function isVolunteerAdmin()
27
    {
28
        return true;
29
    }
30
31
    protected function getSimpleHour($hour)
32
    {
33
        if($hour < 12)
34
        {
35
            if($hour === 0)
36
            {
37
                return '12a';
38
            }
39
            return $hour.'a';
40
        }
41
        if($hour === 12)
42
        {
43
            return $hour.'p';
44
        }
45
        return ($hour - 12).'p';
46
    }
47
48
    protected function grayOutUnused($hourCount, $rowCount, $sheat)
49
    {
50
        for($i = 0; $i < $hourCount; $i++)
51
        {
52
            for($j = 0; $j < $rowCount; $j++)
53
            {
54
                 $cell = $sheat->getCellByColumnAndRow($i+2, $j+4);
55
                 if($cell->isInMergeRange())
56
                 {
57
                      continue;
58
                 }
59
                 else
60
                 {
61
                     $style = $cell->getStyle();
62
                     $style->getBorders()->getAllBorders()->setBorderStyle(false);
63
                     $style->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_PATTERN_LIGHTGRAY);
64
                 }
65
            }
66
        }
67
    }
68
69
    protected function setShiftNameInCell($sheat, $col, $row, $shift)
70
    {
71
        if(isset($shift['participant']))
72
        {
73
            $sheat->setCellValueByColumnAndRow($col, $row, $this->getParticipantDiplayName($shift['participant']));
74
        }
75
    }
76
77
    protected function getHoursArrays($hour, $hourCount)
78
    {
79
        $simpleHours = array();
80
        $militaryHours = array();
81
        for($i = 0; $i < $hourCount; $i++)
82
        {
83
            array_push($simpleHours, $this->getSimpleHour($hour));
84
            array_push($militaryHours, $hour.':00');
85
            $hour++;
86
            if($hour === 24)
87
            {
88
                $hour = 0;
89
            }
90
        }
91
        return array($simpleHours, $militaryHours);
92
    }
93
94
    protected function createShiftCell($sheat, $col, $row, $shift)
95
    {
96
        $sheat->mergeCellsByColumnAndRow($col, $row, $col+$shift['length']-1, $row);
97
        $this->setShiftNameInCell($sheat, $col, $row, $shift);
98
    }
99
100
    protected function getRowForShift($roleID, $rows, $col, $sheat)
101
    {
102
        $firstRow = array_search($roleID, $rows);
103
        $cell = $sheat->getCellByColumnAndRow($col, $firstRow+4);
104
        if($cell->isInMergeRange())
105
        {
106
            while($rows[$firstRow+$i] === $roleID)
0 ignored issues
show
Bug introduced by
The variable $i does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
107
            {
108
                $cell = $sheat->getCellByColumnAndRow($hoursFromStart+2, $firstRow+4+$i);
0 ignored issues
show
Bug introduced by
The variable $hoursFromStart does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
109
                if(!$cell->isInMergeRange())
110
                {
111
                    break;
112
                }
113
                $i++;
114
            }
115
            return $firstRow+4+$i;
116
        }
117
        return $firstRow+4;
118
    }
119
120
    protected function createSpreadSheet()
121
    {
122
        $shifts = $this->shifts;
123
        $dept = $this->department;
124
        $ssheat = new Spreadsheet();
125
        $sheat = $ssheat->getActiveSheet();
126
        $sheat->setCellValue('A1', $dept['departmentName']);
127
        $count = count($shifts);
128
        $days = array();
129
        $roles = array();
130
        $roles2 = array();
131
        for($i = 0; $i < $count; $i++)
132
        {
133
            $start = new \DateTime($shifts[$i]['startTime']);
134
            $end = new \DateTime($shifts[$i]['endTime']);
135
            $shifts[$i]['startTime'] = $start;
136
            $shifts[$i]['endTime'] = $end;
137
            $startDateStr = $start->format('l (n/j/Y)');
138
            $endDateStr = $end->format('l (n/j/Y)');
139
            $days[$startDateStr] = 1;
140
            $days[$endDateStr] = 1;
141
            $diff = $start->diff($end);
142
            $shifts[$i]['length'] = $diff->h;
143
            if(!isset($roles[$shifts[$i]['roleID']]))
144
            {
145
                 $roles[$shifts[$i]['roleID']] = $shifts[$i]['length'];
146
                 $roles2[$shifts[$i]['roleID']] = array();
147
            }
148
            else
149
            {
150
                 if($roles[$shifts[$i]['roleID']] < $shifts[$i]['length'])
151
                 {
152
                     $roles[$shifts[$i]['roleID']] = $shifts[$i]['length'];
153
                 }
154
            }
155
            array_push($roles2[$shifts[$i]['roleID']], array('start'=>$start, 'end'=>$end));
156
        }
157
        arsort($roles);
158
        usort($shifts, array($this, 'shiftTimeSort'));
159
        $originalStartTime = $shifts[0]['startTime'];
160
        $str = $shifts[0]['startTime']->format('c');
161
        $start = date_parse($str);
162
        $lastShift = $shifts[$count - 1];
163
        $interval = $lastShift['endTime']->diff($shifts[0]['startTime']);
164
        $hourCount = ($interval->d*24) + $interval->h;
165
        $tmp = $this->getHoursArrays($start['hour'], $hourCount);
166
        $simpleHours = $tmp[0];
167
        $militaryHours = $tmp[1];
168
        $sheat->fromArray($simpleHours, null, 'B2');
169
        $sheat->fromArray($militaryHours, null, 'B3');
170
        $mergeCount = 24 - $start['hour'];
171
        if($mergeCount > $hourCount)
172
        {
173
            $mergeCount = $hourCount;
174
        }
175
        $days = array_keys($days);
176
        $cellIndex = 2;
177
        while($mergeCount)
178
        {
179
            $sheat->mergeCellsByColumnAndRow($cellIndex, 1, $cellIndex + $mergeCount - 1, 1);
180
            $sheat->setCellValueByColumnAndRow($cellIndex, 1, array_shift($days));
181
            $cell = $sheat->getCellByColumnAndRow($cellIndex, 1);
182
            $cell->getStyle()->getAlignment()->setHorizontal('center');
183
            $cellIndex += $mergeCount;
184
            $hourCount -= $mergeCount;
185
            $mergeCount = $hourCount;
186
            if($mergeCount > 24)
187
            {
188
                $mergeCount = 24;
189
            }
190
        }
191
        $i = 0;
192
        $rows = array();
193
        foreach($roles as $role=>$hour)
194
        {
195
            $sheat->setCellValueByColumnAndRow(1, 4 + $i, $this->getRoleNameFromID($role));
196
            array_push($rows, $role);
197
            $overlaps = array();
198
            for($j = 0; $j < count($roles2[$role]) - 1; $j++)
199
            {
200
                $currRole = $roles2[$role][$j];
201
                $nextRole = $roles2[$role][$j + 1];
202
                if($currRole['end'] > $nextRole['start'])
203
                {
204
                    $str = $currRole['start']->format('c');
205
                    if(!isset($overlaps[$str]))
206
                    {
207
                        $overlaps[$str] = 0;
208
                    }
209
                    $overlaps[$str]++;
210
                }
211
            }
212
            if(!empty($overlaps))
213
            {
214
                $overlapCount = max(array_values($overlaps));
215
                for($j = 0; $j < $overlapCount + 1; $j++)
216
                {
217
                    $i++;
218
                    $sheat->setCellValueByColumnAndRow(1, 4 + $i, $this->getRoleNameFromID($role));
219
                    if($j > 0)
220
                    {
221
                        array_push($rows, $role);
222
                    }
223
                }
224
            }
225
            else
226
            {
227
                $i++;
228
            }
229
        }
230
        $shift = array_shift($shifts);
231
        while($shift)
232
        {
233
            $i = 1;
0 ignored issues
show
Unused Code introduced by
$i is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
234
            $timeDiff = $originalStartTime->diff($shift['startTime']);
235
            $hoursFromStart = ($timeDiff->d*24)+$timeDiff->h;
236
            $rowForShift = $this->getRowForShift($shift['roleID'], $rows, $hoursFromStart+2, $sheat);
237
            $this->createShiftCell($sheat, $hoursFromStart+2, $rowForShift, $shift);
238
            $shift = array_shift($shifts);
239
        }
240
        $rowCount = count($rows);
241
        $style = $sheat->getStyleByColumnAndRow(2, 4, 1+count($simpleHours), 3 + $rowCount);
242
        $style->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
243
        $hourCount = count($simpleHours);
244
        $this->grayOutUnused($hourCount, $rowCount, $sheat);
245
        $sheat->getColumnDimension('A')->setAutoSize(true);
246
        return $ssheat;
247
    }
248
249
    public function getBuffer($type)
250
    {
251
        if($type === 'XLSX')
252
        {
253
            $writer = new Xlsx($this->ssheat);
254
            $content = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
255
            $extension = '.xlsx';
256
        }
257
        else if($type === 'PDF')
258
        {
259
            $this->ssheat->getActiveSheet()->getPageSetup()->setOrientation(\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);
260
            $writer = new mpdf($this->ssheat);
261
            $writer->setOrientation(\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);
262
            $content = 'application/pdf';
263
            $extension = '.pdf';
264
        }
265
        else
266
        {
267
            return array('error'=> true, 'msg'=>'Unknown type specified: '.$type);
268
        }
269
        ob_start();
270
        $writer->save('php://output');
271
        $str = ob_get_clean();
272
        return array('content-type'=>$content, 'extension'=>$extension, 'buffer'=>$str); 
273
    }
274
275
    public function shiftSort($a, $b)
276
    {
277
        return strcmp($this->getRoleNameFromID($a['roleID']), $this->getRoleNameFromID($b['roleID']));
278
    }
279
280
    public function groupSort($a, $b)
281
    {
282
        $aArr = explode(' ', $a);
283
        $bArr = explode(' ', $b);
284
        if($aArr[1] === 'PM' && $bArr[1] === 'AM')
285
        {
286
            return 1;
287
        }
288
        else if($aArr[1] === 'AM' && $bArr[1] === 'PM')
289
        {
290
            return -1;
291
        }
292
        return strcmp($a, $b);
293
    }
294
295
    public function shiftTimeSort($a, $b)
296
    {
297
        $interval = $a['startTime']->diff($b['startTime']);
298
        if($interval->invert === 0)
299
        {
300
            if($interval->h || $interval->i)
301
            {
302
                return -1;
303
            }
304
            else
305
            {
306
                return 0;
307
            }
308
        }
309
        else if($interval->invert === 1 && ($interval->h || $interval->days))
310
        {
311
            return 1;
312
        }
313
        print_r($interval);
314
        die();
315
    }
316
}
317