r67754 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r67753‎ | r67754 | r67755 >
Date:20:09, 9 June 2010
Author:daniel
Status:deferred
Tags:
Comment:
stylize
Modified paths:
  • /trunk/extensions/DataTransclusion/DBDataTransclusionSource.php (modified) (history)
  • /trunk/extensions/DataTransclusion/DataTransclusion.php (modified) (history)
  • /trunk/extensions/DataTransclusion/DataTransclusionHandler.php (modified) (history)
  • /trunk/extensions/DataTransclusion/DataTransclusionSource.php (modified) (history)
  • /trunk/extensions/DataTransclusion/WebDataTransclusionSource.php (modified) (history)
  • /trunk/extensions/DataTransclusion/tests/DataTransclusionTest.php (modified) (history)

Diff [purge]

Index: trunk/extensions/DataTransclusion/DataTransclusionHandler.php
@@ -9,281 +9,285 @@
1010 * @licence GNU General Public Licence 2.0 or later
1111 */
1212
13 -if( !defined( 'MEDIAWIKI' ) ) {
 13+if ( !defined( 'MEDIAWIKI' ) ) {
1414 echo( "Not a valid entry point.\n" );
1515 die( 1 );
1616 }
1717
1818 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;
2735 }
28 - else {
29 - $v = trim( $p );
30 - $k = $i;
31 - $i += 1;
32 - }
3336
34 - $argv[$k] = $v;
 37+ return $argv;
3538 }
3639
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
3947
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+ }
4752
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 );
5255
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+ }
5560
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 ) {
6262 $params = func_get_args();
6363 array_shift( $params ); // $key
6464 array_shift( $params ); // $asHTML
6565
66 - if ( $asHTML ) $mode = 'parseinline';
 66+ if ( $asHTML ) $mode = 'parseinline';
6767 else $mode = 'parsemag';
6868
6969 $m = wfMsgExt( $key, $mode, $params );
7070
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+ }
7474
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+ }
8181
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+ }
9494
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
9797
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'];
101101
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
104104
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+ }
110110
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+ }
118118
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
122122
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
126126
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)
129129
130 - $handler = new DataTransclusionHandler( $parser, $source, $t, $templateText );
 130+ $handler = new DataTransclusionHandler( $parser, $source, $t, $templateText );
131131
132 - $record = $handler->normalizeRecord( $record );
133 - $text = $handler->render( $record );
 132+ $record = $handler->normalizeRecord( $record );
 133+ $text = $handler->render( $record );
134134
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
136136
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+ }
142142
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+ }
150150
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+ }
157157
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+ */
165165
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 );
169169
170 - $piece = array();
 170+ $piece = array();
171171
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() . ":";
174174
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
178178
179 - $ret = $this->parser->braceSubstitution( $piece, $frame );
180 - $text = $ret[ 'text' ];
181 - */
 179+ $ret = $this->parser->braceSubstitution( $piece, $frame );
 180+ $text = $ret[ 'text' ];
 181+ */
182182
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 );
190191
191 - $text = $article->getContent();
192 - }
 192+ if ( !$article->exists() )
 193+ return false; // TESTME
193194
194 - $text = $this->parser->replaceVariables( $text, $record, true );
 195+ $text = $article->getContent();
 196+ }
195197
196 - return $text;
197 - }
 198+ $text = $this->parser->replaceVariables( $text, $record, true );
198199
199 - function normalizeRecord( $record ) {
200 - $rec = array();
 200+ return $text;
 201+ }
201202
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();
207205
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 = '';
210211
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+ }
218214
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+ }
221222
222 - protected static $sanitizerSubstitution = array(
223 - # '!&!' => '&amp;', #breaks URLs. not really needed when parsed as wiki-text...
224 - '!&(#?x?[\w\d]+);!' => '&amp;$1;',
225 - '!<!' => '&lt;',
226 - '!>!' => '&gt;',
227 - '!\[!' => '&#91;',
228 - '!\]!' => '&#93;',
229 - '!\{!' => '&#123;',
230 - '!\}!' => '&#125;',
231 - '!\'!' => '&apos;',
232 - '!\|!' => '&#124;',
233 - '!^\*!m' => '&#42;',
234 - '!^#!m' => '&#35;',
235 - '!^:!m' => '&#58;',
236 - '!^;!m' => '&#59;',
237 - '![\r\n]!' => ' ',
238 - '!^ !m' => '&#32;',
239 - '!^-!m' => '&#45;',
240 - '!^=!m' => '&#61;',
241 - );
 223+ return $rec;
 224+ }
