Completed
Push — master ( 15a86c...ff0242 )
by Michael
03:23
created

AtomCreator03::createFeed()   B

Complexity

Conditions 8
Paths 54

Size

Total Lines 53
Code Lines 44

Duplication

Lines 3
Ratio 5.66 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 8
eloc 44
c 4
b 0
f 0
nc 54
nop 0
dl 3
loc 53
rs 7.1199

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
//
3
// ------------------------------------------------------------------------ //
4
// This program is free software; you can redistribute it and/or modify     //
5
// it under the terms of the GNU General Public License as published by     //
6
// the Free Software Foundation; either version 2 of the License, or        //
7
// (at your option) any later version.                                      //
8
//                                                                          //
9
// You may not change or alter any portion of this comment or credits       //
10
// of supporting developers from this source code or any supporting         //
11
// source code which is considered copyrighted (c) material of the          //
12
// original comment or credit authors.                                      //
13
//                                                                          //
14
// This program is distributed in the hope that it will be useful,          //
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of           //
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
17
// GNU General Public License for more details.                             //
18
//                                                                          //
19
// You should have received a copy of the GNU General Public License        //
20
// along with this program; if not, write to the Free Software              //
21
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
22
// ------------------------------------------------------------------------ //
23
// Author: phppp (D.J., [email protected])                                  //
24
// URL: http://xoops.org                         //
25
// Project: Article Project                                                 //
26
// ------------------------------------------------------------------------ //
27
28
/*
29
30
FeedCreator class v1.7.2
31
originally (c) Kai Blankenhorn
32
www.bitfolge.de
33
[email protected]
34
v1.3 work by Scott Reynen ([email protected]) and Kai Blankenhorn
35
v1.5 OPML support by Dirk Clemens
36
37
This library is free software; you can redistribute it and/or
38
modify it under the terms of the GNU Lesser General Public
39
License as published by the Free Software Foundation; either
40
version 2.1 of the License, or (at your option) any later version.
41
42
This library is distributed in the hope that it will be useful,
43
but WITHOUT ANY WARRANTY; without even the implied warranty of
44
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
45
Lesser General Public License for more details.
46
47
You should have received a copy of the GNU Lesser General Public
48
License along with this library; if not, write to the Free Software
49
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
50
51
****************************************************************************
52
53
54
Changelog:
55
56
v1.7.2  10-11-04
57
    license changed to LGPL
58
59
v1.7.1
60
    fixed a syntax bug
61
    fixed left over debug code
62
63
v1.7    07-18-04
64
    added HTML and JavaScript feeds (configurable via CSS) (thanks to Pascal Van Hecke)
65
    added HTML descriptions for all feed formats (thanks to Pascal Van Hecke)
66
    added a switch to select an external stylesheet (thanks to Pascal Van Hecke)
67
    changed default content-type to application/xml
68
    added character encoding setting
69
    fixed numerous smaller bugs (thanks to S�ren Fuhrmann of golem.de)
70
    improved changing ATOM versions handling (thanks to August Trometer)
71
    improved the UniversalFeedCreator's useCached method (thanks to S�ren Fuhrmann of golem.de)
72
    added charset output in HTTP headers (thanks to S�ren Fuhrmann of golem.de)
73
    added Slashdot namespace to RSS 1.0 (thanks to S�ren Fuhrmann of golem.de)
74
75
v1.6    05-10-04
76
    added stylesheet to RSS 1.0 feeds
77
    fixed generator comment (thanks Kevin L. Papendick and Tanguy Pruvot)
78
    fixed RFC822 date bug (thanks Tanguy Pruvot)
79
    added TimeZone customization for RFC8601 (thanks Tanguy Pruvot)
80
    fixed Content-type could be empty (thanks Tanguy Pruvot)
81
    fixed author/creator in RSS1.0 (thanks Tanguy Pruvot)
82
83
v1.6 beta   02-28-04
84
    added Atom 0.3 support (not all features, though)
85
    improved OPML 1.0 support (hopefully - added more elements)
86
    added support for arbitrary additional elements (use with caution)
87
    code beautification :-)
88
    considered beta due to some internal changes
89
90
v1.5.1  01-27-04
91
    fixed some RSS 1.0 glitches (thanks to St�phane Vanpoperynghe)
92
    fixed some inconsistencies between documentation and code (thanks to Timothy Martin)
93
94
v1.5    01-06-04
95
    added support for OPML 1.0
96
    added more documentation
97
98
v1.4    11-11-03
99
    optional feed saving and caching
100
    improved documentation
101
    minor improvements
102
103
v1.3    10-02-03
104
    renamed to FeedCreator, as it not only creates RSS anymore
105
    added support for mbox
106
    tentative support for echo/necho/atom/pie/???
107
108
v1.2    07-20-03
109
    intelligent auto-truncating of RSS 0.91 attributes
110
    don't create some attributes when they're not set
111
    documentation improved
112
    fixed a real and a possible bug with date conversions
113
    code cleanup
114
115
v1.1    06-29-03
116
    added images to feeds
117
    now includes most RSS 0.91 attributes
118
    added RSS 2.0 feeds
119
120
v1.0    06-24-03
121
    initial release
122
123
124
125
***************************************************************************/
126
127
/* ** GENERAL USAGE *********************************************************
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
128
129
include("feedcreator.class.php");
130
131
$rss = new UniversalFeedCreator();
132
$rss->useCached(); // use cached version if age<1 hour
133
$rss->title = "PHP news";
134
$rss->description = "daily news from the PHP scripting world";
135
136
//optional
137
$rss->descriptionTruncSize = 500;
138
$rss->descriptionHtmlSyndicated = true;
139
140
$rss->link = "http://www.dailyphp.net/news";
141
$rss->syndicationURL = "http://www.dailyphp.net/".$_SERVER["PHP_SELF"];
142
143
$image = new FeedImage();
144
$image->title = "dailyphp.net logo";
145
$image->url = "http://www.dailyphp.net/images/logo.gif";
146
$image->link = "http://www.dailyphp.net";
147
$image->description = "Feed provided by dailyphp.net. Click to visit.";
148
149
//optional
150
$image->descriptionTruncSize = 500;
151
$image->descriptionHtmlSyndicated = true;
152
153
$rss->image = $image;
154
155
// get your news items from somewhere, e.g. your database:
156
mysql_select_db($dbHost, $dbUser, $dbPass);
157
$res $GLOBALS['xoopsDB']->query("SELECT * FROM news ORDER BY newsdate DESC");
158
while ($data = mysql_fetch_object($res)) {
159
    $item = new FeedItem();
160
    $item->title = $data->title;
161
    $item->link = $data->url;
162
    $item->description = $data->short;
163
164
    //optional
165
    item->descriptionTruncSize = 500;
166
    item->descriptionHtmlSyndicated = true;
167
168
    $item->date = $data->newsdate;
169
    $item->source = "http://www.dailyphp.net";
170
    $item->author = "John Doe";
171
172
    $rss->addItem($item);
173
}
174
175
// valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1 (deprecated),
176
// MBOX, OPML, ATOM, ATOM0.3, HTML, JS
177
echo $rss->saveFeed("RSS1.0", "news/feed.xml");
178
179
180
***************************************************************************
181
*          A little setup                                                 *
182
**************************************************************************/
183
184
// your local timezone, set to "" to disable or for GMT
185
//define("TIME_ZONE","+01:00");
186
187
/**
188
 * Version string.
189
 **/
190
//define("FEEDCREATOR_VERSION", "ARTICLE @ XOOPS powered by FeedCreator 1.7.2");
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
191
192
/**
193
 * A FeedItem is a part of a FeedCreator feed.
194
 *
195
 * @author Kai Blankenhorn <[email protected]>
196
 * @since  1.3
197
 */
