Rev 3925 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 // filedetails.php 21 // filedetails.php
24 // 22 //
25 // Simply lists the contents of a file 23 // Simply lists the contents of a file
26   24  
27 require_once("include/setup.inc"); 25 require_once 'include/setup.php';
28 require_once("include/svnlook.inc"); 26 require_once 'include/svnlook.php';
29 require_once("include/utils.inc"); 27 require_once 'include/utils.php';
30 require_once("include/template.inc"); 28 require_once 'include/template.php';
31   29  
32 // Make sure that we have a repository 30 // Make sure that we have a repository
33 if (!isset($rep)) 31 if (!$rep)
34 { 32 {
35 echo $lang["NOREP"]; 33 renderTemplate404('file','NOREP');
36 exit; -  
37 } 34 }
38   35  
39 $svnrep = new SVNRepository($rep); 36 $svnrep = new SVNRepository($rep);
40   37  
41 if ($path{0} != "/") 38 if ($path[0] != '/')
-   39 {
42 $ppath = "/".$path; 40 $ppath = '/'.$path;
-   41 }
43 else 42 else
-   43 {
44 $ppath = $path; 44 $ppath = $path;
-   45 }
45   46  
46 $passrev = $rev; 47 $useMime = false;
47   48  
48 // If there's no revision info, go to the lastest revision for this path 49 // If there's no revision info, go to the lastest revision for this path
49 $history = $svnrep->getLog($path, "", "", true); 50 $history = $svnrep->getLog($path, 'HEAD', 1, false, 2, ($path == '/') ? '' : $peg);
50 $youngest = $history->entries[0]->rev; -  
51   51  
-   52 if (!$history)
-   53 {
-   54 unset($vars['error']);
-   55 $history = $svnrep->getLog($path, '', '', false, 2, ($path == '/') ? '' : $peg);
-   56 if (!$history)
-   57 {
-   58 renderTemplate404('file','NOPATH');
-   59 }
-   60 }
-   61  
-   62 $youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : false;
-   63  
52 if (empty($rev)) 64 if (empty($rev))
-   65 {
53 $rev = $youngest; 66 $rev = !$peg ? $youngest : min($peg, $youngest);
-   67 }
54   68  
55 $extn = strrchr($path, "."); 69 $extn = strtolower(strrchr($path, '.'));
56   70  
57 // Check to see if the user has requested that this type be zipped and sent 71 // Check to see if the user has requested that this type be zipped and sent
58 // to the browser as an attachment 72 // to the browser as an attachment
59   73  
60 if (in_array($extn, $zipped)) 74 if ($history && isset($zipped) && in_array($extn, $zipped) && $rep->hasReadAccess($path, false))
61 { 75 {
62 $base = basename($path); 76 $base = basename($path);
63 header("Content-Type: application/x-gzip"); 77 header('Content-Type: application/gzip');
64 header("Content-Disposition: attachment; filename=".urlencode($base).".gz"); 78 header("Content-Disposition: attachment; filename*=UTF-8''".rawurlencode($base).'.gz');
65   79  
66 // Get the file contents and pipe into gzip. All this without creating 80 // Get the file contents and pipe into gzip. All this without creating
67 // a temporary file. Damn clever. 81 // a temporary file. Damn clever.
68 $svnrep->getFileContents($path, "", $rev, "| ".$config->gzip." -n -f"); 82 $svnrep->getFileContents($path, '', $rev, $peg, '| '.$config->gzip.' -n -f');
69 -  
70 exit; 83 exit;
71 } 84 }
72   85  
73 // Check to see if we should serve it with a particular content-type. 86 // Check to see if we should serve it with a particular content-type.
74 // The content-type could come from an svn:mime-type property on the 87 // The content-type could come from an svn:mime-type property on the
75 // file, or from the $contentType array in setup.inc. 88 // file, or from the $contentType array in setup.php.
76   89  
77 if (!$rep->getIgnoreSvnMimeTypes()) 90 if (!$rep->getIgnoreSvnMimeTypes())
78 { 91 {
79 $svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev); 92 $svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev);
80 } 93 }
81   94  
82 if (!$rep->getIgnoreWebSVNContentTypes()) 95 if (!$rep->getIgnoreWebSVNContentTypes())
83 { 96 {
84 $setupContentType = @$contentType[$extn]; 97 $setupContentType = @$contentType[$extn];
85 } 98 }
86   99  
87 // Use this set of priorities when establishing what content-type to 100 // Use the documented priorities when establishing what content-type to use.
88 // actually use. -  
89   -  
90 if (!empty($svnMimeType) && $svnMimeType != 'application/octet-stream') 101 if (!empty($svnMimeType) && $svnMimeType != 'application/octet-stream')
91 { 102 {
92 $cont = $svnMimeType; 103 $mimeType = $svnMimeType;
93 } 104 }
94 else if (!empty($setupContentType)) 105 else if (!empty($setupContentType))
95 { 106 {
96 $cont = $setupContentType; 107 $mimeType = $setupContentType;
97 } 108 }
98 else if (!empty($svnMimeType)) 109 else if (!empty($svnMimeType))
-   110 {
-   111 $mimeType = $svnMimeType; // Use SVN's default of 'application/octet-stream'
-   112 }
-   113 else
-   114 {
-   115 $mimeType = '';
-   116 }
-   117  
-   118 $useMime = ($mimeType) ? @$_REQUEST['usemime'] : false;
-   119  
-   120 if ($history && !empty($mimeType) && !$useMime)
-   121 {
-   122 $useMime = $mimeType; // Save MIME type for later before possibly clobbering
-   123 // If a MIME type exists but is set to be ignored, set it to an empty string.
-   124 foreach ($config->inlineMimeTypes as $inlineType)
-   125 {
-   126 if (preg_match('|'.$inlineType.'|', $mimeType))
-   127 {
-   128 $mimeType = '';
-   129 break;
-   130 }
-   131 }
-   132 }
-   133  
-   134 // If a MIME type is associated with the file, deliver with Content-Type header.
-   135 if ($history && !empty($mimeType) && $rep->hasReadAccess($path, false))
99 { 136 {
-   137 $base = basename($path);
100 // It now is equal to application/octet-stream due to logic 138 header('Content-Type: '.$mimeType);
101 // above.... 139 //header('Content-Length: '.$size);
-   140 header("Content-Disposition: inline; filename*=UTF-8''".rawurlencode($base));
102 $cont = $svnMimeType; 141 $svnrep->getFileContents($path, '', $rev, $peg);
-   142 exit;
103 } 143 }
104   144  
-   145 // Display the file inline using WebSVN.
-   146  
-   147 $vars['action'] = '';
105 // If there's a MIME type associated with this format, then we deliver it 148 $vars['path'] = str_replace('%2F', '/', rawurlencode($ppath));
106 // with this information 149 $vars['safepath'] = escape($ppath);
107   150  
108 if (!empty($cont)) 151 if (isset($history->entries[0]))
109 { 152 {
110 $base = basename($path); -  
111 -  
112 header("Content-Type: $cont"); 153 $vars['log'] = xml_entities($history->entries[0]->msg);
113 //header("Content-Length: $size"); 154 $vars['date'] = $history->entries[0]->date;
114 header("Content-Disposition: inline; filename=".urlencode($base)); 155 $vars['age'] = datetimeFormatDuration(time() - strtotime($history->entries[0]->date));
115 -  
116 $svnrep->getFileContents($path, "", $rev); 156 $vars['author'] = $history->entries[0]->author;
117 -  
118 exit; -  
119 } 157 }
120   158  
-   159 createPathLinks($rep, $ppath, !$passrev && $peg ? $rev : $passrev, $peg);
121 // Explicitly requested file as attachment 160 $passRevString = createRevAndPegString($rev, $peg);
-   161  
122 if (isset($_REQUEST['getfile'])) 162 if ($rev != $youngest)
123 { 163 {
124 $base = basename($path); 164 $vars['goyoungesturl'] = $config->getURL($rep, $path, 'file').createRevAndPegString($youngest, $peg);
-   165 $vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>';
-   166 }
125   167  
126 header("Content-Type: application/octet-stream"); -  
127 header("Content-Length: $size"); 168 $revurl = $config->getURL($rep, $path, 'file');
128 header("Content-Disposition: inline; filename=".urlencode($base)); -  
129   169  
-   170 if ($rev < $youngest)
-   171 {
130 $svnrep->getFileContents($path, "", $rev); 172 $history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg ? $peg : 'HEAD');
131   173  
-   174 if (isset($history2->entries[1]))
-   175 {
-   176 $nextRev = $history2->entries[1]->rev;
-   177 if ($nextRev != $youngest)
-   178 {
-   179 $vars['nextrev'] = $nextRev;
-   180 $vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg);
132 exit; 181 }
-   182 }
-   183  
-   184 unset($vars['error']);
133 } 185 }
134   186  
135 // There's no associated MIME type. Show the file using WebSVN. 187 $history3 = $svnrep->getLog($path, $rev, 1, true, 2, $peg ? $peg : 'HEAD');
136   188  
-   189 if (isset($history3->entries[1]))
-   190 {
-   191 $prevRev = $history3->entries[1]->rev;
137 $url = $config->getURL($rep, $path, "file"); 192 $prevPath = $history3->entries[1]->path;
-   193 $vars['prevrev'] = $prevRev;
-   194 $vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg);
-   195 }
138   196  
139 if ($rev != $youngest) 197 unset($vars['error']);
140 $vars["goyoungestlink"] = "<a href=\"${url}sc=1\">${lang["GOYOUNGEST"]}</a>"; -  
141 else -  
142 $vars["goyoungestlink"] = ""; -  
143   198  
144 $vars["action"] = ""; -  
145 $vars["repname"] = $rep->getDisplayName(); 199 $vars['revurl'] = $config->getURL($rep, $path, 'revision').$passRevString;
146 $vars["rev"] = $rev; 200 $vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>';
147 $vars["path"] = $ppath; -  
148   201  
149 createDirLinks($rep, $ppath, $passrev, $showchanged); 202 $vars['logurl'] = $config->getURL($rep, $path, 'log').$passRevString;
-   203 $vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>';
150   204  
151 $url = $config->getURL($rep, $path, "log"); 205 $vars['blameurl'] = $config->getURL($rep, $path, 'blame').$passRevString;
152 $vars["fileviewloglink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged&isdir=0\">${lang["VIEWLOG"]}</a>"; 206 $vars['blamelink'] = '<a href="'.$vars['blameurl'].'">'.$lang['BLAME'].'</a>';
153   207  
-   208 if ($history == null || count($history->entries) > 1)
-   209 {
154 $url = $config->getURL($rep, $path, "diff"); 210 $vars['diffurl'] = $config->getURL($rep, $path, 'diff').$passRevString;
155 $vars["prevdifflink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged\">${lang["DIFFPREV"]}</a>"; 211 $vars['difflink'] = '<a href="'.$vars['diffurl'].'">'.$lang['DIFFPREV'].'</a>';
-   212 }
156   213  
-   214 if ($rep->isDownloadAllowed($path))
-   215 {
157 $url = $config->getURL($rep, $path, "blame"); 216 $vars['downloadlurl'] = $config->getURL($rep, $path, 'dl').$passRevString;
158 $vars["blamelink"] = "<a href=\"${url}rev=$passrev&amp;sc=$showchanged\">${lang["BLAME"]}</a>"; 217 $vars['downloadlink'] = '<a href="'.$vars['downloadlurl'].'">'.$lang['DOWNLOAD'].'</a>';
-   218 }
159   219  
160 #$url = $config->getURL($rep, $path, "get"); 220 if ($rep->isRssEnabled())
-   221 {
161 $url = $config->getURL($rep, $path, "file"); 222 $vars['rssurl'] = $config->getURL($rep, $path, 'rss').createRevAndPegString('', $peg);
162 $vars["getfile"] = "<a href=\"${url}getfile&amp;rev=$passrev&amp;sc=$showchanged\">${lang["GETFILE"]}</a>"; 223 $vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>';
-   224 }
163   225  
-   226 $mimeType = $useMime; // Restore preserved value to use for 'mimelink' variable.
-   227 // If there was a MIME type, create a link to display file with that type.
164 $listing = array (); 228 if ($mimeType && !isset($vars['warning']))
-   229 {
-   230 $vars['mimeurl'] = $config->getURL($rep, $path, 'file').'usemime=1&amp;'.$passRevString;
-   231 $vars['mimelink'] = '<a href="'.$vars['mimeurl'].'">'.$lang['VIEWAS'].' "'.$mimeType.'"</a>';
-   232 }
165   233  
-   234 $vars['rev'] = $rev;
166 $vars["version"] = $version; 235 $vars['peg'] = $peg;
167   236  
168 if (!$rep->hasReadAccess($path, false)) 237 if (!$rep->hasReadAccess($path))
-   238 {
169 $vars["noaccess"] = true; 239 $vars['error'] = $lang['NOACCESS'];
-   240 sendHeaderForbidden();
-   241 }
-   242 else if (!$svnrep->isFile($path, $rev, $peg))
-   243 {
-   244 renderTemplate404('file','NOPATH');
-   245 }
170   246  
171 parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing); 247 // $listing is populated with file data when file.tmpl calls [websvn-getlisting]
172 parseTemplate($rep->getTemplatePath()."file.tmpl", $vars, $listing); 248 renderTemplate('file');
173 parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing); -  
174 ?> -