| Index: trunk/extensions/DynamicPageList/DynamicPageList.php |
| — | — | @@ -59,7 +59,7 @@ |
| 60 | 60 | |
| 61 | 61 | $wgHooks['LanguageGetMagic'][] = 'ExtDynamicPageList__languageGetMagic'; |
| 62 | 62 | |
| 63 | | -$DPLVersion = '1.8.8'; |
| | 63 | +$DPLVersion = '1.8.9'; |
| 64 | 64 | |
| 65 | 65 | $wgExtensionCredits['parserhook'][] = array( |
| 66 | 66 | 'path' => __FILE__, |
| Index: trunk/extensions/DynamicPageList/DPL.php |
| — | — | @@ -199,6 +199,7 @@ |
| 200 | 200 | $sTag = str_replace('%NAMESPACE%',$this->nameSpaces[$article->mNamespace],$sTag); |
| 201 | 201 | $sTag = str_replace('%IMAGE%',$imageUrl,$sTag); |
| 202 | 202 | $sTag = str_replace('%EXTERNALLINK%',$article->mExternalLink,$sTag); |
| | 203 | + $sTag = str_replace('%EDITSUMMARY%',$article->mComment,$sTag); |
| 203 | 204 | |
| 204 | 205 | $title = $article->mTitle->getText(); |
| 205 | 206 | if (strpos($title,'%TITLE%')>=0) { |
| — | — | @@ -233,16 +234,18 @@ |
| 234 | 235 | } |
| 235 | 236 | } |
| 236 | 237 | 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 | + } |
| 247 | 250 | return $sTag; |
| 248 | 251 | } |
| 249 | 252 | |
| — | — | @@ -316,7 +319,7 @@ |
| 317 | 320 | if (array_key_exists('0',$mode->sSectionTags)){ |
| 318 | 321 | $incwiki .= $this->substTagParm($mode->sSectionTags[0], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen); |
| 319 | 322 | $pieces = array(0=>$text); |
| 320 | | - $this->formatSingleItems($pieces, 0); |
| | 323 | + $this->formatSingleItems($pieces, 0, $article); |
| 321 | 324 | $incwiki .= $pieces[0]; |
| 322 | 325 | } |
| 323 | 326 | else $incwiki .= $text; |
| — | — | @@ -342,17 +345,27 @@ |
| 343 | 346 | if ($sSecLabel[0] == '%') $sSecLabel = '#'.$sSecLabel; |
| 344 | 347 | |
| 345 | 348 | $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] != '{') { |
| 347 | 356 | $limpos = strpos($sSecLabel,'['); |
| 348 | 357 | $cutLink='default'; |
| 349 | | - $skipPattern=''; |
| | 358 | + $skipPattern=array(); |
| 350 | 359 | 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)); |
| 353 | 362 | $sSecLabel=substr($sSecLabel,0,$limpos); |
| | 363 | + $cutInfo=explode(" ",$fmtSec[count($fmtSec)-1],2); |
| 354 | 364 | $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 | + } |
| 357 | 370 | } |
| 358 | 371 | if ($maxlen<0) $maxlen = -1; // without valid limit include whole section |
| 359 | 372 | } |
| — | — | @@ -365,13 +378,16 @@ |
| 366 | 379 | $mustNotMatch = $this->mIncSecLabelsNotMatch[$s]; |
| 367 | 380 | else $mustNotMatch = ''; |
| 368 | 381 | |
| 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 |
| 370 | 383 | $sectionHeading[0]=''; |
| 371 | | - if($sSecLabel[0] == '#') { |
| | 384 | + if($sSecLabel=='-') { |
| | 385 | + $secPiece[$s] = $secPieces[0]; |
| | 386 | + |
| | 387 | + } else if($sSecLabel[0] == '#' || $sSecLabel[0] == '@') { |
| 372 | 388 | $sectionHeading[0]=substr($sSecLabel,1); |
| 373 | 389 | // Uses DPLInclude::includeHeading() from LabeledSectionTransclusion extension to include headings from the page |
| 374 | 390 | $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); |
| 376 | 392 | if ($mustMatch!='' || $mustNotMatch!='') { |
| 377 | 393 | $secPiecesTmp = $secPieces; |
| 378 | 394 | $offset=0; |
| — | — | @@ -383,8 +399,10 @@ |
| 384 | 400 | } |
| 385 | 401 | } |
| 386 | 402 | } |
| | 403 | + // if maxlen was 0 we suppress all output; note that for matching we used the full text |
| | 404 | + if ($maxlen==0) $secPieces=array(''); |
| 387 | 405 | |
| 388 | | - $this->formatSingleItems($secPieces,$s); |
| | 406 | + $this->formatSingleItems($secPieces,$s,$article); |
| 389 | 407 | if (!array_key_exists(0,$secPieces)) { |
| 390 | 408 | // avoid matching against a non-existing array element |
| 391 | 409 | // and skip the article if there was a match condition |
| — | — | @@ -408,11 +426,17 @@ |
| 409 | 427 | |
| 410 | 428 | } else if($sSecLabel[0] == '{') { |
| 411 | 429 | // Uses DPLInclude::includeTemplate() from LabeledSectionTransclusion extension to include templates from the page |
| | 430 | + // primary syntax {template}suffix |
| 412 | 431 | $template1 = trim(substr($sSecLabel,1,strpos($sSecLabel,'}')-1)); |
| 413 | 432 | $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 | + } |
| 414 | 438 | $secPieces = DPLInclude::includeTemplate($this->mParser, $this, $s, $article, $template1, |
| 415 | 439 | $template2, $template2.$defaultTemplateSuffix,$mustMatch, |
| 416 | | - $mustNotMatch,$this->mIncParsed,$iTitleMaxLen); |
| | 440 | + $mustNotMatch,$this->mIncParsed,$iTitleMaxLen,implode(', ', $article->mCategoryLinks)); |
| 417 | 441 | $secPiece[$s] = implode(isset($mode->aMultiSecSeparators[$s])? |
| 418 | 442 | $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen):'',$secPieces); |
| 419 | 443 | if ($mode->iDominantSection>=0 && $s==$mode->iDominantSection && count($secPieces)>1) $dominantPieces=$secPieces; |
| — | — | @@ -502,9 +526,14 @@ |
| 503 | 527 | $nv = $this->msgExt( 'nviews', array( 'parsemag', 'escape'), $wgLang->formatNum( $article->mCounter ) ); |
| 504 | 528 | $rBody .= ' ' . $wgContLang->getDirMark() . '(' . $nv . ')'; |
| 505 | 529 | } |
| 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 | + } |
| 507 | 534 | if($article->mContributor != '')$rBody .= ' . . [[User:' . $article->mContributor .'|'.$article->mContributor." $article->mContrib]]"; |
| 508 | 535 | |
| | 536 | + |
| | 537 | + |
| 509 | 538 | if( !empty($article->mCategoryLinks) ) $rBody .= ' . . <SMALL>' . wfMsg('categories') . ': ' . implode(' | ', $article->mCategoryLinks) . '</SMALL>'; |
| 510 | 539 | if( $this->mAddExternalLink && $article->mExternalLink!= '') $rBody .= ' → ' . $article->mExternalLink; |
| 511 | 540 | } |
| — | — | @@ -596,6 +625,7 @@ |
| 597 | 626 | $action=''; |
| 598 | 627 | $hidden=array(); |
| 599 | 628 | $legendPage=''; |
| | 629 | + $instructionPage=''; |
| 600 | 630 | $table=''; |
| 601 | 631 | $fieldFormat=''; |
| 602 | 632 | |
| — | — | @@ -637,26 +667,27 @@ |
| 638 | 668 | } |
| 639 | 669 | } |
| 640 | 670 | } |
| 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; |
| 649 | 680 | |
| 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; |
| 652 | 683 | |
| 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; |
| 658 | 689 | |
| 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) |
| 661 | 692 | } |
| 662 | 693 | |
| 663 | 694 | if ($summary=='') { |
| — | — | @@ -699,6 +730,15 @@ |
| 700 | 731 | $legendText = preg_replace('/^.*?\<section\s+begin\s*=\s*legend\s*\/\>/s','',$legendText); |
| 701 | 732 | $legendText = preg_replace('/\<section\s+end\s*=\s*legend\s*\/\>.*/s','',$legendText); |
| 702 | 733 | } |
| | 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 | + } |
| 703 | 743 | // construct an edit form containing all template invocations |
| 704 | 744 | $form="<html><form method=post action=\"$action\" $editForm>\n"; |
| 705 | 745 | foreach ($tpv as $call => $tplValues) { |
| — | — | @@ -706,6 +746,15 @@ |
| 707 | 747 | foreach ($parameter as $nr => $parm) { |
| 708 | 748 | // try to extract legend from the docs of the template |
| 709 | 749 | $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 | + } |
| 710 | 759 | $myFormat='' ; if (array_key_exists($nr,$format)) $myFormat = $format[$nr]; |
| 711 | 760 | $myOptional=array_key_exists($nr,$optional); |
| 712 | 761 | if ($legendText !='' && $myToolTip=='') { |
| — | — | @@ -716,8 +765,9 @@ |
| 717 | 766 | $myToolTip=preg_replace('/\<section\s+end\s*=\s*'.preg_quote($parm,'/').'\s*\/\>.*/s','',$myToolTip); |
| 718 | 767 | } |
| 719 | 768 | } |
| 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); |
| 722 | 772 | } |
| 723 | 773 | $form .= "</table>\n<br/><br/>"; |
| 724 | 774 | } |
| — | — | @@ -800,7 +850,7 @@ |
| 801 | 851 | } |
| 802 | 852 | } |
| 803 | 853 | |
| 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) { |
| 805 | 855 | $matches=array(); |
| 806 | 856 | $nlCount = preg_match_all('/\n/',$value,$matches); |
| 807 | 857 | if ($nlCount>0) $rows= $nlCount+1; |
| — | — | @@ -809,9 +859,11 @@ |
| 810 | 860 | $cols=50; |
| 811 | 861 | if (preg_match('/cols\s*=/',$format)<=0) $format.= " cols=$cols"; |
| 812 | 862 | $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, |
| 814 | 865 | 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))))); |
| 816 | 868 | } |
| 817 | 869 | |
| 818 | 870 | /** |
| — | — | @@ -819,6 +871,7 @@ |
| 820 | 872 | */ |
| 821 | 873 | function getTemplateParmValues($text,$template) { |
| 822 | 874 | $matches=array(); |
| | 875 | +// $noMatches = preg_match_all('/\{\{\s*'.preg_quote($template,'/').'\s*((\<!--).*?(--\>)\s*)*[|}]/i',$text,$matches,PREG_OFFSET_CAPTURE); |
| 823 | 876 | $noMatches = preg_match_all('/\{\{\s*'.preg_quote($template,'/').'\s*[|}]/i',$text,$matches,PREG_OFFSET_CAPTURE); |
| 824 | 877 | if ($noMatches<=0) return ''; |
| 825 | 878 | $textLen = strlen($text); |
| — | — | @@ -829,7 +882,6 @@ |
| 830 | 883 | foreach($matchA as $matchB) { |
| 831 | 884 | $match=$matchB[0]; |
| 832 | 885 | $start=$matchB[1]; |
| 833 | | - |
| 834 | 886 | $tval[++$call]=array(); |
| 835 | 887 | $nr=0; // number of parameter if no name given |
| 836 | 888 | $parmValue=''; |
| — | — | @@ -848,6 +900,7 @@ |
| 849 | 901 | // parameter (name or value) found |
| 850 | 902 | if ($parmName=='') $tval[$call][++$nr] = trim($parm); |
| 851 | 903 | else $tval[$call][$parmName] = trim($parmValue); |
| | 904 | +// die ("cbrackets=$cbrackets, parmName=<pre>$parm</pre>, parmValue=<pre>$parmValue</pre>"); |
| 852 | 905 | $parmName=''; |
| 853 | 906 | $parmValue=''; |
| 854 | 907 | $parm=''; |
| — | — | @@ -866,6 +919,7 @@ |
| 867 | 920 | } |
| 868 | 921 | } |
| 869 | 922 | } |
| | 923 | +// die ("match=$match, start=$start,\ntextstart=<pre>".substr($text,$start+strlen($match), $textLen)."<pre>,\n,tval=".$tval[0].",\ntext=<pre>$text</pre>"); |
| 870 | 924 | return $tval; |
| 871 | 925 | } |
| 872 | 926 | |
| — | — | @@ -1066,7 +1120,7 @@ |
| 1067 | 1121 | } |
| 1068 | 1122 | |
| 1069 | 1123 | //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) { |
| 1071 | 1125 | $firstCall=true; |
| 1072 | 1126 | foreach ($pieces as $key => $val) { |
| 1073 | 1127 | if (array_key_exists($s,$this->mTableRow)) { |
| — | — | @@ -1083,6 +1137,20 @@ |
| 1084 | 1138 | $pieces[$key] = str_replace('%%',$val,substr($this->mTableRow[$s],$n+1)); |
| 1085 | 1139 | } |
| 1086 | 1140 | } |
| | 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 | + } |
| 1087 | 1155 | } |
| 1088 | 1156 | $firstCall=false; |
| 1089 | 1157 | } |
| — | — | @@ -1090,25 +1158,31 @@ |
| 1091 | 1159 | |
| 1092 | 1160 | //format one single template argument of one occurence of one item from the include parameter |
| 1093 | 1161 | // 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) { |
| 1095 | 1163 | // we could try to format fields differently within the first call of a template |
| 1096 | 1164 | // 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) |
| 1097 | 1168 | if (array_key_exists("$s.$argNr",$this->mTableRow)) { |
| | 1169 | + $n=-1; |
| 1098 | 1170 | if ($s>=1 && $argNr==0 && !$firstCall) { |
| 1099 | 1171 | $n=strpos($this->mTableRow["$s.$argNr"],'|'); |
| 1100 | 1172 | if ($n===false || !(strpos(substr($this->mTableRow["$s.$argNr"],0,$n),'{')===false) |
| 1101 | 1173 | || !(strpos(substr($this->mTableRow["$s.$argNr"],0,$n),'[')===false)) { |
| 1102 | | - return $this->cutAt($maxlen,str_replace('%%',$arg,$this->mTableRow["$s.$argNr"])); |
| | 1174 | + $n= -1; |
| 1103 | 1175 | } |
| 1104 | | - else { |
| 1105 | | - return $this->cutAt($maxlen,str_replace('%%',$arg,substr($this->mTableRow["$s.$argNr"],$n+1))); |
| 1106 | | - } |
| 1107 | 1176 | } |
| 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; |
| 1111 | 1183 | } |
| 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; |
| 1113 | 1187 | } |
| 1114 | 1188 | |
| 1115 | 1189 | //return the total number of rows (filtered) |
| — | — | @@ -1116,7 +1190,17 @@ |
| 1117 | 1191 | return $this->filteredCount; |
| 1118 | 1192 | } |
| 1119 | 1193 | |
| 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 | + */ |
| 1121 | 1205 | function cutAt($lim,$text) { |
| 1122 | 1206 | if ($lim<0) return $text; |
| 1123 | 1207 | return DPLInclude::limitTranscludedText($text, $lim); |
| — | — | @@ -1138,9 +1222,26 @@ |
| 1139 | 1223 | } |
| 1140 | 1224 | return ''; |
| 1141 | 1225 | } |
| 1142 | | - |
| 1143 | 1226 | |
| 1144 | 1227 | /** |
| | 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 | + /** |
| 1145 | 1246 | * Returns message in the requested format after parsing wikitext to html |
| 1146 | 1247 | * 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). |
| 1147 | 1248 | */ |
| Index: trunk/extensions/DynamicPageList/DPLSetup.php |
| — | — | @@ -368,11 +368,39 @@ |
| 369 | 369 | * deleterules: does some kind of permission checking now |
| 370 | 370 | * various improvements in template editing (calling the edit page now for the real update) |
| 371 | 371 | * 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 ! |
| 374 | 403 | */ |
| 375 | 404 | |
| 376 | | - |
| 377 | 405 | // changed back to global functions due to trouble with older MW installations, g.s. |
| 378 | 406 | function ExtDynamicPageList__languageGetMagic( &$magicWords, $langCode ) { |
| 379 | 407 | return ExtDynamicPageList::languageGetMagic( $magicWords, $langCode ); |
| — | — | @@ -410,6 +438,10 @@ |
| 411 | 439 | // .. to be set by DynamicPageList.php and DynamicPageListMigration.php |
| 412 | 440 | public static $respectParserCache = false; // false = make page dynamic ; true = execute only when parser cache is refreshed |
| 413 | 441 | // .. 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 |
| 414 | 446 | |
| 415 | 447 | /** |
| 416 | 448 | * Map parameters to possible values. |
| — | — | @@ -455,6 +487,10 @@ |
| 456 | 488 | * Min and Max of categories allowed for an article |
| 457 | 489 | */ |
| 458 | 490 | 'categoriesminmax' => array('default' => '', 'pattern' => '/^\d*,?\d*$/'), |
| | 491 | + /** |
| | 492 | + * hiddencategories |
| | 493 | + */ |
| | 494 | + 'hiddencategories' => array('default' => 'include', 'exclude', 'only'), |
| 459 | 495 | /** |
| 460 | 496 | * perform the command and do not query the database |
| 461 | 497 | */ |
| — | — | @@ -739,6 +775,7 @@ |
| 740 | 776 | */ |
| 741 | 777 | 'title<' => NULL, |
| 742 | 778 | 'title>' => NULL, |
| | 779 | + 'scroll' => array('default' => 'false', 'true', 'no', 'yes', '0', '1', 'off', 'on'), |
| 743 | 780 | 'titlematch' => NULL, |
| 744 | 781 | 'titleregexp' => NULL, |
| 745 | 782 | 'userdateformat' => NULL, // depends on behaveAs... mode |
| — | — | @@ -848,6 +885,10 @@ |
| 849 | 886 | */ |
| 850 | 887 | 'reset' => array( 'default' => '', 'categories', 'templates', 'links', 'images', 'all', 'none'), |
| 851 | 888 | /** |
| | 889 | + * fixcategory=.. prevents a category from being reset |
| | 890 | + */ |
| | 891 | + 'fixcategory' => array( 'default' => ''), |
| | 892 | + /** |
| 852 | 893 | * number of rows for output, default is 1 |
| 853 | 894 | * note: a "row" is a group of lines for which the heading tags defined in listseparators/format will be repeated |
| 854 | 895 | */ |
| — | — | @@ -919,6 +960,7 @@ |
| 920 | 961 | addfirstcategorydate |
| 921 | 962 | category |
| 922 | 963 | count |
| | 964 | + hiddencategories |
| 923 | 965 | mode |
| 924 | 966 | namespace |
| 925 | 967 | notcategory |
| — | — | @@ -956,6 +998,7 @@ |
| 957 | 999 | rowcolformat |
| 958 | 1000 | rows |
| 959 | 1001 | rowsize |
| | 1002 | + scroll |
| 960 | 1003 | title |
| 961 | 1004 | title< |
| 962 | 1005 | title> |
| — | — | @@ -979,6 +1022,7 @@ |
| 980 | 1023 | dplcache |
| 981 | 1024 | dplcacheperiod |
| 982 | 1025 | eliminate |
| | 1026 | + fixcategory |
| 983 | 1027 | headingcount |
| 984 | 1028 | headingmode |
| 985 | 1029 | hitemattr |
| — | — | @@ -1071,6 +1115,7 @@ |
| 1072 | 1116 | $wgParser->setHook( 'DynamicPageList', array( __CLASS__, 'intersectionTag' ) ); |
| 1073 | 1117 | |
| 1074 | 1118 | $wgParser->setFunctionHook( 'dpl', array( __CLASS__, 'dplParserFunction' ) ); |
| | 1119 | + $wgParser->setFunctionHook( 'dplnum', array( __CLASS__, 'dplNumParserFunction' ) ); |
| 1075 | 1120 | $wgParser->setFunctionHook( 'dplchapter', array( __CLASS__, 'dplChapterParserFunction' ) ); |
| 1076 | 1121 | $wgParser->setFunctionHook( 'dplmatrix', array( __CLASS__, 'dplMatrixParserFunction' ) ); |
| 1077 | 1122 | |
| — | — | @@ -1113,6 +1158,10 @@ |
| 1114 | 1159 | require_once( 'DynamicPageList.i18n.php' ); |
| 1115 | 1160 | global $wgMessageCache; |
| 1116 | 1161 | |
| | 1162 | + foreach( DPL_i18n::getMessages() as $sLang => $aMsgs ) |
| | 1163 | + { |
| | 1164 | + $wgMessageCache->addMessages( $aMsgs, $sLang ); |
| | 1165 | + } |
| 1117 | 1166 | |
| 1118 | 1167 | /** |
| 1119 | 1168 | * Define codes and map debug message to min debug level above which message can be displayed |
| — | — | @@ -1153,9 +1202,10 @@ |
| 1154 | 1203 | # Add the magic word |
| 1155 | 1204 | # The first array element is case sensitivity, in this case it is not case sensitive |
| 1156 | 1205 | # 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' ); |
| 1160 | 1210 | $magicWords['DynamicPageList'] = array( 0, 'DynamicPageList' ); |
| 1161 | 1211 | # unless we return true, other parser functions extensions won't get loaded. |
| 1162 | 1212 | return true; |
| — | — | @@ -1257,6 +1307,23 @@ |
| 1258 | 1308 | |
| 1259 | 1309 | } |
| 1260 | 1310 | |
| | 1311 | + public static function dplNumParserFunction(&$parser, $text='') { |
| | 1312 | + $num = str_replace(' ',' ',$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 | + |
| 1261 | 1328 | public static function dplChapterParserFunction(&$parser, $text='', $heading=' ', $maxLength = -1, $page = '?page?', $link = 'default', $trim=false ) { |
| 1262 | 1329 | $arg_list = func_get_args(); |
| 1263 | 1330 | $output = DPLInclude::extractHeadingFromText($parser, $page, '?title?', $text, $heading, '', $sectionHeading, true, $maxLength, $link, $trim); |
| — | — | @@ -1351,15 +1418,24 @@ |
| 1352 | 1419 | return ''; |
| 1353 | 1420 | } |
| 1354 | 1421 | |
| | 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= |
| 1355 | 1427 | public static function endReset( &$parser, $text ) { |
| 1356 | 1428 | if (!self::$createdLinks['resetdone']) { |
| 1357 | 1429 | 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 | + } |
| 1358 | 1433 | // $text .= self::dumpParsedRefs($parser,"before final reset"); |
| 1359 | 1434 | 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; |
| 1361 | 1436 | if (self::$createdLinks['resetTemplates']) $parser->mOutput->mTemplates = array(); |
| 1362 | 1437 | if (self::$createdLinks['resetImages']) $parser->mOutput->mImages = array(); |
| 1363 | 1438 | // $text .= self::dumpParsedRefs($parser,"after final reset"); |
| | 1439 | + self::$fixedCategories=array(); |
| 1364 | 1440 | } |
| 1365 | 1441 | return true; |
| 1366 | 1442 | } |
| — | — | @@ -1408,16 +1484,17 @@ |
| 1409 | 1485 | |
| 1410 | 1486 | class MyBug { |
| 1411 | 1487 | |
| 1412 | | - static function trace($class,$label,$msg) { |
| | 1488 | + static function trace($class,$label,$msg='') { |
| 1413 | 1489 | $fileName = dirname(__FILE__).'/MyBug'; |
| 1414 | 1490 | if ($class=='') { |
| 1415 | 1491 | if (file_exists($fileName)) unlink(dirname(__FILE__).'/MyBug'); |
| | 1492 | + self::trace(__CLASS__,'start tracing ..'); |
| 1416 | 1493 | return; |
| 1417 | 1494 | } |
| 1418 | 1495 | $bugFile=fopen($fileName,'a'); |
| 1419 | 1496 | fwrite($bugFile,"$class -------------------------------------------------------------------------------------------- $label\n"); |
| 1420 | | - fwrite($bugFile,$msg."\n"); |
| 1421 | | - fclose($bugFile); |
| | 1497 | + if ($msg!='') fwrite($bugFile,$msg."\n"); |
| | 1498 | + fclose($bugFile); |
| 1422 | 1499 | } |
| 1423 | 1500 | |
| 1424 | 1501 | } |
| \ No newline at end of file |
| Index: trunk/extensions/DynamicPageList/DynamicPageListInclude.php |
| — | — | @@ -135,7 +135,7 @@ |
| 136 | 136 | * Handle recursive substitution here, so we can break cycles, and set up |
| 137 | 137 | * return values so that edit sections will resolve correctly. |
| 138 | 138 | **/ |
| 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()) |
| 140 | 140 | { |
| 141 | 141 | global $wgVersion; |
| 142 | 142 | |
| — | — | @@ -144,8 +144,8 @@ |
| 145 | 145 | $text = str_replace('</section>', '', $text); |
| 146 | 146 | |
| 147 | 147 | // 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); |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | 152 | |
| — | — | @@ -243,7 +243,7 @@ |
| 244 | 244 | } |
| 245 | 245 | |
| 246 | 246 | ///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()) { |
| 248 | 248 | $output = array(); |
| 249 | 249 | if (self::text($parser, $page, $title, $text) == false) { |
| 250 | 250 | $output[] = $text; |
| — | — | @@ -263,13 +263,35 @@ |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | 266 | |
| 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 | + */ |
| 270 | 283 | 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 |
| 272 | 286 | 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; |
| 274 | 296 | $cbrackets=0; |
| 275 | 297 | $n0=-1; $nb=0; |
| 276 | 298 | for ($i=0; $i<$limit;$i++) { |
| — | — | @@ -284,13 +306,48 @@ |
| 285 | 307 | if ($c == ' ') $nb = $i; |
| 286 | 308 | } |
| 287 | 309 | } |
| | 310 | + |
| 288 | 311 | // 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 |
| 291 | 314 | if ($nb>0 && $nb+15>$n0) $n0=$nb; |
| 292 | 315 | $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"); |
| 295 | 352 | return $cut.$link; |
| 296 | 353 | } |
| 297 | 354 | else if ($limit==0) { |
| — | — | @@ -305,26 +362,22 @@ |
| 306 | 363 | } |
| 307 | 364 | |
| 308 | 365 | 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()) |
| 310 | 367 | { |
| 311 | 368 | $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); |
| 318 | 376 | } |
| 319 | 377 | |
| 320 | 378 | //section inclusion - include all matching sections (return array) |
| 321 | 379 | 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() ) { |
| 323 | 381 | |
| 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.'|..→]]'; |
| 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); |
| 329 | 382 | $continueSearch = true; |
| 330 | 383 | $n=0; |
| 331 | 384 | $output[$n]=''; |
| — | — | @@ -333,25 +386,31 @@ |
| 334 | 387 | if (preg_match('/^%-?[1-9][0-9]*$/',$sec)) $nr = substr($sec,1); |
| 335 | 388 | if (preg_match('/^%0$/',$sec)) $nr = -2; // transclude text before the first section |
| 336 | 389 | |
| 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 |
| 338 | 391 | $isPlain=true; |
| 339 | | - if ($sec!='' && $sec[0]=='#') { |
| | 392 | + if ($sec!='' && ($sec[0]=='#'||$sec[0]=='@')) { |
| 340 | 393 | $sec=substr($sec,1); |
| 341 | 394 | $isPlain=false; |
| 342 | 395 | } |
| 343 | 396 | do { |
| 344 | 397 | //Generate a regex to match the === classical heading section(s) === we're |
| 345 | 398 | //interested in. |
| | 399 | + $headLine = ''; |
| 346 | 400 | if ($sec == '') { |
| 347 | 401 | $begin_off = 0; |
| 348 | 402 | $head_len = 6; |
| 349 | 403 | } else { |
| 350 | 404 | if ($nr!=0) $pat = '^(={1,6})\s*[^=\s\n][^\n=]*\s*\1\s*($)' ; |
| 351 | 405 | 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 | + } |
| 353 | 409 | 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]; |
| 355 | 413 | $head_len = strlen($m[1][0]); |
| | 414 | + $headLine = trim($m[0][0],"\n =\t"); |
| 356 | 415 | } else if ($nr == -2) { |
| 357 | 416 | $m[1][1] = strlen($text)+1; // take whole article if no heading found |
| 358 | 417 | } else { |
| — | — | @@ -359,7 +418,12 @@ |
| 360 | 419 | return $output; |
| 361 | 420 | } |
| 362 | 421 | } |
| 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.'|..→]]'; |
| | 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); |
| 364 | 428 | if ($nr==-2) { |
| 365 | 429 | // output text before first section and done |
| 366 | 430 | $piece = substr($text,0,$m[1][1]-1); |
| — | — | @@ -375,7 +439,6 @@ |
| 376 | 440 | if (preg_match( "/$pat/im", $text, $mm, PREG_OFFSET_CAPTURE, $begin_off)) |
| 377 | 441 | $end_off = $mm[0][1]-1; |
| 378 | 442 | } |
| 379 | | - |
| 380 | 443 | if (! isset($end_off)) { |
| 381 | 444 | if ($nr!=0) $pat = '^(={1,6})\s*[^\s\n=][^\n=]*\s*\1\s*$'; |
| 382 | 445 | else $pat = '^(={1,'.$head_len.'})(?!=)\s*.*?\1\s*$'; |
| — | — | @@ -406,10 +469,15 @@ |
| 407 | 470 | } |
| 408 | 471 | |
| 409 | 472 | 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]); |
| 412 | 476 | } |
| 413 | | - else $sectionHeading[$n] = ''; |
| | 477 | + else { |
| | 478 | + // $sectionHeading[$n] = ''; |
| | 479 | + $sectionHeading[0] = $headLine; |
| | 480 | + } |
| | 481 | + |
| 414 | 482 | if ($nr==1) { |
| 415 | 483 | // output n-th section and done |
| 416 | 484 | $output[0] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", $nhead, $recursionCheck, $maxLength, $link, $trim, $skipPattern); |
| — | — | @@ -438,15 +506,18 @@ |
| 439 | 507 | // and do NOT match the condition "$mustNotMatch" (if specified) |
| 440 | 508 | // we use a callback function to format retrieved parameters, accessible via $dpl->formatTemplateArg() |
| 441 | 509 | public static function includeTemplate($parser, $dpl, $dplNr, $article, $template1='', $template2='', $defaultTemplate, |
| 442 | | - $mustMatch, $mustNotMatch, $matchParsed, $iTitleMaxLen) |
| | 510 | + $mustMatch, $mustNotMatch, $matchParsed, $iTitleMaxLen, $catlist) |
| 443 | 511 | { |
| 444 | 512 | $page = $article->mTitle->getPrefixedText(); |
| 445 | 513 | $date = $article->myDate; |
| 446 | 514 | $user = $article->mUserLink; |
| 447 | 515 | $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 |
| 449 | 519 | |
| 450 | 520 | if ($template1 != '' && $template1[0]=='#') { |
| | 521 | + // --------------------------------------------- looking for a parser function call |
| 451 | 522 | $template1=substr($template1,1); |
| 452 | 523 | $template2=substr($template2,1); |
| 453 | 524 | $defaultTemplate=substr($defaultTemplate,1); |
| — | — | @@ -456,6 +527,7 @@ |
| 457 | 528 | foreach($tCalls as $i => $tCall) if (($n=strpos($tCall,':'))!==false)$tCalls[$i][$n]=' '; |
| 458 | 529 | } |
| 459 | 530 | else if ($template1 != '' && $template1[0]=='~') { |
| | 531 | + // --------------------------------------------- looking for an xml-tag extension call |
| 460 | 532 | $template1=substr($template1,1); |
| 461 | 533 | $template2=substr($template2,1); |
| 462 | 534 | $defaultTemplate=substr($defaultTemplate,1); |
| — | — | @@ -467,8 +539,18 @@ |
| 468 | 540 | } |
| 469 | 541 | } |
| 470 | 542 | 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); |
| 473 | 555 | // We restore the first separator symbol (we had to include that symbol into the SPLIT, because we must make |
| 474 | 556 | // sure that we only accept exact matches of the complete template name |
| 475 | 557 | // (e.g. when looking for "foo" we must not accept "foo xyz") |
| — | — | @@ -485,7 +567,7 @@ |
| 486 | 568 | // in that case we won´t invoke template2 but will directly return the extracted parameters |
| 487 | 569 | // as a sequence of table columns; |
| 488 | 570 | 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))); |
| 490 | 572 | } |
| 491 | 573 | |
| 492 | 574 | if (count($tCalls) <= 1) { |
| — | — | @@ -493,10 +575,10 @@ |
| 494 | 576 | if (count($extractParm)>0) { |
| 495 | 577 | // if parameters are required directly: return empty columns |
| 496 | 578 | 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); |
| 499 | 581 | } |
| 500 | | - else $output[0]=$dpl->formatTemplateArg('',$dplNr,0,true,-1); |
| | 582 | + else $output[0]=$dpl->formatTemplateArg('',$dplNr,0,true,-1,$article); |
| 501 | 583 | } else { |
| 502 | 584 | // put a red link into the output |
| 503 | 585 | $output[0]= $parser->preprocess( |
| — | — | @@ -520,7 +602,7 @@ |
| 521 | 603 | if (count($extractParm)==0) { |
| 522 | 604 | // find the end of the call: bracket level must be zero |
| 523 | 605 | $cbrackets=0; |
| 524 | | - $templateCall = '{{'.$template2.$tCall; |
| | 606 | + $templateCall = '{{'.$altNamespace.$template2.$tCall; |
| 525 | 607 | $size=strlen($templateCall); |
| 526 | 608 | for ($i=0; $i<$size;$i++) { |
| 527 | 609 | $c = $templateCall[$i]; |
| — | — | @@ -530,8 +612,10 @@ |
| 531 | 613 | // if we must match a condition: test against it |
| 532 | 614 | if (($mustMatch =='' || preg_match($mustMatch,substr($templateCall,0,$i-1))) && |
| 533 | 615 | ($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); |
| 536 | 620 | } |
| 537 | 621 | break; |
| 538 | 622 | } |
| — | — | @@ -540,7 +624,7 @@ |
| 541 | 625 | else { |
| 542 | 626 | // if the user wants parameters directly from the call line of template1 we return just those |
| 543 | 627 | $cbrackets=2; |
| 544 | | - $templateCall = preg_replace('/<!--.*-->/Us','',$tCall); |
| | 628 | + $templateCall = $tCall; |
| 545 | 629 | $size=strlen($templateCall); |
| 546 | 630 | $parms=array(); |
| 547 | 631 | $parm=''; |
| — | — | @@ -584,15 +668,15 @@ |
| 585 | 669 | if (strpos($exParm,'%')!==FALSE) { |
| 586 | 670 | // %% is a short form for inclusion of %PAGE% and %TITLE% |
| 587 | 671 | $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); |
| 589 | 673 | } |
| 590 | 674 | if (!$found) { |
| 591 | 675 | // named parameter |
| 592 | 676 | $exParmQuote = str_replace('/','\/',$exParm); |
| 593 | 677 | foreach ($parms as $parm) { |
| 594 | | - if (!preg_match("/^\s*$exParmQuote\s*(<!--.*-->)*\s*=/",$parm)) continue; |
| | 678 | + if (!preg_match("/^\s*$exParmQuote\s*=/",$parm)) continue; |
| 595 | 679 | $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); |
| 597 | 681 | break; |
| 598 | 682 | } |
| 599 | 683 | } |
| — | — | @@ -603,11 +687,11 @@ |
| 604 | 688 | if(strstr($parm, '=') === FALSE) ++$np; |
| 605 | 689 | if ($np!=$exParm) continue; |
| 606 | 690 | $found=true; |
| 607 | | - $output[$n] .= $dpl->formatTemplateArg($parm,$dplNr,$exParmKey,$firstCall,$maxlen); |
| | 691 | + $output[$n] .= $dpl->formatTemplateArg($parm,$dplNr,$exParmKey,$firstCall,$maxlen,$article); |
| 608 | 692 | break; |
| 609 | 693 | } |
| 610 | 694 | } |
| 611 | | - if (!$found) $output[$n] .= $dpl->formatTemplateArg('',$dplNr,$exParmKey,$firstCall,$maxlen); |
| | 695 | + if (!$found) $output[$n] .= $dpl->formatTemplateArg('',$dplNr,$exParmKey,$firstCall,$maxlen,$article); |
| 612 | 696 | $second=true; |
| 613 | 697 | } |
| 614 | 698 | } |
| — | — | @@ -620,4 +704,9 @@ |
| 621 | 705 | return $output; |
| 622 | 706 | } |
| 623 | 707 | |
| | 708 | + static function spaceOrUnderscore($pattern) { |
| | 709 | + // returns a pettern that matches underscores as well as spaces |
| | 710 | + return str_replace(' ','[ _]',$pattern); |
| | 711 | + } |
| | 712 | + |
| 624 | 713 | } |
| Index: trunk/extensions/DynamicPageList/DPLArticle.php |
| — | — | @@ -21,6 +21,7 @@ |
| 22 | 22 | var $mRevision = ''; // the revision number if specified |
| 23 | 23 | var $mUserLink = ''; // link to editor (first/last, depending on user's request) 's page or contributions if not registered |
| 24 | 24 | var $mUser = ''; // name of editor (first/last, depending on user's request) or contributions if not registered |
| | 25 | + var $mComment = ''; // revision comment / edit summary |
| 25 | 26 | var $mContribution= ''; // number of bytes changed |
| 26 | 27 | var $mContrib= ''; // short string indicating the size of a contribution |
| 27 | 28 | var $mContributor= ''; // user who made the changes |
| Index: trunk/extensions/DynamicPageList/DPLMain.php |
| — | — | @@ -21,7 +21,7 @@ |
| 22 | 22 | global $wgUser, $wgLang, $wgContLang, $wgRequest, $wgRawHtml; |
| 23 | 23 | global $wgTitle, $wgArticle, $wgNonincludableNamespaces; |
| 24 | 24 | |
| 25 | | - // we use "makeKnownLinkObject" to create hyperlinbks; |
| | 25 | + // we use "makeKnownLinkObject" to create hyperlinks; |
| 26 | 26 | // the code we store in the dplcache may contain <html>....</html> sequences |
| 27 | 27 | // for both reasons we need to enable rawHtml output |
| 28 | 28 | // note that this does not affect the article wiki source - a <html> tag in the wiki source |
| — | — | @@ -83,6 +83,8 @@ |
| 84 | 84 | } |
| 85 | 85 | |
| 86 | 86 | // check parameters which can be set via the URL |
| | 87 | + |
| | 88 | + self::getUrlArgs(); |
| 87 | 89 | |
| 88 | 90 | if (strpos($input,'{%DPL_') >= 0) { |
| 89 | 91 | for($i=1;$i<=5;$i++) { |
| — | — | @@ -90,10 +92,10 @@ |
| 91 | 93 | } |
| 92 | 94 | } |
| 93 | 95 | |
| | 96 | + |
| 94 | 97 | $_sOffset=$wgRequest->getVal('DPL_offset',ExtDynamicPageList::$options['offset']['default']); |
| 95 | 98 | $iOffset = ($_sOffset == '') ? 0: intval($_sOffset); |
| 96 | 99 | |
| 97 | | - $sCount = $wgRequest->getVal('DPL_count',''); |
| 98 | 100 | $iCount = -1; |
| 99 | 101 | |
| 100 | 102 | // commandline parameters like %DPL_offset% are replaced |
| — | — | @@ -103,18 +105,15 @@ |
| 104 | 106 | $input = self::resolveUrlArg($input,'DPL_findTitle'); |
| 105 | 107 | $input = self::resolveUrlArg($input,'DPL_toTitle'); |
| 106 | 108 | |
| 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 = ''; |
| 118 | 116 | |
| | 117 | + |
| 119 | 118 | $originalInput = $input; |
| 120 | 119 | |
| 121 | 120 | $bDPLRefresh = ($wgRequest->getVal('DPL_refresh','')=='yes'); |
| — | — | @@ -176,6 +175,8 @@ |
| 177 | 176 | |
| 178 | 177 | $bEscapeLinks = ExtDynamicPageList::$options['escapelinks']['default']; |
| 179 | 178 | $bSkipThisPage= ExtDynamicPageList::$options['skipthispage']['default']; |
| | 179 | + |
| | 180 | + $sHiddenCategories = ExtDynamicPageList::$options['hiddencategories']['default']; |
| 180 | 181 | |
| 181 | 182 | $sMinorEdits = NULL; |
| 182 | 183 | $acceptOpenReferences = self::argBoolean(ExtDynamicPageList::$options['openreferences']['default']); |
| — | — | @@ -290,6 +291,8 @@ |
| 291 | 292 | |
| 292 | 293 | $_sIncludeMaxLen = ExtDynamicPageList::$options['includemaxlength']['default']; |
| 293 | 294 | $iIncludeMaxLen = ($_sIncludeMaxLen == '') ? NULL: intval($_sIncludeMaxLen); |
| | 295 | + |
| | 296 | + $bScroll = self::argBoolean(ExtDynamicPageList::$options['scroll']['default']); |
| 294 | 297 | |
| 295 | 298 | $aLinksTo = array(); |
| 296 | 299 | $aNotLinksTo = array(); |
| — | — | @@ -414,11 +417,13 @@ |
| 415 | 418 | } |
| 416 | 419 | foreach($aParams as $sParam) { |
| 417 | 420 | $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]=''; |
| 419 | 424 | $bIncludeUncat = true; |
| 420 | 425 | $aCategories[] = ''; |
| 421 | 426 | } else { |
| 422 | | - if ($sParam[0]=='*') { |
| | 427 | + if ($sParam[0]=='*' && strlen($sParam)>=2) { |
| 423 | 428 | if ($sParam[1]=='*') $sParamList = explode('|',self::getSubcategories(substr($sParam,2),$sPageTable,2)); |
| 424 | 429 | else $sParamList = explode('|',self::getSubcategories(substr($sParam,1),$sPageTable,1)); |
| 425 | 430 | foreach ($sParamList as $sPar) { |
| — | — | @@ -448,6 +453,13 @@ |
| 449 | 454 | $bConflictsWithOpenReferences=true; |
| 450 | 455 | } |
| 451 | 456 | 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; |
| 452 | 464 | case 'notcategory': |
| 453 | 465 | $title = Title::newFromText($localParser->transformMsg($sArg, $pOptions)); |
| 454 | 466 | if( !is_null($title) ) { |
| — | — | @@ -597,7 +609,8 @@ |
| 598 | 610 | case 'execandexit': |
| 599 | 611 | // we offer a possibility to execute a DPL command without querying the database |
| 600 | 612 | // 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; |
| 602 | 615 | break; |
| 603 | 616 | |
| 604 | 617 | |
| — | — | @@ -765,6 +778,31 @@ |
| 766 | 779 | $bSelectionCriteriaFound=true; |
| 767 | 780 | break; |
| 768 | 781 | |
| | 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 | + |
| 769 | 807 | case 'titlemaxlength': |
| 770 | 808 | //processed like 'count' param |
| 771 | 809 | if( preg_match(ExtDynamicPageList::$options['titlemaxlength']['pattern'], $sArg) ) |
| — | — | @@ -837,64 +875,31 @@ |
| 838 | 876 | */ |
| 839 | 877 | |
| 840 | 878 | 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; |
| 850 | 881 | $bConflictsWithOpenReferences=true; |
| 851 | 882 | break; |
| 852 | 883 | |
| 853 | 884 | 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; |
| 863 | 887 | $bConflictsWithOpenReferences=true; |
| 864 | 888 | break; |
| 865 | 889 | |
| 866 | 890 | 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; |
| 876 | 894 | break; |
| 877 | 895 | |
| 878 | 896 | 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; |
| 888 | 899 | break; |
| 889 | 900 | |
| 890 | 901 | 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; |
| 899 | 904 | $bConflictsWithOpenReferences=true; |
| 900 | 905 | break; |
| 901 | 906 | |
| — | — | @@ -1255,15 +1260,20 @@ |
| 1256 | 1261 | */ |
| 1257 | 1262 | |
| 1258 | 1263 | 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 | + } |
| 1268 | 1278 | break; |
| 1269 | 1279 | |
| 1270 | 1280 | case 'dplcache': |
| — | — | @@ -1285,6 +1295,10 @@ |
| 1286 | 1296 | $output .= $logger->msgWrongParam('dplcacheperiod', $sArg); |
| 1287 | 1297 | break; |
| 1288 | 1298 | |
| | 1299 | + case 'fixcategory': |
| | 1300 | + ExtDynamicPageList::fixCategory($sArg); |
| | 1301 | + break; |
| | 1302 | + |
| 1289 | 1303 | case 'reset': |
| 1290 | 1304 | foreach (preg_split('/[;,]/',$sArg) as $arg) { |
| 1291 | 1305 | $arg=trim($arg); |
| — | — | @@ -1490,6 +1504,7 @@ |
| 1491 | 1505 | |
| 1492 | 1506 | // set COUNT |
| 1493 | 1507 | |
| | 1508 | + if ($sCount=='') $sCount = $sCountScroll; |
| 1494 | 1509 | if ($sCount=='') { |
| 1495 | 1510 | $iCount=-1; |
| 1496 | 1511 | } else { |
| — | — | @@ -1516,7 +1531,12 @@ |
| 1517 | 1532 | |
| 1518 | 1533 | |
| 1519 | 1534 | |
| 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 | + } |
| 1521 | 1541 | |
| 1522 | 1542 | |
| 1523 | 1543 | |
| — | — | @@ -1741,7 +1761,7 @@ |
| 1742 | 1762 | $sSqlPage_touched = ''; |
| 1743 | 1763 | $sSqlCalcFoundRows = ''; |
| 1744 | 1764 | 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'; |
| 1746 | 1766 | if ($sDistinctResultSet == 'false') $sSqlDistinct = ''; |
| 1747 | 1767 | else $sSqlDistinct = 'DISTINCT'; |
| 1748 | 1768 | $sSqlGroupBy = ''; |
| — | — | @@ -1865,7 +1885,7 @@ |
| 1866 | 1886 | break; |
| 1867 | 1887 | case 'user': |
| 1868 | 1888 | $sSqlRevisionTable = $sRevisionTable . ', '; |
| 1869 | | - $sSqlRev_user = ', rev_user, rev_user_text'; |
| | 1889 | + $sSqlRev_user = ', rev_user, rev_user_text, rev_comment'; |
| 1870 | 1890 | break; |
| 1871 | 1891 | case 'none': |
| 1872 | 1892 | break; |
| — | — | @@ -1873,32 +1893,58 @@ |
| 1874 | 1894 | } |
| 1875 | 1895 | |
| 1876 | 1896 | // linksto |
| | 1897 | + |
| 1877 | 1898 | if ( count($aLinksTo)>0 ) { |
| 1878 | 1899 | $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 '; |
| 1880 | 1901 | $sSqlSelPage = ', pl.pl_title as sel_title, pl.pl_namespace as sel_ns'; |
| 1881 | 1902 | $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 .= ')))'; |
| 1888 | 1932 | } |
| 1889 | | - $sSqlCond_page_pl .= ')'; |
| 1890 | 1933 | } |
| 1891 | 1934 | |
| 1892 | 1935 | // notlinksto |
| 1893 | 1936 | if ( count($aNotLinksTo)>0 ) { |
| 1894 | 1937 | $sSqlCond_page_pl .= ' AND '.$sPageTable.'.page_id not in (select '.$sPageLinksTable.'.pl_from from '.$sPageLinksTable.' where ('; |
| 1895 | 1938 | $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 | + } |
| 1903 | 1949 | $sSqlCond_page_pl .= ') )'; |
| 1904 | 1950 | } |
| 1905 | 1951 | |
| — | — | @@ -1907,10 +1953,12 @@ |
| 1908 | 1954 | if ($acceptOpenReferences) { |
| 1909 | 1955 | $sSqlCond_page_pl .= ' AND ('; |
| 1910 | 1956 | $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 | + } |
| 1915 | 1963 | } |
| 1916 | 1964 | $sSqlCond_page_pl .= ')'; |
| 1917 | 1965 | } |
| — | — | @@ -1919,11 +1967,13 @@ |
| 1920 | 1968 | $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 ('; |
| 1921 | 1969 | $sSqlSelPage = ', pagesrc.page_title as sel_title, pagesrc.page_namespace as sel_ns'; |
| 1922 | 1970 | $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 | + } |
| 1928 | 1978 | $sSqlCond_page_pl .= ')'; |
| 1929 | 1979 | } |
| 1930 | 1980 | } |
| — | — | @@ -1933,10 +1983,12 @@ |
| 1934 | 1984 | if ($acceptOpenReferences) { |
| 1935 | 1985 | $sSqlCond_page_pl .= ' AND ('; |
| 1936 | 1986 | $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 | + } |
| 1941 | 1993 | } |
| 1942 | 1994 | $sSqlCond_page_pl .= ')'; |
| 1943 | 1995 | } |
| — | — | @@ -1944,10 +1996,12 @@ |
| 1945 | 1997 | $sSqlCond_page_pl .= ' AND CONCAT(page_namespace,page_title) not in (select CONCAT('.$sPageLinksTable.'.pl_namespace,' |
| 1946 | 1998 | .$sPageLinksTable.'.pl_title) from '.$sPageLinksTable.' where ('; |
| 1947 | 1999 | $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 | + } |
| 1952 | 2006 | } |
| 1953 | 2007 | $sSqlCond_page_pl .= '))'; |
| 1954 | 2008 | } |
| — | — | @@ -1959,12 +2013,28 @@ |
| 1960 | 2014 | $sSqlCond_page_el .= ' AND '.$sPageTable.'.page_id=el.el_from AND ('; |
| 1961 | 2015 | $sSqlSelPage = ', el.el_to as el_to'; |
| 1962 | 2016 | $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 .= ')))'; |
| 1967 | 2038 | } |
| 1968 | | - $sSqlCond_page_el .= ')'; |
| 1969 | 2039 | } |
| 1970 | 2040 | |
| 1971 | 2041 | // imageused |
| — | — | @@ -2145,7 +2215,7 @@ |
| 2146 | 2216 | if ($bAddPageTouchedDate && $sSqlPage_touched=='') |
| 2147 | 2217 | $sSqlPage_touched = ", $sPageTable.page_touched as page_touched"; |
| 2148 | 2218 | if ($bAddUser || $bAddAuthor || $bAddLastEditor || $sSqlRevisionTable != '') |
| 2149 | | - $sSqlRev_user = ', rev_user, rev_user_text'; |
| | 2219 | + $sSqlRev_user = ', rev_user, rev_user_text, rev_comment'; |
| 2150 | 2220 | if ($bAddCategories) { |
| 2151 | 2221 | $sSqlCats = ", GROUP_CONCAT(DISTINCT cl_gc.cl_to ORDER BY cl_gc.cl_to ASC SEPARATOR ' | ') AS cats"; |
| 2152 | 2222 | // Gives list of all categories linked from each article, if any. |
| — | — | @@ -2187,7 +2257,7 @@ |
| 2188 | 2258 | $sCategoryComparisonMode . $dbr->addQuotes(str_replace(' ','_',$aIncludeCategories[$i][0])); |
| 2189 | 2259 | for ($j = 1; $j < count($aIncludeCategories[$i]); $j++) |
| 2190 | 2260 | $sSqlSelectFrom .= ' OR cl' . $iClTable . '.cl_to' . $sCategoryComparisonMode . $dbr->addQuotes(str_replace(' ','_',$aIncludeCategories[$i][$j])); |
| 2191 | | - $sSqlSelectFrom .= ') '; |
| | 2261 | + $sSqlSelectFrom .= ') '; |
| 2192 | 2262 | $iClTable++; |
| 2193 | 2263 | } |
| 2194 | 2264 | |
| — | — | @@ -2472,8 +2542,10 @@ |
| 2473 | 2543 | } |
| 2474 | 2544 | |
| 2475 | 2545 | 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)); |
| 2478 | 2550 | if ($sNoResultsHeader == '' && $sNoResultsFooter == '') $output .= $logger->escapeMsg(DPL_i18n::WARN_NORESULTS); |
| 2479 | 2551 | $dbr->freeResult( $res ); |
| 2480 | 2552 | return $output; |
| — | — | @@ -2644,6 +2716,7 @@ |
| 2645 | 2717 | if($bAddUser || $bAddAuthor || $bAddLastEditor || $sLastRevisionBefore.$sAllRevisionsBefore.$sFirstRevisionSince.$sAllRevisionsSince != '') { |
| 2646 | 2718 | $dplArticle->mUserLink = '[[User:'.$row->rev_user_text.'|'.$row->rev_user_text.']]'; |
| 2647 | 2719 | $dplArticle->mUser = $row->rev_user_text; |
| | 2720 | + $dplArticle->mComment = $row->rev_comment; |
| 2648 | 2721 | } |
| 2649 | 2722 | |
| 2650 | 2723 | //CATEGORY LINKS FROM CURRENT PAGE |
| — | — | @@ -2714,8 +2787,10 @@ |
| 2715 | 2788 | if ($sOneResultHeader != '' && $rowcount==1) { |
| 2716 | 2789 | $header = str_replace('%TOTALPAGES%',$rowcount,str_replace('%PAGES%',1,$sOneResultHeader)); |
| 2717 | 2790 | } 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)); |
| 2720 | 2795 | if ($sNoResultsHeader == '' && $sNoResultsFooter == '') $output .= $logger->escapeMsg(DPL_i18n::WARN_NORESULTS); |
| 2721 | 2796 | } |
| 2722 | 2797 | else { |
| — | — | @@ -2757,6 +2832,9 @@ |
| 2758 | 2833 | $footer = str_replace('%SCROLLDIR%', $scrollDir, $footer); |
| 2759 | 2834 | |
| 2760 | 2835 | $output .= $header . $dplResult . $footer; |
| | 2836 | + |
| | 2837 | + self::defineScrollVariables($firstNamespaceFound,$firstTitleFound,$lastNamespaceFound,$lastTitleFound, |
| | 2838 | + $scrollDir,$iCount,"$dplElapsedTime ($nowTimeStamp)",$rowcount,$dpl->getRowCount()); |
| 2761 | 2839 | |
| 2762 | 2840 | // save generated wiki text to dplcache page if desired |
| 2763 | 2841 | |
| — | — | @@ -2863,6 +2941,34 @@ |
| 2864 | 2942 | // auxiliary functions =============================================================================== |
| 2865 | 2943 | |
| 2866 | 2944 | |
| | 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 | + |
| 2867 | 2973 | // create keys for TableRow which represent the structure of the "include=" arguments |
| 2868 | 2974 | private static function updateTableRowKeys(&$aTableRow,$aSecLabels) { |
| 2869 | 2975 | $tableRow = $aTableRow; |
| — | — | @@ -2969,4 +3075,36 @@ |
| 2970 | 3076 | return str_replace('{%'.$arg.'%}' , $dplArg ,$input); |
| 2971 | 3077 | } |
| 2972 | 3078 | } |
| | 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 | + } |
| 2973 | 3111 | } |
| Index: trunk/extensions/DynamicPageList/DynamicPageListMigration.php |
| — | — | @@ -40,7 +40,7 @@ |
| 41 | 41 | |
| 42 | 42 | $wgHooks['LanguageGetMagic'][] = 'ExtDynamicPageList__languageGetMagic'; |
| 43 | 43 | |
| 44 | | -$DPLVersion = '1.8.8'; |
| | 44 | +$DPLVersion = '1.8.9'; |
| 45 | 45 | |
| 46 | 46 | $wgExtensionCredits['parserhook'][] = array( |
| 47 | 47 | 'path' => __FILE__, |