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