MediaWiki r58681 - Code Review

Jump to: navigation, search
Repository:MediaWiki
Revision:r58680‎ | r58681 (on ViewVC)‎ | r58682 >
Date:20:57, 6 November 2009
Author:shinjiman
Status:deferred
Tags:
Comment:
Update the DPL codebase to 1.8.9.
code based on Gero aka Algorithmix
Modified paths:

Diff [purge]

Index: trunk/extensions/DynamicPageList/DynamicPageList.php
@@ -59,7 +59,7 @@
6060
6161 $wgHooks['LanguageGetMagic'][] = 'ExtDynamicPageList__languageGetMagic';
6262
63 -$DPLVersion = '1.8.8';
 63+$DPLVersion = '1.8.9';
6464
6565 $wgExtensionCredits['parserhook'][] = array(
6666 'path' => __FILE__,
Index: trunk/extensions/DynamicPageList/DPL.php
@@ -199,6 +199,7 @@
200200 $sTag = str_replace('%NAMESPACE%',$this->nameSpaces[$article->mNamespace],$sTag);
201201 $sTag = str_replace('%IMAGE%',$imageUrl,$sTag);
202202 $sTag = str_replace('%EXTERNALLINK%',$article->mExternalLink,$sTag);
 203+ $sTag = str_replace('%EDITSUMMARY%',$article->mComment,$sTag);
203204
204205 $title = $article->mTitle->getText();
205206 if (strpos($title,'%TITLE%')>=0) {
@@ -233,16 +234,18 @@
234235 }
235236 }
236237 if ($article->mImageSelTitle!= '') $sTag = str_replace('%IMAGESEL%',str_replace('_',' ',$article->mImageSelTitle),$sTag);
237 - if (!empty($article->mCategoryLinks) ) {
238 - $sTag = str_replace('%'.'CATLIST%',implode(', ', $article->mCategoryLinks),$sTag);
239 - $sTag = str_replace('%'.'CATBULLETS%','* '.implode("\n* ", $article->mCategoryLinks),$sTag);
240 - $sTag = str_replace('%'.'CATNAMES%',implode(', ', $article->mCategoryTexts),$sTag);
241 - }
242 - else {
243 - $sTag = str_replace('%'.'CATLIST%','',$sTag);
244 - $sTag = str_replace('%'.'CATBULLETS%','',$sTag);
245 - $sTag = str_replace('%'.'CATNAMES%','',$sTag);
246 - }
 238+ if (strpos($sTag,"%CAT")>=0 ) {
 239+ if (!empty($article->mCategoryLinks) ) {
 240+ $sTag = str_replace('%'.'CATLIST%',implode(', ', $article->mCategoryLinks),$sTag);
 241+ $sTag = str_replace('%'.'CATBULLETS%','* '.implode("\n* ", $article->mCategoryLinks),$sTag);
 242+ $sTag = str_replace('%'.'CATNAMES%',implode(', ', $article->mCategoryTexts),$sTag);
 243+ }
 244+ else {
 245+ $sTag = str_replace('%'.'CATLIST%','',$sTag);
 246+ $sTag = str_replace('%'.'CATBULLETS%','',$sTag);
 247+ $sTag = str_replace('%'.'CATNAMES%','',$sTag);
 248+ }
 249+ }
247250 return $sTag;
248251 }
249252
@@ -316,7 +319,7 @@
317320 if (array_key_exists('0',$mode->sSectionTags)){
318321 $incwiki .= $this->substTagParm($mode->sSectionTags[0], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen);
319322 $pieces = array(0=>$text);
320 - $this->formatSingleItems($pieces, 0);
 323+ $this->formatSingleItems($pieces, 0, $article);
321324 $incwiki .= $pieces[0];
322325 }
323326 else $incwiki .= $text;
@@ -342,17 +345,27 @@
343346 if ($sSecLabel[0] == '%') $sSecLabel = '#'.$sSecLabel;
344347
345348 $maxlen=-1;
346 - if($sSecLabel[0] != '{') {
 349+ if($sSecLabel=='-') {
 350+ // '-' is used as a dummy parameter which will produce no output
 351+ // if maxlen was 0 we suppress all output; note that for matching we used the full text
 352+ $secPieces=array('');
 353+ $this->formatSingleItems($secPieces,$s,$article);
 354+
 355+ } else if($sSecLabel[0] != '{') {
347356 $limpos = strpos($sSecLabel,'[');
348357 $cutLink='default';
349 - $skipPattern='';
 358+ $skipPattern=array();
350359 if ($limpos>0 && $sSecLabel[strlen($sSecLabel)-1]==']') {
351 - $fmtSec=explode('~',substr($sSecLabel,$limpos+1,strlen($sSecLabel)-$limpos-2),2);
352 - $cutInfo=explode(" ",$fmtSec[0],2);
 360+ // regular expressions which define a skip pattern may precede the text
 361+ $fmtSec=explode('~',substr($sSecLabel,$limpos+1,strlen($sSecLabel)-$limpos-2));
353362 $sSecLabel=substr($sSecLabel,0,$limpos);
 363+ $cutInfo=explode(" ",$fmtSec[count($fmtSec)-1],2);
354364 $maxlen=intval($cutInfo[0]);
355 - if (isset($cutInfo[1])) $cutLink=$cutInfo[1];
356 - if (isset($fmtSec[1])) $skipPattern=$fmtSec[1];
 365+ if (array_key_exists('1',$cutInfo)) $cutLink=$cutInfo[1];
 366+ foreach( $fmtSec as $skipKey => $skipPat) {
 367+ if ($skipKey==count($fmtSec)-1) continue;
 368+ $skipPattern[]=$skipPat;
 369+ }
357370 }
358371 if ($maxlen<0) $maxlen = -1; // without valid limit include whole section
359372 }
@@ -365,13 +378,16 @@
366379 $mustNotMatch = $this->mIncSecLabelsNotMatch[$s];
367380 else $mustNotMatch = '';
368381
369 - // if chapters are selected by number we get the heading from DPLInclude::includeHeading
 382+ // if chapters are selected by number, text or regexp we get the heading from DPLInclude::includeHeading
370383 $sectionHeading[0]='';
371 - if($sSecLabel[0] == '#') {
 384+ if($sSecLabel=='-') {
 385+ $secPiece[$s] = $secPieces[0];
 386+
 387+ } else if($sSecLabel[0] == '#' || $sSecLabel[0] == '@') {
372388 $sectionHeading[0]=substr($sSecLabel,1);
373389 // Uses DPLInclude::includeHeading() from LabeledSectionTransclusion extension to include headings from the page
374390 $secPieces = DPLInclude::includeHeading($this->mParser, $article->mTitle->getPrefixedText(), substr($sSecLabel, 1),'',
375 - $sectionHeading,false,$maxlen,$cutLink,$bIncludeTrim,$skipPattern);
 391+ $sectionHeading,false,$maxlen,$cutLink,$bIncludeTrim,$skipPattern);
376392 if ($mustMatch!='' || $mustNotMatch!='') {
377393 $secPiecesTmp = $secPieces;
378394 $offset=0;
@@ -383,8 +399,10 @@
384400 }
385401 }
386402 }
 403+ // if maxlen was 0 we suppress all output; note that for matching we used the full text
 404+ if ($maxlen==0) $secPieces=array('');
387405
388 - $this->formatSingleItems($secPieces,$s);
 406+ $this->formatSingleItems($secPieces,$s,$article);
389407 if (!array_key_exists(0,$secPieces)) {
390408 // avoid matching against a non-existing array element
391409 // and skip the article if there was a match condition
@@ -408,11 +426,17 @@
409427
410428 } else if($sSecLabel[0] == '{') {
411429 // Uses DPLInclude::includeTemplate() from LabeledSectionTransclusion extension to include templates from the page
 430+ // primary syntax {template}suffix
412431 $template1 = trim(substr($sSecLabel,1,strpos($sSecLabel,'}')-1));
413432 $template2 = trim(str_replace('}','',substr($sSecLabel,1)));
 433+ // alternate syntax: {template|surrogate}
 434+ if ($template2==$template1 && strpos($template1,'|')>0) {
 435+ $template1=preg_replace('/\|.*/' ,'',$template1);
 436+ $template2=preg_replace('/^.+\|/','',$template2);
 437+ }
414438 $secPieces = DPLInclude::includeTemplate($this->mParser, $this, $s, $article, $template1,
415439 $template2, $template2.$defaultTemplateSuffix,$mustMatch,
416 - $mustNotMatch,$this->mIncParsed,$iTitleMaxLen);
 440+ $mustNotMatch,$this->mIncParsed,$iTitleMaxLen,implode(', ', $article->mCategoryLinks));
417441 $secPiece[$s] = implode(isset($mode->aMultiSecSeparators[$s])?
418442 $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen):'',$secPieces);
419443 if ($mode->iDominantSection>=0 && $s==$mode->iDominantSection && count($secPieces)>1) $dominantPieces=$secPieces;
@@ -502,9 +526,14 @@
503527 $nv = $this->msgExt( 'nviews', array( 'parsemag', 'escape'), $wgLang->formatNum( $article->mCounter ) );
504528 $rBody .= ' ' . $wgContLang->getDirMark() . '(' . $nv . ')';
505529 }
506 - if($article->mUserLink != '') $rBody .= ' . . [[User:' . $article->mUser .'|'.$article->mUser.']]';
 530+ if($article->mUserLink != '') {
 531+ $rBody .= ' . . [[User:' . $article->mUser .'|'.$article->mUser.']]';
 532+ if($article->mComment != '')$rBody .= ' { '.$article->mComment.' }';
 533+ }
507534 if($article->mContributor != '')$rBody .= ' . . [[User:' . $article->mContributor .'|'.$article->mContributor." $article->mContrib]]";
508535
 536+
 537+
509538 if( !empty($article->mCategoryLinks) ) $rBody .= ' . . <SMALL>' . wfMsg('categories') . ': ' . implode(' | ', $article->mCategoryLinks) . '</SMALL>';
510539 if( $this->mAddExternalLink && $article->mExternalLink!= '') $rBody .= ' &rarr; ' . $article->mExternalLink;
511540 }
@@ -596,6 +625,7 @@
597626 $action='';
598627 $hidden=array();
599628 $legendPage='';
 629+ $instructionPage='';
600630 $table='';
601631 $fieldFormat='';
602632
@@ -637,26 +667,27 @@
638668 }
639669 }
640670 }
641 - if ($cmd[0] == 'value') $value[$nr] = $arg;
642 - if ($cmd[0] == 'format') $format[$nr] = $arg;
643 - if ($cmd[0] == 'tooltip') $tooltip[$nr]=$arg;
644 - if ($cmd[0] == 'optional') $optional[$nr]=true;
645 - if ($cmd[0] == 'afterparm') $afterparm[$nr] = array($arg);
646 - if ($cmd[0] == 'legend') $legendPage = $arg;
647 - if ($cmd[0] == 'table') $table = $arg;
648 - if ($cmd[0] == 'field') $fieldFormat = $arg;
 671+ if ($cmd[0] == 'value') $value[$nr] = $arg;
 672+ if ($cmd[0] == 'format') $format[$nr] = $arg;
 673+ if ($cmd[0] == 'tooltip') $tooltip[$nr]=$arg;
 674+ if ($cmd[0] == 'optional') $optional[$nr]=true;
 675+ if ($cmd[0] == 'afterparm') $afterparm[$nr] = array($arg);
 676+ if ($cmd[0] == 'legend') $legendPage = $arg;
 677+ if ($cmd[0] == 'instruction') $instructionPage = $arg;
 678+ if ($cmd[0] == 'table') $table = $arg;
 679+ if ($cmd[0] == 'field') $fieldFormat = $arg;
649680
650 - if ($cmd[0] == 'replace') $replaceThis=$arg;
651 - if ($cmd[0] == 'by') $replacement=$arg;
 681+ if ($cmd[0] == 'replace') $replaceThis=$arg;
 682+ if ($cmd[0] == 'by') $replacement=$arg;