198
class FeedItem extends HtmlDescribable
199
{
200
    /**
201
     * Mandatory attributes of an item.
202
     */
203
    public $title, $description, $link;
204
205
    /**
206
     * Optional attributes of an item.
207
     */
208
    public $author, $authorEmail, $image, $category, $comments, $guid, $source, $creator;
209
210
    /**
211
     * Publishing date of an item. May be in one of the following formats:
212
     *
213
     *  RFC 822:
214
     *  "Mon, 20 Jan 03 18:05:41 +0400"
215
     *  "20 Jan 03 18:05:41 +0000"
216
     *
217
     *  ISO 8601:
218
     *  "2003-01-20T18:05:41+04:00"
219
     *
220
     *  Unix:
221
     *  1043082341
222
     */
223
    public $date;
224
225
    /**
226
     * Any additional elements to include as an assiciated array. All $key => $value pairs
227
     * will be included unencoded in the feed item in the form
228
     *     <$key>$value</$key>
229
     * Again: No encoding will be used! This means you can invalidate or enhance the feed
230
     * if $value contains markup. This may be abused to embed tags not implemented by
231
     * the FeedCreator class used.
232
     */
233
    public $additionalElements = array();
234
235
    // on hold
236
    // var $source;
237
}
238
239
/**
240
 * An FeedImage may be added to a FeedCreator feed.
241
 * @author Kai Blankenhorn <[email protected]>
242
 * @since  1.3
243
 */
244
class FeedImage extends HtmlDescribable
245
{
246
    /**
247
     * Mandatory attributes of an image.
248
     */
249
    public $title, $url, $link;
250
251
    /**
252
     * Optional attributes of an image.
253
     */
254
    public $width, $height, $description;
255
}
256
257
/**
258
 * An HtmlDescribable is an item within a feed that can have a description that may
259
 * include HTML markup.
260
 */
261
class HtmlDescribable
262
{
263
    /**
264
     * Indicates whether the description field should be rendered in HTML.
265
     */
266
    public $descriptionHtmlSyndicated;
267
268
    /**
269
     * Indicates whether and to how many characters a description should be truncated.
270
     */
271
    public $descriptionTruncSize;
272
273
    /**
274
     * Returns a formatted description field, depending on descriptionHtmlSyndicated and
275
     * $descriptionTruncSize properties
276
     * @return string the formatted description
277
     */
278
    public function getDescription() {
279
        $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...
280
        $descriptionField->syndicateHtml = $this->descriptionHtmlSyndicated;
281
        $descriptionField->truncSize     = $this->descriptionTruncSize;
282
283
        return $descriptionField->output();
284
    }
285
}
286
287
/**
288
 * An FeedHtmlField describes and generates
289
 * a feed, item or image html field (probably a description). Output is
290
 * generated based on $truncSize, $syndicateHtml properties.
291
 * @author  Pascal Van Hecke <[email protected]>
292
 */
293
class FeedHtmlField
294
{
295
    /**
296
     * Mandatory attributes of a FeedHtmlField.
297
     */
298
    public $rawFieldContent;
299
300
    /**
301
     * Optional attributes of a FeedHtmlField.
302
     *
303
     */
304
    public $truncSize, $syndicateHtml;
305
306
    /**
307
     * Creates a new instance of FeedHtmlField.
308
     * @param $parFieldContent
309
     * @internal param $string : if given, sets the rawFieldContent property
310
     */
311
    public function __construct($parFieldContent) {
312
        if ($parFieldContent) {
313
            $this->rawFieldContent = $parFieldContent;
314
        }
315
    }
316
317
    /**
318
     * Creates the right output, depending on $truncSize, $syndicateHtml properties.
319
     * @return string the formatted field
320
     */
321
    public function output() {
322
        // when field available and syndicated in html we assume
323
        // - valid html in $rawFieldContent and we enclose in CDATA tags
324
        // - no truncation (truncating risks producing invalid html)
325
        if (!$this->rawFieldContent) {
326
            $result = '';
327
        } elseif ($this->syndicateHtml) {
328
            $result = '<![CDATA[' . $this->rawFieldContent . ']]>';
329
        } else {
330
            if ($this->truncSize && is_int($this->truncSize)) {
331
                $result = FeedCreator::iTrunc(htmlspecialchars($this->rawFieldContent), $this->truncSize);
332
            } else {
333
                $result = htmlspecialchars($this->rawFieldContent);
334
            }
335
        }
336
337
        return $result;
338
    }
339
}
340
341
/**
342
 * UniversalFeedCreator lets you choose during runtime which
343
 * format to build.
344
 * For general usage of a feed class, see the FeedCreator class
345
 * below or the example above.
346
 *
347
 * @since  1.3
348
 * @author Kai Blankenhorn <[email protected]>
349
 */
350
class UniversalFeedCreator extends FeedCreator
351
{
352
    public $_feed;
353
354
    /**
355
     * @param $format
356
     */
357
    public function _setFormat($format) {
358
        switch (strtoupper($format)) {
359
360
            case '2.0':
361
                // fall through
362
            case 'RSS2.0':
363
                $this->_feed = new RSSCreator20();
364
                break;
365
366
            case '1.0':
367
                // fall through
368
            case 'RSS1.0':
369
                $this->_feed = new RSSCreator10();
370
                break;
371
372
            case '0.91':
373
                // fall through
374
            case 'RSS0.91':
375
                $this->_feed = new RSSCreator091();
376
                break;
377
378
            case 'PIE0.1':
379
                $this->_feed = new PIECreator01();
0 ignored issues
show
Deprecated Code introduced by
The class PIECreator01 has been deprecated.

This class, trait or interface has been deprecated.

Loading history...
380
                break;
381
382
            case 'MBOX':
383
                $this->_feed = new MBOXCreator();
384
                break;
385
386
            case 'OPML':
387
                $this->_feed = new OPMLCreator();
388
                break;
389
390
            case 'ATOM':
391
                // fall through: always the latest ATOM version
392
393
            case 'ATOM0.3':
394
                $this->_feed = new AtomCreator03();
395
                break;
396
397
            case 'HTML':
398
                $this->_feed = new HTMLCreator();
399
                break;
400
401
            case 'JS':
402
                // fall through
403
            case 'JAVASCRIPT':
404
                $this->_feed = new JSCreator();
405
                break;
406
407
            default:
408
                $this->_feed = new RSSCreator091();
409
                break;
410
        }
411
412
        $vars = get_object_vars($this);
413
        foreach ($vars as $key => $value) {
414
            // prevent overwriting of properties "contentType", "encoding"; do not copy "_feed" itself
415
            //if (!in_array($key, array("_feed", "contentType", "encoding"))) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
416
            $this->_feed->{$key} = $this->{$key};
417
            //}
418
        }
419
    }
420
421
    /**
422
     * Creates a syndication feed based on the items previously added.
423
     *
424
     * @see        FeedCreator::addItem()
425
     * @param    string    format    format the feed should comply to. Valid values are:
426
     *                     "PIE0.1", "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3", "HTML", "JS"
427
     * @return string the contents of the feed.
428
     */
429
    public function createFeed($format = 'RSS0.91') {
430
        $this->_setFormat($format);
431
432
        return $this->_feed->createFeed();
433
    }
434
435
    /**
436
     * Saves this feed as a file on the local disk. After the file is saved, an HTTP redirect
437
     * header may be sent to redirect the use to the newly created file.
438
     * @since    1.4
439
     *
440
     * @param string $format
441
     * @param string $filename
442
     * @param bool   $displayContents displayContents optional    send the content of the file or not. If true, the file will be sent in the body of the response.
443
     * @internal param format $string format the feed should comply to. Valid values are:
444
     *                                "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM", "ATOM0.3", "HTML", "JS"
445
     * @internal param filename $string optional    the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
446
     */
447
    public function saveFeed($format = 'RSS0.91', $filename = '', $displayContents = true) {
448
        $this->_setFormat($format);
449
        $this->_feed->saveFeed($filename, $displayContents);
450
    }
451
452
    /**
453
     * Turns on caching and checks if there is a recent version of this feed in the cache.
454
     * If there is, an HTTP redirect header is sent.
455
     * To effectively use caching, you should create the FeedCreator object and call this method
456
     * before anything else, especially before you do the time consuming task to build the feed
457
     * (web fetching, for example).
458
     *
459
     * @param string $format
460
     * @param string $filename
461
     * @param int    $timeout
462
     * @internal param format $string format the feed should comply to. Valid values are:
463
     *                     "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
464
     * @internal param string $filename optional the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
465
     * @internal param int $timeout optional the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
466
     */
467
    public function useCached($format = 'RSS0.91', $filename = '', $timeout = 3600) {
468
        $this->_setFormat($format);
469
        $this->_feed->useCached($filename, $timeout);
470
    }
471
}
472
473
/**
474
 * FeedCreator is the abstract base implementation for concrete
475
 * implementations that implement a specific format of syndication.
476
 *
477
 * @abstract
478
 * @author Kai Blankenhorn <[email protected]>
479
 * @since  1.4
480
 */
