Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 65 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
SpecialMathShowImage | |
0.00% |
0 / 65 |
|
0.00% |
0 / 5 |
462 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
setHeaders | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
12 | |||
execute | |
0.00% |
0 / 37 |
|
0.00% |
0 / 1 |
210 | |||
printSvgError | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 | |||
getGroupName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Math; |
4 | |
5 | use MediaWiki\Extension\Math\Render\RendererFactory; |
6 | use MediaWiki\SpecialPage\SpecialPage; |
7 | |
8 | /** |
9 | * Description of SpecialMathShowSVG |
10 | * |
11 | * @author Moritz Schubotz (Physikerwelt) |
12 | */ |
13 | class SpecialMathShowImage extends SpecialPage { |
14 | /** @var bool */ |
15 | private $noRender = false; |
16 | /** @var MathRenderer|null */ |
17 | private $renderer = null; |
18 | /** @var string */ |
19 | private $mode = MathConfig::MODE_MATHML; |
20 | |
21 | /** @var MathConfig */ |
22 | private $mathConfig; |
23 | |
24 | /** @var RendererFactory */ |
25 | private $rendererFactory; |
26 | |
27 | /** |
28 | * @param MathConfig $mathConfig |
29 | * @param RendererFactory $rendererFactory |
30 | */ |
31 | public function __construct( |
32 | MathConfig $mathConfig, |
33 | RendererFactory $rendererFactory |
34 | ) { |
35 | parent::__construct( |
36 | 'MathShowImage', |
37 | '', // Don't restrict |
38 | false // Don't show on Special:SpecialPages - it's not useful interactively |
39 | ); |
40 | $this->mathConfig = $mathConfig; |
41 | $this->rendererFactory = $rendererFactory; |
42 | } |
43 | |
44 | /** |
45 | * Sets headers - this should be called from the execute() method of all derived classes! |
46 | * @param bool $success |
47 | */ |
48 | public function setHeaders( $success = true ) { |
49 | $out = $this->getOutput(); |
50 | $request = $this->getRequest(); |
51 | $out->setArticleBodyOnly( true ); |
52 | $out->setArticleRelated( false ); |
53 | $out->setRobotPolicy( "noindex,nofollow" ); |
54 | $out->disable(); |
55 | $request->response()->header( "Content-type: image/svg+xml; charset=utf-8" ); |
56 | if ( $success && !( $this->noRender ) ) { |
57 | $request->response()->header( |
58 | 'Cache-Control: public, s-maxage=604800, max-age=3600' |
59 | ); // 1 week (server) 1 hour (client) |
60 | $request->response()->header( 'Vary: User-Agent' ); |
61 | } |
62 | } |
63 | |
64 | public function execute( $par ) { |
65 | global $wgMathEnableExperimentalInputFormats; |
66 | $request = $this->getRequest(); |
67 | $hash = $request->getText( 'hash', '' ); |
68 | $tex = $request->getText( 'tex', '' ); |
69 | if ( $wgMathEnableExperimentalInputFormats ) { |
70 | $asciimath = $request->getText( 'asciimath', '' ); |
71 | } else { |
72 | $asciimath = ''; |
73 | } |
74 | $this->mode = MathConfig::normalizeRenderingMode( $request->getText( 'mode' ) ); |
75 | if ( !$this->mathConfig->isValidRenderingMode( $this->mode ) ) { |
76 | // Fallback to the default if an invalid mode was specified |
77 | $this->mode = MathConfig::MODE_MATHML; |
78 | } |
79 | if ( $hash === '' && $tex === '' && $asciimath === '' ) { |
80 | $this->setHeaders( false ); |
81 | echo $this->printSvgError( 'No Inputhash specified' ); |
82 | } else { |
83 | if ( $tex === '' && $asciimath === '' ) { |
84 | $this->renderer = $this->rendererFactory->getFromHash( $hash ); |
85 | $this->noRender = $request->getBool( 'noRender', false ); |
86 | $isInDatabase = $this->renderer->readFromCache(); |
87 | if ( $isInDatabase || $this->noRender ) { |
88 | $success = $isInDatabase; |
89 | } else { |
90 | $success = $this->renderer->render(); |
91 | } |
92 | } elseif ( $asciimath === '' ) { |
93 | $this->renderer = $this->rendererFactory->getRenderer( $tex, [], $this->mode ); |
94 | $success = $this->renderer->render(); |
95 | } else { |
96 | $this->renderer = $this->rendererFactory->getRenderer( |
97 | $asciimath, [ 'type' => 'ascii' ], $this->mode |
98 | ); |
99 | $success = $this->renderer->render(); |
100 | } |
101 | if ( $success ) { |
102 | $output = $this->renderer->getSvg(); |
103 | } else { |
104 | $output = $this->printSvgError( $this->renderer->getLastError() ); |
105 | } |
106 | if ( $output == "" ) { |
107 | $output = $this->printSvgError( 'No Output produced' ); |
108 | $success = false; |
109 | } |
110 | $this->setHeaders( $success ); |
111 | echo $output; |
112 | if ( $success ) { |
113 | $this->renderer->writeCache(); |
114 | } |
115 | } |
116 | } |
117 | |
118 | /** |
119 | * Prints the specified error message as svg. |
120 | * @param string $msg error message, HTML escaped |
121 | * @return string xml svg image with the error message |
122 | */ |
123 | private function printSvgError( $msg ) { |
124 | global $wgDebugComments; |
125 | $result = <<<SVG |
126 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 4" preserveAspectRatio="xMidYMid meet" > |
127 | <text text-anchor="start" fill="red" y="2"> |
128 | $msg |
129 | </text> |
130 | </svg> |
131 | SVG; |
132 | if ( $wgDebugComments ) { |
133 | $result .= '<!--' . var_export( $this->renderer, true ) . '-->'; |
134 | } |
135 | return $result; |
136 | } |
137 | |
138 | protected function getGroupName() { |
139 | return 'other'; |
140 | } |
141 | } |