Completed
Push — master ( 706e3c...232af6 )
by Ricardo
14:38
created

AtomCreator10   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 67
Duplicated Lines 4.48 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 3
loc 67
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 2

2 Methods

Rating   Name   Duplication   Size   Complexity  
A AtomCreator10() 0 5 1
B createFeed() 3 55 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
2
/**
3
 * A FeedItem is a part of a FeedCreator feed.
4
 *
5
 * @author Kai Blankenhorn <[email protected]>
6
 * @since  1.3
7
 */
8
class FeedItem extends HtmlDescribable
9
{
10
    /**
11
     * Mandatory attributes of an item.
12
     */
13
    var $title, $description, $link;
14
15
    /**
16
     * Optional attributes of an item.
17
     */
18
    var $author, $authorEmail, $image, $category, $comments, $guid, $source, $creator;
19
20
    /**
21
     * Publishing date of an item. May be in one of the following formats:
22
     *
23
     *    RFC 822:
24
     *    "Mon, 20 Jan 03 18:05:41 +0400"
25
     *    "20 Jan 03 18:05:41 +0000"
26
     *
27
     *    ISO 8601:
28
     *    "2003-01-20T18:05:41+04:00"
29
     *
30
     *    Unix:
31
     *    1043082341
32
     */
33
    var $date;
34
35
    /**
36
     * Add <enclosure> element tag RSS 2.0
37
     * modified by : Mohammad Hafiz bin Ismail ([email protected])
38
     *
39
     * display :
40
     * <enclosure length="17691" url="http://something.com/picture.jpg" type="image/jpeg" />
41
     */
42
    var $enclosure;
43
44
    /**
45
     * Any additional elements to include as an assiciated array. All $key => $value pairs
46
     * will be included unencoded in the feed item in the form
47
     *     <$key>$value</$key>
48
     * Again: No encoding will be used! This means you can invalidate or enhance the feed
49
     * if $value contains markup. This may be abused to embed tags not implemented by
50
     * the FeedCreator class used.
51
     */
52
    var $additionalElements = Array();
53
54
    // on hold
55
    // var $source;
56
}
57
58
class EnclosureItem extends HtmlDescribable
59
{
60
    /*
61
    *
62
    * core variables
63
    *
64
    **/
65
    var $url,$length,$type;
66
67
    /*
68
    * For use with another extension like Yahoo mRSS
69
    * Warning :
70
    * These variables might not show up in
71
    * later release / not finalize yet!
72
    *
73
    */
74
    var $width, $height, $title, $description, $keywords, $thumburl;
75
76
    var $additionalElements = Array();
77
78
}
79
80
81
/**
82
 * An FeedImage may be added to a FeedCreator feed.
83
 *
84
 * @author Kai Blankenhorn <[email protected]>
85
 * @since  1.3
86
 */
87
class FeedImage extends HtmlDescribable
88
{
89
    /**
90
     * Mandatory attributes of an image.
91
     */
92
    var $title, $url, $link;
93
94
    /**
95
     * Optional attributes of an image.
96
     */
97
    var $width, $height, $description;
98
}
99
100
101
102
/**
103
 * An HtmlDescribable is an item within a feed that can have a description that may
104
 * include HTML markup.
105
 */
106
class HtmlDescribable
107
{
108
    /**
109
     * Indicates whether the description field should be rendered in HTML.
110
     */
111
    var $descriptionHtmlSyndicated;
112
113
    /**
114
     * Indicates whether and to how many characters a description should be truncated.
115
     */
116
    var $descriptionTruncSize;
117
118
    /**
119
     * Returns a formatted description field, depending on descriptionHtmlSyndicated and
120
     * $descriptionTruncSize properties
121
     *
122
     * @return string    the formatted description
123
     */
124
    function getDescription()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
125
    {
126
        $descriptionField = new FeedHtmlField($this->description);
0 ignored issues
show
Bug introduced by
The property description does not seem to exist. Did you mean descriptionHtmlSyndicated?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
127
        $descriptionField->syndicateHtml = $this->descriptionHtmlSyndicated;
128
        $descriptionField->truncSize = $this->descriptionTruncSize;
129
        return $descriptionField->output();
130
    }
131
132
}
133
134
135
136
/**
137
 * An FeedHtmlField describes and generates
138
 * a feed, item or image html field (probably a description). Output is
139
 * generated based on $truncSize, $syndicateHtml properties.
140
 *
141
 * @author  Pascal Van Hecke <[email protected]>
142
 * @version 1.6
143
 */
