/** */ function wfStreamFile($fname) { $stat = @stat($fname); if (!$stat) { header('HTTP/1.0 404 Not Found'); header('Cache-Control: no-cache'); header('Content-Type: text/html; charset=utf-8'); $encFile = htmlspecialchars($fname); $encScript = htmlspecialchars($_SERVER['SCRIPT_NAME']); echo "<html><body>\n<h1>File not found</h1>\n<p>Although this PHP script ({$encScript}) exists, the file requested for output \n({$encFile}) does not.</p>\n</body></html>\n"; return; } header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $stat['mtime']) . ' GMT'); // Cancel output buffering and gzipping if set wfResetOutputBuffers(); $type = wfGetType($fname); if ($type and $type != "unknown/unknown") { header("Content-type: {$type}"); } else { header('Content-type: application/x-wiki'); } if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $modsince = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']); $sinceTime = strtotime($modsince); if ($stat['mtime'] <= $sinceTime) { header("HTTP/1.0 304 Not Modified"); return; } } header('Content-Length: ' . $stat['size']); readfile($fname); }
function csvOutput($res) { global $wgOut, $wgRequest; $ts = wfTimestampNow(); $filename = "community_applications_{$ts}.csv"; $wgOut->disable(); wfResetOutputBuffers(); $wgRequest->response()->header("Content-disposition: attachment;filename={$filename}"); $wgRequest->response()->header("Content-type: text/csv; charset=utf-8"); $fh = fopen('php://output', 'w'); $fields = null; foreach ($res as $row) { $data = FormatJson::decode($row->ch_data, true); $data = array('id' => $row->ch_id) + $data; if (!is_array($fields)) { $fields = array_keys($data); fputcsv($fh, $fields); } $outData = array(); foreach ($fields as $k) { $outData[] = isset($data[$k]) ? $data[$k] : null; unset($data[$k]); } foreach ($data as $k => $v) { $outData[] = "{$k}: {$v}"; } fputcsv($fh, $outData); } fclose($fh); }
function streamAppleTouch() { global $wgAppleTouchIcon; wfResetOutputBuffers(); if ($wgAppleTouchIcon === false) { # That's not very helpful, that's where we are already header('HTTP/1.1 404 Not Found'); faviconShowError('$wgAppleTouchIcon is configured incorrectly, ' . 'it must be set to something other than false \\n'); return; } $req = RequestContext::getMain()->getRequest(); if ($req->getHeader('X-Favicon-Loop') !== false) { header('HTTP/1.1 500 Internal Server Error'); faviconShowError('Proxy forwarding loop detected'); return; } $url = wfExpandUrl($wgAppleTouchIcon, PROTO_CANONICAL); $client = MWHttpRequest::factory($url); $client->setHeader('X-Favicon-Loop', '1'); $status = $client->execute(); if (!$status->isOK()) { header('HTTP/1.1 500 Internal Server Error'); faviconShowError("Failed to fetch URL \"{$url}\""); return; } $content = $client->getContent(); header('Content-Length: ' . strlen($content)); header('Content-Type: ' . $client->getResponseHeader('Content-Type')); header('Cache-Control: public'); header('Expires: ' . gmdate('r', time() + 86400)); echo $content; }
function execute($par) { global $wgMemc; $tempToken = $this->getRequest()->getVal('token'); $logout = $this->getRequest()->getBool('logout'); # Don't cache error messages $this->getOutput()->enableClientCache(false); if (strlen($tempToken) == 0) { $this->setHeaders(); $this->getOutput()->addWikiMsg('centralauth-autologin-desc'); return; } $key = CentralAuthUser::memcKey('login-token', $tempToken); $data = $wgMemc->get($key); $wgMemc->delete($key); if (!$data) { $msg = 'Token is invalid or has expired'; wfDebug(__METHOD__ . ": {$msg}\n"); $this->setHeaders(); $this->getOutput()->addWikiText($msg); return; } $userName = $data['userName']; $token = $data['token']; $remember = $data['remember']; if ($data['wiki'] != wfWikiID()) { $msg = 'Bad token (wrong wiki)'; wfDebug(__METHOD__ . ": {$msg}\n"); $this->setHeaders(); $this->getOutput()->addWikiText($msg); return; } $centralUser = new CentralAuthUser($userName); $loginResult = $centralUser->authenticateWithToken($token); if ($loginResult != 'ok') { $msg = "Bad token: {$loginResult}"; wfDebug(__METHOD__ . ": {$msg}\n"); $this->setHeaders(); $this->getOutput()->addWikiText($msg); return; } // Auth OK. if ($logout) { $centralUser->deleteGlobalCookies(); } else { $centralUser->setGlobalCookies($remember); } $this->getOutput()->disable(); wfResetOutputBuffers(); header('Cache-Control: no-cache'); header('Content-Type: image/png'); global $wgCentralAuthLoginIcon; if ($wgCentralAuthLoginIcon) { readfile($wgCentralAuthLoginIcon); } else { readfile(dirname(__FILE__) . '/1x1.png'); } }
function execute($par) { global $wgOut; $this->setHideCookie(); $wgOut->disable(); wfResetOutputBuffers(); header('Content-Type: image/png'); header('Cache-Control: no-cache'); readfile(dirname(__FILE__) . '/../1x1.png'); }
/** * getImage method * */ public function getImage() { wfProfileIn(__METHOD__); if ($this->wg->User->isLoggedIn()) { # make proper thumb path: c/central/images/thumb/.... $path = sprintf("%s/%s/images", substr($this->wg->DBname, 0, 1), $this->wg->DBname); # take thumb request from request $img = $this->getVal('image'); if (preg_match('/^(\\/?)thumb\\//', $img)) { # build proper thumb url for thumbnailer $thumb_url = sprintf("%s/%s/%s", $this->wg->ThumbnailerService, $path, $img); # call thumbnailer $options = array('method' => 'GET', 'timeout' => 'default', 'noProxy' => 1); $thumb_request = MWHttpRequest::factory($thumb_url, $options); $status = $thumb_request->execute(); $headers = $thumb_request->getResponseHeaders(); if ($status->isOK()) { if (!empty($headers)) { foreach ($headers as $header_name => $header_value) { if (is_array($header_value)) { list($value) = $header_value; } else { $value = $header_value; } header(sprintf("%s: %s", $header_name, $value)); } } echo $thumb_request->getContent(); } else { wfdebug("Cannot generate auth thumb"); $this->_access_forbidden('img-auth-accessdenied', 'img-auth-nofile', $img); } } else { # serve original image $filename = realpath(sprintf("%s/%s", $this->wg->UploadDirectory, $img)); $stat = @stat($filename); if ($stat) { wfResetOutputBuffers(); $fileinfo = finfo_open(FILEINFO_MIME_TYPE); $imageType = finfo_file($fileinfo, $filename); header(sprintf("Content-Disposition: inline;filename*=utf-8'%s'%s", $this->wg->ContLanguageCode, urlencode(basename($filename)))); header(sprintf("Content-Type: %s", $imageType)); header(sprintf("Content-Length: %d" . $stat['size'])); readfile($filename); } else { $this->_access_forbidden('img-auth-accessdenied', 'img-auth-nopathinfo', $img); } } } else { $this->_access_forbidden('img-auth-accessdenied', 'img-auth-public', ''); } wfProfileOut(__METHOD__); exit; }
/** * Call this function used in preparation before streaming a file. * This function does the following: * (a) sends Last-Modified, Content-type, and Content-Disposition headers * (b) cancels any PHP output buffering and automatic gzipping of output * (c) sends Content-Length header based on HTTP_IF_MODIFIED_SINCE check * * @param $path string Storage path or file system path * @param $info Array|false File stat info with 'mtime' and 'size' fields * @param $headers Array Additional headers to send * @param $sendErrors bool Send error messages if errors occur (like 404) * @return int|false READY_STREAM, NOT_MODIFIED, or false on failure */ public static function prepareForStream($path, $info, $headers = array(), $sendErrors = true) { global $wgLanguageCode; if (!is_array($info)) { if ($sendErrors) { header('HTTP/1.0 404 Not Found'); header('Cache-Control: no-cache'); header('Content-Type: text/html; charset=utf-8'); $encFile = htmlspecialchars($path); $encScript = htmlspecialchars($_SERVER['SCRIPT_NAME']); echo "<html><body>\n\t\t\t\t\t<h1>File not found</h1>\n\t\t\t\t\t<p>Although this PHP script ({$encScript}) exists, the file requested for output\n\t\t\t\t\t({$encFile}) does not.</p>\n\t\t\t\t\t</body></html>\n\t\t\t\t\t"; } return false; } // Sent Last-Modified HTTP header for client-side caching header('Last-Modified: ' . wfTimestamp(TS_RFC2822, $info['mtime'])); // Cancel output buffering and gzipping if set wfResetOutputBuffers(); $type = self::contentTypeFromPath($path); if ($type && $type != 'unknown/unknown') { header("Content-type: {$type}"); } else { // Send a content type which is not known to Internet Explorer, to // avoid triggering IE's content type detection. Sending a standard // unknown content type here essentially gives IE license to apply // whatever content type it likes. header('Content-type: application/x-wiki'); } // Don't stream it out as text/html if there was a PHP error if (headers_sent()) { echo "Headers already sent, terminating.\n"; return false; } header("Content-Disposition: inline;filename*=utf-8'{$wgLanguageCode}'" . urlencode(basename($path))); // Send additional headers foreach ($headers as $header) { header($header); } // Don't send if client has up to date cache if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $modsince = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']); if (wfTimestamp(TS_UNIX, $info['mtime']) <= strtotime($modsince)) { ini_set('zlib.output_compression', 0); header("HTTP/1.0 304 Not Modified"); return self::NOT_MODIFIED; // ok } } header('Content-Length: ' . $info['size']); return self::READY_STREAM; // ok }
function wfProtectAdminNamespace(Parser $parser) { global $wgTitle, $wgUser, $wgOut, $mediaWiki; if (is_object($wgTitle) && $wgTitle->getNamespace() == NS_ADMIN && !in_array('bureaucrat', $wgUser->getEffectiveGroups())) { if (is_object($mediaWiki)) { $mediaWiki->restInPeace(); } $wgOut->disable(); wfResetOutputBuffers(); header("Location: http://wiki.ligmincha.org/"); } return true; }
public function setup() { global $wgOut, $wgResourceModules, $wgAutoloadClasses, $wgExtensionAssetsPath, $IP, $wgUser, $wgAjaxCommentsPollServer, $wgAjaxCommentsLikeDislike, $wgAjaxCommentsCopyTalkpages, $wgAjaxCommentsAdmins; // Determine if the current user is an admin for comments self::$admin = count(array_intersect($wgAjaxCommentsAdmins, $wgUser->getEffectiveGroups())) > 0; // If options set, hook into the new revisions to change talk page additions to ajaxcomments if ($wgAjaxCommentsCopyTalkpages) { Hooks::register('PageContentSave', $this); } // Create a hook to allow external condition for whether there should be comments shown $title = array_key_exists('title', $_GET) ? Title::newFromText($_GET['title']) : false; if (!array_key_exists('action', $_REQUEST) && self::checkTitle($title)) { Hooks::register('BeforePageDisplay', $this); } else { $wgAjaxCommentsPollServer = -1; } // Create a hook to allow external condition for whether comments can be added or replied to (default is just user logged in) $this->canComment = $wgUser->isLoggedIn(); Hooks::run('AjaxCommentsCheckWritable', array($title, &$this->canComment)); // Redirect talk pages with AjaxComments to the comments if (is_object($title) && $title->getNamespace() > 0 && $title->getNamespace() & 1) { $ret = true; Hooks::run('AjaxCommentsCheckTitle', array($userpage, &$ret)); if ($ret) { $userpage = Title::newFromText($title->getText(), $title->getNamespace() - 1); global $mediaWiki; if (is_object($mediaWiki)) { $mediaWiki->restInPeace(); } $wgOut->disable(); wfResetOutputBuffers(); $url = $userpage->getLocalUrl(); header("Location: {$url}#ajaxcomments"); wfDebugLog(__CLASS__, "Redirecting to {$url}"); exit; } } // This gets the remote path even if it's a symlink (MW1.25+) $path = $wgExtensionAssetsPath . str_replace("{$IP}/extensions", '', dirname($wgAutoloadClasses[__CLASS__])); $wgResourceModules['ext.ajaxcomments']['remoteExtPath'] = $path; $wgOut->addModules('ext.ajaxcomments'); $wgOut->addStyle("{$path}/styles/ajaxcomments.css"); // Add config vars to client side $wgOut->addJsConfigVars('ajaxCommentsPollServer', $wgAjaxCommentsPollServer); $wgOut->addJsConfigVars('ajaxCommentsCanComment', $this->canComment); $wgOut->addJsConfigVars('ajaxCommentsLikeDislike', $wgAjaxCommentsLikeDislike); $wgOut->addJsConfigVars('ajaxCommentsAdmin', self::$admin); }
/** * @param $fname string * @param $headers array */ function wfStreamFile($fname, $headers = array()) { wfSuppressWarnings(); $stat = stat($fname); wfRestoreWarnings(); if (!$stat) { header('HTTP/1.0 404 Not Found'); header('Cache-Control: no-cache'); header('Content-Type: text/html; charset=utf-8'); $encFile = htmlspecialchars($fname); $encScript = htmlspecialchars($_SERVER['SCRIPT_NAME']); echo "<html><body>\n<h1>File not found</h1>\n<p>Although this PHP script ({$encScript}) exists, the file requested for output\n({$encFile}) does not.</p>\n</body></html>\n"; return; } header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $stat['mtime']) . ' GMT'); // Cancel output buffering and gzipping if set wfResetOutputBuffers(); $type = wfGetType($fname); if ($type and $type != "unknown/unknown") { header("Content-type: {$type}"); } else { header('Content-type: application/x-wiki'); } // Don't stream it out as text/html if there was a PHP error if (headers_sent()) { echo "Headers already sent, terminating.\n"; return; } global $wgLanguageCode; header("Content-Disposition: inline;filename*=utf-8'{$wgLanguageCode}'" . urlencode(basename($fname))); foreach ($headers as $header) { header($header); } if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $modsince = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']); $sinceTime = strtotime($modsince); if ($stat['mtime'] <= $sinceTime) { ini_set('zlib.output_compression', 0); header("HTTP/1.0 304 Not Modified"); return; } } header('Content-Length: ' . $stat['size']); readfile($fname); }
/** */ function wfStreamFile($fname, $headers = array()) { $stat = @stat($fname); if (!$stat) { header('HTTP/1.0 404 Not Found'); header('Cache-Control: no-cache'); header('Content-Type: text/html; charset=utf-8'); $encFile = htmlspecialchars($fname); $encScript = htmlspecialchars($_SERVER['SCRIPT_NAME']); echo "<html><body>\n<h1>File not found</h1>\n<p>Although this PHP script ({$encScript}) exists, the file requested for output \n({$encFile}) does not.</p>\n</body></html>\n"; return; } header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $stat['mtime']) . ' GMT'); // Cancel output buffering and gzipping if set wfResetOutputBuffers(); $type = wfGetType($fname); if ($type and $type != "unknown/unknown") { header("Content-type: {$type}"); } else { header('Content-type: application/x-wiki'); } global $wgContLanguageCode; header("Content-Disposition: inline;filename*=utf-8'{$wgContLanguageCode}'" . urlencode(basename($fname))); foreach ($headers as $header) { header($header); } if (!empty($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $modsince = preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']); $sinceTime = strtotime($modsince); if ($stat['mtime'] <= $sinceTime) { header("HTTP/1.0 304 Not Modified"); return; } } $h = ""; foreach ($stat as $k => $v) { $h .= "{$k}={$v},"; } header('Content-Length: ' . $stat['size']); header('X-stat-results: ' . $h); header('X-Serving-host: ' . wfHostname()); header('Content-Length-true: ' . $stat['size']); readfile($fname); }
/** * */ function wfSpecialExport($page = '') { global $wgOut, $wgRequest, $wgSitename, $wgExportAllowListContributors; global $wgExportAllowHistory, $wgExportMaxHistory; $curonly = true; $doexport = false; if ($wgRequest->getCheck('addcat')) { $page = $wgRequest->getText('pages'); $catname = $wgRequest->getText('catname'); if ($catname !== '' && $catname !== NULL && $catname !== false) { $t = Title::makeTitleSafe(NS_MAIN, $catname); if ($t) { /** * @fixme This can lead to hitting memory limit for very large * categories. Ideally we would do the lookup synchronously * during the export in a single query. */ $catpages = wfExportGetPagesFromCategory($t); if ($catpages) { $page .= "\n" . implode("\n", $catpages); } } } } else { if ($wgRequest->wasPosted() && $page == '') { $page = $wgRequest->getText('pages'); $curonly = $wgRequest->getCheck('curonly'); $rawOffset = $wgRequest->getVal('offset'); if ($rawOffset) { $offset = wfTimestamp(TS_MW, $rawOffset); } else { $offset = null; } $limit = $wgRequest->getInt('limit'); $dir = $wgRequest->getVal('dir'); $history = array('dir' => 'asc', 'offset' => false, 'limit' => $wgExportMaxHistory); $historyCheck = $wgRequest->getCheck('history'); if ($curonly) { $history = WikiExporter::CURRENT; } elseif (!$historyCheck) { if ($limit > 0 && $limit < $wgExportMaxHistory) { $history['limit'] = $limit; } if (!is_null($offset)) { $history['offset'] = $offset; } if (strtolower($dir) == 'desc') { $history['dir'] = 'desc'; } } if ($page != '') { $doexport = true; } } else { // Default to current-only for GET requests $page = $wgRequest->getText('pages', $page); $historyCheck = $wgRequest->getCheck('history'); if ($historyCheck) { $history = WikiExporter::FULL; } else { $history = WikiExporter::CURRENT; } if ($page != '') { $doexport = true; } } } if (!$wgExportAllowHistory) { // Override $history = WikiExporter::CURRENT; } $list_authors = $wgRequest->getCheck('listauthors'); if (!$curonly || !$wgExportAllowListContributors) { $list_authors = false; } if ($doexport) { $wgOut->disable(); // Cancel output buffering and gzipping if set // This should provide safer streaming for pages with history wfResetOutputBuffers(); header("Content-type: application/xml; charset=utf-8"); if ($wgRequest->getCheck('wpDownload')) { // Provide a sane filename suggestion $filename = urlencode($wgSitename . '-' . wfTimestampNow() . '.xml'); $wgRequest->response()->header("Content-disposition: attachment;filename={$filename}"); } /* Split up the input and look up linked pages */ $inputPages = array_filter(explode("\n", $page), 'wfFilterPage'); $pageSet = array_flip($inputPages); if ($wgRequest->getCheck('templates')) { $pageSet = wfExportGetTemplates($inputPages, $pageSet); } /* // Enable this when we can do something useful exporting/importing image information. :) if( $wgRequest->getCheck( 'images' ) ) { $pageSet = wfExportGetImages( $inputPages, $pageSet ); } */ $pages = array_keys($pageSet); /* Ok, let's get to it... */ if ($history == WikiExporter::CURRENT) { $lb = false; $db = wfGetDB(DB_SLAVE); $buffer = WikiExporter::BUFFER; } else { // Use an unbuffered query; histories may be very long! $lb = wfGetLBFactory()->newMainLB(); $db = $lb->getConnection(DB_SLAVE); $buffer = WikiExporter::STREAM; // This might take a while... :D wfSuppressWarnings(); set_time_limit(0); wfRestoreWarnings(); } $exporter = new WikiExporter($db, $history, $buffer); $exporter->list_authors = $list_authors; $exporter->openStream(); foreach ($pages as $page) { /* if( $wgExportMaxHistory && !$curonly ) { $title = Title::newFromText( $page ); if( $title ) { $count = Revision::countByTitle( $db, $title ); if( $count > $wgExportMaxHistory ) { wfDebug( __FUNCTION__ . ": Skipped $page, $count revisions too big\n" ); continue; } } }*/ #Bug 8824: Only export pages the user can read $title = Title::newFromText($page); if (is_null($title)) { continue; } #TODO: perhaps output an <error> tag or something. if (!$title->userCanRead()) { continue; } #TODO: perhaps output an <error> tag or something. $exporter->pageByTitle($title); } $exporter->closeStream(); if ($lb) { $lb->closeAll(); } return; } $self = SpecialPage::getTitleFor('Export'); $wgOut->addHTML(wfMsgExt('exporttext', 'parse')); $form = Xml::openElement('form', array('method' => 'post', 'action' => $self->getLocalUrl('action=submit'))); $form .= Xml::inputLabel(wfMsg('export-addcattext'), 'catname', 'catname', 40) . ' '; $form .= Xml::submitButton(wfMsg('export-addcat'), array('name' => 'addcat')) . '<br />'; $form .= Xml::openElement('textarea', array('name' => 'pages', 'cols' => 40, 'rows' => 10)); $form .= htmlspecialchars($page); $form .= Xml::closeElement('textarea'); $form .= '<br />'; if ($wgExportAllowHistory) { $form .= Xml::checkLabel(wfMsg('exportcuronly'), 'curonly', 'curonly', true) . '<br />'; } else { $wgOut->addHTML(wfMsgExt('exportnohistory', 'parse')); } $form .= Xml::checkLabel(wfMsg('export-templates'), 'templates', 'wpExportTemplates', false) . '<br />'; // Enable this when we can do something useful exporting/importing image information. :) //$form .= Xml::checkLabel( wfMsg( 'export-images' ), 'images', 'wpExportImages', false ) . '<br />'; $form .= Xml::checkLabel(wfMsg('export-download'), 'wpDownload', 'wpDownload', true) . '<br />'; $form .= Xml::submitButton(wfMsg('export-submit'), array('accesskey' => 's')); $form .= Xml::closeElement('form'); $wgOut->addHTML($form); }
public function execute($par) { global $wgSitename, $wgExportAllowListContributors, $wgExportFromNamespaces; global $wgExportAllowHistory, $wgExportMaxHistory, $wgExportMaxLinkDepth; global $wgExportAllowAll; $this->setHeaders(); $this->outputHeader(); // Set some variables $this->curonly = true; $this->doExport = false; $request = $this->getRequest(); $this->templates = $request->getCheck('templates'); $this->images = $request->getCheck('images'); // Doesn't do anything yet $this->pageLinkDepth = $this->validateLinkDepth($request->getIntOrNull('pagelink-depth')); $nsindex = ''; $exportall = false; if ($request->getCheck('addcat')) { $page = $request->getText('pages'); $catname = $request->getText('catname'); if ($catname !== '' && $catname !== null && $catname !== false) { $t = Title::makeTitleSafe(NS_MAIN, $catname); if ($t) { /** * @todo FIXME: This can lead to hitting memory limit for very large * categories. Ideally we would do the lookup synchronously * during the export in a single query. */ $catpages = $this->getPagesFromCategory($t); if ($catpages) { $page .= "\n" . implode("\n", $catpages); } } } } elseif ($request->getCheck('addns') && $wgExportFromNamespaces) { $page = $request->getText('pages'); $nsindex = $request->getText('nsindex', ''); if (strval($nsindex) !== '') { /** * Same implementation as above, so same @todo */ $nspages = $this->getPagesFromNamespace($nsindex); if ($nspages) { $page .= "\n" . implode("\n", $nspages); } } } elseif ($request->getCheck('exportall') && $wgExportAllowAll) { $this->doExport = true; $exportall = true; } elseif ($request->wasPosted() && $par == '') { $page = $request->getText('pages'); $this->curonly = $request->getCheck('curonly'); $rawOffset = $request->getVal('offset'); if ($rawOffset) { $offset = wfTimestamp(TS_MW, $rawOffset); } else { $offset = null; } $limit = $request->getInt('limit'); $dir = $request->getVal('dir'); $history = array('dir' => 'asc', 'offset' => false, 'limit' => $wgExportMaxHistory); $historyCheck = $request->getCheck('history'); if ($this->curonly) { $history = WikiExporter::CURRENT; } elseif (!$historyCheck) { if ($limit > 0 && ($wgExportMaxHistory == 0 || $limit < $wgExportMaxHistory)) { $history['limit'] = $limit; } if (!is_null($offset)) { $history['offset'] = $offset; } if (strtolower($dir) == 'desc') { $history['dir'] = 'desc'; } } if ($page != '') { $this->doExport = true; } } else { // Default to current-only for GET requests. $page = $request->getText('pages', $par); $historyCheck = $request->getCheck('history'); if ($historyCheck) { $history = WikiExporter::FULL; } else { $history = WikiExporter::CURRENT; } if ($page != '') { $this->doExport = true; } } if (!$wgExportAllowHistory) { // Override $history = WikiExporter::CURRENT; } $list_authors = $request->getCheck('listauthors'); if (!$this->curonly || !$wgExportAllowListContributors) { $list_authors = false; } if ($this->doExport) { $this->getOutput()->disable(); // Cancel output buffering and gzipping if set // This should provide safer streaming for pages with history wfResetOutputBuffers(); $request->response()->header("Content-type: application/xml; charset=utf-8"); if ($request->getCheck('wpDownload')) { // Provide a sane filename suggestion $filename = urlencode($wgSitename . '-' . wfTimestampNow() . '.xml'); $request->response()->header("Content-disposition: attachment;filename={$filename}"); } $this->doExport($page, $history, $list_authors, $exportall); return; } $out = $this->getOutput(); $out->addWikiMsg('exporttext'); $form = Xml::openElement('form', array('method' => 'post', 'action' => $this->getTitle()->getLocalUrl('action=submit'))); $form .= Xml::inputLabel(wfMsg('export-addcattext'), 'catname', 'catname', 40) . ' '; $form .= Xml::submitButton(wfMsg('export-addcat'), array('name' => 'addcat')) . '<br />'; if ($wgExportFromNamespaces) { $form .= Xml::namespaceSelector($nsindex, null, 'nsindex', wfMsg('export-addnstext')) . ' '; $form .= Xml::submitButton(wfMsg('export-addns'), array('name' => 'addns')) . '<br />'; } if ($wgExportAllowAll) { $form .= Xml::checkLabel(wfMsg('exportall'), 'exportall', 'exportall', $request->wasPosted() ? $request->getCheck('exportall') : false) . '<br />'; } $form .= Xml::element('textarea', array('name' => 'pages', 'cols' => 40, 'rows' => 10), $page, false); $form .= '<br />'; if ($wgExportAllowHistory) { $form .= Xml::checkLabel(wfMsg('exportcuronly'), 'curonly', 'curonly', $request->wasPosted() ? $request->getCheck('curonly') : true) . '<br />'; } else { $out->addHTML(wfMsgExt('exportnohistory', 'parse')); } $form .= Xml::checkLabel(wfMsg('export-templates'), 'templates', 'wpExportTemplates', $request->wasPosted() ? $request->getCheck('templates') : false) . '<br />'; if ($wgExportMaxLinkDepth || $this->userCanOverrideExportDepth()) { $form .= Xml::inputLabel(wfMsg('export-pagelinks'), 'pagelink-depth', 'pagelink-depth', 20, 0) . '<br />'; } // Enable this when we can do something useful exporting/importing image information. :) //$form .= Xml::checkLabel( wfMsg( 'export-images' ), 'images', 'wpExportImages', false ) . '<br />'; $form .= Xml::checkLabel(wfMsg('export-download'), 'wpDownload', 'wpDownload', $request->wasPosted() ? $request->getCheck('wpDownload') : true) . '<br />'; if ($wgExportAllowListContributors) { $form .= Xml::checkLabel(wfMsg('exportlistauthors'), 'listauthors', 'listauthors', $request->wasPosted() ? $request->getCheck('listauthors') : false) . '<br />'; } $form .= Xml::submitButton(wfMsg('export-submit'), Linker::tooltipAndAccesskeyAttribs('export')); $form .= Xml::closeElement('form'); $out->addHTML($form); }
static function doSpecialViewXML() { global $wgOut, $wgRequest, $wgUser, $wgContLang; $skin = $wgUser->getSkin(); $namespace_labels = $wgContLang->getNamespaces(); $category_label = $namespace_labels[NS_CATEGORY]; $template_label = $namespace_labels[NS_TEMPLATE]; $name_str = str_replace(' ', '_', wfMsgForContent('dt_xml_name')); $namespace_str = str_replace(' ', '_', wfMsg('dt_xml_namespace')); $pages_str = str_replace(' ', '_', wfMsgForContent('dt_xml_pages')); $form_submitted = false; $page_titles = array(); $cats = $wgRequest->getArray('categories'); $nses = $wgRequest->getArray('namespaces'); if (count($cats) > 0 || count($nses) > 0) { $form_submitted = true; } if ($form_submitted) { $wgOut->disable(); // Cancel output buffering and gzipping if set // This should provide safer streaming for pages with history wfResetOutputBuffers(); header("Content-type: application/xml; charset=utf-8"); $groupings = self::getGroupings(); $simplified_format = $wgRequest->getVal('simplified_format'); $text = "<{$pages_str}>"; if ($cats) { foreach ($cats as $cat => $val) { if ($simplified_format) { $text .= '<' . str_replace(' ', '_', $cat) . ">\n"; } else { $text .= "<{$category_label} {$name_str}=\"{$cat}\">\n"; } $titles = self::getPagesForCategory($cat, 10); foreach ($titles as $title) { $text .= self::getXMLForPage($title, $simplified_format, $groupings); } if ($simplified_format) { $text .= '</' . str_replace(' ', '_', $cat) . ">\n"; } else { $text .= "</{$category_label}>\n"; } } } if ($nses) { foreach ($nses as $ns => $val) { if ($ns == 0) { $ns_name = "Main"; } else { $ns_name = MWNamespace::getCanonicalName($ns); } if ($simplified_format) { $text .= '<' . str_replace(' ', '_', $ns_name) . ">\n"; } else { $text .= "<{$namespace_str} {$name_str}=\"{$ns_name}\">\n"; } $titles = self::getPagesForNamespace($ns); foreach ($titles as $title) { $text .= self::getXMLForPage($title, $simplified_format, $groupings); } if ($simplified_format) { $text .= '</' . str_replace(' ', '_', $ns_name) . ">\n"; } else { $text .= "</{$namespace_str}>\n"; } } } $text .= "</{$pages_str}>"; print $text; } else { // set 'title' as hidden field, in case there's no URL niceness global $wgContLang; $mw_namespace_labels = $wgContLang->getNamespaces(); $special_namespace = $mw_namespace_labels[NS_SPECIAL]; $text = <<<END \t<form action="" method="get"> \t<input type="hidden" name="title" value="{$special_namespace}:ViewXML"> END; $text .= "<p>" . wfMsg('dt_viewxml_docu') . "</p>\n"; $text .= "<h2>" . wfMsg('dt_viewxml_categories') . "</h2>\n"; $categories = self::getCategoriesList(); foreach ($categories as $category) { $title = Title::makeTitle(NS_CATEGORY, $category); $link = $skin->makeLinkObj($title, $title->getText()); $text .= "<input type=\"checkbox\" name=\"categories[{$category}]\" /> {$link} <br />\n"; } $text .= "<h2>" . wfMsg('dt_viewxml_namespaces') . "</h2>\n"; $namespaces = self::getNamespacesList(); foreach ($namespaces as $namespace) { if ($namespace == 0) { $ns_name = wfMsgHtml('blanknamespace'); } else { $ns_name = htmlspecialchars($wgContLang->getFormattedNsText($namespace)); } $ns_name = str_replace('_', ' ', $ns_name); $text .= "<input type=\"checkbox\" name=\"namespaces[{$namespace}]\" /> {$ns_name} <br />\n"; } $text .= "<br /><p><input type=\"checkbox\" name=\"simplified_format\" /> " . wfMsg('dt_viewxml_simplifiedformat') . "</p>\n"; $text .= "<input type=\"submit\" value=\"" . wfMsg('viewxml') . "\">\n"; $text .= "</form>\n"; $wgOut->addHTML($text); } }
function execute( $param ) { global $wgOut, $wgRequest, $wgRecordAdmin, $wgSecurityProtectRecords; if ( !isset( $wgSecurityProtectRecords ) ) $wgSecurityProtectRecords = false; $this->setHeaders(); $type = $wgRequest->getText( 'wpType' ) or $type = $param; $newtype = $wgRequest->getText( 'wpNewType' ); $invert = $wgRequest->getText( 'wpInvert' ); $record = $wgRecordAdmin->record = $wgRequest->getText( 'wpRecord' ); $title = $this->title = SpecialPage::getTitleFor( 'RecordAdmin' ); $action = $title->getLocalURL( 'action=submit' ); $wpTitle = trim( $wgRequest->getText( 'wpTitle' ) ); $this->template = Title::makeTitle( NS_TEMPLATE, $type ); $wgOut->addHTML( '<div class="recordadmin-menubar"><a href="' . $title->getLocalURL() . "/$type\">" . wfMsg( 'recordadmin-newsearch', $type ) . '</a>' . ' ' . '<a href="' . $title->getLocalURL() . '">' . wfMsg( 'recordadmin-newrecord' ) . '</a></div>'."\n" ); # Get posted form values if any $posted = array(); foreach ( $_REQUEST as $k => $v ) if ( preg_match( "|^ra_(\\w+)|", $k, $m ) ) $posted[$m[1]] = is_array( $v ) ? join( "\n", $v ) : $v; # Read in and prepare the form for this record type if one has been selected if ( $type ) $wgRecordAdmin->preProcessForm( $type ); # Extract the input names and types used in the form $wgRecordAdmin->examineForm(); # Process Create New Type form if submitted and user permitted if ( $newtype ) { $wgRecordAdmin->createRecordType( $newtype ); $type = ''; } # If no type selected, render form for record types and create record-type if ( empty( $type ) ) { $wgOut->addHTML( Xml::element( 'form', array( 'class' => 'recordadmin', 'action' => $action, 'method' => 'post' ), null ) ); $wgOut->addWikiText( "<div class='visualClear'></div>\n==" . wfMsg( 'recordadmin-select' ) . "==\n" ); # Render type select list $options = ""; foreach( $wgRecordAdmin->getRecordTypes() as $option ) $options .= "<option>$option</option>"; if ( $options ) $wgOut->addHTML( "<select name='wpType'>$options</select> " . Xml::element( 'input', array( 'type' => 'submit', 'value' => wfMsg( 'recordadmin-submit' ) ) ) ); else $wgOut->AddWikiText( wfMsg( 'recordadmin-noforms' ) ); # Render type create $wgOut->addWikiText( "<br />\n==" . wfMsg( 'recordadmin-createtype' ) . "==\n" ); $wgOut->addHTML( Xml::element( 'input', array( 'name' => 'wpNewType', 'type' => 'text' ) ) . ' ' . Xml::element( 'input', array( 'type' => 'submit', 'value' => wfMsg( 'recordadmin-buttoncreate' ) ) ) . '</form>' ); } # Record type known, render form for searching or creating else { # Process Create submission if ( count( $posted ) && $wgRequest->getText( 'wpCreate' ) ) { if ( empty( $wpTitle ) ) $wpTitle = $wgRecordAdmin->guid; $t = Title::newFromText( $wpTitle ); if ( is_object( $t ) ) { if ( $t->exists() ) $wgOut->addHTML( "<div class='errorbox'>" . wfMsg( 'recordadmin-alreadyexist' , $wpTitle ) . "</div>\n" ); else { # Attempt to create the article $article = new Article( $t ); $summary = "[[Special:RecordAdmin/$type|" . wfMsgForContent( 'recordadmin' ) . "]]: " . wfMsg( 'recordadmin-summary-typecreated', $type ); $success = $article->doEdit( $wgRecordAdmin->valuesToText( $type, $posted ), $summary, EDIT_NEW ); # Redirect to view the record if successfully updated if ( $success ) { $wgOut->disable(); wfResetOutputBuffers(); header( "Location: " . $t->getFullUrl() ); } # Or stay in edit view and report error else $wgOut->addHTML( "<div class='errorbox'>" . wfMsg( 'recordadmin-createerror', $type ) . "</div>\n" ); } } else $wgOut->addHTML( "<div class='errorbox'>" . wfMsg( 'recordadmin-badtitle' ) . "</div>\n" ); $wgOut->addHTML( "<br /><br /><br /><br />\n" ); } # Populate the search form with any posted values $wgRecordAdmin->populateForm( $posted ); # Process Find submission (select and render records) if ( count( $posted ) && $wgRequest->getText( 'wpFind' ) ) { $wgOut->addWikiText( "== " . wfMsg( 'recordadmin-searchresult' ) . " ==\n" ); $records = $wgRecordAdmin->getRecords( $type, $posted, '=', $wpTitle, $invert ); $wgOut->addHTML( $wgRecordAdmin->renderRecords( $records ) ); } # Render the form $wgOut->addHTML( "<br /><form class=\"{$wgRecordAdmin->formClass}\"{$wgRecordAdmin->formAtts} action=\"$action\" method=\"POST\">" ); $wgOut->addWikiText( "==" . wfMsg( 'recordadmin-create', $type ) . "==\n" ); $wgOut->addHTML( '<table class="recordadmin-create">' . '<tr><td class="recordadmin-create-id"><b>' . wfMsg( 'recordadmin-recordid' ) . '</b> ' . Xml::element( 'input', array( 'id' => 'ra-title', 'name' => 'wpTitle', 'size' => 30, 'value' => $wpTitle ) ) . '   ' . Xml::element( 'input', array( 'name' => 'wpInvert', 'type' => 'checkbox' ) ) . ' ' . wfMsg( 'recordadmin-invert' ) . '</td></tr>' . '<tr><td>' . $wgRecordAdmin->form . '</td></tr>' . '<tr><td>' . Xml::element( 'input', array( 'type' => 'hidden', 'id' => 'ra-type', 'name' => 'wpType', 'value' => $type ) ) . '</td></tr>' . '<tr><td>' . Xml::element( 'input', array( 'type' => 'submit', 'name' => 'wpFind', 'id' => 'ra-find', 'value' => wfMsg( 'recordadmin-buttonsearch' ) ) ) . Xml::element( 'input', array( 'type' => 'submit', 'name' => 'wpCreate', 'id' => 'ra-create', 'value' => wfMsg( 'recordadmin-buttoncreate' ) ) ) . Xml::element( 'input', array( 'type' => 'reset', 'value' => wfMsg( 'recordadmin-buttonreset' ) ) ) . '</td></tr>' . '</table></form>' ); } }
/** * Permissions: For non-sysops lock all but a few specials down - return a 404 if not allowed to read */ function onUserGetRights($user, &$rights) { global $wgTitle, $wgOut, $wgContLang; $specials = $wgContLang->getSpecialPageAliases(); $title = explode('/', $wgTitle->getText()); $title = $title[0]; if (is_object($wgTitle) && $wgTitle->getNamespace() == NS_SPECIAL && !self::sysop() && $title != $specials['Userlogin'][0] && $title != $specials['Userlogout'][0] && $title != $specials['ChangePassword'][0] && $title != $specials['PasswordReset'][0] && $title != $specials['Confirmemail'][0]) { $wgOut->disable(); wfResetOutputBuffers(); $code = 404; include dirname(__FILE__) . "/error.php"; die; } return true; }
/** * Do preparations for getting outputted data as a downloadable file * rather than written to the current page */ function prepareCreatingDownloadableFile() { global $wgOut; // Disable MediaWikis theming $wgOut->disable(); // Enables downloading as a stream, which is important for large dumps wfResetOutputBuffers(); // Send headers telling that this is a special content type // and potentially is to be downloaded as a file $this->sendHeadersForOutputType($this->requestdata->outputtype); }
public function execute($par) { $this->setHeaders(); $this->outputHeader(); $config = $this->getConfig(); // Set some variables $this->curonly = true; $this->doExport = false; $request = $this->getRequest(); $this->templates = $request->getCheck('templates'); $this->pageLinkDepth = $this->validateLinkDepth($request->getIntOrNull('pagelink-depth')); $nsindex = ''; $exportall = false; if ($request->getCheck('addcat')) { $page = $request->getText('pages'); $catname = $request->getText('catname'); if ($catname !== '' && $catname !== null && $catname !== false) { $t = Title::makeTitleSafe(NS_MAIN, $catname); if ($t) { /** * @todo FIXME: This can lead to hitting memory limit for very large * categories. Ideally we would do the lookup synchronously * during the export in a single query. */ $catpages = $this->getPagesFromCategory($t); if ($catpages) { if ($page !== '') { $page .= "\n"; } $page .= implode("\n", $catpages); } } } } elseif ($request->getCheck('addns') && $config->get('ExportFromNamespaces')) { $page = $request->getText('pages'); $nsindex = $request->getText('nsindex', ''); if (strval($nsindex) !== '') { /** * Same implementation as above, so same @todo */ $nspages = $this->getPagesFromNamespace($nsindex); if ($nspages) { $page .= "\n" . implode("\n", $nspages); } } } elseif ($request->getCheck('exportall') && $config->get('ExportAllowAll')) { $this->doExport = true; $exportall = true; /* Although $page and $history are not used later on, we nevertheless set them to avoid that PHP notices about using undefined variables foul up our XML output (see call to doExport(...) further down) */ $page = ''; $history = ''; } elseif ($request->wasPosted() && $par == '') { $page = $request->getText('pages'); $this->curonly = $request->getCheck('curonly'); $rawOffset = $request->getVal('offset'); if ($rawOffset) { $offset = wfTimestamp(TS_MW, $rawOffset); } else { $offset = null; } $maxHistory = $config->get('ExportMaxHistory'); $limit = $request->getInt('limit'); $dir = $request->getVal('dir'); $history = array('dir' => 'asc', 'offset' => false, 'limit' => $maxHistory); $historyCheck = $request->getCheck('history'); if ($this->curonly) { $history = WikiExporter::CURRENT; } elseif (!$historyCheck) { if ($limit > 0 && ($maxHistory == 0 || $limit < $maxHistory)) { $history['limit'] = $limit; } if (!is_null($offset)) { $history['offset'] = $offset; } if (strtolower($dir) == 'desc') { $history['dir'] = 'desc'; } } if ($page != '') { $this->doExport = true; } } else { // Default to current-only for GET requests. $page = $request->getText('pages', $par); $historyCheck = $request->getCheck('history'); if ($historyCheck) { $history = WikiExporter::FULL; } else { $history = WikiExporter::CURRENT; } if ($page != '') { $this->doExport = true; } } if (!$config->get('ExportAllowHistory')) { // Override $history = WikiExporter::CURRENT; } $list_authors = $request->getCheck('listauthors'); if (!$this->curonly || !$config->get('ExportAllowListContributors')) { $list_authors = false; } if ($this->doExport) { $this->getOutput()->disable(); // Cancel output buffering and gzipping if set // This should provide safer streaming for pages with history wfResetOutputBuffers(); $request->response()->header("Content-type: application/xml; charset=utf-8"); if ($request->getCheck('wpDownload')) { // Provide a sane filename suggestion $filename = urlencode($config->get('Sitename') . '-' . wfTimestampNow() . '.xml'); $request->response()->header("Content-disposition: attachment;filename={$filename}"); } $this->doExport($page, $history, $list_authors, $exportall); return; } $out = $this->getOutput(); $out->addWikiMsg('exporttext'); if ($page == '') { $categoryName = $request->getText('catname'); } else { $categoryName = ''; } $formDescriptor = array('catname' => array('type' => 'textwithbutton', 'name' => 'catname', 'horizontal-label' => true, 'label-message' => 'export-addcattext', 'default' => $categoryName, 'size' => 40, 'buttontype' => 'submit', 'buttonname' => 'addcat', 'buttondefault' => $this->msg('export-addcat')->text())); if ($config->get('ExportFromNamespaces')) { $formDescriptor += array('nsindex' => array('type' => 'namespaceselectwithbutton', 'default' => $nsindex, 'label-message' => 'export-addnstext', 'horizontal-label' => true, 'name' => 'nsindex', 'id' => 'namespace', 'cssclass' => 'namespaceselector', 'buttontype' => 'submit', 'buttonname' => 'addns', 'buttondefault' => $this->msg('export-addns')->text())); } if ($config->get('ExportAllowAll')) { $formDescriptor += array('exportall' => array('type' => 'check', 'label-message' => 'exportall', 'name' => 'exportall', 'id' => 'exportall', 'default' => $request->wasPosted() ? $request->getCheck('exportall') : false)); } $formDescriptor += array('textarea' => array('class' => 'HTMLTextAreaField', 'name' => 'pages', 'nodata' => true, 'cols' => 40, 'rows' => 10, 'default' => $page)); if ($config->get('ExportAllowHistory')) { $formDescriptor += array('curonly' => array('type' => 'check', 'label-message' => 'exportcuronly', 'name' => 'curonly', 'id' => 'curonly', 'default' => $request->wasPosted() ? $request->getCheck('curonly') : true)); } else { $out->addWikiMsg('exportnohistory'); } $formDescriptor += array('templates' => array('type' => 'check', 'label-message' => 'export-templates', 'name' => 'templates', 'id' => 'wpExportTemplates', 'default' => $request->wasPosted() ? $request->getCheck('templates') : false)); if ($config->get('ExportMaxLinkDepth') || $this->userCanOverrideExportDepth()) { $formDescriptor += array('pagelink-depth' => array('type' => 'text', 'name' => 'pagelink-depth', 'id' => 'pagelink-depth', 'label-message' => 'export-pagelinks', 'default' => '0', 'size' => 20)); } $formDescriptor += array('wpDownload' => array('type' => 'check', 'name' => 'wpDownload', 'id' => 'wpDownload', 'default' => $request->wasPosted() ? $request->getCheck('wpDownload') : true, 'label-message' => 'export-download')); if ($config->get('ExportAllowListContributors')) { $formDescriptor += array('listauthors' => array('type' => 'check', 'label-message' => 'exportlistauthors', 'default' => $request->wasPosted() ? $request->getCheck('listauthors') : false, 'name' => 'listauthors', 'id' => 'listauthors')); } $htmlForm = HTMLForm::factory('div', $formDescriptor, $this->getContext()); $htmlForm->setSubmitTextMsg('export-submit'); $htmlForm->prepareForm()->displayForm(false); $this->addHelpLink('Help:Export'); }
private function exportOntology() { $this->getOutput()->disable(); wfResetOutputBuffers(); $request = $this->getRequest(); $config = $this->getConfig(); $request->response()->header("Content-type: application/xml; charset=utf-8"); if ($request->getCheck('downloadOntology')) { $filename = urlencode($config->get('Sitename') . '-' . wfTimestamp() . '.xml'); $request->response()->header("Content-disposition: attachment; filename={$filename}"); } $ontAbbr = $request->getVal('ontology'); $ontology = new OntologyData($ontAbbr); $rdf = $ontology->getRDF(); $xml = $rdf->exportOntology($ontology->getGraph()); wfDebugLog('OntoKiWi', 'OKW\\Special\\ExportOntology: output ontology RDF/XML generated'); print $xml; }
/** * */ function wfSpecialExport($page = '') { global $wgOut, $wgRequest, $wgExportAllowListContributors; global $wgExportAllowHistory, $wgExportMaxHistory; $curonly = true; if ($wgRequest->wasPosted()) { $page = $wgRequest->getText('pages'); $curonly = $wgRequest->getCheck('curonly'); $rawOffset = $wgRequest->getVal('offset'); if ($rawOffset) { $offset = wfTimestamp(TS_MW, $rawOffset); } else { $offset = null; } $limit = $wgRequest->getInt('limit'); $dir = $wgRequest->getVal('dir'); $history = array('dir' => 'asc', 'offset' => false, 'limit' => $wgExportMaxHistory); $historyCheck = $wgRequest->getCheck('history'); if ($curonly) { $history = WikiExporter::CURRENT; } elseif (!$historyCheck) { if ($limit > 0 && $limit < $wgExportMaxHistory) { $history['limit'] = $limit; } if (!is_null($offset)) { $history['offset'] = $offset; } if (strtolower($dir) == 'desc') { $history['dir'] = 'desc'; } } } else { // Default to current-only for GET requests $page = $wgRequest->getText('pages', $page); $historyCheck = $wgRequest->getCheck('history'); if ($historyCheck) { $history = WikiExporter::FULL; } else { $history = WikiExporter::CURRENT; } } if (!$wgExportAllowHistory) { // Override $history = WikiExporter::CURRENT; } $list_authors = $wgRequest->getCheck('listauthors'); if (!$curonly || !$wgExportAllowListContributors) { $list_authors = false; } if ($page != '') { $wgOut->disable(); // Cancel output buffering and gzipping if set // This should provide safer streaming for pages with history wfResetOutputBuffers(); header("Content-type: application/xml; charset=utf-8"); $pages = explode("\n", $page); $db =& wfGetDB(DB_SLAVE); $exporter = new WikiExporter($db, $history); $exporter->list_authors = $list_authors; $exporter->openStream(); foreach ($pages as $page) { /* if( $wgExportMaxHistory && !$curonly ) { $title = Title::newFromText( $page ); if( $title ) { $count = Revision::countByTitle( $db, $title ); if( $count > $wgExportMaxHistory ) { wfDebug( __FUNCTION__ . ": Skipped $page, $count revisions too big\n" ); continue; } } }*/ $exporter->pageByName($page); } $exporter->closeStream(); return; } $wgOut->addWikiText(wfMsg("exporttext")); $titleObj = SpecialPage::getTitleFor("Export"); $form = wfOpenElement('form', array('method' => 'post', 'action' => $titleObj->getLocalUrl())); $form .= wfOpenElement('textarea', array('name' => 'pages', 'cols' => 40, 'rows' => 10)) . '</textarea><br />'; if ($wgExportAllowHistory) { $form .= wfCheck('curonly', true, array('value' => 'true', 'id' => 'curonly')); $form .= wfLabel(wfMsg('exportcuronly'), 'curonly') . '<br />'; } else { $wgOut->addWikiText(wfMsg('exportnohistory')); } $form .= wfHidden('action', 'submit'); $form .= wfSubmitButton(wfMsg('export-submit')) . '</form>'; $wgOut->addHtml($form); }
private function sendFile( $error_block = '' ) { global $wgContLanguageCode; if ( headers_sent() ) { # there already was sent an error, no need to send anything exit(); } if ( $error_block !== '' ) { # there was an error, send $error_block message instead of real block $this->stat = false; $this->block = $error_block; $content_type = 'text/plain'; } else { # indicates there is no error $content_type = 'application/x-wiki'; } $blocklen = strlen( $this->block ); # Cancel output buffering and gzipping if set wfResetOutputBuffers(); if ( $this->stat !== false ) { $partial_content = ($this->offset !== 0 || $this->stat['size'] !== $blocklen); if ( $partial_content ) { header( 'HTTP/1.1 206 Partial content' ); header( 'Accept-Ranges: bytes' ); } header( 'Last-Modified: ' . gmdate( 'D, d M Y H:i:s', $this->stat['mtime'] ) . ' GMT' ); } header( 'Cache-Control: no-cache' ); header( 'Content-type: ' . $content_type ); if ( $this->stat !== false ) { header( "Content-Disposition: inline;filename*=utf-8'$wgContLanguageCode'" . urlencode( $this->dbkey ) ); if ( $partial_content ) { header( "Content-Range: bytes " . $this->offset . "-" . ( $this->offset + $blocklen - 1 ) . "/" . $this->stat['size'] ); } } header( 'Content-Length: ' . $blocklen ); echo $this->block; exit(); }
/** * More legible than passing a 'false' parameter to wfResetOutputBuffers(): * * Clear away output buffers, but keep the Content-Encoding header * produced by ob_gzhandler, if any. * * This should be used for HTTP 304 responses, where you need to * preserve the Content-Encoding header of the real result, but * also need to suppress the output of ob_gzhandler to keep to spec * and avoid breaking Firefox in rare cases where the headers and * body are broken over two packets. */ function wfClearOutputBuffers() { wfResetOutputBuffers(false); }
/** * */ protected function streamThumbnail() { global $wgVipsThumbnailerHost, $wgVipsTestExpiry; $request = $this->getRequest(); # Validate title and file existance $title = Title::makeTitleSafe( NS_FILE, $request->getText( 'thumb' ) ); if ( is_null( $title ) ) { $this->streamError( 404, "VipsScaler: invalid title\n" ); return; } $file = wfFindFile( $title ); if ( !$file || !$file->exists() ) { $this->streamError( 404, "VipsScaler: file not found\n" ); return; } # Check if vips can handle this file if ( VipsScaler::getVipsHandler( $file ) === false ) { $this->streamError( 500, "VipsScaler: VIPS cannot handle this file type\n" ); return; } # Validate param string $handler = $file->getHandler(); $params = array( 'width' => $request->getInt( 'width' ) ); if ( !$handler->normaliseParams( $file, $params ) ) { $this->streamError( 500, "VipsScaler: invalid parameters\n" ); return; } # Get the thumbnail if ( is_null( $wgVipsThumbnailerHost ) || $request->getBool( 'noproxy' ) ) { # No remote scaler, need to do it ourselves. # Emulate the BitmapHandlerTransform hook $dstPath = VipsCommand::makeTemp( $file->getExtension() ); $dstUrl = ''; wfDebug( __METHOD__ . ": Creating vips thumbnail at $dstPath\n" ); $scalerParams = array( # The size to which the image will be resized 'physicalWidth' => $params['physicalWidth'], 'physicalHeight' => $params['physicalHeight'], 'physicalDimensions' => "{$params['physicalWidth']}x{$params['physicalHeight']}", # The size of the image on the page 'clientWidth' => $params['width'], 'clientHeight' => $params['height'], # Comment as will be added to the EXIF of the thumbnail 'comment' => isset( $params['descriptionUrl'] ) ? "File source: {$params['descriptionUrl']}" : '', # Properties of the original image 'srcWidth' => $file->getWidth(), 'srcHeight' => $file->getHeight(), 'mimeType' => $file->getMimeType(), 'srcPath' => $file->getPath(), 'dstPath' => $dstPath, 'dstUrl' => $dstUrl, ); $options = array(); if ( $request->getBool( 'bilinear' ) ) { $options['bilinear'] = true; wfDebug( __METHOD__ . ": using bilinear scaling\n" ); } if ( $request->getVal( 'sharpen' ) && $request->getVal( 'sharpen' ) < 5 ) { # Limit sharpen sigma to 5, otherwise we have to write huge convolution matrices $options['sharpen'] = array( 'sigma' => floatval( $request->getVal( 'sharpen' ) ) ); wfDebug( __METHOD__ . ": sharpening with radius {$options['sharpen']}\n" ); } # Call the hook $mto = null; VipsScaler::doTransform( $handler, $file, $scalerParams, $options, $mto ); if ( $mto && !$mto->isError() ) { wfDebug( __METHOD__ . ": streaming thumbnail...\n" ); $this->getOutput()->disable(); StreamFile::stream( $dstPath, array( "Cache-Control: public, max-age=$wgVipsTestExpiry, s-maxage=$wgVipsTestExpiry", 'Expires: ' . gmdate( 'r ', time() + $wgVipsTestExpiry ) ) ); } else { $this->streamError( 500, $mto->getHtmlMsg() ); } # Cleanup the temporary file wfSuppressWarnings(); unlink( $dstPath ); wfRestoreWarnings(); } else { # Request the thumbnail at a remote scaler $url = wfExpandUrl( $request->getRequestURL(), PROTO_INTERNAL ); $url = wfAppendQuery( $url, array( 'noproxy' => '1' ) ); wfDebug( __METHOD__ . ": Getting vips thumb from remote url $url\n" ); $bits = IP::splitHostAndPort( $wgVipsThumbnailerHost ); if ( !$bits ) { throw new MWException( __METHOD__.': $wgVipsThumbnailerHost is not set to a valid host' ); } list( $host, $port ) = $bits; if ( $port === false ) { $port = 80; } $proxy = IP::combineHostAndPort( $host, $port ); $options = array( 'method' => 'GET', 'proxy' => $proxy, ); $req = MWHttpRequest::factory( $url, $options ); $status = $req->execute(); if ( $status->isOk() ) { # Disable output and stream the file $this->getOutput()->disable(); wfResetOutputBuffers(); header( 'Content-Type: ' . $file->getMimeType() ); header( 'Content-Length: ' . strlen( $req->getContent() ) ); header( "Cache-Control: public, max-age=$wgVipsTestExpiry, s-maxage=$wgVipsTestExpiry" ); header( 'Expires: ' . gmdate( 'r ', time() + $wgVipsTestExpiry ) ); print $req->getContent(); } elseif ( $status->hasMessage( 'http-bad-status' ) ) { $this->streamError( 500, $req->getContent() ); return; } else { global $wgOut; $this->streamError( 500, $wgOut->parse( $status->getWikiText() ) ); return; } } }
static function doSpecialViewXML() { global $wgOut, $wgRequest, $wgContLang; $namespace_labels = $wgContLang->getNamespaces(); $category_label = $namespace_labels[NS_CATEGORY]; $name_str = str_replace(' ', '_', wfMessage('dt_xml_name')->inContentLanguage()->text()); $namespace_str = str_replace(' ', '_', wfMessage('dt_xml_namespace')->text()); $pages_str = str_replace(' ', '_', wfMessage('dt_xml_pages')->inContentLanguage()->text()); $form_submitted = false; $cats = $wgRequest->getArray('categories'); $nses = $wgRequest->getArray('namespaces'); $requestedTitles = $wgRequest->getVal('titles'); if (count($cats) > 0 || count($nses) > 0 || $requestedTitles != null) { $form_submitted = true; } if ($form_submitted) { $wgOut->disable(); // Cancel output buffering and gzipping if set // This should provide safer streaming for pages with history wfResetOutputBuffers(); header("Content-type: application/xml; charset=utf-8"); $groupings = self::getGroupings(); $simplified_format = $wgRequest->getVal('simplified_format'); $text = "<{$pages_str}>"; if ($cats) { foreach ($cats as $cat => $val) { if ($simplified_format) { $text .= '<' . str_replace(' ', '_', $cat) . ">\n"; } else { $text .= "<{$category_label} {$name_str}=\"{$cat}\">\n"; } $titles = self::getPagesForCategory($cat, 10); foreach ($titles as $title) { $text .= self::getXMLForPage($title, $simplified_format, $groupings); } if ($simplified_format) { $text .= '</' . str_replace(' ', '_', $cat) . ">\n"; } else { $text .= "</{$category_label}>\n"; } } } if ($nses) { foreach ($nses as $ns => $val) { if ($ns == 0) { $ns_name = "Main"; } else { $ns_name = MWNamespace::getCanonicalName($ns); } if ($simplified_format) { $text .= '<' . str_replace(' ', '_', $ns_name) . ">\n"; } else { $text .= "<{$namespace_str} {$name_str}=\"{$ns_name}\">\n"; } $titles = self::getPagesForNamespace($ns); foreach ($titles as $title) { $text .= self::getXMLForPage($title, $simplified_format, $groupings); } if ($simplified_format) { $text .= '</' . str_replace(' ', '_', $ns_name) . ">\n"; } else { $text .= "</{$namespace_str}>\n"; } } } // The user can specify a set of page names to view // the XML of, using a "titles=" parameter, separated // by "|", in the manner of the MediaWiki API. // Hm... perhaps all of Special:ViewXML should just // be replaced by an API action? if ($requestedTitles) { $pageNames = explode('|', $requestedTitles); foreach ($pageNames as $pageName) { $title = Title::newFromText($pageName); $text .= self::getXMLForPage($title, $simplified_format, $groupings); } } $text .= "</{$pages_str}>"; print $text; } else { // set 'title' as hidden field, in case there's no URL niceness global $wgContLang; $mw_namespace_labels = $wgContLang->getNamespaces(); $special_namespace = $mw_namespace_labels[NS_SPECIAL]; $text = <<<END \t<form action="" method="get"> \t<input type="hidden" name="title" value="{$special_namespace}:ViewXML"> END; $text .= "<p>" . wfMessage('dt_viewxml_docu')->text() . "</p>\n"; $text .= "<h2>" . wfMessage('dt_viewxml_categories')->text() . "</h2>\n"; $categories = self::getCategoriesList(); foreach ($categories as $category) { $text .= Html::input("categories[{$category}]", null, 'checkbox'); $title = Title::makeTitle(NS_CATEGORY, $category); $link = Linker::link($title, htmlspecialchars($title->getText())); $text .= " {$link}<br />\n"; } $text .= "<h2>" . wfMessage('dt_viewxml_namespaces')->text() . "</h2>\n"; $namespaces = self::getNamespacesList(); foreach ($namespaces as $nsCode) { if ($nsCode === '0') { $nsName = wfMessage('blanknamespace')->escaped(); } else { $nsName = htmlspecialchars($wgContLang->getFormattedNsText($nsCode)); if ($nsName === '') { continue; } } $text .= Html::input("namespaces[{$nsCode}]", null, 'checkbox'); $text .= ' ' . str_replace('_', ' ', $nsName) . "<br />\n"; } $text .= "<br /><p><label><input type=\"checkbox\" name=\"simplified_format\" /> " . wfMessage('dt_viewxml_simplifiedformat')->text() . "</label></p>\n"; $text .= "<input type=\"submit\" value=\"" . wfMessage('viewxml')->text() . "\">\n"; $text .= "</form>\n"; $wgOut->addHTML($text); } }
/** * Return rendered content of page */ function render(&$out, &$text) { $this->setCaching(); $out->disable(); wfResetOutputBuffers(); echo $text; return false; }
/** * Output HTTP response of raw content * Side effect: writes HTTP response to STDOUT. * @param string $content Content * @param string $contentType MIME type * @throws SpecialUploadStashTooLargeException * @return bool */ private function outputContents($content, $contentType) { $size = strlen($content); if ($size > self::MAX_SERVE_BYTES) { throw new SpecialUploadStashTooLargeException(); } // Cancel output buffering and gzipping if set wfResetOutputBuffers(); self::outputFileHeaders($contentType, $size); print $content; return true; }
/** * Respond with 304 Last Modified if appropiate. * * If there's an If-Modified-Since header, respond with a 304 appropriately * and clear out the output buffer. If the client cache is too old then do nothing. * * @param ResourceLoaderContext $context * @param string $mtime The TS_MW timestamp to check the header against * @return bool True if 304 header sent and output handled */ protected function tryRespondLastModified(ResourceLoaderContext $context, $mtime) { // If there's an If-Modified-Since header, respond with a 304 appropriately // Some clients send "timestamp;length=123". Strip the part after the first ';' // so we get a valid timestamp. $ims = $context->getRequest()->getHeader('If-Modified-Since'); // Never send 304s in debug mode if ($ims !== false && !$context->getDebug()) { $imsTS = strtok($ims, ';'); if ($mtime <= wfTimestamp(TS_UNIX, $imsTS)) { // There's another bug in ob_gzhandler (see also the comment at // the top of this function) that causes it to gzip even empty // responses, meaning it's impossible to produce a truly empty // response (because the gzip header is always there). This is // a problem because 304 responses have to be completely empty // per the HTTP spec, and Firefox behaves buggily when they're not. // See also http://bugs.php.net/bug.php?id=51579 // To work around this, we tear down all output buffering before // sending the 304. wfResetOutputBuffers(true); header('HTTP/1.0 304 Not Modified'); header('Status: 304 Not Modified'); return true; } } return false; }
/** * */ function wfSpecialExport($page = '') { global $wgOut, $wgRequest, $wgSitename, $wgExportAllowListContributors; global $wgExportAllowHistory, $wgExportMaxHistory; $curonly = true; $doexport = false; if ($wgRequest->getCheck('addcat')) { $page = $wgRequest->getText('pages'); $catname = $wgRequest->getText('catname'); if ($catname !== '' && $catname !== NULL && $catname !== false) { $t = Title::makeTitleSafe(NS_CATEGORY, $catname); if ($t) { $catpages = wfExportGetPagesFromCategory($t); if ($catpages) { $page .= "\n" . implode("\n", $catpages); } } } } else { if ($wgRequest->wasPosted() && $page == '') { $page = $wgRequest->getText('pages'); $curonly = $wgRequest->getCheck('curonly'); $rawOffset = $wgRequest->getVal('offset'); if ($rawOffset) { $offset = wfTimestamp(TS_MW, $rawOffset); } else { $offset = null; } $limit = $wgRequest->getInt('limit'); $dir = $wgRequest->getVal('dir'); $history = array('dir' => 'asc', 'offset' => false, 'limit' => $wgExportMaxHistory); $historyCheck = $wgRequest->getCheck('history'); if ($curonly) { $history = WikiExporter::CURRENT; } elseif (!$historyCheck) { if ($limit > 0 && $limit < $wgExportMaxHistory) { $history['limit'] = $limit; } if (!is_null($offset)) { $history['offset'] = $offset; } if (strtolower($dir) == 'desc') { $history['dir'] = 'desc'; } } if ($page != '') { $doexport = true; } } else { // Default to current-only for GET requests $page = $wgRequest->getText('pages', $page); $historyCheck = $wgRequest->getCheck('history'); if ($historyCheck) { $history = WikiExporter::FULL; } else { $history = WikiExporter::CURRENT; } if ($page != '') { $doexport = true; } } } if (!$wgExportAllowHistory) { // Override $history = WikiExporter::CURRENT; } $list_authors = $wgRequest->getCheck('listauthors'); if (!$curonly || !$wgExportAllowListContributors) { $list_authors = false; } if ($doexport) { $wgOut->disable(); // Cancel output buffering and gzipping if set // This should provide safer streaming for pages with history wfResetOutputBuffers(); header("Content-type: application/xml; charset=utf-8"); if ($wgRequest->getCheck('wpDownload')) { // Provide a sane filename suggestion $filename = urlencode($wgSitename . '-' . wfTimestampNow() . '.xml'); $wgRequest->response()->header("Content-disposition: attachment;filename={$filename}"); } $pages = explode("\n", $page); $db = wfGetDB(DB_SLAVE); $exporter = new WikiExporter($db, $history); $exporter->list_authors = $list_authors; $exporter->openStream(); foreach ($pages as $page) { /* if( $wgExportMaxHistory && !$curonly ) { $title = Title::newFromText( $page ); if( $title ) { $count = Revision::countByTitle( $db, $title ); if( $count > $wgExportMaxHistory ) { wfDebug( __FUNCTION__ . ": Skipped $page, $count revisions too big\n" ); continue; } } }*/ #Bug 8824: Only export pages the user can read $title = Title::newFromText($page); if (is_null($title)) { continue; } #TODO: perhaps output an <error> tag or something. if (!$title->userCan('read')) { continue; } #TODO: perhaps output an <error> tag or something. $exporter->pageByTitle($title); } $exporter->closeStream(); return; } $self = SpecialPage::getTitleFor('Export'); $wgOut->addHtml(wfMsgExt('exporttext', 'parse')); $form = Xml::openElement('form', array('method' => 'post', 'action' => $self->getLocalUrl('action=submit'))); $form .= Xml::inputLabel(wfMsg('export-addcattext'), 'catname', 'catname', 40) . ' '; $form .= Xml::submitButton(wfMsg('export-addcat'), array('name' => 'addcat')) . '<br />'; $form .= Xml::openElement('textarea', array('name' => 'pages', 'cols' => 40, 'rows' => 10)); $form .= htmlspecialchars($page); $form .= Xml::closeElement('textarea'); $form .= '<br />'; if ($wgExportAllowHistory) { $form .= Xml::checkLabel(wfMsg('exportcuronly'), 'curonly', 'curonly', true) . '<br />'; } else { $wgOut->addHtml(wfMsgExt('exportnohistory', 'parse')); } $form .= Xml::checkLabel(wfMsg('export-download'), 'wpDownload', 'wpDownload', true) . '<br />'; $form .= Xml::submitButton(wfMsg('export-submit')); $form .= Xml::closeElement('form'); $wgOut->addHtml($form); }
/** * Respond with HTTP 304 Not Modified if appropiate. * * If there's an If-None-Match header, respond with a 304 appropriately * and clear out the output buffer. If the client cache is too old then do nothing. * * @param ResourceLoaderContext $context * @param string $etag ETag header value * @return bool True if HTTP 304 was sent and output handled */ protected function tryRespondNotModified(ResourceLoaderContext $context, $etag) { // See RFC 2616 § 14.26 If-None-Match // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26 $clientKeys = $context->getRequest()->getHeader('If-None-Match', WebRequest::GETHEADER_LIST); // Never send 304s in debug mode if ($clientKeys !== false && !$context->getDebug() && in_array($etag, $clientKeys)) { // There's another bug in ob_gzhandler (see also the comment at // the top of this function) that causes it to gzip even empty // responses, meaning it's impossible to produce a truly empty // response (because the gzip header is always there). This is // a problem because 304 responses have to be completely empty // per the HTTP spec, and Firefox behaves buggily when they're not. // See also http://bugs.php.net/bug.php?id=51579 // To work around this, we tear down all output buffering before // sending the 304. wfResetOutputBuffers(true); HttpStatus::header(304); $this->sendResponseHeaders($context, $etag, false); return true; } return false; }
function download() { global $wgOut, $wgRequest, $wgCollectionContentTypeToFilename; $tempfile = tmpfile(); $r = self::mwServeCommand('render_status', array('collection_id' => $wgRequest->getVal('collection_id'), 'writer' => $wgRequest->getVal('writer'))); $info = false; if (isset($r['url'])) { $result = Http::get($r['url']); if ($result) { fwrite($tempfile, $result); $info = true; } $content_type = $r['content_type']; $content_length = $r['content_length']; $content_disposition = $r['content_disposition']; } else { $info = self::mwServeCommand('download', array('collection_id' => $wgRequest->getVal('collection_id'), 'writer' => $wgRequest->getVal('writer'))); $content_type = $info['content_type']; $content_length = $info['download_content_length']; $content_disposition = null; } if (!$info) { $wgOut->showErrorPage('coll-download_notfound_title', 'coll-download_notfound_text'); return; } wfResetOutputBuffers(); header('Content-Type: ' . $content_type); header('Content-Length: ' . $content_length); if ($content_disposition) { header('Content-Disposition: ' . $content_disposition); } else { $ct_enc = explode(';', $content_type); $ct = $ct_enc[0]; if (isset($wgCollectionContentTypeToFilename[$ct])) { header('Content-Disposition: ' . 'inline; filename=' . $wgCollectionContentTypeToFilename[$ct]); } } fseek($tempfile, 0); fpassthru($tempfile); $wgOut->disable(); }