Merge "Provide command to adjust phpunit.xml for code coverage"
[lhc/web/wiklou.git] / includes / parser / Preprocessor.php
1 <?php
2 /**
3 * Interfaces for preprocessors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Parser
22 */
23
24 use MediaWiki\Logger\LoggerFactory;
25 use MediaWiki\MediaWikiServices;
26
27 /**
28 * @ingroup Parser
29 */
30 abstract class Preprocessor {
31
32 const CACHE_VERSION = 1;
33
34 /**
35 * @var Parser
36 */
37 public $parser;
38
39 /**
40 * @var array Brace matching rules.
41 */
42 protected $rules = [
43 '{' => [
44 'end' => '}',
45 'names' => [
46 2 => 'template',
47 3 => 'tplarg',
48 ],
49 'min' => 2,
50 'max' => 3,
51 ],
52 '[' => [
53 'end' => ']',
54 'names' => [ 2 => null ],
55 'min' => 2,
56 'max' => 2,
57 ],
58 '-{' => [
59 'end' => '}-',
60 'names' => [ 2 => null ],
61 'min' => 2,
62 'max' => 2,
63 ],
64 ];
65
66 /**
67 * Store a document tree in the cache.
68 *
69 * @param string $text
70 * @param int $flags
71 * @param string $tree
72 */
73 protected function cacheSetTree( $text, $flags, $tree ) {
74 $config = RequestContext::getMain()->getConfig();
75
76 $length = strlen( $text );
77 $threshold = $config->get( 'PreprocessorCacheThreshold' );
78 if ( $threshold === false || $length < $threshold || $length > 1e6 ) {
79 return;
80 }
81
82 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
83 $key = $cache->makeKey(
84 // @phan-suppress-next-line PhanUndeclaredConstant
85 defined( 'static::CACHE_PREFIX' ) ? static::CACHE_PREFIX : static::class,
86 md5( $text ),
87 $flags
88 );
89 $value = sprintf( "%08d", static::CACHE_VERSION ) . $tree;
90
91 $cache->set( $key, $value, 86400 );
92
93 LoggerFactory::getInstance( 'Preprocessor' )
94 ->info( "Cached preprocessor output (key: $key)" );
95 }
96
97 /**
98 * Attempt to load a precomputed document tree for some given wikitext
99 * from the cache.
100 *
101 * @param string $text
102 * @param int $flags
103 * @return PPNode_Hash_Tree|bool
104 */
105 protected function cacheGetTree( $text, $flags ) {
106 $config = RequestContext::getMain()->getConfig();
107
108 $length = strlen( $text );
109 $threshold = $config->get( 'PreprocessorCacheThreshold' );
110 if ( $threshold === false || $length < $threshold || $length > 1e6 ) {
111 return false;
112 }
113
114 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
115
116 $key = $cache->makeKey(
117 // @phan-suppress-next-line PhanUndeclaredConstant
118 defined( 'static::CACHE_PREFIX' ) ? static::CACHE_PREFIX : static::class,
119 md5( $text ),
120 $flags
121 );
122
123 $value = $cache->get( $key );
124 if ( !$value ) {
125 return false;
126 }
127
128 $version = intval( substr( $value, 0, 8 ) );
129 if ( $version !== static::CACHE_VERSION ) {
130 return false;
131 }
132
133 LoggerFactory::getInstance( 'Preprocessor' )
134 ->info( "Loaded preprocessor output from cache (key: $key)" );
135
136 return substr( $value, 8 );
137 }
138
139 /**
140 * Create a new top-level frame for expansion of a page
141 *
142 * @return PPFrame
143 */
144 abstract public function newFrame();
145
146 /**
147 * Create a new custom frame for programmatic use of parameter replacement
148 * as used in some extensions.
149 *
150 * @param array $args
151 *
152 * @return PPFrame
153 */
154 abstract public function newCustomFrame( $args );
155
156 /**
157 * Create a new custom node for programmatic use of parameter replacement
158 * as used in some extensions.
159 *
160 * @param array $values
161 */
162 abstract public function newPartNodeArray( $values );
163
164 /**
165 * Preprocess text to a PPNode
166 *
167 * @param string $text
168 * @param int $flags
169 *
170 * @return PPNode
171 */
172 abstract public function preprocessToObj( $text, $flags = 0 );
173 }