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/FRSFile.class.php';
30 * Factory method which creates a FRSRelease from an release id
32 * @param int The release id
33 * @param array The result array, if it's passed in
34 * @return object FRSRelease object
36 function &frsrelease_get_object($release_id, $data=false) {
37 global $FRSRELEASE_OBJ;
38 if (!isset($FRSRELEASE_OBJ['_'.$release_id.'_'])) {
40 //the db result handle was passed in
42 $res = db_query_params ('SELECT * FROM frs_release WHERE release_id=$1',
43 array ($release_id)) ;
44 if (db_numrows($res)<1 ) {
45 $FRSRELEASE_OBJ['_'.$release_id.'_']=false;
48 $data =& db_fetch_array($res);
50 $FRSPackage =& frspackage_get_object($data['package_id']);
51 $FRSRELEASE_OBJ['_'.$release_id.'_']= new FRSRelease($FRSPackage,$data['release_id'],$data);
53 return $FRSRELEASE_OBJ['_'.$release_id.'_'];
56 class FRSRelease extends Error {
59 * Associative array of data from db.
61 * @var array $data_array.
68 * @var object FRSPacakge.
76 * @param object The FRSPackage object to which this release is associated.
77 * @param int The release_id.
78 * @param array The associative array of data.
79 * @return boolean success.
81 function FRSRelease(&$FRSPackage, $release_id=false, $arr=false) {
83 if (!$FRSPackage || !is_object($FRSPackage)) {
84 $this->setError('FRSRelease:: No Valid FRSPackage Object');
87 if ($FRSPackage->isError()) {
88 $this->setError('FRSRelease:: '.$FRSPackage->getErrorMessage());
91 $this->FRSPackage =& $FRSPackage;
94 if (!$arr || !is_array($arr)) {
95 if (!$this->fetchData($release_id)) {
99 $this->data_array =& $arr;
100 if ($this->data_array['package_id'] != $this->FRSPackage->getID()) {
101 $this->setError('FRSPackage_id in db result does not match FRSPackage Object');
102 $this->data_array=null;
111 * create - create a new release in the database.
113 * @param string The name of the release.
114 * @param string The release notes for the release.
115 * @param string The change log for the release.
116 * @param int Whether the notes/log are preformatted with \n chars (1) true (0) false.
117 * @param int The unix date of the release.
118 * @return boolean success.
120 function create($name,$notes,$changes,$preformatted,$release_date=false) {
121 if (strlen($name) < 3) {
122 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
132 if (!forge_check_perm ('frs', $this->FRSPackage->Group->getID(), 'write')) {
133 $this->setPermissionDeniedError();
137 if (!$release_date) {
138 $release_date=time();
140 $res = db_query_params ('SELECT * FROM frs_release WHERE package_id=$1 AND name=$2',
141 array ($this->FRSPackage->getID(),
142 htmlspecialchars($name))) ;
143 if (db_numrows($res)) {
144 $this->setError('FRSRelease::create() Error Adding Release: Name Already Exists');
149 $result=db_query_params ('INSERT INTO frs_release(package_id,notes,changes,preformatted,name,release_date,released_by,status_id) VALUES ($1,$2,$3,$4,$5,$6,$7,$8)',
150 array ($this->FRSPackage->getId(),
151 htmlspecialchars($notes),
152 htmlspecialchars($changes),
154 htmlspecialchars($name),
160 $this->setError('FRSRelease::create() Error Adding Release: '.db_error());
163 $this->release_id=db_insertid($result,'frs_release','release_id');
164 if (!$this->fetchData($this->release_id)) {
168 $newdirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$this->getFileName();
169 if (!is_dir($newdirlocation)) {
170 @mkdir($newdirlocation);
178 * fetchData - re-fetch the data for this Release from the database.
180 * @param int The release_id.
181 * @return boolean success.
183 function fetchData($release_id) {
184 $res = db_query_params ('SELECT * FROM frs_release WHERE release_id=$1 AND package_id=$2',
186 $this->FRSPackage->getID())) ;
187 if (!$res || db_numrows($res) < 1) {
188 $this->setError('FRSRelease::fetchData() Invalid release_id');
191 $this->data_array =& db_fetch_array($res);
192 db_free_result($res);
197 * getFRSPackage - get the FRSPackage object this release is associated with.
199 * @return object The FRSPackage object.
201 function &getFRSPackage() {
202 return $this->FRSPackage;
206 * getID - get this release_id.
208 * @return int The id of this release.
211 return $this->data_array['release_id'];
215 * getName - get the name of this release.
217 * @return string The name of this release.
220 return $this->data_array['name'];
224 * getFileName - get the filename of this release.
226 * @return string The filename of this release.
228 function getFileName() {
229 return eregi_replace("[^-A-Z0-9_\.]",'',$this->data_array['name']);
233 * getStatus - get the status of this release.
235 * @return int The status.
237 function getStatus() {
238 return $this->data_array['status_id'];
242 * getNotes - get the release notes of this release.
244 * @return string The release notes.
246 function getNotes() {
247 return $this->data_array['notes'];
251 * getChanges - get the changelog of this release.
253 * @return string The changelog.
255 function getChanges() {
256 return $this->data_array['changes'];
260 * getPreformatted - get the preformatted option of this release.
262 * @return boolean preserve_formatting.
264 function getPreformatted() {
265 return $this->data_array['preformatted'];
269 * getReleaseDate - get the releasedate of this release.
271 * @return int The release date in unix time.
273 function getReleaseDate() {
274 return $this->data_array['release_date'];
278 * sendNotice - the logic to send an email/jabber notice for a release.
280 * @return boolean success.
282 function sendNotice() { //send E-Mail
283 $arr =& $this->FRSPackage->getMonitorIDs();
285 $date = date('Y-m-d H:i',time());
287 $subject = sprintf (_('[%1$s Release] %2$s'),
288 $this->FRSPackage->Group->getUnixName(),
289 $this->FRSPackage->getName());
290 $text = stripcslashes(sprintf(_('Project %1$s (%2$s) has released a new version of package "%3$s".
301 You can download it by following this link:
305 You receive this email because you requested to be notified when new
306 versions of this package were released. If you don\'t wish to be
307 notified in the future, please login to %7$s and click this link:
317 $this->FRSPackage->Group->getPublicName(),
318 $this->FRSPackage->Group->getUnixName(),
319 $this->FRSPackage->getName(),
322 util_make_url ("/frs/?group_id=". $this->FRSPackage->Group->getID() ."&release_id=". $this->getID()),
323 forge_get_config ('forge_name'),
324 util_make_url ("/frs/monitor.php?filemodule_id=".$this->FRSPackage->getID()."&group_id=".$this->FRSPackage->Group->getID()."&stop=1")));
325 // $text = util_line_wrap($text);
327 util_handle_message(array_unique($arr),$subject,$text);
333 * getFiles - gets all the file objects for files in this release.
335 * return array Array of FRSFile Objects.
337 function &getFiles() {
338 if (!is_array($this->release_files) || count($this->release_files) < 1) {
339 $this->release_files=array();
340 $res = db_query_params ('SELECT * FROM frs_file_vw WHERE release_id=$1',
341 array ($this->getID())) ;
342 while ($arr = db_fetch_array($res)) {
343 $this->release_files[]=new FRSFile($this,$arr['file_id'],$arr);
346 return $this->release_files;
350 * delete - delete this release and all its related data.
352 * @param bool I'm Sure.
353 * @param bool I'm REALLY sure.
354 * @return bool true/false;
356 function delete($sure, $really_sure) {
357 if (!$sure || !$really_sure) {
358 $this->setMissingParamsError();
361 if (!forge_check_perm ('frs', $this->FRSPackage->Group->getID(), 'write')) {
362 $this->setPermissionDeniedError();
365 $f =& $this->getFiles();
366 for ($i=0; $i<count($f); $i++) {
367 if (!is_object($f[$i]) || $f[$i]->isError() || !$f[$i]->delete()) {
368 $this->setError('File Error: '.$f[$i]->getName().':'.$f[$i]->getErrorMessage());
372 $dir=forge_get_config('upload_dir').'/'.
373 $this->FRSPackage->Group->getUnixName() . '/' .
374 $this->FRSPackage->getFileName().'/'.
375 $this->getFileName().'/';
377 // double-check we're not trying to remove root dir
378 if (util_is_root_dir($dir)) {
379 $this->setError('Release::delete error: trying to delete root dir');
382 exec('rm -rf '.$dir);
384 db_query_params ('DELETE FROM frs_release WHERE release_id=$1 AND package_id=$2',
385 array ($this->getID(),
386 $this->FRSPackage->getID())) ;
391 * update - update a new release in the database.
393 * @param int The status of this release from the frs_status table.
394 * @param string The name of the release.
395 * @param string The release notes for the release.
396 * @param string The change log for the release.
397 * @param int Whether the notes/log are preformatted with \n chars (1) true (0) false.
398 * @param int The unix date of the release.
399 * @return boolean success.
401 function update($status,$name,$notes,$changes,$preformatted,$release_date) {
402 if (strlen($name) < 3) {
403 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
407 if (!forge_check_perm ('frs', $this->FRSPackage->Group->getID(), 'write')) {
408 $this->setPermissionDeniedError();
418 if($this->getName()!=htmlspecialchars($name)) {
419 $res = db_query_params ('SELECT * FROM frs_release WHERE package_id=$1 AND name=$2',
420 array ($this->FRSPackage->getID(),
421 htmlspecialchars($name))) ;
422 if (db_numrows($res)) {
423 $this->setError('FRSRelease::update() Error On Update: Name Already Exists');
428 $res = db_query_params ('UPDATE frs_release SET name=$1,status_id=$2,notes=$3,
429 changes=$4,preformatted=$5,release_date=$6,released_by=$7
430 WHERE package_id=$8 AND release_id=$9',
431 array (htmlspecialchars($name),
433 htmlspecialchars($notes),
434 htmlspecialchars($changes),
438 $this->FRSPackage->getID(),
441 if (!$res || db_affected_rows($res) < 1) {
443 $this->setError('FRSRelease::update() Error On Update: '.db_error());
447 $oldfilename = $this->getFileName();
448 if(!$this->fetchData($this->getID())){
450 $this->setError("FRSRelease::update() Error Updating Release: Couldn't fetch data");
453 $newfilename = $this->getFileName();
454 $olddirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$oldfilename;
455 $newdirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$newfilename;
457 if (($oldfilename!=$newfilename) && is_dir($olddirlocation)) {
458 if (is_dir($newdirlocation)) {
460 $this->setError('FRSRelease::update() Error Updating Release: Directory Already Exists');
463 if(!rename($olddirlocation,$newdirlocation)) {
465 $this->setError("FRSRelease::update() Error Updating Release: Couldn't rename dir");
478 // c-file-style: "bsd"