urlapprove.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. <?php if (!defined('PmWiki')) exit();
  2. /* Copyright 2004-2016 Patrick R. Michaud (pmichaud@pobox.com)
  3. This file is part of PmWiki; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published
  5. by the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version. See pmwiki.php for full details.
  7. This script provides a URL-approval capability. To enable this
  8. script, add the following line to a configuration file:
  9. include_once('scripts/urlapprove.php');
  10. The URL prefixes to be allowed are stored as patterns in
  11. $WhiteUrlPatterns. This array can be loaded from config.php, or
  12. from the wiki pages given by the $ApprovedUrlPagesFmt[] array.
  13. Any http: or https: URL that isn't in $WhiteUrlPatterns is rendered
  14. using $UnapprovedLinkFmt.
  15. The script also provides ?action=approveurls and ?action=approvesites,
  16. which scan the current page for any new URLs to be automatically added
  17. the first page of $UrlApprovalPagesFmt.
  18. Finally, the script will block any post containing more than
  19. $UnapprovedLinkCountMax unapproved urls in it. By default this
  20. is set to a very large number, leaving the posting of unapproved
  21. urls wide open, but by setting $UnapprovedLinkCountMax to a smaller
  22. number you can limit the number of unapproved urls that make it into
  23. a page. (Wikispammers seem to like to post long lists of urls, while
  24. more "normal" authors tend to only post a few.)
  25. Script maintained by Petko YOTOV www.pmwiki.org/petko
  26. */
  27. $LinkFunctions['http:'] = 'LinkHTTP';
  28. $LinkFunctions['https:'] = 'LinkHTTP';
  29. SDV($ApprovedUrlPagesFmt, array('$SiteAdminGroup.ApprovedUrls'));
  30. SDV($UnapprovedLinkFmt,
  31. "\$LinkText<a class='apprlink' href='{\$PageUrl}?action=approvesites'>$[(approve sites)]</a>");
  32. SDVA($HTMLStylesFmt, array('urlapprove' => '.apprlink { font-size:smaller; }'));
  33. SDV($ApproveUrlPattern,
  34. "\\bhttps?:[^\\s$UrlExcludeChars]*[^\\s.,?!$UrlExcludeChars]");
  35. $WhiteUrlPatterns = (array)$WhiteUrlPatterns;
  36. SDV($HandleActions['approveurls'], 'HandleApprove');
  37. SDV($HandleAuth['approveurls'], 'edit');
  38. SDV($HandleActions['approvesites'], 'HandleApprove');
  39. SDV($HandleAuth['approvesites'], 'edit');
  40. SDV($UnapprovedLinkCountMax, 1000000);
  41. array_splice($EditFunctions, array_search('PostPage', $EditFunctions),
  42. 0, 'BlockUnapprovedPosts');
  43. function LinkHTTP($pagename,$imap,$path,$alt,$txt,$fmt=NULL) {
  44. global $EnableUrlApprovalRequired, $IMap, $WhiteUrlPatterns, $FmtV,
  45. $UnapprovedLink, $UnapprovedLinkCount, $UnapprovedLinkFmt;
  46. if (!IsEnabled($EnableUrlApprovalRequired,1))
  47. return LinkIMap($pagename,$imap,$path,$alt,$txt,$fmt);
  48. static $havereadpages;
  49. if (!$havereadpages) { ReadApprovedUrls($pagename); $havereadpages=true; }
  50. $p = str_replace(' ','%20',$path);
  51. $url = str_replace('$1',$p,$IMap[$imap]);
  52. if (!isset($UnapprovedLink)) $UnapprovedLink = array();
  53. foreach((array)$WhiteUrlPatterns as $pat) {
  54. if (preg_match("!^$pat(/|$)!i",$url))
  55. return LinkIMap($pagename,$imap,$path,$alt,$txt,$fmt);
  56. }
  57. $FmtV['$LinkUrl'] = PUE(str_replace('$1',$path,$IMap[$imap]));
  58. $FmtV['$LinkText'] = $txt;
  59. $FmtV['$LinkAlt'] = str_replace(array('"',"'"),array('&#34;','&#39;'),$alt);
  60. $UnapprovedLink[] = $url;
  61. @$UnapprovedLinkCount++;
  62. return FmtPageName($UnapprovedLinkFmt,$pagename);
  63. }
  64. function ReadApprovedUrls($pagename) {
  65. global $ApprovedUrlPagesFmt,$ApproveUrlPattern,$WhiteUrlPatterns;
  66. foreach((array)$ApprovedUrlPagesFmt as $p) {
  67. $pn = FmtPageName($p, $pagename);
  68. StopWatch("ReadApprovedUrls $pn begin");
  69. $apage = ReadPage($pn, READPAGE_CURRENT);
  70. preg_match_all("/$ApproveUrlPattern/",@$apage['text'],$match);
  71. foreach($match[0] as $a)
  72. $WhiteUrlPatterns[] = preg_quote($a,'!');
  73. StopWatch("ReadApprovedUrls $pn end");
  74. }
  75. }
  76. function HandleApprove($pagename, $auth='edit') {
  77. global $ApproveUrlPattern,$WhiteUrlPatterns,$ApprovedUrlPagesFmt,$action;
  78. Lock(2);
  79. $page = ReadPage($pagename);
  80. $text = preg_replace('/[()]/','',$page['text']);
  81. preg_match_all("/$ApproveUrlPattern/",$text,$match);
  82. ReadApprovedUrls($pagename);
  83. $addpat = array();
  84. foreach($match[0] as $a) {
  85. if ($action=='approvesites')
  86. $a=preg_replace("!^([^:]+://[^/]+).*$!",'$1',$a);
  87. $addpat[] = $a;
  88. }
  89. if (count($addpat)>0) {
  90. $aname = FmtPageName($ApprovedUrlPagesFmt[0],$pagename);
  91. $apage = RetrieveAuthPage($aname, $auth);
  92. if (!$apage) Abort("?cannot edit $aname");
  93. $new = $apage;
  94. if (substr($new['text'],-1,1)!="\n") $new['text'].="\n";
  95. foreach($addpat as $a) {
  96. foreach((array)$WhiteUrlPatterns as $pat)
  97. if (preg_match("!^$pat(/|$)!i",$a)) continue 2;
  98. $urlp = preg_quote($a,'!');
  99. $WhiteUrlPatterns[] = $urlp;
  100. $new['text'].=" $a\n";
  101. }
  102. $_POST['post'] = 'y';
  103. PostPage($aname,$apage,$new);
  104. }
  105. Redirect($pagename);
  106. }
  107. function BlockUnapprovedPosts($pagename, &$page, &$new) {
  108. global $EnableUrlApprovalRequired, $UnapprovedLinkCount,
  109. $UnapprovedLinkCountMax, $EnablePost, $MessagesFmt, $BlockMessageFmt;
  110. if (!IsEnabled($EnableUrlApprovalRequired, 1)) return;
  111. if ($UnapprovedLinkCount <= $UnapprovedLinkCountMax) return;
  112. if ($page['=auth']['admin']) return;
  113. $EnablePost = 0;
  114. $MessagesFmt[] = $BlockMessageFmt;
  115. $MessagesFmt[] = XL('Too many unapproved external links.');
  116. }