144
class FeedHtmlField
145
{
146
    /**
147
     * Mandatory attributes of a FeedHtmlField.
148
     */
149
    var $rawFieldContent;
150
151
    /**
152
     * Optional attributes of a FeedHtmlField.
153
     */
154
    var $truncSize, $syndicateHtml;
155
156
    /**
157
     * Creates a new instance of FeedHtmlField.
158
     *
159
     * @param $string: if given, sets the rawFieldContent property
160
     */
161
    function FeedHtmlField($parFieldContent)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
162
    {
163
        if ($parFieldContent) {
164
            $this->rawFieldContent = $parFieldContent;
165
        }
166
    }
167
168
169
    /**
170
     * Creates the right output, depending on $truncSize, $syndicateHtml properties.
171
     *
172
     * @return string    the formatted field
173
     */
174
    function output()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
175
    {
176
        // when field available and syndicated in html we assume
177
        // - valid html in $rawFieldContent and we enclose in CDATA tags
178
        // - no truncation (truncating risks producing invalid html)
179
        if (!$this->rawFieldContent) {
180
            $result = "";
181
        }    elseif ($this->syndicateHtml) {
182
            $result = "<![CDATA[".$this->rawFieldContent."]]>";
183
        } else {
184
            if ($this->truncSize and is_int($this->truncSize)) {
185
                $result = FeedCreator::iTrunc(htmlspecialchars($this->rawFieldContent), $this->truncSize);
186
            } else {
187
                $result = htmlspecialchars($this->rawFieldContent);
188
            }
189
        }
190
        return $result;
191
    }
192
193
}
194
195
196
197
/**
198
 * UniversalFeedCreator lets you choose during runtime which
199
 * format to build.
200
 * For general usage of a feed class, see the FeedCreator class
201
 * below or the example above.
202
 *
203
 * @since  1.3
204
 * @author Kai Blankenhorn <[email protected]>
205
 */
206
class UniversalFeedCreator extends FeedCreator
207
{
208
209
    var $_feed;
210
211
    function _setMIME($format)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
212
    {
213
        switch (strtoupper($format)) {
214
215
        case "RSS":
216
        case "2.0":
217
            // fall through
218
        case "RSS2.0":
219
            header('Content-type: text/xml', true);
220
            break;
221
222
        case "ATOM":
223
            // fall through: always the latest ATOM version
224
        case "ATOM1.0":
225
            header('Content-type: application/xml', true);
226
            break;
227
228
        default:
229
        case "0.91":
0 ignored issues
show
Unused Code introduced by
case '0.91': does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
230
            // fall through
231
        case "RSS0.91":
232
            header('Content-type: text/xml', true);
233
            break;
234
        }
235
    }
236
237
    function _setFormat($format)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
238
    {
239
        switch (strtoupper($format)) {
240
241
        case "RSS":
242
        case "2.0":
243
            // fall through
244
        case "RSS2.0":
245
            $this->_feed = new RSSCreator20();
246
            break;
247
248
        case "0.91":
249
            // fall through
250
        case "RSS0.91":
251
            $this->_feed = new RSSCreator091();
252
            break;
253
254
        case "ATOM":
255
            // fall through: always the latest ATOM version
256
        case "ATOM1.0":
257
            $this->_feed = new AtomCreator10();
258
            break;
259
260
        default:
261
            $this->_feed = new RSSCreator091();
262
            break;
263
        }
264
265
        $vars = get_object_vars($this);
266
        foreach ($vars as $key => $value) {
267
            // prevent overwriting of properties "contentType", "encoding"; do not copy "_feed" itself
268
            if (!in_array($key, array("_feed", "contentType", "encoding"))) {
269
                $this->_feed->{$key} = $this->{$key};
270
            }
271
        }
272
    }
273
274
    /**
275
     * Creates a syndication feed based on the items previously added.
276
     *
277
     * @see    FeedCreator::addItem()
278
     * @param  string    format    format the feed should comply to. Valid values are:
279
     *            "PIE0.1", "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3", "HTML", "JS"
280
     * @return string    the contents of the feed.
281
     */
282
    function createFeed($format = "RSS0.91")
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
283
    {
284
        $this->_setFormat($format);
285
        return $this->_feed->createFeed();
0 ignored issues
show
Bug introduced by
The call to createFeed() misses a required argument $timezone.

This check looks for function calls that miss required arguments.

Loading history...
286
    }
287
288
289
    /**
290
     * Outputs feed to the browser - needed for on-the-fly feed generation (like it is done in WordPress, etc.)
291
     *
292
     * @param format    string    format the feed should comply to. Valid values are:
293
     *                             "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
294
     */
295
    function outputFeed( $timezone , $format='RSS2.0' )
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
296
    {
297
        $this->_setFormat($format);
298
        $this->_setMIME($format);
299
        $this->_feed->outputFeed($timezone, $format);
300
    }
301
302
}
303
304
305
/**
306
 * FeedCreator is the abstract base implementation for concrete
307
 * implementations that implement a specific format of syndication.
308
 *
309
 * @abstract
310
 * @author   Kai Blankenhorn <[email protected]>
311
 * @since    1.4
312
 */