652683
653 - if ($cmd[0] == 'editform') $editForm=$arg;
654 - if ($cmd[0] == 'action') $action=$arg;
655 - if ($cmd[0] == 'hidden') $hidden[]=$arg;
656 - if ($cmd[0] == 'preview') $preview[]=$arg;
657 - if ($cmd[0] == 'save') $save[]=$arg;
 684+ if ($cmd[0] == 'editform') $editForm=$arg;
 685+ if ($cmd[0] == 'action') $action=$arg;
 686+ if ($cmd[0] == 'hidden') $hidden[]=$arg;
 687+ if ($cmd[0] == 'preview') $preview[]=$arg;
 688+ if ($cmd[0] == 'save') $save[]=$arg;
658689
659 - if ($cmd[0] == 'summary') $summary=$arg;
660 - if ($cmd[0] == 'exec') $exec=$arg; // desired action (set or edit or preview)
 690+ if ($cmd[0] == 'summary') $summary=$arg;
 691+ if ($cmd[0] == 'exec') $exec=$arg; // desired action (set or edit or preview)
661692 }
662693
663694 if ($summary=='') {
@@ -699,6 +730,15 @@
700731 $legendText = preg_replace('/^.*?\<section\s+begin\s*=\s*legend\s*\/\>/s','',$legendText);
701732 $legendText = preg_replace('/\<section\s+end\s*=\s*legend\s*\/\>.*/s','',$legendText);
702733 }
 734+ $instructionText='';
 735+ $instructions=array();
 736+ if ($instructionPage!='') {
 737+ $instructionTitle='';
 738+ global $wgParser, $wgUser;
 739+ $parser = clone $wgParser;
 740+ DPLInclude::text($parser, $instructionPage, $instructionTitle, $instructionText);
 741+ $instructions = $this->getTemplateParmValues($instructionText,'Template field');
 742+ }
703743 // construct an edit form containing all template invocations
704744 $form="<html><form method=post action=\"$action\" $editForm>\n";
705745 foreach ($tpv as $call => $tplValues) {
@@ -706,6 +746,15 @@
707747 foreach ($parameter as $nr => $parm) {
708748 // try to extract legend from the docs of the template
709749 $myToolTip=''; if (array_key_exists($nr,$tooltip)) $myToolTip = $tooltip[$nr];
 750+ $myInstruction = '';
 751+ $myType='';
 752+ foreach($instructions as $instruct) {
 753+ if (array_key_exists('field',$instruct) && $instruct['field']==$parm) {
 754+ if (array_key_exists('doc',$instruct)) $myInstruction = $instruct['doc'];
 755+ if (array_key_exists('type',$instruct)) $myType = $instruct['type'];
 756+ break;
 757+ }
 758+ }
710759 $myFormat='' ; if (array_key_exists($nr,$format)) $myFormat = $format[$nr];
711760 $myOptional=array_key_exists($nr,$optional);
712761 if ($legendText !='' && $myToolTip=='') {
@@ -716,8 +765,9 @@
717766 $myToolTip=preg_replace('/\<section\s+end\s*=\s*'.preg_quote($parm,'/').'\s*\/\>.*/s','',$myToolTip);
718767 }
719768 }
720 - $myValue=''; if (array_key_exists($parm,$tpv[$call])) $myValue=$tpv[$call][$parm];
721 - $form .= $this->editTemplateCall($text,$template,$call,$parm,$myValue,$myFormat,$myToolTip,$myOptional,$fieldFormat);
 769+ $myValue='';
 770+ if (array_key_exists($parm,$tpv[$call])) $myValue=$tpv[$call][$parm];
 771+ $form .= $this->editTemplateCall($text,$template,$call,$parm,$myType,$myValue,$myFormat,$myToolTip,$myInstruction,$myOptional,$fieldFormat);
722772 }
723773 $form .= "</table>\n<br/><br/>";
724774 }
@@ -800,7 +850,7 @@
801851 }
802852 }
803853
804 - function editTemplateCall($text,$template,$call,$parameter,$value,$format,$tooltip,$optional,$fieldFormat) {
 854+ function editTemplateCall($text,$template,$call,$parameter,$type,$value,$format,$legend,$instruction,$optional,$fieldFormat) {
805855 $matches=array();
806856 $nlCount = preg_match_all('/\n/',$value,$matches);
807857 if ($nlCount>0) $rows= $nlCount+1;
@@ -809,9 +859,11 @@
810860 $cols=50;
811861 if (preg_match('/cols\s*=/',$format)<=0) $format.= " cols=$cols";
812862 $textArea = "<textarea name=\"".urlencode($call.'_'.$parameter)."\" $format/>".htmlspecialchars($value)."</textarea>";
813 - return str_replace('%NAME%', htmlspecialchars(str_replace('_',' ',$parameter)),
 863+ return str_replace('%NAME%', htmlspecialchars(str_replace('_',' ',$parameter)),
 864+ str_replace('%TYPE%', $type,
814865 str_replace('%INPUT%', $textArea,
815 - str_replace('%LEGEND%', "</html>".htmlspecialchars($tooltip)."<html>",$fieldFormat)));
 866+ str_replace('%LEGEND%', "</html>".htmlspecialchars($legend)."<html>",
 867+ str_replace('%INSTRUCTION%', "</html>".htmlspecialchars($instruction)."<html>",$fieldFormat)))));
816868 }
817869
818870 /**
@@ -819,6 +871,7 @@
820872 */
821873 function getTemplateParmValues($text,$template) {
822874 $matches=array();
 875+// $noMatches = preg_match_all('/\{\{\s*'.preg_quote($template,'/').'\s*((\<!--).*?(--\>)\s*)*[|}]/i',$text,$matches,PREG_OFFSET_CAPTURE);
823876 $noMatches = preg_match_all('/\{\{\s*'.preg_quote($template,'/').'\s*[|}]/i',$text,$matches,PREG_OFFSET_CAPTURE);
824877 if ($noMatches<=0) return '';
825878 $textLen = strlen($text);
@@ -829,7 +882,6 @@
830883 foreach($matchA as $matchB) {
831884 $match=$matchB[0];
832885 $start=$matchB[1];
833 -
834886 $tval[++$call]=array();
835887 $nr=0; // number of parameter if no name given
836888 $parmValue='';
@@ -848,6 +900,7 @@
849901 // parameter (name or value) found
850902 if ($parmName=='') $tval[$call][++$nr] = trim($parm);
851903 else $tval[$call][$parmName] = trim($parmValue);
 904+// die ("cbrackets=$cbrackets, parmName=<pre>$parm</pre>, parmValue=<pre>$parmValue</pre>");
852905 $parmName='';
853906 $parmValue='';
854907 $parm='';
@@ -866,6 +919,7 @@
867920 }
868921 }
869922 }
 923+// die ("match=$match, start=$start,\ntextstart=<pre>".substr($text,$start+strlen($match), $textLen)."<pre>,\n,tval=".$tval[0].",\ntext=<pre>$text</pre>");
870924 return $tval;
871925 }
872926
@@ -1066,7 +1120,7 @@
10671121 }
10681122
10691123 //format one single item of an entry in the output list (i.e. one occurence of one item from the include parameter)
1070 - function formatSingleItems(&$pieces, $s) {
 1124+ function formatSingleItems(&$pieces, $s, $article) {
10711125 $firstCall=true;
10721126 foreach ($pieces as $key => $val) {
10731127 if (array_key_exists($s,$this->mTableRow)) {
@@ -1083,6 +1137,20 @@
10841138 $pieces[$key] = str_replace('%%',$val,substr($this->mTableRow[$s],$n+1));
10851139 }
10861140 }
 1141+ $pieces[$key] = str_replace('%IMAGE%',self::imageWithPath($val),$pieces[$key]);
 1142+ $pieces[$key] = str_replace('%PAGE%',$article->mTitle->getPrefixedText(),$pieces[$key]);
 1143+ if (strpos($pieces[$key],"%CAT")>=0 ) {
 1144+ if (!empty($article->mCategoryLinks)) {
 1145+ $pieces[$key] = str_replace('%'.'CATLIST%',implode(', ', $article->mCategoryLinks),$pieces[$key]);
 1146+ $pieces[$key] = str_replace('%'.'CATBULLETS%','* '.implode("\n* ", $article->mCategoryLinks),$pieces[$key]);
 1147+ $pieces[$key] = str_replace('%'.'CATNAMES%',implode(', ', $article->mCategoryTexts),$pieces[$key]);
 1148+ }
 1149+ else {
 1150+ $pieces[$key] = str_replace('%'.'CATLIST%','',$pieces[$key]);
 1151+ $pieces[$key] = str_replace('%'.'CATBULLETS%','',$pieces[$key]);
 1152+ $pieces[$key] = str_replace('%'.'CATNAMES%','',$pieces[$key]);
 1153+ }
 1154+ }
10871155 }
10881156 $firstCall=false;
10891157 }
@@ -1090,25 +1158,31 @@
10911159
10921160 //format one single template argument of one occurence of one item from the include parameter
10931161 // is called via a backlink from DPLInclude::includeTemplate()
1094 - function formatTemplateArg($arg, $s, $argNr, $firstCall, $maxlen) {
 1162+ function formatTemplateArg($arg, $s, $argNr, $firstCall, $maxlen, $article) {
10951163 // we could try to format fields differently within the first call of a template
10961164 // currently we do not make such a difference
 1165+
 1166+ // if the result starts with a '-' we add a leading space; thus we avoid a misinterpretation of |- as
 1167+ // a start of a new row (wiki table syntax)
10971168 if (array_key_exists("$s.$argNr",$this->mTableRow)) {
 1169+ $n=-1;
10981170 if ($s>=1 && $argNr==0 && !$firstCall) {
10991171 $n=strpos($this->mTableRow["$s.$argNr"],'|');
11001172 if ($n===false || !(strpos(substr($this->mTableRow["$s.$argNr"],0,$n),'{')===false)
11011173 || !(strpos(substr($this->mTableRow["$s.$argNr"],0,$n),'[')===false)) {
1102 - return $this->cutAt($maxlen,str_replace('%%',$arg,$this->mTableRow["$s.$argNr"]));
 1174+ $n= -1;
11031175 }
1104 - else {
1105 - return $this->cutAt($maxlen,str_replace('%%',$arg,substr($this->mTableRow["$s.$argNr"],$n+1)));
1106 - }
11071176 }
1108 - else {
1109 - return $this->cutAt($maxlen,str_replace('%%',$arg,$this->mTableRow["$s.$argNr"]));
1110 - }
 1177+ $result = str_replace('%%',$arg,substr($this->mTableRow["$s.$argNr"],$n+1));
 1178+ $result = str_replace('%PAGE%',$article->mTitle->getPrefixedText(),$result);
 1179+ $result = str_replace('%IMAGE%',self::imageWithPath($arg),$result);
 1180+ $result = $this->cutAt($maxlen,$result);
 1181+ if (strlen($result)>0 && $result[0]=='-') return ' '.$result;
 1182+ else return $result;
11111183 }
1112 - return $this->cutAt($maxlen,$arg);
 1184+ $result = $this->cutAt($maxlen,$arg);
 1185+ if (strlen($result)>0 && $result[0]=='-') return ' '.$result;
 1186+ else return $result;
11131187 }
11141188
11151189 //return the total number of rows (filtered)
@@ -1116,7 +1190,17 @@
11171191 return $this->filteredCount;
11181192 }
11191193
1120 - //cut wiki text around lim
 1194+ /**
 1195+ * Truncate a portion of wikitext so that ..
 1196+ * ... it is not larger that $lim characters
 1197+ * ... it is balanced in terms of braces, brackets and tags
 1198+ * ... can be used as content of a wikitable field without spoiling the whole surrounding wikitext structure
 1199+ * @param $lim limit of character count for the result
 1200+ * @param $text the wikitext to be truncated
 1201+ * @return the truncated text; note that in some cases it may be slightly longer than the given limit
 1202+ * if the text is alread shorter than the limit or if the limit is negative, the text
 1203+ * will be returned without any checks for balance of tags
 1204+ */