242225
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+ # '!&!' => '&amp;', #breaks URLs. not really needed when parsed as wiki-text...
 228+ '!&(#?x?[\w\d]+);!' => '&amp;$1;',
 229+ '!<!' => '&lt;',
 230+ '!>!' => '&gt;',
 231+ '!\[!' => '&#91;',
 232+ '!\]!' => '&#93;',
 233+ '!\{!' => '&#123;',
 234+ '!\}!' => '&#125;',
 235+ '!\'!' => '&apos;',
 236+ '!\|!' => '&#124;',
 237+ '!^\*!m' => '&#42;',
 238+ '!^#!m' => '&#35;',
 239+ '!^:!m' => '&#58;',
 240+ '!^;!m' => '&#59;',
 241+ '![\r\n]!' => ' ',
 242+ '!^ !m' => '&#32;',
 243+ '!^-!m' => '&#45;',
 244+ '!^=!m' => '&#61;',
 245+ );
245246
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
248249
249 - $v = preg_replace( $find, $subst, $v );
250 - return $v;
251 - }
 250+ $find = array_keys( self::$sanitizerSubstitution );
 251+ $subst = array_values( self::$sanitizerSubstitution );
252252
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+ }
256256
257 - $source = $wgDataTransclusionSources[ $name ];
 257+ static function getDataSource( $name ) {
 258+ global $wgDataTransclusionSources;
 259+ if ( empty( $wgDataTransclusionSources[ $name ] ) ) return false;
258260
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 ];
262262
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;
264266
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." );
268268
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." );
270272
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;
276274
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
278285 }
279286
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+ }
282293
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 -
290294 }
Index: trunk/extensions/DataTransclusion/tests/DataTransclusionTest.php
@@ -11,7 +11,7 @@
1212 else $IP = $dir;
1313 }
1414
15 -if( isset( $GET_ ) ) {
 15+if ( isset( $GET_ ) ) {
1616 echo( "This file cannot be run from the web.\n" );
1717 die( 1 );
1818 }
@@ -21,7 +21,7 @@
2222 // requires PHPUnit 3.4
2323 require_once 'PHPUnit/Framework.php';
2424
25 -error_reporting(E_ALL);
 25+error_reporting( E_ALL );
2626
2727 class DataTransclusionTest extends PHPUnit_Framework_TestCase {
2828
@@ -47,23 +47,23 @@
4848 }
4949
5050 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>' );
5353
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>' );
5656
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>' );
5959
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>' );
6262
63 - $m = DataTransclusionHandler::errorMessage('datatransclusion-test-evil-html', true);
64 - $this->assertEquals( $m, '<span class="error datatransclusion-test-evil-html">some &lt;object&gt;evil&lt;/object&gt; html.</span>' );
 63+ $m = DataTransclusionHandler::errorMessage( 'datatransclusion-test-evil-html', true );
 64+ $this->assertEquals( $m, '<span class="error datatransclusion-test-evil-html">some &lt;object&gt;evil&lt;/object&gt; html.</span>' );
6565
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>' );
6868 }
6969
7070 function testSanitizeValue() {
@@ -95,10 +95,10 @@
9696 $args = array( "foo bar", "x=y", " ah = \"be\" ", "blubber bla" );
9797 $assoc = DataTransclusionhandler::buildAssociativeArguments( $args );
9898
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'] ) );
103103 $this->assertEquals( $assoc[1], 'foo bar' );
104104 $this->assertEquals( $assoc[2], 'blubber bla' );
105105 $this->assertEquals( $assoc['x'], 'y' );
@@ -109,8 +109,8 @@
110110 global $wgDataTransclusionSources;
111111
112112 $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' );
115115 $wgDataTransclusionSources[ 'FOO' ] = new FakeDataTransclusionSource( $spec, $data );
116116
117117 $src = DataTransclusionHandler::getDataSource( 'FOO' );
@@ -126,7 +126,7 @@
127127 $this->assertEquals( $rec['name'], 'bar' );
128128 $this->assertEquals( $rec['info'], 'test 2' );
129129
130 - ///////////////////////////////////////////////////////////////////////////////
 130+ // /////////////////////////////////////////////////////////////////////////////
131131 $spec[ 'class' ] = 'FakeDataTransclusionSource';
132132 $spec[ 'data' ] = $data;
133133
@@ -154,11 +154,11 @@
155155 global $wgParser;
156156 global $wgDataTransclusionSources;
157157
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',
161161 'data' => $data,
162 - 'keyFields' => 'name,id',
 162+ 'keyFields' => 'name,id',
163163 'fieldNames' => 'id,name,info',
164164 'defaultKey' => 'id'
165165 );
@@ -167,39 +167,39 @@
168168
169169 # failure mode: no source given
170170 $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 );
172172
173173 # failure mode: bad source given
174174 $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 );
176176
177177 # failure mode: bad source given (alternative)
178178 $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 );
180180
181181 # failure mode: illegal value for by= (must be a key field)
182182 $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 );
184184
185185 # failure mode: no key value specified
186186 $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 );
188188
189189 # failure mode: no template specified
190190 $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 );
192192
193193 # failure mode: illegal template specified
194194 $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 );
196196
197197 # failure mode: record can't be found for that key
198198 $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 );
200200
201201 # failure mode: unknown template
202202 $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 );
204204
205205 # success: render record
206206 $res = DataTransclusionHandler::handleRecordTransclusion( "3", array( 'source' => 'FOO', 'template' => 'Test' ), $wgParser, false, "'''{{{id}}}'''|{{{name}}}|{{{info}}}" );
@@ -211,15 +211,15 @@
212212
213213 # success: render record (as HTML)
214214 $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 &amp; here, no? why not?
 215+ $this->assertEquals( $res, '<b>3</b>|foo|test&X' ); // FIXME: & should have been escaped to &amp; here, no? why not?