481
class FeedCreator extends HtmlDescribable
482
{
483
    /**
484
     * Mandatory attributes of a feed.
485
     */
486
    public $title, $description, $link;
487
488
    /**
489
     * Optional attributes of a feed.
490
     */
491
    public $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
492
493
    /**
494
     * The url of the external xsl stylesheet used to format the naked rss feed.
495
     * Ignored in the output when empty.
496
     */
497
    public $xslStyleSheet = '';
498
499
    public $cssStyleSheet = '';
500
501
    /**
502
     * @access private
503
     */
504
    public $items = array();
505
506
    /**
507
     * This feed's MIME content type.
508
     * @since  1.4
509
     * @access private
510
     */
511
    public $contentType = 'application/xml';
512
513
    /**
514
     * This feed's character encoding.
515
     * @since 1.6.1
516
     **/
517
    public $encoding = 'ISO-8859-1';
518
519
    /**
520
     * Any additional elements to include as an assiciated array. All $key => $value pairs
521
     * will be included unencoded in the feed in the form
522
     *     <$key>$value</$key>
523
     * Again: No encoding will be used! This means you can invalidate or enhance the feed
524
     * if $value contains markup. This may be abused to embed tags not implemented by
525
     * the FeedCreator class used.
526
     */
527
    public $additionalElements = array();
528
529
    /**
530
     * Adds an FeedItem to the feed.
531
     *
532
     * @param $item
533
     * @internal param FeedItem $object $item The FeedItem to add to the feed.
534
     * @access   public
535
     */
536
    public function addItem($item) {
537
        $this->items[] = $item;
538
    }
539
540
    /**
541
     * Truncates a string to a certain length at the most sensible point.
542
     * First, if there's a '.' character near the end of the string, the string is truncated after this character.
543
     * If there is no '.', the string is truncated after the last ' ' character.
544
     * If the string is truncated, " ..." is appended.
545
     * If the string is already shorter than $length, it is returned unchanged.
546
     *
547
     * @static
548
     * @param string     string A string to be truncated.
549
     * @param int        length the maximum length the string should be truncated to
550
     * @return string the truncated string
551
     */
552
    public function iTrunc($string, $length) {
553
        if (strlen($string) <= $length) {
554
            return $string;
555
        }
556
557
        $pos = strrpos($string, '.');
558 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...
559
            $string = substr($string, 0, $length - 4);
560
            $pos    = strrpos($string, '.');
561
        }
562
        if ($pos >= $length * 0.4) {
563
            return substr($string, 0, $pos + 1) . ' ...';
564
        }
565
566
        $pos = strrpos($string, ' ');
567 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...
568
            $string = substr($string, 0, $length - 4);
569
            $pos    = strrpos($string, ' ');
570
        }
571
        if ($pos >= $length * 0.4) {
572
            return substr($string, 0, $pos) . ' ...';
573
        }
574
575
        return substr($string, 0, $length - 4) . ' ...';
576
    }
577
578
    /**
579
     * Creates a comment indicating the generator of this feed.
580
     * The format of this comment seems to be recognized by
581
     * Syndic8.com.
582
     */
583
    public function _createGeneratorComment() {
584
        return "<!-- generator=\"" . FEEDCREATOR_VERSION . "\" -->\n";
585
    }
586
587
    /**
588
     * Creates a string containing all additional elements specified in
589
     * $additionalElements.
590
     * @param array  $elements
591
     * @param string $indentString
592
     * @return string the XML tags corresponding to $additionalElements
593
     * @internal param array $elements an associative array containing key => value pairs
594
     * @internal param string $indentString a string that will be inserted before every generated line
595
     */
596
    public function _createAdditionalElements($elements, $indentString = '') {
597
        $ae = '';
598
        if (is_array($elements)) {
599
            foreach ($elements as $key => $value) {
600
                $ae .= $indentString . "<$key>$value</$key>\n";
601
            }
602
        }
603
604
        return $ae;
605
    }
606
607
    /**
608
     * @return string
609
     */
610
    public function _createStylesheetReferences() {
611
        $xml = '';
612
        if ($this->cssStyleSheet) {
613
            $xml .= "<?xml-stylesheet href=\"" . $this->cssStyleSheet . "\" type=\"text/css\"?>\n";
614
        }
615
        if ($this->xslStyleSheet) {
616
            $xml .= "<?xml-stylesheet href=\"" . $this->xslStyleSheet . "\" type=\"text/xsl\"?>\n";
617
        }
618
619
        return $xml;
620
    }
621
622
    /**
623
     * Builds the feed's text.
624
     * @abstract
625
     * @return string the feed's complete text
626
     */
627
    public function createFeed() {
628
    }
629
630
    /**
631
     * Generate a filename for the feed cache file. The result will be $_SERVER["PHP_SELF"] with the extension changed to .xml.
632
     * For example:
633
     *
634
     * echo $_SERVER["PHP_SELF"]."\n";
635
     * echo FeedCreator::_generateFilename();
636
     *
637
     * would produce:
638
     *
639
     * /rss/latestnews.php
640
     * latestnews.xml
641
     *
642
     * @return string the feed cache filename
643
     * @since  1.4
644
     * @access private
645
     */
646
    public function _generateFilename() {
647
        $fileInfo = pathinfo($_SERVER['PHP_SELF']);
648
649
        return substr($fileInfo['basename'], 0, -(strlen($fileInfo['extension']) + 1)) . '.xml';
650
    }
651
652
    /**
653
     * @since  1.4
654
     * @access private
655
     * @param $filename
656
     */
657
    public function _redirect($filename) {
658
        // attention, heavily-commented-out-area
659
660
        // maybe use this in addition to file time checking
661
        //Header("Expires: ".date("r",time()+$this->_timeout));
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
662
663
        /* no caching at all, doesn't seem to work as good:
664
        Header("Cache-Control: no-cache");
665
        Header("Pragma: no-cache");
666
        */
667
668
        // HTTP redirect, some feed readers' simple HTTP implementations don't follow it
669
        //Header("Location: ".$filename);
0 ignored issues
show
Unused Code Comprehensibility introduced by
72% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
670
671
        header('Content-Type: ' . $this->contentType . '; charset=' . $this->encoding . '; filename='
672
               . basename($filename));
673
        header('Content-Disposition: inline; filename=' . basename($filename));
674
        readfile($filename, 'r');
675
        die();
676
    }
677
678
    /**
679
     * Turns on caching and checks if there is a recent version of this feed in the cache.
680
     * If there is, an HTTP redirect header is sent.
681
     * To effectively use caching, you should create the FeedCreator object and call this method
682
     * before anything else, especially before you do the time consuming task to build the feed
683
     * (web fetching, for example).
684
     * @since    1.4
685
     * @param     filename  string  optional    the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
686
     * @param int $timeout
687
     * @internal param int $timeout optional    the timeout in seconds before a cached version is refreshed (defaults to 3600 = 1 hour)
688
     */
689
    public function useCached($filename = '', $timeout = 3600) {
690
        $this->_timeout = $timeout;
0 ignored issues
show
Bug introduced by
The property _timeout 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...
691
        if ($filename == '') {
692
            $filename = $this->_generateFilename();
693
        }
694
        if (file_exists($filename) && (time() - filemtime($filename) < $timeout)) {
695
            $this->_redirect($filename);
696
        }
697
    }
698
699
    /**
700
     * Saves this feed as a file on the local disk. After the file is saved, a redirect
701
     * header may be sent to redirect the user to the newly created file.
702
     * @since    1.4
703
     *
704
     * @param      filename  string  optional    the filename where a recent version of the feed is saved. If not specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see _generateFilename()).
705
     * @param bool $displayContents
706
     * @internal param bool $redirect optional    send an HTTP redirect header or not. If true, the user will be automatically redirected to the created file.
707
     */
