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) {
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 or "-" "_" "+" "." "~"'));
142 if (!forge_check_perm ('frs', $this->Group->getID(), 'write')) {
143 $this->setPermissionDeniedError();
147 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1 AND name=$2',
148 array ($this->Group->getID(),
149 htmlspecialchars($name))) ;
150 if (db_numrows($res)) {
151 $this->setError('FRSPackage::create() Error Adding Package: Name Already Exists');
156 $result = db_query_params ('INSERT INTO frs_package(group_id,name,status_id,is_public) VALUES ($1,$2,$3,$4)',
157 array ($this->Group->getId(),
158 htmlspecialchars($name),
163 $this->setError('FRSPackage::create() Error Adding Package: '.db_error());
166 $this->package_id=db_insertid($result,'frs_package','package_id');
167 if (!$this->fetchData($this->package_id)) {
172 //make groupdir if it doesn't exist
173 $groupdir = forge_get_config('upload_dir').'/'.$this->Group->getUnixName();
174 if (!is_dir($groupdir)) {
178 $newdirlocation = $groupdir.'/'.$this->getFileName();
179 if (!is_dir($newdirlocation)) {
180 @mkdir($newdirlocation);
183 // 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
184 @chown($newdirlocation,forge_get_config('apache_user'));
185 @chgrp($newdirlocation,forge_get_config('apache_group'));
192 * fetchData - re-fetch the data for this Package from the database.
194 * @param int The package_id.
195 * @return boolean success.
197 function fetchData($package_id) {
198 $res = db_query_params ('SELECT * FROM frs_package WHERE package_id=$1 AND group_id=$2',
200 $this->Group->getID())) ;
201 if (!$res || db_numrows($res) < 1) {
202 $this->setError('FRSPackage::fetchData() Invalid package_id'.db_error());
205 $this->data_array =& db_fetch_array($res);
206 db_free_result($res);
211 * getGroup - get the Group object this FRSPackage is associated with.
213 * @return object The Group object.
215 function &getGroup() {
220 * getID - get this package_id.
222 * @return int The id of this package.
225 return $this->data_array['package_id'];
229 * getName - get the name of this package.
231 * @return string The name of this package.
234 return $this->data_array['name'];
238 * getFileName - get the filename of this package.
240 * @return string The name of this package.
242 function getFileName() {
243 return eregi_replace("[^-A-Z0-9_\.]",'',$this->data_array['name']);
247 * getStatus - get the status of this package.
249 * @return int The status.
251 function getStatus() {
252 return $this->data_array['status_id'];
256 * isPublic - whether non-group-members can view.
258 * @return boolean is_public.
260 function isPublic() {
261 return $this->data_array['is_public'];
265 * setMonitor - Add the current user to the list of people monitoring this package.
267 * @return boolean success.
269 function setMonitor() {
270 if (!session_loggedin()) {
271 $this->setError(_('You can only monitor if you are logged in'));
274 $result = db_query_params ('SELECT * FROM filemodule_monitor WHERE user_id=$1 AND filemodule_id=$2',
278 if (!$result || db_numrows($result) < 1) {
280 User is not already monitoring thread, so
281 insert a row so monitoring can begin
283 $result = db_query_params ('INSERT INTO filemodule_monitor (filemodule_id,user_id) VALUES ($1,$2)',
284 array ($this->getID(),
288 $this->setError('Unable to add monitor: '.db_error());
297 * stopMonitor - Remove the current user from the list of people monitoring this package.
299 * @return boolean success.
301 function stopMonitor() {
302 if (!session_loggedin()) {
303 $this->setError(_('You can only monitor if you are logged in'));
306 return db_query_params ('DELETE FROM filemodule_monitor WHERE user_id=$1 AND filemodule_id=$2',
312 * getMonitorCount - Get the count of people monitoring this package
314 * @return int the count
316 function getMonitorCount() {
317 $res = db_result(db_query_params ('select count(*) as count from filemodule_monitor where filemodule_id=$1',
318 array ($this->getID())), 0, 0);
320 $this->setError('FRSPackage::getMonitorCount() Error On querying monitor count: '.db_error());
327 * isMonitoring - Is the current user in the list of people monitoring this package.
329 * @return boolean is_monitoring.
331 function isMonitoring() {
332 if (!session_loggedin()) {
336 $result = db_query_params ('SELECT * FROM filemodule_monitor WHERE user_id=$1 AND filemodule_id=$2',
340 if (!$result || db_numrows($result) < 1) {
348 * getMonitorIDs - Return an array of user_id's of the list of people monitoring this package.
350 * @return array The array of user_id's.
352 function &getMonitorIDs() {
353 $res = db_query_params ('SELECT user_id FROM filemodule_monitor WHERE filemodule_id=$1',
354 array ($this->getID())) ;
355 return util_result_column_to_array($res);
359 * update - update an FRSPackage in the database.
361 * @param string The name of this package.
362 * @param int The status_id of this package from frs_status table.
363 * @return boolean success.
365 function update($name,$status) {
366 if (strlen($name) < 3) {
367 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
371 if (!forge_check_perm ('frs', $this->Group->getID(), 'write')) {
372 $this->setPermissionDeniedError();
375 if($this->getName()!=htmlspecialchars($name)) {
376 $res = db_query_params ('SELECT * FROM frs_package WHERE group_id=$1 AND name=$2',
377 array ($this->Group->getID(),
378 htmlspecialchars($name))) ;
379 if (db_numrows($res)) {
380 $this->setError('FRSPackage::update() Error Updating Package: Name Already Exists');
385 $res = db_query_params ('UPDATE frs_package SET name=$1, status_id=$2 WHERE group_id=$3 AND package_id=$4',
386 array (htmlspecialchars($name),
388 $this->Group->getID(),
390 if (!$res || db_affected_rows($res) < 1) {
392 $this->setError('FRSPackage::update() Error On Update: '.db_error());
396 $olddirname = $this->getFileName();
397 if(!$this->fetchData($this->getID())){
399 $this->setError("FRSPackage::update() Error Updating Package: Couldn't fetch data");
402 $newdirname = $this->getFileName();
403 $olddirlocation = forge_get_config('upload_dir').'/'.$this->Group->getUnixName().'/'.$olddirname;
404 $newdirlocation = forge_get_config('upload_dir').'/'.$this->Group->getUnixName().'/'.$newdirname;
406 if(($olddirname!=$newdirname)){
407 if(is_dir($newdirlocation)){
409 $this->setError('FRSPackage::update() Error Updating Package: Directory Already Exists');
412 if(!@rename($olddirlocation,$newdirlocation)) {
414 $this->setError("FRSPackage::update() Error Updating Package: Couldn't rename dir");
424 * getReleases - gets Release objects for all the releases in this package.
426 * return array Array of FRSRelease Objects.
428 function &getReleases() {
429 if (!is_array($this->package_releases) || count($this->package_releases) < 1) {
430 $this->package_releases=array();
431 $res = db_query_params ('SELECT * FROM frs_release WHERE package_id=$1',
432 array ($this->getID())) ;
433 while ($arr = db_fetch_array($res)) {
434 $this->package_releases[]=new FRSRelease($this,$arr['release_id'],$arr);
437 return $this->package_releases;
441 * delete - delete this package and all its related data.
443 * @param bool I'm Sure.
444 * @param bool I'm REALLY sure.
445 * @return bool true/false;
447 function delete($sure, $really_sure) {
448 if (!$sure || !$really_sure) {
449 $this->setMissingParamsError();
452 if (!forge_check_perm ('frs', $this->Group->getID(), 'write')) {
453 $this->setPermissionDeniedError();
456 $r =& $this->getReleases();
457 for ($i=0; $i<count($r); $i++) {
458 if (!is_object($r[$i]) || $r[$i]->isError() || !$r[$i]->delete($sure, $really_sure)) {
459 $this->setError('Release Error: '.$r[$i]->getName().':'.$r[$i]->getErrorMessage());
463 $dir=forge_get_config('upload_dir').'/'.
464 $this->Group->getUnixName() . '/' .
465 $this->getFileName().'/';
467 // double-check we're not trying to remove root dir
468 if (util_is_root_dir($dir)) {
469 $this->setError('Package::delete error: trying to delete root dir');
472 exec('rm -rf '.$dir);
474 db_query_params ('DELETE FROM frs_package WHERE package_id=$1 AND group_id=$2',
475 array ($this->getID(),
476 $this->Group->getID())) ;
484 // c-file-style: "bsd"