216216 }
217217
218218 function testNormalizeRecord() {
219219 global $wgParser;
220220
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',
224224 'sourceInfo' => array( 'x' => 43, 'quux' => 'xyzzy' ),
225225 );
226226 $data[] = $rec = array( "name" => "foo", "id" => 3, "info" => '{{test}}=[[x]] 1&2 ', 'stuff' => 'bla bla bla' );
@@ -236,8 +236,8 @@
237237 $this->assertEquals( $rec['name'], 'foo' );
238238 $this->assertEquals( $rec['id'], '3' );
239239 $this->assertEquals( $rec['info'], '&#123;&#123;test&#125;&#125;=&#91;&#91;x&#93;&#93; 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'] ) );
242242 }
243243
244244 function testRender() {
@@ -245,7 +245,7 @@
246246
247247 $source = null;
248248 $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' );
250250 $template = "{{{id}}}|{{{name}}}|{{{info}}}";
251251
252252 $handler = new DataTransclusionHandler( $wgParser, $source, $title, $template );
@@ -257,15 +257,15 @@
258258 function testCachedFetchRecord() {
259259 global $wgDataTransclusionSources;
260260
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',
265265 'data' => $data,
266 - 'keyFields' => 'name,id',
 266+ 'keyFields' => 'name,id',
267267 'fieldNames' => 'id,name,info',
268 - 'cacheDuration' => 2,
269 - 'cache' => new HashBagOStuff(),
 268+ 'cacheDuration' => 2,
 269+ 'cache' => new HashBagOStuff(),
270270 );
271271
272272 $wgDataTransclusionSources[ 'FOO' ] = $spec;
@@ -273,75 +273,75 @@
274274 $src = DataTransclusionHandler::getDataSource( 'FOO' );
275275 $this->assertTrue( $src instanceof CachingDataTransclusionSource );
276276
277 - //get original version
 277+ // get original version
278278 $rec = $src->fetchRecord( 'id', 3 );
279279 $this->assertEquals( $rec['id'], 3 );
280280 $this->assertEquals( $rec['name'], 'foo' );
281281 $this->assertEquals( $rec['info'], 'test 1' );
282282
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' );
285285 $src->source->putRecord( $rec );
286286
287 - //fetch record - should be the cached version
 287+ // fetch record - should be the cached version
288288 $rec = $src->fetchRecord( 'id', 3 );
289289 $this->assertEquals( $rec['info'], 'test 1' );
290290
291 - sleep(3);
 291+ sleep( 3 );
292292
293 - //fetch record - cached version should have expired
 293+ // fetch record - cached version should have expired
294294 $rec = $src->fetchRecord( 'id', 3 );
295295 $this->assertEquals( $rec['info'], 'test X' );
296296 }
297297
298298 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+ );
305305
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 );
312312
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 );
315315 }
316316
317317 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+ );
326326
327 - $source = new WebDataTransclusionSource( $spec );
 327+ $source = new WebDataTransclusionSource( $spec );