708
    public function saveFeed($filename = '', $displayContents = true) {
709
        if ($filename == '') {
710
            $filename = $this->_generateFilename();
711
        }
712
        $feedFile = fopen($filename, 'w+');
713
        if ($feedFile) {
714
            fwrite($feedFile, $this->createFeed());
715
            fclose($feedFile);
716
            if ($displayContents) {
717
                $this->_redirect($filename);
718
            }
719
        } else {
720
            echo '<br><b>Error creating feed file, please check write permissions.</b><br>';
721
        }
722
    }
723
}
724
725
/**
726
 * FeedDate is an internal class that stores a date for a feed or feed item.
727
 * Usually, you won't need to use this.
728
 */
729
class FeedDate
730
{
731
    public $unix;
732
733
    /**
734
     * Creates a new instance of FeedDate representing a given date.
735
     * Accepts RFC 822, ISO 8601 date formats as well as unix time stamps.
736
     * @param mixed $dateString optional the date this FeedDate will represent. If not specified, the current date and time is used.
737
     */
738
    public function __construct($dateString = '') {
739
        $tzOffset = 0;
740
        if ($dateString == '') {
741
            $dateString = date('r');
742
        }
743
744
        //if (is_integer($dateString)) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
745
        if (is_numeric($dateString)) {
746
            $this->unix = $dateString;
747
748
            return;
749
        }
750
        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+(.*)~",
751
                       $dateString, $matches)) {
752
            $months     = array(
753
                'Jan' => 1,
754
                'Feb' => 2,
755
                'Mar' => 3,
756
                'Apr' => 4,
757
                'May' => 5,
758
                'Jun' => 6,
759
                'Jul' => 7,
760
                'Aug' => 8,
761
                'Sep' => 9,
762
                'Oct' => 10,
763
                'Nov' => 11,
764
                'Dec' => 12
765
            );
766
            $this->unix = mktime($matches[4], $matches[5], $matches[6], $months[$matches[2]], $matches[1], $matches[3]);
767
            if (substr($matches[7], 0, 1) == '+' || substr($matches[7], 0, 1) == '-') {
768
                $tzOffset = (substr($matches[7], 0, 3) * 60 + substr($matches[7], -2)) * 60;
769
            } else {
770
                if (strlen($matches[7]) == 1) {
771
                    $oneHour = 3600;
772
                    $ord     = ord($matches[7]);
773
                    if ($ord < ord('M')) {
774
                        $tzOffset = (ord('A') - $ord - 1) * $oneHour;
775
                    } elseif ($ord >= ord('M') && $matches[7] !== 'Z') {
776
                        $tzOffset = ($ord - ord('M')) * $oneHour;
777
                    } elseif ($matches[7] === 'Z') {
778
                        $tzOffset = 0;
779
                    }
780
                }
781
                switch ($matches[7]) {
782
                    case 'UT':
783
                    case 'GMT':
784
                        $tzOffset = 0;
785
                }
786
            }
787
            $this->unix += $tzOffset;
788
789
            return;
790
        }
791
        if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~", $dateString, $matches)) {
792
            $this->unix = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
793
            if (substr($matches[7], 0, 1) == '+' || substr($matches[7], 0, 1) == '-') {
794
                $tzOffset = (substr($matches[7], 0, 3) * 60 + substr($matches[7], -2)) * 60;
795
            } else {
796
                if ($matches[7] === 'Z') {
797
                    $tzOffset = 0;
798
                }
799
            }
800
            $this->unix += $tzOffset;
801
802
            return;
803
        }
804
        $this->unix = 0;
805
    }
806
807
    /**
808
     * Gets the date stored in this FeedDate as an RFC 822 date.
809
     *
810
     * @return a date in RFC 822 format
811
     */
812
    public function rfc822() {
813
        //return gmdate("r",$this->unix);
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
814
        $date = gmdate('D, d M Y H:i:s', $this->unix);
815
        if (TIME_ZONE != '') {
816
            $date .= ' ' . str_replace(':', '', TIME_ZONE);
817
        }
818
819
        return $date;
820
    }
821
822
    /**
823
     * Gets the date stored in this FeedDate as an ISO 8601 date.
824
     *
825
     * @return a date in ISO 8601 format
826
     */
827
    public function iso8601() {
828
        $date = gmdate("Y-m-d\TH:i:sO", $this->unix);
829
        $date = substr($date, 0, 22) . ':' . substr($date, -2);
830
        if (TIME_ZONE != '') {
831
            $date = str_replace('+00:00', TIME_ZONE, $date);
832
        }
833
834
        return $date;
835
    }
836
837
    /**
838
     * Gets the date stored in this FeedDate as unix time stamp.
839
     *
840
     * @return a date as a unix time stamp
841
     */
842
    public function unix() {
843
        return $this->unix;
844
    }
845
}
846
847
/**
848
 * RSSCreator10 is a FeedCreator that implements RDF Site Summary (RSS) 1.0.
849
 *
850
 * @see    http://www.purl.org/rss/1.0/
851
 * @since  1.3
852
 * @author Kai Blankenhorn <[email protected]>
853
 */
854
class RSSCreator10 extends FeedCreator
855
{
856
    /**
857
     * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
858
     * The feed will contain all items previously added in the same order.
859
     * @return string the feed's complete text
860
     */
861
    public function createFeed() {
862
        $feed = "<?xml version=\"1.0\" encoding=\"" . $this->encoding . "\"?>\n";
863
        $feed .= $this->_createGeneratorComment();
864
        if ($this->cssStyleSheet == '') {
865
            $cssStyleSheet = 'http://www.w3.org/2000/08/w3c-synd/style.css';
0 ignored issues
show
Unused Code introduced by
$cssStyleSheet is not used, you could remove the assignment.

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

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

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

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

Loading history...
866
        }
867
        $feed .= $this->_createStylesheetReferences();
868
        $feed .= "<rdf:RDF\n";
869
        $feed .= "    xmlns=\"http://purl.org/rss/1.0/\"\n";
870
        $feed .= "    xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n";
871
        $feed .= "    xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\"\n";
872
        $feed .= "    xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n";
873
        $feed .= "    <channel rdf:about=\"" . $this->syndicationURL . "\">\n";
874
        $feed .= '        <title>' . htmlspecialchars($this->title) . "</title>\n";
875
        $feed .= '        <description>' . htmlspecialchars($this->description) . "</description>\n";
876
        $feed .= '        <link>' . $this->link . "</link>\n";
877
        if ($this->image != null) {
878
            $feed .= "        <image rdf:resource=\"" . $this->image->url . "\" />\n";
879
        }
880
        $now = new FeedDate();
881
        $feed .= '       <dc:date>' . htmlspecialchars($now->iso8601()) . "</dc:date>\n";
882
        $feed .= "        <items>\n";
883
        $feed .= "            <rdf:Seq>\n";
884
        for ($i = 0, $iMax = count($this->items); $i < $iMax; ++$i) {
885
            $feed .= "                <rdf:li rdf:resource=\"" . htmlspecialchars($this->items[$i]->link) . "\"/>\n";
886
        }
887
        $feed .= "            </rdf:Seq>\n";
888
        $feed .= "        </items>\n";
889
        $feed .= "    </channel>\n";
890
        if ($this->image != null) {
891
            $feed .= "    <image rdf:about=\"" . $this->image->url . "\">\n";
892
            $feed .= '        <title>' . $this->image->title . "</title>\n";
893
            $feed .= '        <link>' . $this->image->link . "</link>\n";
894
            $feed .= '        <url>' . $this->image->url . "</url>\n";
895
            $feed .= "    </image>\n";
896
        }
897
        $feed .= $this->_createAdditionalElements($this->additionalElements, '    ');
898
899
        for ($i = 0, $iMax = count($this->items); $i < $iMax; ++$i) {
900
            $feed .= "    <item rdf:about=\"" . htmlspecialchars($this->items[$i]->link) . "\">\n";
901
            //$feed.= "        <dc:type>Posting</dc:type>\n";
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
902
            $feed .= "        <dc:format>text/html</dc:format>\n";
903
            if ($this->items[$i]->date != null) {
904
                $itemDate = new FeedDate($this->items[$i]->date);
905
                $feed .= '        <dc:date>' . htmlspecialchars($itemDate->iso8601()) . "</dc:date>\n";
906
            }
907 View Code Duplication
            if ($this->items[$i]->source != '') {
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...
908
                $feed .= '        <dc:source>' . htmlspecialchars($this->items[$i]->source) . "</dc:source>\n";
909
            }
910 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...
911
                $feed .= '        <dc:creator>' . htmlspecialchars($this->items[$i]->author) . "</dc:creator>\n";
912
            }
913
            $feed .= '        <title>' . htmlspecialchars(strip_tags(strtr($this->items[$i]->title, "\n\r", '  ')))
914
                     . "</title>\n";
915
            $feed .= '        <link>' . htmlspecialchars($this->items[$i]->link) . "</link>\n";
916
            $feed .= '        <description>' . htmlspecialchars($this->items[$i]->description) . "</description>\n";
917
            $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, '        ');
918
            $feed .= "    </item>\n";
919
        }
