3 * FusionForge file release system
5 * Copyright 2002, Tim Perdue/GForge, LLC
6 * Copyright 2009, Roland Mas
8 * This file is part of FusionForge. FusionForge is free software;
9 * you can redistribute it and/or modify it under the terms of the
10 * GNU General Public License as published by the Free Software
11 * Foundation; either version 2 of the Licence, or (at your option)
14 * FusionForge is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 require_once $gfcommon.'include/Error.class.php';
25 require_once $gfcommon.'frs/FRSFile.class.php';
28 * Factory method which creates a FRSRelease from an release id
30 * @param int The release id
31 * @param array The result array, if it's passed in
32 * @return object FRSRelease object
34 function frsrelease_get_object($release_id, $data = false) {
35 global $FRSRELEASE_OBJ;
36 if (!isset($FRSRELEASE_OBJ['_'.$release_id.'_'])) {
38 //the db result handle was passed in
40 $res = db_query_params ('SELECT * FROM frs_release WHERE release_id=$1',
41 array ($release_id)) ;
42 if (db_numrows($res)<1 ) {
43 $FRSRELEASE_OBJ['_'.$release_id.'_']=false;
46 $data = db_fetch_array($res);
48 $FRSPackage = frspackage_get_object($data['package_id']);
49 $FRSRELEASE_OBJ['_'.$release_id.'_']= new FRSRelease($FRSPackage,$data['release_id'],$data);
51 return $FRSRELEASE_OBJ['_'.$release_id.'_'];
54 class FRSRelease extends Error {
57 * Associative array of data from db.
59 * @var array $data_array.
66 * @var object FRSPacakge.
74 * @param object The FRSPackage object to which this release is associated.
75 * @param int The release_id.
76 * @param array The associative array of data.
77 * @return boolean success.
79 function FRSRelease(&$FRSPackage, $release_id = false, $arr = false) {
81 if (!$FRSPackage || !is_object($FRSPackage)) {
82 $this->setError('FRSRelease:: No Valid FRSPackage Object');
85 if ($FRSPackage->isError()) {
86 $this->setError('FRSRelease:: '.$FRSPackage->getErrorMessage());
89 $this->FRSPackage =& $FRSPackage;
92 if (!$arr || !is_array($arr)) {
93 if (!$this->fetchData($release_id)) {
97 $this->data_array =& $arr;
98 if ($this->data_array['package_id'] != $this->FRSPackage->getID()) {
99 $this->setError('FRSPackage_id in db result does not match FRSPackage Object');
100 $this->data_array=null;
109 * create - create a new release in the database.
111 * @param string The name of the release.
112 * @param string The release notes for the release.
113 * @param string The change log for the release.
114 * @param int Whether the notes/log are preformatted with \n chars (1) true (0) false.
115 * @param int The unix date of the release.
116 * @return boolean success.
118 function create($name,$notes,$changes,$preformatted,$release_date=false) {
119 if (strlen($name) < 3) {
120 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
130 if (!forge_check_perm ('frs', $this->FRSPackage->Group->getID(), 'write')) {
131 $this->setPermissionDeniedError();
135 if (!$release_date) {
136 $release_date=time();
138 $res = db_query_params ('SELECT * FROM frs_release WHERE package_id=$1 AND name=$2',
139 array ($this->FRSPackage->getID(),
140 htmlspecialchars($name))) ;
141 if (db_numrows($res)) {
142 $this->setError('FRSRelease::create() Error Adding Release: Name Already Exists');
147 $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)',
148 array ($this->FRSPackage->getId(),
149 htmlspecialchars($notes),
150 htmlspecialchars($changes),
152 htmlspecialchars($name),
157 $this->setError('FRSRelease::create() Error Adding Release: '.db_error());
161 $this->release_id=db_insertid($result,'frs_release','release_id');
162 if (!$this->fetchData($this->release_id)) {
166 $newdirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$this->getFileName();
167 if (!is_dir($newdirlocation)) {
168 @mkdir($newdirlocation);
176 * fetchData - re-fetch the data for this Release from the database.
178 * @param int The release_id.
179 * @return boolean success.
181 function fetchData($release_id) {
182 $res = db_query_params ('SELECT * FROM frs_release WHERE release_id=$1 AND package_id=$2',
184 $this->FRSPackage->getID())) ;
185 if (!$res || db_numrows($res) < 1) {
186 $this->setError('FRSRelease::fetchData() Invalid release_id');
189 $this->data_array = db_fetch_array($res);
190 db_free_result($res);
195 * getFRSPackage - get the FRSPackage object this release is associated with.
197 * @return object The FRSPackage object.
199 function &getFRSPackage() {
200 return $this->FRSPackage;
204 * getID - get this release_id.
206 * @return int The id of this release.
209 return $this->data_array['release_id'];
213 * getName - get the name of this release.
215 * @return string The name of this release.
218 return $this->data_array['name'];
222 * getFileName - get the filename of this release.
224 * @return string The filename of this release.
226 function getFileName() {
227 return util_secure_filename($this->data_array['name']);
231 * getStatus - get the status of this release.
233 * @return int The status.
235 function getStatus() {
236 return $this->data_array['status_id'];
240 * getNotes - get the release notes of this release.
242 * @return string The release notes.
244 function getNotes() {
245 return $this->data_array['notes'];
249 * getChanges - get the changelog of this release.
251 * @return string The changelog.
253 function getChanges() {
254 return $this->data_array['changes'];
258 * getPreformatted - get the preformatted option of this release.
260 * @return boolean preserve_formatting.
262 function getPreformatted() {
263 return $this->data_array['preformatted'];
267 * getReleaseDate - get the releasedate of this release.
269 * @return int The release date in unix time.
271 function getReleaseDate() {
272 return $this->data_array['release_date'];
276 * sendNotice - the logic to send an email/jabber notice for a release.
278 * @return boolean success.
280 function sendNotice() {
281 $arr =& $this->FRSPackage->getMonitorIDs();
283 $date = date('Y-m-d H:i',time());
285 $subject = sprintf (_('[%1$s Release] %2$s'),
286 $this->FRSPackage->Group->getUnixName(),
287 $this->FRSPackage->getName());
288 $text = stripcslashes(sprintf(_('Project %1$s (%2$s) has released a new version of package "%3$s".
299 You can download it by following this link:
303 You receive this email because you requested to be notified when new
304 versions of this package were released. If you don\'t wish to be
305 notified in the future, please login to %7$s and click this link:
315 $this->FRSPackage->Group->getPublicName(),
316 $this->FRSPackage->Group->getUnixName(),
317 $this->FRSPackage->getName(),
320 util_make_url ("/frs/?group_id=". $this->FRSPackage->Group->getID() ."&release_id=". $this->getID()),
321 forge_get_config('forge_name'),
322 util_make_url ("/frs/monitor.php?filemodule_id=".$this->FRSPackage->getID()."&group_id=".$this->FRSPackage->Group->getID()."&stop=1")));
323 // $text = util_line_wrap($text);
325 util_handle_message(array_unique($arr),$subject,$text);
331 * getFiles - gets all the file objects for files in this release.
333 * return array Array of FRSFile Objects.
335 function &getFiles() {
336 if (!is_array($this->release_files) || count($this->release_files) < 1) {
337 $this->release_files=array();
338 $res = db_query_params ('SELECT * FROM frs_file_vw WHERE release_id=$1',
339 array ($this->getID())) ;
340 while ($arr = db_fetch_array($res)) {
341 $this->release_files[]=new FRSFile($this,$arr['file_id'],$arr);
344 return $this->release_files;
348 * delete - delete this release and all its related data.
350 * @param bool I'm Sure.
351 * @param bool I'm REALLY sure.
352 * @return bool true/false;
354 function delete($sure, $really_sure) {
355 if (!$sure || !$really_sure) {
356 $this->setMissingParamsError(_('Please tick all checkboxes.'));
359 if (!forge_check_perm ('frs', $this->FRSPackage->Group->getID(), 'write')) {
360 $this->setPermissionDeniedError();
363 $f =& $this->getFiles();
364 for ($i=0; $i<count($f); $i++) {
365 if (!is_object($f[$i]) || $f[$i]->isError() || !$f[$i]->delete()) {
366 $this->setError('File Error: '.$f[$i]->getName().':'.$f[$i]->getErrorMessage());
370 $dir=forge_get_config('upload_dir').'/'.
371 $this->FRSPackage->Group->getUnixName() . '/' .
372 $this->FRSPackage->getFileName().'/'.
373 $this->getFileName().'/';
375 // double-check we're not trying to remove root dir
376 if (util_is_root_dir($dir)) {
377 $this->setError('Release::delete error: trying to delete root dir');
382 db_query_params ('DELETE FROM frs_release WHERE release_id=$1 AND package_id=$2',
383 array ($this->getID(),
384 $this->FRSPackage->getID())) ;
389 * update - update a new release in the database.
391 * @param int The status of this release from the frs_status table.
392 * @param string The name of the release.
393 * @param string The release notes for the release.
394 * @param string The change log for the release.
395 * @param int Whether the notes/log are preformatted with \n chars (1) true (0) false.
396 * @param int The unix date of the release.
397 * @return boolean success.
399 function update($status, $name, $notes, $changes, $preformatted, $release_date) {
400 if (strlen($name) < 3) {
401 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
405 if (!forge_check_perm('frs', $this->FRSPackage->Group->getID(), 'write')) {
406 $this->setPermissionDeniedError();
416 if($this->getName() != htmlspecialchars($name)) {
417 $res = db_query_params ('SELECT * FROM frs_release WHERE package_id=$1 AND name=$2',
418 array ($this->FRSPackage->getID(),
419 htmlspecialchars($name))) ;
420 if (db_numrows($res)) {
421 $this->setError('FRSRelease::update() Error On Update: Name Already Exists');
426 $res = db_query_params ('UPDATE frs_release SET name=$1,status_id=$2,notes=$3,
427 changes=$4,preformatted=$5,release_date=$6,released_by=$7
428 WHERE package_id=$8 AND release_id=$9',
429 array (htmlspecialchars($name),
431 htmlspecialchars($notes),
432 htmlspecialchars($changes),
436 $this->FRSPackage->getID(),
439 if (!$res || db_affected_rows($res) < 1) {
440 $this->setError('FRSRelease::update() Error On Update: '.db_error());
445 $oldfilename = $this->getFileName();
446 if(!$this->fetchData($this->getID())){
447 $this->setError("FRSRelease::update() Error Updating Release: Couldn't fetch data");
451 $newfilename = $this->getFileName();
452 $olddirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$oldfilename;
453 $newdirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$newfilename;
455 if (($oldfilename!=$newfilename) && is_dir($olddirlocation)) {
456 if (is_dir($newdirlocation)) {
457 $this->setError('FRSRelease::update() Error Updating Release: Directory Already Exists');
461 if(!rename($olddirlocation,$newdirlocation)) {
462 $this->setError("FRSRelease::update() Error Updating Release: Couldn't rename dir");
469 $this->FRSPackage->createNewestReleaseFilesAsZip();
477 // c-file-style: "bsd"