Completed
Push — master ( 8c2a67...711ae7 )
by Daniel
02:48
created

DomComponentsByDanielGP   F

Complexity

Total Complexity 146

Size/Duplication

Total Lines 738
Duplicated Lines 13.14 %

Coupling/Cohesion

Components 4
Dependencies 2

Importance

Changes 33
Bugs 0 Features 6
Metric Value
wmc 146
c 33
b 0
f 6
lcom 4
cbo 2
dl 97
loc 738
rs 1.0434

13 Methods

Rating   Name   Duplication   Size   Complexity  
A normalizeArrayForUrl() 0 12 3
A setArrayToSelect() 0 17 3
A setArrayToStringForUrl() 0 7 1
F setArrayToTable() 54 399 93
A setCalendarControl() 12 12 1
A setCalendarControlWithTime() 12 12 1
A setFooterCommon() 0 7 3
A setFooterCommonInjected() 0 11 3
C setHeaderCommon() 19 68 14
C setTableCell() 0 58 16
A setTableHeader() 0 13 3
A setUpperRightBoxLanguages() 0 12 1
A setUpperRightVisibleOnHoverLanguages() 0 18 4

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like DomComponentsByDanielGP often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DomComponentsByDanielGP, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 *
5
 * The MIT License (MIT)
6
 *
7
 * Copyright (c) 2015 Daniel Popiniuc
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a copy
10
 * of this software and associated documentation files (the "Software"), to deal
11
 * in the Software without restriction, including without limitation the rights
12
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
 * copies of the Software, and to permit persons to whom the Software is
14
 * furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included in all
17
 * copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
 * SOFTWARE.
26
 *
27
 */
28
29
namespace danielgp\common_lib;
30
31
/**
32
 * DOM component functions
33
 *
34
 * @author Daniel Popiniuc
35
 */