328328
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' );
331331
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+ ) );
339339
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' ) );
343343
344 - $this->assertEquals( $err, 'test error' );
345 - $this->assertEquals( $rec['id'], 3 );
 344+ $this->assertEquals( $err, 'test error' );
 345+ $this->assertEquals( $rec['id'], 3 );
346346 }
347347 }
348348
Index: trunk/extensions/DataTransclusion/WebDataTransclusionSource.php
@@ -9,7 +9,7 @@
1010 * @licence GNU General Public Licence 2.0 or later
1111 */
1212
13 -if( !defined( 'MEDIAWIKI' ) ) {
 13+if ( !defined( 'MEDIAWIKI' ) ) {
1414 echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
1515 die( 1 );
1616 }
@@ -50,92 +50,92 @@
5151 */
5252 class WebDataTransclusionSource extends DataTransclusionSource {
5353
54 - function __construct( $spec ) {
55 - DataTransclusionSource::__construct( $spec );
 54+ function __construct( $spec ) {
 55+ DataTransclusionSource::__construct( $spec );
5656
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' ];
6363
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+ }
6868
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?
7272
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?
7575
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?
8178
82 - return $rec;
83 - }
 79+ $rec = $this->extractRecord( $data ); // TESTME
 80+ if ( !$rec ) return false; // TODO: log error?
8481
85 - public function getRecordURL( $field, $value ) {
86 - $u = $this->url;
 82+ return $rec;
 83+ }
8784
88 - if ( strpos( $u, '?' ) === false ) $u .= '?';
89 - else $u .= '&';
 85+ public function getRecordURL( $field, $value ) {
 86+ $u = $this->url;
9087
91 - $u .= $field;
92 - $u .= '=';
93 - $u .= urlencode( $value );
 88+ if ( strpos( $u, '?' ) === false ) $u .= '?';
 89+ else $u .= '&';
9490
95 - return $u;
96 - }
 91+ $u .= $field;
 92+ $u .= '=';
 93+ $u .= urlencode( $value );
9794
98 - public function loadRecordData( $field, $value ) {
99 - $u = $this->getRecordURL( $field, $value );
 95+ return $u;
 96+ }
10097
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 );
104100
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+ }
109104
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
112109
113 - public function extractError( $data ) {
114 - return $this->extractField( $data, $this->errorPath );
115 - }
 110+ return false;
 111+ }
116112
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+ }
120116
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+ }
124120
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 ];
127124
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 );
135127
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+ }
139135
140 - return $data;
141 - }
 136+ if ( !isset( $data[ $p ] ) ) return false;
 137+ $data = $data[ $p ];
 138+ }
 139+
 140+ return $data;
 141+ }