313
class FeedCreator extends HtmlDescribable
314
{
315
316
    /**
317
     * Mandatory attributes of a feed.
318
     */
319
    var $title, $description, $link;
320
321
322
    /**
323
     * Optional attributes of a feed.
324
     */
325
    var $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
326
327
    /**
328
     * The url of the external xsl stylesheet used to format the naked rss feed.
329
     * Ignored in the output when empty.
330
     */
331
    var $xslStyleSheet = "";
332
333
334
    /**
335
     * @access private
336
     */
337
    var $items = Array();
338
339
340
    /**
341
     * This feed's MIME content type.
342
     *
343
     * @since  1.4
344
     * @access private
345
     */
346
    var $contentType = "application/xml";
347
348
349
    /**
350
     * This feed's character encoding.
351
     *
352
     * @since 1.6.1
353
     **/
354
    var $encoding = "UTF-8";
355
356
357
    /**
358
     * Any additional elements to include as an assiciated array. All $key => $value pairs
359
     * will be included unencoded in the feed in the form
360
     *     <$key>$value</$key>
361
     * Again: No encoding will be used! This means you can invalidate or enhance the feed
362
     * if $value contains markup. This may be abused to embed tags not implemented by
363
     * the FeedCreator class used.
364
     */
365
    var $additionalElements = Array();
366
367
368
    /**
369
     * Adds an FeedItem to the feed.
370
     *
371
     * @param  object FeedItem $item The FeedItem to add to the feed.
372
     * @access public
373
     */
374
    function addItem($item)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
375
    {
376
        $this->items[] = $item;
377
    }
378
379
380
    /**
381
     * Truncates a string to a certain length at the most sensible point.
382
     * First, if there's a '.' character near the end of the string, the string is truncated after this character.
383
     * If there is no '.', the string is truncated after the last ' ' character.
384
     * If the string is truncated, " ..." is appended.
385
     * If the string is already shorter than $length, it is returned unchanged.
386
     *
387
     * @static
388
     * @param  string    string A string to be truncated.
389
     * @param  int        length the maximum length the string should be truncated to
390
     * @return string    the truncated string
391
     */
392
    function iTrunc($string, $length)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
393
    {
394
        if (strlen($string)<=$length) {
395
            return $string;
396
        }
397
398
        $pos = strrpos($string, ".");
399 View Code Duplication
        if ($pos>=$length-4) {
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...
400
            $string = substr($string, 0, $length-4);
401
            $pos = strrpos($string, ".");
402
        }
403
        if ($pos>=$length*0.4) {
404
            return substr($string, 0, $pos+1)." ...";
405
        }
406
407
        $pos = strrpos($string, " ");
408 View Code Duplication
        if ($pos>=$length-4) {
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...
409
            $string = substr($string, 0, $length-4);
410
            $pos = strrpos($string, " ");
411
        }
412
        if ($pos>=$length*0.4) {
413
            return substr($string, 0, $pos)." ...";
414
        }
415
416
        return substr($string, 0, $length-4)." ...";
417
418
    }
419
420
421
    /**
422
     * Creates a comment indicating the generator of this feed.
423
     * The format of this comment seems to be recognized by
424
     * Syndic8.com.
425
     */
426
    function _createGeneratorComment()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
427
    {
428
        return "<!-- generator=\"".FEEDCREATOR_VERSION."\" -->\n";
429
    }
430
431
432
    /**
433
     * Creates a string containing all additional elements specified in
434
     * $additionalElements.
435
     *
436
     * @param  elements    array    an associative array containing key => value pairs
437
     * @param  indentString    string    a string that will be inserted before every generated line
438
     * @return string    the XML tags corresponding to $additionalElements
439
     */
440
    function _createAdditionalElements($elements, $indentString="")
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
441
    {
442
        $ae = "";
443
        if (is_array($elements)) {
444
            foreach($elements AS $key => $value) {
445
                $ae.= $indentString."<$key>$value</$key>\n";
446
            }
447
        }
448
        return $ae;
449
    }
450
451
    function _createStylesheetReferences()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
452
    {
453
        $xml = "";
454
        if (isset($this->cssStyleSheet) ) { $xml .= "<?xml-stylesheet href=\"".$this->cssStyleSheet."\" type=\"text/css\"?>\n";
0 ignored issues
show
Bug introduced by
The property cssStyleSheet does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
455
        }
456
        if (isset($this->xslStyleSheet) ) { $xml .= "<?xml-stylesheet href=\"".$this->xslStyleSheet."\" type=\"text/xsl\"?>\n";
457
        }
458
        return $xml;
459
    }
460
461
462
    /**
463
     * Builds the feed's text.
464
     *
465
     * @abstract
466
     * @return   string    the feed's complete text
467
     */
468
    function createFeed( $timezone )
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
469
    {
470
    }
471
472
    /**
473
     * Generate a filename for the feed cache file. The result will be $_SERVER["PHP_SELF"] with the extension changed to .xml.
474
     * For example:
475
     *
476
     * echo $_SERVER["PHP_SELF"]."\n";
477
     * echo FeedCreator::_generateFilename();
478
     *
479
     * would produce:
480
     *
481
     * /rss/latestnews.php
482
     * latestnews.xml
483
     *
484
     * @return string the feed cache filename
485
     * @since  1.4
486
     * @access private
487
     */
488
    function _generateFilename()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
489
    {
490
        $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
491
        return substr($fileInfo["basename"], 0, -(strlen($fileInfo["extension"])+1)).".xml";
492
    }
493
494
495
    /**
496
     * @since  1.4
497
     * @access private
498
     */
499
    function _redirect($filename)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
500
    {
501
        // attention, heavily-commented-out-area
502
503
        // maybe use this in addition to file time checking
504
        //Header("Expires: ".date("r",time()+$this->_timeout));
505
506
        /* no caching at all, doesn't seem to work as good:
507
        Header("Cache-Control: no-cache");
508
        Header("Pragma: no-cache");
509
        */
510
511
        // HTTP redirect, some feed readers' simple HTTP implementations don't follow it
512
        //Header("Location: ".$filename);
513
514
        Header("Content-Type: ".$this->contentType."; charset=".$this->encoding."; filename=".basename($filename));
515
        Header("Content-Disposition: inline; filename=".basename($filename));
516
        readfile($filename, "r");
517
        die();
518
    }
519
520
    /**
521
     * Outputs this feed directly to the browser - for on-the-fly feed generation
522
     *
523
     * @since 1.7.2-mod
524
     *
525
     * still missing: proper header output - currently you have to add it manually
526
     */
527
    function outputFeed( $timezone , $format='RSS2.0' )
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
528
    {
529
        echo $this->createFeed($timezone);
530
    }
531
532
}
533
534
535
/**
536
 * FeedDate is an internal class that stores a date for a feed or feed item.
537
 * Usually, you won't need to use this.
538
 */
