Rev 185 Rev 4988
Line 1... Line 1...
1 <?php 1 <?php
2 # vim:et:ts=3:sts=3:sw=3:fdm=marker: -  
3   -  
4 // WebSVN - Subversion repository viewing via the web using PHP 2 // WebSVN - Subversion repository viewing via the web using PHP
5 // Copyright © 2004-2006 Tim Armes, Matt Sicker 3 // Copyright (C) 2004-2006 Tim Armes
6 // 4 //
7 // This program is free software; you can redistribute it and/or modify 5 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by 6 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or 7 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version. 8 // (at your option) any later version.
11 // 9 //
12 // This program is distributed in the hope that it will be useful, 10 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details. 13 // GNU General Public License for more details.
16 // 14 //
17 // You should have received a copy of the GNU General Public License 15 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software 16 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // 18 //
21 // -- 19 // --
22 // 20 //
23 // blame.php 21 // blame.php
24 // 22 //
25 // Show the blame information of a file. 23 // Show the blame information of a file.
26 // 24 //
27   25  
28 require_once 'include/setup.inc'; 26 require_once 'include/setup.php';
29 require_once 'include/svnlook.inc'; 27 require_once 'include/svnlook.php';
30 require_once 'include/utils.inc'; 28 require_once 'include/utils.php';
31 require_once 'include/template.inc'; 29 require_once 'include/template.php';
32   30  
33 $vars['action'] = $lang['BLAME']; 31 $vars['action'] = $lang['BLAME'];
34   32  
-   33 // Make sure that we have a repository
-   34 if (!$rep)
-   35 {
-   36 renderTemplate404('blame','NOREP');
-   37 }
-   38  
35 $svnrep = new SVNRepository($rep); 39 $svnrep = new SVNRepository($rep);
36   40  
37 // If there's no revision info, go to the lastest revision for this path 41 // If there's no revision info, go to the lastest revision for this path
38 $history = $svnrep->getLog($path, '', '', true); 42 $history = $svnrep->getLog($path, 'HEAD', 1, false, 2, ($path == '/') ? '' : $peg);
-   43  
-   44 if (!$history)
-   45 {
39 $youngest = $history->entries[0]->rev; 46 unset($vars['error']);
-   47 $history = $svnrep->getLog($path, '', '', false, 2, ($path == '/') ? '' : $peg);
40   48  
41 if (empty($rev)) 49 if (!$history)
-   50 {
42 $rev = $youngest; 51 renderTemplate404('blame','NOPATH');
-   52 }
-   53 }
-   54 $youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : false;
43   55  
-   56 if (empty($rev))
-   57 {
-   58 $rev = $youngest;
-   59 }
-   60 else
-   61 {
-   62 $history = $svnrep->getLog($path, $rev, '', false, 2, $peg);
-   63 if (!$history)
-   64 {
-   65 renderTemplate404('blame','NOPATH');
-   66 }
-   67 }
-   68  
44 if ($path{0} != '/') 69 if ($path[0] != '/')
-   70 {
45 $ppath = '/'.$path; 71 $ppath = '/'.$path;
-   72 }
46 else 73 else
-   74 {
47 $ppath = $path; 75 $ppath = $path;
-   76 }
48   77  
49 // Find the parent path (or the whole path if it's already a directory) 78 // Find the parent path (or the whole path if it's already a directory)
50 $pos = strrpos($ppath, '/'); 79 $pos = strrpos($ppath, '/');
51 $parent = substr($ppath, 0, $pos + 1); 80 $parent = substr($ppath, 0, $pos + 1);
52   81  
53 $vars['repname'] = $rep->getDisplayName(); -  
54 $vars['rev'] = $rev; 82 $vars['rev'] = $rev;
55 $vars['path'] = $ppath; 83 $vars['peg'] = $peg;
-   84 $vars['path'] = str_replace('%2F', '/', rawurlencode($ppath));
-   85 $vars['safepath'] = escape($ppath);
-   86  
-   87 if (isset($history->entries[0]))
-   88 {
-   89 $vars['log'] = xml_entities($history->entries[0]->msg);
-   90 $vars['date'] = $history->entries[0]->date;
-   91 $vars['age'] = datetimeFormatDuration(time() - strtotime($history->entries[0]->date));
-   92 $vars['author'] = $history->entries[0]->author;
-   93 }
-   94  
-   95 createPathLinks($rep, $ppath, $passrev, $peg);
-   96 $passRevString = createRevAndPegString($rev, $peg);
-   97  
-   98 if ($rev != $youngest)
-   99 {
-   100 $vars['goyoungesturl'] = $config->getURL($rep, $path, 'blame').createRevAndPegString('', $peg);
-   101 $vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>';
-   102 }
-   103  
-   104 $revurl = $config->getURL($rep, $path, 'blame');
-   105  
-   106 if ($rev < $youngest)
-   107 {
-   108 $history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg);
-   109  
-   110 if (isset($history2->entries[1]))
-   111 {
-   112 $nextRev = $history2->entries[1]->rev;
-   113 if ($nextRev != $youngest)
-   114 {
-   115 $vars['nextrev'] = $nextRev;
-   116 $vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg);
-   117 }
-   118 }
-   119  
-   120 unset($vars['error']);
-   121 }
-   122  
-   123 if (isset($history->entries[1]))
-   124 {
-   125 $prevRev = $history->entries[1]->rev;
-   126 $prevPath = $history->entries[1]->path;
-   127 $vars['prevrev'] = $prevRev;
-   128 $vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg);
-   129 }
-   130  
-   131 $vars['revurl'] = $config->getURL($rep, $path, 'revision').$passRevString;
-   132 $vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>';
-   133  
-   134 $vars['logurl'] = $config->getURL($rep, $path, 'log').$passRevString;
-   135 $vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>';
56   136  
-   137 $vars['filedetailurl'] = $config->getURL($rep, $path, 'file').$passRevString;
-   138 $vars['filedetaillink'] = '<a href="'.$vars['filedetailurl'].'">'.$lang['FILEDETAIL'].'</a>';
-   139  
-   140 if ($history == null || count($history->entries) > 1)
-   141 {
57 createDirLinks($rep, $ppath, $rev, $showchanged); 142 $vars['diffurl'] = $config->getURL($rep, $path, 'diff').$passRevString;
-   143 $vars['difflink'] = '<a href="'.$vars['diffurl'].'">'.$lang['DIFFPREV'].'</a>';
-   144 }
58   145  
-   146 if ($rep->isRssEnabled())
-   147 {
-   148 $vars['rssurl'] = $config->getURL($rep, $path, 'rss').createRevAndPegString('', $peg);
-   149 $vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>';
-   150 }
-   151  
-   152 // Check for binary file type before grabbing blame information.
-   153 $svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev, $peg);
-   154  
-   155 if (!$rep->getIgnoreSvnMimeTypes() && preg_match('~application/*~', $svnMimeType))
-   156 {
-   157 $vars['warning'] = 'Cannot display blame info for binary file. (svn:mime-type = '.$svnMimeType.')';
-   158 $vars['javascript'] = '';
-   159 }
-   160 else
-   161 {
-   162 // Get the contents of the file
-   163 $tfname = tempnamWithCheck($config->getTempDir(), '');
-   164 $highlighted = $svnrep->getFileContents($path, $tfname, $rev, $peg, '', 'line');
-   165  
-   166 if ($file = fopen($tfname, 'r'))
-   167 {
-   168 // Get the blame info
-   169 $tbname = tempnamWithCheck($config->getTempDir(), '');
-   170  
-   171 $svnrep->getBlameDetails($path, $tbname, $rev, $peg);
-   172  
-   173 if ($blame = fopen($tbname, 'r'))
-   174 {
-   175 // Create an array of version/author/line
-   176  
-   177 $index = 0;
-   178 $seen_rev = array();
-   179 $last_rev = '';
-   180 $row_class = '';
-   181  
-   182 while (!feof($blame) && !feof($file))
-   183 {
-   184 $blameline = rtrim(fgets($blame), "\n\r");
-   185  
-   186 if ($blameline != '')
-   187 {
-   188 list($revision, $author, $remainder) = sscanf($blameline, '%d %s %s');
-   189 $empty = !$remainder;
-   190  
-   191 $listvar = &$listing[$index];
-   192 $listvar['lineno'] = $index + 1;
-   193  
-   194 if ($last_rev != $revision)
-   195 {
-   196 $listvar['revision'] = '<a id="l'.$index.'-rev" class="blame-revision" href="'.$config->getURL($rep, $path, 'blame').createRevAndPegString($revision, $peg ? $peg : $rev).'">'.$revision.'</a>';
-   197 $seen_rev[$revision] = 1;
-   198 $row_class = ($row_class == 'light') ? 'dark' : 'light';
-   199 $listvar['author'] = $author;
-   200 }
-   201 else
-   202 {
-   203 $listvar['revision'] = '';
-   204 $listvar['author'] = '';
-   205 }
-   206  
-   207 $listvar['row_class'] = $row_class;
-   208 $last_rev = $revision;
-   209  
-   210 $line = rtrim(fgets($file), "\n\r");
-   211 if (!$highlighted)
-   212 {
-   213 $line = escape(toOutputEncoding($line));
-   214 }
-   215 $listvar['line'] = ($empty) ? '&nbsp;' : wrapInCodeTagIfNecessary($line);
-   216 $index++;
-   217 }
-   218 }
-   219 fclose($blame);
-   220 }
-   221  
-   222 fclose($file);
-   223 @unlink($tbname);
-   224 }
-   225 @unlink($tfname);
-   226  
-   227 // Build the necessary JavaScript as an array of lines, then join them with \n
59 $listing = array(); 228 $javascript = array();
-   229 $javascript[] = '<script type="text/javascript" src="'.$locwebsvnhttp.'/javascript/blame-popup.js"></script>';
-   230 $javascript[] = '<script type="text/javascript">';
-   231 $javascript[] = '/* <![CDATA[ */';
-   232 $javascript[] = 'var rev = new Array();';
-   233  
-   234 ksort($seen_rev); // Sort revisions in descending order by key
-   235 if (empty($peg))
-   236 {
-   237 $peg = $rev;
-   238 }
-   239 if (!isset($vars['warning']))
-   240 {
-   241 foreach ($seen_rev as $key => $val)
-   242 {
-   243 $history = $svnrep->getLog($path, $key, $key, false, 1, $peg);
-   244  
-   245 if ($history && $history->curEntry)
-   246 {
-   247 $javascript[] = 'rev['.$key.'] = \'<div class="date">'.$history->curEntry->date.'</div><div class="msg">'.addslashes(preg_replace('/\n/', ' ', $history->curEntry->msg)).'</div>\';';
-   248 }
-   249 }
-   250 }
-   251  
-   252 $javascript[] = '/* ]]> */';
-   253 $javascript[] = '</script>';
-   254 $vars['javascript'] = implode("\n", $javascript);
-   255 }
-   256  
-   257 if (!$rep->hasReadAccess($path, false))
-   258 {
-   259 $vars['error'] = $lang['NOACCESS'];
-   260 sendHeaderForbidden();
-   261 }
60   262  
61 // Get the contents of the file -  
62 $tfname = tempnam('temp', ''); -  
63 $svnrep->getFileContents($path, $tfname, $rev, '', true); -  
64   -  
65 $filecache = array(); -  
66   -  
67 if ($file = fopen($tfname, 'r')) -  
68 { -  
69 // Get the blame info -  
70 $tbname = tempnam('temp', ''); -  
71 $svnrep->getBlameDetails($path, $tbname, $rev); -  
72 -  
73 $ent = true; -  
74 $extension = strrchr(basename($path), '.'); -  
75 if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript)) -  
76 $ent = false; -  
77   -  
78 if ($blame = fopen($tbname, 'r')) -  
79 { -  
80 // Create an array of version/author/line -  
81 -  
82 $index = 0; -  
83 -  
84 while (!feof($blame) && !feof($file)) -  
85 { -  
86 $blameline = fgets($blame); -  
87 -  
88 if ($blameline != '') -  
89 { -  
90 list($revision, $author) = sscanf($blameline, '%d %s'); -  
91 -  
92 $listing[$index]['lineno'] = $index + 1; -  
93 -  
94 $url = $config->getURL($rep, $parent, 'dir'); -  
95 $listing[$index]['revision'] = "<a href=\"${url}rev=$revision&amp;sc=1\">$revision</a>"; -  
96   -  
97 $listing[$index]['author'] = $author; -  
98 -  
99 if ($ent) -  
100 $line = replaceEntities(rtrim(fgets($file)), $rep); -  
101 else -  
102 $line = rtrim(fgets($file)); -  
103   -  
104 $listing[$index]['line'] = hardspace($line); -  
105 -  
106 if (trim($listing[$index]['line']) == '') -  
107 $listing[$index]['line'] = '&nbsp;'; -  
108 -  
109 $index++; -  
110 } -  
111 } -  
112 -  
113 fclose($blame); 263 renderTemplate('blame');
114 } -  
115 -  
116 fclose($file); -  
117 } -  
118   -  
119 unlink($tfname); -  
120 unlink($tbname); -  
121   -  
122 $vars['version'] = $version; -  
123   -  
124 if (!$rep->hasReadAccess($path, false)) -  
125 $vars['noaccess'] = true; -  
126   -  
127 parseTemplate($rep->getTemplatePath().'header.tmpl', $vars, $listing); -  
128 parseTemplate($rep->getTemplatePath().'blame.tmpl', $vars, $listing); -  
129 parseTemplate($rep->getTemplatePath().'footer.tmpl', $vars, $listing); -  
130 -  
131 ?> -