11211205 function cutAt($lim,$text) {
11221206 if ($lim<0) return $text;
11231207 return DPLInclude::limitTranscludedText($text, $lim);
@@ -1138,9 +1222,26 @@
11391223 }
11401224 return '';
11411225 }
1142 -
11431226
11441227 /**
 1228+ * Prepends an image name with its hash path.
 1229+ *
 1230+ * @param $imgName name of the image (may start with Image: or File:)
 1231+ * @return $uniq_prefix
 1232+ */
 1233+ static function imageWithPath($imgName) {
 1234+ $title = Title::newfromText('Image:'.$imgName);
 1235+ if( !is_null($title) ) {
 1236+ $iTitle = Title::makeTitleSafe(6,$title->getDBKey());
 1237+ $imageUrl = preg_replace('~^.*images/(.*)~','\1',RepoGroup::singleton()->getLocalRepo()->newFile($iTitle)->getPath());
 1238+ }
 1239+ else {
 1240+ $imageUrl = '???';
 1241+ }
 1242+ return $imageUrl;
 1243+ }
 1244+
 1245+ /**
11451246 * Returns message in the requested format after parsing wikitext to html
11461247 * This is meant to be equivalent to wfMsgExt() with parse, parsemag and escape as available options but using the DPL local parser instead of the global one (bugfix).
11471248 */
Index: trunk/extensions/DynamicPageList/DPLSetup.php
@@ -368,11 +368,39 @@
369369 * deleterules: does some kind of permission checking now
370370 * various improvements in template editing (calling the edit page now for the real update)
371371 * call to parser->clearState() inserted; does this solve the UNIQ-QINU problem without a patch to LnkHolderArray ??
372 - *
373 - * ! when making changes here you must update the version field in DynamicPageList.php and DynamicPageListMigration.php !
 372+ * @version 1.8.9
 373+ * further improvements of updaterules
 374+ * include: _ in template names are now treated like spaces
 375+ * providing URL-args as variables execandexit = geturlargs
 376+ * new command scroll = yes/no
 377+ * if %TOTALPAGES% is not used, the number of total hits will not be calculated in SQL
 378+ * when searching for a template call the localized word for "Template:" may preceed the template´s name
 379+ * when making changes here you must update the version field in DynamicPageList.php and DynamicPageListMigration.php !
 380+ * categories= : empty argument is now ignored; use _none_ to list articles with NO category assignment
 381+ * include: we use :and whitespace for separation of field names
 382+ * {{{%CATLIST%}}} is now available in phantom templates
 383+ * %IMAGE% is now translated to the image plus hashpath if used within a tablerow statement
 384+ * The function which truncates wiki text was improved (logic to check balance of tags)
 385+ * setting execandexit to true will prevent the parser cache from being disabled by successive settings of allowcachedresults
 386+ * bug fix: replacing %SECTION% in an include link text did not work wit hregukar expressions as section titles
 387+ * command fixcategory added
 388+ * adding a way to define an alternate namespace for surrogate templates {ns::xyz}.abc
 389+ * accept @ as a synonym for # in the include statement, @@ will match regular expressions
 390+ * syntax changed in include: regexp~ must precede all other information, allow multiple regexps :[regex1~regex2~regex3~number linkText]
 391+ * allow %CATLIST% in tablerow
 392+ * allow '-' as a dummy parameter in include
 393+ * allow alternate syntax for surrogate template {tpl|surrogate} in include
 394+ * multiple linksto statements are now AND-wired (%PAGESEL%) refers to the FIRST statement only
 395+ * multiple linkstoexternal statements are now AND-wired
 396+ * new parser function #dplnum
 397+ * allow like expressions in LINKSTO (depending on % in target name)
 398+ * prevent %xx from being misinterpreted as a hex code when used in linksto (e.g. %2c)
 399+ * Added hiddencategories = yes / no / only [dead code - not yet WORKING !]
 400+ * added %EDITSUMMARY%
 401+
 402+ * when making changes here you must update the version field in DynamicPageList.php and DynamicPageListMigration.php !
374403 */
375404
376 -
377405 // changed back to global functions due to trouble with older MW installations, g.s.
378406 function ExtDynamicPageList__languageGetMagic( &$magicWords, $langCode ) {
379407 return ExtDynamicPageList::languageGetMagic( $magicWords, $langCode );
@@ -410,6 +438,10 @@
411439 // .. to be set by DynamicPageList.php and DynamicPageListMigration.php
412440 public static $respectParserCache = false; // false = make page dynamic ; true = execute only when parser cache is refreshed
413441 // .. to be changed in LocalSettings.php
 442+
 443+ public static $fixedCategories = array(); // an array which holds categories to which the page containing the DPL query
 444+ // shall be assigned althoug reset_all|categories has been used
 445+ // see the fixcategory command
414446
415447 /**
416448 * Map parameters to possible values.
@@ -455,6 +487,10 @@
456488 * Min and Max of categories allowed for an article
457489 */
458490 'categoriesminmax' => array('default' => '', 'pattern' => '/^\d*,?\d*$/'),
 491+ /**
 492+ * hiddencategories
 493+ */
 494+ 'hiddencategories' => array('default' => 'include', 'exclude', 'only'),
459495 /**
460496 * perform the command and do not query the database
461497 */
@@ -739,6 +775,7 @@
740776 */
741777 'title<' => NULL,
742778 'title>' => NULL,
 779+ 'scroll' => array('default' => 'false', 'true', 'no', 'yes', '0', '1', 'off', 'on'),
743780 'titlematch' => NULL,
744781 'titleregexp' => NULL,
745782 'userdateformat' => NULL, // depends on behaveAs... mode
@@ -848,6 +885,10 @@
849886 */
850887 'reset' => array( 'default' => '', 'categories', 'templates', 'links', 'images', 'all', 'none'),
851888 /**
 889+ * fixcategory=.. prevents a category from being reset
 890+ */
 891+ 'fixcategory' => array( 'default' => ''),
 892+ /**
852893 * number of rows for output, default is 1
853894 * note: a "row" is a group of lines for which the heading tags defined in listseparators/format will be repeated
854895 */
@@ -919,6 +960,7 @@
920961 addfirstcategorydate
921962 category
922963 count
 964+ hiddencategories
923965 mode
924966 namespace
925967 notcategory
@@ -956,6 +998,7 @@
957999 rowcolformat
9581000 rows
9591001 rowsize
 1002+ scroll
9601003 title
9611004 title<
9621005 title>
@@ -979,6 +1022,7 @@
9801023 dplcache
9811024 dplcacheperiod
9821025 eliminate
 1026+ fixcategory
9831027 headingcount
9841028 headingmode
9851029 hitemattr
@@ -1071,6 +1115,7 @@
10721116 $wgParser->setHook( 'DynamicPageList', array( __CLASS__, 'intersectionTag' ) );
10731117
10741118 $wgParser->setFunctionHook( 'dpl', array( __CLASS__, 'dplParserFunction' ) );
 1119+ $wgParser->setFunctionHook( 'dplnum', array( __CLASS__, 'dplNumParserFunction' ) );
10751120 $wgParser->setFunctionHook( 'dplchapter', array( __CLASS__, 'dplChapterParserFunction' ) );
10761121 $wgParser->setFunctionHook( 'dplmatrix', array( __CLASS__, 'dplMatrixParserFunction' ) );
10771122
@@ -1113,6 +1158,10 @@
11141159 require_once( 'DynamicPageList.i18n.php' );
11151160 global $wgMessageCache;
11161161
 1162+ foreach( DPL_i18n::getMessages() as $sLang => $aMsgs )
 1163+ {
 1164+ $wgMessageCache->addMessages( $aMsgs, $sLang );
 1165+ }
11171166
11181167 /**
11191168 * Define codes and map debug message to min debug level above which message can be displayed
@@ -1153,9 +1202,10 @@
11541203 # Add the magic word
11551204 # The first array element is case sensitivity, in this case it is not case sensitive
11561205 # All remaining elements are synonyms for our parser function
1157 - $magicWords['dpl'] = array( 0, 'dpl' );
1158 - $magicWords['dplchapter'] = array( 0, 'dplchapter' );
1159 - $magicWords['dplmatrix'] = array( 0, 'dplmatrix' );
 1206+ $magicWords['dpl'] = array( 0, 'dpl' );
 1207+ $magicWords['dplnum'] = array( 0, 'dplnum' );
 1208+ $magicWords['dplchapter'] = array( 0, 'dplchapter' );
 1209+ $magicWords['dplmatrix'] = array( 0, 'dplmatrix' );
11601210 $magicWords['DynamicPageList'] = array( 0, 'DynamicPageList' );
11611211 # unless we return true, other parser functions extensions won't get loaded.
11621212 return true;
@@ -1257,6 +1307,23 @@
12581308
12591309 }
12601310
 1311+ public static function dplNumParserFunction(&$parser, $text='') {
 1312+ $num = str_replace('&nbsp;',' ',$text);
 1313+ $num = preg_replace('/([0-9])([.])([0-9][0-9]?[^0-9,])/','\1,\3',$num);
 1314+ $num = preg_replace('/([0-9.]+),([0-9][0-9][0-9])\s*Mrd/','\1\2 000000 ',$num);
 1315+ $num = preg_replace('/([0-9.]+),([0-9][0-9])\s*Mrd/','\1\2 0000000 ',$num);
 1316+ $num = preg_replace('/([0-9.]+),([0-9])\s*Mrd/','\1\2 00000000 ',$num);
 1317+ $num = preg_replace('/\s*Mrd/','000000000 ',$num);
 1318+ $num = preg_replace('/([0-9.]+),([0-9][0-9][0-9])\s*Mio/','\1\2 000 ',$num);
 1319+ $num = preg_replace('/([0-9.]+),([0-9][0-9])\s*Mio/','\1\2 0000 ',$num);
 1320+ $num = preg_replace('/([0-9.]+),([0-9])\s*Mio/','\1\2 00000 ',$num);
 1321+ $num = preg_replace('/\s*Mio/','000000 ',$num);
 1322+ $num = preg_replace('/[. ]/','',$num);
 1323+ $num = preg_replace('/^[^0-9]+/','',$num);
 1324+ $num = preg_replace('/[^0-9].*/','',$num);
 1325+ return $num;
 1326+ }
 1327+
12611328 public static function dplChapterParserFunction(&$parser, $text='', $heading=' ', $maxLength = -1, $page = '?page?', $link = 'default', $trim=false ) {
12621329 $arg_list = func_get_args();
12631330 $output = DPLInclude::extractHeadingFromText($parser, $page, '?title?', $text, $heading, '', $sectionHeading, true, $maxLength, $link, $trim);
@@ -1351,15 +1418,24 @@
13521419 return '';
13531420 }
13541421
 1422+ public static function fixCategory($cat) {
 1423+ if ($cat!='') self::$fixedCategories[$cat]=1;
 1424+ }
 1425+
 1426+// reset everything; some categories may have been fixed, however via fixcategory=