539
class FeedDate
540
{
541
    var $unix;
542
543
    /**
544
     * Creates a new instance of FeedDate representing a given date.
545
     * Accepts RFC 822, ISO 8601 date formats as well as unix time stamps.
546
     *
547
     * @param mixed $dateString optional the date this FeedDate will represent. If not specified, the current date and time is used.
548
     */
549
    function FeedDate($dateString="")
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
550
    {
551
        if ($dateString=="") { $dateString = date("r");
552
        }
553
554
        if (is_numeric($dateString)) {
555
            $this->unix = $dateString;
556
            return;
557
        }
558
        if (preg_match("~(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?(\\d{1,2})\\s+([a-zA-Z]{3})\\s+(\\d{4})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(.*)~", $dateString, $matches)) {
559
            $months = Array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12);
560
            $this->unix = mktime($matches[4], $matches[5], $matches[6], $months[$matches[2]], $matches[1], $matches[3]);
561
            if (substr($matches[7], 0, 1)=='+' OR substr($matches[7], 0, 1)=='-') {
562
                $tzOffset = (substr($matches[7], 0, 3) * 60 + substr($matches[7], -2)) * 60;
563
            } else {
564
                if (strlen($matches[7])==1) {
565
                    $oneHour = 3600;
566
                    $ord = ord($matches[7]);
567
                    if ($ord < ord("M")) {
568
                        $tzOffset = (ord("A") - $ord - 1) * $oneHour;
569
                    } elseif ($ord >= ord("M") AND $matches[7]!="Z") {
570
                        $tzOffset = ($ord - ord("M")) * $oneHour;
571
                    } elseif ($matches[7]=="Z") {
572
                        $tzOffset = 0;
573
                    }
574
                }
575
                switch ($matches[7]) {
576
                case "UT":
577
                case "GMT":    $tzOffset = 0;
578
                }
579
            }
580
            $this->unix += $tzOffset;
0 ignored issues
show
Bug introduced by
The variable $tzOffset 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...
581
            return;
582
        }
583
        if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~", $dateString, $matches)) {
584
            $this->unix = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
585
            if (substr($matches[7], 0, 1)=='+' OR substr($matches[7], 0, 1)=='-') {
586
                $tzOffset = (substr($matches[7], 0, 3) * 60 + substr($matches[7], -2)) * 60;
587
            } else {
588
                if ($matches[7]=="Z") {
589
                    $tzOffset = 0;
590
                }
591
            }
592
            $this->unix += $tzOffset;
593
            return;
594
        }