920
        $feed .= "</rdf:RDF>\n";
921
922
        return $feed;
923
    }
924
}
925
926
/**
927
 * RSSCreator091 is a FeedCreator that implements RSS 0.91 Spec, revision 3.
928
 *
929
 * @see    http://my.netscape.com/publish/formats/rss-spec-0.91.html
930
 * @since  1.3
931
 * @author Kai Blankenhorn <[email protected]>
932
 */
933
class RSSCreator091 extends FeedCreator
934
{
935
    /**
936
     * Stores this RSS feed's version number.
937
     * @access private
938
     */
939
    public $RSSVersion;
940
941
    /**
942
     * RSSCreator091 constructor.
943
     */
944
    public function __construct() {
945
        $this->_setRSSVersion('0.91');
946
        $this->contentType = 'application/rss+xml';
947
    }
948
949
    /**
950
     * Sets this RSS feed's version number.
951
     * @access private
952
     * @param $version
953
     */
954
    public function _setRSSVersion($version) {
955
        $this->RSSVersion = $version;
956
    }
957
958
    /**
959
     * Builds the RSS feed's text. The feed will be compliant to RDF Site Summary (RSS) 1.0.
960
     * The feed will contain all items previously added in the same order.
961
     * @return string the feed's complete text
962
     */
963
    public function createFeed() {
964
        $feed = "<?xml version=\"1.0\" encoding=\"" . $this->encoding . "\"?>\n";
965
        $feed .= $this->_createGeneratorComment();
966
        $feed .= $this->_createStylesheetReferences();
967
        $feed .= "<rss version=\"" . $this->RSSVersion . "\">\n";
968
        $feed .= "    <channel>\n";
969
        $feed .= '        <title>' . FeedCreator::iTrunc(htmlspecialchars($this->title), 100) . "</title>\n";
970
        $this->descriptionTruncSize = 500;
971
        $feed .= '        <description>' . $this->getDescription() . "</description>\n";
972
        $feed .= '        <link>' . $this->link . "</link>\n";
973
        $now = new FeedDate();
974
        $feed .= '        <lastBuildDate>' . htmlspecialchars($now->rfc822()) . "</lastBuildDate>\n";
975
        $feed .= '        <generator>' . FEEDCREATOR_VERSION . "</generator>\n";
976
977
        if ($this->image != null) {
978
            $feed .= "        <image>\n";
979
            $feed .= '            <url>' . $this->image->url . "</url>\n";
980
            $feed .= '            <title>' . FeedCreator::iTrunc(htmlspecialchars($this->image->title), 100)
981
                     . "</title>\n";
982
            $feed .= '            <link>' . $this->image->link . "</link>\n";
983
            if ($this->image->width != '') {
984
                $feed .= '            <width>' . $this->image->width . "</width>\n";
985
            }
986
            if ($this->image->height != '') {
987
                $feed .= '            <height>' . $this->image->height . "</height>\n";
988
            }
989
            if ($this->image->description != '') {
990
                $feed .= '            <description>' . $this->image->getDescription() . "</description>\n";
991
            }
992
            $feed .= "        </image>\n";
993
        }
994
        if ($this->language != '') {
995
            $feed .= '        <language>' . $this->language . "</language>\n";
996
        }
997
        if ($this->copyright != '') {
998
            $feed .= '        <copyright>' . FeedCreator::iTrunc(htmlspecialchars($this->copyright), 100)
999
                     . "</copyright>\n";
1000
        }
1001
        if ($this->editor != '') {
1002
            $feed .= '        <managingEditor>' . FeedCreator::iTrunc(htmlspecialchars($this->editor), 100)
1003
                     . "</managingEditor>\n";
1004
        }
1005
        if ($this->webmaster != '') {
1006
            $feed .= '        <webMaster>' . FeedCreator::iTrunc(htmlspecialchars($this->webmaster), 100)
1007
                     . "</webMaster>\n";
1008
        }
1009
        if ($this->pubDate != '') {
1010
            $pubDate = new FeedDate($this->pubDate);
1011
            $feed .= '        <pubDate>' . htmlspecialchars($pubDate->rfc822()) . "</pubDate>\n";
1012
        }
1013
        if ($this->category != '') {
1014
            $feed .= '        <category>' . htmlspecialchars($this->category) . "</category>\n";
1015
        }
1016 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...
1017
            $feed .= '        <docs>' . FeedCreator::iTrunc(htmlspecialchars($this->docs), 500) . "</docs>\n";
1018
        }
1019
        if ($this->ttl != '') {
1020
            $feed .= '        <ttl>' . htmlspecialchars($this->ttl) . "</ttl>\n";
1021
        }
1022 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...
1023
            $feed .= '        <rating>' . FeedCreator::iTrunc(htmlspecialchars($this->rating), 500) . "</rating>\n";
1024
        }
1025
        if ($this->skipHours != '') {
1026
            $feed .= '        <skipHours>' . htmlspecialchars($this->skipHours) . "</skipHours>\n";
1027
        }
1028
        if ($this->skipDays != '') {
1029
            $feed .= '        <skipDays>' . htmlspecialchars($this->skipDays) . "</skipDays>\n";
1030
        }
1031
        $feed .= $this->_createAdditionalElements($this->additionalElements, '    ');
1032
1033
        for ($i = 0, $iMax = count($this->items); $i < $iMax; ++$i) {
1034
            $feed .= "        <item>\n";
1035
            $feed .= '            <title>' . FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)),
1036
                                                                 100) . "</title>\n";
1037
            $feed .= '            <link>' . htmlspecialchars($this->items[$i]->link) . "</link>\n";
1038
            $feed .= '            <description>' . $this->items[$i]->getDescription() . "</description>\n";
1039
1040 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...
1041
                $feed .= '            <author>' . htmlspecialchars($this->items[$i]->author) . "</author>\n";
1042
            }
1043
            /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1044
            // on hold
1045
            if ($this->items[$i]->source!="") {
1046
                    $feed.= "            <source>".htmlspecialchars($this->items[$i]->source)."</source>\n";
1047
            }
1048
            */
1049 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...
1050
                $feed .= '            <category>' . htmlspecialchars($this->items[$i]->category) . "</category>\n";
1051
            }
1052 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...
1053
                $feed .= '            <comments>' . htmlspecialchars($this->items[$i]->comments) . "</comments>\n";
1054
            }
1055 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...
1056
                $itemDate = new FeedDate($this->items[$i]->date);
1057
                $feed .= '            <pubDate>' . htmlspecialchars($itemDate->rfc822()) . "</pubDate>\n";
1058
            }
1059 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...
1060
                $feed .= '            <guid>' . htmlspecialchars($this->items[$i]->guid) . "</guid>\n";
1061
            }
1062
            $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, '        ');
1063
            $feed .= "        </item>\n";
1064
        }
1065
        $feed .= "    </channel>\n";
1066
        $feed .= "</rss>\n";
1067
1068
        return $feed;
1069
    }
1070
}
1071
1072
/**
1073
 * RSSCreator20 is a FeedCreator that implements RDF Site Summary (RSS) 2.0.
1074
 *
1075
 * @see    http://backend.userland.com/rss
1076
 * @since  1.3
1077
 * @author Kai Blankenhorn <[email protected]>
1078
 */
1079
class RSSCreator20 extends RSSCreator091
1080
{
1081
    /**
1082
     * RSSCreator20 constructor.
1083
     */
1084
    public function __construct() {
1085
        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 __construct()). 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...
1086
    }
1087
}
1088
1089
/**
1090
 * PIECreator01 is a FeedCreator that implements the emerging PIE specification,
1091
 * as in http://intertwingly.net/wiki/pie/Syntax.
1092
 *
1093
 * @deprecated
1094
 * @since  1.3
1095
 * @author Scott Reynen <[email protected]> and Kai Blankenhorn <[email protected]>
1096
 */
