2 /** FusionForge Subversion plugin
4 * Copyright 2003-2009, Roland Mas
5 * Copyright 2004, GForge, LLC
7 * This file is part of FusionForge.
9 * FusionForge is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2 of the License,
12 * or (at your option) any later version.
14 * FusionForge is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with FusionForge; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 class SVNPlugin extends SCM {
26 function SVNPlugin () {
29 $this->name = 'scmsvn';
31 $this->hooks[] = 'scm_page';
32 $this->hooks[] = 'scm_admin_update';
33 $this->hooks[] = 'scm_admin_page';
34 $this->hooks[] = 'scm_stats';
35 $this->hooks[] = 'scm_createrepo';
36 $this->hooks[] = 'scm_plugin';
38 require_once $gfconfig.'plugins/scmsvn/config.php' ;
40 $this->default_svn_server = $default_svn_server ;
41 $this->enabled_by_default = $enabled_by_default ;
42 $this->use_ssh = $use_ssh;
43 $this->use_dav = $use_dav;
44 $this->use_ssl = $use_ssl;
45 $this->svn_root = $svn_root;
50 function getDefaultServer() {
51 return $this->default_svn_server ;
54 function CallHook ($hookname, $params) {
59 $group_id = $params['group_id'] ;
60 $this->getPage ($group_id) ;
62 case 'scm_admin_update':
63 $this->AdminUpdate ($params) ;
65 case 'scm_admin_page':
66 $this->getAdminPage ($params) ;
69 $this->getStats ($params) ;
71 case 'scm_createrepo':
72 $this->createOrUpdateRepo ($params) ;
75 $scm_plugins=& $params['scm_plugins'];
76 $scm_plugins[]=$this->name;
83 function getPage ($group_id) {
84 global $HTML, $sys_scm_snapshots_path;
86 $project =& group_get_object($group_id);
87 if (!$project || !is_object($project)) {
89 } elseif ($project->isError()) {
93 if ($project->usesPlugin ($this->name)) {
95 // SVN browser links must be displayed if
96 // project enables anon SVN or if logged-in
97 // user is a member of the group
98 $displaySvnBrowser = $project->enableAnonSCM();
99 if(session_loggedin()) {
100 $perm =& $project->getPermission(session_get_user());
101 if ($perm && is_object($perm) && !$perm->isError() && $perm->isMember()) {
102 $displaySvnBrowser = true;
106 // Table for summary info
107 print '<table width="100%"><tr valign="top"><td width="65%">' ;
108 print _('<p>Documentation for Subversion (sometimes referred to as "SVN") is available <a href="http://svnbook.red-bean.com/">here</a>.</p>');
110 // Anonymous SVN Instructions
111 if ($project->enableAnonSCM()) {
112 print _('<p><b>Anonymous Subversion Access</b></p><p>This project\'s SVN repository can be checked out through anonymous access with the following command(s).</p>');
114 if ($this->use_ssh) {
115 print '<tt>svn checkout svn://'.$project->getSCMBox().'/'.$this->svn_root.'/'.$project->getUnixName().'</tt><br />';
117 if ($this->use_dav) {
118 print '<tt>svn checkout --username anonsvn http'.(($this->use_ssl) ? 's' : '').'://' . $project->getSCMBox(). '/' . $this->svn_root .'/'. $project->getUnixName() .'</tt><br/><br/>';
119 print _('The password is \'anonsvn\'').'<br/>';
125 if ($this->use_ssh) {
126 if (session_loggedin()) {
127 echo _('<p><b>Developer Subversion Access via SSH</b></p><p>Only project developers can access the SVN tree via this method. SSH must be installed on your client machine. Enter your site password when prompted.</p>');
128 print '<p><tt>svn checkout svn+ssh://' ;
129 $u = session_get_user();
130 print $u->getUnixName();
131 print '@' . $project->getSCMBox() . '/'. $this->svn_root .'/'. $project->getUnixName().'</tt></p>' ;
133 echo _('<p><b>Developer Subversion Access via SSH</b></p><p>Only project developers can access the SVN tree via this method. SSH must be installed on your client machine. Substitute <i>developername</i> with the proper values. Enter your site password when prompted.</p>');
134 print '<p><tt>svn checkout svn+ssh://<i>'._('developername').'</i>@' . $project->getSCMBox() . '/'. $this->svn_root .'/'. $project->getUnixName().'</tt></p>' ;
137 if ($this->use_dav) {
138 if (session_loggedin()) {
139 echo _('<p><b>Developer Subversion Access via DAV</b></p><p>Only project developers can access the SVN tree via this method. Enter your site password when prompted.</p>');
140 print '<p><tt>svn checkout --username ';
141 $u = session_get_user();
142 print $u->getUnixName();
143 print ' http'.(($this->use_ssl) ? 's' : '').'://'. $project->getSCMBox() .'/'. $this->svn_root .'/'.$project->getUnixName().'</tt></p>' ;
145 echo _('<p><b>Developer Subversion Access via DAV</b></p><p>Only project developers can access the SVN tree via this method. Substitute <i>developername</i> with the proper values. Enter your site password when prompted.</p>');
146 print '<p><tt>svn checkout --username <i>'._('developername').'</i> http'.(($this->use_ssl) ? 's' : '').'://'. $project->getSCMBox() .'/'. $this->svn_root .'/'.$project->getUnixName().'</tt></p>' ;
151 if ($displaySvnBrowser) {
152 $filename=$project->getUnixName().'-scm-latest.tar.gz';
153 if (file_exists($sys_scm_snapshots_path.'/'.$filename)) {
155 print util_make_link ("/snapshots.php?group_id=$group_id",
156 _('Download The Nightly SVN Tree Snapshot')
161 print '</td><td width="35%" valign="top">' ;
164 echo $HTML->boxTop(_('Repository History'));
165 echo $this->getDetailedStats(array('group_id'=>$group_id)).'<p>';
166 if ($displaySvnBrowser) {
167 echo _('<b>Browse the Subversion Tree</b><p>Browsing the SVN tree gives you a great view into the current status of this project\'s code. You may also view the complete histories of any file in the repository.</p>');
169 echo util_make_link ("/scm/viewvc.php/?root=".$project->getUnixName(),
170 _('Browse Subversion Repository')
175 echo $HTML->boxBottom();
176 print '</td></tr></table>' ;
180 function AdminUpdate ($params) {
181 $group =& group_get_object($params['group_id']);
182 if (!$group || !is_object($group)) {
184 } elseif ($group->isError()) {
188 if ( $group->usesPlugin ( $this->name ) ) {
189 if ($params['scmsvn_enable_anon_svn']) {
190 $group->SetUsesAnonSCM(true);
192 $group->SetUsesAnonSCM(false);
197 // This function is used to render checkboxes below
200 return 'checked="checked"';
206 function getAdminPage ($params) {
207 $group =& group_get_object($params['group_id']);
208 if ( $group->usesPlugin ( $this->name ) && $group->isPublic()) {
209 print '<p><input type="checkbox" name="scmsvn_enable_anon_svn" value="1" '.$this->c($group->enableAnonSCM()).' /><strong>'._('Enable Anonymous Access').'</strong></p>';
213 function getStats ($params) {
214 $group_id = $params['group_id'] ;
215 $project =& group_get_object($group_id);
216 if (!$project || !is_object($project)) {
218 } elseif ($project->isError()) {
222 if ($project->usesPlugin ($this->name)) {
223 list($commit_num, $add_num) = $this->getTotalStats($group_id);
224 echo ' (SVN: '.sprintf(_('<strong>%1$s</strong> updates, <strong>%2$s</strong> adds'), number_format($commit_num, 0), number_format($add_num, 0)).')';
228 // Get the total stats for a group
229 function getTotalStats($group_id) {
230 $result = db_query_params ('
231 SELECT SUM(commits) AS commits, SUM(adds) AS adds
235 $commit_num = db_result($result,0,0);
236 $add_num = db_result($result,0,1);
243 return array($commit_num, $add_num);
246 function getDetailedStats ($params) {
248 $group_id = $params['group_id'] ;
251 SELECT u.realname, u.user_name, u.user_id, sum(commits) as commits, sum(adds) as adds, sum(adds+commits) as combined
252 FROM stats_cvs_user s, users u
253 WHERE group_id=\''.$group_id.'\' AND s.user_id=u.user_id AND (commits>0 OR adds >0)
254 GROUP BY group_id, realname, user_name, u.user_id
255 ORDER BY combined DESC, realname;
258 if (db_numrows($result) > 0) {
259 $tableHeaders = array(
264 echo $HTML->listTableTop($tableHeaders);
267 $total = array('adds' => 0, 'commits' => 0);
269 while($data = db_fetch_array($result)) {
270 echo '<tr '. $HTML->boxGetAltRowStyle($i) .'>';
271 echo '<td width="50%">' ;
272 echo util_make_link_u ($data['user_name'], $data['user_id'], $data['realname']) ;
273 echo '</td><td width="25%" align="right">'.$data['adds']. '</td>'.
274 '<td width="25%" align="right">'.$data['commits'].'</td></tr>';
275 $total['adds'] += $data['adds'];
276 $total['commits'] += $data['commits'];
279 list($commit_num, $add_num) = $this->getTotalStats($group_id);
280 if ($commit_num > $total['commits'] ||
281 $add_num > $total['adds']) {
282 echo '<tr '. $HTML->boxGetAltRowStyle($i) .'>';
283 echo '<td width="50%">' .
285 '</td><td width="25%" align="right">'.
286 ($add_num - $total['adds']) . '</td>'.
287 '<td width="25%" align="right">'.
288 ($commit_num - $total['commits']) .
292 echo '<tr '. $HTML->boxGetAltRowStyle($i) .'>';
293 echo '<td width="50%"><strong>'._('Total').':</strong></td>'.
294 '<td width="25%" align="right"><strong>'.$add_num. '</strong></td>'.
295 '<td width="25%" align="right"><strong>'.$commit_num.'</strong></td>';
297 echo $HTML->listTableBottom();
298 echo '<hr size="1" />';
302 function createOrUpdateRepo ($params) {
303 $group_id = $params['group_id'] ;
305 $project =& group_get_object($group_id);
306 if (!$project || !is_object($project)) {
308 } elseif ($project->isError()) {
312 if (! $project->usesPlugin ($this->name)) {
316 $repo = $this->svn_root . '/' . $project->getUnixName() ;
317 $unix_group = 'scm_' . $project->getUnixName() ;
319 $repo_exists = false ;
320 if (is_dir ($repo) && is_file ("$repo/format")) {
321 $repo_exists = true ;
325 system ("svnadmin create --fs-type fsfs $repo") ;
328 system ("chgrp -R $unix_group $repo") ;
329 if ($project->enableAnonSCM()) {
330 system ("chmod -R g+wXs,o+rX-w $repo") ;
332 system ("chmod -R g+wXs,o-rwx $repo") ;
339 // c-file-style: "bsd"