595
        $this->unix = 0;
596
    }
597
598
599
600
601
602
    /**
603
     * Gets the date stored in this FeedDate as an RFC 822 date.
604
     *
605
     * @return a date in RFC 822 format
606
     */
607
    function rfc822()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
608
    {
609
        $d = new DateTime("@" . $this->unix);
610
611
        return $d->format('r');
612
    }
613
614
    /**
615
     * Gets the date stored in this FeedDate as an ISO 8601 date.
616
     *
617
     * @return a date in ISO 8601 (RFC 3339) format
618
     */
619
    function iso8601()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
620
    {
621
        $d = new DateTime("@" . $this->unix);
622
623
        return $d->format('c');
624
    }
625
626
627
    /**
628
     * Gets the date stored in this FeedDate as unix time stamp.
629
     *
630
     * @return a date as a unix time stamp
631
     */
632
    function unix()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
633
    {
634
        return $this->unix;
635
    }
636
}
637
638
639
640
641
/**
642
 * RSSCreator091 is a FeedCreator that implements RSS 0.91 Spec, revision 3.
643
 *
644
 * @see    http://my.netscape.com/publish/formats/rss-spec-0.91.html
645
 * @since  1.3
646
 * @author Kai Blankenhorn <[email protected]>
647
 */
648
class RSSCreator091 extends FeedCreator
649
{
650
651
    /**
652
     * Stores this RSS feed's version number.
653
     *
654
     * @access private
655
     */
656
    var $RSSVersion;
657
658
    function RSSCreator091()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
659
    {
660
        $this->_setRSSVersion("0.91");
661
        $this->contentType = "application/rss+xml";
662
    }
663
664
    /**
665
     * Sets this RSS feed's version number.
666
     *
667
     * @access private
668
     */
669
    function _setRSSVersion($version)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
670
    {
671
        $this->RSSVersion = $version;
672
    }
673
674
    /**
675
     * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
676
     * The feed will contain all items previously added in the same order.
677
     *
678
     * @return string    the feed's complete text
679
     */
680
    function createFeed( $timezone )
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
681
    {
682
        $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
683
        $feed.= $this->_createGeneratorComment();
684
        $feed.= $this->_createStylesheetReferences();
685
        $feed.= "<rss version=\"".$this->RSSVersion."\">\n";
686
        $feed.= "    <channel>\n";
687
        $feed.= "        <title>".FeedCreator::iTrunc(htmlspecialchars($this->title), 100)."</title>\n";
688
        $this->descriptionTruncSize = 500;
689
        $feed.= "        <description>".$this->getDescription()."</description>\n";
690
        $feed.= "        <link>".htmlspecialchars($this->link)."</link>\n";
691
692
        $now = new DateTime('@' . time());
693
694
        $feed.= "        <lastBuildDate>".htmlspecialchars($now->format('r'))."</lastBuildDate>\n";
695
        $feed.= "        <generator>".FEEDCREATOR_VERSION."</generator>\n";
696
697
        if ($this->image!=null) {
698
            $feed.= "        <image>\n";
699
            $feed.= "            <url>".$this->image->url."</url>\n";
700
            $feed.= "            <title>".FeedCreator::iTrunc(htmlspecialchars($this->image->title), 100)."</title>\n";
701
            $feed.= "            <link>".htmlspecialchars($this->image->link)."</link>\n";
702
            if ($this->image->width!="") {
703
                $feed.= "            <width>".$this->image->width."</width>\n";
704
            }
705
            if ($this->image->height!="") {
706
                $feed.= "            <height>".$this->image->height."</height>\n";
707
            }
708
            if ($this->image->description!="") {
709
                $feed.= "            <description>".$this->image->getDescription()."</description>\n";
710
            }
711
            $feed.= "        </image>\n";
712
        }
713
        if ($this->language!="") {
714
            $feed.= "        <language>".$this->language."</language>\n";
715
        }
716
        if ($this->copyright!="") {
717
            $feed.= "        <copyright>".FeedCreator::iTrunc(htmlspecialchars($this->copyright), 100)."</copyright>\n";
718
        }
719
        if ($this->editor!="") {
720
            $feed.= "        <managingEditor>".FeedCreator::iTrunc(htmlspecialchars($this->editor), 100)."</managingEditor>\n";
721
        }
722
        if ($this->webmaster!="") {
723
            $feed.= "        <webMaster>".FeedCreator::iTrunc(htmlspecialchars($this->webmaster), 100)."</webMaster>\n";
724
        }
725
        if ($this->pubDate!="") {
726
            $pubDate = new FeedDate($this->pubDate);
727
            $feed.= "        <pubDate>".htmlspecialchars($pubDate->rfc822())."</pubDate>\n";
728
        }
729
        if ($this->category!="") {
730
            $feed.= "        <category>".htmlspecialchars($this->category)."</category>\n";
731
        }
732 View Code Duplication
        if ($this->docs!="") {
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...
733
            $feed.= "        <docs>".FeedCreator::iTrunc(htmlspecialchars($this->docs), 500)."</docs>\n";
734
        }
735
        if ($this->ttl!="") {
736
            $feed.= "        <ttl>".htmlspecialchars($this->ttl)."</ttl>\n";
737
        }
738 View Code Duplication
        if ($this->rating!="") {
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...
739
            $feed.= "        <rating>".FeedCreator::iTrunc(htmlspecialchars($this->rating), 500)."</rating>\n";
740
        }
741
        if ($this->skipHours!="") {
742
            $feed.= "        <skipHours>".htmlspecialchars($this->skipHours)."</skipHours>\n";
743
        }
744
        if ($this->skipDays!="") {
745
            $feed.= "        <skipDays>".htmlspecialchars($this->skipDays)."</skipDays>\n";
746
        }
747
        $feed.= $this->_createAdditionalElements($this->additionalElements, "    ");
748
749
        for ($i=0;$i<count($this->items);$i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
750
            $feed.= "        <item>\n";
751
            $feed.= "            <title>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100)."</title>\n";
752
            $feed.= "            <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
753
            $feed.= "            <description>".$this->items[$i]->getDescription()."</description>\n";
754
755 View Code Duplication
            if ($this->items[$i]->author!="") {
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...
756
                $feed.= "            <author>".htmlspecialchars($this->items[$i]->author)."</author>\n";
757
            }
758
            /*
759
            // on hold
760
            if ($this->items[$i]->source!="") {
761
            $feed.= "            <source>".htmlspecialchars($this->items[$i]->source)."</source>\n";
762
            }
763
            */
764 View Code Duplication
            if ($this->items[$i]->category!="") {
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...
765
                $feed.= "            <category>".htmlspecialchars($this->items[$i]->category)."</category>\n";
766
            }
767 View Code Duplication
            if ($this->items[$i]->comments!="") {
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...
768
                $feed.= "            <comments>".htmlspecialchars($this->items[$i]->comments)."</comments>\n";
769
            }
770 View Code Duplication
            if ($this->items[$i]->date!="") {
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...
771
                $itemDate = new FeedDate($this->items[$i]->date);
772
                $feed.= "            <pubDate>".htmlspecialchars($itemDate->rfc822())."</pubDate>\n";
773
            }
774 View Code Duplication
            if ($this->items[$i]->guid!="") {
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...
775
                $feed.= "            <guid>".htmlspecialchars($this->items[$i]->guid)."</guid>\n";
776
            }
777
            $feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, "        ");
778
779
            if ($this->RSSVersion == "2.0" && $this->items[$i]->enclosure != null) {
780
                                $feed.= "            <enclosure url=\"";
781
                                $feed.= $this->items[$i]->enclosure->url;
782
                                $feed.= "\" length=\"";
783
                                $feed.= $this->items[$i]->enclosure->length;
784
                                $feed.= "\" type=\"";
785
                                $feed.= $this->items[$i]->enclosure->type;
786
                                $feed.= "\"/>\n";
787
            }
788
789
790
791
            $feed.= "        </item>\n";
792
        }
793
794
        $feed.= "    </channel>\n";
795
        $feed.= "</rss>\n";
796
        return $feed;
797
    }
