| Current File : /home/jvzmxxx/wiki1/extensions/Graph/includes/ApiGraph.php |
<?php
/**
*
* @license MIT
* @file
*
* @author Yuri Astrakhan
*/
namespace Graph;
use ApiBase;
use FormatJson;
use Title;
use ParserOptions;
/**
* This class implements action=graph api, allowing client-side graphs to get the spec,
* regardless of how it is stored (page-props or other storage)
* Class ApiGraph
* @package Graph
*/
class ApiGraph extends ApiBase {
public function execute() {
$params = $this->extractRequestParams();
$this->requireOnlyOneParameter( $params, 'title', 'text' );
if ( $params['title'] !== null ) {
if ( $params['hash'] === null ) {
$this->dieUsage( 'Parameter "hash" is required', 'missingparam' );
}
$graph = $this->getFromStorage( $params['title'], $params['hash'] );
} else {
if ( !$this->getRequest()->wasPosted() ) {
$this->dieUsage( 'Request had to be POSTed when used with "text" parameter', 'invalidparammix' );
}
if ( $params['hash'] !== null ) {
$this->dieUsage( 'Parameter "hash" cannot be used with "text"', 'invalidparammix' );
}
$graph = $this->preprocess( $params['text'] );
}
$this->getMain()->setCacheMode( 'public' );
$this->getResult()->addValue( null, $this->getModuleName(), $graph );
}
public function getAllowedParams() {
return [
'hash' => [
ApiBase::PARAM_TYPE => 'string',
],
'title' => [
ApiBase::PARAM_TYPE => 'string',
],
'text' => [
ApiBase::PARAM_TYPE => 'string',
],
];
}
protected function getExamplesMessages() {
return [
'formatversion=2&action=graph&title=Extension%3AGraph%2FDemo&hash=1533aaad45c733dcc7e07614b54cbae4119a6747'
=> 'apihelp-graph-example',
];
}
/**
* Parse graph definition that may contain wiki markup into pure json
* @param string $text
* @return string
*/
private function preprocess( $text ) {
global $wgParser;
$title = Title::makeTitle( NS_SPECIAL, Sandbox::PageName )->fixSpecialName();
$text = $wgParser->getFreshParser()->preprocess( $text, $title, new ParserOptions() );
$st = FormatJson::parse( $text );
if ( !$st->isOK() ) {
// Sometimes we get <graph ...> {...} </graph> as input. Try to strip <graph> tags
$count = 0;
$text = preg_replace( '/^\s*<graph[^>]*>(.*)<\/graph>\s*$/s', '$1', $text, 1, $count );
if ( $count === 1 ) {
$st = FormatJson::parse( $text );
}
if ( !$st->isOK() ) {
$this->dieUsage( 'Graph is not valid.', 'invalidtext' );
}
}
return $st->getValue();
}
/**
* Get graph definition with title and hash
* @param string $title
* @param string $hash
* @return string
*/
private function getFromStorage( $title, $hash ) {
// NOTE: Very strange wgMemc feature: Even though we store the data structure into memcached
// by JSON-encoding and gzip-ing it, when we get it out it is already in the original form.
$graph = Store::getFromCache( $hash );
if ( !$graph ) {
$title = Title::newFromText( $title );
if ( !$title || !$title->exists() || !$title->userCan( 'read', $this->getUser() ) ) {
$this->dieUsage( 'Invalid title given.', 'invalidtitle' );
}
$ppValue = $this->getDB()->selectField( 'page_props', 'pp_value', [
'pp_page' => $title->getArticleID(),
'pp_propname' => 'graph_specs',
], __METHOD__ );
if ( $ppValue ) {
// Copied from TemplateDataBlob.php:newFromDatabase()
// Handle GZIP compression. \037\213 is the header for GZIP files.
if ( substr( $ppValue, 0, 2 ) === "\037\213" ) {
$ppValue = gzdecode( $ppValue );
}
$st = FormatJson::parse( $ppValue );
if ( $st->isOK() ) {
$allGraphs = $st->getValue();
if ( property_exists( $allGraphs, $hash ) ) {
$graph = $allGraphs->$hash;
}
}
}
}
if ( !$graph ) {
$this->dieUsage( 'No graph found.', 'invalidhash' );
}
return $graph;
}
}