Passed
Push — master ( d2520f...3f8ec2 )
by Michael
02:50
created

MonthPayload_Decorator   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 78
Duplicated Lines 14.1 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 11
loc 78
rs 10
c 0
b 0
f 0
wmc 14
lcom 1
cbo 5

3 Methods

Rating   Name   Duplication   Size   Complexity  
A fetch() 0 9 2
B build() 0 25 3
B setSelection() 0 13 9

How to fix   Duplicated Code   

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:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 8 and the first side effect is on line 14.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Description: demonstrates a decorator used to "attach a payload" to a selection
4
 * to make it available when iterating over calendar children.
5
 */
6
7
//if you use ISO-8601 dates, switch to PearDate engine
8
define('CALENDAR_ENGINE', 'PearDate');
9
10
if (!@include 'Calendar/Calendar.php') {
11
    define('CALENDAR_ROOT', '../../');
12
}
13
14
require_once CALENDAR_ROOT . 'Month/Weekdays.php';
15
require_once CALENDAR_ROOT . 'Day.php';
16
require_once CALENDAR_ROOT . 'Decorator.php';
17
18
// accepts multiple entries
19
20
/**
21
 * Class DiaryEvent.
22
 */
23
class DiaryEvent extends Calendar_Decorator
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
24
{
25
    public $entries = [];
26
27
    /**
28
     * @param $calendar
29
     */
30
    public function __construct($calendar)
31
    {
32
        parent::__construct($calendar);
33
    }
34
35
    /**
36
     * @param $entry
37
     */
38
    public function addEntry($entry)
39
    {
40
        $this->entries[] = $entry;
41
    }
42
43
    /**
44
     * @return bool
45
     */
46
    public function getEntry()
47
    {
48
        $entry = each($this->entries);
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

48
        $entry = /** @scrutinizer ignore-deprecated */ each($this->entries);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
Bug Best Practice introduced by
The property entries does not exist on DiaryEvent. Did you maybe forget to declare it?
Loading history...
49
        if ($entry) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $entry of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
50
            return $entry['value'];
51
        } else {
52
            reset($this->entries);
53
54
            return false;
55
        }
56
    }
57
}
58
59
/**
60
 * Class MonthPayload_Decorator.
61
 */
62
class MonthPayload_Decorator extends Calendar_Decorator
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
63
{
64
    //Calendar engine
65
    public $cE;
66
    public $tableHelper;
67
68
    public $year;
69
    public $month;
70
    public $firstDay = false;
71
72
    /**
73
     * @param array $events
74
     *
75
     * @return bool
76
     */
77
    public function build($events = [])
78
    {
79
        require_once CALENDAR_ROOT . 'Day.php';
80
        require_once CALENDAR_ROOT . 'Table/Helper.php';
81
82
        $this->tableHelper = new Calendar_Table_Helper($this, $this->firstDay);
0 ignored issues
show
Bug introduced by
$this->firstDay of type boolean is incompatible with the type integer expected by parameter $firstDay of Calendar_Table_Helper::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

82
        $this->tableHelper = new Calendar_Table_Helper($this, /** @scrutinizer ignore-type */ $this->firstDay);
Loading history...
83
        $this->cE          = $this->getEngine();
84
        $this->year        = $this->thisYear();
85
        $this->month       = $this->thisMonth();
86
87
        $daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month);
88
        for ($i = 1; $i <= $daysInMonth; ++$i) {
89
            $Day = new Calendar_Day(2000, 1, 1); // Create Day with dummy values
90
            $Day->setTimestamp($this->cE->dateToStamp($this->year, $this->month, $i));
91
            $this->children[$i] = new DiaryEvent($Day);
0 ignored issues
show
Bug Best Practice introduced by
The property children does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
92
        }
93
        if (count($events) > 0) {
94
            $this->setSelection($events);
95
        }
96
        Calendar_Month_Weekdays::buildEmptyDaysBefore();
0 ignored issues
show
Bug Best Practice introduced by
The method Calendar_Month_Weekdays::buildEmptyDaysBefore() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

96
        Calendar_Month_Weekdays::/** @scrutinizer ignore-call */ 
97
                                 buildEmptyDaysBefore();
Loading history...
97
        Calendar_Month_Weekdays::shiftDays();
0 ignored issues
show
Bug Best Practice introduced by
The method Calendar_Month_Weekdays::shiftDays() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

97
        Calendar_Month_Weekdays::/** @scrutinizer ignore-call */ 
98
                                 shiftDays();
Loading history...
98
        Calendar_Month_Weekdays::buildEmptyDaysAfter();
0 ignored issues
show
Bug Best Practice introduced by
The method Calendar_Month_Weekdays::buildEmptyDaysAfter() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

98
        Calendar_Month_Weekdays::/** @scrutinizer ignore-call */ 
99
                                 buildEmptyDaysAfter();
Loading history...
99
        Calendar_Month_Weekdays::setWeekMarkers();
0 ignored issues
show
Bug Best Practice introduced by
The method Calendar_Month_Weekdays::setWeekMarkers() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

99
        Calendar_Month_Weekdays::/** @scrutinizer ignore-call */ 
100
                                 setWeekMarkers();
Loading history...
100
101
        return true;
102
    }
103
104
    /**
105
     * @param $events
106
     */
107
    public function setSelection($events)