798
}
799
800
801
/**
802
 * RSSCreator20 is a FeedCreator that implements RDF Site Summary (RSS) 2.0.
803
 *
804
 * @see    http://backend.userland.com/rss
805
 * @since  1.3
806
 * @author Kai Blankenhorn <[email protected]>
807
 */
808
class RSSCreator20 extends RSSCreator091
809
{
810
811
    function RSSCreator20()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
812
    {
813
        parent::_setRSSVersion("2.0");
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (_setRSSVersion() instead of RSSCreator20()). Are you sure this is correct? If so, you might want to change this to $this->_setRSSVersion().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
814
    }
815
816
}
817
818
819
/**
820
 * AtomCreator10 is a FeedCreator that implements the atom specification,
821
 * as in http://www.atomenabled.org/developers/syndication/atom-format-spec.php
822
 * Please note that just by using AtomCreator10 you won't automatically
823
 * produce valid atom files. For example, you have to specify either an editor
824
 * for the feed or an author for every single feed item.
825
 *
826
 * Some elements have not been implemented yet. These are (incomplete list):
827
 * author URL, item author's email and URL, item contents, alternate links,
828
 * other link content types than text/html. Some of them may be created with
829
 * AtomCreator10::additionalElements.
830
 *
831
 * @see    FeedCreator#additionalElements
832
 * @since  1.7.2-mod (modified)
833
 * @author Mohammad Hafiz Ismail ([email protected])
834
 */
