3 * FusionForge file release system
5 * Copyright 2002, Tim Perdue/GForge, LLC
6 * Copyright 2009, Roland Mas
7 * Copyright (C) 2012 Alain Peyrat - Alcatel-Lucent
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/Error.class.php';
26 require_once $gfcommon.'frs/FRSFile.class.php';
29 * Factory method which creates a FRSRelease from an release id
31 * @param int The release id
32 * @param array The result array, if it's passed in
33 * @return object FRSRelease object
35 function frsrelease_get_object($release_id, $data = false) {
36 global $FRSRELEASE_OBJ;
37 if (!isset($FRSRELEASE_OBJ['_'.$release_id.'_'])) {
39 //the db result handle was passed in
41 $res = db_query_params ('SELECT * FROM frs_release WHERE release_id=$1',
42 array ($release_id)) ;
43 if (db_numrows($res)<1 ) {
44 $FRSRELEASE_OBJ['_'.$release_id.'_']=false;
47 $data = db_fetch_array($res);
49 $FRSPackage = frspackage_get_object($data['package_id']);
50 $FRSRELEASE_OBJ['_'.$release_id.'_']= new FRSRelease($FRSPackage,$data['release_id'],$data);
52 return $FRSRELEASE_OBJ['_'.$release_id.'_'];
55 class FRSRelease extends Error {
58 * Associative array of data from db.
60 * @var array $data_array.
67 * @var object FRSPacakge.
75 * @param object The FRSPackage object to which this release is associated.
76 * @param int The release_id.
77 * @param array The associative array of data.
78 * @return boolean success.
80 function FRSRelease(&$FRSPackage, $release_id = false, $arr = false) {
82 if (!$FRSPackage || !is_object($FRSPackage)) {
83 $this->setError('FRSRelease:: No Valid FRSPackage Object');
86 if ($FRSPackage->isError()) {
87 $this->setError('FRSRelease:: '.$FRSPackage->getErrorMessage());
90 $this->FRSPackage =& $FRSPackage;
93 if (!$arr || !is_array($arr)) {
94 if (!$this->fetchData($release_id)) {
98 $this->data_array =& $arr;
99 if ($this->data_array['package_id'] != $this->FRSPackage->getID()) {
100 $this->setError('FRSPackage_id in db result does not match FRSPackage Object');
101 $this->data_array=null;
110 * create - create a new release in the database.
112 * @param string The name of the release.
113 * @param string The release notes for the release.
114 * @param string The change log for the release.
115 * @param int Whether the notes/log are preformatted with \n chars (1) true (0) false.
116 * @param int The unix date of the release.
117 * @return boolean success.
119 function create($name,$notes,$changes,$preformatted,$release_date=false) {
120 if (strlen($name) < 3) {
121 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
131 if (!forge_check_perm ('frs', $this->FRSPackage->Group->getID(), 'write')) {
132 $this->setPermissionDeniedError();
136 if (!$release_date) {
137 $release_date=time();
139 $res = db_query_params ('SELECT * FROM frs_release WHERE package_id=$1 AND name=$2',
140 array ($this->FRSPackage->getID(),
141 htmlspecialchars($name))) ;
142 if (db_numrows($res)) {
143 $this->setError('FRSRelease::create() Error Adding Release: Name Already Exists');
148 $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)',
149 array ($this->FRSPackage->getId(),
150 htmlspecialchars($notes),
151 htmlspecialchars($changes),
153 htmlspecialchars($name),
158 $this->setError('FRSRelease::create() Error Adding Release: '.db_error());
162 $this->release_id=db_insertid($result,'frs_release','release_id');
163 if (!$this->fetchData($this->release_id)) {
167 $newdirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$this->getFileName();
168 if (!is_dir($newdirlocation)) {
169 @mkdir($newdirlocation);
177 * fetchData - re-fetch the data for this Release from the database.
179 * @param int The release_id.
180 * @return boolean success.
182 function fetchData($release_id) {
183 $res = db_query_params ('SELECT * FROM frs_release WHERE release_id=$1 AND package_id=$2',
185 $this->FRSPackage->getID())) ;
186 if (!$res || db_numrows($res) < 1) {
187 $this->setError('FRSRelease::fetchData() Invalid release_id');
190 $this->data_array = db_fetch_array($res);
191 db_free_result($res);
196 * getFRSPackage - get the FRSPackage object this release is associated with.
198 * @return object The FRSPackage object.
200 function &getFRSPackage() {
201 return $this->FRSPackage;
205 * getID - get this release_id.
207 * @return int The id of this release.
210 return $this->data_array['release_id'];
214 * getName - get the name of this release.
216 * @return string The name of this release.
219 return $this->data_array['name'];
223 * getFileName - get the filename of this release.
225 * @return string The filename of this release.
227 function getFileName() {
228 return util_secure_filename($this->data_array['name']);
232 * getStatus - get the status of this release.
234 * @return int The status.
236 function getStatus() {
237 return $this->data_array['status_id'];
241 * getNotes - get the release notes of this release.
243 * @return string The release notes.
245 function getNotes() {
246 return $this->data_array['notes'];
250 * getChanges - get the changelog of this release.
252 * @return string The changelog.
254 function getChanges() {
255 return $this->data_array['changes'];
259 * getPreformatted - get the preformatted option of this release.
261 * @return boolean preserve_formatting.
263 function getPreformatted() {
264 return $this->data_array['preformatted'];
268 * getReleaseDate - get the releasedate of this release.
270 * @return int The release date in unix time.
272 function getReleaseDate() {
273 return $this->data_array['release_date'];
277 * sendNotice - the logic to send an email/jabber notice for a release.
279 * @return boolean success.
281 function sendNotice() {
282 $arr =& $this->FRSPackage->getMonitorIDs();
284 $date = date('Y-m-d H:i',time());
286 $subject = sprintf (_('[%1$s Release] %2$s'),
287 $this->FRSPackage->Group->getUnixName(),
288 $this->FRSPackage->getName());
289 $text = stripcslashes(sprintf(_('Project %1$s (%2$s) has released a new version of package "%3$s".
300 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:
308 $this->FRSPackage->Group->getPublicName(),
309 $this->FRSPackage->Group->getUnixName(),
310 $this->FRSPackage->getName(),
313 util_make_url ("/frs/?group_id=". $this->FRSPackage->Group->getID() ."&release_id=". $this->getID()),
314 forge_get_config('forge_name'),
315 util_make_url ("/frs/monitor.php?filemodule_id=".$this->FRSPackage->getID()."&group_id=".$this->FRSPackage->Group->getID()."&stop=1")));
316 // $text = util_line_wrap($text);
318 util_handle_message(array_unique($arr),$subject,$text);
324 * getFiles - gets all the file objects for files in this release.
326 * return array Array of FRSFile Objects.
328 function &getFiles() {
329 if (!is_array($this->release_files) || count($this->release_files) < 1) {
330 $this->release_files=array();
331 $res = db_query_params ('SELECT * FROM frs_file_vw WHERE release_id=$1',
332 array ($this->getID())) ;
333 while ($arr = db_fetch_array($res)) {
334 $this->release_files[]=new FRSFile($this,$arr['file_id'],$arr);
337 return $this->release_files;
341 * delete - delete this release and all its related data.
343 * @param bool I'm Sure.
344 * @param bool I'm REALLY sure.
345 * @return bool true/false;
347 function delete($sure, $really_sure) {
348 if (!$sure || !$really_sure) {
349 $this->setMissingParamsError(_('Please tick all checkboxes.'));
352 if (!forge_check_perm ('frs', $this->FRSPackage->Group->getID(), 'write')) {
353 $this->setPermissionDeniedError();
356 $f =& $this->getFiles();
357 for ($i=0; $i<count($f); $i++) {
358 if (!is_object($f[$i]) || $f[$i]->isError() || !$f[$i]->delete()) {
359 $this->setError('File Error: '.$f[$i]->getName().':'.$f[$i]->getErrorMessage());
363 $dir=forge_get_config('upload_dir').'/'.
364 $this->FRSPackage->Group->getUnixName() . '/' .
365 $this->FRSPackage->getFileName().'/'.
366 $this->getFileName().'/';
368 // double-check we're not trying to remove root dir
369 if (util_is_root_dir($dir)) {
370 $this->setError('Release::delete error: trying to delete root dir');
375 db_query_params ('DELETE FROM frs_release WHERE release_id=$1 AND package_id=$2',
376 array ($this->getID(),
377 $this->FRSPackage->getID())) ;
382 * update - update a new release in the database.
384 * @param int The status of this release from the frs_status table.
385 * @param string The name of the release.
386 * @param string The release notes for the release.
387 * @param string The change log for the release.
388 * @param int Whether the notes/log are preformatted with \n chars (1) true (0) false.
389 * @param int The unix date of the release.
390 * @return boolean success.
392 function update($status, $name, $notes, $changes, $preformatted, $release_date) {
393 if (strlen($name) < 3) {
394 $this->setError(_('FRSPackage Name Must Be At Least 3 Characters'));
398 if (!forge_check_perm('frs', $this->FRSPackage->Group->getID(), 'write')) {
399 $this->setPermissionDeniedError();
409 if($this->getName() != htmlspecialchars($name)) {
410 $res = db_query_params ('SELECT * FROM frs_release WHERE package_id=$1 AND name=$2',
411 array ($this->FRSPackage->getID(),
412 htmlspecialchars($name))) ;
413 if (db_numrows($res)) {
414 $this->setError('FRSRelease::update() Error On Update: Name Already Exists');
419 $res = db_query_params ('UPDATE frs_release SET name=$1,status_id=$2,notes=$3,
420 changes=$4,preformatted=$5,release_date=$6,released_by=$7
421 WHERE package_id=$8 AND release_id=$9',
422 array (htmlspecialchars($name),
424 htmlspecialchars($notes),
425 htmlspecialchars($changes),
429 $this->FRSPackage->getID(),
432 if (!$res || db_affected_rows($res) < 1) {
433 $this->setError('FRSRelease::update() Error On Update: '.db_error());
438 $oldfilename = $this->getFileName();
439 if(!$this->fetchData($this->getID())){
440 $this->setError("FRSRelease::update() Error Updating Release: Couldn't fetch data");
444 $newfilename = $this->getFileName();
445 $olddirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$oldfilename;
446 $newdirlocation = forge_get_config('upload_dir').'/'.$this->FRSPackage->Group->getUnixName().'/'.$this->FRSPackage->getFileName().'/'.$newfilename;
448 if (($oldfilename!=$newfilename) && is_dir($olddirlocation)) {
449 if (is_dir($newdirlocation)) {
450 $this->setError('FRSRelease::update() Error Updating Release: Directory Already Exists');
454 if(!rename($olddirlocation,$newdirlocation)) {
455 $this->setError("FRSRelease::update() Error Updating Release: Couldn't rename dir");
462 $this->FRSPackage->createNewestReleaseFilesAsZip();
470 // c-file-style: "bsd"