142142 }
Index: trunk/extensions/DataTransclusion/DataTransclusion.php
@@ -9,7 +9,7 @@
1010 * @licence GNU General Public Licence 2.0 or later
1111 */
1212
13 -if( !defined( 'MEDIAWIKI' ) ) {
 13+if ( !defined( 'MEDIAWIKI' ) ) {
1414 echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
1515 die( 1 );
1616 }
@@ -22,26 +22,26 @@
2323 'descriptionmsg' => 'datatransclusion-desc',
2424 );
2525
26 -$dir = dirname(__FILE__) . '/';
 26+$dir = dirname( __FILE__ ) . '/';
2727 $wgExtensionMessagesFiles['DataTransclusion'] = $dir . 'DataTransclusion.i18n.php';
2828 $wgExtensionMessagesFiles['DataTransclusionMagic'] = $dir . 'DataTransclusion.i18n.magic.php';
2929
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';
3737
3838 $wgHooks['ParserFirstCallInit'][] = 'efDataTransclusionSetHooks';
3939
40 -//TODO: Special Page for displaying all configured data sources
 40+// TODO: Special Page for displaying all configured data sources
4141
4242 $wgDataTransclusionSources = array();
4343
4444 function efDataTransclusionSetHooks( $parser ) {
4545 $parser->setHook( 'record' , 'DataTransclusionHandler::handleRecordTag' );
46 - $parser->setFunctionHook( 'record' , 'DataTransclusionHandler::handleRecordFunction' );
 46+ $parser->setFunctionHook( 'record' , 'DataTransclusionHandler::handleRecordFunction' );
4747 return true;
4848 }
Index: trunk/extensions/DataTransclusion/DataTransclusionSource.php
@@ -9,7 +9,7 @@
1010 * @licence GNU General Public Licence 2.0 or later
1111 */
1212
13 -if( !defined( 'MEDIAWIKI' ) ) {
 13+if ( !defined( 'MEDIAWIKI' ) ) {
1414 echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
1515 die( 1 );
1616 }
@@ -55,73 +55,73 @@
5656 * Lists may be given as arrays or strings with items separated by [,;|].
5757 */
5858 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+ }
6666
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' ];
7373
74 - $this->keyFields = self::splitList( $spec[ 'keyFields' ] );
 74+ $this->keyFields = self::splitList( $spec[ 'keyFields' ] );
7575
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;
8080
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 ];
8383
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;
8686
87 - $this->sourceInfo = array();
 87+ $this->sourceInfo = array();
8888
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
9297 }
93 - }
9498
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+ }
98102
99 - public function getName() {
100 - return $this->name;
101 - }
 103+ public function getDefaultKey() {
 104+ return $this->defaultKey;
 105+ }
102106
103 - public function getDefaultKey() {
104 - return $this->defaultKey;
105 - }
 107+ public function getSourceInfo() {
 108+ return $this->sourceInfo;
 109+ }
106110
107 - public function getSourceInfo() {
108 - return $this->sourceInfo;
109 - }
 111+ public function getKeyFields() {
 112+ return $this->keyFields;
 113+ }
110114
111 - public function getKeyFields() {
112 - return $this->keyFields;
113 - }
 115+ public function getFieldNames() {
 116+ return $this->fieldNames;
 117+ }
114118
115 - public function getFieldNames() {
116 - return $this->fieldNames;
117 - }
 119+ public function getCacheDuration() {
 120+ return $this->cacheDuration;
 121+ }
118122
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+ }
126126 }
127127
128128 /**
@@ -130,57 +130,57 @@
131131 */
132132 class CachingDataTransclusionSource extends DataTransclusionSource {
133133
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+ }
146146
147 - public function getName() {
148 - return $this->source->getName();
149 - }
 147+ public function getName() {
 148+ return $this->source->getName();
 149+ }
150150
151 - public function getDefaultTemplate() {
152 - return $this->source->getDefaultTemplate();
153 - }
 151+ public function getDefaultTemplate() {
 152+ return $this->source->getDefaultTemplate();
 153+ }