835
class AtomCreator10 extends FeedCreator
836
{
837
838
    function AtomCreator10()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
839
    {
840
        $this->contentType = "application/atom+xml";
841
        $this->encoding = "utf-8";
842
    }
843
844
    function createFeed( $timezone )
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
845
    {
846
        $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
847
        $feed.= $this->_createGeneratorComment();
848
        $feed.= $this->_createStylesheetReferences();
849
        $feed.= "<feed xmlns=\"http://www.w3.org/2005/Atom\"";
850
        if ($this->language!="") {
851
            $feed.= " xml:lang=\"".$this->language."\"";
852
        }
853
        $feed.= ">\n";
854
        $feed.= "    <title>".htmlspecialchars($this->title)."</title>\n";
855
        $feed.= "    <subtitle type=\"html\">".htmlspecialchars($this->description)."</subtitle>\n";
856
        $feed.= "    <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->link)."\"/>\n";
857
        $feed.= "    <id>".htmlspecialchars($this->link)."</id>\n";
858
        $now = new DateTime('@' . time());
859
        $feed.= "    <updated>".htmlspecialchars($now->format('c'))."</updated>\n";
860
        if ($this->editor!="") {
861
            $feed.= "    <author>\n";
862
            $feed.= "        <name>".$this->editor."</name>\n";
863
            if ($this->editorEmail!="") {
864
                $feed.= "        <email>".$this->editorEmail."</email>\n";
865
            }
866
            $feed.= "    </author>\n";
867
        }
868
        $feed.= "    <generator>".FEEDCREATOR_VERSION."</generator>\n";
869
        $feed.= "<link rel=\"self\" type=\"application/atom+xml\" href=\"". htmlspecialchars($this->syndicationURL) . "\" />\n";
870
        $feed.= $this->_createAdditionalElements($this->additionalElements, "    ");
871
        for ($i=0;$i<count($this->items);$i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
872
            $feed.= "    <entry>\n";
873
            $feed.= "        <title>".htmlspecialchars(strip_tags($this->items[$i]->title))."</title>\n";
874
            $feed.= "        <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
875
            if ($this->items[$i]->date=="") {
876
                $this->items[$i]->date = time();
877
            }
878
            $itemDate = new FeedDate($this->items[$i]->date);
879
            $feed.= "        <published>".htmlspecialchars($itemDate->iso8601())."</published>\n";
880
            $feed.= "        <updated>".htmlspecialchars($itemDate->iso8601())."</updated>\n";
881
            $feed.= "        <id>".htmlspecialchars($this->items[$i]->link)."</id>\n";
882
            $feed.= $this->_createAdditionalElements($this->items[$i]->additionalElements, "        ");
883
            if ($this->items[$i]->author!="") {
884
                $feed.= "        <author>\n";
885
                $feed.= "            <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
886
                $feed.= "        </author>\n";
887
            }
888 View Code Duplication
            if ($this->items[$i]->description!="") {
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...
889
                $feed.= "        <summary type=\"html\">".htmlspecialchars($this->items[$i]->description)."</summary>\n";
890
            }
891
            if ($this->items[$i]->enclosure != null) {
892
                $feed.="        <link rel=\"enclosure\" href=\"". $this->items[$i]->enclosure->url ."\" type=\"". $this->items[$i]->enclosure->type."\"  length=\"". $this->items[$i]->enclosure->length . "\" />\n";
893
            }
894
            $feed.= "    </entry>\n";
895
        }
896
        $feed.= "</feed>\n";
897
        return $feed;
898
    }
899
900
901
}
902
903
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
904