1097
class PIECreator01 extends FeedCreator
1098
{
1099
    /**
1100
     * PIECreator01 constructor.
1101
     */
1102
    public function __construct() {
1103
        $this->encoding = 'utf-8';
1104
    }
1105
1106
    /**
1107
     * @return string
1108
     */
1109
    public function createFeed() {
1110
        $feed = "<?xml version=\"1.0\" encoding=\"" . $this->encoding . "\"?>\n";
1111
        $feed .= $this->_createStylesheetReferences();
1112
        $feed .= "<feed version=\"0.1\" xmlns=\"http://example.com/newformat#\">\n";
1113
        $feed .= '    <title>' . FeedCreator::iTrunc(htmlspecialchars($this->title), 100) . "</title>\n";
1114
        $this->truncSize = 500;
0 ignored issues
show
Bug introduced by
The property truncSize does not seem to exist. Did you mean descriptionTruncSize?

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...
1115
        $feed .= '    <subtitle>' . $this->getDescription() . "</subtitle>\n";
1116
        $feed .= '    <link>' . $this->link . "</link>\n";
1117
        for ($i = 0, $iMax = count($this->items); $i < $iMax; ++$i) {
1118
            $feed .= "    <entry>\n";
1119
            $feed .= '        <title>' . FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100)
1120
                     . "</title>\n";
1121
            $feed .= '        <link>' . htmlspecialchars($this->items[$i]->link) . "</link>\n";
1122
            $itemDate = new FeedDate($this->items[$i]->date);
1123
            $feed .= '        <created>' . htmlspecialchars($itemDate->iso8601()) . "</created>\n";
1124
            $feed .= '        <issued>' . htmlspecialchars($itemDate->iso8601()) . "</issued>\n";
1125
            $feed .= '        <modified>' . htmlspecialchars($itemDate->iso8601()) . "</modified>\n";
1126
            $feed .= '        <id>' . htmlspecialchars($this->items[$i]->guid) . "</id>\n";
1127
            if ($this->items[$i]->author != '') {
1128
                $feed .= "        <author>\n";
1129
                $feed .= '            <name>' . htmlspecialchars($this->items[$i]->author) . "</name>\n";
1130
                if ($this->items[$i]->authorEmail != '') {
1131
                    $feed .= '            <email>' . $this->items[$i]->authorEmail . "</email>\n";
1132
                }
1133
                $feed .= "        </author>\n";
1134
            }
1135
            $feed .= "        <content type=\"text/html\" xml:lang=\"en-us\">\n";
1136
            $feed .= "            <div xmlns=\"http://www.w3.org/1999/xhtml\">" . $this->items[$i]->getDescription()
1137
                     . "</div>\n";
1138
            $feed .= "        </content>\n";
1139
            $feed .= "    </entry>\n";
1140
        }
1141
        $feed .= "</feed>\n";
1142
1143
        return $feed;
1144
    }
1145
}
1146
1147
/**
1148
 * AtomCreator03 is a FeedCreator that implements the atom specification,
1149
 * as in http://www.intertwingly.net/wiki/pie/FrontPage.
1150
 * Please note that just by using AtomCreator03 you won't automatically
1151
 * produce valid atom files. For example, you have to specify either an editor
1152
 * for the feed or an author for every single feed item.
1153
 *
1154
 * Some elements have not been implemented yet. These are (incomplete list):
1155
 * author URL, item author's email and URL, item contents, alternate links,
1156
 * other link content types than text/html. Some of them may be created with
1157
 * AtomCreator03::additionalElements.
1158
 *
1159
 * @see    FeedCreator#additionalElements
1160
 * @since  1.6
1161
 * @author Kai Blankenhorn <[email protected]>, Scott Reynen <[email protected]>
1162
 */
1163
class AtomCreator03 extends FeedCreator
1164
{
1165
    /**
1166
     * AtomCreator03 constructor.
1167
     */
1168
    public function __construct() {
1169
        $this->contentType = 'application/atom+xml';
1170
        $this->encoding    = 'utf-8';
1171
    }
1172
1173
    /**
1174
     * @return string
1175
     */
1176
    public function createFeed() {
1177
        $feed = "<?xml version=\"1.0\" encoding=\"" . $this->encoding . "\"?>\n";
1178
        $feed .= $this->_createGeneratorComment();
1179
        $feed .= $this->_createStylesheetReferences();
1180
        $feed .= "<feed version=\"0.3\" xmlns=\"http://purl.org/atom/ns#\"";
1181
        if ($this->language != '') {
1182
            $feed .= " xml:lang=\"" . $this->language . "\"";
1183
        }
1184
        $feed .= ">\n";
1185
        $feed .= '    <title>' . htmlspecialchars($this->title) . "</title>\n";
1186
        $feed .= '    <tagline>' . htmlspecialchars($this->description) . "</tagline>\n";
1187
        $feed .= "    <link rel=\"alternate\" type=\"text/html\" href=\"" . htmlspecialchars($this->link) . "\"/>\n";
1188
        $feed .= '    <id>' . htmlspecialchars($this->link) . "</id>\n";
1189
        $now = new FeedDate();
1190
        $feed .= '    <modified>' . htmlspecialchars($now->iso8601()) . "</modified>\n";
1191
        if ($this->editor != '') {
1192
            $feed .= "    <author>\n";
1193
            $feed .= '        <name>' . $this->editor . "</name>\n";
1194
            if ($this->editorEmail != '') {
1195
                $feed .= '        <email>' . $this->editorEmail . "</email>\n";
1196
            }
1197
            $feed .= "    </author>\n";
1198
        }
1199
        $feed .= '    <generator>' . FEEDCREATOR_VERSION . "</generator>\n";
1200
        $feed .= $this->_createAdditionalElements($this->additionalElements, '    ');
1201
        for ($i = 0, $iMax = count($this->items); $i < $iMax; ++$i) {
1202
            $feed .= "    <entry>\n";
1203
            $feed .= '        <title>' . htmlspecialchars(strip_tags($this->items[$i]->title)) . "</title>\n";
1204
            $feed .= "        <link rel=\"alternate\" type=\"text/html\" href=\""
1205
                     . htmlspecialchars($this->items[$i]->link) . "\"/>\n";
1206
            if ($this->items[$i]->date == '') {
1207
                $this->items[$i]->date = time();
1208
            }
1209
            $itemDate = new FeedDate($this->items[$i]->date);
1210
            $feed .= '        <created>' . htmlspecialchars($itemDate->iso8601()) . "</created>\n";
1211
            $feed .= '        <issued>' . htmlspecialchars($itemDate->iso8601()) . "</issued>\n";
1212
            $feed .= '        <modified>' . htmlspecialchars($itemDate->iso8601()) . "</modified>\n";
1213
            $feed .= '        <id>' . htmlspecialchars($this->items[$i]->link) . "</id>\n";
1214
            $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, '        ');
1215
            if ($this->items[$i]->author != '') {
1216
                $feed .= "        <author>\n";
1217
                $feed .= '            <name>' . htmlspecialchars($this->items[$i]->author) . "</name>\n";
1218
                $feed .= "        </author>\n";
1219
            }
1220 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...
1221
                $feed .= '        <summary>' . htmlspecialchars($this->items[$i]->description) . "</summary>\n";
1222
            }
1223
            $feed .= "    </entry>\n";
1224
        }
1225
        $feed .= "</feed>\n";
1226
1227
        return $feed;
1228
    }
1229
}
1230
1231
/**
1232
 * MBOXCreator is a FeedCreator that implements the mbox format
1233
 * as described in http://www.qmail.org/man/man5/mbox.html
1234
 *
1235
 * @since  1.3
1236
 * @author Kai Blankenhorn <[email protected]>
1237
 */