154154
155 - public function getSourceInfo() {
156 - return $this->source->getSourceInfo();
157 - }
 155+ public function getSourceInfo() {
 156+ return $this->source->getSourceInfo();
 157+ }
158158
159 - public function getKeyFields() {
160 - return $this->source->getKeyFields();
161 - }
 159+ public function getKeyFields() {
 160+ return $this->source->getKeyFields();
 161+ }
162162
163 - public function getFieldNames() {
164 - return $this->source->getFieldNames();
165 - }
 163+ public function getFieldNames() {
 164+ return $this->source->getFieldNames();
 165+ }
166166
167 - public function getCacheDuration() {
168 - return $this->source->getCacheDuration();
169 - }
 167+ public function getCacheDuration() {
 168+ return $this->source->getCacheDuration();
 169+ }
170170
171 - public function fetchRecord( $key, $value ) {
172 - global $wgDBname, $wgUser;
 171+ public function fetchRecord( $key, $value ) {
 172+ global $wgDBname, $wgUser;
173173
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 );
177177
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+ }
182182
183 - return $rec;
184 - }
 183+ return $rec;
 184+ }
185185 }
186186
187187 /**
@@ -189,39 +189,39 @@
190190 */
191191 class FakeDataTransclusionSource extends DataTransclusionSource {
192192
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 );
205205
206 - if ( $data === null ) $data = $spec[ 'data' ];
 206+ if ( $data === null ) $data = $spec[ 'data' ];
207207
208 - $this->lookup = array();
 208+ $this->lookup = array();
209209
210 - foreach ( $data as $rec ) {
211 - $this->putRecord( $rec );
 210+ foreach ( $data as $rec ) {
 211+ $this->putRecord( $rec );
 212+ }
212213 }
213 - }
214214
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+ }
222223 }
223 - }
224224
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+ }
228228 }
Index: trunk/extensions/DataTransclusion/DBDataTransclusionSource.php
@@ -9,7 +9,7 @@
1010 * @licence GNU General Public Licence 2.0 or later
1111 */
1212
13 -if( !defined( 'MEDIAWIKI' ) ) {
 13+if ( !defined( 'MEDIAWIKI' ) ) {
1414 echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
1515 die( 1 );
1616 }
@@ -42,62 +42,62 @@
4343 */
4444 class DBDataTransclusionSource extends DataTransclusionSource {
4545
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' ] );
5252
53 - DataTransclusionSource::__construct( $spec );
 53+ DataTransclusionSource::__construct( $spec );
5454
55 - $this->query = $spec[ 'query' ];
56 - $this->querySuffix = @$spec[ 'querySuffix' ];
 55+ $this->query = $spec[ 'query' ];
 56+ $this->querySuffix = @$spec[ 'querySuffix' ];
5757
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+ }
6161
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;
6464
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+ }
7171
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
7575
76 - $value = $this->convertKey( $field, $value ); //TESTME
 76+ $value = $this->convertKey( $field, $value ); // TESTME
7777
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;
8080
81 - $where = "( " . $field . " = " . $v . " )";
 81+ $where = "( " . $field . " = " . $v . " )";
8282
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;
8585
86 - if ( $this->querySuffix ) $sql = $sql . ' ' . $this->querySuffix;
 86+ if ( $this->querySuffix ) $sql = $sql . ' ' . $this->querySuffix;
8787
88 - return $sql;
89 - }
 88+ return $sql;
 89+ }
9090
91 - public function fetchRecord( $field, $value ) {
92 - $db = wfGetDB( DB_SLAVE );
 91+ public function fetchRecord( $field, $value ) {
 92+ $db = wfGetDB( DB_SLAVE );
9393
94 - $sql = $this->getQuery( $field, $value, $db );
 94+ $sql = $this->getQuery( $field, $value, $db );
9595
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;
9898
99 - $rec = $db->fetchRow( $rs );
 99+ $rec = $db->fetchRow( $rs );
100100
101 - $db->freeResult( $rs );
102 - return $rec;
103 - }
 101+ $db->freeResult( $rs );
 102+ return $rec;
 103+ }
104104 }

Status & tagging log