13551427 public static function endReset( &$parser, $text ) {
13561428 if (!self::$createdLinks['resetdone']) {
13571429 self::$createdLinks['resetdone'] = true;
 1430+ foreach ($parser->mOutput->mCategories as $key => $val) {
 1431+ if (array_key_exists($key,self::$fixedCategories)) self::$fixedCategories[$key] = $val;
 1432+ }
13581433 // $text .= self::dumpParsedRefs($parser,"before final reset");
13591434 if (self::$createdLinks['resetLinks']) $parser->mOutput->mLinks = array();
1360 - if (self::$createdLinks['resetCategories']) $parser->mOutput->mCategories = array();
 1435+ if (self::$createdLinks['resetCategories']) $parser->mOutput->mCategories = self::$fixedCategories;
13611436 if (self::$createdLinks['resetTemplates']) $parser->mOutput->mTemplates = array();
13621437 if (self::$createdLinks['resetImages']) $parser->mOutput->mImages = array();
13631438 // $text .= self::dumpParsedRefs($parser,"after final reset");
 1439+ self::$fixedCategories=array();
13641440 }
13651441 return true;
13661442 }
@@ -1408,16 +1484,17 @@
14091485
14101486 class MyBug {
14111487
1412 - static function trace($class,$label,$msg) {
 1488+ static function trace($class,$label,$msg='') {
14131489 $fileName = dirname(__FILE__).'/MyBug';
14141490 if ($class=='') {
14151491 if (file_exists($fileName)) unlink(dirname(__FILE__).'/MyBug');
 1492+ self::trace(__CLASS__,'start tracing ..');
14161493 return;
14171494 }
14181495 $bugFile=fopen($fileName,'a');
14191496 fwrite($bugFile,"$class -------------------------------------------------------------------------------------------- $label\n");
1420 - fwrite($bugFile,$msg."\n");
1421 - fclose($bugFile);
 1497+ if ($msg!='') fwrite($bugFile,$msg."\n");
 1498+ fclose($bugFile);
14221499 }
14231500
14241501 }
\ No newline at end of file
Index: trunk/extensions/DynamicPageList/DynamicPageListInclude.php
@@ -135,7 +135,7 @@
136136 * Handle recursive substitution here, so we can break cycles, and set up
137137 * return values so that edit sections will resolve correctly.
138138 **/
139 - private static function parse($parser, $title, $text, $part1, $skiphead=0, $recursionCheck=true, $maxLength=-1, $link='', $trim=false, $skipPattern='')
 139+ private static function parse($parser, $title, $text, $part1, $skiphead=0, $recursionCheck=true, $maxLength=-1, $link='', $trim=false, $skipPattern=array())
140140 {
141141 global $wgVersion;
142142
@@ -144,8 +144,8 @@
145145 $text = str_replace('</section>', '', $text);
146146
147147 // if desired we remove portions of the text, esp. template calls
148 - if ($skipPattern!='') {
149 - $text=preg_replace($skipPattern,'',$text);
 148+ foreach ($skipPattern as $skipPat) {
 149+ $text=preg_replace($skipPat,'',$text);
150150 }
151151
152152
@@ -243,7 +243,7 @@
244244 }
245245
246246 ///section inclusion - include all matching sections
247 - public static function includeSection($parser, $page='', $sec='', $to='', $recursionCheck=true, $trim=false, $skipPattern='') {
 247+ public static function includeSection($parser, $page='', $sec='', $to='', $recursionCheck=true, $trim=false, $skipPattern=array()) {
248248 $output = array();
249249 if (self::text($parser, $page, $title, $text) == false) {
250250 $output[] = $text;
@@ -263,13 +263,35 @@
264264 }
265265
266266
267 - //reduce transcluded wiki text to a certain length; we will care for matching brackets to some extent
268 - // so that we do not spoil wiki syntax; the returned result may be smaller or bigger that the limit
269 - // to achieve this.
 267+ /**
 268+ * Truncate a portion of wikitext so that ..
 269+ * ... does not contain (open) html comments
 270+ * ... it is not larger that $lim characters
 271+ * ... it is balanced in terms of braces, brackets and tags
 272+ * ... it is cut at a word boundary (white space) if possible
 273+ * ... can be used as content of a wikitable field without spoiling the whole surrounding wikitext structure
 274+ * @param $lim limit of character count for the result
 275+ * @param $text the wikitext to be truncated
 276+ * @param $link an optional link which will be appended to the text if it was truncatedt
 277+ * @return the truncated text;
 278+ * note that the returned text may be longer than the limit if this is necessary
 279+ * to return something at all. We do not want to return an empty string if the input is not empty
 280+ * if the text is already shorter than the limit, the text
 281+ * will be returned without any checks for balance of tags
 282+ */
270283 public static function limitTranscludedText($text, $limit, $link='') {
271 - // if text is smaller than the limit return complete text
 284+
 285+ // if text is smaller than limit return complete text
272286 if ($limit >= strlen($text)) return $text;
273 - $brackets=0;
 287+
 288+ // otherwise strip html comments and check again
 289+ $text = preg_replace('/<!--.*?-->/s','',$text);
 290+ if ($limit >= strlen($text)) return $text;
 291+
 292+ // search latest position with balanced brackets/braces
 293+ // store also the position of the last preceding space
 294+
 295+ $brackets=0;
274296 $cbrackets=0;
275297 $n0=-1; $nb=0;
276298 for ($i=0; $i<$limit;$i++) {
@@ -284,13 +306,48 @@
285307 if ($c == ' ') $nb = $i;
286308 }
287309 }
 310+
288311 // if there is a valid cut-off point we use it; it will be the largest one which is not above the limit
289 - if ( $n0>=0 ) {
290 - // we try to cut off at a word boundary
 312+ if ( $n0 >= 0 ) {
 313+ // we try to cut off at a word boundary, this may lead to a shortening of max. 15 chars
291314 if ($nb>0 && $nb+15>$n0) $n0=$nb;
292315 $cut=substr($text, 0, $n0+1);
293 - if (stristr($cut,'<nowiki>')!==false && stristr($cut,'</nowiki>')===false) $cut.='</nowiki>';
294 - if (stristr($cut,'<pre>')!==false && stristr($cut,'</pre>')===false) $cut.='</pre>';
 316+
 317+ // an open html comment would be fatal, but this should not happen as we already have
 318+ // eliminated html comments at the beginning
 319+
 320+ // some tags are critical: ref, pre, nowiki
 321+ // if these tags were not balanced they would spoil the result completely
 322+ // we enforce balance by appending the necessary amount of corresponding closing tags
 323+ // currently we ignore the nesting, i.e. all closing tags are appended at the end.
 324+ // This simple approach may fail in some cases ...
 325+
 326+ $matches = array();
 327+ $noMatches = preg_match_all('#<\s*(/?ref|/?pre|/?nowiki)(\s+[^>]*?)*>#im',$cut,$matches);
 328+ $tags = array ('ref'=>0,'pre'=>0,'nowiki'=>0);
 329+
 330+ if ($noMatches>0) {
 331+ // calculate tag count (ignoring nesting)
 332+ foreach ($matches[1] as $mmInx => $mm) {
 333+ if ($mm[0]=='/') $tags[substr($mm,1)] --;
 334+ else $tags[$mm]++;
 335+ }
 336+ // append missing closing tags - should the tags be ordered by precedence ?
 337+ foreach($tags as $tagName => $level) {
 338+ while ($level>0) {
 339+ // avoid empty ref tag
 340+ if ($tagName=='ref' && substr($cut,strlen($cut)-5)=='<ref>') {
 341+ $cut=substr($cut,0,strlen($cut)-5);
 342+ }
 343+ else {
 344+ $cut.='</'.$tagName.'>';
 345+ }
 346+ $level--;
 347+ }
 348+ }
 349+ }
 350+
 351+ // MyBug::trace(__CLASS__,'truncate',"corrected cut=$cut");
295352 return $cut.$link;
296353 }
297354 else if ($limit==0) {
@@ -305,26 +362,22 @@
306363 }
307364
308365 public static function includeHeading($parser, $page='', $sec='', $to='', &$sectionHeading, $recursionCheck=true, $maxLength=-1,
309 - $link='default', $trim=false, $skipPattern='')
 366+ $link='default', $trim=false, $skipPattern=array())
310367 {
311368 $output=array();
312 - if (self::text($parser, $page, $title, $text) == false) {
313 - $output[0] = $text;
314 - return $output;
315 - }
316 -
317 - return self::extractHeadingFromText($parser, $page, $title, $text, $sec, $to, $sectionHeading, $recursionCheck, $maxLength, $link, $trim, $skipPattern);
 369+ if (self::text($parser, $page, $title, $text) == false) {
 370+ $output[0] = $text;
 371+ return $output;
 372+ }
 373+ /* throw away comments */
 374+ $text = preg_replace('/<!--.*?-->/s','',$text);
 375+ return self::extractHeadingFromText($parser, $page, $title, $text, $sec, $to, $sectionHeading, $recursionCheck, $maxLength, $link, $trim, $skipPattern);
318376 }
319377
320378 //section inclusion - include all matching sections (return array)
321379 public static function extractHeadingFromText($parser, $page, $title, $text, $sec='', $to='', &$sectionHeading, $recursionCheck=true,
322 - $maxLength=-1, $link='default', $trim=false, $skipPattern='' ) {
 380+ $maxLength=-1, $cLink='default', $trim=false, $skipPattern=array() ) {
323381
324 - // create a link symbol (arrow, img, ...) in case we have to cut the text block to maxLength
325 - if ($link=='default') $link = ' [['.$page.'#'.$sec.'|..&rarr;]]';
326 - else if (strstr($link,'img=')!=false) $link = str_replace('img=',"<linkedimage>page=".$page.'#'.$sec."\nimg=Image:",$link)."\n</linkedimage>";
327 - else if (strstr($link,'%SECTION%')==false) $link = ' [['.$page.'#'.$sec.'|'.$link.']]';
328 - else $link = str_replace('%SECTION%',$page.'#'.$sec,$link);
329382 $continueSearch = true;
330383 $n=0;
331384 $output[$n]='';
@@ -333,25 +386,31 @@
334387 if (preg_match('/^%-?[1-9][0-9]*$/',$sec)) $nr = substr($sec,1);
335388 if (preg_match('/^%0$/',$sec)) $nr = -2; // transclude text before the first section
336389
337 - // if the section name starts with a # we use it as regexp, otherwise as plain string
 390+ // if the section name starts with a # or with a @ we use it as regexp, otherwise as plain string
338391 $isPlain=true;
339 - if ($sec!='' && $sec[0]=='#') {
 392+ if ($sec!='' && ($sec[0]=='#'||$sec[0]=='@')) {
340393 $sec=substr($sec,1);
341394 $isPlain=false;
342395 }
343396 do {
344397 //Generate a regex to match the === classical heading section(s) === we're
345398 //interested in.
 399+ $headLine = '';
346400 if ($sec == '') {
347401 $begin_off = 0;
348402 $head_len = 6;
349403 } else {
350404 if ($nr!=0) $pat = '^(={1,6})\s*[^=\s\n][^\n=]*\s*\1\s*($)' ;
351405 else if ($isPlain) $pat = '^(={1,6})\s*' . preg_quote($sec, '/') . '\s*\1\s*($)' ;
352 - else $pat = '^(={1,6})\s*' . str_replace('/','\/',$sec) . '\s*\1\s*($)' ;
 406+ else {
 407+ $pat = '^(={1,6})\s*' . str_replace('/','\/',$sec) . '\s*\1\s*($)' ;
 408+ }
353409 if ( preg_match( "/$pat/im", $text, $m, PREG_OFFSET_CAPTURE) ) {
354 - $begin_off = $m[2][1];
 410+ $mata=array();
 411+ $no_parenthesis=preg_match_all('/\(/',$pat,$mata);
 412+ $begin_off = $m[$no_parenthesis][1];
355413 $head_len = strlen($m[1][0]);
 414+ $headLine = trim($m[0][0],"\n =\t");
356415 } else if ($nr == -2) {
357416 $m[1][1] = strlen($text)+1; // take whole article if no heading found
358417 } else {
@@ -359,7 +418,12 @@
360419 return $output;
361420 }
362421 }
363 -
 422+ // create a link symbol (arrow, img, ...) in case we have to cut the text block to maxLength
 423+ $link=$cLink;
 424+ if ($link=='default') $link = ' [['.$page.'#'.$headLine.'|..&rarr;]]';
 425+ else if (strstr($link,'img=')!=false) $link = str_replace('img=',"<linkedimage>page=".$page.'#'.$headLine."\nimg=Image:",$link)."\n</linkedimage>";
 426+ else if (strstr($link,'%SECTION%')==false) $link = ' [['.$page.'#'.$headLine.'|'.$link.']]';
 427+ else $link = str_replace('%SECTION%',$page.'#'.$headLine,$link);
364428 if ($nr==-2) {
365429 // output text before first section and done
366430 $piece = substr($text,0,$m[1][1]-1);
@@ -375,7 +439,6 @@
376440 if (preg_match( "/$pat/im", $text, $mm, PREG_OFFSET_CAPTURE, $begin_off))
377441 $end_off = $mm[0][1]-1;
378442 }
379 -
380443 if (! isset($end_off)) {
381444 if ($nr!=0) $pat = '^(={1,6})\s*[^\s\n=][^\n=]*\s*\1\s*$';
382445 else $pat = '^(={1,'.$head_len.'})(?!=)\s*.*?\1\s*$';
@@ -406,10 +469,15 @@
407470 }
408471
409472 if (isset($m[0][0])) {
410 - $sectionHeading[$n]=preg_replace("/^=+\s*/","",$m[0][0]);
411 - $sectionHeading[$n]=preg_replace("/\s*=+\s*$/","",$sectionHeading[$n]);
 473+ $sectionHeading[$n] = $headLine;
 474+ //$sectionHeading[$n]=preg_replace("/^=+\s*/","",$m[0][0]);
 475+ //$sectionHeading[$n]=preg_replace("/\s*=+\s*$/","",$sectionHeading[$n]);
412476 }
413 - else $sectionHeading[$n] = '';
 477+ else {
 478+ // $sectionHeading[$n] = '';
 479+ $sectionHeading[0] = $headLine;
 480+ }
 481+
414482 if ($nr==1) {
415483 // output n-th section and done
416484 $output[0] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", $nhead, $recursionCheck, $maxLength, $link, $trim, $skipPattern);
@@ -438,15 +506,18 @@
439507 // and do NOT match the condition "$mustNotMatch" (if specified)
440508 // we use a callback function to format retrieved parameters, accessible via $dpl->formatTemplateArg()
441509 public static function includeTemplate($parser, $dpl, $dplNr, $article, $template1='', $template2='', $defaultTemplate,
442 - $mustMatch, $mustNotMatch, $matchParsed, $iTitleMaxLen)
 510+ $mustMatch, $mustNotMatch, $matchParsed, $iTitleMaxLen, $catlist)
443511 {
444512 $page = $article->mTitle->getPrefixedText();
445513 $date = $article->myDate;
446514 $user = $article->mUserLink;
447515 $title = Title::newFromText($page);
448 - $text = $parser->fetchTemplate($title);
 516+ /* get text and throw away html comments */
 517+ $text = preg_replace('/<!--.*?-->/s','',$parser->fetchTemplate($title));
 518+ $altNamespace=''; // alternate namespace for phantom templates
449519
450520 if ($template1 != '' && $template1[0]=='#') {
 521+ // --------------------------------------------- looking for a parser function call
451522 $template1=substr($template1,1);
452523 $template2=substr($template2,1);
453524 $defaultTemplate=substr($defaultTemplate,1);
@@ -456,6 +527,7 @@
457528 foreach($tCalls as $i => $tCall) if (($n=strpos($tCall,':'))!==false)$tCalls[$i][$n]=' ';
458529 }
459530 else if ($template1 != '' && $template1[0]=='~') {
 531+ // --------------------------------------------- looking for an xml-tag extension call
460532 $template1=substr($template1,1);
461533 $template2=substr($template2,1);
462534 $defaultTemplate=substr($defaultTemplate,1);
@@ -467,8 +539,18 @@
468540 }
469541 }
470542 else {
471 - // when looking for template calls we only accept plain text as a template name
472 - $tCalls = preg_split( "/\{\{\s*".preg_quote($template1,'/').'\s*[|}]/i', ' '.$text);
 543+ // --------------------------------------------- looking for template call
 544+ // we accept plain text as a template name, space or underscore are the same
 545+ // the localized name for "Template:" may preceed the template name
 546+ // the name may start with a different namespace for the surrogate template, followed by ::
 547+ global $wgContLang;
 548+ if (($n=strpos($template1,'::'))>0) {
 549+ $altNamespace=substr($template1,0,$n+1);
 550+ $template1 = substr($template1,$n+2);
 551+ $template2 = str_replace($altNamespace.':','',$template2);
 552+ }
 553+ $nsNames = $wgContLang->getNamespaces();
 554+ $tCalls = preg_split( '/\{\{\s*(Template:|'.$nsNames[10].':)?'.self::spaceOrUnderscore(preg_quote($template1,'/')).'\s*[|}]/i', ' '.$text);
473555 // We restore the first separator symbol (we had to include that symbol into the SPLIT, because we must make
474556 // sure that we only accept exact matches of the complete template name
475557 // (e.g. when looking for "foo" we must not accept "foo xyz")
@@ -485,7 +567,7 @@
486568 // in that case we won´t invoke template2 but will directly return the extracted parameters
487569 // as a sequence of table columns;
488570 if (strlen($template2)>strlen($template1) && ($template2[strlen($template1)]==':')) {
489 - $extractParm = split(':',substr($template2,strlen($template1)+1));
 571+ $extractParm = preg_split('/:\s*/s',trim(substr($template2,strlen($template1)+1)));
490572 }
491573
492574 if (count($tCalls) <= 1) {
@@ -493,10 +575,10 @@
494576 if (count($extractParm)>0) {
495577 // if parameters are required directly: return empty columns
496578 if (count($extractParm)>1) {
497 - $output[0]=$dpl->formatTemplateArg('',$dplNr,0,true,-1);
498 - for ($i=1;$i<count($extractParm); $i++) $output[0] .= "\n|" . $dpl->formatTemplateArg('',$dplNr,$i,true,-1);
 579+ $output[0]=$dpl->formatTemplateArg('',$dplNr,0,true,-1,$article);
 580+ for ($i=1;$i<count($extractParm); $i++) $output[0] .= "\n|" . $dpl->formatTemplateArg('',$dplNr,$i,true,-1,$article);
499581 }
500 - else $output[0]=$dpl->formatTemplateArg('',$dplNr,0,true,-1);
 582+ else $output[0]=$dpl->formatTemplateArg('',$dplNr,0,true,-1,$article);
501583 } else {
502584 // put a red link into the output
503585 $output[0]= $parser->preprocess(
@@ -520,7 +602,7 @@
521603 if (count($extractParm)==0) {
522604 // find the end of the call: bracket level must be zero
523605 $cbrackets=0;
524 - $templateCall = '{{'.$template2.$tCall;
 606+ $templateCall = '{{'.$altNamespace.$template2.$tCall;
525607 $size=strlen($templateCall);
526608 for ($i=0; $i<$size;$i++) {
527609 $c = $templateCall[$i];
@@ -530,8 +612,10 @@
531613 // if we must match a condition: test against it
532614 if (($mustMatch =='' || preg_match($mustMatch,substr($templateCall,0,$i-1))) &&
533615 ($mustNotMatch=='' || !preg_match($mustNotMatch,substr($templateCall,0,$i-1)))) {
534 - $output[++$n] = $parser->preprocess(substr($templateCall,0,$i-1).
535 - '|%PAGE%='.$page.'|%TITLE%='.$title->getText().'|%DATE%='.$date.'|%USER%='.$user.'}}',$parser->mTitle,$parser->mOptions);
 616+ $argChain = substr($templateCall,0,$i-1).'|%PAGE%='.$page.'|%TITLE%='.$title->getText();
 617+ if ($catlist!='') $argChain .= "|%CATLIST%=$catlist";
 618+ $argChain.= '|%DATE%='.$date.'|%USER%='.$user.'}}';
 619+ $output[++$n] = $parser->preprocess($argChain,$parser->mTitle,$parser->mOptions);
536620 }
537621 break;
538622 }
@@ -540,7 +624,7 @@
541625 else {
542626 // if the user wants parameters directly from the call line of template1 we return just those
543627 $cbrackets=2;
544 - $templateCall = preg_replace('/<!--.*-->/Us','',$tCall);
 628+ $templateCall = $tCall;
545629 $size=strlen($templateCall);
546630 $parms=array();
547631 $parm='';
@@ -584,15 +668,15 @@
585669 if (strpos($exParm,'%')!==FALSE) {
586670 // %% is a short form for inclusion of %PAGE% and %TITLE%
587671 $found=true;
588 - $output[$n] .= $dpl->formatTemplateArg($dpl->articleLink($exParm,$article,$iTitleMaxLen),$dplNr,$exParmKey,$firstCall,$maxlen);
 672+ $output[$n] .= $dpl->formatTemplateArg($dpl->articleLink($exParm,$article,$iTitleMaxLen),$dplNr,$exParmKey,$firstCall,$maxlen,$article);
589673 }
590674 if (!$found) {
591675 // named parameter
592676 $exParmQuote = str_replace('/','\/',$exParm);
593677 foreach ($parms as $parm) {
594 - if (!preg_match("/^\s*$exParmQuote\s*(<!--.*-->)*\s*=/",$parm)) continue;
 678+ if (!preg_match("/^\s*$exParmQuote\s*=/",$parm)) continue;
595679 $found=true;
596 - $output[$n] .= $dpl->formatTemplateArg(preg_replace("/^$exParmQuote\s*(<!--.*-->)*\s*=\s*/","",$parm),$dplNr,$exParmKey,$firstCall,$maxlen);
 680+ $output[$n] .= $dpl->formatTemplateArg(preg_replace("/^$exParmQuote\s*=\s*/","",$parm),$dplNr,$exParmKey,$firstCall,$maxlen,$article);
597681 break;
598682 }
599683 }
@@ -603,11 +687,11 @@
604688 if(strstr($parm, '=') === FALSE) ++$np;
605689 if ($np!=$exParm) continue;
606690 $found=true;
607 - $output[$n] .= $dpl->formatTemplateArg($parm,$dplNr,$exParmKey,$firstCall,$maxlen);
 691+ $output[$n] .= $dpl->formatTemplateArg($parm,$dplNr,$exParmKey,$firstCall,$maxlen,$article);
608692 break;
609693 }
610694 }
611 - if (!$found) $output[$n] .= $dpl->formatTemplateArg('',$dplNr,$exParmKey,$firstCall,$maxlen);
 695+ if (!$found) $output[$n] .= $dpl->formatTemplateArg('',$dplNr,$exParmKey,$firstCall,$maxlen,$article);
612696 $second=true;
613697 }
614698 }
@@ -620,4 +704,9 @@
621705 return $output;
622706 }
623707
 708+ static function spaceOrUnderscore($pattern) {
 709+ // returns a pettern that matches underscores as well as spaces
 710+ return str_replace(' ','[ _]',$pattern);
 711+ }
 712+
624713 }
Index: trunk/extensions/DynamicPageList/DPLArticle.php
@@ -21,6 +21,7 @@
2222 var $mRevision = ''; // the revision number if specified
2323 var $mUserLink = ''; // link to editor (first/last, depending on user's request) 's page or contributions if not registered
2424 var $mUser = ''; // name of editor (first/last, depending on user's request) or contributions if not registered
 25+ var $mComment = ''; // revision comment / edit summary
2526 var $mContribution= ''; // number of bytes changed
2627 var $mContrib= ''; // short string indicating the size of a contribution
2728 var $mContributor= ''; // user who made the changes
Index: trunk/extensions/DynamicPageList/DPLMain.php
@@ -21,7 +21,7 @@
2222 global $wgUser, $wgLang, $wgContLang, $wgRequest, $wgRawHtml;
2323 global $wgTitle, $wgArticle, $wgNonincludableNamespaces;
2424
25 - // we use "makeKnownLinkObject" to create hyperlinbks;
 25+ // we use "makeKnownLinkObject" to create hyperlinks;
2626 // the code we store in the dplcache may contain <html>....</html> sequences
2727 // for both reasons we need to enable rawHtml output
2828 // note that this does not affect the article wiki source - a <html> tag in the wiki source
@@ -83,6 +83,8 @@
8484 }
8585
8686 // check parameters which can be set via the URL
 87+
 88+ self::getUrlArgs();
8789
8890 if (strpos($input,'{%DPL_') >= 0) {
8991 for($i=1;$i<=5;$i++) {
@@ -90,10 +92,10 @@
9193 }
9294 }
9395
 96+
9497 $_sOffset=$wgRequest->getVal('DPL_offset',ExtDynamicPageList::$options['offset']['default']);
9598 $iOffset = ($_sOffset == '') ? 0: intval($_sOffset);
9699
97 - $sCount = $wgRequest->getVal('DPL_count','');
98100 $iCount = -1;
99101
100102 // commandline parameters like %DPL_offset% are replaced
@@ -103,18 +105,15 @@
104106 $input = self::resolveUrlArg($input,'DPL_findTitle');
105107 $input = self::resolveUrlArg($input,'DPL_toTitle');
106108
107 - $sTitleGE = $wgRequest->getVal('DPL_fromTitle','');
108 - if (strlen($sTitleGE)>0) $sTitleGE[0] = strtoupper($sTitleGE[0]);
109 - // findTitle has priority over fromTitle
110 - $findTitle = $wgRequest->getVal('DPL_findTitle','');
111 - if (strlen($findTitle)>0) $findTitle[0] = strtoupper($findTitle[0]);
112 - if ($findTitle !='') $sTitleGE = '=_'.$findTitle;
113 - $sTitleLE = $wgRequest->getVal('DPL_toTitle','');
114 - if (strlen($sTitleLE)>0) $sTitleLE[0] = strtoupper($sTitleLE[0]);
115 - $sTitleGE = str_replace(' ','_',$sTitleGE);
116 - $sTitleLE = str_replace(' ','_',$sTitleLE);
117 - $scrollDir = $wgRequest->getVal('DPL_scrollDir','');
 109+ // variables needed for scrolling
 110+ $sCount = '';
 111+ $sCountScroll = '';
 112+ $sTitleGE = '';
 113+ $findTitle = '';
 114+ $sTitleLE = '';
 115+ $scrollDir = '';
118116
 117+
119118 $originalInput = $input;
120119
121120 $bDPLRefresh = ($wgRequest->getVal('DPL_refresh','')=='yes');
@@ -176,6 +175,8 @@
177176
178177 $bEscapeLinks = ExtDynamicPageList::$options['escapelinks']['default'];
179178 $bSkipThisPage= ExtDynamicPageList::$options['skipthispage']['default'];
 179+
 180+ $sHiddenCategories = ExtDynamicPageList::$options['hiddencategories']['default'];
180181
181182 $sMinorEdits = NULL;
182183 $acceptOpenReferences = self::argBoolean(ExtDynamicPageList::$options['openreferences']['default']);
@@ -290,6 +291,8 @@
291292
292293 $_sIncludeMaxLen = ExtDynamicPageList::$options['includemaxlength']['default'];
293294 $iIncludeMaxLen = ($_sIncludeMaxLen == '') ? NULL: intval($_sIncludeMaxLen);
 295+
 296+ $bScroll = self::argBoolean(ExtDynamicPageList::$options['scroll']['default']);
294297
295298 $aLinksTo = array();
296299 $aNotLinksTo = array();
@@ -414,11 +417,13 @@
415418 }
416419 foreach($aParams as $sParam) {
417420 $sParam=trim($sParam);
418 - if($sParam == '') { // include uncategorized pages (special value: empty string)
 421+ if($sParam == '') { // ignore empty line
 422+ } else if($sParam == '_none_') { // include uncategorized pages (special value: empty string)
 423+ $aParams[$sParam]='';
419424 $bIncludeUncat = true;
420425 $aCategories[] = '';
421426 } else {
422 - if ($sParam[0]=='*') {
 427+ if ($sParam[0]=='*' && strlen($sParam)>=2) {
423428 if ($sParam[1]=='*') $sParamList = explode('|',self::getSubcategories(substr($sParam,2),$sPageTable,2));
424429 else $sParamList = explode('|',self::getSubcategories(substr($sParam,1),$sPageTable,1));
425430 foreach ($sParamList as $sPar) {
@@ -448,6 +453,13 @@
449454 $bConflictsWithOpenReferences=true;
450455 }
451456 break;
 457+ case 'hiddencategories':
 458+ if( in_array($sArg, ExtDynamicPageList::$options['hiddencategories']) ) {
 459+ $sHiddenCategories = $sArg;
 460+ }
 461+ else
 462+ $output .= $logger->msgWrongParam('hiddencategories', $sArg);
 463+ break;
452464 case 'notcategory':
453465 $title = Title::newFromText($localParser->transformMsg($sArg, $pOptions));
454466 if( !is_null($title) ) {
@@ -597,7 +609,8 @@
598610 case 'execandexit':
599611 // we offer a possibility to execute a DPL command without querying the database
600612 // this is useful if you want to catch the command line parameters DPL_arg1,... etc
601 - $sExecAndExit = $sArg;
 613+ // in this case we prevent the parser cache from being disabled by later statements
 614+ $sExecAndExit = $sArg;
602615 break;
603616
604617
@@ -765,6 +778,31 @@
766779 $bSelectionCriteriaFound=true;
767780 break;
768781
 782+ case 'scroll':
 783+ if( in_array($sArg, ExtDynamicPageList::$options['scroll'])) {
 784+ $bScroll = self::argBoolean($sArg);
 785+ // if scrolling is active we adjust the values for ceratin other parameters
 786+ // based on URL arguments
 787+ if ($bScroll) {
 788+ $sTitleGE = $wgRequest->getVal('DPL_fromTitle','');
 789+ if (strlen($sTitleGE)>0) $sTitleGE[0] = strtoupper($sTitleGE[0]);
 790+ // findTitle has priority over fromTitle
 791+ $findTitle = $wgRequest->getVal('DPL_findTitle','');
 792+ if (strlen($findTitle)>0) $findTitle[0] = strtoupper($findTitle[0]);
 793+ if ($findTitle !='') $sTitleGE = '=_'.$findTitle;
 794+ $sTitleLE = $wgRequest->getVal('DPL_toTitle','');
 795+ if (strlen($sTitleLE)>0) $sTitleLE[0] = strtoupper($sTitleLE[0]);
 796+ $sTitleGE = str_replace(' ','_',$sTitleGE);
 797+ $sTitleLE = str_replace(' ','_',$sTitleLE);
 798+ $scrollDir = $wgRequest->getVal('DPL_scrollDir','');
 799+ // also set count limit from URL if not otherwise set
 800+ $sCountScroll = $wgRequest->getVal('DPL_count','');
 801+ }
 802+ }
 803+ else
 804+ $output .= $logger->msgWrongParam('scroll', $sArg);
 805+ break;
 806+
769807 case 'titlemaxlength':
770808 //processed like 'count' param
771809 if( preg_match(ExtDynamicPageList::$options['titlemaxlength']['pattern'], $sArg) )
@@ -837,64 +875,31 @@
838876 */
839877
840878 case 'linksto':
841 - $pages = explode('|', trim($sArg));
842 - $n=0;
843 - foreach($pages as $page) {
844 - if (trim($page)=='') continue;
845 - if (!($theTitle = Title::newFromText(trim($page)))) return $logger->msgWrongParam('linksto', $sArg);
846 - $aLinksTo[$n++] = $theTitle;
847 - $bSelectionCriteriaFound=true;
848 - }
849 - if(!$bSelectionCriteriaFound) return $logger->msgWrongParam('linksto', $sArg);
 879+ $problems = self::getPageNameList('linksto', $sArg, $aLinksTo, $bSelectionCriteriaFound, $logger, true);
 880+ if ($problems!='') return $problems;
850881 $bConflictsWithOpenReferences=true;
851882 break;
852883
853884 case 'notlinksto':
854 - $pages = explode('|', trim($sArg));
855 - $n=0;
856 - foreach($pages as $page) {
857 - if (trim($page)=='') continue;
858 - if (!($theTitle = Title::newFromText(trim($page)))) return $logger->msgWrongParam('notlinksto', $sArg);
859 - $aNotLinksTo[$n++] = $theTitle;
860 - $bSelectionCriteriaFound=true;
861 - }
862 - if(!$bSelectionCriteriaFound) return $logger->msgWrongParam('notlinksto', $sArg);
 885+ $problems = self::getPageNameList('notlinksto', $sArg, $aNotLinksTo, $bSelectionCriteriaFound, $logger, true);
 886+ if ($problems!='') return $problems;
863887 $bConflictsWithOpenReferences=true;
864888 break;
865889
866890 case 'linksfrom':
867 - $pages = explode('|', trim($sArg));
868 - $n=0;
869 - foreach($pages as $page) {
870 - if (trim($page)=='') continue;
871 - if (!($theTitle = Title::newFromText(trim($page)))) return $logger->msgWrongParam('linksfrom', $sArg);
872 - $aLinksFrom[$n++] = $theTitle;
873 - $bSelectionCriteriaFound=true;
874 - }
875 - if(!$bSelectionCriteriaFound) return $logger->msgWrongParam('linksfrom', $sArg);
 891+ $problems = self::getPageNameList('linksfrom', $sArg, $aLinksFrom, $bSelectionCriteriaFound, $logger, true);
 892+ if ($problems!='') return $problems;
 893+ $bConflictsWithOpenReferences=true;
876894 break;
877895
878896 case 'notlinksfrom':
879 - $pages = explode('|', trim($sArg));
880 - $n=0;
881 - foreach($pages as $page) {
882 - if (trim($page)=='') continue;
883 - if (!($theTitle = Title::newFromText(trim($page)))) return $logger->msgWrongParam('notlinksfrom', $sArg);
884 - $aNotLinksFrom[$n++] = $theTitle;
885 - $bSelectionCriteriaFound=true;
886 - }
887 - if(!$bSelectionCriteriaFound) return $logger->msgWrongParam('notlinksfrom', $sArg);
 897+ $problems = self::getPageNameList('notlinksfrom', $sArg, $aNotLinksFrom, $bSelectionCriteriaFound, $logger, true);
 898+ if ($problems!='') return $problems;
888899 break;
889900
890901 case 'linkstoexternal':
891 - $pages = explode('|', trim($sArg));
892 - $n=0;
893 - foreach($pages as $page) {
894 - if (trim($page)=='') continue;
895 - $aLinksToExternal[$n++] = $page;
896 - $bSelectionCriteriaFound=true;
897 - }
898 - if(!$bSelectionCriteriaFound) return $logger->msgWrongParam('linkstoexternal', $sArg);
 902+ $problems = self::getPageNameList('linkstoexternal', $sArg, $aLinksToExternal, $bSelectionCriteriaFound, $logger, false);
 903+ if ($problems!='') return $problems;
899904 $bConflictsWithOpenReferences=true;
900905 break;
901906
@@ -1255,15 +1260,20 @@
12561261 */
12571262
12581263 case 'allowcachedresults':
1259 - if( in_array($sArg, ExtDynamicPageList::$options['allowcachedresults'])) {
1260 - $bAllowCachedResults = self::argBoolean($sArg);
1261 - if ($sArg=='yes+warn') {
1262 - $bAllowCachedResults = true;
1263 - $bWarnCachedResults = true;
1264 - }
1265 - }
1266 - else
1267 - $output .= $logger->msgWrongParam('allowcachedresults', $sArg);
 1264+ // if execAndExit was previously set (i.e. if it is not empty) we will ignore all cache settings
 1265+ // which are placed AFTER the execandexit statement
 1266+ // thus we make sure that the cache will only become invalid if the query is really executed
 1267+ if ($sExecAndExit=='') {
 1268+ if( in_array($sArg, ExtDynamicPageList::$options['allowcachedresults'])) {
 1269+ $bAllowCachedResults = self::argBoolean($sArg);
 1270+ if ($sArg=='yes+warn') {
 1271+ $bAllowCachedResults = true;
 1272+ $bWarnCachedResults = true;
 1273+ }
 1274+ }
 1275+ else
 1276+ $output .= $logger->msgWrongParam('allowcachedresults', $sArg);
 1277+ }
12681278 break;
12691279
12701280 case 'dplcache':
@@ -1285,6 +1295,10 @@
12861296 $output .= $logger->msgWrongParam('dplcacheperiod', $sArg);
12871297 break;
12881298
 1299+ case 'fixcategory':
 1300+ ExtDynamicPageList::fixCategory($sArg);
 1301+ break;
 1302+
12891303 case 'reset':
12901304 foreach (preg_split('/[;,]/',$sArg) as $arg) {
12911305 $arg=trim($arg);
@@ -1490,6 +1504,7 @@
14911505
14921506 // set COUNT
14931507
 1508+ if ($sCount=='') $sCount = $sCountScroll;
14941509 if ($sCount=='') {
14951510 $iCount=-1;
14961511 } else {
@@ -1516,7 +1531,12 @@
15171532
15181533
15191534
1520 - if ($sExecAndExit != '') return $sExecAndExit;
 1535+ if ($sExecAndExit != '') {
 1536+ // the keyword "geturlargs" is used to return the Url arguments and do nothing else.
 1537+ if ($sExecAndExit == 'geturlargs') return '';
 1538+ // in all other cases we return the value of the argument (which may contain parser function calls)
 1539+ return $sExecAndExit;
 1540+ }
15211541
15221542
15231543
@@ -1741,7 +1761,7 @@
17421762 $sSqlPage_touched = '';
17431763 $sSqlCalcFoundRows = '';
17441764 if ( !ExtDynamicPageList::$allowUnlimitedResults && $sGoal != 'categories'
1745 - && strpos($sResultsHeader.$sResultsFooter,'%TOTALPAGES%')!==false) $sSqlCalcFoundRows = 'SQL_CALC_FOUND_ROWS';
 1765+ && strpos($sResultsHeader.$sResultsFooter.$sNoResultsHeader,'%TOTALPAGES%')!==false) $sSqlCalcFoundRows = 'SQL_CALC_FOUND_ROWS';
17461766 if ($sDistinctResultSet == 'false') $sSqlDistinct = '';
17471767 else $sSqlDistinct = 'DISTINCT';
17481768 $sSqlGroupBy = '';
@@ -1865,7 +1885,7 @@
18661886 break;
18671887 case 'user':
18681888 $sSqlRevisionTable = $sRevisionTable . ', ';
1869 - $sSqlRev_user = ', rev_user, rev_user_text';
 1889+ $sSqlRev_user = ', rev_user, rev_user_text, rev_comment';
18701890 break;
18711891 case 'none':
18721892 break;
@@ -1873,32 +1893,58 @@
18741894 }
18751895
18761896 // linksto
 1897+
18771898 if ( count($aLinksTo)>0 ) {
18781899 $sSqlPageLinksTable .= $sPageLinksTable . ' as pl, ';
1879 - $sSqlCond_page_pl .= ' AND '.$sPageTable.'.page_id=pl.pl_from AND (';
 1900+ $sSqlCond_page_pl .= ' AND '.$sPageTable.'.page_id=pl.pl_from AND ';
18801901 $sSqlSelPage = ', pl.pl_title as sel_title, pl.pl_namespace as sel_ns';
18811902 $n=0;
1882 - foreach ($aLinksTo as $link) {
1883 - if ($n>0) $sSqlCond_page_pl .= ' OR ';
1884 - $sSqlCond_page_pl .= '(pl.pl_namespace=' . intval( $link->getNamespace() );
1885 - if ($bIgnoreCase) $sSqlCond_page_pl .= " AND LOWER(pl.pl_title)=LOWER(" . $dbr->addQuotes( $link->getDbKey() ).'))';
1886 - else $sSqlCond_page_pl .= " AND pl.pl_title=" . $dbr->addQuotes( $link->getDbKey() ).')';
1887 - $n++;
 1903+ foreach ($aLinksTo as $linkGroup) {
 1904+ if (++$n>1) break;
 1905+ $sSqlCond_page_pl .= '( ';
 1906+ $m=0;
 1907+ foreach ($linkGroup as $link) {
 1908+ if (++$m>1) $sSqlCond_page_pl .= ' OR ';
 1909+ $sSqlCond_page_pl .= '(pl.pl_namespace=' . intval( $link->getNamespace() );
 1910+ if (strpos($link->getDbKey(),'%')>=0) $operator = ' LIKE '; else $operator='=';
 1911+ if ($bIgnoreCase) $sSqlCond_page_pl .= ' AND LOWER(pl.pl_title)'.$operator.'LOWER(' . $dbr->addQuotes( $link->getDbKey() ).'))';
 1912+ else $sSqlCond_page_pl .= ' AND pl.pl_title'.$operator.$dbr->addQuotes( $link->getDbKey() ).')';
 1913+ }
 1914+ $sSqlCond_page_pl .= ')';
 1915+ }
 1916+ }
 1917+ if ( count($aLinksTo)>1 ) {
 1918+ $n=0;
 1919+ foreach ($aLinksTo as $linkGroup) {
 1920+ if (++$n == 1) continue;
 1921+ $m=0;
 1922+ $sSqlCond_page_pl .= ' AND EXISTS(select pl_from from '.$sPageLinksTable.' where ('.$sPageLinksTable.'.pl_from=page_id AND (';
 1923+ foreach ($linkGroup as $link) {
 1924+ if (++$m>1) $sSqlCond_page_pl .= ' OR ';
 1925+ $sSqlCond_page_pl.= '('.$sPageLinksTable.'.pl_namespace=' . intval( $link->getNamespace() );
 1926+ if (strpos($link->getDbKey(),'%')>=0) $operator = ' LIKE '; else $operator='=';
 1927+ if ($bIgnoreCase) $sSqlCond_page_pl .= ' AND LOWER(pagelinks.pl_title)'.$operator.'LOWER(' . $dbr->addQuotes( $link->getDbKey() ).')';
 1928+ else $sSqlCond_page_pl .= ' AND pagelinks.pl_title'.$operator.$dbr->addQuotes( $link->getDbKey() );
 1929+ $sSqlCond_page_pl .= ')';
 1930+ }
 1931+ $sSqlCond_page_pl .= ')))';
18881932 }
1889 - $sSqlCond_page_pl .= ')';
18901933 }
18911934
18921935 // notlinksto
18931936 if ( count($aNotLinksTo)>0 ) {
18941937 $sSqlCond_page_pl .= ' AND '.$sPageTable.'.page_id not in (select '.$sPageLinksTable.'.pl_from from '.$sPageLinksTable.' where (';
18951938 $n=0;
1896 - foreach ($aNotLinksTo as $link) {
1897 - if ($n>0) $sSqlCond_page_pl .= ' OR ';
1898 - $sSqlCond_page_pl .= '('.$sPageLinksTable.'.pl_namespace=' . intval($link->getNamespace());
1899 - if ($bIgnoreCase) $sSqlCond_page_pl .= ' AND LOWER('.$sPageLinksTable.'.pl_title)=LOWER(' . $dbr->addQuotes( $link->getDbKey() ).'))';
1900 - else $sSqlCond_page_pl .= ' AND '.$sPageLinksTable.'.pl_title=' . $dbr->addQuotes( $link->getDbKey() ).')';
1901 - $n++;
1902 - }
 1939+ foreach ($aNotLinksTo as $links) {
 1940+ foreach ($links as $link) {
 1941+ if ($n>0) $sSqlCond_page_pl .= ' OR ';
 1942+ $sSqlCond_page_pl .= '('.$sPageLinksTable.'.pl_namespace=' . intval($link->getNamespace());
 1943+ if (strpos($link->getDbKey(),'%')>=0) $operator = ' LIKE '; else $operator='=';
 1944+ if ($bIgnoreCase) $sSqlCond_page_pl .= ' AND LOWER('.$sPageLinksTable.'.pl_title)'.$operator.'LOWER(' . $dbr->addQuotes( $link->getDbKey() ).'))';
 1945+ else $sSqlCond_page_pl .= ' AND '.$sPageLinksTable.'.pl_title'.$operator. $dbr->addQuotes( $link->getDbKey() ).')';
 1946+ $n++;
 1947+ }
 1948+ }
19031949 $sSqlCond_page_pl .= ') )';
19041950 }
19051951
@@ -1907,10 +1953,12 @@
19081954 if ($acceptOpenReferences) {
19091955 $sSqlCond_page_pl .= ' AND (';
19101956 $n=0;
1911 - foreach ($aLinksFrom as $link) {
1912 - if ($n>0) $sSqlCond_page_pl .= ' OR ';
1913 - $sSqlCond_page_pl .= '(pl_from=' . $link->getArticleID().')';
1914 - $n++;
 1957+ foreach ($aLinksFrom as $links) {
 1958+ foreach ($links as $link) {
 1959+ if ($n>0) $sSqlCond_page_pl .= ' OR ';
 1960+ $sSqlCond_page_pl .= '(pl_from=' . $link->getArticleID().')';
 1961+ $n++;
 1962+ }
19151963 }
19161964 $sSqlCond_page_pl .= ')';
19171965 }
@@ -1919,11 +1967,13 @@
19201968 $sSqlCond_page_pl .= ' AND '.$sPageTable.'.page_namespace = plf.pl_namespace AND '.$sPageTable.'.page_title = plf.pl_title AND pagesrc.page_id=plf.pl_from AND (';
19211969 $sSqlSelPage = ', pagesrc.page_title as sel_title, pagesrc.page_namespace as sel_ns';
19221970 $n=0;
1923 - foreach ($aLinksFrom as $link) {
1924 - if ($n>0) $sSqlCond_page_pl .= ' OR ';
1925 - $sSqlCond_page_pl .= '(plf.pl_from=' . $link->getArticleID().')';
1926 - $n++;
1927 - }
 1971+ foreach ($aLinksFrom as $links) {
 1972+ foreach ($links as $link) {
 1973+ if ($n>0) $sSqlCond_page_pl .= ' OR ';
 1974+ $sSqlCond_page_pl .= '(plf.pl_from=' . $link->getArticleID().')';
 1975+ $n++;
 1976+ }
 1977+ }
19281978 $sSqlCond_page_pl .= ')';
19291979 }
19301980 }
@@ -1933,10 +1983,12 @@
19341984 if ($acceptOpenReferences) {
19351985 $sSqlCond_page_pl .= ' AND (';
19361986 $n=0;
1937 - foreach ($aNotLinksFrom as $link) {
1938 - if ($n>0) $sSqlCond_page_pl .= ' AND ';
1939 - $sSqlCond_page_pl .= 'pl_from <> ' . $link->getArticleID(). ' ';
1940 - $n++;
 1987+ foreach ($aNotLinksFrom as $links) {
 1988+ foreach ($links as $link) {
 1989+ if ($n>0) $sSqlCond_page_pl .= ' AND ';
 1990+ $sSqlCond_page_pl .= 'pl_from <> ' . $link->getArticleID(). ' ';
 1991+ $n++;
 1992+ }
19411993 }
19421994 $sSqlCond_page_pl .= ')';
19431995 }
@@ -1944,10 +1996,12 @@
19451997 $sSqlCond_page_pl .= ' AND CONCAT(page_namespace,page_title) not in (select CONCAT('.$sPageLinksTable.'.pl_namespace,'
19461998 .$sPageLinksTable.'.pl_title) from '.$sPageLinksTable.' where (';
19471999 $n=0;
1948 - foreach ($aNotLinksFrom as $link) {
1949 - if ($n>0) $sSqlCond_page_pl .= ' OR ';
1950 - $sSqlCond_page_pl .= $sPageLinksTable.'.pl_from=' . $link->getArticleID(). ' ';
1951 - $n++;
 2000+ foreach ($aNotLinksFrom as $links) {
 2001+ foreach ($links as $link) {
 2002+ if ($n>0) $sSqlCond_page_pl .= ' OR ';
 2003+ $sSqlCond_page_pl .= $sPageLinksTable.'.pl_from=' . $link->getArticleID(). ' ';
 2004+ $n++;
 2005+ }
19522006 }
19532007 $sSqlCond_page_pl .= '))';
19542008 }
@@ -1959,12 +2013,28 @@
19602014 $sSqlCond_page_el .= ' AND '.$sPageTable.'.page_id=el.el_from AND (';
19612015 $sSqlSelPage = ', el.el_to as el_to';
19622016 $n=0;
1963 - foreach ($aLinksToExternal as $link) {
1964 - if ($n>0) $sSqlCond_page_el .= ' OR ';
1965 - $sSqlCond_page_el .= '(el.el_to LIKE ' . $dbr->addQuotes( $link ).')';
1966 - $n++;
 2017+ foreach ($aLinksToExternal as $linkGroup) {
 2018+ if (++$n>1) break;
 2019+ $m=0;
 2020+ foreach ($linkGroup as $link) {
 2021+ if (++$m>1) $sSqlCond_page_el .= ' OR ';
 2022+ $sSqlCond_page_el .= '(el.el_to LIKE ' . $dbr->addQuotes( $link ).')';
 2023+ }
 2024+ }
 2025+ $sSqlCond_page_el .= ')';
 2026+ }
 2027+ if ( count($aLinksToExternal)>1 ) {
 2028+ $n=0;
 2029+ foreach ($aLinksToExternal as $linkGroup) {
 2030+ if (++$n == 1) continue;
 2031+ $m=0;
 2032+ $sSqlCond_page_el .= ' AND EXISTS(select el_from from '.$sExternalLinksTable.' where ('.$sExternalLinksTable.'.el_from=page_id AND (';
 2033+ foreach ($linkGroup as $link) {
 2034+ if (++$m>1) $sSqlCond_page_el .= ' OR ';
 2035+ $sSqlCond_page_el .= '('.$sExternalLinksTable.'.el_to LIKE ' . $dbr->addQuotes( $link ).')';
 2036+ }
 2037+ $sSqlCond_page_el .= ')))';
19672038 }
1968 - $sSqlCond_page_el .= ')';
19692039 }
19702040
19712041 // imageused
@@ -2145,7 +2215,7 @@
21462216 if ($bAddPageTouchedDate && $sSqlPage_touched=='')
21472217 $sSqlPage_touched = ", $sPageTable.page_touched as page_touched";
21482218 if ($bAddUser || $bAddAuthor || $bAddLastEditor || $sSqlRevisionTable != '')
2149 - $sSqlRev_user = ', rev_user, rev_user_text';
 2219+ $sSqlRev_user = ', rev_user, rev_user_text, rev_comment';
21502220 if ($bAddCategories) {
21512221 $sSqlCats = ", GROUP_CONCAT(DISTINCT cl_gc.cl_to ORDER BY cl_gc.cl_to ASC SEPARATOR ' | ') AS cats";
21522222 // Gives list of all categories linked from each article, if any.
@@ -2187,7 +2257,7 @@
21882258 $sCategoryComparisonMode . $dbr->addQuotes(str_replace(' ','_',$aIncludeCategories[$i][0]));
21892259 for ($j = 1; $j < count($aIncludeCategories[$i]); $j++)
21902260 $sSqlSelectFrom .= ' OR cl' . $iClTable . '.cl_to' . $sCategoryComparisonMode . $dbr->addQuotes(str_replace(' ','_',$aIncludeCategories[$i][$j]));
2191 - $sSqlSelectFrom .= ') ';
 2261+ $sSqlSelectFrom .= ') ';
21922262 $iClTable++;
21932263 }
21942264
@@ -2472,8 +2542,10 @@
24732543 }
24742544
24752545 if ($dbr->numRows( $res ) <= 0) {
2476 - if ($sNoResultsHeader != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsHeader));
2477 - if ($sNoResultsFooter != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsFooter));
 2546+ $header = str_replace('%TOTALPAGES%','0',str_replace('%PAGES%','0',$sNoResultsHeader));
 2547+ if ($sNoResultsHeader != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $header));
 2548+ $footer = str_replace('%TOTALPAGES%','0',str_replace('%PAGES%','0',$sNoResultsFooter));
 2549+ if ($sNoResultsFooter != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $footer));
24782550 if ($sNoResultsHeader == '' && $sNoResultsFooter == '') $output .= $logger->escapeMsg(DPL_i18n::WARN_NORESULTS);
24792551 $dbr->freeResult( $res );
24802552 return $output;
@@ -2644,6 +2716,7 @@
26452717 if($bAddUser || $bAddAuthor || $bAddLastEditor || $sLastRevisionBefore.$sAllRevisionsBefore.$sFirstRevisionSince.$sAllRevisionsSince != '') {
26462718 $dplArticle->mUserLink = '[[User:'.$row->rev_user_text.'|'.$row->rev_user_text.']]';
26472719 $dplArticle->mUser = $row->rev_user_text;
 2720+ $dplArticle->mComment = $row->rev_comment;
26482721 }
26492722
26502723 //CATEGORY LINKS FROM CURRENT PAGE
@@ -2714,8 +2787,10 @@
27152788 if ($sOneResultHeader != '' && $rowcount==1) {
27162789 $header = str_replace('%TOTALPAGES%',$rowcount,str_replace('%PAGES%',1,$sOneResultHeader));
27172790 } else if ($rowcount==0) {
2718 - if ($sNoResultsHeader != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsHeader));
2719 - if ($sNoResultsFooter != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $sNoResultsFooter));
 2791+ $header = str_replace('%TOTALPAGES%',$rowcount,str_replace('%PAGES%',$dpl->getRowCount(),$sNoResultsHeader));
 2792+ if ($sNoResultsHeader != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $header));
 2793+ $footer = str_replace('%TOTALPAGES%',$rowcount,str_replace('%PAGES%',$dpl->getRowCount(),$sNoResultsFooter));
 2794+ if ($sNoResultsFooter != '') $output .= str_replace( '\n', "\n", str_replace( "¶", "\n", $footer));
27202795 if ($sNoResultsHeader == '' && $sNoResultsFooter == '') $output .= $logger->escapeMsg(DPL_i18n::WARN_NORESULTS);
27212796 }
27222797 else {
@@ -2757,6 +2832,9 @@
27582833 $footer = str_replace('%SCROLLDIR%', $scrollDir, $footer);
27592834
27602835 $output .= $header . $dplResult . $footer;
 2836+
 2837+ self::defineScrollVariables($firstNamespaceFound,$firstTitleFound,$lastNamespaceFound,$lastTitleFound,
 2838+ $scrollDir,$iCount,"$dplElapsedTime ($nowTimeStamp)",$rowcount,$dpl->getRowCount());
27612839
27622840 // save generated wiki text to dplcache page if desired
27632841
@@ -2863,6 +2941,34 @@
28642942 // auxiliary functions ===============================================================================
28652943
28662944
 2945+ // get a list of valid page names; returns true if valid args found
 2946+ private static function getPageNameList($cmd, $text, &$aLinks, &$bSelectionCriteriaFound, $logger, $mustExist=true) {
 2947+ $theLinks = array();
 2948+ $errorMsg='';
 2949+ $pages = explode('|', trim($text));
 2950+ foreach($pages as $page) {
 2951+ if (($page=trim($page))=='') continue;
 2952+ // sequences like %1a would be translated to hex chars; we avoid this by escaping the cahr after the %
 2953+ $page=str_replace('%','%\\',$page);
 2954+ if ($page[strlen($page)-1]=='\\') $page=substr($page,0,strlen($page)-1);
 2955+ if ($mustExist) {
 2956+ if (!($theTitle = Title::newFromText($page))) {
 2957+ $errorMsg .= $logger->msgWrongParam($cmd, $page)."<br/>\n";
 2958+ continue;
 2959+ }
 2960+ $theLinks[] = $theTitle;
 2961+ }
 2962+ else {
 2963+ $theLinks[] = $page;
 2964+ }
 2965+ }
 2966+ if (!empty($theLinks)) {
 2967+ $aLinks[] = $theLinks;
 2968+ $bSelectionCriteriaFound=true;
 2969+ }
 2970+ return $errorMsg;
 2971+ }
 2972+
28672973 // create keys for TableRow which represent the structure of the "include=" arguments
28682974 private static function updateTableRowKeys(&$aTableRow,$aSecLabels) {
28692975 $tableRow = $aTableRow;
@@ -2969,4 +3075,36 @@
29703076 return str_replace('{%'.$arg.'%}' , $dplArg ,$input);
29713077 }
29723078 }
 3079+
 3080+ // this function uses the Variables extension to provide URL-arguments like &DPL_xyz=abc
 3081+ // in the form of a variable which can be accessed as {{#var:xyz}} if ExtensionVariables is installed
 3082+ private static function getUrlArgs() {
 3083+ global $wgRequest, $wgExtVariables;
 3084+ if (!isset($wgExtVariables)) return;
 3085+ $args = $wgRequest->getValues();
 3086+ $dummy='';
 3087+ foreach ($args as $argName => $argValue) {
 3088+ if (substr($argName,0,4) == 'DPL_') {
 3089+ $wgExtVariables->vardefine($dummy,$argName,$argValue);
 3090+ }
 3091+ }
 3092+ }
 3093+
 3094+ // this function uses the Variables extension to provide navigation aids like DPL_firstTitle, DPL_lastTitle, DPL_findTitle
 3095+ // these variables can be accessed as {{#var:DPL_firstTitle}} etc. if ExtensionVariables is installed
 3096+ private static function defineScrollVariables($firstNamespace,$firstTitle,$lastNamespace,$lastTitle,
 3097+ $scrollDir,$dplCount,$dplElapsedTime,$totalPages,$pages) {
 3098+ global $wgExtVariables;
 3099+ if (!isset($wgExtVariables)) return;
 3100+ $dummy='';
 3101+ $wgExtVariables->vardefine($dummy,'DPL_firstNamespace',$firstNamespace);
 3102+ $wgExtVariables->vardefine($dummy,'DPL_firstTitle',$firstTitle);
 3103+ $wgExtVariables->vardefine($dummy,'DPL_lastNamespace',$lastNamespace);
 3104+ $wgExtVariables->vardefine($dummy,'DPL_lastTitle',$lastTitle);
 3105+ $wgExtVariables->vardefine($dummy,'DPL_scrollDir' ,$scrollDir);
 3106+ $wgExtVariables->vardefine($dummy,'DPL_time' ,$dplElapsedTime);
 3107+ $wgExtVariables->vardefine($dummy,'DPL_count' ,$dplCount);
 3108+ $wgExtVariables->vardefine($dummy,'DPL_totalPages' ,$totalPages);
 3109+ $wgExtVariables->vardefine($dummy,'DPL_pages' ,$pages);
 3110+ }
29733111 }
Index: trunk/extensions/DynamicPageList/DynamicPageListMigration.php
@@ -40,7 +40,7 @@
4141
4242 $wgHooks['LanguageGetMagic'][] = 'ExtDynamicPageList__languageGetMagic';
4343
44 -$DPLVersion = '1.8.8';
 44+$DPLVersion = '1.8.9';
4545
4646 $wgExtensionCredits['parserhook'][] = array(
4747 'path' => __FILE__,

Status & tagging log

  • 00:25, 4 December 2009 Siebrand (Talk | contribs) changed the status of r58681 [removed: new added: deferred]
Personal tools
Namespaces

Variants
Views
Actions
Navigation
Support
Download
Development
Communication
Toolbox