1238
class MBOXCreator extends FeedCreator
1239
{
1240
    /**
1241
     * MBOXCreator constructor.
1242
     */
1243
    public function __construct() {
1244
        $this->contentType = 'text/plain';
1245
        $this->encoding    = 'ISO-8859-15';
1246
    }
1247
1248
    /**
1249
     * @param string $input
1250
     * @param int    $line_max
1251
     * @return string
1252
     */
1253
    public function qp_enc($input = '', $line_max = 76) {
1254
        $hex    = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
1255
        $lines  = preg_split("/(?:\r\n|\r|\n)/", $input);
1256
        $eol    = "\r\n";
1257
        $escape = '=';
1258
        $output = '';
1259
        while (list(, $line) = each($lines)) {
1260
            //$line = rtrim($line); // remove trailing white space -> no =20\r\n necessary
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1261
            $linlen  = strlen($line);
1262
            $newline = '';
1263
            for ($i = 0; $i < $linlen; ++$i) {
1264
                $c   = substr($line, $i, 1);
1265
                $dec = ord($c);
1266
                if (($dec == 32) && ($i == ($linlen - 1))) { // convert space at eol only
1267
                    $c = '=20';
1268
                } elseif (($dec == 61) || ($dec < 32) || ($dec > 126)) { // always encode "\t", which is *not* required
1269
                    $h2 = floor($dec / 16);
1270
                    $h1 = floor($dec % 16);
1271
                    $c  = $escape . $hex["$h2"] . $hex["$h1"];
1272
                }
1273
                if ((strlen($newline) + strlen($c)) >= $line_max) { // CRLF is not counted
1274
                    $output .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay
1275
                    $newline = '';
1276
                }
1277
                $newline .= $c;
1278
            } // end of for
1279
            $output .= $newline . $eol;
1280
        }
1281
1282
        return trim($output);
1283
    }
1284
1285
    /**
1286
     * Builds the MBOX contents.
1287
     * @return string the feed's complete text
1288
     */
1289
    public function createFeed() {
1290
        for ($i = 0, $iMax = count($this->items); $i < $iMax; ++$i) {
1291
            if ($this->items[$i]->author != '') {
1292
                $from = $this->items[$i]->author;
1293
            } else {
1294
                $from = $this->title;
1295
            }
1296
            $itemDate = new FeedDate($this->items[$i]->date);
1297
            $feed .= 'From ' . strtr(MBOXCreator::qp_enc($from), ' ', '_') . ' ' . date('D M d H:i:s Y',
0 ignored issues
show
Bug introduced by
The variable $feed 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...
1298
                                                                                        $itemDate->unix()) . "\n";
1299
            $feed .= "Content-Type: text/plain;\n";
1300
            $feed .= "   charset=\"" . $this->encoding . "\"\n";
1301
            $feed .= "Content-Transfer-Encoding: quoted-printable\n";
1302
            $feed .= "Content-Type: text/plain\n";
1303
            $feed .= "From: \"" . MBOXCreator::qp_enc($from) . "\"\n";
1304
            $feed .= 'Date: ' . $itemDate->rfc822() . "\n";
1305
            $feed .= 'Subject: ' . MBOXCreator::qp_enc(FeedCreator::iTrunc($this->items[$i]->title, 100)) . "\n";
1306
            $feed .= "\n";
1307
            $body = chunk_split(MBOXCreator::qp_enc($this->items[$i]->description));
1308
            $feed .= preg_replace("~\nFrom ([^\n]*)(\n?)~", "\n>From $1$2\n", $body);
1309
            $feed .= "\n";
1310
            $feed .= "\n";
1311
        }
1312
1313
        return $feed;
1314
    }
1315
1316
    /**
1317
     * Generate a filename for the feed cache file. Overridden from FeedCreator to prevent XML data types.
1318
     * @return string the feed cache filename
1319
     * @since  1.4
1320
     * @access private
1321
     */
1322
    public function _generateFilename() {
1323
        $fileInfo = pathinfo($_SERVER['PHP_SELF']);
1324
1325
        return substr($fileInfo['basename'], 0, -(strlen($fileInfo['extension']) + 1)) . '.mbox';
1326
    }
1327
}
1328
1329
/**
1330
 * OPMLCreator is a FeedCreator that implements OPML 1.0.
1331
 *
1332
 * @see    http://opml.scripting.com/spec
1333
 * @author Dirk Clemens, Kai Blankenhorn
1334
 * @since  1.5
1335
 */
1336
class OPMLCreator extends FeedCreator
1337
{
1338
    /**
1339
     * OPMLCreator constructor.
1340
     */
1341
    public function __construct() {
1342
        $this->encoding = 'utf-8';
1343
    }
1344
1345
    /**
1346
     * @return string
1347
     */
1348
    public function createFeed() {
1349
        $feed = "<?xml version=\"1.0\" encoding=\"" . $this->encoding . "\"?>\n";
1350
        $feed .= $this->_createGeneratorComment();
1351
        $feed .= $this->_createStylesheetReferences();
1352
        $feed .= "<opml xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
1353
        $feed .= "    <head>\n";
1354
        $feed .= '        <title>' . htmlspecialchars($this->title) . "</title>\n";
1355
        if ($this->pubDate != '') {
1356
            $date = new FeedDate($this->pubDate);
1357
            $feed .= '         <dateCreated>' . $date->rfc822() . "</dateCreated>\n";
1358
        }
1359
        if ($this->lastBuildDate != '') {
1360
            $date = new FeedDate($this->lastBuildDate);
1361
            $feed .= '         <dateModified>' . $date->rfc822() . "</dateModified>\n";
1362
        }
1363
        if ($this->editor != '') {
1364
            $feed .= '         <ownerName>' . $this->editor . "</ownerName>\n";
1365
        }
1366
        if ($this->editorEmail != '') {
1367
            $feed .= '         <ownerEmail>' . $this->editorEmail . "</ownerEmail>\n";
1368
        }
1369
        $feed .= "    </head>\n";
1370
        $feed .= "    <body>\n";
1371
        for ($i = 0, $iMax = count($this->items); $i < $iMax; ++$i) {
1372
            $feed .= "    <outline type=\"rss\" ";
1373
            $title = htmlspecialchars(strip_tags(strtr($this->items[$i]->title, "\n\r", '  ')));
1374
            $feed .= " title=\"" . $title . "\"";
1375
            $feed .= " text=\"" . $title . "\"";
1376
            //$feed.= " description=\"".htmlspecialchars($this->items[$i]->description)."\"";
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1377
            $feed .= " url=\"" . htmlspecialchars($this->items[$i]->link) . "\"";
1378
            $feed .= "/>\n";
1379
        }
1380
        $feed .= "    </body>\n";
1381
        $feed .= "</opml>\n";
1382
1383
        return $feed;
1384
    }
1385
}
1386
1387
/**
1388
 * HTMLCreator is a FeedCreator that writes an HTML feed file to a specific
1389
 * location, overriding the createFeed method of the parent FeedCreator.
1390
 * The HTML produced can be included over http by scripting languages, or serve
1391
 * as the source for an IFrame.
1392
 * All output by this class is embedded in <div></div> tags to enable formatting
1393
 * using CSS.
1394
 *
1395
 * @author Pascal Van Hecke
1396
 * @since  1.7
1397
 */