108
    {
109
        $daysInMonth = $this->cE->getDaysInMonth($this->year, $this->month);
110
        for ($i = 1; $i <= $daysInMonth; ++$i) {
111
            $stamp1 = $this->cE->dateToStamp($this->year, $this->month, $i);
112
            $stamp2 = $this->cE->dateToStamp($this->year, $this->month, $i + 1);
113
            foreach ($events as $event) {
114
                if (($stamp1 >= $event['start'] && $stamp1 < $event['end'])
115
                    || ($stamp2 >= $event['start']
116
                        && $stamp2 < $event['end'])
117
                    || ($stamp1 <= $event['start'] && $stamp2 > $event['end'])) {
118
                    $this->children[$i]->addEntry($event);
119
                    $this->children[$i]->setSelected();
120
                }
121
            }
122
        }
123
    }
124
125
    /**
126
     * @return bool
127
     */
128
    public function fetch()
129
    {
130
        $child = each($this->children);
0 ignored issues
show
Deprecated Code introduced by
The function each() has been deprecated: 7.2 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

130
        $child = /** @scrutinizer ignore-deprecated */ each($this->children);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
131
        if ($child) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $child of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
132
            return $child['value'];
133
        } else {
134
            reset($this->children);
135
136
            return false;
137
        }
138
    }
139
}
140
141
// Calendar instance used to get the dates in the preferred format:
142
// you can switch Calendar Engine and the example still works
143
$cal = new Calendar();
144
145
$events = [];
146
//add some events
147
$events[] = [
148
    'start' => $cal->cE->dateToStamp(2004, 6, 1, 10),
149
    'end'   => $cal->cE->dateToStamp(2004, 6, 1, 12),
150
    'desc'  => 'Important meeting',
151
];
152
$events[] = [
153
    'start' => $cal->cE->dateToStamp(2004, 6, 1, 21),
154
    'end'   => $cal->cE->dateToStamp(2004, 6, 1, 23, 59),
155
    'desc'  => 'Dinner with the boss',
156
];
157
$events[] = [
158
    'start' => $cal->cE->dateToStamp(2004, 6, 5),
159
    'end'   => $cal->cE->dateToStamp(2004, 6, 10, 23, 59),
160
    'desc'  => 'Holidays!',
161
];
162
163
$Month          = new Calendar_Month_Weekdays(2004, 6);
164
$MonthDecorator = new MonthPayload_Decorator($Month);
165
$MonthDecorator->build($events);
166
167
?>
168
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
169
<html>
170
<head>
171
    <title> Calendar </title>
172
    <style text="text/css">
173
        table {
174
            border-collapse: collapse;
175
        }
176
177
        caption {
178
            font-family: verdana, sans-serif;
179
            font-size: 14pt;
180
            padding-bottom: 4pt;
181
        }
182
183
        th {
184
            font-family: verdana, sans-serif;
185
            font-size: 11px;
186
            text-align: center;
187
            background-color: #e7e3e7;
188
            padding: 5pt;
189
            line-height: 150%;
190
            border: 1px solid #ccc;
191
        }
192
193
        td {
194
            font-family: verdana, sans-serif;
195
            font-size: 11px;
196
            text-align: left;
197
            vertical-align: top;
198
        }
199
200
        td.calCell {
201
            border: 1px solid #b5bece;
202
            padding: 3px;
203
        }
204
205
        td.calCellEmpty {
206
            background-color: #f3f3f7;
207
        }
208
209
        td.calCellBusy {
210
            background-color: #efeffa;
211
        }
212
213
        div.dayNumber {
214
            text-align: right;
215
            background-color: #f8f8f8;
216
            border-bottom: 1px solid #ccc;
217
        }
218
219
        ul {
220
            margin-left: 0;
221
            margin-top: 5pt;
222
            padding: 0 10pt 0 12pt;
223
            list-style-type: square;
224
        }
225
    </style>
226
</head>
227
228
<body>
229
230
<h2>Sample Calendar Payload Decorator (using <?php echo CALENDAR_ENGINE; ?> engine)</h2>
231
<table class="calendar" width="98%" cellspacing="0" cellpadding="0">
232
    <caption>
233
        <?php echo $MonthDecorator->thisMonth() . ' / ' . $MonthDecorator->thisYear(); ?>
234
    </caption>
235
    <tr>
236
        <th>Monday</th>
237
        <th>Tuesday</th>
238
        <th>Wednesday</th>
239
        <th>Thursday</th>
240
        <th>Friday</th>
241
        <th>Saturday</th>
242
        <th>Sunday</th>
243
    </tr>
244
    <?php
245
    while ($Day = $MonthDecorator->fetch()) {
246
        if ($Day->isFirst()) {
247
            echo "<tr>\n";
248
        }
249
250
        echo '<td class="calCell';
251
        if ($Day->isSelected()) {
252
            echo ' calCellBusy';
253
        } elseif ($Day->isEmpty()) {
254
            echo ' calCellEmpty';
255
        }
256
        echo '">';
257
        echo '<div class="dayNumber">' . $Day->thisDay() . '</div>';
258
259
        if ($Day->isEmpty()) {
260
            echo '&nbsp;';
261
        } else {
262
            echo '<div class="dayContents"><ul>';
263
            while ($entry = $Day->getEntry()) {
264
                echo '<li>' . $entry['desc'] . '</li>';
265
                //you can print the time range as well
266
            }
267
            echo '</ul></div>';
268
        }
269
        echo '</td>';
270
271
        if ($Day->isLast()) {
272
            echo "</tr>\n";
273
        }
274
    }
275
    ?>
276
</table>
277
</body>
278
</html>
279