1<?php 2/** 3 * @package tikiwiki 4 */ 5// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 6// 7// All Rights Reserved. See copyright.txt for details and a complete list of authors. 8// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 9// $Id$ 10 11$inputConfiguration = [ 12 [ 'staticKeyFilters' => [ 13 'searchtext' => 'xss', 14 'replacetext' => 'xss', 15 'maxRecords' => 'digits', 16 'offset' => 'digits', 17 'paddingLength' => 'digits', 18 ] 19 ] 20]; 21 22require_once('tiki-setup.php'); 23 24$wikilib = TikiLib::lib('wiki'); 25 26$access->check_feature(['feature_wiki']); 27$access->check_permission(['tiki_p_admin_wiki']); 28 29// Search input 30$searchtext = ''; 31$replacetext = ''; 32if (! empty($_REQUEST['replacetext'])) { 33 $replacetext = $_REQUEST['replacetext']; 34} else { 35 $replacetext = ''; 36} 37if (! empty($_REQUEST['searchtext'])) { 38 $searchtext = $_REQUEST['searchtext']; 39} 40if (! isset($_REQUEST["offset"])) { 41 $offset = 0; 42} else { 43 $offset = $_REQUEST["offset"]; 44} 45$smarty->assign('offset', $offset); 46 47if (! empty($_REQUEST['categId'])) { 48 $categFilter = [$_REQUEST['categId']]; 49 $smarty->assign('find_categId', $_REQUEST['categId']); 50} else { 51 $categFilter = []; 52 $smarty->assign('find_categId', ''); 53} 54if ($prefs['feature_categories'] == 'y') { 55 $categlib = TikiLib::lib('categ'); 56 $categories = $categlib->getCategories(null, true, false); 57 $smarty->assign('categories', $categories); 58} 59if (isset($_REQUEST["maxRecords"])) { 60 $maxRecords = $_REQUEST["maxRecords"]; 61} else { 62 $maxRecords = 10; 63} 64$smarty->assign('maxRecords', $maxRecords); 65 66if (! isset($_REQUEST["paddingLength"])) { 67 $paddingLength = 50; 68} else { 69 $paddingLength = $_REQUEST["paddingLength"]; 70} 71$smarty->assign('paddingLength', $paddingLength); 72if (isset($_REQUEST["casesensitive"]) && $_REQUEST["casesensitive"] == 'y') { 73 $casesensitive = 'y'; 74} else { 75 $casesensitive = 'n'; 76} 77$smarty->assign('casesensitive', $casesensitive); 78 79if (isset($_REQUEST['search']) && $searchtext) { 80 $results = $wikilib->get_pages_contains($searchtext, $offset, $maxRecords, 'pageName_asc', $categFilter); 81 $searchtextLength = strlen($searchtext); 82 foreach ($results["data"] as &$r) { 83 $pageLength = strlen($r["data"]); 84 $curpos = -1; 85 while ($curpos < $pageLength) { 86 if ($casesensitive == 'y') { 87 $curpos = strpos($r["data"], $searchtext, $curpos + 1); 88 } else { 89 $curpos = stripos($r["data"], $searchtext, $curpos + 1); 90 } 91 if ($curpos === false) { 92 $r["beforeSnippet"][] = tra('This match was not case sensitive'); 93 $r["afterSnippet"][] = tra('This match was not case sensitive'); 94 $r["searchreplace"][] = '0:0:0'; 95 break; 96 } 97 // can't use str_replace because it replaces all: we need to be more precise 98 $snippetStart = max(0, $curpos - $paddingLength); 99 $leftpartLength = $curpos - $snippetStart; 100 $rightpartLength = min($paddingLength, $pageLength - $curpos - $searchtextLength); 101 $rightpartStart = $curpos + $searchtextLength; 102 $foundtext = substr($r["data"], $curpos, $searchtextLength); 103 104 $lefthash = md5($r["page_id"] . $r["version"] . $searchtext . $curpos); 105 $righthash = md5($curpos . $searchtext . $r["version"] . $r["page_id"]); 106 107 $beforeSnippet = substr($r["data"], $snippetStart, $leftpartLength) . $lefthash . $foundtext . $righthash . substr($r["data"], $rightpartStart, $rightpartLength); 108 $beforeSnippet = htmlentities($beforeSnippet); 109 $beforeSnippet = str_replace($lefthash, '<strong>', $beforeSnippet); 110 $beforeSnippet = str_replace($righthash, '</strong>', $beforeSnippet); 111 112 $afterSnippet = substr($r["data"], $snippetStart, $leftpartLength) . $lefthash . $replacetext . $righthash . substr($r["data"], $rightpartStart, $rightpartLength); 113 $afterSnippet = htmlentities($afterSnippet); 114 $afterSnippet = str_replace($lefthash, '<strong>', $afterSnippet); 115 $afterSnippet = str_replace($righthash, '</strong>', $afterSnippet); 116 117 $r["beforeSnippet"][] = $beforeSnippet; 118 $r["afterSnippet"][] = $afterSnippet; 119 $r["searchreplace"][] = ($r["page_id"] . ":" . $r["version"] . ":" . $curpos); 120 } 121 } 122 $smarty->assign('cant', $results['cant']); 123 $smarty->assign('results', $results['data']); 124} 125 126if (isset($_REQUEST['replace']) && $searchtext) { 127 if (empty($_REQUEST['checked'])) { 128 $message = tra('No items selected'); 129 } else { 130 $last_page_id = 0; 131 foreach ($_REQUEST['checked'] as $c) { 132 list($page_id, $version, $curpos) = explode(":", $c); 133 if ($last_page_id && $page_id == $last_page_id) { 134 $version = $version + $versionadjuster; 135 $curpos = $curpos + $curposadjuster; 136 } else { 137 $last_page_id = 0; 138 $curposadjuster = 0; 139 $versionadjuster = 0; 140 } 141 $page_info = $tikilib->get_page_info_from_id($page_id); 142 if (! $page_info) { 143 $message .= tra("Page cannot be found: ") . $page_id . "<br />"; 144 continue; 145 } 146 if ($page_info["version"] != $version) { 147 $message .= tra("Page has changed since preview: ") . htmlentities($page_info["pageName"]) . "<br />"; 148 continue; 149 } 150 // do replacing 151 $searchtextLength = strlen($searchtext); 152 $data = $page_info["data"]; 153 $firstpart = substr($data, 0, $curpos); 154 $lastpart = substr($data, $curpos + $searchtextLength); 155 if (strtolower(substr($data, $curpos, $searchtextLength)) != strtolower($searchtext)) { 156 $message .= tra("Page not updated due to error in replacing: ") . htmlentities($page_info["pageName"]) . "<br />"; 157 continue; 158 } 159 $data = $firstpart . $replacetext . $lastpart; 160 $tikilib->update_page($page_info["pageName"], $data, tra('Mass search and replace'), $user, $tikilib->get_ip_address()); 161 $message .= tra("Page updated: ") . htmlentities($page_info["pageName"]) . "<br />"; 162 $versionadjuster++; 163 $curposadjuster = $curposadjuster + strlen($replacetext) - $searchtextLength; 164 $last_page_id = $page_id; 165 } 166 } 167 if (empty($message)) { 168 $message = tra('Nothing was replaced. Try selecting fewer items or increasing the limit change max_input_vars in php.ini.'); 169 } 170 $smarty->assign('message', $message); 171} 172 173$smarty->assign('searchtext', $searchtext); 174$smarty->assign('replacetext', $replacetext); 175 176$smarty->assign('mid', 'tiki-search_replace.tpl'); 177$smarty->display("tiki.tpl"); 178