3 * FusionForge project manager
5 * Copyright 1999-2000, Tim Perdue/Sourceforge
6 * Copyright 2002, Tim Perdue/GForge, LLC
7 * Copyright 2009, Roland Mas
8 * Copyright 2014, Franck Villaume - TrivialDev
10 * This file is part of FusionForge. FusionForge is free software;
11 * you can redistribute it and/or modify it under the terms of the
12 * GNU General Public License as published by the Free Software
13 * Foundation; either version 2 of the Licence, or (at your option)
16 * FusionForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 require_once $gfcommon.'include/FFError.class.php';
29 * Fetches a ProjectGroup object from the database
31 * @param array $group_project_id whether or not the db result handle is passed in
33 * @return ProjectGroup|bool the ProjectGroup object
35 function &projectgroup_get_object($group_project_id, $data = false) {
36 global $PROJECTGROUP_OBJ;
37 if (!isset($PROJECTGROUP_OBJ["_".$group_project_id."_"])) {
39 //the db result handle was passed in
41 $res = db_query_params('SELECT * FROM project_group_list_vw WHERE group_project_id=$1',
42 array($group_project_id));
43 if (db_numrows($res) <1 ) {
44 $PROJECTGROUP_OBJ["_".$group_project_id."_"]=false;
47 $data = db_fetch_array($res);
49 $Group = group_get_object($data["group_id"]);
50 $PROJECTGROUP_OBJ["_".$group_project_id."_"]= new ProjectGroup($Group,$group_project_id,$data);
52 return $PROJECTGROUP_OBJ["_".$group_project_id."_"];
55 function projectgroup_get_groupid($group_project_id) {
56 global $PROJECTGROUP_OBJ;
57 if (isset($PROJECTGROUP_OBJ["_".$group_project_id."_"])) {
58 return $PROJECTGROUP_OBJ["_".$group_project_id."_"]->Group->getID() ;
61 $res = db_query_params('SELECT group_id FROM project_group_list WHERE group_project_id=$1',
62 array($group_project_id));
63 if (!$res || db_numrows($res) < 1) {
66 $arr = db_fetch_array($res);
67 return $arr['group_id'];
70 class ProjectGroup extends FFError {
73 * Associative array of data from db.
75 * @var array $data_array.
91 * @param bool $group_project_id
94 function __construct(&$Group, $group_project_id = false, $arr = false) {
95 parent::__construct();
96 if (!$Group || !is_object($Group)) {
97 $this->setError(_('Invalid Project'));
100 if ($Group->isError()) {
101 $this->setError('ProjectGroup: '.$Group->getErrorMessage());
104 $this->Group =& $Group;
106 if ($group_project_id) {
107 if (!$arr || !is_array($arr)) {
108 if (!$this->fetchData($group_project_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');
119 // Make sure they can even access this object
121 if (!forge_check_perm ('pm', $this->getID(), 'read')) {
122 $this->setPermissionDeniedError();
123 $this->data_array = null;
130 * create - create a new ProjectGroup in the database.
132 * @param string $project_name The project name.
133 * @param string $description The project description.
134 * @param string $send_all_posts_to The email address to send new notifications to.
135 * @return bool success.
137 function create($project_name,$description,$send_all_posts_to='') {
138 if (strlen($project_name) < 3) {
139 $this->setError(sprintf(_('Title Must Be At Least %d Characters'), 3));
142 if (strlen($description) < 10) {
143 $this->setError(_('Subproject Description Must Be At Least 10 Characters'));
146 if ($send_all_posts_to) {
147 $invalid_mails = validate_emails($send_all_posts_to);
148 if (count($invalid_mails) > 0) {
149 $this->setInvalidEmailError($send_all_posts_to);
154 if (!forge_check_perm ('pm_admin', $this->Group->getID())) {
155 $this->setPermissionDeniedError();
160 $result = db_query_params('INSERT INTO project_group_list (group_id,project_name,description,send_all_posts_to) VALUES ($1,$2,$3,$4)',
161 array($this->Group->getID(),
162 htmlspecialchars($project_name),
163 htmlspecialchars($description),
164 $send_all_posts_to));
166 $this->setError('Error Adding ProjectGroup: '.db_error());
170 $this->group_project_id=db_insertid($result,'project_group_list','group_project_id');
171 $this->fetchData($this->group_project_id);
172 $this->Group->normalizeAllRoles () ;
180 * fetchData - re-fetch the data for this ProjectGroup from the database.
182 * @param int $group_project_id The project group ID.
183 * @return bool success.
185 function fetchData($group_project_id) {
186 $res = db_query_params ('SELECT * FROM project_group_list_vw WHERE group_project_id=$1 AND group_id=$2',
187 array ($group_project_id,
188 $this->Group->getID())) ;
189 if (!$res || db_numrows($res) < 1) {
190 $this->setError(_('Invalid group_project_id'));
193 $this->data_array = db_fetch_array($res);
194 db_free_result($res);
199 * getGroup - get the Group object this ProjectGroup is associated with.
201 * @return Group The Group object.
203 function &getGroup() {
208 * getID - get this GroupProjectID.
210 * @return int The group_project_id #.
213 return $this->data_array['group_project_id'];
217 * getOpenCount - get the count of open tracker items in this tracker type.
219 * @return int The count.
221 function getOpenCount() {
222 return $this->data_array['open_count'];
226 * getTotalCount - get the total number of tracker items in this tracker type.
228 * @return int The total count.
230 function getTotalCount() {
231 return $this->data_array['count'];
235 * getCount - get the number of tasks item in this pm type per status and category
237 * @param int $status_id the status id
238 * @param int $category_id the category id
239 * @return int the count
241 function getCount($status_id, $category_id) {
242 $qpa = db_construct_qpa();
243 $qpa = db_construct_qpa($qpa, 'SELECT count(project_task_id) FROM project_task WHERE group_project_id = $1', array($this->getID()));
245 $qpa = db_construct_qpa($qpa, ' AND category_id = $1 ', array($category_id));
247 if (is_int($status_id) && $status_id != 100) {
248 $qpa = db_construct_qpa($qpa, ' AND status_id = $1 ', array($status_id));
250 $res = db_query_qpa($qpa);
251 $arr = db_fetch_array($res);
256 * getName - get the name of this projectGroup.
258 * @return string The name of this projectGroup.
261 return $this->data_array['project_name'];
265 * getSendAllPostsTo - an optional email address to send all task updates to.
267 * @return string The email address.
269 function getSendAllPostsTo() {
270 return $this->data_array['send_all_posts_to'];
274 * getDescription - the description of this ProjectGroup.
276 * @return string The description.
278 function getDescription() {
279 return $this->data_array['description'];
283 * getStatuses - Return result set of statuses.
285 * @return object Database result set.
287 function getStatuses() {
288 if (!$this->statuses) {
289 $this->statuses = db_query_params('SELECT * FROM project_status',
292 return $this->statuses;
296 * getCategories - Return result set of categories.
298 * @return object Database result set.
300 function getCategories() {
301 if (!$this->categories) {
302 $this->categories = db_query_params('SELECT category_id,category_name FROM project_category WHERE group_project_id=$1',
303 array($this->getID()));
305 return $this->categories;
309 * getCategoryObjects - Array of ProjectCategory objects set up for this artifact type.
311 * @return array Of ProjectCategory objects.
313 function &getCategoryObjects() {
314 $res = $this->getCategories();
316 while ($arr = db_fetch_array($res)) {
317 $cats[] = new ProjectCategory($this,$arr);
323 * update - update a ProjectGroup in the database.
325 * @param string $project_name The project name.
326 * @param string $description The project description.
327 * @param string $send_all_posts_to The email address to send new notifications to.
328 * @return boolean success.
330 function update($project_name, $description, $send_all_posts_to = '') {
331 if (strlen($project_name) < 3) {
332 $this->setError(sprintf(_('Title Must Be At Least %d Characters'), 3));
335 if (strlen($description) < 10) {
336 $this->setError(_('Subproject Description Must Be At Least 10 Characters'));
340 if ($send_all_posts_to) {
341 $invalid_mails = validate_emails($send_all_posts_to);
342 if (count($invalid_mails) > 0) {
343 $this->setInvalidEmailError($send_all_posts_to);
348 if (!forge_check_perm ('pm', $this->getID(), 'manager')) {
349 $this->setPermissionDeniedError();
353 $res = db_query_params('UPDATE project_group_list SET project_name=$1,
354 description=$2, send_all_posts_to=$3
355 WHERE group_id=$4 AND group_project_id=$5',
356 array(htmlspecialchars($project_name),
357 htmlspecialchars($description),
359 $this->Group->getID(),
362 if (!$res || db_affected_rows($res) < 1) {
363 $this->setError(_('Error On Update')._(': ').db_error());
370 * delete - delete this subproject and all its related data.
372 * @param bool $sure I'm Sure.
373 * @param bool $really_sure I'm REALLY sure.
374 * @return bool true/false;
376 function delete($sure, $really_sure) {
377 if (!$sure || !$really_sure) {
378 $this->setMissingParamsError(_('Please tick all checkboxes.'));
381 if (!forge_check_perm('pm', $this->getID(), 'manager')) {
382 $this->setPermissionDeniedError();
388 $res = db_query_params('DELETE FROM project_assigned_to
389 WHERE EXISTS (SELECT project_task_id FROM project_task
390 WHERE group_project_id=$1
391 AND project_task.project_task_id=project_assigned_to.project_task_id)',
392 array($this->getID()));
395 $this->setError('DATABASE '.db_error());
399 $res = db_query_params('DELETE FROM project_dependencies
400 WHERE EXISTS (SELECT project_task_id FROM project_task
401 WHERE group_project_id=$1
402 AND project_task.project_task_id=project_dependencies.project_task_id)',
403 array($this->getID()));
406 $this->setError('DATABASE '.db_error());
410 $res = db_query_params('DELETE FROM project_history
411 WHERE EXISTS (SELECT project_task_id FROM project_task
412 WHERE group_project_id=$1
413 AND project_task.project_task_id=project_history.project_task_id)',
414 array($this->getID()));
417 $this->setError('DATABASE '.db_error());
421 $res = db_query_params('DELETE FROM project_messages
422 WHERE EXISTS (SELECT project_task_id FROM project_task
423 WHERE group_project_id=$1
424 AND project_task.project_task_id=project_messages.project_task_id)',
425 array($this->getID()));
428 $this->setError('DATABASE '.db_error());
432 $res = db_query_params('DELETE FROM project_task_artifact
433 WHERE EXISTS (SELECT project_task_id FROM project_task
434 WHERE group_project_id=$1
435 AND project_task.project_task_id=project_task_artifact.project_task_id)',
436 array($this->getID()));
439 $this->setError('DATABASE '.db_error());
443 $res = db_query_params('DELETE FROM rep_time_tracking
444 WHERE EXISTS (SELECT project_task_id FROM project_task
445 WHERE group_project_id=$1
446 AND project_task.project_task_id=rep_time_tracking.project_task_id)',
447 array($this->getID()));
450 $this->setError('DATABASE '.db_error());
454 $res = db_query_params ('DELETE FROM project_task
455 WHERE group_project_id=$1',
456 array ($this->getID()));
459 $this->setError('DATABASE '.db_error());
463 $res = db_query_params ('DELETE FROM project_category WHERE group_project_id=$1',
464 array ($this->getID()));
467 $this->setError('DATABASE '.db_error());
471 $res = db_query_params ('DELETE FROM project_group_list WHERE group_project_id=$1',
472 array ($this->getID()));
475 $this->setError('DATABASE '.db_error());
479 $res = db_query_params ('DELETE FROM project_counts_agg WHERE group_project_id=$1',
480 array ($this->getID()));
483 $this->setError('DATABASE '.db_error());
489 $this->Group->normalizeAllRoles();
496 // c-file-style: "bsd"