1398
class HTMLCreator extends FeedCreator
1399
{
1400
    public $contentType = 'text/html';
1401
1402
    /**
1403
     * Contains HTML to be output at the start of the feed's html representation.
1404
     */
1405
    public $header;
1406
1407
    /**
1408
     * Contains HTML to be output at the end of the feed's html representation.
1409
     */
1410
    public $footer;
1411
1412
    /**
1413
     * Contains HTML to be output between entries. A separator is only used in
1414
     * case of multiple entries.
1415
     */
1416
    public $separator;
1417
1418
    /**
1419
     * Used to prefix the stylenames to make sure they are unique
1420
     * and do not clash with stylenames on the users' page.
1421
     */
1422
    public $stylePrefix;
1423
1424
    /**
1425
     * Determines whether the links open in a new window or not.
1426
     */
1427
    public $openInNewWindow = true;
1428
1429
    public $imageAlign = 'right';
1430
1431
    /**
1432
     * In case of very simple output you may want to get rid of the style tags,
1433
     * hence this variable.  There's no equivalent on item level, but of course you can
1434
     * add strings to it while iterating over the items ($this->stylelessOutput .= ...)
1435
     * and when it is non-empty, ONLY the styleless output is printed, the rest is ignored
1436
     * in the function createFeed().
1437
     */
1438
    public $stylelessOutput = '';
1439
1440
    /**
1441
     * Writes the HTML.
1442
     * @return string the scripts's complete text
1443
     */
1444
    public function createFeed() {
1445
        // if there is styleless output, use the content of this variable and ignore the rest
1446
        if ($this->stylelessOutput != '') {
1447
            return $this->stylelessOutput;
1448
        }
1449
1450
        //if no stylePrefix is set, generate it yourself depending on the script name
1451
        if ($this->stylePrefix == '') {
1452
            $this->stylePrefix = str_replace('.', '_', $this->_generateFilename()) . '_';
1453
        }
1454
1455
        //set an openInNewWindow_token_to be inserted or not
1456
        if ($this->openInNewWindow) {
1457
            $targetInsert = " target='_blank'";
1458
        }
1459
1460
        // use this array to put the lines in and implode later with "document.write" javascript
1461
        $feedArray = array();
1462
        if ($this->image != null) {
1463
            $imageStr = "<a href='" . $this->image->link . "'" . $targetInsert . '>' . "<img src='" . $this->image->url
0 ignored issues
show
Bug introduced by
The variable $targetInsert 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...
1464
                        . "' border='0' alt='" . FeedCreator::iTrunc(htmlspecialchars($this->image->title), 100)
1465
                        . "' align='" . $this->imageAlign . "' ";
1466
            if ($this->image->width) {
1467
                $imageStr .= " width='" . $this->image->width . "' ";
1468
            }
1469
            if ($this->image->height) {
1470
                $imageStr .= " height='" . $this->image->height . "' ";
1471
            }
1472
            $imageStr .= '/></a>';
1473
            $feedArray[] = $imageStr;
1474
        }
1475
1476
        if ($this->title) {
1477
            $feedArray[] = "<div class='" . $this->stylePrefix . "title'><a href='" . $this->link . "' " . $targetInsert
1478
                           . " class='" . $this->stylePrefix . "title'>"
1479
                           . FeedCreator::iTrunc(htmlspecialchars($this->title), 100) . '</a></div>';
1480
        }
1481
        if ($this->getDescription()) {
1482
            $feedArray[] = "<div class='" . $this->stylePrefix . "description'>" . str_replace(']]>', '',
1483
                                                                                               str_replace('<![CDATA[',
1484
                                                                                                           '',
1485
                                                                                                           $this->getDescription()))
1486
                           . '</div>';
1487
        }
1488
1489
        if ($this->header) {
1490
            $feedArray[] = "<div class='" . $this->stylePrefix . "header'>" . $this->header . '</div>';
1491
        }
1492
1493
        for ($i = 0, $iMax = count($this->items); $i < $iMax; ++$i) {
1494
            if ($this->separator && $i > 0) {
1495
                $feedArray[] = "<div class='" . $this->stylePrefix . "separator'>" . $this->separator . '</div>';
1496
            }
1497
1498
            if ($this->items[$i]->title) {
1499
                if ($this->items[$i]->link) {
1500
                    $feedArray[] = "<div class='" . $this->stylePrefix . "item_title'><a href='"
1501
                                   . $this->items[$i]->link . "' class='" . $this->stylePrefix . "item_title'"
1502
                                   . $targetInsert . '>'
1503
                                   . FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100)
1504
                                   . '</a></div>';
1505
                } else {
1506
                    $feedArray[] = "<div class='" . $this->stylePrefix . "item_title'>"
1507
                                   . FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100)
1508
                                   . '</div>';
1509
                }
1510
            }
1511
            if ($this->items[$i]->getDescription()) {
1512
                $feedArray[] = "<div class='" . $this->stylePrefix . "item_description'>" . str_replace(']]>', '',
1513
                                                                                                        str_replace('<![CDATA[',
1514
                                                                                                                    '',
1515
                                                                                                                    $this->items[$i]->getDescription()))
1516
                               . '</div>';
1517
            }
1518
        }
1519
        if ($this->footer) {
1520
            $feedArray[] = "<div class='" . $this->stylePrefix . "footer'>" . $this->footer . '</div>';
1521
        }
1522
1523
        $feed = '' . implode($feedArray, "\r\n");
1524
1525
        return $feed;
1526
    }
1527
1528
    /**
1529
     * Overrrides parent to produce .html extensions
1530
     *
1531
     * @return string the feed cache filename
1532
     * @since  1.4
1533
     * @access private
1534
     */
1535
    public function _generateFilename() {
1536
        $fileInfo = pathinfo($_SERVER['PHP_SELF']);
1537
1538
        return substr($fileInfo['basename'], 0, -(strlen($fileInfo['extension']) + 1)) . '.html';
1539
    }
1540
}
1541
1542
/**
1543
 * JSCreator is a class that writes a js file to a specific
1544
 * location, overriding the createFeed method of the parent HTMLCreator.
1545
 *
1546
 * @author Pascal Van Hecke
1547
 */
1548
class JSCreator extends HTMLCreator
1549
{
1550
    public $contentType = 'text/javascript';
1551
1552
    /**
1553
     * writes the javascript
1554
     * @return string the scripts's complete text
1555
     */
1556
    public function createFeed() {
1557
        $feed      = parent::createFeed();
1558
        $feedArray = explode("\n", $feed);
1559
1560
        $jsFeed = '';
1561
        foreach ($feedArray as $value) {
1562
            $jsFeed .= "document.write('" . trim(addslashes($value)) . "');\n";
1563
        }
1564
1565
        return $jsFeed;
1566
    }
1567
1568
    /**
1569
     * Overrrides parent to produce .js extensions
1570
     *
1571
     * @return string the feed cache filename
1572
     * @since  1.4
1573
     * @access private
1574
     */
1575
    public function _generateFilename() {
1576
        $fileInfo = pathinfo($_SERVER['PHP_SELF']);
1577
1578
        return substr($fileInfo['basename'], 0, -(strlen($fileInfo['extension']) + 1)) . '.js';
1579
    }
1580
}
1581
1582
/*** TEST SCRIPT *********************************************************
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1583
 *
1584
 * //include("feedcreator.class.php");
1585
 *
1586
 * $rss = new UniversalFeedCreator();
1587
 * $rss->useCached();
1588
 * $rss->title = "PHP news";
1589
 * $rss->description = "daily news from the PHP scripting world";
1590
 *
1591
 * //optional
1592
 * //$rss->descriptionTruncSize = 500;
1593
 * //$rss->descriptionHtmlSyndicated = true;
1594
 * //$rss->xslStyleSheet = "http://feedster.com/rss20.xsl";
1595
 *
1596
 * $rss->link = "http://www.dailyphp.net/news";
1597
 * $rss->feedURL = "http://www.dailyphp.net/".$PHP_SELF;
1598
 *
1599
 * $image = new FeedImage();
1600
 * $image->title = "dailyphp.net logo";
1601
 * $image->url = "http://www.dailyphp.net/images/logo.gif";
1602
 * $image->link = "http://www.dailyphp.net";
1603
 * $image->description = "Feed provided by dailyphp.net. Click to visit.";
1604
 *
1605
 * //optional
1606
 * $image->descriptionTruncSize = 500;
1607
 * $image->descriptionHtmlSyndicated = true;
1608
 *
1609
 * $rss->image = $image;
1610
 *
1611
 * // get your news items from somewhere, e.g. your database:
1612
 * //mysqli_select_db($dbHost, $dbUser, $dbPass);
1613
 * //$res = mysqli_query("SELECT * FROM news ORDER BY newsdate DESC");
1614
 * //while ($data = mysqli_fetch_object($res)) {
1615
 * $item = new FeedItem();
1616
 * $item->title = "This is an the test title of an item";
1617
 * $item->link = "http://localhost/item/";
1618
 * $item->description = "<b>description in </b><br>HTML";
1619
 *
1620
 * //optional
1621
 * //item->descriptionTruncSize = 500;
1622
 * $item->descriptionHtmlSyndicated = true;
1623
 *
1624
 * $item->date = time();
1625
 * $item->source = "http://www.dailyphp.net";
1626
 * $item->author = "John Doe";
1627
 *
1628
 * $rss->addItem($item);
1629
 * //}
1630
 *
1631
 * // valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1, MBOX, OPML, ATOM0.3, HTML, JS
1632
 * echo $rss->saveFeed("RSS0.91", "feed.xml");
1633
 ***************************************************************************/
1634