Test Setup Failed
Push — master ( 4e700f...c7183e )
by Julito
63:12
created

Career::parseSubGroups()   F

Complexity

Conditions 35
Paths > 20000

Size

Total Lines 171
Code Lines 119

Duplication

Lines 24
Ratio 14.04 %

Importance

Changes 0
Metric Value
cc 35
eloc 119
nc 289556
nop 5
dl 24
loc 171
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Fhaculty\Graph\Graph;
5
use Fhaculty\Graph\Vertex;
6
7
/**
8
 * Class Career
9
 */
10
class Career extends Model
11
{
12
    public $table;
13
    public $columns = array(
14
        'id',
15
        'name',
16
        'description',
17
        'status',
18
        'created_at',
19
        'updated_at'
20
    );
21
22
    /**
23
     * Constructor
24
     */
25
    public function __construct()
26
    {
27
        $this->table = Database::get_main_table(TABLE_CAREER);
28
    }
29
30
    /**
31
     * Get the count of elements
32
     * @return int
33
     */
34
    public function get_count()
35
    {
36
        $row = Database::select(
37
            'count(*) as count',
38
            $this->table,
39
            array(),
40
            'first'
41
        );
42
        return $row['count'];
43
    }
44
45
    /**
46
     * @param array $where_conditions
47
     * @return array
48
     */
49
    public function get_all($where_conditions = array())
50
    {
51
        return Database::select(
52
            '*',
53
            $this->table,
54
            array('where' => $where_conditions, 'order' => 'name ASC')
55
        );
56
    }
57
58
    /**
59
     * Update all promotion status by career
60
     * @param   int     $career_id
61
     * @param   int     $status (1 or 0)
62
     */
63
    public function update_all_promotion_status_by_career_id($career_id, $status)
64
    {
65
        $promotion = new Promotion();
66
        $promotion_list = $promotion->get_all_promotions_by_career_id($career_id);
67
        if (!empty($promotion_list)) {
68
            foreach ($promotion_list as $item) {
69
                $params['id'] = $item['id'];
70
                $params['status'] = $status;
71
                $promotion->update($params);
72
                $promotion->update_all_sessions_status_by_promotion_id($params['id'], $status);
73
            }
74
        }
75
    }
76
77
    /**
78
     * Displays the title + grid
79
     */
80 View Code Duplication
    public function display()
81
    {
82
        echo '<div class="actions" style="margin-bottom:20px">';
83
        echo '<a href="career_dashboard.php">'.
84
            Display::return_icon('back.png', get_lang('Back'), '', ICON_SIZE_MEDIUM).'</a>';
85
        echo '<a href="'.api_get_self().'?action=add">'.
86
                Display::return_icon('new_career.png', get_lang('Add'), '', ICON_SIZE_MEDIUM).'</a>';
87
        echo '</div>';
88
        echo Display::grid_html('careers');
89
    }
90
91
    /**
92
     * @return array
93
     */
94
    public function get_status_list()
95
    {
96
        return array(
97
            CAREER_STATUS_ACTIVE => get_lang('Unarchived'),
98
            CAREER_STATUS_INACTIVE => get_lang('Archived')
99
        );
100
    }
101
102
    /**
103
     * Returns a Form validator Obj
104
     * @todo the form should be auto generated
105
     * @param   string  $url
106
     * @param   string  $action add, edit
107
     * @return  FormValidator
108
     */
109 View Code Duplication
    public function return_form($url, $action)
110
    {
111
        $form = new FormValidator('career', 'post', $url);
112
        // Setting the form elements
113
        $header = get_lang('Add');
114
        if ($action == 'edit') {
115
            $header = get_lang('Modify');
116
        }
117
118
        $form->addElement('header', $header);
119
        $id = isset($_GET['id']) ? intval($_GET['id']) : '';
120
        $form->addElement('hidden', 'id', $id);
121
        $form->addElement('text', 'name', get_lang('Name'), array('size' => '70'));
122
        $form->addHtmlEditor(
123
            'description',
124
            get_lang('Description'),
125
            false,
126
            false,
127
            array(
128
                'ToolbarSet' => 'Careers',
129
                'Width' => '100%',
130
                'Height' => '250'
131
            )
132
        );
133
        $status_list = $this->get_status_list();
134
        $form->addElement('select', 'status', get_lang('Status'), $status_list);
135
        if ($action == 'edit') {
136
            $form->addElement('text', 'created_at', get_lang('CreatedAt'));
137
            $form->freeze('created_at');
138
        }
139
        if ($action == 'edit') {
140
            $form->addButtonSave(get_lang('Modify'), 'submit');
141
        } else {
142
            $form->addButtonCreate(get_lang('Add'), 'submit');
143
        }
144
145
        // Setting the defaults
146
        $defaults = $this->get($id);
147
148
        if (!empty($defaults['created_at'])) {
149
            $defaults['created_at'] = api_convert_and_format_date($defaults['created_at']);
150
        }
151
        if (!empty($defaults['updated_at'])) {
152
            $defaults['updated_at'] = api_convert_and_format_date($defaults['updated_at']);
153
        }
154
        $form->setDefaults($defaults);
155
156
        // Setting the rules
157
        $form->addRule('name', get_lang('ThisFieldIsRequired'), 'required');
158
159
        return $form;
160
    }
161
162
    /**
163
     * Copies the career to a new one
164
     * @param   integer     Career ID
165
     * @param   boolean     Whether or not to copy the promotions inside
166
     * @return  integer     New career ID on success, false on failure
167
     */
168
    public function copy($id, $copy_promotions = false)
169
    {
170
        $career = $this->get($id);
171
        $new = array();
172
        foreach ($career as $key => $val) {
173
            switch ($key) {
174
                case 'id':
175
                case 'updated_at':
176
                    break;
177
                case 'name':
178
                    $val .= ' '.get_lang('CopyLabelSuffix');
179
                    $new[$key] = $val;
180
                    break;
181
                case 'created_at':
182
                    $val = api_get_utc_datetime();
183
                    $new[$key] = $val;
184
                    break;
185
                default:
186
                    $new[$key] = $val;
187
                    break;
188
            }
189
        }
190
        $cid = $this->save($new);
191
        if ($copy_promotions) {
192
            //Now also copy each session of the promotion as a new session and register it inside the promotion
193
            $promotion = new Promotion();
194
            $promo_list = $promotion->get_all_promotions_by_career_id($id);
195
            if (!empty($promo_list)) {
196
                foreach ($promo_list as $item) {
197
                    $promotion->copy($item['id'], $cid, true);
198
                }
199
            }
200
        }
201
202
        return $cid;
203
    }
204
205
    /**
206
     * @param int $career_id
207
     * @return bool
208
     */
209 View Code Duplication
    public function get_status($career_id)
210
    {
211
        $TBL_CAREER = Database::get_main_table(TABLE_CAREER);
212
        $career_id = intval($career_id);
213
        $sql = "SELECT status FROM $TBL_CAREER WHERE id = '$career_id'";
214
        $result = Database::query($sql);
215
        if (Database::num_rows($result) > 0) {
216
            $data = Database::fetch_array($result);
217
            return $data['status'];
218
        } else {
219
            return false;
220
        }
221
    }
222
223
    /**
224
     * @param array $params
225
     * @param bool $show_query
226
     * @return bool
227
     */
228
    public function save($params, $show_query = false)
229
    {
230
        if (isset($params['description'])) {
231
            $params['description'] = Security::remove_XSS($params['description']);
232
        }
233
234
        $id = parent::save($params);
235
        if (!empty($id)) {
236
            Event::addEvent(
237
                LOG_CAREER_CREATE,
238
                LOG_CAREER_ID,
239
                $id,
240
                api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
241
                api_get_user_id()
242
            );
243
        }
244
245
        return $id;
246
    }
247
248
    /**
249
     * Delete a record from the career table and report in the default events log table
250
     * @param int $id The ID of the career to delete
251
     * @return bool True if the career could be deleted, false otherwise
252
     */
253
    public function delete($id)
254
    {
255
        $res = parent::delete($id);
256
        if ($res) {
257
            $extraFieldValues = new ExtraFieldValue('career');
258
            $extraFieldValues->deleteValuesByItem($id);
259
            Event::addEvent(
260
                LOG_CAREER_DELETE,
261
                LOG_CAREER_ID,
262
                $id,
263
                api_get_utc_datetime(),
0 ignored issues
show
Bug introduced by
It seems like api_get_utc_datetime() can also be of type object<DateTime>; however, Event::addEvent() does only seem to accept string|null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
264
                api_get_user_id()
265
            );
266
        }
267
        return $res;
268
    }
269
270
    /**
271
     * Update the career table with the given params
272
     * @param array $params The field values to be set
273
     * @return bool Returns true if the record could be updated, false otherwise
274
     */
275
    public function update($params)
276
    {
277
        if (isset($params['description'])) {
278
            $params['description'] = Security::remove_XSS($params['description']);
279
        }
280
281
        return parent::update($params);
282
    }
283
284
    /**
285
     * @param array
286
     * @param Graph $graph
287
     *
288
     * @return string
289
     */
290
    public static function renderDiagram($careerInfo, $graph)
291
    {
292
        if (!($graph instanceof Graph)) {
293
            return '';
294
        }
295
296
        $debug = false;
297
298
        // Getting max column
299
        $maxColumn = 0;
300
        foreach ($graph->getVertices() as $vertex) {
301
            $groupId = (int) $vertex->getGroup();
302
            if ($groupId > $maxColumn) {
303
                $maxColumn = $groupId;
304
            }
305
        }
306
307
        $list = [];
308
        /** @var Vertex $vertex */
309
        foreach ($graph->getVertices() as $vertex) {
310
            $group = $vertex->getAttribute('Group');
311
            $subGroup = $vertex->getAttribute('SubGroup');
312
            $subGroupData = explode(':', $subGroup);
313
            $column = $vertex->getGroup();
314
            $row = $vertex->getAttribute('Row');
315
            $subGroupId = $subGroupData[0];
316
            $label = isset($subGroupData[1]) ? $subGroupData[1] : '';
317
            $list[$group][$subGroupId]['columns'][$column][$row] = $vertex;
318
            $list[$group][$subGroupId]['label'] = $label;
319
        }
320
321
        $maxGroups = count($list);
322
        $widthGroup = 30;
323
        if (!empty($maxGroups)) {
324
            $widthGroup = 85 / $maxGroups;
325
        }
326
327
        $connections = '';
328
        $groupDrawLine = [];
329
        $groupCourseList = [];
330
331
        // Read Connections column
332
        foreach ($list as $group => $subGroupList) {
333
            foreach ($subGroupList as $subGroupData) {
334
                $columns = $subGroupData['columns'];
335
                $showGroupLine = true;
336
                if (count($columns) == 1) {
337
                    $showGroupLine = false;
338
                }
339
                $groupDrawLine[$group] = $showGroupLine;
340
341
                //if ($showGroupLine == false) {
342
                /** @var Vertex $vertex */
343
                foreach ($columns as $row => $items) {
344
                    foreach ($items as $vertex) {
345
                        if ($vertex instanceof Vertex) {
346
                            $groupCourseList[$group][] = $vertex->getId();
347
                            $connectionList = $vertex->getAttribute(
348
                                'Connections'
349
                            );
350
                            $firstConnection = '';
351
                            $secondConnection = '';
352
                            if (!empty($connectionList)) {
353
                                $explode = explode('-', $connectionList);
354
                                $pos = strpos($explode[0], 'SG');
355 View Code Duplication
                                if ($pos === false) {
356
                                    $pos = strpos($explode[0], 'G');
357
                                    if (is_numeric($pos)) {
358
                                        // group_123 id
359
                                        $groupValueId = (int)str_replace(
360
                                            'G',
361
                                            '',
362
                                            $explode[0]
363
                                        );
364
                                        $firstConnection = 'group_'.$groupValueId;
365
                                        $groupDrawLine[$groupValueId] = true;
366
                                    } else {
367
                                        // Course block (row_123 id)
368
                                        if (!empty($explode[0])) {
369
                                            $firstConnection = 'row_'.(int) $explode[0];
370
                                        }
371
                                    }
372
                                } else {
373
                                    // subgroup__123 id
374
                                    $firstConnection = 'subgroup_'.(int)str_replace('SG', '', $explode[0]);
375
                                }
376
377
                                $pos = strpos($explode[1], 'SG');
378 View Code Duplication
                                if ($pos === false) {
379
                                    $pos = strpos($explode[1], 'G');
380
                                    if (is_numeric($pos)) {
381
                                        $groupValueId = (int)str_replace(
382
                                            'G',
383
                                            '',
384
                                            $explode[1]
385
                                        );
386
                                        $secondConnection = 'group_'.$groupValueId;
387
                                        $groupDrawLine[$groupValueId] = true;
388
                                    } else {
389
                                        // Course block (row_123 id)
390
                                        if (!empty($explode[0])) {
391
                                            $secondConnection = 'row_'.(int) $explode[1];
392
                                        }
393
                                    }
394
                                } else {
395
                                    $secondConnection = 'subgroup_'.(int)str_replace('SG', '', $explode[1]);
396
                                }
397
398
                                if (!empty($firstConnection) && !empty($firstConnection)) {
399
                                    $connections .= self::createConnection(
400
                                        $firstConnection,
401
                                        $secondConnection,
402
                                        ['Left', 'Right']
403
                                    );
404
                                }
405
                            }
406
                        }
407
                    }
408
                }
409
                //}
410
            }
411
        }
412
413
        $graphHtml = '<div class="container">';
414
        foreach ($list as $group => $subGroupList) {
415
            $showGroupLine = false;
416
            if (isset($groupDrawLine[$group]) && $groupDrawLine[$group]) {
417
                $showGroupLine = true;
418
            }
419
            $graphHtml .= self::parseSubGroups(
420
                $groupCourseList,
421
                $group,
422
                $showGroupLine,
423
                $subGroupList,
424
                $widthGroup
425
            );
426
        }
427
        $graphHtml .= '</div>';
428
        $graphHtml .= $connections;
429
430
        return $graphHtml;
431
    }
432
433
    /**
434
     * @param array $groupCourseList list of groups and their courses
435
     * @param int $group
436
     * @param bool $showGroupLine
437
     * @param array $subGroupList
438
     * @param $widthGroup
439
     * @return string
440
     */
441
    public static function parseSubGroups(
442
        $groupCourseList,
443
        $group,
444
        $showGroupLine,
445
        $subGroupList,
446
        $widthGroup
447
    ) {
448
        $topValue = 90;
449
        $defaultSpace = 40;
450
        $leftGroup = $defaultSpace.'px';
451
        if ($group == 1) {
452
            $leftGroup = 0;
453
        }
454
455
        $groupIdTag = "group_$group";
456
        $borderLine = $showGroupLine === true ? 'border-style:solid;' : '';
457
        // padding:15px;
458
        $graphHtml = '<div id="'.$groupIdTag.'" class="career_group" style=" '.$borderLine.' padding:15px; float:left; margin-left:'.$leftGroup.'; width:'.$widthGroup.'%">';
459
460
        foreach ($subGroupList as $subGroup => $subGroupData) {
461
            $subGroupLabel = $subGroupData['label'];
462
            $columnList = $subGroupData['columns'];
463
464
            $line = '';
465
            if (!empty($subGroup)) {
466
                $line = 'border-style:solid;';
467
            }
468
            // padding:15px;
469
            $graphHtml .= '<div id="subgroup_'.$subGroup.'" class="career_subgroup" style="'.$line.' margin-bottom:20px; padding:15px; float:left; margin-left:0px; width:100%">';
470
            if (!empty($subGroupLabel)) {
471
                $graphHtml .= '<h3>'.$subGroupLabel.'</h3>';
472
            }
473
            foreach ($columnList as $column => $rows) {
474
                $leftColumn = $defaultSpace.'px';
475
                if ($column == 1) {
476
                    $leftColumn = 0;
477
                }
478
                if (count($columnList) == 1) {
479
                    $leftColumn = 0;
480
                }
481
482
                $widthColumn = 85 / count($columnList);
483
                $graphHtml .= '<div id="col_'.$column.'" class="career_column" style="padding:15px;float:left; margin-left:'.$leftColumn.'; width:'.$widthColumn.'%">';
484
                $maxRow = 0;
485
                foreach ($rows as $row => $vertex) {
486
                    if ($row > $maxRow) {
487
                        $maxRow = $row;
488
                    }
489
                }
490
491
                $newRowList = [];
492
                $defaultSubGroup = -1;
493
                $subGroupCountList = [];
494
                for ($i = 0; $i < $maxRow; $i++) {
495
                    /** @var Vertex $vertex */
496
                    $vertex = isset($rows[$i + 1]) ? $rows[$i + 1] : null;
497
                    if (!is_null($vertex)) {
498
                        $subGroup = $vertex->getAttribute('SubGroup');
499
                        if ($subGroup == '' || empty($subGroup)) {
500
                            $defaultSubGroup = 0;
501
                        } else {
502
                            $defaultSubGroup = (int)$subGroup;
503
                        }
504
                    }
505
                    $newRowList[$i + 1][$defaultSubGroup][] = $vertex;
506
                    if (!isset($subGroupCountList[$defaultSubGroup])) {
507
                        $subGroupCountList[$defaultSubGroup] = 1;
508
                    } else {
509
                        $subGroupCountList[$defaultSubGroup]++;
510
                    }
511
                }
512
513
                $subGroup = null;
514
                $subGroupAdded = [];
515
                /** @var Vertex $vertex */
516
                foreach ($newRowList as $row => $subGroupList) {
517
                    foreach ($subGroupList as $subGroup => $vertexList) {
518
                        if (!empty($subGroup) && $subGroup != -1) {
519
                            if (!isset($subGroupAdded[$subGroup])) {
520
                                $subGroupAdded[$subGroup] = 1;
521
                            } else {
522
                                $subGroupAdded[$subGroup]++;
523
                            }
524
                        }
525
526
                        foreach ($vertexList as $vertex) {
527
                            if (is_null($vertex)) {
528
                                $graphHtml .= '<div class="career_empty" style="height: 130px">';
529
                                $graphHtml .= '</div>';
530
                                continue;
531
                            }
532
533
                            $id = $vertex->getId();
534
                            $rowId = "row_$row";
535
                            $graphHtml .= '<div id = "row_'.$id.'" class="'.$rowId.' career_row" >';
536
                            $color = '';
537
                            if (!empty($vertex->getAttribute('DefinedColor'))) {
538
                                $color = $vertex->getAttribute('DefinedColor');
539
                            }
540
                            $content = $vertex->getAttribute('Notes');
541
                            $content .= '<div class="pull-right">['.$id.']</div>';
542
543
                            $graphHtml .= Display::panel(
544
                                $content,
545
                                $vertex->getAttribute('graphviz.label'),
546
                                null,
547
                                null,
548
                                null,
549
                                null,
550
                                $color
551
                            );
552
                            $graphHtml .= '</div>';
553
554
                            $arrow = $vertex->getAttribute('DrawArrowFrom');
555
                            $found = false;
556
                            if (!empty($arrow)) {
557
                                $pos = strpos($arrow, 'SG');
558
                                if ($pos === false) {
559
                                    $pos = strpos($arrow, 'G');
560 View Code Duplication
                                    if (is_numeric($pos)) {
561
                                        $parts = explode('G', $arrow);
562
                                        if (empty($parts[0]) && count($parts) == 2) {
563
                                            $groupArrow = $parts[1];
564
                                            $graphHtml .= self::createConnection(
565
                                                "group_$groupArrow",
566
                                                "row_$id",
567
                                                ['Left', 'Right']
568
                                            );
569
                                            $found = true;
570
                                        }
571
                                    }
572 View Code Duplication
                                } else {
573
                                    $parts = explode('SG', $arrow);
574
                                    if (empty($parts[0]) && count($parts) == 2) {
575
                                        $subGroupArrow = $parts[1];
576
                                        /*var_dump($subGroupArrow);
577
                                        var_dump(array_keys($subGroupList));*/
578
                                        $graphHtml .= self::createConnection(
579
                                            "subgroup_$subGroupArrow",
580
                                            "row_$id",
581
                                            ['Left', 'Right']
582
                                        );
583
                                        $found = true;
584
                                    }
585
                                }
586
                            }
587
588
                            if ($found == false) {
589
                                $defaultArrow = ['Left', 'Right'];
590
                                if (isset($groupCourseList[$group]) &&
591
                                    in_array($arrow, $groupCourseList[$group])
592
                                ) {
593
                                    $defaultArrow = ['Top', 'Bottom'];
594
                                }
595
                                $graphHtml .= self::createConnection(
596
                                    "row_$arrow",
597
                                    "row_$id",
598
                                    $defaultArrow
599
                                );
600
                            }
601
                        }
602
                    }
603
                }
604
                $graphHtml .= '</div>';
605
            }
606
            $graphHtml .= '</div>';
607
        }
608
        $graphHtml .= '</div>';
609
610
        return $graphHtml;
611
    }
612
613
    /**
614
     * @param string $source
615
     * @param string $target
616
     * @param array $anchor
617
     * @return string
618
     */
619
    public static function createConnection($source, $target, $anchor = [])
620
    {
621
        if (empty($anchor)) {
622
            // Default
623
            $anchor = ['Bottom', 'Right'];
624
        }
625
626
        $anchor = implode('","', $anchor);
627
        $html = '<script>
628
629
        var connectorPaintStyle = {
630
            strokeWidth: 2,
631
            stroke: "#a31ed3",
632
            joinstyle: "round",
633
            outlineStroke: "white",
634
            outlineWidth: 2
635
        },
636
        // .. and this is the hover style.
637
        connectorHoverStyle = {
638
            strokeWidth: 3,
639
            stroke: "#216477",
640
            outlineWidth: 5,
641
            outlineStroke: "white"
642
        },
643
        endpointHoverStyle = {
644
            fill: "#E80CAF",
645
            stroke: "#E80CAF"
646
        };
647
        jsPlumb.ready(function() { ';
648
        $html .= 'jsPlumb.connect({
649
            source:"'.$source.'",
650
            target:"'.$target.'",
651
            endpoint:[ "Rectangle", { width:1, height:1 }],                                        
652
            connector: ["Flowchart"],             
653
            paintStyle: connectorPaintStyle,    
654
            hoverPaintStyle: endpointHoverStyle,                
655
            anchor: ["'.$anchor.'"],
656
            overlays: [
657
                [ 
658
                    "Arrow", 
659
                    { 
660
                        location:1,  
661
                        width:11, 
662
                        length:11 
663
                    } 
664
                ],
665
            ],
666
        });';
667
        $html .= '});</script>'.PHP_EOL;
668
669
        return $html;
670
    }
671
}
672