Index: trunk/extensions/DataTransclusion/DataTransclusionHandler.php |
— | — | @@ -9,281 +9,285 @@ |
10 | 10 | * @licence GNU General Public Licence 2.0 or later |
11 | 11 | */ |
12 | 12 | |
13 | | -if( !defined( 'MEDIAWIKI' ) ) { |
| 13 | +if ( !defined( 'MEDIAWIKI' ) ) { |
14 | 14 | echo( "Not a valid entry point.\n" ); |
15 | 15 | die( 1 ); |
16 | 16 | } |
17 | 17 | |
18 | 18 | class DataTransclusionHandler { |
19 | | - static function buildAssociativeArguments ( $params ) { |
20 | | - // build associative arguments from flat parameter list |
21 | | - $argv = array(); |
22 | | - $i = 1; |
23 | | - foreach ( $params as $p ) { |
24 | | - if ( preg_match( '/^\s*(\S.*?)\s*=\s*(.*?)\s*$/', $p, $m ) ) { |
25 | | - $k = $m[1]; |
26 | | - $v = preg_replace( '/^"\s*(.*?)\s*"$/', '$1', $m[2] ); // strip any quotes enclosing the value |
| 19 | + static function buildAssociativeArguments ( $params ) { |
| 20 | + // build associative arguments from flat parameter list |
| 21 | + $argv = array(); |
| 22 | + $i = 1; |
| 23 | + foreach ( $params as $p ) { |
| 24 | + if ( preg_match( '/^\s*(\S.*?)\s*=\s*(.*?)\s*$/', $p, $m ) ) { |
| 25 | + $k = $m[1]; |
| 26 | + $v = preg_replace( '/^"\s*(.*?)\s*"$/', '$1', $m[2] ); // strip any quotes enclosing the value |
| 27 | + } |
| 28 | + else { |
| 29 | + $v = trim( $p ); |
| 30 | + $k = $i; |
| 31 | + $i += 1; |
| 32 | + } |
| 33 | + |
| 34 | + $argv[$k] = $v; |
27 | 35 | } |
28 | | - else { |
29 | | - $v = trim( $p ); |
30 | | - $k = $i; |
31 | | - $i += 1; |
32 | | - } |
33 | 36 | |
34 | | - $argv[$k] = $v; |
| 37 | + return $argv; |
35 | 38 | } |
36 | 39 | |
37 | | - return $argv; |
38 | | - } |
| 40 | + /** |
| 41 | + * Entry point for the {{#record}} parser function. |
| 42 | + * This is a wrapper around handleRecordTag |
| 43 | + */ |
| 44 | + static function handleRecordFunction ( $parser ) { |
| 45 | + $params = func_get_args(); |
| 46 | + array_shift( $params ); // first is &$parser, strip it |
39 | 47 | |
40 | | - /** |
41 | | - * Entry point for the {{#record}} parser function. |
42 | | - * This is a wrapper around handleRecordTag |
43 | | - */ |
44 | | - static function handleRecordFunction ( $parser ) { |
45 | | - $params = func_get_args(); |
46 | | - array_shift( $params ); // first is &$parser, strip it |
| 48 | + // first user-supplied parameter must be category name |
| 49 | + if ( !$params ) { |
| 50 | + return ''; // no category specified, return nothing |
| 51 | + } |
47 | 52 | |
48 | | - // first user-supplied parameter must be category name |
49 | | - if ( !$params ) { |
50 | | - return ''; // no category specified, return nothing |
51 | | - } |
| 53 | + // build associative arguments from flat parameter list |
| 54 | + $argv = DataTransclusionHandler::buildAssociativeArguments( $params ); |
52 | 55 | |
53 | | - // build associative arguments from flat parameter list |
54 | | - $argv = DataTransclusionHandler::buildAssociativeArguments( $params ); |
| 56 | + // FIXME: error messages contining special blocks like <nowiki> don't get re-substitutet correctly. |
| 57 | + $text = DataTransclusionHandler::handleRecordTransclusion( null, $argv, $parser, false ); |
| 58 | + return array( $text, 'noparse' => false, 'isHTML' => false ); |
| 59 | + } |
55 | 60 | |
56 | | - //FIXME: error messages contining special blocks like <nowiki> don't get re-substitutet correctly. |
57 | | - $text = DataTransclusionHandler::handleRecordTransclusion( null, $argv, $parser, false ); |
58 | | - return array( $text, 'noparse' => false, 'isHTML' => false ); |
59 | | - } |
60 | | - |
61 | | - static function errorMessage( $key, $asHTML ) { |
| 61 | + static function errorMessage( $key, $asHTML ) { |
62 | 62 | $params = func_get_args(); |
63 | 63 | array_shift( $params ); // $key |
64 | 64 | array_shift( $params ); // $asHTML |
65 | 65 | |
66 | | - if ( $asHTML ) $mode = 'parseinline'; |
| 66 | + if ( $asHTML ) $mode = 'parseinline'; |
67 | 67 | else $mode = 'parsemag'; |
68 | 68 | |
69 | 69 | $m = wfMsgExt( $key, $mode, $params ); |
70 | 70 | |
71 | | - //NOTE: using the key as a css class is done mainely for testing/debugging, but could be useful for scripting and styling too. |
72 | | - return "<span class=\"error $key\">$m</span>"; |
73 | | - } |
| 71 | + // NOTE: using the key as a css class is done mainely for testing/debugging, but could be useful for scripting and styling too. |
| 72 | + return "<span class=\"error $key\">$m</span>"; |
| 73 | + } |
74 | 74 | |
75 | | - /** |
76 | | - * Entry point for the <record> tag parser hook. Delegates to handleRecordTransclusion. |
77 | | - */ |
78 | | - static function handleRecordTag( $key, $argv, $parser ) { |
79 | | - DataTransclusionHandler::handleRecordTransclusion( $key, $argv, $parser, true ); |
80 | | - } |
| 75 | + /** |
| 76 | + * Entry point for the <record> tag parser hook. Delegates to handleRecordTransclusion. |
| 77 | + */ |
| 78 | + static function handleRecordTag( $key, $argv, $parser ) { |
| 79 | + DataTransclusionHandler::handleRecordTransclusion( $key, $argv, $parser, true ); |
| 80 | + } |
81 | 81 | |
82 | | - /** |
83 | | - * Fetches a records and renders it, according to the given array of parameters. |
84 | | - * Common implementation for parser tag and parser function. |
85 | | - */ |
86 | | - static function handleRecordTransclusion( $key, $argv, $parser, $asHTML, $templateText = null ) { |
87 | | - //find out which data source to use... |
88 | | - if ( empty( $argv['source'] ) ) { |
89 | | - if ( empty( $argv[1] ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-missing-source', $asHTML ); //TESTME |
90 | | - else $sourceName = $argv[1]; |
91 | | - } else { |
92 | | - $sourceName = $argv['source']; |
93 | | - } |
| 82 | + /** |
| 83 | + * Fetches a records and renders it, according to the given array of parameters. |
| 84 | + * Common implementation for parser tag and parser function. |
| 85 | + */ |
| 86 | + static function handleRecordTransclusion( $key, $argv, $parser, $asHTML, $templateText = null ) { |
| 87 | + // find out which data source to use... |
| 88 | + if ( empty( $argv['source'] ) ) { |
| 89 | + if ( empty( $argv[1] ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-missing-source', $asHTML ); // TESTME |
| 90 | + else $sourceName = $argv[1]; |
| 91 | + } else { |
| 92 | + $sourceName = $argv['source']; |
| 93 | + } |
94 | 94 | |
95 | | - $source = DataTransclusionHandler::getDataSource( $sourceName ); |
96 | | - if ( empty( $source ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-unknown-source', $asHTML, $sourceName ); //TESTME |
| 95 | + $source = DataTransclusionHandler::getDataSource( $sourceName ); |
| 96 | + if ( empty( $source ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-unknown-source', $asHTML, $sourceName ); // TESTME |
97 | 97 | |
98 | | - //find out how to find the desired record |
99 | | - if ( empty( $argv['by'] ) ) $by = $source->getDefaultKey(); |
100 | | - else $by = $argv['by']; |
| 98 | + // find out how to find the desired record |
| 99 | + if ( empty( $argv['by'] ) ) $by = $source->getDefaultKey(); |
| 100 | + else $by = $argv['by']; |
101 | 101 | |
102 | | - $keyFields = $source->getKeyFields(); |
103 | | - if ( ! in_array( $by, $keyFields ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-bad-argument-by', $asHTML, $sourceName, $by, join(', ', $keyFields) ); //TESTME |
| 102 | + $keyFields = $source->getKeyFields(); |
| 103 | + if ( ! in_array( $by, $keyFields ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-bad-argument-by', $asHTML, $sourceName, $by, join( ', ', $keyFields ) ); // TESTME |
104 | 104 | |
105 | | - if ( !empty( $argv['key'] ) ) $key = $argv['key']; |
106 | | - else if ( $key === null || $key === false ) { |
107 | | - if ( empty( $argv[2] ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-missing-argument-key', $asHTML ); //TESTME |
108 | | - else $key = $argv[2]; |
109 | | - } |
| 105 | + if ( !empty( $argv['key'] ) ) $key = $argv['key']; |
| 106 | + else if ( $key === null || $key === false ) { |
| 107 | + if ( empty( $argv[2] ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-missing-argument-key', $asHTML ); // TESTME |
| 108 | + else $key = $argv[2]; |
| 109 | + } |
110 | 110 | |
111 | | - //find out how to render the record |
112 | | - if ( empty( $argv['template'] ) ) { |
113 | | - if ( empty( $argv[3] ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-missing-argument-template', $asHTML ); //TESTME |
114 | | - else $template = $argv[3]; |
115 | | - } else { |
116 | | - $template = $argv['template']; |
117 | | - } |
| 111 | + // find out how to render the record |
| 112 | + if ( empty( $argv['template'] ) ) { |
| 113 | + if ( empty( $argv[3] ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-missing-argument-template', $asHTML ); // TESTME |
| 114 | + else $template = $argv[3]; |
| 115 | + } else { |
| 116 | + $template = $argv['template']; |
| 117 | + } |
118 | 118 | |
119 | | - //load the record |
120 | | - $record = $source->fetchRecord( $by, $key ); |
121 | | - if ( empty( $record ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-record-not-found', $asHTML, $sourceName, $by, $key ); //TESTME |
| 119 | + // load the record |
| 120 | + $record = $source->fetchRecord( $by, $key ); |
| 121 | + if ( empty( $record ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-record-not-found', $asHTML, $sourceName, $by, $key ); // TESTME |
122 | 122 | |
123 | | - //render the record into wiki text |
124 | | - $t = Title::newFromText( $template, NS_TEMPLATE ); |
125 | | - if ( empty( $t ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-bad-template-name', $asHTML, $template ); //TESTME |
| 123 | + // render the record into wiki text |
| 124 | + $t = Title::newFromText( $template, NS_TEMPLATE ); |
| 125 | + if ( empty( $t ) ) return DataTransclusionHandler::errorMessage( 'datatransclusion-bad-template-name', $asHTML, $template ); // TESTME |
126 | 126 | |
127 | | - //FIXME: log the template we used into the parser output, like regular template use |
128 | | - // (including templates used by the template, etc) |
| 127 | + // FIXME: log the template we used into the parser output, like regular template use |
| 128 | + // (including templates used by the template, etc) |
129 | 129 | |
130 | | - $handler = new DataTransclusionHandler( $parser, $source, $t, $templateText ); |
| 130 | + $handler = new DataTransclusionHandler( $parser, $source, $t, $templateText ); |
131 | 131 | |
132 | | - $record = $handler->normalizeRecord( $record ); |
133 | | - $text = $handler->render( $record ); |
| 132 | + $record = $handler->normalizeRecord( $record ); |
| 133 | + $text = $handler->render( $record ); |
134 | 134 | |
135 | | - if ( $text === false ) return DataTransclusionHandler::errorMessage( 'datatransclusion-unknown-template', $asHTML, $template ); //TESTME |
| 135 | + if ( $text === false ) return DataTransclusionHandler::errorMessage( 'datatransclusion-unknown-template', $asHTML, $template ); // TESTME |
136 | 136 | |
137 | | - //set parser output expiry |
138 | | - $expire = $source->getCacheDuration(); |
139 | | - if ( $expire !== false && $expire !== null ) { |
140 | | - $parser->getOutput()->updateCacheExpiry( $expire ); //NOTE: this works only since r67185 //TESTME |
141 | | - } |
| 137 | + // set parser output expiry |
| 138 | + $expire = $source->getCacheDuration(); |
| 139 | + if ( $expire !== false && $expire !== null ) { |
| 140 | + $parser->getOutput()->updateCacheExpiry( $expire ); // NOTE: this works only since r67185 //TESTME |
| 141 | + } |
142 | 142 | |
143 | | - if ( $asHTML && $parser ) { //render into HTML if desired |
144 | | - $html = $parser->recursiveTagParse( $text ); |
145 | | - return $html; //TESTME |
146 | | - } else { |
147 | | - return $text; //TESTME |
148 | | - } |
149 | | - } |
| 143 | + if ( $asHTML && $parser ) { // render into HTML if desired |
| 144 | + $html = $parser->recursiveTagParse( $text ); |
| 145 | + return $html; // TESTME |
| 146 | + } else { |
| 147 | + return $text; // TESTME |
| 148 | + } |
| 149 | + } |
150 | 150 | |
151 | | - function __construct( $parser, $source, $template, $templateText = null ) { |
152 | | - $this->template = $template; |
153 | | - $this->source = $source; |
154 | | - $this->parser = $parser; |
155 | | - $this->templateText = $templateText; |
156 | | - } |
| 151 | + function __construct( $parser, $source, $template, $templateText = null ) { |
| 152 | + $this->template = $template; |
| 153 | + $this->source = $source; |
| 154 | + $this->parser = $parser; |
| 155 | + $this->templateText = $templateText; |
| 156 | + } |
157 | 157 | |
158 | | - function render( $record ) { |
159 | | - //XXX: use cached & preparsed template. $template doesn't have the right type, it seems |
160 | | - /* |
161 | | - list( $text, $this->template ) = $this->parser->getTemplateDom( $this->template ); |
162 | | - $frame = $this->parser->getPreprocessor()->newCustomFrame( $record ); |
163 | | - $text = $frame->expand( $template ); |
164 | | - */ |
| 158 | + function render( $record ) { |
| 159 | + // XXX: use cached & preparsed template. $template doesn't have the right type, it seems |
| 160 | + /* |
| 161 | + list( $text, $this->template ) = $this->parser->getTemplateDom( $this->template ); |
| 162 | + $frame = $this->parser->getPreprocessor()->newCustomFrame( $record ); |
| 163 | + $text = $frame->expand( $template ); |
| 164 | + */ |
165 | 165 | |
166 | | - //XXX: trying another way. but $piece['parts'] needs to be a PPNode. how to do that? |
167 | | - /* |
168 | | - $frame = $this->parser->getPreprocessor()->newCustomFrame( $record ); |
| 166 | + // XXX: trying another way. but $piece['parts'] needs to be a PPNode. how to do that? |
| 167 | + /* |
| 168 | + $frame = $this->parser->getPreprocessor()->newCustomFrame( $record ); |
169 | 169 | |
170 | | - $piece = array(); |
| 170 | + $piece = array(); |
171 | 171 | |
172 | | - if ( $this->template->getNamespace() == NS_TEMPLATE ) $n = ""; |
173 | | - else $n = $this->template->getNsText() . ":"; |
| 172 | + if ( $this->template->getNamespace() == NS_TEMPLATE ) $n = ""; |
| 173 | + else $n = $this->template->getNsText() . ":"; |
174 | 174 | |
175 | | - $piece ['title'] = $n . $this->template->getText(); |
176 | | - $piece['parts'] = $record; |
177 | | - $piece['lineStart'] = false; //XXX: ugly. can't know here whether the brace was at the start of a line |
| 175 | + $piece ['title'] = $n . $this->template->getText(); |
| 176 | + $piece['parts'] = $record; |
| 177 | + $piece['lineStart'] = false; //XXX: ugly. can't know here whether the brace was at the start of a line |
178 | 178 | |
179 | | - $ret = $this->parser->braceSubstitution( $piece, $frame ); |
180 | | - $text = $ret[ 'text' ]; |
181 | | - */ |
| 179 | + $ret = $this->parser->braceSubstitution( $piece, $frame ); |
| 180 | + $text = $ret[ 'text' ]; |
| 181 | + */ |
182 | 182 | |
183 | | - //dumb and slow, but works |
184 | | - if ( $this->templateText ) { |
185 | | - if ( is_string( $this->templateText ) ) $text = $this->templateText; |
186 | | - else $text = $this->templateText->getContent(); |
187 | | - } else { |
188 | | - $article = new Article( $this->template ); |
189 | | - if ( !$article->exists() ) return false; //TESTME |
| 183 | + // dumb and slow, but works |
| 184 | + if ( $this->templateText ) { |
| 185 | + if ( is_string( $this->templateText ) ) |
| 186 | + $text = $this->templateText; |
| 187 | + else |
| 188 | + $text = $this->templateText->getContent(); |
| 189 | + } else { |
| 190 | + $article = new Article( $this->template ); |
190 | 191 | |
191 | | - $text = $article->getContent(); |
192 | | - } |
| 192 | + if ( !$article->exists() ) |
| 193 | + return false; // TESTME |
193 | 194 | |
194 | | - $text = $this->parser->replaceVariables( $text, $record, true ); |
| 195 | + $text = $article->getContent(); |
| 196 | + } |
195 | 197 | |
196 | | - return $text; |
197 | | - } |
| 198 | + $text = $this->parser->replaceVariables( $text, $record, true ); |
198 | 199 | |
199 | | - function normalizeRecord( $record ) { |
200 | | - $rec = array(); |
| 200 | + return $text; |
| 201 | + } |
201 | 202 | |
202 | | - //keep record fields, add missing values |
203 | | - $fields = $this->source->getFieldNames(); |
204 | | - foreach ( $fields as $f ) { |
205 | | - if ( isset( $record[ $f ] ) ) $v = $record[ $f ]; |
206 | | - else $v = ''; |
| 203 | + function normalizeRecord( $record ) { |
| 204 | + $rec = array(); |
207 | 205 | |
208 | | - $rec[ $f ] = $this->sanitizeValue( $v ); //TESTME |
209 | | - } |
| 206 | + // keep record fields, add missing values |
| 207 | + $fields = $this->source->getFieldNames(); |
| 208 | + foreach ( $fields as $f ) { |
| 209 | + if ( isset( $record[ $f ] ) ) $v = $record[ $f ]; |
| 210 | + else $v = ''; |
210 | 211 | |
211 | | - //add source meta info, so we can render links back to the source, |
212 | | - //provide license info, etc |
213 | | - $info = $this->source->getSourceInfo(); //TESTME |
214 | | - foreach ( $info as $f => $v ) { |
215 | | - if ( is_array( $v ) || is_object( $v ) || is_resource( $v ) ) continue; |
216 | | - $rec[ "source.$f" ] = $this->sanitizeValue( $v ); |
217 | | - } |
| 212 | + $rec[ $f ] = $this->sanitizeValue( $v ); // TESTME |
| 213 | + } |
218 | 214 | |
219 | | - return $rec; |
220 | | - } |
| 215 | + // add source meta info, so we can render links back to the source, |
| 216 | + // provide license info, etc |
| 217 | + $info = $this->source->getSourceInfo(); // TESTME |
| 218 | + foreach ( $info as $f => $v ) { |
| 219 | + if ( is_array( $v ) || is_object( $v ) || is_resource( $v ) ) continue; |
| 220 | + $rec[ "source.$f" ] = $this->sanitizeValue( $v ); |
| 221 | + } |
221 | 222 | |
222 | | - protected static $sanitizerSubstitution = array( |
223 | | - # '!&!' => '&', #breaks URLs. not really needed when parsed as wiki-text... |
224 | | - '!&(#?x?[\w\d]+);!' => '&$1;', |
225 | | - '!<!' => '<', |
226 | | - '!>!' => '>', |
227 | | - '!\[!' => '[', |
228 | | - '!\]!' => ']', |
229 | | - '!\{!' => '{', |
230 | | - '!\}!' => '}', |
231 | | - '!\'!' => ''', |
232 | | - '!\|!' => '|', |
233 | | - '!^\*!m' => '*', |
234 | | - '!^#!m' => '#', |
235 | | - '!^:!m' => ':', |
236 | | - '!^;!m' => ';', |
237 | | - '![\r\n]!' => ' ', |
238 | | - '!^ !m' => ' ', |
239 | | - '!^-!m' => '-', |
240 | | - '!^=!m' => '=', |
241 | | - ); |
| 223 | + return $rec; |
| 224 | + } |
242 | 225 | |
243 | | - static function sanitizeValue( $v ) { |
244 | | - //TODO: would be nicer to use <nowiki> - or better, insert substitution chunks directly into the parser state. would still need html escpaing though |
| 226 | + protected static $sanitizerSubstitution = array( |
| 227 | + # '!&!' => '&', #breaks URLs. not really needed when parsed as wiki-text... |
| 228 | + '!&(#?x?[\w\d]+);!' => '&$1;', |
| 229 | + '!<!' => '<', |
| 230 | + '!>!' => '>', |
| 231 | + '!\[!' => '[', |
| 232 | + '!\]!' => ']', |
| 233 | + '!\{!' => '{', |
| 234 | + '!\}!' => '}', |
| 235 | + '!\'!' => ''', |
| 236 | + '!\|!' => '|', |
| 237 | + '!^\*!m' => '*', |
| 238 | + '!^#!m' => '#', |
| 239 | + '!^:!m' => ':', |
| 240 | + '!^;!m' => ';', |
| 241 | + '![\r\n]!' => ' ', |
| 242 | + '!^ !m' => ' ', |
| 243 | + '!^-!m' => '-', |
| 244 | + '!^=!m' => '=', |
| 245 | + ); |
245 | 246 | |
246 | | - $find = array_keys( self::$sanitizerSubstitution ); |
247 | | - $subst = array_values( self::$sanitizerSubstitution ); |
| 247 | + static function sanitizeValue( $v ) { |
| 248 | + // TODO: would be nicer to use <nowiki> - or better, insert substitution chunks directly into the parser state. would still need html escpaing though |
248 | 249 | |
249 | | - $v = preg_replace( $find, $subst, $v ); |
250 | | - return $v; |
251 | | - } |
| 250 | + $find = array_keys( self::$sanitizerSubstitution ); |
| 251 | + $subst = array_values( self::$sanitizerSubstitution ); |
252 | 252 | |
253 | | - static function getDataSource( $name ) { |
254 | | - global $wgDataTransclusionSources; |
255 | | - if ( empty( $wgDataTransclusionSources[ $name ] ) ) return false; |
| 253 | + $v = preg_replace( $find, $subst, $v ); |
| 254 | + return $v; |
| 255 | + } |
256 | 256 | |
257 | | - $source = $wgDataTransclusionSources[ $name ]; |
| 257 | + static function getDataSource( $name ) { |
| 258 | + global $wgDataTransclusionSources; |
| 259 | + if ( empty( $wgDataTransclusionSources[ $name ] ) ) return false; |
258 | 260 | |
259 | | - if ( is_array( $source ) ) { //if the source is an array, use it to instantiate the sourece object |
260 | | - $spec = $source; |
261 | | - $spec[ 'name' ] = $name; |
| 261 | + $source = $wgDataTransclusionSources[ $name ]; |
262 | 262 | |
263 | | - if ( !isset( $spec[ 'class' ] ) ) throw new MWException( "\$wgDataTransclusionSources['$name'] must specifying a class name in the 'class' field." ); |
| 263 | + if ( is_array( $source ) ) { // if the source is an array, use it to instantiate the sourece object |
| 264 | + $spec = $source; |
| 265 | + $spec[ 'name' ] = $name; |
264 | 266 | |
265 | | - $c = $spec[ 'class' ]; |
266 | | - $obj = new $c( $spec ); //pass spec array as constructor argument |
267 | | - if ( !$obj ) throw new MWException( "failed to instantiate \$wgDataTransclusionSources['$name'] as new $c." ); |
| 267 | + if ( !isset( $spec[ 'class' ] ) ) throw new MWException( "\$wgDataTransclusionSources['$name'] must specifying a class name in the 'class' field." ); |
268 | 268 | |
269 | | - $source = $obj; |
| 269 | + $c = $spec[ 'class' ]; |
| 270 | + $obj = new $c( $spec ); // pass spec array as constructor argument |
| 271 | + if ( !$obj ) throw new MWException( "failed to instantiate \$wgDataTransclusionSources['$name'] as new $c." ); |
270 | 272 | |
271 | | - if ( isset( $spec[ 'cache' ] ) ) { //check if a cache should be used |
272 | | - $c = $spec[ 'cache' ]; |
273 | | - if ( !is_object( $c ) ) { //cache may be specified as a string |
274 | | - $c = wfGetCache( $c ); // $c should be one of the CACHE_* constants |
275 | | - } |
| 273 | + $source = $obj; |
276 | 274 | |
277 | | - $source = new CachingDataTransclusionSource( $obj, $c, @$spec['cache-duration'] ); //apply caching wrapper |
| 275 | + if ( isset( $spec[ 'cache' ] ) ) { // check if a cache should be used |
| 276 | + $c = $spec[ 'cache' ]; |
| 277 | + if ( !is_object( $c ) ) { // cache may be specified as a string |
| 278 | + $c = wfGetCache( $c ); // $c should be one of the CACHE_* constants |
| 279 | + } |
| 280 | + |
| 281 | + $source = new CachingDataTransclusionSource( $obj, $c, @$spec['cache-duration'] ); // apply caching wrapper |
| 282 | + } |
| 283 | + |
| 284 | + $wgDataTransclusionSources[ $name ] = $source; // replace spec array by actual object, for later re-use |
278 | 285 | } |
279 | 286 | |
280 | | - $wgDataTransclusionSources[ $name ] = $source; //replace spec array by actual object, for later re-use |
281 | | - } |
| 287 | + if ( !is_object( $source ) ) { |
| 288 | + if ( !isset( $source[ 'class' ] ) ) throw new MWException( "\$wgDataTransclusionSources['$name'] must be an array or an object." ); |
| 289 | + } |
| 290 | + |
| 291 | + return $source; |
| 292 | + } |
282 | 293 | |
283 | | - if ( !is_object( $source ) ) { |
284 | | - if ( !isset( $source[ 'class' ] ) ) throw new MWException( "\$wgDataTransclusionSources['$name'] must be an array or an object." ); |
285 | | - } |
286 | | - |
287 | | - return $source; |
288 | | - } |
289 | | - |
290 | 294 | } |
Index: trunk/extensions/DataTransclusion/tests/DataTransclusionTest.php |
— | — | @@ -11,7 +11,7 @@ |
12 | 12 | else $IP = $dir; |
13 | 13 | } |
14 | 14 | |
15 | | -if( isset( $GET_ ) ) { |
| 15 | +if ( isset( $GET_ ) ) { |
16 | 16 | echo( "This file cannot be run from the web.\n" ); |
17 | 17 | die( 1 ); |
18 | 18 | } |
— | — | @@ -21,7 +21,7 @@ |
22 | 22 | // requires PHPUnit 3.4 |
23 | 23 | require_once 'PHPUnit/Framework.php'; |
24 | 24 | |
25 | | -error_reporting(E_ALL); |
| 25 | +error_reporting( E_ALL ); |
26 | 26 | |
27 | 27 | class DataTransclusionTest extends PHPUnit_Framework_TestCase { |
28 | 28 | |
— | — | @@ -47,23 +47,23 @@ |
48 | 48 | } |
49 | 49 | |
50 | 50 | function testErrorMessage() { |
51 | | - $m = DataTransclusionHandler::errorMessage('datatransclusion-test-wikitext', false); |
52 | | - $this->assertEquals( $m, '<span class="error datatransclusion-test-wikitext">some <span class="test">html</span> and \'\'markup\'\'.</span>' ); |
| 51 | + $m = DataTransclusionHandler::errorMessage( 'datatransclusion-test-wikitext', false ); |
| 52 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-wikitext">some <span class="test">html</span> and \'\'markup\'\'.</span>' ); |
53 | 53 | |
54 | | - $m = DataTransclusionHandler::errorMessage('datatransclusion-test-evil-html', false); |
55 | | - $this->assertEquals( $m, '<span class="error datatransclusion-test-evil-html">some <object>evil</object> html.</span>' ); |
| 54 | + $m = DataTransclusionHandler::errorMessage( 'datatransclusion-test-evil-html', false ); |
| 55 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-evil-html">some <object>evil</object> html.</span>' ); |
56 | 56 | |
57 | | - $m = DataTransclusionHandler::errorMessage('datatransclusion-test-nowiki', false); |
58 | | - $this->assertEquals( $m, '<span class="error datatransclusion-test-nowiki">some <nowiki>{{nowiki}}</nowiki> code.</span>' ); |
| 57 | + $m = DataTransclusionHandler::errorMessage( 'datatransclusion-test-nowiki', false ); |
| 58 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-nowiki">some <nowiki>{{nowiki}}</nowiki> code.</span>' ); |
59 | 59 | |
60 | | - $m = DataTransclusionHandler::errorMessage('datatransclusion-test-wikitext', true); |
61 | | - $this->assertEquals( $m, '<span class="error datatransclusion-test-wikitext">some <span class="test">html</span> and <i>markup</i>.</span>' ); |
| 60 | + $m = DataTransclusionHandler::errorMessage( 'datatransclusion-test-wikitext', true ); |
| 61 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-wikitext">some <span class="test">html</span> and <i>markup</i>.</span>' ); |
62 | 62 | |
63 | | - $m = DataTransclusionHandler::errorMessage('datatransclusion-test-evil-html', true); |
64 | | - $this->assertEquals( $m, '<span class="error datatransclusion-test-evil-html">some <object>evil</object> html.</span>' ); |
| 63 | + $m = DataTransclusionHandler::errorMessage( 'datatransclusion-test-evil-html', true ); |
| 64 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-evil-html">some <object>evil</object> html.</span>' ); |
65 | 65 | |
66 | | - $m = DataTransclusionHandler::errorMessage('datatransclusion-test-nowiki', true); |
67 | | - $this->assertEquals( $m, '<span class="error datatransclusion-test-nowiki">some {{nowiki}} code.</span>' ); |
| 66 | + $m = DataTransclusionHandler::errorMessage( 'datatransclusion-test-nowiki', true ); |
| 67 | + $this->assertEquals( $m, '<span class="error datatransclusion-test-nowiki">some {{nowiki}} code.</span>' ); |
68 | 68 | } |
69 | 69 | |
70 | 70 | function testSanitizeValue() { |
— | — | @@ -95,10 +95,10 @@ |
96 | 96 | $args = array( "foo bar", "x=y", " ah = \"be\" ", "blubber bla" ); |
97 | 97 | $assoc = DataTransclusionhandler::buildAssociativeArguments( $args ); |
98 | 98 | |
99 | | - $this->asserttrue( !isset($assoc[0]) ); |
100 | | - $this->asserttrue( !isset($assoc[3]) ); |
101 | | - $this->asserttrue( !isset($assoc['foo']) ); |
102 | | - $this->asserttrue( !isset($assoc['foo bar']) ); |
| 99 | + $this->asserttrue( !isset( $assoc[0] ) ); |
| 100 | + $this->asserttrue( !isset( $assoc[3] ) ); |
| 101 | + $this->asserttrue( !isset( $assoc['foo'] ) ); |
| 102 | + $this->asserttrue( !isset( $assoc['foo bar'] ) ); |
103 | 103 | $this->assertEquals( $assoc[1], 'foo bar' ); |
104 | 104 | $this->assertEquals( $assoc[2], 'blubber bla' ); |
105 | 105 | $this->assertEquals( $assoc['x'], 'y' ); |
— | — | @@ -109,8 +109,8 @@ |
110 | 110 | global $wgDataTransclusionSources; |
111 | 111 | |
112 | 112 | $spec = array( 'name' => 'FOO', 'keyFields' => 'name,id', 'fieldNames' => 'id,name,info' ); |
113 | | - $data[] = array( "name" => "foo", "id" => 3, "info" => 'test 1'); |
114 | | - $data[] = array( "name" => "bar", "id" => 5, "info" => 'test 2'); |
| 113 | + $data[] = array( "name" => "foo", "id" => 3, "info" => 'test 1' ); |
| 114 | + $data[] = array( "name" => "bar", "id" => 5, "info" => 'test 2' ); |
115 | 115 | $wgDataTransclusionSources[ 'FOO' ] = new FakeDataTransclusionSource( $spec, $data ); |
116 | 116 | |
117 | 117 | $src = DataTransclusionHandler::getDataSource( 'FOO' ); |
— | — | @@ -126,7 +126,7 @@ |
127 | 127 | $this->assertEquals( $rec['name'], 'bar' ); |
128 | 128 | $this->assertEquals( $rec['info'], 'test 2' ); |
129 | 129 | |
130 | | - /////////////////////////////////////////////////////////////////////////////// |
| 130 | + // ///////////////////////////////////////////////////////////////////////////// |
131 | 131 | $spec[ 'class' ] = 'FakeDataTransclusionSource'; |
132 | 132 | $spec[ 'data' ] = $data; |
133 | 133 | |
— | — | @@ -154,11 +154,11 @@ |
155 | 155 | global $wgParser; |
156 | 156 | global $wgDataTransclusionSources; |
157 | 157 | |
158 | | - $data[] = array( "name" => "foo", "id" => "3", "info" => 'test&X'); |
159 | | - $spec = array( |
160 | | - 'class' => 'FakeDataTransclusionSource', |
| 158 | + $data[] = array( "name" => "foo", "id" => "3", "info" => 'test&X' ); |
| 159 | + $spec = array( |
| 160 | + 'class' => 'FakeDataTransclusionSource', |
161 | 161 | 'data' => $data, |
162 | | - 'keyFields' => 'name,id', |
| 162 | + 'keyFields' => 'name,id', |
163 | 163 | 'fieldNames' => 'id,name,info', |
164 | 164 | 'defaultKey' => 'id' |
165 | 165 | ); |
— | — | @@ -167,39 +167,39 @@ |
168 | 168 | |
169 | 169 | # failure mode: no source given |
170 | 170 | $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'foo' => 'bar' ), $wgParser, false ); |
171 | | - $this->assertTrue( preg_match('/class="error datatransclusion-missing-source"/', $s) === 1 ); |
| 171 | + $this->assertTrue( preg_match( '/class="error datatransclusion-missing-source"/', $s ) === 1 ); |
172 | 172 | |
173 | 173 | # failure mode: bad source given |
174 | 174 | $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => '*** nonsense ***', 'template' => 'Dummy' ), $wgParser, false ); |
175 | | - $this->assertTrue( preg_match('/class="error datatransclusion-unknown-source"/', $s) === 1 ); |
| 175 | + $this->assertTrue( preg_match( '/class="error datatransclusion-unknown-source"/', $s ) === 1 ); |
176 | 176 | |
177 | 177 | # failure mode: bad source given (alternative) |
178 | 178 | $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 1 => '*** nonsense ***', 'template' => 'Dummy' ), $wgParser, false ); |
179 | | - $this->assertTrue( preg_match('/class="error datatransclusion-unknown-source"/', $s) === 1 ); |
| 179 | + $this->assertTrue( preg_match( '/class="error datatransclusion-unknown-source"/', $s ) === 1 ); |
180 | 180 | |
181 | 181 | # failure mode: illegal value for by= (must be a key field) |
182 | 182 | $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'by' => 'info', 'template' => 'Dummy' ), $wgParser, false ); |
183 | | - $this->assertTrue( preg_match('/class="error datatransclusion-bad-argument-by"/', $s) === 1 ); |
| 183 | + $this->assertTrue( preg_match( '/class="error datatransclusion-bad-argument-by"/', $s ) === 1 ); |
184 | 184 | |
185 | 185 | # failure mode: no key value specified |
186 | 186 | $s = DataTransclusionHandler::handleRecordTransclusion( null, array( 'source' => 'FOO', 'template' => 'Dummy' ), $wgParser, false ); |
187 | | - $this->assertTrue( preg_match('/class="error datatransclusion-missing-argument-key"/', $s) === 1 ); |
| 187 | + $this->assertTrue( preg_match( '/class="error datatransclusion-missing-argument-key"/', $s ) === 1 ); |
188 | 188 | |
189 | 189 | # failure mode: no template specified |
190 | 190 | $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO' ), $wgParser, false ); |
191 | | - $this->assertTrue( preg_match('/class="error datatransclusion-missing-argument-template"/', $s) === 1 ); |
| 191 | + $this->assertTrue( preg_match( '/class="error datatransclusion-missing-argument-template"/', $s ) === 1 ); |
192 | 192 | |
193 | 193 | # failure mode: illegal template specified |
194 | 194 | $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => '#' ), $wgParser, false ); |
195 | | - $this->assertTrue( preg_match('/class="error datatransclusion-bad-template-name"/', $s) === 1 ); |
| 195 | + $this->assertTrue( preg_match( '/class="error datatransclusion-bad-template-name"/', $s ) === 1 ); |
196 | 196 | |
197 | 197 | # failure mode: record can't be found for that key |
198 | 198 | $s = DataTransclusionHandler::handleRecordTransclusion( "xxxxxxxxxx", array( 'source' => 'FOO', 'template' => 'Dummy' ), $wgParser, false ); |
199 | | - $this->assertTrue( preg_match('/class="error datatransclusion-record-not-found"/', $s) === 1 ); |
| 199 | + $this->assertTrue( preg_match( '/class="error datatransclusion-record-not-found"/', $s ) === 1 ); |
200 | 200 | |
201 | 201 | # failure mode: unknown template |
202 | 202 | $s = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => '---SomeTemplateThatHopefullyDoesNotExist---' ), $wgParser, false ); |
203 | | - $this->assertTrue( preg_match('/class="error datatransclusion-unknown-template"/', $s) === 1 ); |
| 203 | + $this->assertTrue( preg_match( '/class="error datatransclusion-unknown-template"/', $s ) === 1 ); |
204 | 204 | |
205 | 205 | # success: render record |
206 | 206 | $res = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => 'Test' ), $wgParser, false, "'''{{{id}}}'''|{{{name}}}|{{{info}}}" ); |
— | — | @@ -211,15 +211,15 @@ |
212 | 212 | |
213 | 213 | # success: render record (as HTML) |
214 | 214 | $res = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => 'Test' ), $wgParser, true, "'''{{{id}}}'''|{{{name}}}|{{{info}}}" ); |
215 | | - $this->assertEquals( $res, '<b>3</b>|foo|test&X' ); //FIXME: & should have been escaped to & here, no? why not? |
| 215 | + $this->assertEquals( $res, '<b>3</b>|foo|test&X' ); // FIXME: & should have been escaped to & here, no? why not? |
216 | 216 | } |
217 | 217 | |
218 | 218 | function testNormalizeRecord() { |
219 | 219 | global $wgParser; |
220 | 220 | |
221 | | - $spec = array( 'name' => 'FOO', |
222 | | - 'keyFields' => 'name,id', |
223 | | - 'fieldNames' => 'id,name,info', |
| 221 | + $spec = array( 'name' => 'FOO', |
| 222 | + 'keyFields' => 'name,id', |
| 223 | + 'fieldNames' => 'id,name,info', |
224 | 224 | 'sourceInfo' => array( 'x' => 43, 'quux' => 'xyzzy' ), |
225 | 225 | ); |
226 | 226 | $data[] = $rec = array( "name" => "foo", "id" => 3, "info" => '{{test}}=[[x]] 1&2 ', 'stuff' => 'bla bla bla' ); |
— | — | @@ -236,8 +236,8 @@ |
237 | 237 | $this->assertEquals( $rec['name'], 'foo' ); |
238 | 238 | $this->assertEquals( $rec['id'], '3' ); |
239 | 239 | $this->assertEquals( $rec['info'], '{{test}}=[[x]] 1&2 ' ); |
240 | | - $this->assertTrue( !isset($rec['stuff']) ); |
241 | | - $this->assertTrue( !isset($rec['name.keyFields']) ); |
| 240 | + $this->assertTrue( !isset( $rec['stuff'] ) ); |
| 241 | + $this->assertTrue( !isset( $rec['name.keyFields'] ) ); |
242 | 242 | } |
243 | 243 | |
244 | 244 | function testRender() { |
— | — | @@ -245,7 +245,7 @@ |
246 | 246 | |
247 | 247 | $source = null; |
248 | 248 | $title = Title::newFromText( "Template:Thing" ); |
249 | | - $rec = array( "name" => "foo", "id" => 3, "info" => 'test X'); |
| 249 | + $rec = array( "name" => "foo", "id" => 3, "info" => 'test X' ); |
250 | 250 | $template = "{{{id}}}|{{{name}}}|{{{info}}}"; |
251 | 251 | |
252 | 252 | $handler = new DataTransclusionHandler( $wgParser, $source, $title, $template ); |
— | — | @@ -257,15 +257,15 @@ |
258 | 258 | function testCachedFetchRecord() { |
259 | 259 | global $wgDataTransclusionSources; |
260 | 260 | |
261 | | - $data[] = array( "name" => "foo", "id" => 3, "info" => 'test 1'); |
262 | | - $data[] = array( "name" => "bar", "id" => 5, "info" => 'test 2'); |
263 | | - $spec = array( |
264 | | - 'class' => 'FakeDataTransclusionSource', |
| 261 | + $data[] = array( "name" => "foo", "id" => 3, "info" => 'test 1' ); |
| 262 | + $data[] = array( "name" => "bar", "id" => 5, "info" => 'test 2' ); |
| 263 | + $spec = array( |
| 264 | + 'class' => 'FakeDataTransclusionSource', |
265 | 265 | 'data' => $data, |
266 | | - 'keyFields' => 'name,id', |
| 266 | + 'keyFields' => 'name,id', |
267 | 267 | 'fieldNames' => 'id,name,info', |
268 | | - 'cacheDuration' => 2, |
269 | | - 'cache' => new HashBagOStuff(), |
| 268 | + 'cacheDuration' => 2, |
| 269 | + 'cache' => new HashBagOStuff(), |
270 | 270 | ); |
271 | 271 | |
272 | 272 | $wgDataTransclusionSources[ 'FOO' ] = $spec; |
— | — | @@ -273,75 +273,75 @@ |
274 | 274 | $src = DataTransclusionHandler::getDataSource( 'FOO' ); |
275 | 275 | $this->assertTrue( $src instanceof CachingDataTransclusionSource ); |
276 | 276 | |
277 | | - //get original version |
| 277 | + // get original version |
278 | 278 | $rec = $src->fetchRecord( 'id', 3 ); |
279 | 279 | $this->assertEquals( $rec['id'], 3 ); |
280 | 280 | $this->assertEquals( $rec['name'], 'foo' ); |
281 | 281 | $this->assertEquals( $rec['info'], 'test 1' ); |
282 | 282 | |
283 | | - //change record |
284 | | - $rec = array( "name" => "foo", "id" => 3, "info" => 'test X'); |
| 283 | + // change record |
| 284 | + $rec = array( "name" => "foo", "id" => 3, "info" => 'test X' ); |
285 | 285 | $src->source->putRecord( $rec ); |
286 | 286 | |
287 | | - //fetch record - should be the cached version |
| 287 | + // fetch record - should be the cached version |
288 | 288 | $rec = $src->fetchRecord( 'id', 3 ); |
289 | 289 | $this->assertEquals( $rec['info'], 'test 1' ); |
290 | 290 | |
291 | | - sleep(3); |
| 291 | + sleep( 3 ); |
292 | 292 | |
293 | | - //fetch record - cached version should have expired |
| 293 | + // fetch record - cached version should have expired |
294 | 294 | $rec = $src->fetchRecord( 'id', 3 ); |
295 | 295 | $this->assertEquals( $rec['info'], 'test X' ); |
296 | 296 | } |
297 | 297 | |
298 | 298 | function testDBDataTransclusionSource() { |
299 | | - $spec = array( |
300 | | - 'name' => 'FOO', |
301 | | - 'keyTypes' => array( 'id' => 'int', 'name' => 'string' ), |
302 | | - 'query' => 'SELECT * FROM foo ', |
303 | | - 'querySuffix' => ' GROUP BY id', |
304 | | - ); |
| 299 | + $spec = array( |
| 300 | + 'name' => 'FOO', |
| 301 | + 'keyTypes' => array( 'id' => 'int', 'name' => 'string' ), |
| 302 | + 'query' => 'SELECT * FROM foo ', |
| 303 | + 'querySuffix' => ' GROUP BY id', |
| 304 | + ); |
305 | 305 | |
306 | | - $source = new DBDataTransclusionSource( $spec ); |
307 | | - $sql = $source->getQuery( 'name', 'foo"' ); |
308 | | - |
309 | | - $this->assertTrue( preg_match('/^SELECT \* FROM foo/', $sql) === 1 ); |
310 | | - $this->assertTrue( preg_match('/GROUP BY id$/', $sql) === 1 ); |
311 | | - $this->assertTrue( preg_match("/WHERE \\( *name *= *'foo\\\\\"' *\\)/", $sql) === 1 ); |
| 306 | + $source = new DBDataTransclusionSource( $spec ); |
| 307 | + $sql = $source->getQuery( 'name', 'foo"' ); |
| 308 | + |
| 309 | + $this->assertTrue( preg_match( '/^SELECT \* FROM foo/', $sql ) === 1 ); |
| 310 | + $this->assertTrue( preg_match( '/GROUP BY id$/', $sql ) === 1 ); |
| 311 | + $this->assertTrue( preg_match( "/WHERE \\( *name *= *'foo\\\\\"' *\\)/", $sql ) === 1 ); |
312 | 312 | |
313 | | - $sql = $source->getQuery( 'id', '3' ); |
314 | | - $this->assertTrue( preg_match('/WHERE \( *id *= *3 *\)/', $sql) === 1 ); |
| 313 | + $sql = $source->getQuery( 'id', '3' ); |
| 314 | + $this->assertTrue( preg_match( '/WHERE \( *id *= *3 *\)/', $sql ) === 1 ); |
315 | 315 | } |
316 | 316 | |
317 | 317 | function testWebDataTransclusionSource() { |
318 | | - $spec = array( |
319 | | - 'name' => 'FOO', |
320 | | - 'keyFields' => 'id,name', |
321 | | - 'url' => 'http://acme.com/', |
322 | | - 'dataFormat' => 'php', |
323 | | - 'dataPath' => 'response/content/@0', |
324 | | - 'errorPath' => 'response/error', |
325 | | - ); |
| 318 | + $spec = array( |
| 319 | + 'name' => 'FOO', |
| 320 | + 'keyFields' => 'id,name', |
| 321 | + 'url' => 'http://acme.com/', |
| 322 | + 'dataFormat' => 'php', |
| 323 | + 'dataPath' => 'response/content/@0', |
| 324 | + 'errorPath' => 'response/error', |
| 325 | + ); |
326 | 326 | |
327 | | - $source = new WebDataTransclusionSource( $spec ); |
| 327 | + $source = new WebDataTransclusionSource( $spec ); |
328 | 328 | |
329 | | - $u = $source->getRecordURL( 'name', 'foo&bar' ); |
330 | | - $this->assertEquals( $u, 'http://acme.com/?name=foo%26bar' ); |
| 329 | + $u = $source->getRecordURL( 'name', 'foo&bar' ); |
| 330 | + $this->assertEquals( $u, 'http://acme.com/?name=foo%26bar' ); |
331 | 331 | |
332 | | - $rec = array( "name" => "foo", "id" => 3, "info" => 'test X'); |
333 | | - $data = array( 'response' => array( |
334 | | - 'error' => 'test error', |
335 | | - 'content' => array( |
336 | | - 'foo' => $rec |
337 | | - ) |
338 | | - ) ); |
| 332 | + $rec = array( "name" => "foo", "id" => 3, "info" => 'test X' ); |
| 333 | + $data = array( 'response' => array( |
| 334 | + 'error' => 'test error', |
| 335 | + 'content' => array( |
| 336 | + 'foo' => $rec |
| 337 | + ) |
| 338 | + ) ); |
339 | 339 | |
340 | | - $data = serialize( $data ); |
341 | | - $rec = $source->extractRecord( $source->decodeData( $data, 'php' ) ); |
342 | | - $err = $source->extractError( $source->decodeData( $data, 'php' ) ); |
| 340 | + $data = serialize( $data ); |
| 341 | + $rec = $source->extractRecord( $source->decodeData( $data, 'php' ) ); |
| 342 | + $err = $source->extractError( $source->decodeData( $data, 'php' ) ); |
343 | 343 | |
344 | | - $this->assertEquals( $err, 'test error' ); |
345 | | - $this->assertEquals( $rec['id'], 3 ); |
| 344 | + $this->assertEquals( $err, 'test error' ); |
| 345 | + $this->assertEquals( $rec['id'], 3 ); |
346 | 346 | } |
347 | 347 | } |
348 | 348 | |
Index: trunk/extensions/DataTransclusion/WebDataTransclusionSource.php |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | * @licence GNU General Public Licence 2.0 or later |
11 | 11 | */ |
12 | 12 | |
13 | | -if( !defined( 'MEDIAWIKI' ) ) { |
| 13 | +if ( !defined( 'MEDIAWIKI' ) ) { |
14 | 14 | echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); |
15 | 15 | die( 1 ); |
16 | 16 | } |
— | — | @@ -50,92 +50,92 @@ |
51 | 51 | */ |
52 | 52 | class WebDataTransclusionSource extends DataTransclusionSource { |
53 | 53 | |
54 | | - function __construct( $spec ) { |
55 | | - DataTransclusionSource::__construct( $spec ); |
| 54 | + function __construct( $spec ) { |
| 55 | + DataTransclusionSource::__construct( $spec ); |
56 | 56 | |
57 | | - $this->url = $spec[ 'url' ]; |
58 | | - $this->dataFormat = @$spec[ 'dataFormat' ]; |
59 | | - $this->dataPath = DataTransclusionSource::splitList( @$spec[ 'dataPath' ] ); |
60 | | - $this->errorPath = DataTransclusionSource::splitList( @$spec[ 'errorPath' ] ); |
61 | | - $this->httpOptions = @$spec[ 'httpOptions' ]; |
62 | | - $this->timeout = @$spec[ 'timeout' ]; |
| 57 | + $this->url = $spec[ 'url' ]; |
| 58 | + $this->dataFormat = @$spec[ 'dataFormat' ]; |
| 59 | + $this->dataPath = DataTransclusionSource::splitList( @$spec[ 'dataPath' ] ); |
| 60 | + $this->errorPath = DataTransclusionSource::splitList( @$spec[ 'errorPath' ] ); |
| 61 | + $this->httpOptions = @$spec[ 'httpOptions' ]; |
| 62 | + $this->timeout = @$spec[ 'timeout' ]; |
63 | 63 | |
64 | | - if ( !$this->dataFormat ) $this->dataFormat = 'php'; |
65 | | - if ( !$this->timeout ) $this->timeout = &$this->httpOptions[ 'timeout' ]; |
66 | | - if ( !$this->timeout ) $this->timeout = 5; |
67 | | - } |
| 64 | + if ( !$this->dataFormat ) $this->dataFormat = 'php'; |
| 65 | + if ( !$this->timeout ) $this->timeout = &$this->httpOptions[ 'timeout' ]; |
| 66 | + if ( !$this->timeout ) $this->timeout = 5; |
| 67 | + } |
68 | 68 | |
69 | | - public function fetchRecord( $field, $value ) { |
70 | | - $raw = $this->loadRecordData( $field, $value ); //TESTME |
71 | | - if ( !$raw ) return false; //TODO: log error? |
| 69 | + public function fetchRecord( $field, $value ) { |
| 70 | + $raw = $this->loadRecordData( $field, $value ); // TESTME |
| 71 | + if ( !$raw ) return false; // TODO: log error? |
72 | 72 | |
73 | | - $data = $this->decodeData( $raw, $this->dataFormat ); //TESTME |
74 | | - if ( !$data ) return false; //TODO: log error? |
| 73 | + $data = $this->decodeData( $raw, $this->dataFormat ); // TESTME |
| 74 | + if ( !$data ) return false; // TODO: log error? |
75 | 75 | |
76 | | - $err = $this->extractError( $data ); //TESTME |
77 | | - if ( $err ) return false; //TODO: log error? |
78 | | - |
79 | | - $rec = $this->extractRecord( $data ); //TESTME |
80 | | - if ( !$rec ) return false; //TODO: log error? |
| 76 | + $err = $this->extractError( $data ); // TESTME |
| 77 | + if ( $err ) return false; // TODO: log error? |
81 | 78 | |
82 | | - return $rec; |
83 | | - } |
| 79 | + $rec = $this->extractRecord( $data ); // TESTME |
| 80 | + if ( !$rec ) return false; // TODO: log error? |
84 | 81 | |
85 | | - public function getRecordURL( $field, $value ) { |
86 | | - $u = $this->url; |
| 82 | + return $rec; |
| 83 | + } |
87 | 84 | |
88 | | - if ( strpos( $u, '?' ) === false ) $u .= '?'; |
89 | | - else $u .= '&'; |
| 85 | + public function getRecordURL( $field, $value ) { |
| 86 | + $u = $this->url; |
90 | 87 | |
91 | | - $u .= $field; |
92 | | - $u .= '='; |
93 | | - $u .= urlencode( $value ); |
| 88 | + if ( strpos( $u, '?' ) === false ) $u .= '?'; |
| 89 | + else $u .= '&'; |
94 | 90 | |
95 | | - return $u; |
96 | | - } |
| 91 | + $u .= $field; |
| 92 | + $u .= '='; |
| 93 | + $u .= urlencode( $value ); |
97 | 94 | |
98 | | - public function loadRecordData( $field, $value ) { |
99 | | - $u = $this->getRecordURL( $field, $value ); |
| 95 | + return $u; |
| 96 | + } |
100 | 97 | |
101 | | - $raw = Http::get( $u, $this->timeout, $this->httpOptions ); |
102 | | - return $raw; |
103 | | - } |
| 98 | + public function loadRecordData( $field, $value ) { |
| 99 | + $u = $this->getRecordURL( $field, $value ); |
104 | 100 | |
105 | | - public function decodeData( $raw, $format = 'php' ) { |
106 | | - if ( $format == 'json' ) return FormatJson::decode( $raw, true ); //TESTME |
107 | | - if ( $format == 'wddx' ) return wddx_unserialize( $raw ); //TESTME |
108 | | - if ( $format == 'php' ) return unserialize( $raw ); //TESTME |
| 101 | + $raw = Http::get( $u, $this->timeout, $this->httpOptions ); |
| 102 | + return $raw; |
| 103 | + } |
109 | 104 | |
110 | | - return false; |
111 | | - } |
| 105 | + public function decodeData( $raw, $format = 'php' ) { |
| 106 | + if ( $format == 'json' ) return FormatJson::decode( $raw, true ); // TESTME |
| 107 | + if ( $format == 'wddx' ) return wddx_unserialize( $raw ); // TESTME |
| 108 | + if ( $format == 'php' ) return unserialize( $raw ); // TESTME |
112 | 109 | |
113 | | - public function extractError( $data ) { |
114 | | - return $this->extractField( $data, $this->errorPath ); |
115 | | - } |
| 110 | + return false; |
| 111 | + } |
116 | 112 | |
117 | | - public function extractRecord( $data ) { |
118 | | - return $this->extractField( $data, $this->dataPath ); |
119 | | - } |
| 113 | + public function extractError( $data ) { |
| 114 | + return $this->extractField( $data, $this->errorPath ); |
| 115 | + } |
120 | 116 | |
121 | | - public function extractField( $data, $path ) { |
122 | | - if ( $path == null ) return $data; |
123 | | - if ( is_string( $path ) ) return @$data[ $path ]; |
| 117 | + public function extractRecord( $data ) { |
| 118 | + return $this->extractField( $data, $this->dataPath ); |
| 119 | + } |
124 | 120 | |
125 | | - foreach ( $path as $p ) { |
126 | | - if ( is_object( $data ) ) $data = wfObjectToArray( $data ); |
| 121 | + public function extractField( $data, $path ) { |
| 122 | + if ( $path == null ) return $data; |
| 123 | + if ( is_string( $path ) ) return @$data[ $path ]; |
127 | 124 | |
128 | | - // meta-key: index in the list of array-keys. |
129 | | - // e.g. use @0 to grab the first value from an assoc array. |
130 | | - if ( is_string( $p ) && preg_match( '/^@(\d+)$/', $p, $m ) ) { |
131 | | - $i = (int)$m[1]; |
132 | | - $k = array_keys( $data ); |
133 | | - $p = $k[ $i ]; |
134 | | - } |
| 125 | + foreach ( $path as $p ) { |
| 126 | + if ( is_object( $data ) ) $data = wfObjectToArray( $data ); |
135 | 127 | |
136 | | - if ( !isset( $data[ $p ] ) ) return false; |
137 | | - $data = $data[ $p ]; |
138 | | - } |
| 128 | + // meta-key: index in the list of array-keys. |
| 129 | + // e.g. use @0 to grab the first value from an assoc array. |
| 130 | + if ( is_string( $p ) && preg_match( '/^@(\d+)$/', $p, $m ) ) { |
| 131 | + $i = (int)$m[1]; |
| 132 | + $k = array_keys( $data ); |
| 133 | + $p = $k[ $i ]; |
| 134 | + } |
139 | 135 | |
140 | | - return $data; |
141 | | - } |
| 136 | + if ( !isset( $data[ $p ] ) ) return false; |
| 137 | + $data = $data[ $p ]; |
| 138 | + } |
| 139 | + |
| 140 | + return $data; |
| 141 | + } |
142 | 142 | } |
Index: trunk/extensions/DataTransclusion/DataTransclusion.php |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | * @licence GNU General Public Licence 2.0 or later |
11 | 11 | */ |
12 | 12 | |
13 | | -if( !defined( 'MEDIAWIKI' ) ) { |
| 13 | +if ( !defined( 'MEDIAWIKI' ) ) { |
14 | 14 | echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); |
15 | 15 | die( 1 ); |
16 | 16 | } |
— | — | @@ -22,26 +22,26 @@ |
23 | 23 | 'descriptionmsg' => 'datatransclusion-desc', |
24 | 24 | ); |
25 | 25 | |
26 | | -$dir = dirname(__FILE__) . '/'; |
| 26 | +$dir = dirname( __FILE__ ) . '/'; |
27 | 27 | $wgExtensionMessagesFiles['DataTransclusion'] = $dir . 'DataTransclusion.i18n.php'; |
28 | 28 | $wgExtensionMessagesFiles['DataTransclusionMagic'] = $dir . 'DataTransclusion.i18n.magic.php'; |
29 | 29 | |
30 | | -$wgAutoloadClasses['DataTransclusionRenderer'] = $dir. 'DataTransclusionRenderer.php'; |
31 | | -$wgAutoloadClasses['DataTransclusionHandler'] = $dir. 'DataTransclusionHandler.php'; |
32 | | -$wgAutoloadClasses['DataTransclusionSource'] = $dir. 'DataTransclusionSource.php'; |
33 | | -$wgAutoloadClasses['CachingDataTransclusionSource'] = $dir. 'DataTransclusionSource.php'; |
34 | | -$wgAutoloadClasses['FakeDataTransclusionSource'] = $dir. 'DataTransclusionSource.php'; |
35 | | -$wgAutoloadClasses['DBDataTransclusionSource'] = $dir. 'DBDataTransclusionSource.php'; |
36 | | -$wgAutoloadClasses['WebDataTransclusionSource'] = $dir. 'WebDataTransclusionSource.php'; |
| 30 | +$wgAutoloadClasses['DataTransclusionRenderer'] = $dir . 'DataTransclusionRenderer.php'; |
| 31 | +$wgAutoloadClasses['DataTransclusionHandler'] = $dir . 'DataTransclusionHandler.php'; |
| 32 | +$wgAutoloadClasses['DataTransclusionSource'] = $dir . 'DataTransclusionSource.php'; |
| 33 | +$wgAutoloadClasses['CachingDataTransclusionSource'] = $dir . 'DataTransclusionSource.php'; |
| 34 | +$wgAutoloadClasses['FakeDataTransclusionSource'] = $dir . 'DataTransclusionSource.php'; |
| 35 | +$wgAutoloadClasses['DBDataTransclusionSource'] = $dir . 'DBDataTransclusionSource.php'; |
| 36 | +$wgAutoloadClasses['WebDataTransclusionSource'] = $dir . 'WebDataTransclusionSource.php'; |
37 | 37 | |
38 | 38 | $wgHooks['ParserFirstCallInit'][] = 'efDataTransclusionSetHooks'; |
39 | 39 | |
40 | | -//TODO: Special Page for displaying all configured data sources |
| 40 | +// TODO: Special Page for displaying all configured data sources |
41 | 41 | |
42 | 42 | $wgDataTransclusionSources = array(); |
43 | 43 | |
44 | 44 | function efDataTransclusionSetHooks( $parser ) { |
45 | 45 | $parser->setHook( 'record' , 'DataTransclusionHandler::handleRecordTag' ); |
46 | | - $parser->setFunctionHook( 'record' , 'DataTransclusionHandler::handleRecordFunction' ); |
| 46 | + $parser->setFunctionHook( 'record' , 'DataTransclusionHandler::handleRecordFunction' ); |
47 | 47 | return true; |
48 | 48 | } |
Index: trunk/extensions/DataTransclusion/DataTransclusionSource.php |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | * @licence GNU General Public Licence 2.0 or later |
11 | 11 | */ |
12 | 12 | |
13 | | -if( !defined( 'MEDIAWIKI' ) ) { |
| 13 | +if ( !defined( 'MEDIAWIKI' ) ) { |
14 | 14 | echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); |
15 | 15 | die( 1 ); |
16 | 16 | } |
— | — | @@ -55,73 +55,73 @@ |
56 | 56 | * Lists may be given as arrays or strings with items separated by [,;|]. |
57 | 57 | */ |
58 | 58 | class DataTransclusionSource { |
59 | | - static function splitList( $s ) { |
60 | | - if ( $s === null || $s === false ) return $s; |
61 | | - if ( !is_string( $s ) ) return $s; |
62 | | - |
63 | | - $list = preg_split( '!\s*[,;|/]\s*!', $s ); |
64 | | - return $list; |
65 | | - } |
| 59 | + static function splitList( $s ) { |
| 60 | + if ( $s === null || $s === false ) return $s; |
| 61 | + if ( !is_string( $s ) ) return $s; |
| 62 | + |
| 63 | + $list = preg_split( '!\s*[,;|/]\s*!', $s ); |
| 64 | + return $list; |
| 65 | + } |
66 | 66 | |
67 | | - /** |
68 | | - * Initializes the DataTransclusionSource from the given parameter array. |
69 | | - * @param $spec associative array of options. See class-level documentation for details. |
70 | | - */ |
71 | | - function __construct( $spec ) { |
72 | | - $this->name = $spec[ 'name' ]; |
| 67 | + /** |
| 68 | + * Initializes the DataTransclusionSource from the given parameter array. |
| 69 | + * @param $spec associative array of options. See class-level documentation for details. |
| 70 | + */ |
| 71 | + function __construct( $spec ) { |
| 72 | + $this->name = $spec[ 'name' ]; |
73 | 73 | |
74 | | - $this->keyFields = self::splitList( $spec[ 'keyFields' ] ); |
| 74 | + $this->keyFields = self::splitList( $spec[ 'keyFields' ] ); |
75 | 75 | |
76 | | - if ( isset( $spec[ 'fieldNames' ] ) ) |
77 | | - $this->fieldNames = self::splitList( $spec[ 'fieldNames' ] ); |
78 | | - else |
79 | | - $this->fieldNames = $this->keyFields; |
| 76 | + if ( isset( $spec[ 'fieldNames' ] ) ) |
| 77 | + $this->fieldNames = self::splitList( $spec[ 'fieldNames' ] ); |
| 78 | + else |
| 79 | + $this->fieldNames = $this->keyFields; |
80 | 80 | |
81 | | - if ( !empty( $spec[ 'defaultKey' ] ) ) $this->defaultKey = $spec[ 'defaultKey' ]; |
82 | | - else $this->defaultKey = $this->keyFields[ 0 ]; |
| 81 | + if ( !empty( $spec[ 'defaultKey' ] ) ) $this->defaultKey = $spec[ 'defaultKey' ]; |
| 82 | + else $this->defaultKey = $this->keyFields[ 0 ]; |
83 | 83 | |
84 | | - if ( !empty( $spec[ 'cacheDuration' ] ) ) $this->cacheDuration = (int)$spec[ 'cacheDuration' ]; |
85 | | - else $this->cacheDuration = null; |
| 84 | + if ( !empty( $spec[ 'cacheDuration' ] ) ) $this->cacheDuration = (int)$spec[ 'cacheDuration' ]; |
| 85 | + else $this->cacheDuration = null; |
86 | 86 | |
87 | | - $this->sourceInfo = array(); |
| 87 | + $this->sourceInfo = array(); |
88 | 88 | |
89 | | - if ( !empty( $spec[ 'sourceInfo' ] ) ) { |
90 | | - foreach ( $spec[ 'sourceInfo' ] as $k => $v ) { |
91 | | - $this->sourceInfo[ $k ] = $v; |
| 89 | + if ( !empty( $spec[ 'sourceInfo' ] ) ) { |
| 90 | + foreach ( $spec[ 'sourceInfo' ] as $k => $v ) { |
| 91 | + $this->sourceInfo[ $k ] = $v; |
| 92 | + } |
| 93 | + } |
| 94 | + |
| 95 | + $this->sourceInfo[ 'name' ] = $this->name; // force this one |
| 96 | + $this->sourceInfo[ 'defaultKey' ] = $this->name; // force this one |
92 | 97 | } |
93 | | - } |
94 | 98 | |
95 | | - $this->sourceInfo[ 'name' ] = $this->name; //force this one |
96 | | - $this->sourceInfo[ 'defaultKey' ] = $this->name; //force this one |
97 | | - } |
| 99 | + public function getName() { |
| 100 | + return $this->name; |
| 101 | + } |
98 | 102 | |
99 | | - public function getName() { |
100 | | - return $this->name; |
101 | | - } |
| 103 | + public function getDefaultKey() { |
| 104 | + return $this->defaultKey; |
| 105 | + } |
102 | 106 | |
103 | | - public function getDefaultKey() { |
104 | | - return $this->defaultKey; |
105 | | - } |
| 107 | + public function getSourceInfo() { |
| 108 | + return $this->sourceInfo; |
| 109 | + } |
106 | 110 | |
107 | | - public function getSourceInfo() { |
108 | | - return $this->sourceInfo; |
109 | | - } |
| 111 | + public function getKeyFields() { |
| 112 | + return $this->keyFields; |
| 113 | + } |
110 | 114 | |
111 | | - public function getKeyFields() { |
112 | | - return $this->keyFields; |
113 | | - } |
| 115 | + public function getFieldNames() { |
| 116 | + return $this->fieldNames; |
| 117 | + } |
114 | 118 | |
115 | | - public function getFieldNames() { |
116 | | - return $this->fieldNames; |
117 | | - } |
| 119 | + public function getCacheDuration() { |
| 120 | + return $this->cacheDuration; |
| 121 | + } |
118 | 122 | |
119 | | - public function getCacheDuration() { |
120 | | - return $this->cacheDuration; |
121 | | - } |
122 | | - |
123 | | - public function fetchRecord( $key, $value ) { |
124 | | - throw new MWException( "override fetchRecord()" ); |
125 | | - } |
| 123 | + public function fetchRecord( $key, $value ) { |
| 124 | + throw new MWException( "override fetchRecord()" ); |
| 125 | + } |
126 | 126 | } |
127 | 127 | |
128 | 128 | /** |
— | — | @@ -130,57 +130,57 @@ |
131 | 131 | */ |
132 | 132 | class CachingDataTransclusionSource extends DataTransclusionSource { |
133 | 133 | |
134 | | - /** |
135 | | - * Initializes the CachingDataTransclusionSource |
136 | | - * |
137 | | - * @param $source a DataTransclusionSource instance for fetching data records. |
138 | | - * @param $cache an ObjectCache instance |
139 | | - * @param $duration number of seconds for which records may be cached |
140 | | - */ |
141 | | - function __construct( $source, $cache, $duration ) { |
142 | | - $this->source = $source; |
143 | | - $this->cache = $cache; |
144 | | - $this->duration = $duration; |
145 | | - } |
| 134 | + /** |
| 135 | + * Initializes the CachingDataTransclusionSource |
| 136 | + * |
| 137 | + * @param $source a DataTransclusionSource instance for fetching data records. |
| 138 | + * @param $cache an ObjectCache instance |
| 139 | + * @param $duration number of seconds for which records may be cached |
| 140 | + */ |
| 141 | + function __construct( $source, $cache, $duration ) { |
| 142 | + $this->source = $source; |
| 143 | + $this->cache = $cache; |
| 144 | + $this->duration = $duration; |
| 145 | + } |
146 | 146 | |
147 | | - public function getName() { |
148 | | - return $this->source->getName(); |
149 | | - } |
| 147 | + public function getName() { |
| 148 | + return $this->source->getName(); |
| 149 | + } |
150 | 150 | |
151 | | - public function getDefaultTemplate() { |
152 | | - return $this->source->getDefaultTemplate(); |
153 | | - } |
| 151 | + public function getDefaultTemplate() { |
| 152 | + return $this->source->getDefaultTemplate(); |
| 153 | + } |
154 | 154 | |
155 | | - public function getSourceInfo() { |
156 | | - return $this->source->getSourceInfo(); |
157 | | - } |
| 155 | + public function getSourceInfo() { |
| 156 | + return $this->source->getSourceInfo(); |
| 157 | + } |
158 | 158 | |
159 | | - public function getKeyFields() { |
160 | | - return $this->source->getKeyFields(); |
161 | | - } |
| 159 | + public function getKeyFields() { |
| 160 | + return $this->source->getKeyFields(); |
| 161 | + } |
162 | 162 | |
163 | | - public function getFieldNames() { |
164 | | - return $this->source->getFieldNames(); |
165 | | - } |
| 163 | + public function getFieldNames() { |
| 164 | + return $this->source->getFieldNames(); |
| 165 | + } |
166 | 166 | |
167 | | - public function getCacheDuration() { |
168 | | - return $this->source->getCacheDuration(); |
169 | | - } |
| 167 | + public function getCacheDuration() { |
| 168 | + return $this->source->getCacheDuration(); |
| 169 | + } |
170 | 170 | |
171 | | - public function fetchRecord( $key, $value ) { |
172 | | - global $wgDBname, $wgUser; |
| 171 | + public function fetchRecord( $key, $value ) { |
| 172 | + global $wgDBname, $wgUser; |
173 | 173 | |
174 | | - $cacheKey = "$wgDBname:DataTransclusion(" . $this->getName() . ":$key=$value)"; |
175 | | - |
176 | | - $rec = $this->cache->get( $cacheKey ); |
| 174 | + $cacheKey = "$wgDBname:DataTransclusion(" . $this->getName() . ":$key=$value)"; |
| 175 | + |
| 176 | + $rec = $this->cache->get( $cacheKey ); |
177 | 177 | |
178 | | - if ( !$rec ) { |
179 | | - $rec = $this->source->fetchRecord( $key, $value ); |
180 | | - if ( $rec ) $this->cache->set( $cacheKey, $rec, $this->getCacheDuration() ) ; //XXX: also cache negatives?? |
181 | | - } |
| 178 | + if ( !$rec ) { |
| 179 | + $rec = $this->source->fetchRecord( $key, $value ); |
| 180 | + if ( $rec ) $this->cache->set( $cacheKey, $rec, $this->getCacheDuration() ) ; // XXX: also cache negatives?? |
| 181 | + } |
182 | 182 | |
183 | | - return $rec; |
184 | | - } |
| 183 | + return $rec; |
| 184 | + } |
185 | 185 | } |
186 | 186 | |
187 | 187 | /** |
— | — | @@ -189,39 +189,39 @@ |
190 | 190 | */ |
191 | 191 | class FakeDataTransclusionSource extends DataTransclusionSource { |
192 | 192 | |
193 | | - /** |
194 | | - * Initializes the CachingDataTransclusionSource |
195 | | - * |
196 | | - * @param $spec an associative array of options. See class-level |
197 | | - * documentation of DataTransclusionSource for details. |
198 | | - * |
199 | | - * @param $data an array containing a list of records. Records from |
200 | | - * this list can be accessed via fetchRecord() using the key fields specified |
201 | | - * by $spec['keyFields']. If $data is not given, $spec['data'] must contain the data array. |
202 | | - */ |
203 | | - function __construct( $spec, $data = null ) { |
204 | | - DataTransclusionSource::__construct( $spec ); |
| 193 | + /** |
| 194 | + * Initializes the CachingDataTransclusionSource |
| 195 | + * |
| 196 | + * @param $spec an associative array of options. See class-level |
| 197 | + * documentation of DataTransclusionSource for details. |
| 198 | + * |
| 199 | + * @param $data an array containing a list of records. Records from |
| 200 | + * this list can be accessed via fetchRecord() using the key fields specified |
| 201 | + * by $spec['keyFields']. If $data is not given, $spec['data'] must contain the data array. |
| 202 | + */ |
| 203 | + function __construct( $spec, $data = null ) { |
| 204 | + DataTransclusionSource::__construct( $spec ); |
205 | 205 | |
206 | | - if ( $data === null ) $data = $spec[ 'data' ]; |
| 206 | + if ( $data === null ) $data = $spec[ 'data' ]; |
207 | 207 | |
208 | | - $this->lookup = array(); |
| 208 | + $this->lookup = array(); |
209 | 209 | |
210 | | - foreach ( $data as $rec ) { |
211 | | - $this->putRecord( $rec ); |
| 210 | + foreach ( $data as $rec ) { |
| 211 | + $this->putRecord( $rec ); |
| 212 | + } |
212 | 213 | } |
213 | | - } |
214 | 214 | |
215 | | - public function putRecord( $record ) { |
216 | | - $fields = $this->getKeyFields(); |
217 | | - foreach ( $fields as $f ) { |
218 | | - $k = $record[ $f ]; |
219 | | - |
220 | | - if ( !isset( $this->lookup[ $f ] ) ) $this->lookup[ $f ] = array(); |
221 | | - $this->lookup[ $f ][ $k ] = $record; |
| 215 | + public function putRecord( $record ) { |
| 216 | + $fields = $this->getKeyFields(); |
| 217 | + foreach ( $fields as $f ) { |
| 218 | + $k = $record[ $f ]; |
| 219 | + |
| 220 | + if ( !isset( $this->lookup[ $f ] ) ) $this->lookup[ $f ] = array(); |
| 221 | + $this->lookup[ $f ][ $k ] = $record; |
| 222 | + } |
222 | 223 | } |
223 | | - } |
224 | 224 | |
225 | | - public function fetchRecord( $key, $value ) { |
226 | | - return @$this->lookup[ $key ][ $value ]; |
227 | | - } |
| 225 | + public function fetchRecord( $key, $value ) { |
| 226 | + return @$this->lookup[ $key ][ $value ]; |
| 227 | + } |
228 | 228 | } |
Index: trunk/extensions/DataTransclusion/DBDataTransclusionSource.php |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | * @licence GNU General Public Licence 2.0 or later |
11 | 11 | */ |
12 | 12 | |
13 | | -if( !defined( 'MEDIAWIKI' ) ) { |
| 13 | +if ( !defined( 'MEDIAWIKI' ) ) { |
14 | 14 | echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); |
15 | 15 | die( 1 ); |
16 | 16 | } |
— | — | @@ -42,62 +42,62 @@ |
43 | 43 | */ |
44 | 44 | class DBDataTransclusionSource extends DataTransclusionSource { |
45 | 45 | |
46 | | - /** |
47 | | - * Initializes the DBDataTransclusionSource from the given parameter array. |
48 | | - * @param $spec associative array of options. See class-level documentation for details. |
49 | | - */ |
50 | | - function __construct( $spec ) { |
51 | | - if ( !isset( $spec[ 'keyFields' ] ) && isset( $spec[ 'keyTypes' ] ) ) $spec[ 'keyFields' ] = array_keys( $spec[ 'keyTypes' ] ); |
| 46 | + /** |
| 47 | + * Initializes the DBDataTransclusionSource from the given parameter array. |
| 48 | + * @param $spec associative array of options. See class-level documentation for details. |
| 49 | + */ |
| 50 | + function __construct( $spec ) { |
| 51 | + if ( !isset( $spec[ 'keyFields' ] ) && isset( $spec[ 'keyTypes' ] ) ) $spec[ 'keyFields' ] = array_keys( $spec[ 'keyTypes' ] ); |
52 | 52 | |
53 | | - DataTransclusionSource::__construct( $spec ); |
| 53 | + DataTransclusionSource::__construct( $spec ); |
54 | 54 | |
55 | | - $this->query = $spec[ 'query' ]; |
56 | | - $this->querySuffix = @$spec[ 'querySuffix' ]; |
| 55 | + $this->query = $spec[ 'query' ]; |
| 56 | + $this->querySuffix = @$spec[ 'querySuffix' ]; |
57 | 57 | |
58 | | - if ( isset( $spec[ 'keyTypes' ] ) ) $this->keyTypes = $spec[ 'keyTypes' ]; |
59 | | - else $this->keyTypes = null; |
60 | | - } |
| 58 | + if ( isset( $spec[ 'keyTypes' ] ) ) $this->keyTypes = $spec[ 'keyTypes' ]; |
| 59 | + else $this->keyTypes = null; |
| 60 | + } |
61 | 61 | |
62 | | - public function convertKey( $key, $value ) { |
63 | | - if ( !isset( $this->keyTypes[ $key ] ) ) return (string)$value; |
| 62 | + public function convertKey( $key, $value ) { |
| 63 | + if ( !isset( $this->keyTypes[ $key ] ) ) return (string)$value; |
64 | 64 | |
65 | | - $t = strtolower( trim( $this->keyTypes[ $key ] ) ); |
66 | | - |
67 | | - if ( $t == 'int' ) return (int)$value; |
68 | | - else if ( $t == 'decimal' || $t == 'float' ) return (float)$value; |
69 | | - else return (string)$value; |
70 | | - } |
| 65 | + $t = strtolower( trim( $this->keyTypes[ $key ] ) ); |
| 66 | + |
| 67 | + if ( $t == 'int' ) return (int)$value; |
| 68 | + else if ( $t == 'decimal' || $t == 'float' ) return (float)$value; |
| 69 | + else return (string)$value; |
| 70 | + } |
71 | 71 | |
72 | | - public function getQuery( $field, $value, $db = null ) { |
73 | | - if ( !$db ) $db = wfGetDB( DB_SLAVE ); |
74 | | - if ( !preg_match( '/\w+[\w\d]+/', $field ) ) return false; // redundant, but make extra sure we don't get anythign evil here //TESTME |
| 72 | + public function getQuery( $field, $value, $db = null ) { |
| 73 | + if ( !$db ) $db = wfGetDB( DB_SLAVE ); |
| 74 | + if ( !preg_match( '/\w+[\w\d]+/', $field ) ) return false; // redundant, but make extra sure we don't get anythign evil here //TESTME |
75 | 75 | |
76 | | - $value = $this->convertKey( $field, $value ); //TESTME |
| 76 | + $value = $this->convertKey( $field, $value ); // TESTME |
77 | 77 | |
78 | | - if ( is_string( $value ) ) $v = $db->addQuotes( $value ); //TESTME |
79 | | - else $v = $value; |
| 78 | + if ( is_string( $value ) ) $v = $db->addQuotes( $value ); // TESTME |
| 79 | + else $v = $value; |
80 | 80 | |
81 | | - $where = "( " . $field . " = " . $v . " )"; |
| 81 | + $where = "( " . $field . " = " . $v . " )"; |
82 | 82 | |
83 | | - if ( preg_match('/[)\s]WHERE[\s(]/is', $this->query ) ) $sql = $this->query . " AND " . $where; |
84 | | - else $sql = $this->query . " WHERE " . $where; |
| 83 | + if ( preg_match( '/[)\s]WHERE[\s(]/is', $this->query ) ) $sql = $this->query . " AND " . $where; |
| 84 | + else $sql = $this->query . " WHERE " . $where; |
85 | 85 | |
86 | | - if ( $this->querySuffix ) $sql = $sql . ' ' . $this->querySuffix; |
| 86 | + if ( $this->querySuffix ) $sql = $sql . ' ' . $this->querySuffix; |
87 | 87 | |
88 | | - return $sql; |
89 | | - } |
| 88 | + return $sql; |
| 89 | + } |
90 | 90 | |
91 | | - public function fetchRecord( $field, $value ) { |
92 | | - $db = wfGetDB( DB_SLAVE ); |
| 91 | + public function fetchRecord( $field, $value ) { |
| 92 | + $db = wfGetDB( DB_SLAVE ); |
93 | 93 | |
94 | | - $sql = $this->getQuery( $field, $value, $db ); |
| 94 | + $sql = $this->getQuery( $field, $value, $db ); |
95 | 95 | |
96 | | - $rs = $db->query( $sql, "DBDataTransclusionSource(" . $this->getName() . ")::fetchRecord" ); |
97 | | - if ( !$rs ) return false; |
| 96 | + $rs = $db->query( $sql, "DBDataTransclusionSource(" . $this->getName() . ")::fetchRecord" ); |
| 97 | + if ( !$rs ) return false; |
98 | 98 | |
99 | | - $rec = $db->fetchRow( $rs ); |
| 99 | + $rec = $db->fetchRow( $rs ); |
100 | 100 | |
101 | | - $db->freeResult( $rs ); |
102 | | - return $rec; |
103 | | - } |
| 101 | + $db->freeResult( $rs ); |
| 102 | + return $rec; |
| 103 | + } |
104 | 104 | } |