Index: trunk/extensions/DynamicPageList/DynamicPageList.php |
— | — | @@ -14,7 +14,7 @@ |
15 | 15 | |
16 | 16 | ExtDynamicPageList::setFunctionalRichness( <n> ); |
17 | 17 | |
18 | | - where <n> is a number between 0 and 3. |
| 18 | + where <n> is a number between 0 and 4. |
19 | 19 | |
20 | 20 | If your wiki has been using Extension:Intersection you must UNINSTALL that |
21 | 21 | extension before you can use DynamicPageList (DPL). |
— | — | @@ -36,7 +36,7 @@ |
37 | 37 | on your server / database. For wikis up to 10.000 pages this is normally not a problem, |
38 | 38 | but with larger wikis some care is advisable. |
39 | 39 | |
40 | | - By default the RichnessLevel is set to 3 (= activate whole set of functions). |
| 40 | + By default the RichnessLevel is set to 4 (= activate whole set of functions). |
41 | 41 | |
42 | 42 | Use a different value if you do not feel comfortable with this: |
43 | 43 | - level=0 will not allow any additional functionality (compared to Extension:Intersection). |
— | — | @@ -59,16 +59,16 @@ |
60 | 60 | |
61 | 61 | $wgHooks['LanguageGetMagic'][] = 'ExtDynamicPageList__languageGetMagic'; |
62 | 62 | |
63 | | -$DPLVersion = '1.8.6'; |
| 63 | +$DPLVersion = '1.8.7'; |
64 | 64 | |
65 | 65 | $wgExtensionCredits['parserhook'][] = array( |
66 | | - 'path' => __FILE__, |
67 | | - 'name' => 'DynamicPageList', |
68 | | - 'author' => '[http://de.wikipedia.org/wiki/Benutzer:Algorithmix Gero Scholz]', |
69 | | - 'url' => 'http://www.mediawiki.org/wiki/Extension:DynamicPageList_(third-party)', |
70 | | - 'description' => 'A highly flexible report generator for MediaWikis - manual and examples: see [http://semeb.com/dpldemo]', |
71 | | - 'descriptionmsg' => 'dpl-desc', |
72 | | - 'version' => $DPLVersion |
| 66 | + 'path' => __FILE__, |
| 67 | + 'name' => 'DynamicPageList', |
| 68 | + 'author' => '[http://de.wikipedia.org/wiki/Benutzer:Algorithmix Gero Scholz]', |
| 69 | + 'url' => 'http://www.mediawiki.org/wiki/Extension:DynamicPageList_(third-party)', |
| 70 | + 'description' => 'A highly flexible report generator for MediaWikis - manual and examples: see [http://semeb.com/dpldemo]', |
| 71 | + 'descriptionmsg' => 'dpl-desc', |
| 72 | + 'version' => $DPLVersion |
73 | 73 | ); |
74 | 74 | |
75 | 75 | require_once( 'DPLSetup.php' ); |
— | — | @@ -77,3 +77,5 @@ |
78 | 78 | |
79 | 79 | // use full functionality by default |
80 | 80 | ExtDynamicPageList::setFunctionalRichness(4); |
| 81 | + |
| 82 | +// MyBug::trace('','',''); |
Index: trunk/extensions/DynamicPageList/DPL.php |
— | — | @@ -30,6 +30,7 @@ |
31 | 31 | $listmode, $bescapelinks, $baddexternallink, $includepage, $includemaxlen, $includeseclabels, $includeseclabelsmatch, |
32 | 32 | $includeseclabelsnotmatch, $includematchparsed, &$parser, $logger, $replaceInTitle, $iTitleMaxLen, |
33 | 33 | $defaultTemplateSuffix, $aTableRow, $bIncludeTrim, $iTableSortCol, $updateRules, $deleteRules ) { |
| 34 | + |
34 | 35 | global $wgContLang; |
35 | 36 | $this->nameSpaces = $wgContLang->getNamespaces(); |
36 | 37 | $this->mArticles = $articles; |
— | — | @@ -46,12 +47,22 @@ |
47 | 48 | |
48 | 49 | if (isset($includemaxlen)) $this->mIncMaxLen = $includemaxlen + 1; |
49 | 50 | else $this->mIncMaxLen = 0; |
50 | | - $this->mParser = $parser; |
51 | | - $this->mParserOptions = $parser->mOptions; |
52 | | - $this->mParserTitle = $parser->mTitle; |
53 | 51 | $this->mLogger = $logger; |
54 | 52 | $this->mReplaceInTitle = $replaceInTitle; |
55 | 53 | $this->mTableRow = $aTableRow; |
| 54 | + |
| 55 | + // cloning the parser in the following statement leads in some cases to a php error in MW 1.15 |
| 56 | + // You must apply the following patch to avoid this: |
| 57 | + // add in LinkHoldersArray.php at the beginning of function 'merge' the following code lines: |
| 58 | + // if (!isset($this->interwikis)) { |
| 59 | + // $this->internals = array(); |
| 60 | + // $this->interwikis = array(); |
| 61 | + // $this->size = 0; |
| 62 | + // $this->parent = $other->parent; |
| 63 | + // } |
| 64 | + $this->mParser = clone $parser; |
| 65 | + $this->mParserOptions = $parser->mOptions; |
| 66 | + $this->mParserTitle = $parser->mTitle; |
56 | 67 | |
57 | 68 | if(!empty($headings)) { |
58 | 69 | if ($iColumns!=1 || $iRows!=1) { |
— | — | @@ -161,7 +172,9 @@ |
162 | 173 | } else { |
163 | 174 | $this->mOutput .= $this->formatList(0, count($articles), $iTitleMaxLen, $defaultTemplateSuffix, $bIncludeTrim, $iTableSortCol, $updateRules, $deleteRules); |
164 | 175 | } |
165 | | - |
| 176 | + |
| 177 | + // MyBug::trace(__CLASS__,'DPL end',$this->mOutput); |
| 178 | + |
166 | 179 | } |
167 | 180 | |
168 | 181 | function formatCount($numart) { |
— | — | @@ -251,7 +264,14 @@ |
252 | 265 | if ($article->mNamespace==6) { |
253 | 266 | // calculate URL for existing images |
254 | 267 | $img = Image::newFromName($article->mTitle->getText()); |
255 | | - if ($img && $img->exists()) $imageUrl = $img->getURL(); |
| 268 | + if ($img && $img->exists()) { |
| 269 | + $imageUrl = $img->getURL(); |
| 270 | + $imageUrl= preg_replace('~^.*images/(.*)~','\1',$imageUrl); |
| 271 | + } |
| 272 | + else { |
| 273 | + $iTitle = Title::makeTitleSafe(6,$article->mTitle->getDBKey()); |
| 274 | + $imageUrl = preg_replace('~^.*images/(.*)~','\1',RepoGroup::singleton()->getLocalRepo()->newFile($iTitle)->getPath()); |
| 275 | + } |
256 | 276 | } |
257 | 277 | if ($this->mEscapeLinks && ($article->mNamespace==14 || $article->mNamespace==6) ) { |
258 | 278 | // links to categories or images need an additional ":" |
— | — | @@ -321,11 +341,14 @@ |
322 | 342 | if($sSecLabel[0] != '{') { |
323 | 343 | $limpos = strpos($sSecLabel,'['); |
324 | 344 | $cutLink='default'; |
| 345 | + $skipPattern=''; |
325 | 346 | if ($limpos>0 && $sSecLabel[strlen($sSecLabel)-1]==']') { |
326 | | - $cutInfo=explode(" ",substr($sSecLabel,$limpos+1,strlen($sSecLabel)-$limpos-2),2); |
| 347 | + $fmtSec=explode('~',substr($sSecLabel,$limpos+1,strlen($sSecLabel)-$limpos-2),2); |
| 348 | + $cutInfo=explode(" ",$fmtSec[0],2); |
327 | 349 | $sSecLabel=substr($sSecLabel,0,$limpos); |
328 | 350 | $maxlen=intval($cutInfo[0]); |
329 | 351 | if (isset($cutInfo[1])) $cutLink=$cutInfo[1]; |
| 352 | + if (isset($fmtSec[1])) $skipPattern=$fmtSec[1]; |
330 | 353 | } |
331 | 354 | if ($maxlen<0) $maxlen = -1; // without valid limit include whole section |
332 | 355 | } |
— | — | @@ -344,7 +367,7 @@ |
345 | 368 | $sectionHeading[0]=substr($sSecLabel,1); |
346 | 369 | // Uses DPLInclude::includeHeading() from LabeledSectionTransclusion extension to include headings from the page |
347 | 370 | $secPieces = DPLInclude::includeHeading($this->mParser, $article->mTitle->getPrefixedText(), substr($sSecLabel, 1),'', |
348 | | - $sectionHeading,false,$maxlen,$cutLink,$bIncludeTrim); |
| 371 | + $sectionHeading,false,$maxlen,$cutLink,$bIncludeTrim,$skipPattern); |
349 | 372 | if ($mustMatch!='' || $mustNotMatch!='') { |
350 | 373 | $secPiecesTmp = $secPieces; |
351 | 374 | $offset=0; |
— | — | @@ -356,6 +379,7 @@ |
357 | 380 | } |
358 | 381 | } |
359 | 382 | } |
| 383 | + |
360 | 384 | $this->formatSingleItems($secPieces,$s); |
361 | 385 | if (!array_key_exists(0,$secPieces)) break; # to avoid matching against a non-existing array element |
362 | 386 | $secPiece[$s] = $secPieces[0]; |
— | — | @@ -375,8 +399,8 @@ |
376 | 400 | |
377 | 401 | } else if($sSecLabel[0] == '{') { |
378 | 402 | // Uses DPLInclude::includeTemplate() from LabeledSectionTransclusion extension to include templates from the page |
379 | | - $template1 = substr($sSecLabel,1,strpos($sSecLabel,'}')-1); |
380 | | - $template2 = str_replace('}','',substr($sSecLabel,1)); |
| 403 | + $template1 = trim(substr($sSecLabel,1,strpos($sSecLabel,'}')-1)); |
| 404 | + $template2 = trim(str_replace('}','',substr($sSecLabel,1))); |
381 | 405 | $secPieces = DPLInclude::includeTemplate($this->mParser, $this, $s, $article, $template1, |
382 | 406 | $template2, $template2.$defaultTemplateSuffix,$mustMatch, |
383 | 407 | $mustNotMatch,$this->mIncParsed,$iTitleMaxLen); |
— | — | @@ -389,7 +413,7 @@ |
390 | 414 | } |
391 | 415 | } else { |
392 | 416 | // Uses DPLInclude::includeSection() from LabeledSectionTransclusion extension to include labeled sections from the page |
393 | | - $secPieces = DPLInclude::includeSection($this->mParser, $article->mTitle->getPrefixedText(), $sSecLabel,'', false, $bIncludeTrim); |
| 417 | + $secPieces = DPLInclude::includeSection($this->mParser, $article->mTitle->getPrefixedText(), $sSecLabel,'', false, $bIncludeTrim, $skipPattern); |
394 | 418 | $secPiece[$s] = implode(isset($mode->aMultiSecSeparators[$s])? |
395 | 419 | $this->substTagParm($mode->aMultiSecSeparators[$s], $pagename, $article, $imageUrl, $this->filteredCount, $iTitleMaxLen):'',$secPieces); |
396 | 420 | if ($mode->iDominantSection>=0 && $s==$mode->iDominantSection && count($secPieces)>1) $dominantPieces=$secPieces; |
— | — | @@ -518,8 +542,19 @@ |
519 | 543 | } |
520 | 544 | |
521 | 545 | return $actStart . $rBody . $mode->sListEnd; |
| 546 | + |
522 | 547 | } |
523 | 548 | |
| 549 | + /** |
| 550 | + * this fucntion hast three tasks (depending on $exec): |
| 551 | + * (1) show an edit dialogue for template fields (exec = edit) |
| 552 | + * (2) set template parameters to values specified in the query (exec=set)v |
| 553 | + * (2) preview the source code including any changes of these parameters made in the edit form or with other changes (exec=preview) |
| 554 | + * (3) save the article with the changed value set or with other changes (exec=save) |
| 555 | + |
| 556 | + * "other changes" means that a regexp can be applied to the source text or arbitrary text can be |
| 557 | + * inserted before or after a pattern occuring in the text |
| 558 | + */ |
524 | 559 | |
525 | 560 | function updateArticleByRule($title,$text,$rulesText) { |
526 | 561 | // we use ; as command delimiter; \; stands for a semicolon |
— | — | @@ -528,18 +563,38 @@ |
529 | 564 | $rulesText = str_replace('\°',';',$rulesText); |
530 | 565 | $rulesText = str_replace("\\n","\n",$rulesText); |
531 | 566 | $rules=split('°',$rulesText); |
532 | | - $exec=false; |
| 567 | + $exec='edit'; |
533 | 568 | $replaceThis=''; |
534 | 569 | $replacement=''; |
535 | 570 | $after=''; |
536 | 571 | $insertionAfter=''; |
537 | 572 | $before=''; |
538 | 573 | $insertionBefore=''; |
| 574 | + $template=''; |
| 575 | + $parameter=array(); |
| 576 | + $value=array(); |
| 577 | + $afterparm=array(); |
| 578 | + $format=array(); |
| 579 | + $submit=array(); |
| 580 | + $commit=array(); |
| 581 | + $tooltip=array(); |
| 582 | + $optional=array(); |
| 583 | + |
539 | 584 | $lastCmd=''; |
540 | 585 | $message= ''; |
541 | 586 | $summary=''; |
| 587 | + $editForm=false; |
| 588 | + $action=''; |
| 589 | + $hidden=array(); |
| 590 | + $legendPage=''; |
| 591 | + $table=''; |
| 592 | + |
542 | 593 | // $message .= 'updaterules=<pre><nowiki>'; |
| 594 | + $nr = -1; |
543 | 595 | foreach ($rules as $rule) { |
| 596 | + if (preg_match('/^\s*#/',$rule)>0) continue; // # is comment symbol |
| 597 | + |
| 598 | + $rule=preg_replace('/^[\s]*/','',$rule); // strip leading white space |
544 | 599 | $cmd = preg_split("/ +/",$rule,2); |
545 | 600 | if (count($cmd)>1) $arg = $cmd[1]; |
546 | 601 | else $arg=''; |
— | — | @@ -547,44 +602,52 @@ |
548 | 603 | |
549 | 604 | // after ... insert ... , before ... insert ... |
550 | 605 | if ($cmd[0] == 'before') { |
551 | | - // $message.= "before = $arg\n"; |
552 | 606 | $before=$arg; |
553 | 607 | $lastCmd='B'; |
554 | 608 | } |
555 | 609 | if ($cmd[0] == 'after') { |
556 | | - // $message.= "after = $arg\n"; |
557 | 610 | $after=$arg; |
558 | 611 | $lastCmd='A'; |
559 | 612 | } |
560 | 613 | if ($cmd[0] == 'insert' && $lastCmd!='') { |
561 | | - // $message.= "insert $lastCmd = $arg\n"; |
562 | 614 | if ($lastCmd=='A') $insertionAfter=$arg; |
563 | 615 | if ($lastCmd=='B') $insertionBefore=$arg; |
564 | 616 | } |
| 617 | + if ($cmd[0] == 'template') $template = $arg; |
565 | 618 | |
566 | | - // replace ... by ... |
567 | | - if ($cmd[0] == 'replace') { |
568 | | - // $message.= "repl = $arg\n"; |
569 | | - $replaceThis=$arg; |
| 619 | + if ($cmd[0] == 'parameter') { |
| 620 | + $nr++; |
| 621 | + $parameter[$nr] = $arg; |
| 622 | + if ($nr>0) { |
| 623 | + $afterparm[$nr] = array($parameter[$nr-1]); |
| 624 | + $n=$nr-1; |
| 625 | + while ($n>0 && array_key_exists($n,$optional)) { |
| 626 | + $n--; |
| 627 | + $afterparm[$nr][]=$parameter[$n]; |
| 628 | + } |
| 629 | + } |
570 | 630 | } |
571 | | - if ($cmd[0] == 'by') { |
572 | | - // $message.= "by = $arg\n"; |
573 | | - $replacement=$arg; |
574 | | - } |
575 | | - |
576 | | - if ($cmd[0] == 'summary') { |
577 | | - // $message.= "summary = $arg\n"; |
578 | | - $summary=$arg; |
579 | | - } |
| 631 | + if ($cmd[0] == 'value') $value[$nr] = $arg; |
| 632 | + if ($cmd[0] == 'format') $format[$nr] = $arg; |
| 633 | + if ($cmd[0] == 'tooltip') $tooltip[$nr]=$arg; |
| 634 | + if ($cmd[0] == 'optional') $optional[$nr]=true; |
| 635 | + if ($cmd[0] == 'afterparm') $afterparm[$nr] = array($arg); |
| 636 | + if ($cmd[0] == 'legend') $legendPage = $arg; |
| 637 | + if ($cmd[0] == 'table') $table = $arg; |
580 | 638 | |
581 | | - // we execute only if "exec" is given, otherwise we merely show what would be done |
582 | | - if ($cmd[0] == 'exec') { |
583 | | - // $message.= "exec = true\n"; |
584 | | - $exec=true; |
585 | | - } |
| 639 | + if ($cmd[0] == 'replace') $replaceThis=$arg; |
| 640 | + if ($cmd[0] == 'by') $replacement=$arg; |
586 | 641 | |
| 642 | + if ($cmd[0] == 'editform') $editForm=$arg; |
| 643 | + if ($cmd[0] == 'action') $action=$arg; |
| 644 | + if ($cmd[0] == 'hidden') $hidden[]=$arg; |
| 645 | + if ($cmd[0] == 'submit') $submit[]=$arg; |
| 646 | + if ($cmd[0] == 'commit') $commit[]=$arg; |
587 | 647 | |
| 648 | + if ($cmd[0] == 'summary') $summary=$arg; |
| 649 | + if ($cmd[0] == 'exec') $exec=$arg; // we execute only if "exec" is 'save' or 'preview', otherwise we show an edit dialogue |
588 | 650 | } |
| 651 | + |
589 | 652 | if ($summary=='') { |
590 | 653 | $summary .= "\nbulk update:"; |
591 | 654 | if ($replaceThis!='') $summary .= "\n replace $replaceThis\n by $replacement"; |
— | — | @@ -594,6 +657,8 @@ |
595 | 658 | |
596 | 659 | // $message.= '</nowiki></pre>'; |
597 | 660 | |
| 661 | + // perform changes to the wiki source text ======================================= |
| 662 | + |
598 | 663 | if ($replaceThis!='') { |
599 | 664 | $text = preg_replace("$replaceThis",$replacement,$text); |
600 | 665 | } |
— | — | @@ -605,17 +670,275 @@ |
606 | 671 | if ($insertionAfter!='' && $after != '') { |
607 | 672 | $text = preg_replace("/($after)/",'\1'.$insertionAfter,$text); |
608 | 673 | } |
| 674 | + |
| 675 | + // deal with template parameters ================================================= |
| 676 | + |
| 677 | + global $wgRequest; |
609 | 678 | |
| 679 | + if ($template!='') { |
| 680 | + |
| 681 | + if ($exec=='edit') { |
| 682 | + $tpv = $this->getTemplateParmValues($text,$template); |
| 683 | + $legendText=''; |
| 684 | + if ($legendPage!='') { |
| 685 | + $legendTitle=''; |
| 686 | + global $wgParser; |
| 687 | + $parser = clone $wgParser; |
| 688 | + DPLInclude::text($parser, $legendPage, $legendTitle, $legendText); |
| 689 | + $legendText = preg_replace('/^.*?\<section\s+begin\s*=\s*legend\s*\/\>/s','',$legendText); |
| 690 | + $legendText = preg_replace('/\<section\s+end\s*=\s*legend\s*\/\>.*/s','',$legendText); |
| 691 | + } |
| 692 | + // construct an edit form containing all template invocations |
| 693 | + $form="<html><form action=\"$action\" $editForm>\n"; |
| 694 | + foreach ($tpv as $call => $tplValues) { |
| 695 | + $form .= "<table $table>\n"; |
| 696 | + foreach ($parameter as $nr => $parm) { |
| 697 | + // try to extract legend from the docs of the template |
| 698 | + $myToolTip=''; if (array_key_exists($nr,$tooltip)) $myToolTip = $tooltip[$nr]; |
| 699 | + $myFormat='' ; if (array_key_exists($nr,$format)) $myFormat = $format[$nr]; |
| 700 | + $myOptional=array_key_exists($nr,$optional); |
| 701 | + if ($legendText !='' && $myToolTip=='') { |
| 702 | + $myToolTip=preg_replace('/^.*\<section\s+begin\s*=\s*'.preg_quote($parm,'/').'\s*\/\>/s','',$legendText); |
| 703 | + if (strlen($myToolTip)==strlen($legendText)) { |
| 704 | + $myToolTip=''; |
| 705 | + } else { |
| 706 | + $myToolTip=preg_replace('/\<section\s+end\s*=\s*'.preg_quote($parm,'/').'\s*\/\>.*/s','',$myToolTip); |
| 707 | + } |
| 708 | + } |
| 709 | + $myValue=''; if (array_key_exists($parm,$tpv[$call])) $myValue=$tpv[$call][$parm]; |
| 710 | + $form .= $this->editTemplateCall($text,$template,$call,$parm,$myValue,$myFormat,$myToolTip,$myOptional); |
| 711 | + } |
| 712 | + $form .= "</table>\n<br/><br/>"; |
| 713 | + } |
| 714 | + foreach($hidden as $hide) { |
| 715 | + $form.= "<input type=hidden ".$hide." /> "; |
| 716 | + } |
| 717 | + foreach($submit as $subm) { |
| 718 | + $form.= "<input type=submit ".$subm." /> "; |
| 719 | + } |
| 720 | + $form .= "</form></html>\n"; |
| 721 | + return $form; |
| 722 | + } |
| 723 | + else if ($exec=='set' || $exec=='save' || $exec=='preview') { |
| 724 | + // loop over all invocations and parameters, this could be improved to enhance performance |
| 725 | + $matchCount=10; |
| 726 | + for ($call=0; $call<10; $call++) { |
| 727 | + foreach ($parameter as $nr => $parm) { |
| 728 | + // set parameters to values specified in the dpl source or get them from the http request |
| 729 | + if ($exec=='set') $myvalue=$value[$nr]; |
| 730 | + else { |
| 731 | + if ($call>= $matchCount) break; |
| 732 | + $myValue= $wgRequest->getVal(urlencode($call.'_'.$parm),''); |
| 733 | + } |
| 734 | + $myOptional= array_key_exists($nr,$optional); |
| 735 | + $myAfterParm=array(); if (array_key_exists($nr,$afterparm)) $myAfterParm = $afterparm[$nr]; |
| 736 | + $text = $this->updateTemplateCall($matchCount,$text,$template,$call,$parm,$myValue,$myAfterParm,$myOptional); |
| 737 | + } |
| 738 | + if ($exec=='set') break; // values taken from dpl text only populate the first invocation |
| 739 | + } |
| 740 | + } |
| 741 | + else if ($exec=='commit') { |
| 742 | + // we expect the contents of an article to be saved |
| 743 | + $text=$wgRequest->getVal('pageText',''); |
| 744 | + if ($text=='') return "DPL: no 'pageText' found."; |
| 745 | + else { |
| 746 | + $titleX = Title::newFromText($title); |
| 747 | + global $wgArticle; |
| 748 | + $wgArticle = $articleX = new Article($titleX); |
| 749 | + $articleX->updateArticle($text, $summary, false, $titleX->userIsWatching()); |
| 750 | + return ''; |
| 751 | + } |
| 752 | + } |
| 753 | + } |
| 754 | + |
610 | 755 | $titleX = Title::newFromText($title); |
611 | 756 | global $wgArticle; |
612 | 757 | $wgArticle = $articleX = new Article($titleX); |
613 | | - if ($exec) $articleX->updateArticle($text, $summary, false, $titleX->userIsWatching()); |
614 | | - else $message .= "set 'exec yes' to perform the following modification to <big>'''$title'''</big>\n"; |
615 | | - $message .= "<pre><nowiki>" |
616 | | - ."\n".$text."</nowiki></pre>"; // <pre><nowiki>\n"; // .$text."\n</nowiki></pre>\n"; |
617 | | - return $message; |
| 758 | + if ($exec=='save' || $exec=='set') { |
| 759 | + $articleX->updateArticle($text, $summary, false, $titleX->userIsWatching()); |
| 760 | + return ''; |
| 761 | + } |
| 762 | + else if ($exec=='preview'){ |
| 763 | + $form ="<html><form action=\"$action\" $editForm>\n"; |
| 764 | + $form.= "<textarea name=pageText rows=30 cols=100>".htmlspecialchars($text)."</textarea>"; |
| 765 | + foreach($hidden as $hide) { |
| 766 | + $form.= "<input type=hidden ".$hide." /> "; |
| 767 | + } |
| 768 | + foreach($commit as $comm) { |
| 769 | + $form.= "<input type=submit ".$comm." /> "; |
| 770 | + } |
| 771 | + $form .= "</form></html>\n"; |
| 772 | + return $form; |
| 773 | + } |
| 774 | + return "exec must be one of the following: edit, preview, save, set, commit"; |
618 | 775 | } |
619 | 776 | |
| 777 | + function editTemplateCall($text,$template,$call,$parameter,$value,$format,$tooltip,$optional) { |
| 778 | + return "<tr><td align=\"right\" title=\"".htmlspecialchars($tooltip)."\">".str_replace('_',' ',$parameter)."</td><td><textarea name=\"". |
| 779 | + urlencode($call.'_'.$parameter)."\" $format/>".htmlspecialchars($value)."</textarea></td>". |
| 780 | + "<td><small>$tooltip</small></td></tr>"; |
| 781 | + } |
| 782 | + |
| 783 | + /** |
| 784 | + * return an array of template invocations; each element is an associative array of parameter and value |
| 785 | + */ |
| 786 | + function getTemplateParmValues($text,$template) { |
| 787 | + $matches=array(); |
| 788 | + $noMatches = preg_match_all('/\{\{\s*'.preg_quote($template,'/').'\s*[|}]/i',$text,$matches,PREG_OFFSET_CAPTURE); |
| 789 | + if ($noMatches<=0) return ''; |
| 790 | + $textLen = strlen($text); |
| 791 | + $tval=array(); // the result array of template values |
| 792 | + $call=-1; // index for tval |
| 793 | + |
| 794 | + foreach($matches as $matchA) { |
| 795 | + foreach($matchA as $matchB) { |
| 796 | + $match=$matchB[0]; |
| 797 | + $start=$matchB[1]; |
| 798 | + |
| 799 | + $tval[++$call]=array(); |
| 800 | + $nr=0; // number of parameter if no name given |
| 801 | + $parmValue=''; |
| 802 | + $parmName=''; |
| 803 | + $parm=''; |
| 804 | + |
| 805 | + if ($match[strlen($match)-1]=='}') break; // template was called without parameters, continue with next invocation |
| 806 | + |
| 807 | + // search to the end of the template call |
| 808 | + $cbrackets=2; |
| 809 | + for ($i=$start+strlen($match); $i<$textLen;$i++) { |
| 810 | + $c = $text[$i]; |
| 811 | + if ($c == '{' || $c=='[') $cbrackets++; // we count both types of brackets |
| 812 | + if ($c == '}' || $c==']') $cbrackets--; |
| 813 | + if (($cbrackets==2 && $c=='|') || ($cbrackets==1 && $c=='}')) { |
| 814 | + // parameter (name or value) found |
| 815 | + if ($parmName=='') $tval[$call][++$nr] = trim($parm); |
| 816 | + else $tval[$call][$parmName] = trim($parmValue); |
| 817 | + $parmName=''; |
| 818 | + $parmValue=''; |
| 819 | + $parm=''; |
| 820 | + continue; |
| 821 | + } |
| 822 | + else { |
| 823 | + if ($parmName=='') { |
| 824 | + if ($c=='=') $parmName = trim($parm); |
| 825 | + } |
| 826 | + else { |
| 827 | + $parmValue.=$c; |
| 828 | + } |
| 829 | + } |
| 830 | + $parm.=$c; |
| 831 | + if ($cbrackets==0) break; // end of parameter list |
| 832 | + } |
| 833 | + } |
| 834 | + } |
| 835 | + return $tval; |
| 836 | + } |
| 837 | + |
| 838 | + /* |
| 839 | + * Changes a single parameter value within a certain call of a tempplate |
| 840 | + */ |
| 841 | + function updateTemplateCall(&$matchCount, $text,$template,$call,$parameter,$value,$afterParm,$optional) { |
| 842 | + |
| 843 | + // if parameter is optional and value is empty we leave everything as it is (i.e. we do not remove the parm) |
| 844 | + if ($optional && $value=='') return $text; |
| 845 | + |
| 846 | + $matches=array(); |
| 847 | + $noMatches = preg_match_all('/\{\{\s*'.preg_quote($template,'/').'\s*[|}]/i',$text,$matches,PREG_OFFSET_CAPTURE); |
| 848 | + if ($noMatches<=0) return $text; |
| 849 | + $rText=''; |
| 850 | + $beginSubst=-1; |
| 851 | + $endSubst=-1; |
| 852 | + $posInsertAt=0; |
| 853 | + $apNrLast=1000; // last (optional) predecessor |
| 854 | + |
| 855 | + foreach($matches as $matchA) { |
| 856 | + $matchCount=count($matchA); |
| 857 | + foreach($matchA as $occurence => $matchB) { |
| 858 | + if ($occurence < $call) continue; |
| 859 | + $match=$matchB[0]; |
| 860 | + $start=$matchB[1]; |
| 861 | + |
| 862 | + if ($match[strlen($match)-1]=='}') { |
| 863 | + // template was called without parameters, add new parameter and value |
| 864 | + // append parameter and value |
| 865 | + $beginSubst=$i; |
| 866 | + $endSubst=$i; |
| 867 | + $substitution="|$parameter = $value"; |
| 868 | + break; |
| 869 | + } |
| 870 | + else { |
| 871 | + // there is already a list of parameters; we search to the end of the template call |
| 872 | + $cbrackets=2; |
| 873 | + $parm=''; |
| 874 | + $pos=$start+strlen($match); |
| 875 | + $textLen = strlen($text); |
| 876 | + for ($i=$pos; $i<$textLen;$i++) { |
| 877 | + $c = $text[$i]; |
| 878 | + if ($c == '{' || $c=='[') $cbrackets++; // we count both types of brackets |
| 879 | + if ($c == '}' || $c==']') $cbrackets--; |
| 880 | + if (($cbrackets==2 && $c=='|') || ($cbrackets==1 && $c=='}')) { |
| 881 | + // parameter (name / value) found |
| 882 | + |
| 883 | + $token = split('=',$parm,2); |
| 884 | + if (count($token)==2) { |
| 885 | + // we need a pair of name / value |
| 886 | + $parmName=trim($token[0]); |
| 887 | + if ($parmName == $parameter) { |
| 888 | + // we found the parameter, now replace the current value |
| 889 | + $parmValue=trim($token[1]); |
| 890 | + if ($parmValue==$value) break; // no need to change when values are identical |
| 891 | + // keep spaces; |
| 892 | + $substitution = str_replace($parmValue,$value,$token[1]); |
| 893 | + $beginSubst=$pos+strlen($token[0])+1; |
| 894 | + $endSubst=$i; |
| 895 | + break; |
| 896 | + } |
| 897 | + else { |
| 898 | + foreach ($afterParm as $apNr => $ap) { |
| 899 | + // store position for insertion |
| 900 | + if ($parmName==$ap && $apNr<$apNrLast) { |
| 901 | + $posInsertAt = $i; |
| 902 | + $apNrLast = $apNr; |
| 903 | + break; |
| 904 | + } |
| 905 | + } |
| 906 | + } |
| 907 | + } |
| 908 | + |
| 909 | + if ($c=='}') { |
| 910 | + // end of template call reached, insert at stored position or here |
| 911 | + if ($posInsertAt !=0) $beginSubst=$posInsertAt; |
| 912 | + else $beginSubst=$i; |
| 913 | + $substitution= "|$parameter = $value"; |
| 914 | + if ($text[$beginSubst-1]=="\n") { |
| 915 | + --$beginSubst; |
| 916 | + $substitution="\n".$substitution; |
| 917 | + } |
| 918 | + $endSubst=$beginSubst; |
| 919 | + break; |
| 920 | + } |
| 921 | + |
| 922 | + $pos=$i; |
| 923 | + $parm=''; |
| 924 | + } |
| 925 | + else { |
| 926 | + $parm .= $c; |
| 927 | + } |
| 928 | + if ($cbrackets==0) { |
| 929 | + break; |
| 930 | + } |
| 931 | + } |
| 932 | + } |
| 933 | + break; |
| 934 | + } |
| 935 | + break; |
| 936 | + } |
| 937 | + |
| 938 | + if ($beginSubst<0) return $text; |
| 939 | + return substr($text,0,$beginSubst).$substitution.substr($text,$endSubst); |
| 940 | + |
| 941 | + } |
| 942 | + |
620 | 943 | function deleteArticleByRule($title,$text,$rulesText) { |
621 | 944 | // we use ; as command delimiter; \; stands for a semicolon |
622 | 945 | // \n is translated to a real linefeed |
Index: trunk/extensions/DynamicPageList/DPLSetup.php |
— | — | @@ -346,10 +346,22 @@ |
347 | 347 | * removed replacement of card suit symbols in SQL query due to collation incompatibilities |
348 | 348 | * added special logic to DPL_fromTitle: reversed sort order for backward scrolling |
349 | 349 | * changed default sort in DPL to 'titlewithoutnamespace (as this is more efficient than 'title') |
350 | | - * bugfix at ordermethod = titlewithoutnamespace (led to invalid SQL statements) |
351 | 350 | * @version 1.8.6 |
| 351 | + * bugfix at ordermethod = titlewithoutnamespace (led to invalid SQL statements) |
| 352 | + * @version 1.8.7 |
| 353 | + * experimental calls to the CacheAPI; can be switched off by $useCacheAPI = false; |
| 354 | + * one can set option[eliminate] to 'all' in LocalSettings now as a default |
| 355 | + * editrulesnow takes several triples of 'parameter', 'value' and 'afterparm' |
| 356 | + * editrules can now produce a screen form to change template values |
| 357 | + * title< and title> now test for greater or less; if you want greater/equal the argument must start with "= " |
| 358 | + * the majority of the php modules are now only loaded if a page contains a DPL statement |
| 359 | + * added %DPL_findTitle% |
| 360 | + * first letter changed toUpper in %DPL_fromTitle%, %DPL_toTitle%, %DPL_findTitle%, |
| 361 | + * enhanced syntax for include : [limit text~skipPattern] |
| 362 | + * UNIQ-QINU Bug resolved |
| 363 | + * convert spaces to underscores in all category (regexp) statements |
| 364 | + * we convert html entities in the category command to avoid false interpretation of & as AND |
352 | 365 | * |
353 | | - * |
354 | 366 | * ! when making changes here you must update the version field in DynamicPageList.php and DynamicPageListMigration.php ! |
355 | 367 | */ |
356 | 368 | |
— | — | @@ -370,7 +382,11 @@ |
371 | 383 | |
372 | 384 | public static $DPLVersion = '?'; // current version is set by DynamicPageList.php and DynamicPageListMigration.php |
373 | 385 | |
| 386 | + public static $useCacheAPI = true; // decide whether we use another extension called CachePI which can help us |
| 387 | + // to invalidate MediaWiki´s ParserCache if suitable |
374 | 388 | |
| 389 | + public static $modulesLoaded = false; // php require_once control |
| 390 | + |
375 | 391 | /** |
376 | 392 | * Extension options |
377 | 393 | */ |
— | — | @@ -1040,8 +1056,6 @@ |
1041 | 1057 | |
1042 | 1058 | global $wgParser; |
1043 | 1059 | |
1044 | | - self::loadModules(); |
1045 | | - |
1046 | 1060 | // DPL offers the same functionality as Intersection; so we register the <DynamicPageList> tag |
1047 | 1061 | // in case LabeledSection Extension is not installed we need to remove section markers |
1048 | 1062 | |
— | — | @@ -1057,7 +1071,6 @@ |
1058 | 1072 | } |
1059 | 1073 | |
1060 | 1074 | public static function setupMigration() { |
1061 | | - self::loadModules(); |
1062 | 1075 | |
1063 | 1076 | // DPL offers the same functionality as Intersection under the tag name <Intersection> |
1064 | 1077 | global $wgParser; |
— | — | @@ -1067,7 +1080,30 @@ |
1068 | 1081 | } |
1069 | 1082 | |
1070 | 1083 | private static function commonSetup() { |
| 1084 | + |
| 1085 | + if (!isset(self::$createdLinks)) { |
| 1086 | + self::$createdLinks=array( |
| 1087 | + 'resetLinks'=> false, 'resetTemplates' => false, |
| 1088 | + 'resetCategories' => false, 'resetImages' => false, 'resetdone' => false , 'elimdone' => false ); |
| 1089 | + } |
1071 | 1090 | |
| 1091 | + // make sure page "Template:Extension DPL" exists |
| 1092 | + $title = Title::newFromText('Template:Extension DPL'); |
| 1093 | + global $wgUser; |
| 1094 | + if (!$title->exists() && $wgUser->isAllowed('edit')) { |
| 1095 | + $article = new Article($title); |
| 1096 | + $article->doEdit( "<noinclude>This page was automatically created. It serves as an anchor page for ". |
| 1097 | + "all '''[[Special:WhatLinksHere/Template:Extension_DPL|invocations]]''' ". |
| 1098 | + "of [http://mediawiki.org/wiki/Extension:DynamicPageList Extension:DynamicPageList (DPL)].</noinclude>", |
| 1099 | + $title, EDIT_NEW | EDIT_FORCE_BOT ); |
| 1100 | + die(header('Location: '.Title::newFromText('Template:Extension DPL')->getFullURL())); |
| 1101 | + } |
| 1102 | + |
| 1103 | + } |
| 1104 | + |
| 1105 | + private static function loadMessages() { |
| 1106 | + |
| 1107 | + require_once( 'DynamicPageList.i18n.php' ); |
1072 | 1108 | global $wgMessageCache; |
1073 | 1109 | |
1074 | 1110 | |
— | — | @@ -1088,36 +1124,22 @@ |
1089 | 1125 | self::$debugMinLevels[$i] = $minlevel; |
1090 | 1126 | } |
1091 | 1127 | |
1092 | | - if (!isset(self::$createdLinks)) { |
1093 | | - self::$createdLinks=array( |
1094 | | - 'resetLinks'=> false, 'resetTemplates' => false, |
1095 | | - 'resetCategories' => false, 'resetImages' => false, 'resetdone' => false ); |
1096 | | - } |
1097 | | - |
1098 | | - // make sure page "Template:Extension DPL" exists |
1099 | | - $title = Title::newFromText('Template:Extension DPL'); |
1100 | | - global $wgUser; |
1101 | | - if (!$title->exists() && $wgUser->isAllowed('edit')) { |
1102 | | - $article = new Article($title); |
1103 | | - $article->doEdit( "<noinclude>This page was automatically created. It serves as an anchor page for ". |
1104 | | - "all '''[[Special:WhatLinksHere/Template:Extension_DPL|invocations]]''' ". |
1105 | | - "of [http://mediawiki.org/wiki/Extension:DynamicPageList Extension:DynamicPageList (DPL)].</noinclude>", |
1106 | | - $title, EDIT_NEW | EDIT_FORCE_BOT ); |
1107 | | - die(header('Location: '.Title::newFromText('Template:Extension DPL')->getFullURL())); |
1108 | | - } |
1109 | | - |
1110 | 1128 | } |
1111 | 1129 | |
1112 | 1130 | private static function loadModules() { |
| 1131 | + |
| 1132 | + if (self::$modulesLoaded == true) return; |
1113 | 1133 | |
1114 | | - // Page Transclusion, adopted from Steve Sanbeg´s LabeledSectionTransclusion |
| 1134 | + self::loadMessages(); |
| 1135 | + |
1115 | 1136 | require_once( 'DynamicPageListInclude.php' ); |
1116 | | - require_once( 'DynamicPageList.i18n.php' ); |
1117 | 1137 | require_once( 'DPL.php' ); |
1118 | 1138 | require_once( 'DPLMain.php' ); |
1119 | 1139 | require_once( 'DPLArticle.php' ); |
1120 | 1140 | require_once( 'DPLListMode.php' ); |
1121 | 1141 | require_once( 'DPLLogger.php' ); |
| 1142 | + |
| 1143 | + self::$modulesLoaded = true; |
1122 | 1144 | } |
1123 | 1145 | |
1124 | 1146 | public static function languageGetMagic( &$magicWords, $langCode ) { |
— | — | @@ -1148,6 +1170,9 @@ |
1149 | 1171 | // The callback function wrapper for converting the input text to HTML output |
1150 | 1172 | private static function executeTag( $input, $params, &$parser ) { |
1151 | 1173 | |
| 1174 | + // late loading of php modules, only if needed |
| 1175 | + self::loadModules(); |
| 1176 | + |
1152 | 1177 | // entry point for user tag <dpl> or <DynamicPageList> |
1153 | 1178 | // create list and do a recursive parse of the output |
1154 | 1179 | |
— | — | @@ -1183,6 +1208,9 @@ |
1184 | 1209 | //------------------------------------------------------------------------------------- ENTRY parser FUNCTION #dpl |
1185 | 1210 | public static function dplParserFunction(&$parser) { |
1186 | 1211 | |
| 1212 | + // late loading of php modules, only if needed |
| 1213 | + self::loadModules(); |
| 1214 | + |
1187 | 1215 | self::behaveLikeIntersection(false); |
1188 | 1216 | |
1189 | 1217 | // callback for the parser function {{#dpl: or {{DynamicPageList:: |
— | — | @@ -1302,74 +1330,13 @@ |
1303 | 1331 | } |
1304 | 1332 | |
1305 | 1333 | private static function dumpParsedRefs($parser,$label) { |
1306 | | - if (!preg_match("/Query Q/",$parser->mTitle->getText())) return ''; |
1307 | | - $text="\n<pre>$label:\n"; |
1308 | | - /* |
1309 | | - $text.=" control:"; |
1310 | | - foreach (self::$createdLinks as $key => $val) { |
1311 | | - if (is_array($val)) continue; |
1312 | | - $text.= "$val($key),"; |
1313 | | - } |
1314 | | - $text.="\n"; |
1315 | | - */ |
1316 | | - $text.=" categories:"; |
1317 | | - foreach ($parser->mOutput->mCategories as $key => $val ) { |
1318 | | - $text .= "$val($key),"; |
1319 | | - } |
1320 | | - $text.="\n"; |
1321 | | - if (array_key_exists(2,self::$createdLinks)) { |
1322 | | - $text.=" CATEGORIES:"; |
1323 | | - foreach (self::$createdLinks[2] as $val ) { |
1324 | | - $text .= "$val,"; |
1325 | | - } |
1326 | | - $text.="\n"; |
1327 | | - } |
1328 | | - $text.=" links:"; |
1329 | | - foreach ($parser->mOutput->mLinks as $lkey => $lval ) { |
1330 | | - $text .= "$lval($lkey)={"; |
1331 | | - foreach ($lval as $key => $val ) { |
1332 | | - $text .= "$val($key),"; |
1333 | | - } |
1334 | | - $text .= "},"; |
1335 | | - } |
1336 | | - $text.="\n"; |
1337 | | - if (array_key_exists(0,self::$createdLinks)) { |
1338 | | - $text.=" LINKS:"; |
1339 | | - foreach (self::$createdLinks[0] as $val ) { |
1340 | | - $text .= "$val,"; |
1341 | | - } |
1342 | | - $text.="\n"; |
1343 | | - } |
1344 | | - $text.=" templates:"; |
1345 | | - foreach ($parser->mOutput->mTemplates as $tkey => $tval ) { |
1346 | | - $text .= "$tval($tkey)={"; |
1347 | | - foreach ($tval as $key => $val ) { |
1348 | | - $text .= "$val($key),"; |
1349 | | - } |
1350 | | - $text .= "},"; |
1351 | | - } |
1352 | | - $text.="\n"; |
1353 | | - if (array_key_exists(1,self::$createdLinks)) { |
1354 | | - $text.=" TEMPLATES:"; |
1355 | | - foreach (self::$createdLinks[1] as $val ) { |
1356 | | - $text .= "$val,"; |
1357 | | - } |
1358 | | - $text.="\n"; |
1359 | | - } |
1360 | | - $text.=" images:"; |
1361 | | - foreach ($parser->mOutput->mImages as $key => $val ) { |
1362 | | - $text .= "$val($key),"; |
1363 | | - } |
1364 | | - $text.="\n"; |
1365 | | - if (array_key_exists(3,self::$createdLinks)) { |
1366 | | - $text.=" IMAGES:"; |
1367 | | - foreach (self::$createdLinks[3] as $val ) { |
1368 | | - $text .= "$val,"; |
1369 | | - } |
1370 | | - $text.="\n"; |
1371 | | - } |
1372 | | - $text.="</pre>\n"; |
1373 | | - return $text; |
| 1334 | + //if (!preg_match("/Query Q/",$parser->mTitle->getText())) return ''; |
| 1335 | + echo '<pre>parser mLinks: '; |
| 1336 | + ob_start(); var_dump($parser->mOutput->mLinks); $a=ob_get_contents(); ob_end_clean(); echo htmlspecialchars($a,ENT_QUOTES); |
| 1337 | + echo '</pre>'; |
| 1338 | + echo '<pre>parser mTemplates: '; |
| 1339 | + ob_start(); var_dump($parser->mOutput->mTemplates); $a=ob_get_contents(); ob_end_clean(); echo htmlspecialchars($a,ENT_QUOTES); |
| 1340 | + echo '</pre>'; |
1374 | 1341 | } |
1375 | 1342 | |
1376 | 1343 | //remove section markers in case the LabeledSectionTransclusion extension is not installed. |
— | — | @@ -1391,54 +1358,59 @@ |
1392 | 1359 | } |
1393 | 1360 | |
1394 | 1361 | public static function endEliminate( &$parser, &$text ) { |
| 1362 | + |
1395 | 1363 | // called during the final output phase; removes links created by DPL |
1396 | | - if (isset(self::$createdLinks) || !self::$createdLinks['elimdone']) { |
1397 | | - self::$createdLinks['elimdone'] = true; |
1398 | | - // $text .= self::dumpParsedRefs($parser,"before final eliminate"); |
1399 | | - if (isset(self::$createdLinks) && array_key_exists(0,self::$createdLinks)) { |
1400 | | - foreach ($parser->mOutput->getLinks() as $linkKey => $link) { |
1401 | | - foreach ($link as $key => $val) { |
1402 | | - if (array_key_exists($key,self::$createdLinks[0])) { |
1403 | | - unset($parser->mOutput->mLinks[$linkKey][$key]); |
1404 | | - // $text .= "removing link: $val($key);"; |
1405 | | - } |
1406 | | - } |
1407 | | - if (count($parser->mOutput->mLinks[$linkKey])==0) { |
1408 | | - unset ($parser->mOutput->mLinks[$linkKey]); |
1409 | | - } |
| 1364 | + if (isset(self::$createdLinks)) { |
| 1365 | + // self::dumpParsedRefs($parser,"before final eliminate"); |
| 1366 | + if (array_key_exists(0,self::$createdLinks)) { |
| 1367 | + foreach ($parser->mOutput->getLinks() as $nsp => $link) { |
| 1368 | + if (!array_key_exists($nsp,self::$createdLinks[0])) continue; |
| 1369 | + // echo ("<pre> elim: created Links [$nsp] = ". count(ExtDynamicPageList::$createdLinks[0][$nsp])."</pre>\n"); |
| 1370 | + // echo ("<pre> elim: parser Links [$nsp] = ". count($parser->mOutput->mLinks[$nsp]) ."</pre>\n"); |
| 1371 | + $parser->mOutput->mLinks[$nsp] = array_diff_assoc($parser->mOutput->mLinks[$nsp],self::$createdLinks[0][$nsp]); |
| 1372 | + // echo ("<pre> elim: parser Links [$nsp] nachher = ". count($parser->mOutput->mLinks[$nsp]) ."</pre>\n"); |
| 1373 | + if (count($parser->mOutput->mLinks[$nsp])==0) unset ($parser->mOutput->mLinks[$nsp]); |
1410 | 1374 | } |
1411 | 1375 | } |
1412 | 1376 | if (isset(self::$createdLinks) && array_key_exists(1,self::$createdLinks)) { |
1413 | | - foreach ($parser->mOutput->getTemplates() as $tplKey => $tpl) { |
1414 | | - foreach ($tpl as $key => $val) { |
1415 | | - if (in_array($val,self::$createdLinks[1])) { |
1416 | | - unset($parser->mOutput->mTemplates[$tplKey][$key]); |
1417 | | - // $text .= "removing use of template: $val($key);"; |
1418 | | - } |
1419 | | - } |
1420 | | - if (count($parser->mOutput->mTemplates[$tplKey])==0) { |
1421 | | - unset ($parser->mOutput->mTemplates[$tplKey]); |
1422 | | - } |
| 1377 | + foreach ($parser->mOutput->mTemplates as $nsp => $tpl) { |
| 1378 | + if (!array_key_exists($nsp,self::$createdLinks[1])) continue; |
| 1379 | + // echo ("<pre> elim: created Tpls [$nsp] = ". count(ExtDynamicPageList::$createdLinks[1][$nsp])."</pre>\n"); |
| 1380 | + // echo ("<pre> elim: parser Tpls [$nsp] = ". count($parser->mOutput->mTemplates[$nsp]) ."</pre>\n"); |
| 1381 | + $parser->mOutput->mTemplates[$nsp] = array_diff_assoc($parser->mOutput->mTemplates[$nsp],self::$createdLinks[1][$nsp]); |
| 1382 | + // echo ("<pre> elim: parser Tpls [$nsp] nachher = ". count($parser->mOutput->mTemplates[$nsp]) ."</pre>\n"); |
| 1383 | + if (count($parser->mOutput->mTemplates[$nsp])==0) unset ($parser->mOutput->mTemplates[$nsp]); |
1423 | 1384 | } |
1424 | 1385 | } |
1425 | 1386 | if (isset(self::$createdLinks) && array_key_exists(2,self::$createdLinks)) { |
1426 | | - foreach (self::$createdLinks[2] as $cat) { |
1427 | | - unset($parser->mOutput->mCategories[$cat]); |
1428 | | - // $text .= "removing cat: $cat;"; |
1429 | | - } |
| 1387 | + $parser->mOutput->mCategories = array_diff_assoc($parser->mOutput->mCategories,self::$createdLinks[2]); |
1430 | 1388 | } |
1431 | 1389 | if (isset(self::$createdLinks) && array_key_exists(3,self::$createdLinks)) { |
1432 | | - foreach (self::$createdLinks[3] as $img) { |
1433 | | - unset($parser->mOutput->mImages[$img]); |
1434 | | - // $text .= "removing img: $img;"; |
1435 | | - } |
| 1390 | + $parser->mOutput->mImages = array_diff_assoc($parser->mOutput->mImages,self::$createdLinks[3]); |
1436 | 1391 | } |
1437 | 1392 | // $text .= self::dumpParsedRefs($parser,"after final eliminate".$parser->mTitle->getText()); |
1438 | 1393 | } |
1439 | | - self::$createdLinks=array( |
1440 | | - 'resetLinks'=> false, 'resetTemplates' => false, |
1441 | | - 'resetCategories' => false, 'resetImages' => false, 'resetdone' => false ); |
| 1394 | + |
| 1395 | + //self::$createdLinks=array( |
| 1396 | + // 'resetLinks'=> false, 'resetTemplates' => false, |
| 1397 | + // 'resetCategories' => false, 'resetImages' => false, 'resetdone' => false ); |
1442 | 1398 | return true; |
1443 | 1399 | } |
1444 | 1400 | |
1445 | 1401 | } |
| 1402 | + |
| 1403 | +class MyBug { |
| 1404 | + |
| 1405 | + static function trace($class,$label,$msg) { |
| 1406 | + $fileName = dirname(__FILE__).'/MyBug'; |
| 1407 | + if ($class=='') { |
| 1408 | + if (file_exists($fileName)) unlink(dirname(__FILE__).'/MyBug'); |
| 1409 | + return; |
| 1410 | + } |
| 1411 | + $bugFile=fopen($fileName,'a'); |
| 1412 | + fwrite($bugFile,"$class -------------------------------------------------------------------------------------------- $label\n"); |
| 1413 | + fwrite($bugFile,$msg."\n"); |
| 1414 | + fclose($bugFile); |
| 1415 | + } |
| 1416 | + |
| 1417 | +} |
\ No newline at end of file |
Index: trunk/extensions/DynamicPageList/DynamicPageListInclude.php |
— | — | @@ -93,6 +93,8 @@ |
94 | 94 | * removal of html-comments within template calls |
95 | 95 | * @version 1.8.5 |
96 | 96 | * includeTemplate understands parser function syntax now |
| 97 | + * @version 1.8.7 |
| 98 | + * UNIQ-QINU-Bug: replaced parser->replaceVariables by parser->preprocess |
97 | 99 | |
98 | 100 | */ |
99 | 101 | |
— | — | @@ -133,7 +135,7 @@ |
134 | 136 | * Handle recursive substitution here, so we can break cycles, and set up |
135 | 137 | * return values so that edit sections will resolve correctly. |
136 | 138 | **/ |
137 | | - private static function parse($parser, $title, $text, $part1, $skiphead=0, $recursionCheck=true, $maxLength=-1, $link='', $trim=false) |
| 139 | + private static function parse($parser, $title, $text, $part1, $skiphead=0, $recursionCheck=true, $maxLength=-1, $link='', $trim=false, $skipPattern='') |
138 | 140 | { |
139 | 141 | global $wgVersion; |
140 | 142 | |
— | — | @@ -141,6 +143,11 @@ |
142 | 144 | // text, may as well do the right thing. |
143 | 145 | $text = str_replace('</section>', '', $text); |
144 | 146 | |
| 147 | + // if desired we remove portions of the text, esp. template calls |
| 148 | + if ($skipPattern!='') { |
| 149 | + $text=preg_replace($skipPattern,'',$text); |
| 150 | + } |
| 151 | + |
145 | 152 | |
146 | 153 | if (self::open($parser, $part1)) { |
147 | 154 | |
— | — | @@ -150,10 +157,11 @@ |
151 | 158 | //release, so this is close enough. |
152 | 159 | |
153 | 160 | if(version_compare( $wgVersion, "1.9" ) < 0 || $recursionCheck == false) { |
154 | | - $text = $parser->replaceVariables($text); |
155 | | - self::close($parser, $part1); |
| 161 | + |
| 162 | + $text = $parser->preprocess($text,$parser->mTitle,$parser->mOptions); |
| 163 | + self::close($parser, $part1); |
156 | 164 | } |
157 | | - |
| 165 | + |
158 | 166 | if ($maxLength>0) { |
159 | 167 | $text = self::limitTranscludedText($text,$maxLength,$link); |
160 | 168 | } |
— | — | @@ -214,7 +222,7 @@ |
215 | 223 | return preg_match_all( "/$pat/im", substr($text,0,$limit), $m); |
216 | 224 | } |
217 | 225 | |
218 | | - private static function text($parser, $page, &$title, &$text) |
| 226 | + public static function text($parser, $page, &$title, &$text) |
219 | 227 | { |
220 | 228 | $title = Title::newFromText($page); |
221 | 229 | |
— | — | @@ -235,7 +243,7 @@ |
236 | 244 | } |
237 | 245 | |
238 | 246 | ///section inclusion - include all matching sections |
239 | | - public static function includeSection($parser, $page='', $sec='', $to='', $recursionCheck=true, $trim=false) { |
| 247 | + public static function includeSection($parser, $page='', $sec='', $to='', $recursionCheck=true, $trim=false, $skipPattern='') { |
240 | 248 | $output = array(); |
241 | 249 | if (self::text($parser, $page, $title, $text) == false) { |
242 | 250 | $output[] = $text; |
— | — | @@ -247,7 +255,7 @@ |
248 | 256 | preg_match_all( $pat, $text, $m, PREG_PATTERN_ORDER); |
249 | 257 | |
250 | 258 | foreach ($m[2] as $nr=>$piece) { |
251 | | - $piece = self::parse($parser,$title,$piece, "#lst:${page}|${sec}", 0, $recursionCheck, $trim); |
| 259 | + $piece = self::parse($parser,$title,$piece, "#lst:${page}|${sec}", 0, $recursionCheck, $trim, $skipPattern); |
252 | 260 | if ($any) $output[] = $m[1][$nr].'::'.$piece; |
253 | 261 | else $output[] = $piece; |
254 | 262 | } |
— | — | @@ -297,7 +305,7 @@ |
298 | 306 | } |
299 | 307 | |
300 | 308 | public static function includeHeading($parser, $page='', $sec='', $to='', &$sectionHeading, $recursionCheck=true, $maxLength=-1, |
301 | | - $link='default', $trim=false) |
| 309 | + $link='default', $trim=false, $skipPattern='') |
302 | 310 | { |
303 | 311 | $output=array(); |
304 | 312 | if (self::text($parser, $page, $title, $text) == false) { |
— | — | @@ -305,12 +313,12 @@ |
306 | 314 | return $output; |
307 | 315 | } |
308 | 316 | |
309 | | - return self::extractHeadingFromText($parser, $page, $title, $text, $sec, $to, $sectionHeading, $recursionCheck, $maxLength, $link, $trim); |
| 317 | + return self::extractHeadingFromText($parser, $page, $title, $text, $sec, $to, $sectionHeading, $recursionCheck, $maxLength, $link, $trim, $skipPattern); |
310 | 318 | } |
311 | 319 | |
312 | 320 | //section inclusion - include all matching sections (return array) |
313 | 321 | public static function extractHeadingFromText($parser, $page, $title, $text, $sec='', $to='', &$sectionHeading, $recursionCheck=true, |
314 | | - $maxLength=-1, $link='default', $trim=false) { |
| 322 | + $maxLength=-1, $link='default', $trim=false, $skipPattern='' ) { |
315 | 323 | |
316 | 324 | // create a link symbol (arrow, img, ...) in case we have to cut the text block to maxLength |
317 | 325 | if ($link=='default') $link = ' [['.$page.'#'.$sec.'|..→]]'; |
— | — | @@ -355,7 +363,7 @@ |
356 | 364 | if ($nr==-2) { |
357 | 365 | // output text before first section and done |
358 | 366 | $piece = substr($text,0,$m[1][1]-1); |
359 | | - $output[0] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", 0, $recursionCheck, $maxLength, $link, $trim); |
| 367 | + $output[0] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", 0, $recursionCheck, $maxLength, $link, $trim, $skipPattern); |
360 | 368 | return $output; |
361 | 369 | } |
362 | 370 | |
— | — | @@ -404,20 +412,21 @@ |
405 | 413 | else $sectionHeading[$n] = ''; |
406 | 414 | if ($nr==1) { |
407 | 415 | // output n-th section and done |
408 | | - $output[0] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", $nhead, $recursionCheck, $maxLength, $link, $trim); |
| 416 | + $output[0] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", $nhead, $recursionCheck, $maxLength, $link, $trim, $skipPattern); |
409 | 417 | break; |
410 | 418 | } |
411 | 419 | if ($nr==-1) { |
412 | 420 | if (!isset($end_off)) { |
413 | 421 | // output last section and done |
414 | | - $output[0] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", $nhead, $recursionCheck, $maxLength, $link, $trim); |
| 422 | + $output[0] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", $nhead, $recursionCheck, $maxLength, $link, $trim, $skipPattern); |
415 | 423 | break; |
416 | 424 | } |
417 | 425 | } else { |
418 | 426 | // output section by name and continue search for another section with the same name |
419 | | - $output[$n++] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", $nhead, $recursionCheck, $maxLength, $link, $trim); |
| 427 | + $output[$n++] = self::parse($parser,$title,$piece, "#lsth:${page}|${sec}", $nhead, $recursionCheck, $maxLength, $link, $trim, $skipPattern); |
420 | 428 | } |
421 | 429 | } while ($continueSearch); |
| 430 | + |
422 | 431 | return $output; |
423 | 432 | } |
424 | 433 | |
— | — | @@ -436,7 +445,7 @@ |
437 | 446 | $user = $article->mUserLink; |
438 | 447 | $title = Title::newFromText($page); |
439 | 448 | $text = $parser->fetchTemplate($title); |
440 | | - |
| 449 | + |
441 | 450 | if ($template1 != '' && $template1[0]=='#') { |
442 | 451 | $template1=substr($template1,1); |
443 | 452 | $template2=substr($template2,1); |
— | — | @@ -490,7 +499,9 @@ |
491 | 500 | else $output[0]=$dpl->formatTemplateArg('',$dplNr,0,true,-1); |
492 | 501 | } else { |
493 | 502 | // put a red link into the output |
494 | | - $output[0]= $parser->replaceVariables('{{'.$defaultTemplate.'|%PAGE%='.$page.'|%TITLE%='.$title->getText().'|%DATE%='.$date.'|%USER%='.$user.'}}'); |
| 503 | + $output[0]= $parser->preprocess( |
| 504 | + '{{'.$defaultTemplate.'|%PAGE%='.$page.'|%TITLE%='.$title->getText().'|%DATE%='.$date.'|%USER%='.$user.'}}', |
| 505 | + $parser->mTitle,$parser->mOptions); |
495 | 506 | } |
496 | 507 | return $output; |
497 | 508 | } |
— | — | @@ -519,9 +530,9 @@ |
520 | 531 | // if we must match a condition: test against it |
521 | 532 | if (($mustMatch =='' || preg_match($mustMatch,substr($templateCall,0,$i-1))) && |
522 | 533 | ($mustNotMatch=='' || !preg_match($mustNotMatch,substr($templateCall,0,$i-1)))) { |
523 | | - $output[++$n] = $parser->replaceVariables(substr($templateCall,0,$i-1). |
524 | | - '|%PAGE%='.$page.'|%TITLE%='.$title->getText().'|%DATE%='.$date.'|%USER%='.$user.'}}'); |
525 | | - } |
| 534 | + $output[++$n] = $parser->preprocess(substr($templateCall,0,$i-1). |
| 535 | + '|%PAGE%='.$page.'|%TITLE%='.$title->getText().'|%DATE%='.$date.'|%USER%='.$user.'}}',$parser->mTitle,$parser->mOptions); |
| 536 | + } |
526 | 537 | break; |
527 | 538 | } |
528 | 539 | } |
— | — | @@ -534,6 +545,7 @@ |
535 | 546 | $parms=array(); |
536 | 547 | $parm=''; |
537 | 548 | $hasParm=false; |
| 549 | + |
538 | 550 | for ($i=0; $i<$size;$i++) { |
539 | 551 | $c = $templateCall[$i]; |
540 | 552 | if ($c == '{' || $c=='[') $cbrackets++; // we count both types of brackets |
Index: trunk/extensions/DynamicPageList/DPLMain.php |
— | — | @@ -19,7 +19,7 @@ |
20 | 20 | error_reporting(E_ALL); |
21 | 21 | |
22 | 22 | global $wgUser, $wgLang, $wgContLang, $wgRequest, $wgRawHtml; |
23 | | - global $wgTitle, $wgNonincludableNamespaces; |
| 23 | + global $wgTitle, $wgArticle, $wgNonincludableNamespaces; |
24 | 24 | |
25 | 25 | // we use "makeKnownLinkObject" to create hyperlinbks; |
26 | 26 | // the code we store in the dplcache may contain <html>....</html> sequences |
— | — | @@ -50,8 +50,13 @@ |
51 | 51 | // check if DPL shall only be executed from protected pages |
52 | 52 | if (array_key_exists('RunFromProtectedPagesOnly',ExtDynamicPageList::$options) && |
53 | 53 | ExtDynamicPageList::$options['RunFromProtectedPagesOnly']==true && !($parser->mTitle->isProtected('edit'))) { |
| 54 | + |
| 55 | + // Ideally we would like to allow using a DPL query if the query istelf is coded on a template page |
| 56 | + // which is protected. Then there would be no need for the article to be protected. |
| 57 | + // BUT: How can one find out from which wiki source an extension has been invoked??? |
| 58 | + |
54 | 59 | return (ExtDynamicPageList::$options['RunFromProtectedPagesOnly']); |
55 | | - } |
| 60 | + } |
56 | 61 | |
57 | 62 | // get database access |
58 | 63 | $dbr =& wfGetDB( DB_SLAVE ); |
— | — | @@ -95,10 +100,19 @@ |
96 | 101 | $input = self::resolveUrlArg($input,'DPL_offset'); |
97 | 102 | $input = self::resolveUrlArg($input,'DPL_count'); |
98 | 103 | $input = self::resolveUrlArg($input,'DPL_fromTitle'); |
| 104 | + $input = self::resolveUrlArg($input,'DPL_findTitle'); |
99 | 105 | $input = self::resolveUrlArg($input,'DPL_toTitle'); |
100 | 106 | |
101 | 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; |
102 | 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); |
103 | 117 | $scrollDir = $wgRequest->getVal('DPL_scrollDir',''); |
104 | 118 | |
105 | 119 | $originalInput = $input; |
— | — | @@ -119,8 +133,9 @@ |
120 | 134 | $bSelectionCriteriaFound=false; |
121 | 135 | $bConflictsWithOpenReferences=false; |
122 | 136 | // array for LINK / TEMPLATE / CATGEORY / IMAGE by RESET / ELIMINATE |
123 | | - $bReset = array ( false, false, false, false, false, false, false, false ); |
124 | | - |
| 137 | + if (ExtDynamicPageList::$options['eliminate'] == 'all') $bReset = array ( false, false, false, false, true, true, true, true ); |
| 138 | + else $bReset = array ( false, false, false, false, false, false, false, false ); |
| 139 | + |
125 | 140 | // we allow " like " or "=" |
126 | 141 | $sCategoryComparisonMode = '='; |
127 | 142 | $sNotCategoryComparisonMode = '='; |
— | — | @@ -389,7 +404,9 @@ |
390 | 405 | $sArg[0] = ''; |
391 | 406 | } |
392 | 407 | $op='OR'; |
393 | | - if (strpos($sArg,'&')!==false) { |
| 408 | + // we expand html entities because they contain an '& 'which would be interpreted as an AND condition |
| 409 | + $sArg=html_entity_decode($sArg,ENT_QUOTES); |
| 410 | + if (strpos($sArg,'&')!==false) { |
394 | 411 | $aParams = explode('&', $sArg); |
395 | 412 | $op = 'AND'; |
396 | 413 | } else { |
— | — | @@ -429,7 +446,7 @@ |
430 | 447 | if($bHeading) $aCatHeadings = array_unique($aCatHeadings + $aCategories); |
431 | 448 | if($bNotHeading) $aCatNotHeadings = array_unique($aCatNotHeadings + $aCategories); |
432 | 449 | $bConflictsWithOpenReferences=true; |
433 | | - } |
| 450 | + } |
434 | 451 | break; |
435 | 452 | case 'notcategory': |
436 | 453 | $title = Title::newFromText($localParser->transformMsg($sArg, $pOptions)); |
— | — | @@ -515,7 +532,7 @@ |
516 | 533 | } |
517 | 534 | if ( !$breakaway ) { |
518 | 535 | $aOrderMethods = $methods; |
519 | | - $bConflictsWithOpenReferences=true; |
| 536 | + if ($methods[0]!='none') $bConflictsWithOpenReferences=true; |
520 | 537 | } |
521 | 538 | break; |
522 | 539 | |
— | — | @@ -1251,7 +1268,6 @@ |
1252 | 1269 | |
1253 | 1270 | case 'dplcache': |
1254 | 1271 | if ($sArg!='') { |
1255 | | - global $wgArticle; |
1256 | 1272 | if (isset($wgArticle)) { |
1257 | 1273 | $DPLCache = $wgArticle->getID().'_'.$sArg.'.txt'; |
1258 | 1274 | $DPLCachePath = $wgArticle->getID() % 10; |
— | — | @@ -1301,7 +1317,9 @@ |
1302 | 1318 | else if ($arg=='all') { |
1303 | 1319 | $bReset[4]=true; $bReset[5]=true; $bReset[6]=true; $bReset[7]=true; |
1304 | 1320 | } |
1305 | | - else if ($arg=='none') ; // do nothing |
| 1321 | + else if ($arg=='none') { |
| 1322 | + $bReset[4]=false;$bReset[5]=false;$bReset[6]=false;$bReset[7]=false; |
| 1323 | + } |
1306 | 1324 | } |
1307 | 1325 | break; |
1308 | 1326 | |
— | — | @@ -1711,7 +1729,6 @@ |
1712 | 1730 | // backward scrolling: if the user specified titleLE and wants ascending order we reverse the SQL sort order |
1713 | 1731 | if ($sTitleLE != '' && $sTitleGE =='') { |
1714 | 1732 | if ($sOrder == 'ascending' ) $sOrder='descending'; |
1715 | | - else if ($sOrder == 'descending') $sOrder='ascending'; |
1716 | 1733 | } |
1717 | 1734 | |
1718 | 1735 | $output.='{{Extension DPL}}'; |
— | — | @@ -2167,9 +2184,9 @@ |
2168 | 2185 | // If we want the Uncategorized |
2169 | 2186 | $sSqlSelectFrom .= ' INNER JOIN ' . ( in_array('', $aIncludeCategories[$i]) ? $sDplClView : $sCategorylinksTable ) . |
2170 | 2187 | ' AS cl' . $iClTable . ' ON '.$sPageTable.'.page_id=cl' . $iClTable . '.cl_from AND (cl' . $iClTable . '.cl_to'. |
2171 | | - $sCategoryComparisonMode . $dbr->addQuotes($aIncludeCategories[$i][0]); |
| 2188 | + $sCategoryComparisonMode . $dbr->addQuotes(str_replace(' ','_',$aIncludeCategories[$i][0])); |
2172 | 2189 | for ($j = 1; $j < count($aIncludeCategories[$i]); $j++) |
2173 | | - $sSqlSelectFrom .= ' OR cl' . $iClTable . '.cl_to' . $sCategoryComparisonMode . $dbr->addQuotes($aIncludeCategories[$i][$j]); |
| 2190 | + $sSqlSelectFrom .= ' OR cl' . $iClTable . '.cl_to' . $sCategoryComparisonMode . $dbr->addQuotes(str_replace(' ','_',$aIncludeCategories[$i][$j])); |
2174 | 2191 | $sSqlSelectFrom .= ') '; |
2175 | 2192 | $iClTable++; |
2176 | 2193 | } |
— | — | @@ -2179,7 +2196,7 @@ |
2180 | 2197 | $sSqlSelectFrom .= |
2181 | 2198 | ' LEFT OUTER JOIN ' . $sCategorylinksTable . ' AS cl' . $iClTable . |
2182 | 2199 | ' ON '.$sPageTable.'.page_id=cl' . $iClTable . '.cl_from' . |
2183 | | - ' AND cl' . $iClTable . '.cl_to'. $sNotCategoryComparisonMode . $dbr->addQuotes($aExcludeCategories[$i]); |
| 2200 | + ' AND cl' . $iClTable . '.cl_to'. $sNotCategoryComparisonMode . $dbr->addQuotes(str_replace(' ','_',$aExcludeCategories[$i])); |
2184 | 2201 | $sSqlWhere .= ' AND cl' . $iClTable . '.cl_to IS NULL'; |
2185 | 2202 | $iClTable++; |
2186 | 2203 | } |
— | — | @@ -2209,16 +2226,26 @@ |
2210 | 2227 | // TitleGE ... |
2211 | 2228 | if ( $sTitleGE != '' ) { |
2212 | 2229 | $sSqlWhere .= ' AND ('; |
2213 | | - if ($acceptOpenReferences) $sSqlWhere .= 'pl_title >=' . $dbr->addQuotes($sTitleGE) ; |
2214 | | - else $sSqlWhere .= $sPageTable.'.page_title >=' . $dbr->addQuotes($sTitleGE) ; |
| 2230 | + if (substr($sTitleGE,0,2)=='=_') { |
| 2231 | + if ($acceptOpenReferences) $sSqlWhere .= 'pl_title >=' . $dbr->addQuotes(substr($sTitleGE,2)) ; |
| 2232 | + else $sSqlWhere .= $sPageTable.'.page_title >=' . $dbr->addQuotes(substr($sTitleGE,2)) ; |
| 2233 | + } else { |
| 2234 | + if ($acceptOpenReferences) $sSqlWhere .= 'pl_title >' . $dbr->addQuotes($sTitleGE) ; |
| 2235 | + else $sSqlWhere .= $sPageTable.'.page_title >' . $dbr->addQuotes($sTitleGE) ; |
| 2236 | + } |
2215 | 2237 | $sSqlWhere .= ')'; |
2216 | 2238 | } |
2217 | 2239 | |
2218 | 2240 | // TitleLE ... |
2219 | 2241 | if ( $sTitleLE != '' ) { |
2220 | 2242 | $sSqlWhere .= ' AND ('; |
2221 | | - if ($acceptOpenReferences) $sSqlWhere .= 'pl_title <=' . $dbr->addQuotes($sTitleLE) ; |
2222 | | - else $sSqlWhere .= $sPageTable.'.page_title <=' . $dbr->addQuotes($sTitleLE) ; |
| 2243 | + if (substr($sTitleLE,0,2)=='=_') { |
| 2244 | + if ($acceptOpenReferences) $sSqlWhere .= 'pl_title <=' . $dbr->addQuotes(substr($sTitleLE,2)) ; |
| 2245 | + else $sSqlWhere .= $sPageTable.'.page_title <=' . $dbr->addQuotes(substr($sTitleLE,2)) ; |
| 2246 | + } else { |
| 2247 | + if ($acceptOpenReferences) $sSqlWhere .= 'pl_title <' . $dbr->addQuotes($sTitleLE) ; |
| 2248 | + else $sSqlWhere .= $sPageTable.'.page_title <' . $dbr->addQuotes($sTitleLE) ; |
| 2249 | + } |
2223 | 2250 | $sSqlWhere .= ')'; |
2224 | 2251 | } |
2225 | 2252 | |
— | — | @@ -2416,7 +2443,8 @@ |
2417 | 2444 | if ($sOrder == 'descending') $sSqlWhere .= ' ) order by cl3.cl_to DESC'; |
2418 | 2445 | else $sSqlWhere .= ' ) order by cl3.cl_to ASC'; |
2419 | 2446 | } |
2420 | | - |
| 2447 | + |
| 2448 | + |
2421 | 2449 | // ###### DUMP SQL QUERY ###### |
2422 | 2450 | if ($logger->iDebugLevel >=3) { |
2423 | 2451 | //DEBUG: output SQL query |
— | — | @@ -2428,6 +2456,7 @@ |
2429 | 2457 | return $output; |
2430 | 2458 | } |
2431 | 2459 | |
| 2460 | + |
2432 | 2461 | // ###### PROCESS SQL QUERY ###### |
2433 | 2462 | |
2434 | 2463 | try { |
— | — | @@ -2663,7 +2692,7 @@ |
2664 | 2693 | } |
2665 | 2694 | |
2666 | 2695 | // backward scrolling: if the user specified titleLE we reverse the output order |
2667 | | - if ($sTitleLE != '' && $sTitleGE =='') $aArticles = array_reverse($aArticles); |
| 2696 | + if ($sTitleLE != '' && $sTitleGE =='' && $sOrder=='descending' ) $aArticles = array_reverse($aArticles); |
2668 | 2697 | |
2669 | 2698 | |
2670 | 2699 | // ###### SHOW OUTPUT ###### |
— | — | @@ -2752,8 +2781,39 @@ |
2753 | 2782 | $parser->disableCache(); |
2754 | 2783 | } |
2755 | 2784 | |
| 2785 | + // update dependencies to CacheAPI if DPL is to respect the MW ParserCache and the page containing the DPL query is changed |
| 2786 | + |
| 2787 | + if (ExtDynamicPageList::$useCacheAPI && $bAllowCachedResults && $wgRequest->getVal('action','view')=='submit') { |
| 2788 | +/* |
| 2789 | + CacheAPI::remDependencies ( $wgArticle->getID()); |
| 2790 | + |
| 2791 | + // add category dependencies |
| 2792 | + |
| 2793 | + $conditionTypes = array ( CACHETYPE_CATEGORY ); |
| 2794 | + $conditions = array(); |
| 2795 | + $conditions[0] = array(); |
| 2796 | + $categorylist = array(); |
| 2797 | + foreach ($aIncludeCategories as $categorygroup) { |
| 2798 | + $c=0; |
| 2799 | + foreach ($categorygroup as $category) { |
| 2800 | + if ($c==0) $conditions[0][]= $category; |
| 2801 | + $c++; |
| 2802 | + } |
| 2803 | + } |
| 2804 | + |
| 2805 | + // add template dependencies |
| 2806 | + |
| 2807 | + // add link dependencies |
| 2808 | + |
| 2809 | + // add general dependencies |
| 2810 | + |
| 2811 | + // CacheAPI::addDependencies ( $wgArticle->getID(), $conditionTypes, $conditions); |
| 2812 | +*/ |
| 2813 | + } |
| 2814 | + |
| 2815 | + |
2756 | 2816 | // The following requires an extra parser step which may consume some time |
2757 | | - // we parse the DPL output and save all referenced found in that output in a global list |
| 2817 | + // we parse the DPL output and save all references found in that output in a global list |
2758 | 2818 | // in a final user exit after the whole document processing we eliminate all these links |
2759 | 2819 | // we use a local parser to avoid interference with the main parser |
2760 | 2820 | |
— | — | @@ -2771,32 +2831,30 @@ |
2772 | 2832 | // we trigger the mediawiki parser to find links, images, categories etc. which are contained in the DPL output |
2773 | 2833 | // this allows us to remove these links from the link list later |
2774 | 2834 | // If the article containing the DPL statement itself uses one of these links they will be thrown away! |
2775 | | - foreach ($parserOutput->getLinks() as $link) { |
2776 | | - foreach ($link as $key => $val) { |
2777 | | - ExtDynamicPageList::$createdLinks[0][$key]=$val; |
2778 | | - // $output.= "storing link $val($key)."; |
2779 | | - } |
| 2835 | + ExtDynamicPageList::$createdLinks[0]=array(); |
| 2836 | + foreach ($parserOutput->getLinks() as $nsp => $link) { |
| 2837 | + ExtDynamicPageList::$createdLinks[0][$nsp]=$link; |
2780 | 2838 | } |
2781 | 2839 | } |
2782 | 2840 | if ($bReset[5]) { // TEMPLATES |
2783 | | - foreach ($parserOutput->getTemplates() as $tpl) { |
2784 | | - foreach ($tpl as $key => $val) { |
2785 | | - ExtDynamicPageList::$createdLinks[1][$key]=$val; |
2786 | | - // $output.= "storing use of template $val($key)."; |
2787 | | - } |
| 2841 | + ExtDynamicPageList::$createdLinks[1]=array(); |
| 2842 | + foreach ($parserOutput->getTemplates() as $nsp => $tpl) { |
| 2843 | + ExtDynamicPageList::$createdLinks[1][$nsp]=$tpl; |
2788 | 2844 | } |
2789 | 2845 | } |
2790 | 2846 | if ($bReset[6]) { // CATEGORIES |
2791 | | - foreach ($parserOutput->mCategories as $catname => $catkey) { |
2792 | | - ExtDynamicPageList::$createdLinks[2][$catname] = $catname; |
2793 | | - } |
| 2847 | + ExtDynamicPageList::$createdLinks[2] = $parserOutput->mCategories; |
2794 | 2848 | } |
2795 | 2849 | if ($bReset[7]) { // IMAGES |
2796 | | - foreach ($parserOutput->mImages as $imgid => $dummy) { |
2797 | | - ExtDynamicPageList::$createdLinks[3][$imgid] = $imgid; |
2798 | | - } |
| 2850 | + ExtDynamicPageList::$createdLinks[3] = $parserOutput->mImages; |
2799 | 2851 | } |
2800 | 2852 | |
| 2853 | + // $file=fopen("d:/a1",'a'); |
| 2854 | + // fwrite($file,$parser->mTitle->getPrefixedText().' '.microtime()."\n"); |
| 2855 | + // fclose($file); |
| 2856 | + |
| 2857 | + // MyBug::trace(__CLASS__,'main END',$output); |
| 2858 | + |
2801 | 2859 | return $output; |
2802 | 2860 | |
2803 | 2861 | } |
— | — | @@ -2897,7 +2955,7 @@ |
2898 | 2956 | if (self::mkdirr($next_pathname)) { |
2899 | 2957 | if (!file_exists($pathname)) return mkdir($pathname); |
2900 | 2958 | } |
2901 | | - return false; |
| 2959 | + return false; |
2902 | 2960 | } |
2903 | 2961 | |
2904 | 2962 | private static function resolveUrlArg($input,$arg) { |
Index: trunk/extensions/DynamicPageList/DynamicPageListMigration.php |
— | — | @@ -40,7 +40,7 @@ |
41 | 41 | |
42 | 42 | $wgHooks['LanguageGetMagic'][] = 'ExtDynamicPageList__languageGetMagic'; |
43 | 43 | |
44 | | -$DPLVersion = '1.8.6'; |
| 44 | +$DPLVersion = '1.8.7'; |
45 | 45 | |
46 | 46 | $wgExtensionCredits['parserhook'][] = array( |
47 | 47 | 'path' => __FILE__, |
— | — | @@ -60,4 +60,3 @@ |
61 | 61 | // be extremely restrictive by default: do not allow anything that goes beyond Extension:Intersection |
62 | 62 | // can be extended by a different call to this function in LocalSettings.php after the require_once() |
63 | 63 | ExtDynamicPageList::setFunctionalRichness(0); |
64 | | - |