jablonka.czprosek.czf

websvn

Subversion Repositories:
[/] [include/] [bugtraq.php] - Blame information for rev 5

 

Line No. Rev Author Line
11simandl<?php
2// WebSVN - Subversion repository viewing via the web using PHP
3// Copyright (C) 2004-2006 Tim Armes
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18//
19// --
20//
21// bugtraq.php
22//
23// Functions for accessing the bugtraq properties and replacing issue IDs
24// with URLs.
25//
26// For more information about bugtraq, see
27// http://svn.collab.net/repos/tortoisesvn/trunk/doc/issuetrackers.txt
28 
29class Bugtraq {
30 // {{{ Properties
31 
32 var $msgstring;
33 var $urlstring;
34 var $logregex;
35 var $append;
36 
37 var $firstPart;
38 var $firstPartLen;
39 var $lastPart;
40 var $lastPartLen;
41 
42 var $propsfound = false;
43 
44 // }}}
45 
46 // {{{ __construct($rep, $svnrep, $path)
47 
48 function Bugtraq($rep, $svnrep, $path) {
49 global $config;
50 
51 if ($rep->getBugtraq()) {
52 $pos = strrpos($path, "/");
53 $parent = substr($path, 0, $pos + 1);
54 $this->append = true;
55 
56 $enoughdata = false;
57 while(!$enoughdata && (strpos($parent, "/") !== false)) {
58 if (empty($this->msgstring)) $this->msgstring = $svnrep->getProperty($parent, 'bugtraq:message');
59 if (empty($this->logregex)) $this->logregex = $svnrep->getProperty($parent, 'bugtraq:logregex');
60 if (empty($this->urlstring)) $this->urlstring = $svnrep->getProperty($parent, 'bugtraq:url');
613simandl if ($svnrep->getProperty($parent, 'bugtraq:append') == 'false') $this->append = false;
621simandl 
63 $parent = substr($parent, 0, -1); // Remove the trailing slash
64 $pos = strrpos($parent, "/"); // Find the last trailing slash
65 $parent = substr($parent, 0, $pos + 1); // Find the previous parent directory
66 $enoughdata = ((!empty($this->msgstring) || !empty($this->logregex)) && !empty($this->urlstring));
67 }
68 
69 $this->msgstring = trim(@$this->msgstring);
70 $this->urlstring = trim(@$this->urlstring);
71 
72 if ($enoughdata && !empty($this->msgstring)) {
73 $this->initPartInfo();
74 }
75 
76 if ($enoughdata) {
77 $this->propsfound = true;
78 }
79 }
80 }
81 
82 // }}}
83 
84 // {{{ initPartInfo()
85 
86 function initPartInfo() {
87 if (($bugidpos = strpos($this->msgstring, "%BUGID%")) !== false && strpos($this->urlstring, "%BUGID%") !== false) {
88 // Get the textual parts of the message string for comparison purposes
89 $this->firstPart = substr($this->msgstring, 0, $bugidpos);
90 $this->firstPartLen = strlen($this->firstPart);
91 $this->lastPart = substr($this->msgstring, $bugidpos + 7);
92 $this->lastPartLen = strlen($this->lastPart);
93 }
94 }
95 
96 // }}}
97 
98 // {{{ replaceIDs($message)
99 
100 function replaceIDs($message) {
101 if ($this->propsfound) {
102 // First we search for the message string
103 
104 $logmsg = "";
105 $message = rtrim($message);
106 
107 if ($this->append) {
108 // Just compare the last line
109 if (($offset = strrpos($message, "\n")) !== false) {
110 $logmsg = substr($message, 0, $offset + 1);
111 $bugLine = substr($message, $offset + 1);
112 } else {
113 $bugLine = $message;
114 }
115 } else {
116 if (($offset = strpos($message, "\n")) !== false) {
117 $bugLine = substr($message, 0, $offset);
118 $logmsg = substr($message, $offset);
119 } else {
120 $bugLine = $message;
121 }
122 }
123 
124 // Make sure that our line really is an issue tracker message
125 
126 if (isset($this->firstPart) && isset($this->lastPart) && ((strncmp($bugLine, $this->firstPart, $this->firstPartLen) == 0)) && strcmp(substr($bugLine, -$this->lastPartLen, $this->lastPartLen), $this->lastPart) == 0) {
127 // Get the issues list
128 if ($this->lastPartLen > 0) {
129 $issues = substr($bugLine, $this->firstPartLen, -$this->lastPartLen);
130 } else {
131 $issues = substr($bugLine, $this->firstPartLen);
132 }
133 
134 // Add each reference to the first part of the line
135 $line = $this->firstPart;
136 while ($pos = strpos($issues, ",")) {
137 $issue = trim(substr($issues, 0, $pos));
138 $issues = substr($issues, $pos + 1);
139 
140 $line .= "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">$issue</a>, ";
141 }
142 $line .= "<a href=\"".str_replace("%BUGID%", trim($issues), $this->urlstring)."\">".trim($issues)."</a>".$this->lastPart;
143 
144 if ($this->append) {
145 $message = $logmsg.$line;
146 } else {
147 $message = $line.$logmsg;
148 }
149 }
150 
151 // Now replace all other instances of bug IDs that match the regex
152 
153 if ($this->logregex) {
154 $message = rtrim($message);
155 $line = "";
156 $allissues = "";
157 
1583simandl $lines = explode("\n", $this->logregex);
1591simandl $regex_all = "~".$lines[0]."~";
160 $regex_single = @$lines[1];
161 
162 if (empty($regex_single)) {
163 // If the property only contains one line, then the pattern is only designed
164 // to find one issue number at a time. e.g. [Ii]ssue #?(\d+). In this case
165 // we need to replace the matched issue ID with the link.
166 
167 if ($numMatches = preg_match_all($regex_all, $message, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
168 $addedOffset = 0;
169 for ($match = 0; $match < $numMatches; $match++) {
170 $issue = $matches[$match][1][0];
171 $issueOffset = $matches[$match][1][1];
172 
173 $issueLink = "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">".$issue."</a>";
174 $message = substr_replace($message, $issueLink, $issueOffset + $addedOffset, strlen($issue));
175 $addedOffset += strlen($issueLink) - strlen($issue);
176 }
177 }
178 } else {
179 // It the property contains two lines, then the first is a pattern for extracting
180 // multiple issue numbers, and the second is a pattern extracting each issue
181 // number from the multiple match. e.g. [Ii]ssue #?(\d+)(,? ?#?(\d+))+ and (\d+)
182 
183 while (preg_match($regex_all, $message, $matches, PREG_OFFSET_CAPTURE)) {
184 $completeMatch = $matches[0][0];
185 $completeMatchOffset = $matches[0][1];
186 
187 $replacement = $completeMatch;
188 
189 if ($numMatches = preg_match_all("~".$regex_single."~", $replacement, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {
190 $addedOffset = 0;
191 for ($match = 0; $match < $numMatches; $match++) {
192 $issue = $matches[$match][1][0];
193 $issueOffset = $matches[$match][1][1];
194 
195 $issueLink = "<a href=\"".str_replace("%BUGID%", $issue, $this->urlstring)."\">".$issue."</a>";
196 $replacement = substr_replace($replacement, $issueLink, $issueOffset + $addedOffset, strlen($issue));
197 $addedOffset += strlen($issueLink) - strlen($issue);
198 }
199 }
200 
201 $message = substr_replace($message, $replacement, $completeMatchOffset, strlen($completeMatch));
202 }
203 }
204 }
205 }
206 
207 return $message;
208 }
209 
210 // }}}
211 
212}
213 
214// The BugtraqTestable class is a derived class that is used to test the matching
215// abilities of the Bugtraq class. In particular, it allows for the initialisation of the
216// class without the need for a repository.
217 
218class BugtraqTestable extends Bugtraq {
219 // {{{ __construct()
220 
221 function BugtraqTestable() {
222 // This constructor serves to assure that the parent constructor is not
223 // called.
224 }
225 
226 // }}}
227 
228 // {{{ setUpVars($message, $url, $regex, $append)
229 
230 function setUpVars($message, $url, $regex, $append) {
231 $this->msgstring = $message;
232 $this->urlstring = $url;
233 $this->logregex = $regex;
234 $this->append = $append;
235 $this->propsfound = true;
236 
237 $this->initPartInfo();
238 }
239 
240 // }}}
241 
242 // {{{ setMessage($message)
243 
244 function setMessage($message) {
245 $this->msgstring = $message;
246 }
247 
248 // }}}
249 
250 // {{{ setUrl($url)
251 
252 function setUrl($url) {
253 $this->urlstring = $url;
254 }
255 
256 // }}}
257 
258 // {{{ setRegex($regex)
259 
260 function setRegEx($regex) {
261 $this->logregex = $regex;
262 }
263 
264 // }}}
265 
266 // {{{ setAppend($append)
267 
268 function setAppend($append) {
269 $this->append = $append;
270 }
271 
272 // }}}
273 
274 // {{{ printVars()
275 
276 function printVars() {
277 echo "msgstring = ".$this->msgstring."\n";
278 echo "urlstring = ".$this->urlstring."\n";
279 echo "logregex = ".$this->logregex."\n";
280 echo "append = ".$this->append."\n";
281 
282 echo "firstPart = ".$this->firstPart."\n";
283 echo "firstPartLen = ".$this->firstPartLen."\n";
284 echo "lastPart = ".$this->lastPart."\n";
285 echo "lastPartLen = ".$this->lastPartLen."\n";
286 }
287 
288 // }}}
289}
290 
291// {{{ test_bugtraq()
292 
293function test_bugtraq() {
294 $tester = new BugtraqTestable;
295 
296 $tester->setUpVars("BugID: %BUGID%",
297 "http://bugtracker/?id=%BUGID%",
298 "[Ii]ssue #?(\d+)",
299 true
300 );
301 
302 //$tester->printVars();
303 
304 $res = $tester->replaceIDs("BugID: 789\n".
305 "This is a test message that refers to issue #123 and\n".
306 "issue #456.\n".
307 "BugID: 789"
308 );
309 
310 echo nl2br($res)."<p>";
311 
312 $res = $tester->replaceIDs("BugID: 789, 101112\n".
313 "This is a test message that refers to issue #123 and\n".
314 "issue #456.\n".
315 "BugID: 789, 101112"
316 );
317 
318 echo nl2br($res)."<p>";
319 
320 $tester->setAppend(false);
321 
322 $res = $tester->replaceIDs("BugID: 789\n".
323 "This is a test message that refers to issue #123 and\n".
324 "issue #456.\n".
325 "BugID: 789"
326 );
327 
328 echo nl2br($res)."<p>";
329 
330 $res = $tester->replaceIDs("BugID: 789, 101112\n".
331 "This is a test message that refers to issue #123 and\n".
332 "issue #456.\n".
333 "BugID: 789, 101112"
334 );
335 
336 echo nl2br($res)."<p>";
337 
338 $tester->setUpVars("BugID: %BUGID%",
339 "http://bugtracker/?id=%BUGID%",
340 "[Ii]ssues?:?(\s*(,|and)?\s*#\d+)+\n(\d+)",
341 true
342 );
343 
344 $res = $tester->replaceIDs("BugID: 789, 101112\n".
345 "This is a test message that refers to issue #123 and\n".
346 "issues #456, #654 and #321.\n".
347 "BugID: 789, 101112"
348 );
349 
350 echo nl2br($res)."<p>";
351 
352 $tester->setUpVars("Test: %BUGID%",
353 "http://bugtracker/?id=%BUGID%",
354 "\s*[Cc]ases*\s*[IDs]*\s*[#: ]+((\d+[ ,:;#]*)+)\n(\d+)",
355 true
356 );
357 
358 $res = $tester->replaceIDs("Cosmetic change\n".
359 "CaseIDs: 48"
360 );
361 
362 echo nl2br($res)."<p>";
363}
364 
365// }}}

Powered by WebSVN 2.2.1