5 * Copyright 2002, GForge, LLC
6 * Copyright (C) 2011 Alain Peyrat - Alcatel-Lucent
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.'tracker/Artifact.class.php';
26 require_once $gfcommon.'tracker/ArtifactType.class.php';
27 require_once $gfcommon.'tracker/ArtifactQuery.class.php';
29 class ArtifactFactory extends Error {
32 * The ArtifactType object.
34 * @var object $ArtifactType.
39 * The artifacts array.
41 * @var array artifacts.
43 var $artifacts = array();
63 var $query_type; // query, default, custom
64 var $query_id; // id of the query (when query_type=query)
69 * @param object $ArtifactType The ArtifactType object to which this ArtifactFactory is associated.
71 function __construct(&$ArtifactType) {
73 if (!$ArtifactType || !is_object($ArtifactType)) {
74 $this->setError('ArtifactFactory:: No Valid ArtifactType Object');
77 if ($ArtifactType->isError()) {
78 $this->setError('ArtifactFactory:: '.$ArtifactType->getErrorMessage());
81 $this->ArtifactType =& $ArtifactType;
82 $this->changed_from = 0x7ffffff; // Any
86 * setup - sets up limits and sorts before you call getTasks().
88 * @param int $offset The offset - number of rows to skip.
89 * @param string $order_col The column to sort on.
90 * @param string $sort The way to order - ASC or DESC.
91 * @param int $max_rows The max number of rows to return.
92 * @param string $set Whether to set these prefs into the user_prefs table - use "custom".
93 * @param int $_assigned_to Include this param if you want to limit to a certain assignee.
94 * @param int $_status Include this param if you want to limit to a particular status.
95 * @param array Array of extra fields & elements to limit the query to.
97 function setup($offset,$order_col,$sort,$max_rows,$set,$_assigned_to,$_status,$_extra_fields=array()) {
99 if ((!$offset) || ($offset < 0)) {
102 $this->offset=$offset;
105 // $max_rows == 0 means we want all the rows
106 if (is_null($max_rows) || $max_rows < 0) {
107 $this->max_rows = 50 ;
109 $this->max_rows = $max_rows ;
112 if (session_loggedin()) {
113 $u =& session_get_user();
115 if (!is_array($_extra_fields)) {
116 $_extra_fields=array();
122 if no set is passed in, see if a preference was set
123 if no preference or not logged in, use open set
125 $this->query_type = '';
126 if (session_loggedin()) {
127 $query_id=$u->getPreference('art_query'.$this->ArtifactType->getID());
129 $this->query_type = 'query';
130 $this->query_id = $query_id;
132 $custom_pref=$u->getPreference('art_cust'.$this->ArtifactType->getID());
134 //$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.'|'.serialize($_extra_fields);
135 $this->query_type = 'custom';
136 $pref_arr=explode('|',$custom_pref);
137 $_assigned_to=$pref_arr[0];
138 $_status=$pref_arr[1];
139 $order_col=$pref_arr[2];
141 $_changed=$pref_arr[4];
142 if ($this->ArtifactType->usesCustomStatuses()) {
143 $_extra_fields=unserialize($pref_arr[5]);
145 $_status=$pref_arr[1];
150 } elseif (isset($_COOKIE["GFTrackerQuery"])) {
151 $gf_tracker = unserialize($_COOKIE["GFTrackerQuery"]);
152 $query_id = (int)$gf_tracker[$this->ArtifactType->getID()];
154 $this->query_type = 'query';
155 $this->query_id = $query_id;
159 if (!$this->query_type) {
160 $res = db_query_params ('SELECT artifact_query_id FROM artifact_query
161 WHERE group_artifact_id=$1
163 array($this->ArtifactType->getID()));
164 if (db_numrows($res)>0) {
165 $this->query_type = 'query';
166 $this->query_id = db_result($res, 0, 'artifact_query_id');
170 if (!$this->query_type) {
171 //default to all opened
172 $this->query_type = 'default';
178 if ($this->query_type == 'query') {
179 $aq = new ArtifactQuery($this->ArtifactType, $this->query_id);
180 $this->submitted_by=$aq->getSubmitter();
181 $_assigned_to=$aq->getAssignee();
182 $_status=$aq->getStatus();
183 $_extra_fields=$aq->getExtraFields();
184 $this->moddaterange = $aq->getModDateRange();
185 $this->opendaterange = $aq->getOpenDateRange();
186 $this->closedaterange = $aq->getCloseDateRange();
187 $this->summary = $aq->getSummary();
188 $this->description = $aq->getDescription();
189 $this->followups = $aq->getFollowups();
190 $order_col=$aq->getSortCol();
191 $sort=$aq->getSortOrd();
196 // validate the column names and sort order passed in from user
197 // before saving it to prefs
199 $allowed_order_col = array ('artifact_id',
206 'last_modified_date') ;
207 $efarr = $this->ArtifactType->getExtraFields();
208 $keys=array_keys($efarr);
209 for ($k=0; $k<count($keys); $k++) {
211 $allowed_order_col[] = $efarr[$i]['extra_field_id'];
214 $_order_col = util_ensure_value_in_set ($order_col,
216 $_sort_ord = util_ensure_value_in_set ($sort,
217 array ('ASC', 'DESC')) ;
218 if ($set=='custom') {
219 $this->query_type = 'custom';
220 if (session_loggedin()) {
222 if this custom set is different than the stored one, reset preference
224 if (is_array($_assigned_to)) {
227 $aux_extra_fields = array();
228 if (is_array($_extra_fields)){
229 //print_r($_extra_fields);
230 $keys=array_keys($_extra_fields);
232 foreach ($keys as $key) {
233 if ($_extra_fields[$key] != 'Array') {
234 $aux_extra_fields[$key] = $_extra_fields[$key];
240 if (count($aux_extra_fields)>0) {
241 $extra_pref = '|'.serialize($aux_extra_fields);
244 $pref_=$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.$extra_pref;
245 if ($pref_ != $u->getPreference('art_cust'.$this->ArtifactType->getID())) {
246 $u->setPreference('art_cust'.$this->ArtifactType->getID(),$pref_);
248 $default_query=$u->getPreference('art_query'.$this->ArtifactType->getID());
249 if ($default_query) {
250 $u->deletePreference('art_query'.$this->ArtifactType->getID());
256 $this->sort=$_sort_ord;
257 $this->order_col=$_order_col;
258 $this->status=$_status;
259 $this->assigned_to=$_assigned_to;
260 $this->extra_fields=$_extra_fields;
261 $this->setChangedFrom($_changed);
266 * setChangedFrom - sets up changed-from and last-changed before you call getTasks().
268 * @param int $changed_from The changed_from - offset time(sec) from now
270 function setChangedFrom($changed_from) {
271 $this->changed_from = ($changed_from <= 0) ? 0x7fffffff : $changed_from;
272 $this->last_changed = time() - $this->changed_from;
276 * getDefaultQuery - get the default query
280 function getDefaultQuery() {
281 if ($this->query_type == 'query')
282 return $this->query_id;
288 * getArtifacts - get an array of Artifact objects.
290 * @return Artifact[] Array of Artifact objects.
292 function getArtifacts() {
293 if (!empty($this->artifacts)) {
294 return $this->artifacts;
300 $selectsql = 'SELECT DISTINCT ON (group_artifact_id, artifact_id) artifact_vw.* FROM artifact_vw';
302 $wheresql = ' WHERE group_artifact_id=$'.$paramcount++ ;
303 $params[] = $this->ArtifactType->getID() ;
305 if (is_array($this->extra_fields) && !empty($this->extra_fields)) {
306 $keys=array_keys($this->extra_fields);
307 $vals=array_values($this->extra_fields);
308 for ($i=0; $i<count($keys); $i++) {
309 if (empty($vals[$i])) {
312 $selectsql .= ', artifact_extra_field_data aefd'.$i;
313 $wheresql .= ' AND aefd'.$i.'.extra_field_id=$'.$paramcount++ ;
314 $params[] = $keys[$i] ;
316 // Hack: Determine the type of the element to get the right search query.
317 $res = db_query_params ('SELECT field_type FROM artifact_extra_field_list WHERE extra_field_id=$1',
319 $type = db_result($res,0,'field_type');
320 if ($type == 4 or $type == 6) {
321 $wheresql .= ' AND aefd'.$i.'.field_data LIKE $'.$paramcount++ ;
322 $params[] = $vals[$i];
324 if (is_array($vals[$i])) {
325 $wheresql .= ' AND aefd'.$i.'.field_data = ANY ($'.$paramcount++ .')' ;
326 $params[] = db_string_array_to_any_clause ($vals[$i]) ;
328 $wheresql .= ' AND aefd'.$i.'.field_data = $'.$paramcount++ ;
329 $params[] = $vals[$i];
332 $wheresql .= ' AND aefd'.$i.'.artifact_id=artifact_vw.artifact_id' ;
336 //if status selected, and more to where clause
337 if ($this->status && ($this->status != 100)) {
338 //for open tasks, add status=100 to make sure we show all
339 $wheresql .= ' AND status_id=$'.$paramcount++ ;
340 $params[] = $this->status;
343 // Add filter if submitted_by is selected.
344 if ($this->submitted_by) {
345 if (is_array($this->submitted_by)) {
346 $wheresql .= ' AND submitted_by = ANY ($'.$paramcount++ ;
347 $params[] = db_int_array_to_any_clause ($this->submitted_by) ;
350 $wheresql .= ' AND submitted_by = $'.$paramcount++ ;
351 $params[] = $this->submitted_by ;
355 //if assigned to selected, and more to where clause
356 if ($this->assigned_to) {
357 if (is_array($this->assigned_to)) {
358 $wheresql .= ' AND assigned_to = ANY ($'.$paramcount++ ;
359 $params[] = db_int_array_to_any_clause ($this->assigned_to) ;
362 $wheresql .= ' AND assigned_to = $'.$paramcount++ ;
363 $params[] = $this->assigned_to ;
367 if ($this->last_changed > 0) {
368 $wheresql .= ' AND last_modified_date > $'.$paramcount++ ;
369 $params[] = $this->last_changed ;
372 //add constraint of range of modified dates
373 if ($this->moddaterange) {
374 $range_arr=explode(' ',$this->moddaterange);
375 $begin_int = strtotime($range_arr[0]);
376 $end_int=strtotime($range_arr[1])+(24*60*60);
377 $wheresql .= ' AND (last_modified_date BETWEEN $'.$paramcount++ ;
378 $params[] = $begin_int ;
379 $wheresql .= ' AND $'.$paramcount++ ;
380 $params[] = $end_int ;
383 //add constraint of range of open dates
384 if ($this->opendaterange) {
385 $range_arr=explode(' ',$this->opendaterange);
386 $begin_int = strtotime($range_arr[0]);
387 $end_int=strtotime($range_arr[1])+(24*60*60);
388 $wheresql .= ' AND (open_date BETWEEN $'.$paramcount++ ;
389 $params[] = $begin_int ;
390 $wheresql .= ' AND $'.$paramcount++ ;
391 $params[] = $end_int ;
394 //add constraint of range of close dates
395 if ($this->closedaterange) {
396 $range_arr=explode(' ',$this->closedaterange);
397 $begin_int = strtotime($range_arr[0]);
398 $end_int=strtotime($range_arr[1])+(24*60*60);
399 $wheresql .= ' AND (close_date BETWEEN $'.$paramcount++ ;
400 $params[] = $begin_int ;
401 $wheresql .= ' AND $'.$paramcount++ ;
402 $params[] = $end_int ;
406 //add constraint on the summary string.
407 if ($this->summary) {
408 $wheresql .= ' AND summary LIKE $'.$paramcount++ ;
409 $params[] = $this->summary;
411 //add constraint on the description string.
412 if ($this->description) {
413 $wheresql .= ' AND details LIKE $'.$paramcount++ ;
414 $params[] = $this->description;
416 //add constraint on the followups string.
417 if ($this->followups) {
418 $selectsql .= ' LEFT OUTER JOIN artifact_message am USING (artifact_id)';
419 $wheresql .= ' AND am.body LIKE $'.$paramcount++;
420 $params[] = $this->followups;
423 $sortorder = util_ensure_value_in_set ($this->sort,
424 array ('ASC', 'DESC')) ;
426 $sortcol = util_ensure_value_in_set ($this->order_col,
436 if ($sortcol != 'extra') {
437 $ordersql = " ORDER BY Artifacts.group_artifact_id $sortorder, Artifacts.$sortcol $sortorder" ;
442 $result = db_query_params ('SELECT * FROM (' . $selectsql . $wheresql . ') AS Artifacts' . $ordersql,
444 $rows = db_numrows($result);
445 $this->fetched_rows=$rows;
447 $this->setError('Database Error: '.db_error());
450 while ($arr = db_fetch_array($result)) {
451 $this->artifacts[] = new Artifact($this->ArtifactType, $arr);
454 if ($sortcol == 'extra') {
455 sortArtifactList ($this->artifacts, $this->order_col, $this->sort) ;
457 return $this->artifacts;
461 * getArtifactsByReleases - get an array of Artifact objects.
463 * @param $extra_field_id
465 * @return array The array of Artifact objects.
467 function getArtifactsByReleases($extra_field_id, $releases) {
468 $artifacts = array();
471 FROM artifact_extra_field_data aefd, artifact_extra_field_elements aefe, artifact_vw a
472 WHERE aefd.extra_field_id=aefe.extra_field_id
473 AND CAST (aefd.field_data AS integer)=aefe.element_id
474 AND aefd.artifact_id=a.artifact_id
475 AND aefd.extra_field_id=$1';
477 $query_params = array($extra_field_id);
480 $query_params[] = db_string_array_to_any_clause($releases);
481 $sql .= ' AND aefe.element_name = ANY ($2)';
484 $sql .= ' ORDER BY a.artifact_id';
486 $result = db_query_params($sql, $query_params);
487 if ($result && db_numrows($result)) {
488 while ($arr = db_fetch_array($result)) {
489 $artifacts[] = new Artifact($this->ArtifactType, $arr);
500 // c-file-style: "bsd"