36
trait DomComponentsByDanielGP
37
{
38
39
    use DomCssAndJavascriptByDanielGP,
40
        DomDynamicSelectByDanielGP;
41
42
    private function normalizeArrayForUrl($featArray)
43
    {
44
        $outArray = [];
45
        foreach ($featArray as $key => $value) {
46
            if (is_numeric($key)) {
47
                $outArray[$value] = 1;
48
            } else {
49
                $outArray[$key] = $value;
50
            }
51
        }
52
        return $outArray;
53
    }
54
55
    /**
56
     * Builds a <select> based on a given array
57
     *
58
     * @version 20080618
59
     * @param array $aElements
60
     * @param string/array $sDefaultValue
0 ignored issues
show
Documentation introduced by
The doc-type string/array could not be parsed: Unknown type name "string/array" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
61
     * @param string $selectName
62
     * @param array $featArray
63
     * @return string
64
     */
65
    protected function setArrayToSelect($aElements, $sDefaultValue, $selectName, $featArray = null)
66
    {
67
        if (!is_array($aElements)) {
68
            return '';
69
        }
70
        if (isset($featArray['readonly'])) {
71
            $inputFeatures = [
72
                'name'     => $selectName,
73
                'id'       => $this->buildSelectId($selectName, $featArray),
74
                'readonly' => 'readonly',
75
                'class'    => 'input_readonly',
76
                'value'    => $sDefaultValue,
77
            ];
78
            return $this->setStringIntoShortTag('input', $inputFeatures) . $aElements[$sDefaultValue];
79
        }
80
        return $this->setArrayToSelectNotReadOnly($aElements, $sDefaultValue, $selectName, $featArray);
81
    }
82
83
    /**
84
     * Converts an array to string
85
     *
86
     * @param string $sSeparator
87
     * @param array $aElements
88
     * @return string
89
     */
90
    protected function setArrayToStringForUrl($sSeparator, $aElements, $aExceptedElements = [''])
91
    {
92
        $outArray   = $this->normalizeArrayForUrl($aElements);
93
        $xptArray   = $this->normalizeArrayForUrl($aExceptedElements);
94
        $finalArray = array_diff_key($outArray, $xptArray);
95
        return http_build_query($finalArray, '', $sSeparator);
96
    }
97
98
    /**
99
     * Returns a table from an query
100
     *
101
     * @param array $gArray
0 ignored issues
show
Bug introduced by
There is no parameter named $gArray. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
102
     * @param array $features
0 ignored issues
show
Bug introduced by
There is no parameter named $features. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
103
     * @param boolean $bKeepFullPage
0 ignored issues
show
Bug introduced by
There is no parameter named $bKeepFullPage. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
104
     * @return string
105
     */
106
    protected function setArrayToTable($aElements, $ftrs = null, $bKpFlPge = true)
0 ignored issues
show
Coding Style introduced by
setArrayToTable uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
setArrayToTable uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
107
    {
108
        $rows = count($aElements);
109
        if ($rows == 0) {
110
            $divTab = [
111
                'start' => '',
112
                'end'   => '',
113
            ];
114
            if (array_key_exists('showGroupingCounter', $ftrs)) {
115
                if (array_key_exists('grouping_cell_type', $ftrs) && ($ftrs['grouping_cell_type'] == 'tab')) {
116
                    $ditTitle = 'No data found';
117
                    if (isset($ftrs['showGroupingCounter'])) {
118
                        $ditTitle .= ' (0)';
119
                    }
120
                    $divTab = [
121
                        'start' => '<div class="tabbertab tabbertabdefault" id="tab_NoData" title="' . $ditTitle . '">',
122
                        'end'   => '</div><!-- from tab_NoData -->',
123
                    ];
124
                    if (!isset($ftrs['noGlobalTab'])) {
125
                        $divTab = [
126
                            'start' => '<div class="tabber" id="tab">' . $divTab['start'],
127
                            'end'   => $divTab['end'] . '</div><!-- from global Tab -->',
128
                        ];
129
                    }
130
                }
131
            }
132
            return $divTab['start']
133
                    . $this->setFeedbackModern('error', 'Error', $this->lclMsgCmn('i18n_NoData'))
134
                    . $divTab['end'];
135
        }
136
        if (isset($ftrs['limits'])) {
137
            $ftrs['limits'][1] = min($ftrs['limits'][1], $ftrs['limits'][2]);
138
            if ($ftrs['limits'][2] > $ftrs['limits'][1]) {
139
                $iStartingPageRecord = 1;
140
            }
141
        }
142
        $sReturn = '';
143
        if (isset($ftrs['hidden_columns'])) {
144
            $hdClmns = $this->setArrayValuesAsKey($ftrs['hidden_columns']);
0 ignored issues
show
Bug introduced by
It seems like setArrayValuesAsKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
145
        } else {
146
            $hdClmns = [''];
147
        }
148
        if ((isset($ftrs['actions']['checkbox_inlineEdit'])) || (isset($ftrs['actions']['checkbox']))) {
149
            $checkboxFormId = 'frm' . date('YmdHis');
150
            $sReturn .= '<form id="' . $checkboxFormId . '" ' . 'name="' . $checkboxFormId
151
                    . '" method="post" ' . ' action="' . $_SERVER['PHP_SELF'] . '" >';
152
        }
153
        $tbl['Def'] = '<table'
0 ignored issues
show
Coding Style Comprehensibility introduced by
$tbl was never initialized. Although not strictly required by PHP, it is generally a good practice to add $tbl = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
154
                . (isset($ftrs['table_style']) ? ' style="' . $ftrs['table_style'] . '"' : '')
155
                . (isset($ftrs['table_class']) ? ' class="' . $ftrs['table_class'] . '"' : '')
156
                . '>';
157
        if (!isset($ftrs['grouping_cell_type'])) {
158
            $ftrs['grouping_cell_type'] = 'row';
159
        }
160
        switch ($ftrs['grouping_cell_type']) {
161
            case 'row':
162
                $sReturn .= $tbl['Def'];
163
                break;
164
            case 'tab':
165
                if (!isset($ftrs['noGlobalTab'])) {
166
                    $sReturn .= '<div class="tabber" id="tab">';
167
                }
168
                break;
169
        }
170
        $iTableColumns    = 0;
171
        $remebered_value  = -1;
172
        $remindGroupValue = null;
173
        $color_no         = null;
174
        if (!isset($ftrs['headers_breaked'])) {
175
            $ftrs['headers_breaked'] = true;
176
        }
177
        for ($rCntr = 0; $rCntr < $rows; $rCntr++) {
178
            if ($rCntr == 0) {
179
                $header        = array_diff_key($aElements[$rCntr], $hdClmns);
180
                $iTableColumns = count($header);
181
                if (isset($ftrs['computed_columns'])) {
182
                    $iTableColumns += count($ftrs['computed_columns']);
183
                }
184
                if (isset($ftrs['actions'])) {
185
                    $iTableColumns += 1;
186
                }
187
                if (isset($ftrs['grouping_cell'])) {
188
                    $iTableColumns -= 1;
189
                }
190
                $tbl['Head'] = '<thead>';
191
                if ($ftrs['grouping_cell_type'] == 'row') {
192
                    $sReturn .= $tbl['Head'];
193
                }
194 View Code Duplication
                if (isset($iStartingPageRecord)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
195
                    $pgn = $this->setPagination($ftrs['limits'][0], $ftrs['limits'][1], $ftrs['limits'][2], $bKpFlPge);
0 ignored issues
show
Bug introduced by
It seems like setPagination() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
196
                    $sReturn .= $this->setStringIntoTag($this->setStringIntoTag($pgn, 'th', [
197
                                'colspan' => $iTableColumns
198
                            ]), 'tr');
199
                }
200
                $tbl['Header'] = '<tr>';
201
                if (isset($ftrs['grouping_cell'])) { // Grouping columns
202
                    $header = array_diff_key($header, [$ftrs['grouping_cell'] => '']);
203
                }
204
                if (isset($ftrs['actions'])) { // Action column
205
                    $tbl['Header'] .= '<th>&nbsp;</th>';
206
                }
207
                if (isset($ftrs['RowStyle'])) { //Exclude style columns from displaying
208
                    $tmpClmns = $this->setArrayValuesAsKey([$ftrs['RowStyle']]);
0 ignored issues
show
Bug introduced by
It seems like setArrayValuesAsKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
209
                    $header   = array_diff_key($header, $tmpClmns);
210
                    $hdClmns  = array_merge($hdClmns, $tmpClmns);
211
                    unset($tmpClmns);
212
                }
213
                $tbl['Header'] .= $this->setTableHeader($header, $ftrs['headers_breaked']); // Regular columns
214
                if (isset($ftrs['computed_columns'])) { // Computed columns
215
                    $tbl['Header'] .= $this->setTableHeader($ftrs['computed_columns'], $ftrs['headers_breaked']);
216
                }
217
                $tbl['Header'] .= '</tr></thead><tbody>';
218
                if ($ftrs['grouping_cell_type'] == 'row') {
219
                    $sReturn .= $tbl['Header'];
220
                }
221
            }
222
            $row_current = array_diff_key($aElements[$rCntr], $hdClmns);
223
            if (isset($ftrs['row_colored_alternated'])) {
224
                if ($ftrs['row_colored_alternated'][0] == '#') {
225
                    $color_column_value = $rCntr;
226
                } else {
227
                    $color_column_value = $row_current[$ftrs['row_colored_alternated'][0]];
228
                }
229
                if ($remebered_value != $color_column_value) {
230
                    if (isset($color_no)) {
231
                        $color_no = 1;
232
                    } else {
233
                        $color_no = 2;
234
                    }
235
                    $remebered_value = $color_column_value;
236
                }
237
                $color = ' style="background-color: ' . $ftrs['row_colored_alternated'][$color_no] . ';"';
238
            } else {
239
                if (isset($ftrs['RowStyle'])) {
240
                    $color = ' style="' . $aElements[$rCntr][$ftrs['RowStyle']] . '"';
241
                } else {
242
                    $color = '';
243
                }
244
            }
245
            $tbl['tr_Color'] = '<tr' . $color . '>';
246
// Grouping column
247
            if (isset($ftrs['grouping_cell'])) {
248
                foreach ($aElements[$rCntr] as $key => $value) {
249
                    if (($ftrs['grouping_cell'] == $key) && ($remindGroupValue != $value)) {
250
                        switch ($ftrs['grouping_cell_type']) {
251
                            case 'row':
252
                                $sReturn .= $tbl['tr_Color'] . '<td ' . 'colspan="' . $iTableColumns . '">'
253
                                        . $this->setStringIntoTag($value, 'div', ['class' => 'rowGroup rounded'])
254
                                        . '</td></tr>';
255
                                break;
256
                            case 'tab':
257
                                if (is_null($remindGroupValue)) {
258
                                    if (isset($ftrs['showGroupingCounter'])) {
259
                                        $groupCounter = 0;
260
                                    }
261
                                } else {
262
                                    $sReturn .= '</tbody></table>';
263
                                    if (isset($ftrs['showGroupingCounter'])) {
264
                                        $sReturn .= $this->updateDivTitleName($remindGroupValue, $groupCounter);
0 ignored issues
show
Bug introduced by
The variable $groupCounter 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...
265
                                        $groupCounter = 0;
266
                                    }
267
                                    $sReturn .= '</div>';
268
                                }
269
                                $sReturn .= '<div class="tabbertab';
270
                                if (isset($ftrs['grouping_default_tab'])) {
271
                                    $sReturn .= ($ftrs['grouping_default_tab'] == $value ? ' tabbertabdefault' : '');
272
                                }
273
                                $sReturn .= '" id="tab_' . $this->cleanStringForId($value) . '" '
274
                                        . 'title="' . $value . '">'
275
                                        . $tbl['Def'] . $tbl['Head'] . $tbl['Header'];
276
                                break;
277
                        }
278
                        $remindGroupValue = $value;
279
                    }
280
                }
281
            }
282
            if (isset($ftrs['grouping_cell'])) {
283
                if ($ftrs['grouping_cell_type'] == 'tab') {
284
                    if (isset($ftrs['showGroupingCounter'])) {
285
                        $groupCounter++;
286
                    }
287
                }
288
            }
289
            $sReturn .= $tbl['tr_Color'];
290
// Action column
291
            if (isset($ftrs['actions'])) {
292
                $sReturn .= '<td style="white-space:nowrap;">';
293
                $action_argument = 0;
294
                if (isset($ftrs['actions']['key'])) {
295
                    $action_key = $ftrs['actions']['key'];
296
                } else {
297
                    $action_key = 'view';
298
                }
299
                if (isset($ftrs['action_prefix'])) {
300
                    $actPrfx    = $ftrs['action_prefix'] . '&amp;';
301
                    $action_key = 'view2';
302
                } else {
303
                    $actPrfx = '';
304
                }
305
                foreach ($ftrs['actions'] as $key => $value) {
306
                    if ($action_argument != 0) {
307
                        $sReturn .= '&nbsp;';
308
                    }
309
                    switch ($key) {
310
                        case 'checkbox':
311
                            $checkboxName  = $value . '[]';
312
                            $checkboxNameS = $value;
313
                            $sReturn .= '&nbsp;<input type="checkbox" name="' . $checkboxName
314
                                    . '" id="n' . $aElements[$rCntr][$value]
315
                                    . '" value="' . $aElements[$rCntr][$value] . '" ';
316
                            if (isset($_REQUEST[$checkboxNameS])) {
317
                                if (is_array($_REQUEST[$checkboxNameS])) {
318
                                    if (in_array($aElements[$rCntr][$value], $_REQUEST[$checkboxNameS])) {
319
                                        $sReturn .= 'checked="checked" ';
320
                                    }
321
                                } else {
322
                                    if ($aElements[$rCntr][$value] == $_REQUEST[$checkboxNameS]) {
323
                                        $sReturn .= 'checked="checked" ';
324
                                    }
325
                                }
326
                            }
327
                            if (strpos($_REQUEST['view'], 'multiEdit') !== false) {
328
                                $sReturn .= 'disabled="disabled" ';
329
                            }
330
                            $sReturn .= '/>';
331
                            break;
332
                        case 'checkbox_inlineEdit':
333
                            $checkboxName  = $value . '[]';
334
                            $checkboxNameS = $value;
335
                            $sReturn .= '&nbsp;<input type="checkbox" name="' . $checkboxName
336
                                    . '" id="n' . $aElements[$rCntr][$value] . '" value="'
337
                                    . $aElements[$rCntr][$value] . '"/>';
338
                            break;
339
                        case 'edit':
340
                            $edt           = '';
341
                            if (isset($ftrs['NoAjaxEditing'])) {
342
                                $edt .= $_SERVER['PHP_SELF'] . '?' . $actPrfx
343
                                        . $action_key . '=' . $value[0] . '&amp;';
344
                                $iActArgs = count($value[1]);
345
                                for ($cntr2 = 0; $cntr2 < $iActArgs; $cntr2++) {
346
                                    $edt .= $value[1][$cntr2] . '=' . $aElements[$rCntr][$value[1][$cntr2]];
347
                                }
348
                                $sReturn .= '<a href="' . $edt . '"><i class="fa fa-pencil">&nbsp;</i></a>';
349 View Code Duplication
                            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
350
                                $edt .= 'javascript:loadAE(\'' . $_SERVER['PHP_SELF'] . '?'
351
                                        . $actPrfx . $action_key . '=' . $value[0] . '&amp;';
352
                                $iActArgs = count($value[1]);
353
                                for ($cntr2 = 0; $cntr2 < $iActArgs; $cntr2++) {
354
                                    $edt .= $value[1][$cntr2] . '=' . $aElements[$rCntr][$value[1][$cntr2]];
355
                                }
356
                                $edt .= '\');';
357
                                $sReturn .= '<a href="#" onclick="' . $edt . '">'
358
                                        . '<i class="fa fa-pencil">&nbsp;</i></a>';
359
                            }
360
                            break;
361
                        case 'list2':
362
                            $edt = '';
363
                            if (isset($ftrs['NoAjaxEditing'])) {
364
                                $sReturn .= '<a href="?' . $actPrfx . $action_key . '=' . $value[0] . '&amp;';
365
                                $iActArgs = count($value[1]);
366
                                for ($cntr2 = 0; $cntr2 < $iActArgs; $cntr2++) {
367
                                    $sReturn .= $value[1][$cntr2] . '=' . $aElements[$rCntr][$value[1][$cntr2]];
368
                                }
369
                                $sReturn .= '"><i class="fa fa-list">&nbsp;</i></a>';
370 View Code Duplication
                            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
371
                                $edt .= 'javascript:loadAE(\'' . $_SERVER['PHP_SELF'] . '?'
372
                                        . $actPrfx . $action_key . '=' . $value[0] . '&amp;';
373
                                $iActArgs = count($value[1]);
374
                                for ($cntr2 = 0; $cntr2 < $iActArgs; $cntr2++) {
375
                                    $edt .= $value[1][$cntr2] . '=' . $aElements[$rCntr][$value[1][$cntr2]];
376
                                }
377
                                $edt .= '\');';
378
                                $sReturn .= '<a href="#" onclick="' . $edt . '">'
379
                                        . '<i class="fa fa-list">&nbsp;</i></a>';
380
                            }
381
                            break;
382
                        case 'delete':
383
                            $sReturn .= '<a href="javascript:setQuest(\'' . $value[0] . '\',\'';
384
                            $iActArgs = count($value[1]);
385
                            for ($cntr2 = 0; $cntr2 < $iActArgs; $cntr2++) {
386
                                $sReturn .= $value[1][$cntr2] . '=' . $aElements[$rCntr][$value[1][$cntr2]];
387
                            }
388
                            $sReturn .= '\');"><i class="fa fa-times">&nbsp;</i></a>';
389
                            break;
390
                    }
391
                    $action_argument += 1;
392
                }
393
                $sReturn .= '</td>';
394
            }
395
// Regular columns
396
            $sReturn .= $this->setTableCell($row_current, $ftrs);
397
// Computed columns
398
            if (isset($ftrs['computed_columns'])) {
399
                foreach ($ftrs['computed_columns'] as $key => $value) {
400
                    if ($value[0] == '%') {
401
                        $dec = $value[2] + 2;
402
                    } else {
403
                        $dec = $value[2];
404
                    }
405
                    switch ($value[1]) {
406
                        case '/':
407
                            // next variable is only to avoid a long line
408
                            $shorter                 = [
409
                                $aElements[$rCntr][$value[3]],
410
                                $aElements[$rCntr][$value[4]],
411
                            ];
412
                            $aElements[$rCntr][$key] = $this->setDividedResult($shorter[0], $shorter[1], $dec);
0 ignored issues
show
Bug introduced by
It seems like setDividedResult() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
413
                            break;
414
                        case '+':
415
                            // next variable is only to avoid a long line
416
                            $iTemp                   = $this->setArrayValuesAsKey([
0 ignored issues
show
Bug introduced by
It seems like setArrayValuesAsKey() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
417
                                $value[0],
418
                                $value[1],
419
                                $value[2]
420
                            ]);
421
                            $aTemp                   = array_diff($value, $iTemp);
422
                            $aElements[$rCntr][$key] = 0;
423
                            foreach ($aTemp as $sValue) {
424
                                $aElements[$rCntr][$key] += $aElements[$rCntr][$sValue];
425
                            }
426
                            break;
427
                        default:
428
                            $row_computed[$key] = '';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$row_computed was never initialized. Although not strictly required by PHP, it is generally a good practice to add $row_computed = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
429
                            break;
430
                    }
431
                    if ($value[0] == '%') {
432
                        $row_computed[$key] = ($aElements[$rCntr][$key] * 100);
0 ignored issues
show
Bug introduced by
The variable $row_computed 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...
433
                        $dec -= 2;
434
                    } else {
435
                        $row_computed[$key] = $aElements[$rCntr][$key];
436
                    }
437
                    $decimals[$key] = $dec;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$decimals was never initialized. Although not strictly required by PHP, it is generally a good practice to add $decimals = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
438
                }
439
// displaying them
440
                $sReturn .= $this->setTableCell($row_computed, ['decimals' => $decimals]);
0 ignored issues
show
Bug introduced by
The variable $decimals 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...
441
            }
442
            $sReturn .= '</tr>';
443
        }
444 View Code Duplication
        if (isset($iStartingPageRecord)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
445
            $pgn = $this->setPagination($ftrs['limits'][0], $ftrs['limits'][1], $ftrs['limits'][2]);
0 ignored issues
show
Bug introduced by
It seems like setPagination() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
446
            $sReturn .= '<tr>' . $this->setStringIntoTag($pgn, 'th', ['colspan' => $iTableColumns]) . '</tr>';
447
        }
448
        $sReturn .= '</tbody></table>';
449
        if ($ftrs['grouping_cell_type'] == 'tab') {
450
            if (isset($ftrs['showGroupingCounter'])) {
451
                $sReturn .= $this->updateDivTitleName($remindGroupValue, $groupCounter);
452
            }
453
            $sReturn .= '</div><!-- from ' . $remindGroupValue . ' -->';
454
            if (!isset($ftrs['noGlobalTab'])) {
455
                $sReturn .= '</div><!-- from global tab -->';
456
            }
457
        }
458
        if (isset($ftrs['actions']['checkbox'])) {
459
            if (strpos($_REQUEST['view'], 'multiEdit') === false) {
460
                $sReturn .= '<a href="#" onclick="javascript:checking(\'' . $checkboxFormId
0 ignored issues
show
Bug introduced by
The variable $checkboxFormId 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...
461
                        . '\',\'' . $checkboxName . '\',true);">Check All</a>&nbsp;&nbsp;'
0 ignored issues
show
Bug introduced by
The variable $checkboxName 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...
462
                        . '<a href="#" onclick="javascript:checking(\'' . $checkboxFormId
463
                        . '\',\'' . $checkboxName . '\',false);">Uncheck All</a>&nbsp;&nbsp;'
464
                        . '<input type="hidden" name="action" value="multiEdit_' . $checkboxNameS . '" />';
0 ignored issues
show
Bug introduced by
The variable $checkboxNameS 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...
465 View Code Duplication
                if (isset($ftrs['hiddenInput'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
466
                    if (is_array($ftrs['hiddenInput'])) {
467
                        foreach ($ftrs['hiddenInput'] as $valueF) {
468
                            $sReturn .= '<input type="hidden" name="' . $valueF
469
                                    . '" value="' . $_REQUEST[$valueF] . '" />';
470
                        }
471
                    } else {
472
                        $sReturn .= '<input type="hidden" name="' . $ftrs['hiddenInput']
473
                                . '" value="' . $_REQUEST[$ftrs['hiddenInput']] . '" />';
474
                    }
475
                }
476
                $sReturn .= '<input style="margin: 0 3em 0 3em;" type="submit" ' . 'value="Edit selected" />';
477
            }
478
            $sReturn .= '</form>';
479
        }
480
        if (isset($ftrs['actions']['checkbox_inlineEdit'])) {
481
            $sReturn .= '<a href="#" onclick="javascript:checking(\'' . $checkboxFormId
482
                    . '\',\'' . $checkboxName . '\',true);">Check All</a>&nbsp;&nbsp;'
483
                    . '<a href="#" onclick="javascript:checking(\'' . $checkboxFormId
484
                    . '\',\'' . $checkboxName . '\',false);">Uncheck All</a>&nbsp;&nbsp;';
485
            if (isset($ftrs['visibleInput'])) {
486
                $sReturn .= $ftrs['visibleInput'];
487
            }
488
            $sReturn .= '<input type="hidden" name="view" value="save_' . $checkboxNameS . '" />';
489 View Code Duplication
            if (isset($ftrs['hiddenInput'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
490
                if (is_array($ftrs['hiddenInput'])) {
491
                    foreach ($ftrs['hiddenInput'] as $valueF) {
492
                        $sReturn .= '<input type="hidden" name="' . $valueF
493
                                . '" value="' . $_REQUEST[$valueF] . '" />';
494
                    }
495
                } else {
496
                    $sReturn .= '<input type="hidden" name="' . $ftrs['hiddenInput']
497
                            . '" value="' . $_REQUEST[$ftrs['hiddenInput']] . '" />';
498
                }
499
            }
500
            $sReturn .= '<input style="margin: 0 3em 0 3em;" type="submit" value="Store the modification" />';
501
            $sReturn .= '</form>';
502
        }
503
        return $sReturn;
504
    }
505
506
    /**
507
     * Set a control to a user-friendly calendar
508
     *
509
     * @param string $controlName
510
     * @param string $additionalStyle
511
     * @return string
512
     */
513 View Code Duplication
    public function setCalendarControl($controlName, $additionalStyle = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
514
    {
515
        return $this->setStringIntoTag('&nbsp;', 'span', [
516
                    'onclick' => implode('', [
517
                        'javascript:NewCssCal(\'' . $controlName,
518
                        '\',\'yyyyMMdd\',\'dropdown\',false,\'24\',false);',
519
                    ]),
520
                    'class'   => 'fa fa-calendar',
521
                    'id'      => $controlName . '_picker',
522
                    'style'   => 'cursor:pointer;' . $additionalStyle,
523
        ]);
524
    }
525
526
    /**
527
     * Set a control to a user-friendly calendar with time included
528
     *
529
     * @param string $controlName
530
     * @param string $additionalStyle
531
     * @return string
532
     */
533 View Code Duplication
    public function setCalendarControlWithTime($controlName, $additionalStyle = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
534
    {
535
        return $this->setStringIntoTag('&nbsp;', 'span', [
536
                    'onclick' => implode('', [
537
                        'javascript:NewCssCal(\'' . $controlName,
538
                        '\',\'yyyyMMdd\',\'dropdown\',true,\'24\',true);',
539
                    ]),
540
                    'class'   => 'fa fa-calendar',
541
                    'id'      => $controlName . '_picker',
542
                    'style'   => 'cursor:pointer;' . $additionalStyle,
543
        ]);
544
    }
545
546
    /**
547
     * Outputs an HTML footer
548
     *
549
     * @param array $footerInjected
550
     * @return string
551
     */
552
    protected function setFooterCommon($footerInjected = null)
0 ignored issues
show
Coding Style introduced by
setFooterCommon uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
553
    {
554
        if (isset($_REQUEST['specialHook']) && (in_array('noFooter', $_REQUEST['specialHook']))) {
555
            return '';
556
        }
557
        return $this->setFooterCommonInjected($footerInjected) . '</body></html>';
558
    }
559
560
    protected function setFooterCommonInjected($footerInjected = null)
561
    {
562
        $sReturn = '';
563
        if (!is_null($footerInjected)) {
564
            $sReturn = $footerInjected;
565
            if (is_array($footerInjected)) {
566
                $sReturn = implode('', $footerInjected);
567
            }
568
        }
569
        return $sReturn;
570
    }
571
572
    /**
573
     * Outputs an HTML header
574
     *
575
     * @param array $headerFeatures
576
     * @return string
577
     */
578
    protected function setHeaderCommon($headerFeatures = null)
0 ignored issues
show
Coding Style introduced by
setHeaderCommon uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
579
    {
580
        $sReturn = [];
581
        if (isset($_REQUEST['specialHook']) && (in_array('noHeader', $_REQUEST['specialHook']))) {
582
            $sReturn[] = ''; // no Header
583
        } else {
584
            $fixedHeaderElements = [
585
                'start'    => '<!DOCTYPE html>',
586
                'lang'     => '<html lang="en-US">',
587
                'head'     => '<head>',
588
                'charset'  => '<meta charset="utf-8" />',
589
                'viewport' => '<meta name="viewport" content="' . implode(', ', [
590
                    'width=device-width',
591
                    'height=device-height',
592
                    'initial-scale=1',
593
                ]) . '" />',
594
            ];
595
            if (!is_null($headerFeatures)) {
596
                if (is_array($headerFeatures)) {
597
                    $aFeatures = [];
598
                    foreach ($headerFeatures as $key => $value) {
599
                        switch ($key) {
600 View Code Duplication
                            case 'css':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
601
                                if (is_array($value)) {
602
                                    foreach ($value as $value2) {
603
                                        $aFeatures[] = $this->setCssFile(filter_var($value2, FILTER_SANITIZE_URL));
604
                                    }
605
                                } else {
606
                                    $aFeatures[] = $this->setCssFile(filter_var($value, FILTER_SANITIZE_URL));
607
                                }
608
                                break;
609 View Code Duplication
                            case 'javascript':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
610
                                if (is_array($value)) {
611
                                    foreach ($value as $value2) {
612
                                        $vl          = filter_var($value2, FILTER_SANITIZE_URL);
613
                                        $aFeatures[] = $this->setJavascriptFile($vl);
614
                                    }
615
                                } else {
616
                                    $aFeatures[] = $this->setJavascriptFile(filter_var($value, FILTER_SANITIZE_URL));
617
                                }
618
                                break;
619
                            case 'lang':
620
                                $fixedHeaderElements['lang'] = '<html lang="'
621
                                        . filter_var($value, FILTER_SANITIZE_STRING) . '">';
622
                                break;
623
                            case 'title':
624
                                $aFeatures[]                 = '<title>'
625
                                        . filter_var($value, FILTER_SANITIZE_STRING) . '</title>';
626
                                break;
627
                        }
628
                    }
629
                    $sReturn[] = implode('', $fixedHeaderElements)
630
                            . implode('', $aFeatures)
631
                            . '</head>'
632
                            . '<body>';
633
                } else {
634
                    $sReturn[] = implode('', $fixedHeaderElements)
635
                            . '</head>'
636
                            . '<body>'
637
                            . '<p style="background-color:red;color:#FFF;">The parameter sent to '
638
                            . __FUNCTION__ . ' must be an array</p>'
639
                            . $this->setFooterCommon();
640
                    throw new \Exception($sReturn);
641
                }
642
            }
643
        }
644
        return implode('', $sReturn);
645
    }
646
647
    /**
648
     * Generates a table cell
649
     *
650
     * @param array $aElements
651
     * @param array $features
652
     * @return string
653
     */
654
    private function setTableCell($aElements, $features = null)
655
    {
656
        $sReturn = null;
657
        foreach ($aElements as $key => $value) {
658
            $value = str_replace(['& ', '\"', "\'"], ['&amp; ', '"', "'"], $value);
659
            if ((isset($features['grouping_cell'])) && ($features['grouping_cell'] == $key)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
660
                // just skip
661
            } else {
662
                $sReturn .= '<td ';
663
                if (isset($features['column_formatting'][$key])) {
664
                    switch ($features['column_formatting'][$key]) {
665
                        case '@':
666
                            $sReturn .= 'style="text-align:left;">' . $value;
667
                            break;
668
                        case 'right':
669
                            $sReturn .= 'style="text-align:right;">' . $value;
670
                            break;
671
                        default:
672
                            $sReturn .= '???';
673
                            break;
674
                    }
675
                } else {
676
                    if (is_numeric($value)) {
677
                        if (substr($value, 0, 1) === '0') {
678
                            $sReturn .= 'style="text-align: right;">' . $value;
679
                        } else {
680
                            $decimals = 0;
681
                            if (isset($features['no_of_decimals'])) {
682
                                $decimals = $features['no_of_decimals'];
683
                            }
684
                            if (isset($features['decimals']) && array_key_exists($key, $features['decimals'])) {
685
                                $decimals = $features['decimals'][$key];
686
                            }
687
                            $sReturn .= 'style="text-align: right;">';
688
                            $sReturn .= $this->setNumberFormat($value, [
689
                                'MinFractionDigits' => $decimals,
690
                                'MaxFractionDigits' => $decimals
691
                            ]);
692
                        }
693
                    } else {
694
                        $outputet = false;
695
                        if ((strpos($value, '-') !== false) && (strlen($value) == 10)) {
696
                            if (preg_match("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})", $value, $regs)) {
697
                                $outputet = true;
698
                                $sReturn .= 'style="text-align:right;width: 10px;">'
699
                                        . $regs[3] . '.' . $regs[2] . '.' . $regs[1];
700
                            }
701
                        }
702
                        if (!$outputet) {
703
                            $sReturn .= 'style="text-align:left;">' . $value;
704
                        }
705
                    }
706
                }
707
                $sReturn .= '</td>';
708
            }
709
        }
710
        return $sReturn;
711
    }
712
713
    /**
714
     * Generates a table header
715
     *
716
     * @param array $aElements
717
     * @param boolean $bHeadersBreaked
718
     * @return string
719
     */
720
    private function setTableHeader($aElements, $bHeadersBreaked)
721
    {
722
        if ($bHeadersBreaked) {
723
            $aTableHeader = $this->setArrayToArrayKbr($aElements);
0 ignored issues
show
Bug introduced by
It seems like setArrayToArrayKbr() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
724
        } else {
725
            $aTableHeader = $aElements;
726
        }
727
        $sReturn[] = null;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$sReturn was never initialized. Although not strictly required by PHP, it is generally a good practice to add $sReturn = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
728
        foreach (array_keys($aTableHeader) as $value) {
729
            $sReturn[] = $this->setStringIntoTag($value, 'th');
730
        }
731
        return implode('', $sReturn);
732
    }
733
734
    /**
735
     * Create an upper right box with choices for languages
736
     * (requires flag-icon.min.css to be loaded)
737
     * (makes usage of custom class "upperRightBox" and id = "visibleOnHover", provided here as scss file)
738
     *
739
     * @param array $aAvailableLanguages
740
     * @return string
741
     */
742
    protected function setUpperRightBoxLanguages($aAvailableLanguages)
743
    {
744
        $this->handleLanguageIntoSession();
745
        return '<div class="upperRightBox">'
746
                . '<div style="text-align:right;">'
747
                . '<span class="flag-icon flag-icon-' . strtolower(substr($this->tCmnSuperGlobals->get('lang'), -2))
748
                . '" style="margin-right:2px;">&nbsp;</span>'
749
                . $aAvailableLanguages[$this->tCmnSession->get('lang')]
750
                . '</div><!-- default Language -->'
751
                . $this->setUpperRightVisibleOnHoverLanguages($aAvailableLanguages)
752
                . '</div><!-- upperRightBox end -->';
753
    }
754
755
    private function setUpperRightVisibleOnHoverLanguages($aAvailableLanguages)
756
    {
757
        $linkWithoutLanguage = '';
758
        if (isset($this->tCmnSuperGlobals->request)) {
759
            $linkWithoutLanguage = $this->setArrayToStringForUrl('&amp;', $this->tCmnSuperGlobals->request, ['lang'])
760
                    . '&amp;';
761
        }
762
        $sReturn = [];
763
        foreach ($aAvailableLanguages as $key => $value) {
764
            if ($this->tCmnSession->get('lang') !== $key) {
765
                $sReturn[] = '<a href="?' . $linkWithoutLanguage . 'lang=' . $key . '" style="display:block;">'
766
                        . '<span class="flag-icon flag-icon-' . strtolower(substr($key, -2))
767
                        . '" style="margin-right:2px;">&nbsp;</span>'
768
                        . $value . '</a>';
769
            }
770
        }
771
        return '<div id="visibleOnHover">' . implode('', $sReturn) . '</div><!-- visibleOnHover end -->';
772
    }
773
}
774