Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ChannelFeed
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 4
42
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 outHeader
n/a
0 / 0
n/a
0 / 0
0
 outItem
n/a
0 / 0
n/a
0 / 0
0
 outFooter
n/a
0 / 0
n/a
0 / 0
0
 httpHeaders
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 contentType
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
6
 outXmlHeader
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3/**
4 * Copyright © 2004 Brooke Vibber <bvibber@wikimedia.org>
5 * https://www.mediawiki.org/
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * http://www.gnu.org/copyleft/gpl.html
21 *
22 * @file
23 */
24
25namespace MediaWiki\Feed;
26
27use MediaWiki\Html\TemplateParser;
28use MediaWiki\MainConfigNames;
29use MediaWiki\MediaWikiServices;
30
31/**
32 * Class to support the outputting of syndication feeds in Atom and RSS format.
33 *
34 * @stable to extend
35 * @ingroup Feed
36 */
37abstract class ChannelFeed extends FeedItem {
38
39    /** @var TemplateParser */
40    protected $templateParser;
41
42    /**
43     * @stable to call
44     *
45     * @param string $title Feed's title
46     * @param string $description
47     * @param string $url URL uniquely designating the feed.
48     * @param string $date Feed's date
49     * @param string $author Author's user name
50     * @param string $comments
51     *
52     */
53    public function __construct(
54        $title, $description, $url, $date = '', $author = '', $comments = ''
55    ) {
56        parent::__construct( $title, $description, $url, $date, $author, $comments );
57        $this->templateParser = new TemplateParser();
58    }
59
60    /**
61     * Generate Header of the feed
62     * @par Example:
63     * @code
64     * print "<feed>";
65     * @endcode
66     */
67    abstract public function outHeader();
68
69    /**
70     * Generate an item
71     * @par Example:
72     * @code
73     * print "<item>...</item>";
74     * @endcode
75     * @param FeedItem $item
76     */
77    abstract public function outItem( $item );
78
79    /**
80     * Generate Footer of the feed
81     * @par Example:
82     * @code
83     * print "</feed>";
84     * @endcode
85     */
86    abstract public function outFooter();
87
88    /**
89     * Setup and send HTTP headers. Don't send any content;
90     * content might end up being cached and re-sent with
91     * these same headers later.
92     *
93     * This should be called from the outHeader() method,
94     * but can also be called separately.
95     */
96    public function httpHeaders() {
97        global $wgOut;
98        $varyOnXFP = MediaWikiServices::getInstance()->getMainConfig()
99            ->get( MainConfigNames::VaryOnXFP );
100        # We take over from $wgOut, excepting its cache header info
101        $wgOut->disable();
102        $mimetype = $this->contentType();
103        header( "Content-type: $mimetype; charset=UTF-8" );
104
105        // Set a sensible filename
106        $mimeAnalyzer = MediaWikiServices::getInstance()->getMimeAnalyzer();
107        $ext = $mimeAnalyzer->getExtensionFromMimeTypeOrNull( $mimetype ) ?? 'xml';
108        header( "Content-Disposition: inline; filename=\"feed.{$ext}\"" );
109
110        if ( $varyOnXFP ) {
111            $wgOut->addVaryHeader( 'X-Forwarded-Proto' );
112        }
113        $wgOut->sendCacheControl();
114    }
115
116    /**
117     * Return an internet media type to be sent in the headers.
118     *
119     * @stable to override
120     *
121     * @return string
122     */
123    private function contentType() {
124        global $wgRequest;
125
126        $ctype = $wgRequest->getVal( 'ctype', 'application/xml' );
127        $allowedctypes = [
128            'application/xml',
129            'text/xml',
130            'application/rss+xml',
131            'application/atom+xml'
132        ];
133
134        return ( in_array( $ctype, $allowedctypes ) ? $ctype : 'application/xml' );
135    }
136
137    /**
138     * Output the initial XML headers.
139     */
140    protected function outXmlHeader() {
141        $this->httpHeaders();
142        echo '<?xml version="1.0"?>' . "\n";
143    }
144}
145
146/** @deprecated class alias since 1.40 */
147class_alias( ChannelFeed::class, 'ChannelFeed' );