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