3 * FusionForge file release system
5 * Copyright 2002, Tim Perdue/GForge, LLC
6 * Copyright 2009, Roland Mas
8 * This file is part of FusionForge.
10 * FusionForge is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published
12 * by the Free Software Foundation; either version 2 of the License,
13 * or (at your option) any later version.
15 * FusionForge is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with FusionForge; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
26 require_once $gfcommon.'include/Error.class.php';
27 require_once $gfcommon.'frs/FRSRelease.class.php';
29 function &get_frs_packages($Group) {
30 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1',
31 array ($Group->getID())) ;
32 if (db_numrows($res) < 1) {
36 while($arr = db_fetch_array($res)) {
37 $ps[]=new FRSPackage($Group,$arr['package_id'],$arr);
43 * Gets a FRSPackage object from the given package id
45 * @param package_id the package id
46 * @param data the DB handle if passed in (optional)
47 * @return the FRSPackage object
49 function &frspackage_get_object($package_id, $data=false) {
50 global $FRSPACKAGE_OBJ;
51 if (!isset($FRSPACKAGE_OBJ['_'.$package_id.'_'])) {
53 //the db result handle was passed in
55 $res = db_query_params ('SELECT * FROM frs_package WHERE package_id=$1',
56 array ($package_id)) ;
57 if (db_numrows($res)<1) {
58 $FRSPACKAGE_OBJ['_'.$package_id.'_']=false;
61 $data =& db_fetch_array($res);
63 $Group =& group_get_object($data['group_id']);
64 $FRSPACKAGE_OBJ['_'.$package_id.'_']= new FRSPackage($Group,$data['package_id'],$data);
66 return $FRSPACKAGE_OBJ['_'.$package_id.'_'];
69 class FRSPackage extends Error {
72 * Associative array of data from db.
74 * @var array $data_array.
77 var $package_releases;
84 var $Group; //group object
89 * @param object The Group object to which this FRSPackage is associated.
90 * @param int The package_id.
91 * @param array The associative array of data.
92 * @return boolean success.
94 function FRSPackage(&$Group, $package_id=false, $arr=false) {
96 if (!$Group || !is_object($Group)) {
97 $this->setError('FRSPackage:: No Valid Group Object');
100 if ($Group->isError()) {
101 $this->setError('FRSPackage:: '.$Group->getErrorMessage());
104 $this->Group =& $Group;
107 if (!$arr || !is_array($arr)) {
108 if (!$this->fetchData($package_id)) {
112 $this->data_array =& $arr;
113 if ($this->data_array['group_id'] != $this->Group->getID()) {
114 $this->setError('Group_id in db result does not match Group Object');
115 $this->data_array=null;
119 // Add an is_public check here
127 * create - create a new FRSPackage in the database.
129 * @param string The name of this package.
130 * @param boolean Whether it's public or not. 1=public 0=private.
131 * @return boolean success.
133 function create($name,$is_public=1) {
134 global $sys_apache_user,$sys_apache_group;
135 if (strlen($name) < 3) {
136 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
139 if (!util_is_valid_filename($name)) {
140 $this->setError(_('FRSPackage::Update: Package Name can only be alphanumeric'));
142 $perm =& $this->Group->getPermission( session_get_user() );
144 if (!$perm || !is_object($perm) || !$perm->isReleaseTechnician()) {
145 $this->setPermissionDeniedError();
149 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1 AND name=$2',
150 array ($this->Group->getID(),
151 htmlspecialchars($name))) ;
152 if (db_numrows($res)) {
153 $this->setError('FRSPackage::create() Error Adding Package: Name Already Exists');
158 $result = db_query_params ('INSERT INTO frs_package(group_id,name,status_id,is_public) VALUES ($1,$2,$3,$4)',
159 array ($this->Group->getId(),
160 htmlspecialchars($name),
165 $this->setError('FRSPackage::create() Error Adding Package: '.db_error());
168 $this->package_id=db_insertid($result,'frs_package','package_id');
169 if (!$this->fetchData($this->package_id)) {
174 //make groupdir if it doesn't exist
175 $groupdir = $GLOBALS['sys_upload_dir'].'/'.$this->Group->getUnixName();
176 if (!is_dir($groupdir)) {
180 $newdirlocation = $GLOBALS['sys_upload_dir'].'/'.$this->Group->getUnixName().'/'.$this->getFileName();
181 exec("/bin/mkdir $newdirlocation",$out);
182 // this 2 should normally silently fail (because it's called with the apache user) but if it's root calling the create() method, then the owner and group for the directory should be changed
183 @chown($newdirlocation,$sys_apache_user);
184 @chgrp($newdirlocation,$sys_apache_group);
191 * fetchData - re-fetch the data for this Package from the database.
193 * @param int The package_id.
194 * @return boolean success.
196 function fetchData($package_id) {
197 $res = db_query_params ('SELECT * FROM frs_package WHERE package_id=$1 AND group_id=$2',
199 $this->Group->getID())) ;
200 if (!$res || db_numrows($res) < 1) {
201 $this->setError('FRSPackage::fetchData() Invalid package_id'.db_error());
204 $this->data_array =& db_fetch_array($res);
205 db_free_result($res);
210 * getGroup - get the Group object this FRSPackage is associated with.
212 * @return object The Group object.
214 function &getGroup() {
219 * getID - get this package_id.
221 * @return int The id of this package.
224 return $this->data_array['package_id'];
228 * getName - get the name of this package.
230 * @return string The name of this package.
233 return $this->data_array['name'];
237 * getFileName - get the filename of this package.
239 * @return string The name of this package.
241 function getFileName() {
242 return eregi_replace("[^-A-Z0-9_\.]",'',$this->data_array['name']);
246 * getStatus - get the status of this package.
248 * @return int The status.
250 function getStatus() {
251 return $this->data_array['status_id'];
255 * isPublic - whether non-group-members can view.
257 * @return boolean is_public.
259 function isPublic() {
260 return $this->data_array['is_public'];
264 * setMonitor - Add the current user to the list of people monitoring this package.
266 * @return boolean success.
268 function setMonitor() {
269 if (!session_loggedin()) {
270 $this->setError(_('You can only monitor if you are logged in'));
273 $result = db_query_params ('SELECT * FROM filemodule_monitor WHERE user_id=$1 AND filemodule_id=$2',
277 if (!$result || db_numrows($result) < 1) {
279 User is not already monitoring thread, so
280 insert a row so monitoring can begin
282 $result = db_query_params ('INSERT INTO filemodule_monitor (filemodule_id,user_id) VALUES ($1,$2)',
283 array ($this->getID(),
287 $this->setError('Unable to add monitor: '.db_error());
296 * stopMonitor - Remove the current user from the list of people monitoring this package.
298 * @return boolean success.
300 function stopMonitor() {
301 if (!session_loggedin()) {
302 $this->setError(_('You can only monitor if you are logged in'));
305 return db_query_params ('DELETE FROM filemodule_monitor WHERE user_id=$1 AND filemodule_id=$2',
311 * getMonitorCount - Get the count of people monitoring this package
313 * @return int the count
315 function getMonitorCount() {
316 $res = db_result(db_query_params ('select count(*) as count from filemodule_monitor where filemodule_id=$1',
317 array ($this->getID())), 0, 0);
319 $this->setError('FRSPackage::getMonitorCount() Error On querying monitor count: '.db_error());
326 * isMonitoring - Is the current user in the list of people monitoring this package.
328 * @return boolean is_monitoring.
330 function isMonitoring() {
331 if (!session_loggedin()) {
334 $sql="SELECT * FROM filemodule_monitor
335 WHERE user_id='".user_getid()."'
336 AND filemodule_id='".$this->getID()."';";
338 $result = db_query_params ('SELECT * FROM filemodule_monitor WHERE user_id=$1 AND filemodule_id=$2',
342 if (!$result || db_numrows($result) < 1) {
350 * getMonitorIDs - Return an array of user_id's of the list of people monitoring this package.
352 * @return array The array of user_id's.
354 function &getMonitorIDs() {
355 $res = db_query_params ('SELECT user_id FROM filemodule_monitor WHERE filemodule_id=$1',
356 array ($this->getID())) ;
357 return util_result_column_to_array($res);
361 * update - update an FRSPackage in the database.
363 * @param string The name of this package.
364 * @param int The status_id of this package from frs_status table.
365 * @return boolean success.
367 function update($name,$status) {
368 if (strlen($name) < 3) {
369 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
373 $perm =& $this->Group->getPermission( session_get_user() );
375 if (!$perm || !is_object($perm) || !$perm->isReleaseTechnician()) {
376 $this->setPermissionDeniedError();
379 if($this->getName()!=htmlspecialchars($name)) {
380 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1 AND name=$2',
381 array ($this->Group->getID(),
382 htmlspecialchars($name))) ;
383 if (db_numrows($res)) {
384 $this->setError('FRSPackage::update() Error Updating Package: Name Already Exists');
389 $res = db_query_params ('UPDATE frs_package SET name=$1, status_id=$2 WHERE group_id=$3 AND package_id=$4',
390 array (htmlspecialchars($name),
392 $this->Group->getID(),
394 if (!$res || db_affected_rows($res) < 1) {
396 $this->setError('FRSPackage::update() Error On Update: '.db_error());
400 $olddirname = $this->getFileName();
401 if(!$this->fetchData($this->getID())){
403 $this->setError("FRSPackage::update() Error Updating Package: Couldn't fetch data");
406 $newdirname = $this->getFileName();
407 $olddirlocation = $GLOBALS['sys_upload_dir'].'/'.$this->Group->getUnixName().'/'.$olddirname;
408 $newdirlocation = $GLOBALS['sys_upload_dir'].'/'.$this->Group->getUnixName().'/'.$newdirname;
410 if(($olddirname!=$newdirname)){
411 if(is_dir($newdirlocation)){
413 $this->setError('FRSPackage::update() Error Updating Package: Directory Already Exists');
416 if(!@rename($olddirlocation,$newdirlocation)) {
418 $this->setError("FRSPackage::update() Error Updating Package: Couldn't rename dir");
428 * getReleases - gets Release objects for all the releases in this package.
430 * return array Array of FRSRelease Objects.
432 function &getReleases() {
433 if (!is_array($this->package_releases) || count($this->package_releases) < 1) {
434 $this->package_releases=array();
435 $res = db_query_params ('SELECT * FROM frs_release WHERE package_id=$1',
436 array ($this->getID())) ;
437 while ($arr = db_fetch_array($res)) {
438 $this->package_releases[]=new FRSRelease($this,$arr['release_id'],$arr);
441 return $this->package_releases;
445 * delete - delete this package and all its related data.
447 * @param bool I'm Sure.
448 * @param bool I'm REALLY sure.
449 * @return bool true/false;
451 function delete($sure, $really_sure) {
452 if (!$sure || !$really_sure) {
453 $this->setMissingParamsError();
456 $perm =& $this->Group->getPermission( session_get_user() );
458 if (!$perm || !is_object($perm) || !$perm->isReleaseTechnician()) {
459 $this->setPermissionDeniedError();
462 $r =& $this->getReleases();
463 for ($i=0; $i<count($r); $i++) {
464 if (!is_object($r[$i]) || $r[$i]->isError() || !$r[$i]->delete($sure, $really_sure)) {
465 $this->setError('Release Error: '.$r[$i]->getName().':'.$r[$i]->getErrorMessage());
469 $dir=$GLOBALS['sys_upload_dir'].'/'.
470 $this->Group->getUnixName() . '/' .
471 $this->getFileName().'/';
473 // double-check we're not trying to remove root dir
474 if (util_is_root_dir($dir)) {
475 $this->setError('Package::delete error: trying to delete root dir');
478 exec('rm -rf '.$dir);
480 db_query_params ('DELETE FROM frs_package WHERE package_id=$1 AND group_id=$2',
481 array ($this->getID(),
482 $this->Group->getID())) ;
490 // c-file-style: "bsd"