Index: trunk/extensions/DynamicPageList/DynamicPageList.php |
— | — | @@ -59,7 +59,7 @@ |
60 | 60 | |
61 | 61 | $wgHooks['LanguageGetMagic'][] = 'ExtDynamicPageList__languageGetMagic'; |
62 | 62 | |
63 | | -$DPLVersion = '1.8.7'; |
| 63 | +$DPLVersion = '1.8.8'; |
64 | 64 | |
65 | 65 | $wgExtensionCredits['parserhook'][] = array( |
66 | 66 | 'path' => __FILE__, |
Index: trunk/extensions/DynamicPageList/DPL.php |
— | — | @@ -61,6 +61,10 @@ |
62 | 62 | // $this->parent = $other->parent; |
63 | 63 | // } |
64 | 64 | $this->mParser = clone $parser; |
| 65 | + // clear state of cloned parser; if the above patch of LinkHoldersArray is not made this |
| 66 | + // can lead to links not being shown in the original document (probably the UIQ_QINU-tags no longer |
| 67 | + // get replaced properly; in combination with the patch however, it does not do any harm. |
| 68 | + $this->mParser->clearState(); |
65 | 69 | $this->mParserOptions = $parser->mOptions; |
66 | 70 | $this->mParserTitle = $parser->mTitle; |
67 | 71 | |
— | — | @@ -381,7 +385,12 @@ |
382 | 386 | } |
383 | 387 | |
384 | 388 | $this->formatSingleItems($secPieces,$s); |
385 | | - if (!array_key_exists(0,$secPieces)) break; # to avoid matching against a non-existing array element |
| 389 | + if (!array_key_exists(0,$secPieces)) { |
| 390 | + // avoid matching against a non-existing array element |
| 391 | + // and skip the article if there was a match condition |
| 392 | + if ($mustMatch!='' || $mustNotMatch!='') $matchFailed=true; |
| 393 | + break; |
| 394 | + } |
386 | 395 | $secPiece[$s] = $secPieces[0]; |
387 | 396 | for ($sp=1;$sp<count($secPieces);$sp++) { |
388 | 397 | if (isset($mode->aMultiSecSeparators[$s])) { |
— | — | @@ -575,8 +584,8 @@ |
576 | 585 | $value=array(); |
577 | 586 | $afterparm=array(); |
578 | 587 | $format=array(); |
579 | | - $submit=array(); |
580 | | - $commit=array(); |
| 588 | + $preview=array(); |
| 589 | + $save=array(); |
581 | 590 | $tooltip=array(); |
582 | 591 | $optional=array(); |
583 | 592 | |
— | — | @@ -588,6 +597,7 @@ |
589 | 598 | $hidden=array(); |
590 | 599 | $legendPage=''; |
591 | 600 | $table=''; |
| 601 | + $fieldFormat=''; |
592 | 602 | |
593 | 603 | // $message .= 'updaterules=<pre><nowiki>'; |
594 | 604 | $nr = -1; |
— | — | @@ -634,6 +644,7 @@ |
635 | 645 | if ($cmd[0] == 'afterparm') $afterparm[$nr] = array($arg); |
636 | 646 | if ($cmd[0] == 'legend') $legendPage = $arg; |
637 | 647 | if ($cmd[0] == 'table') $table = $arg; |
| 648 | + if ($cmd[0] == 'field') $fieldFormat = $arg; |
638 | 649 | |
639 | 650 | if ($cmd[0] == 'replace') $replaceThis=$arg; |
640 | 651 | if ($cmd[0] == 'by') $replacement=$arg; |
— | — | @@ -641,11 +652,11 @@ |
642 | 653 | if ($cmd[0] == 'editform') $editForm=$arg; |
643 | 654 | if ($cmd[0] == 'action') $action=$arg; |
644 | 655 | if ($cmd[0] == 'hidden') $hidden[]=$arg; |
645 | | - if ($cmd[0] == 'submit') $submit[]=$arg; |
646 | | - if ($cmd[0] == 'commit') $commit[]=$arg; |
| 656 | + if ($cmd[0] == 'preview') $preview[]=$arg; |
| 657 | + if ($cmd[0] == 'save') $save[]=$arg; |
647 | 658 | |
648 | 659 | 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 |
| 660 | + if ($cmd[0] == 'exec') $exec=$arg; // desired action (set or edit or preview) |
650 | 661 | } |
651 | 662 | |
652 | 663 | if ($summary=='') { |
— | — | @@ -673,7 +684,7 @@ |
674 | 685 | |
675 | 686 | // deal with template parameters ================================================= |
676 | 687 | |
677 | | - global $wgRequest; |
| 688 | + global $wgRequest, $wgUser; |
678 | 689 | |
679 | 690 | if ($template!='') { |
680 | 691 | |
— | — | @@ -682,14 +693,14 @@ |
683 | 694 | $legendText=''; |
684 | 695 | if ($legendPage!='') { |
685 | 696 | $legendTitle=''; |
686 | | - global $wgParser; |
| 697 | + global $wgParser, $wgUser; |
687 | 698 | $parser = clone $wgParser; |
688 | 699 | DPLInclude::text($parser, $legendPage, $legendTitle, $legendText); |
689 | 700 | $legendText = preg_replace('/^.*?\<section\s+begin\s*=\s*legend\s*\/\>/s','',$legendText); |
690 | 701 | $legendText = preg_replace('/\<section\s+end\s*=\s*legend\s*\/\>.*/s','',$legendText); |
691 | 702 | } |
692 | 703 | // construct an edit form containing all template invocations |
693 | | - $form="<html><form action=\"$action\" $editForm>\n"; |
| 704 | + $form="<html><form method=post action=\"$action\" $editForm>\n"; |
694 | 705 | foreach ($tpv as $call => $tplValues) { |
695 | 706 | $form .= "<table $table>\n"; |
696 | 707 | foreach ($parameter as $nr => $parm) { |
— | — | @@ -706,20 +717,21 @@ |
707 | 718 | } |
708 | 719 | } |
709 | 720 | $myValue=''; if (array_key_exists($parm,$tpv[$call])) $myValue=$tpv[$call][$parm]; |
710 | | - $form .= $this->editTemplateCall($text,$template,$call,$parm,$myValue,$myFormat,$myToolTip,$myOptional); |
| 721 | + $form .= $this->editTemplateCall($text,$template,$call,$parm,$myValue,$myFormat,$myToolTip,$myOptional,$fieldFormat); |
711 | 722 | } |
712 | 723 | $form .= "</table>\n<br/><br/>"; |
713 | 724 | } |
714 | 725 | foreach($hidden as $hide) { |
715 | | - $form.= "<input type=hidden ".$hide." /> "; |
| 726 | + $form.= "<input type=hidden ".$hide." />"; |
716 | 727 | } |
717 | | - foreach($submit as $subm) { |
718 | | - $form.= "<input type=submit ".$subm." /> "; |
| 728 | + $form.= "<input type=hidden name=\"token\" value=\"".$wgUser->editToken()."\" />"; |
| 729 | + foreach($preview as $prev) { |
| 730 | + $form.= "<input type=submit ".$prev." /> "; |
719 | 731 | } |
720 | 732 | $form .= "</form></html>\n"; |
721 | 733 | return $form; |
722 | 734 | } |
723 | | - else if ($exec=='set' || $exec=='save' || $exec=='preview') { |
| 735 | + else if ($exec=='set' || $exec=='preview') { |
724 | 736 | // loop over all invocations and parameters, this could be improved to enhance performance |
725 | 737 | $matchCount=10; |
726 | 738 | for ($call=0; $call<10; $call++) { |
— | — | @@ -737,48 +749,71 @@ |
738 | 750 | if ($exec=='set') break; // values taken from dpl text only populate the first invocation |
739 | 751 | } |
740 | 752 | } |
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 | 753 | } |
754 | 754 | |
| 755 | + if ($exec=='set') { |
| 756 | + return $this->updateArticle($title,$text,$summary); |
| 757 | + } |
| 758 | + else if ($exec=='preview'){ |
| 759 | + global $wgScriptPath,$wgRequest; |
| 760 | + $titleX = Title::newFromText($title); |
| 761 | + $articleX = new Article($titleX); |
| 762 | + $form ='<html><form id="editform" name="editform" method="post" action="'.$wgScriptPath . '/index.php?title='.urlencode($title).'&action=submit" ' |
| 763 | + .'enctype="multipart/form-data">'."\n" |
| 764 | + .'<input type="hidden" value="" name="wpSection" />'."\n" |
| 765 | + .'<input type="hidden" value="'. wfTimestampNow() . '" name="wpStarttime" />'."\n" |
| 766 | + .'<input type="hidden" value="'.$articleX->getTimestamp() .'" name="wpEdittime" />'."\n" |
| 767 | + .'<input type="hidden" value="" name="wpScrolltop" id="wpScrolltop" />'."\n" |
| 768 | + .'<textarea tabindex="1" accesskey="," name="wpTextbox1" id="wpTextbox1" rows="'.$wgUser->getIntOption( 'rows' ) |
| 769 | + .'" cols="'.$wgUser->getIntOption( 'cols' ).'" >' |
| 770 | + .htmlspecialchars($text) |
| 771 | + .'</textarea>'."\n" |
| 772 | + .'<input type="hidden" name="wpSummary value="'.$summary.'" id="wpSummary" />' |
| 773 | + .'<input name="wpAutoSummary" type="hidden" value="" />' |
| 774 | + .'<input id="wpSave" name="wpSave" type="submit" value="Save page" accesskey="s" title="Save your changes [s]" />' |
| 775 | + .'<input type="hidden" value="'.$wgRequest->getVal('token').'" name="wpEditToken" />'."\n" |
| 776 | + .'</form></html>'."\n"; |
| 777 | + return $form; |
| 778 | + } |
| 779 | + return "exec must be one of the following: edit, preview, set"; |
| 780 | + } |
| 781 | + |
| 782 | + function updateArticle($title, $text, $summary) { |
| 783 | + global $wgUser, $wgRequest, $wgArticle, $wgOut; |
| 784 | + |
| 785 | + if (!$wgUser->matchEditToken($wgRequest->getVal('token'))) { |
| 786 | + $wgOut->addWikiMsg( 'sessionfailure' ); |
| 787 | + return 'session failure'; |
| 788 | + } |
| 789 | + |
755 | 790 | $titleX = Title::newFromText($title); |
756 | | - global $wgArticle; |
| 791 | + |
757 | 792 | $wgArticle = $articleX = new Article($titleX); |
758 | | - if ($exec=='save' || $exec=='set') { |
| 793 | + $permission_errors = $articleX->mTitle->getUserPermissionsErrors( 'edit', $wgUser ); |
| 794 | + if (count($permission_errors)==0) { |
759 | 795 | $articleX->updateArticle($text, $summary, false, $titleX->userIsWatching()); |
760 | 796 | return ''; |
761 | 797 | } |
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; |
| 798 | + else { |
| 799 | + $wgOut->showPermissionsErrorPage( $permission_errors ); |
| 800 | + return 'permission error'; |
773 | 801 | } |
774 | | - return "exec must be one of the following: edit, preview, save, set, commit"; |
| 802 | + } |
| 803 | + |
| 804 | + function editTemplateCall($text,$template,$call,$parameter,$value,$format,$tooltip,$optional,$fieldFormat) { |
| 805 | + $matches=array(); |
| 806 | + $nlCount = preg_match_all('/\n/',$value,$matches); |
| 807 | + if ($nlCount>0) $rows= $nlCount+1; |
| 808 | + else $rows = floor(strlen($value) / 50) + 1; |
| 809 | + if (preg_match('/rows\s*=/',$format)<=0) $format.= " rows=$rows"; |
| 810 | + $cols=50; |
| 811 | + if (preg_match('/cols\s*=/',$format)<=0) $format.= " cols=$cols"; |
| 812 | + $textArea = "<textarea name=\"".urlencode($call.'_'.$parameter)."\" $format/>".htmlspecialchars($value)."</textarea>"; |
| 813 | + return str_replace('%NAME%', htmlspecialchars(str_replace('_',' ',$parameter)), |
| 814 | + str_replace('%INPUT%', $textArea, |
| 815 | + str_replace('%LEGEND%', "</html>".htmlspecialchars($tooltip)."<html>",$fieldFormat))); |
775 | 816 | } |
776 | 817 | |
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 | 818 | /** |
784 | 819 | * return an array of template invocations; each element is an associative array of parameter and value |
785 | 820 | */ |
— | — | @@ -838,7 +873,7 @@ |
839 | 874 | * Changes a single parameter value within a certain call of a tempplate |
840 | 875 | */ |
841 | 876 | function updateTemplateCall(&$matchCount, $text,$template,$call,$parameter,$value,$afterParm,$optional) { |
842 | | - |
| 877 | + |
843 | 878 | // if parameter is optional and value is empty we leave everything as it is (i.e. we do not remove the parm) |
844 | 879 | if ($optional && $value=='') return $text; |
845 | 880 | |
— | — | @@ -870,9 +905,9 @@ |
871 | 906 | // there is already a list of parameters; we search to the end of the template call |
872 | 907 | $cbrackets=2; |
873 | 908 | $parm=''; |
874 | | - $pos=$start+strlen($match); |
| 909 | + $pos=$start+strlen($match)-1; |
875 | 910 | $textLen = strlen($text); |
876 | | - for ($i=$pos; $i<$textLen;$i++) { |
| 911 | + for ($i=$pos+1; $i<$textLen;$i++) { |
877 | 912 | $c = $text[$i]; |
878 | 913 | if ($c == '{' || $c=='[') $cbrackets++; // we count both types of brackets |
879 | 914 | if ($c == '}' || $c==']') $cbrackets--; |
— | — | @@ -888,9 +923,20 @@ |
889 | 924 | $parmValue=trim($token[1]); |
890 | 925 | if ($parmValue==$value) break; // no need to change when values are identical |
891 | 926 | // keep spaces; |
892 | | - $substitution = str_replace($parmValue,$value,$token[1]); |
893 | | - $beginSubst=$pos+strlen($token[0])+1; |
| 927 | + if ($parmValue=='') { |
| 928 | + if (strlen($token[1])>0 && $token[1][strlen($token[1])-1]=="\n") { |
| 929 | + $substitution=str_replace ("\n",$value."\n",$token[1]); |
| 930 | + } |
| 931 | + else { |
| 932 | + $substitution=$value.$token[1]; |
| 933 | + } |
| 934 | + } |
| 935 | + else { |
| 936 | + $substitution = str_replace($parmValue,$value,$token[1]); |
| 937 | + } |
| 938 | + $beginSubst=$pos+strlen($token[0])+2; |
894 | 939 | $endSubst=$i; |
| 940 | + // MyBug::trace(__CLASS__,'split',"pos=$pos,substitution=$substitution,...$token[0]...$token[1]..."); |
895 | 941 | break; |
896 | 942 | } |
897 | 943 | else { |
— | — | @@ -935,11 +981,20 @@ |
936 | 982 | } |
937 | 983 | |
938 | 984 | if ($beginSubst<0) return $text; |
| 985 | + // MyBug::trace(__CLASS__,'updParm',"at $beginSubst,$endSubst : .1.".substr($text,$beginSubst-10,10) |
| 986 | + // .".2.".substr($text,$beginSubst,$endSubst-$beginSubst).".3.".substr($text,$endSubst,10).".4.$substitution.5."); |
| 987 | + |
939 | 988 | return substr($text,0,$beginSubst).$substitution.substr($text,$endSubst); |
940 | 989 | |
941 | 990 | } |
942 | 991 | |
943 | 992 | function deleteArticleByRule($title,$text,$rulesText) { |
| 993 | + |
| 994 | + global $wgUser, $wgOut; |
| 995 | + |
| 996 | + // return "deletion of articles by DPL is disabled."; |
| 997 | + |
| 998 | + |
944 | 999 | // we use ; as command delimiter; \; stands for a semicolon |
945 | 1000 | // \n is translated to a real linefeed |
946 | 1001 | $rulesText = str_replace(";",'°',$rulesText); |
— | — | @@ -949,7 +1004,12 @@ |
950 | 1005 | $exec=false; |
951 | 1006 | $message= ''; |
952 | 1007 | $reason=''; |
| 1008 | + |
| 1009 | + |
953 | 1010 | foreach ($rules as $rule) { |
| 1011 | + if (preg_match('/^\s*#/',$rule)>0) continue; // # is comment symbol |
| 1012 | + |
| 1013 | + $rule=preg_replace('/^[\s]*/','',$rule); // strip leading white space |
954 | 1014 | $cmd = preg_split("/ +/",$rule,2); |
955 | 1015 | if (count($cmd)>1) $arg = $cmd[1]; |
956 | 1016 | else $arg=''; |
— | — | @@ -969,7 +1029,21 @@ |
970 | 1030 | $titleX = Title::newFromText($title); |
971 | 1031 | global $wgArticle; |
972 | 1032 | $wgArticle = $articleX = new Article($titleX); |
973 | | - if ($exec) $articleX->doDelete($reason); |
| 1033 | + if ($exec) { |
| 1034 | + # Check permissions |
| 1035 | + $permission_errors = $articleX->mTitle->getUserPermissionsErrors( 'delete', $wgUser ); |
| 1036 | + if (count($permission_errors)>0) { |
| 1037 | + $wgOut->showPermissionsErrorPage( $permission_errors ); |
| 1038 | + return 'permission error'; |
| 1039 | + } |
| 1040 | + else if ( wfReadOnly() ) { |
| 1041 | + $wgOut->readOnlyPage(); |
| 1042 | + return 'DPL: read only mode'; |
| 1043 | + } |
| 1044 | + else { |
| 1045 | + $articleX->doDelete($reason); |
| 1046 | + } |
| 1047 | + } |
974 | 1048 | else $message .= "set 'exec yes' to delete <big>'''$title'''</big>\n"; |
975 | 1049 | $message .= "<pre><nowiki>" |
976 | 1050 | ."\n".$text."</nowiki></pre>"; // <pre><nowiki>\n"; // .$text."\n</nowiki></pre>\n"; |
Index: trunk/extensions/DynamicPageList/DPLSetup.php |
— | — | @@ -361,7 +361,14 @@ |
362 | 362 | * UNIQ-QINU Bug resolved |
363 | 363 | * convert spaces to underscores in all category (regexp) statements |
364 | 364 | * we convert html entities in the category command to avoid false interpretation of & as AND |
365 | | - * |
| 365 | + * @version 1.8.8 |
| 366 | + * offset by one error in updaterules corrected |
| 367 | + * bugfix in checking includematch on chapter content |
| 368 | + * made size of edit fields depend on value size |
| 369 | + * deleterules: does some kind of permission checking now |
| 370 | + * various improvements in template editing (calling the edit page now for the real update) |
| 371 | + * call to parser->clearState() inserted; does this solve the UNIQ-QINU problem without a patch to LnkHolderArray ?? |
| 372 | + * |
366 | 373 | * ! when making changes here you must update the version field in DynamicPageList.php and DynamicPageListMigration.php ! |
367 | 374 | */ |
368 | 375 | |
Index: trunk/extensions/DynamicPageList/DynamicPageListMigration.php |
— | — | @@ -40,7 +40,7 @@ |
41 | 41 | |
42 | 42 | $wgHooks['LanguageGetMagic'][] = 'ExtDynamicPageList__languageGetMagic'; |
43 | 43 | |
44 | | -$DPLVersion = '1.8.7'; |
| 44 | +$DPLVersion = '1.8.8'; |
45 | 45 | |
46 | 46 | $wgExtensionCredits['parserhook'][] = array( |
47 | 47 | 'path' => __FILE__, |