3 * FusionForge source control management
5 * Copyright 2004-2009, Roland Mas
6 * Copyright (C) 2011-2012 Alain Peyrat - Alcatel-Lucent
7 * Copyright 2012,2014,2017, Franck Villaume - TrivialDev
9 * This file is part of FusionForge. FusionForge is free software;
10 * you can redistribute it and/or modify it under the terms of the
11 * GNU General Public License as published by the Free Software
12 * Foundation; either version 2 of the Licence, or (at your option)
15 * FusionForge is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 require_once $gfcommon.'include/scm.php';
26 require_once $gfcommon.'include/SysTasksQ.class.php';
28 abstract class SCMPlugin extends Plugin {
29 function __construct() {
30 parent::__construct();
31 $this->_addHook('group_plugin_use');
32 $this->_addHook('scm_plugin');
33 $this->_addHook('scm_page');
34 $this->_addHook('scm_admin_page');
35 $this->_addHook('scm_admin_update');
36 $this->_addHook('scm_stats');
37 $this->_addHook('scm_create_repo');
39 # Other common hooks that can be enabled per plugin:
40 # scm_generate_snapshots
45 $this->provides['scm'] = true;
48 function CallHook($hookname, &$params) {
50 case 'group_plugin_use': {
51 if ($params['val'] == true) {
52 $systasksq = new SysTasksQ();
53 $systasksq->add(SYSTASK_CORE, 'SCM_REPO', $params['group_id']);
58 $scm_plugins=& $params['scm_plugins'];
59 $scm_plugins[]=$this->name;
63 $this->printPage($params);
66 case 'scm_browser_page': {
67 $this->printBrowserPage($params);
70 case 'scm_admin_page': {
71 $this->printAdminPage($params);
74 case 'scm_admin_update': {
75 $this->adminUpdate($params);
79 $this->printShortStats($params);
82 case 'scm_create_repo': {
84 $this->createOrUpdateRepo($params);
87 case 'scm_update_repolist': {
89 $this->updateRepositoryList($params);
92 case 'scm_regen_apache_auth': {
94 $this->regenApacheAuth($params);
97 case 'scm_generate_snapshots': { // Optional
99 $this->generateSnapshots($params);
102 case 'scm_gather_stats': { // Optional
104 $this->gatherStats($params);
107 case 'widgets': { // Optional
108 $this->widgets($params);
111 case 'widget_instance': { // Optional
112 $this->myPageBox($params);
115 case 'activity': { //Optional
116 $this->activity($params);
120 // Default is to use method named as the hook
121 $this->$hookname($params);
126 final function register() {
129 $scm_list[] = $this->name;
132 function browserDisplayable($project) {
133 if ($project->usesSCM() && $project->usesPlugin($this->name)) {
134 if ($project->enableAnonSCM() || forge_check_perm('scm', $project->getID(), 'read')) {
141 abstract function createOrUpdateRepo($params);
143 function printShortStats($params) {
144 $project = $this->checkParams($params);
149 echo ' ('.$this->text.')';
152 function getBlurb() {
153 return html_e('p', array(), _('Unimplemented SCM plugin.'));
156 function getInstructionsForAnon($project) {
157 return html_e('p', array(), _('Instructions for anonymous access for unimplemented SCM plugin.'));
160 function getInstructionsForRW($project) {
161 return html_e('p', array(), _('Instructions for read-write access for unimplemented SCM plugin.'));
164 function getSnapshotPara($project) {
165 return html_e('p', array(), _('Instructions for snapshot access for unimplemented SCM plugin.'));
168 function getBrowserLinkBlock($project) {
170 $b = $HTML->boxMiddle(_('Repository Browser'));
171 $b .= html_e('p', array(), _('Browsing the SCM tree is not yet implemented for this SCM plugin.'));
172 $b .= html_e('p', array(), '['.util_make_link('/scm/?group_id='.$project->getID(), _('Not implemented yet')).']');
176 function getBrowserBlock($project) {
178 $b = $HTML->boxMiddle(_('Repository Browser'));
179 $b .= html_e('p', array(), _('Browsing the SCM tree is not yet implemented for this SCM plugin.'));
183 function getStatsBlock($project) {
185 $b = $HTML->boxMiddle(_('Repository Statistics'));
186 $b .= html_e('p', array(), _('Not implemented for this SCM plugin yet.'));
190 function printPage($params) {
193 $project = $this->checkParams($params);
198 session_require_perm('scm', $project->getID(), 'read');
199 if (forge_get_config('allow_multiple_scm') && ($params['allow_multiple_scm'] > 1)) {
200 echo html_ao('div', array('id' => 'tabber-'.$this->name, 'class' => 'tabbertab'));
202 // Table for summary info
203 echo $HTML->listTableTop();
205 $cellContent = $this->getBlurb();
207 // Instructions for anonymous access
208 if ($project->enableAnonSCM()) {
209 $cellContent .= $this->getInstructionsForAnon($project);
212 // Instructions for developer access
213 $cellContent .= $this->getInstructionsForRW($project);
216 if ($this->browserDisplayable($project)) {
217 $cellContent .= $this->getBrowserLinkBlock($project);
221 if ($this->browserDisplayable($project)) {
222 $cellContent .= $this->getSnapshotPara($project);
224 $cells[] = array($cellContent, 'style' => 'width:65%');
226 $cellContent = $HTML->boxTop(_('Repository History'));
228 $cellContent .= _('Data about current and past states of the repository.');
229 if ($this->browserDisplayable($project)) {
230 $cellContent .= $this->getStatsBlock($project);
233 $cellContent .= $HTML->boxBottom();
234 $cells[] = array($cellContent, 'style' => 'width:35%', 'class' => 'top');
235 echo $HTML->multiTableRow(array('class' => 'top'), $cells);
236 echo $HTML->listTableBottom();
237 if (forge_get_config('allow_multiple_scm') && ($params['allow_multiple_scm'] > 1)) {
238 echo html_ac(html_ap() - 1);
242 function printBrowserPage($params) {
243 $project = $this->checkParams($params);
248 if ($this->browserDisplayable($project)) {
249 // print '<iframe src="'.util_make_url('/scm/browser.php?title='.$group->getUnixName()).'" frameborder="0" width=100% height=700></iframe>' ;
253 function printAdminPage($params) {
254 $group = $this->checkParams($params);
259 $ra = RoleAnonymous::getInstance();
260 if ($ra->hasPermission('project_read', $group->getID())) {
261 $inputAttr = array('type' => 'checkbox', 'name' => 'scm_enable_anonymous', 'value' => 1);
262 if ($group->enableAnonSCM()) {
263 $inputAttr['checked'] = 'checked';
265 echo html_e('p', array(), html_e('input', $inputAttr).html_e('strong', array(), _('Enable Anonymous Read Access')));
269 function adminUpdate($params) {
270 $project = $this->checkParams($params);
274 if (isset($params['scm_enable_anonymous']) && $params['scm_enable_anonymous']) {
275 $project->SetUsesAnonSCM(true);
277 $project->SetUsesAnonSCM(false);
281 function getBoxForProject($project) {
282 $box = $project->getSCMBox();
284 $box = forge_get_config('default_server', $this->name);
287 $box = forge_get_config('web_host');
292 function scm_delete_repo(&$params) {
293 $project = $this->checkParams($params);
298 if (!isset($params['repo_name'])) {
302 $result = db_query_params('SELECT count(*) AS count FROM scm_secondary_repos WHERE group_id=$1 AND repo_name = $2 AND plugin_id=$3',
303 array ($params['group_id'],
304 $params['repo_name'],
307 $params['error_msg'] = db_error();
310 if (db_result($result, 0, 'count') == 0) {
311 $params['error_msg'] = sprintf(_('No repository %s exists'), $params['repo_name']);
315 $result = db_query_params ('UPDATE scm_secondary_repos SET next_action = $1 WHERE group_id=$2 AND repo_name=$3 AND plugin_id=$4',
316 array (SCM_EXTRA_REPO_ACTION_DELETE,
318 $params['repo_name'],
321 $params['error_msg'] = db_error();
325 plugin_hook("scm_admin_update", $params);
329 function checkParams($params) {
330 $group_id = $params['group_id'];
331 $project = group_get_object($group_id);
332 if (!$project || !is_object($project)) {
334 } elseif ($project->isError()) {
336 } elseif (!$project->usesSCM()) {
338 } elseif (!$project->usesPlugin($this->name)) {
348 // c-file-style: "bsd"