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 The ArtifactType object to which this ArtifactFactory is associated.
70 * @return boolean success.
72 function __construct(&$ArtifactType) {
74 if (!$ArtifactType || !is_object($ArtifactType)) {
75 $this->setError('ArtifactFactory:: No Valid ArtifactType Object');
78 if ($ArtifactType->isError()) {
79 $this->setError('ArtifactFactory:: '.$ArtifactType->getErrorMessage());
82 $this->ArtifactType =& $ArtifactType;
83 $this->changed_from = 0x7ffffff; // Any
89 * setup - sets up limits and sorts before you call getTasks().
91 * @param int The offset - number of rows to skip.
92 * @param string The column to sort on.
93 * @param string The way to order - ASC or DESC.
94 * @param int The max number of rows to return.
95 * @param string Whether to set these prefs into the user_prefs table - use "custom".
96 * @param int Include this param if you want to limit to a certain assignee.
97 * @param int Include this param if you want to limit to a particular status.
98 * @param array Array of extra fields & elements to limit the query to.
100 function setup($offset,$order_col,$sort,$max_rows,$set,$_assigned_to,$_status,$_extra_fields=array()) {
102 if ((!$offset) || ($offset < 0)) {
105 $this->offset=$offset;
108 // $max_rows == 0 means we want all the rows
109 if (is_null($max_rows) || $max_rows < 0) {
110 $this->max_rows = 50 ;
112 $this->max_rows = $max_rows ;
115 if (session_loggedin()) {
116 $u =& session_get_user();
118 if (!is_array($_extra_fields)) {
119 $_extra_fields=array();
125 if no set is passed in, see if a preference was set
126 if no preference or not logged in, use open set
128 $this->query_type = '';
129 if (session_loggedin()) {
130 $query_id=$u->getPreference('art_query'.$this->ArtifactType->getID());
132 $this->query_type = 'query';
133 $this->query_id = $query_id;
135 $custom_pref=$u->getPreference('art_cust'.$this->ArtifactType->getID());
137 //$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.'|'.serialize($_extra_fields);
138 $this->query_type = 'custom';
139 $pref_arr=explode('|',$custom_pref);
140 $_assigned_to=$pref_arr[0];
141 $_status=$pref_arr[1];
142 $order_col=$pref_arr[2];
144 $_changed=$pref_arr[4];
145 if ($this->ArtifactType->usesCustomStatuses()) {
146 $_extra_fields=unserialize($pref_arr[5]);
148 $_status=$pref_arr[1];
153 } elseif (isset($_COOKIE["GFTrackerQuery"])) {
154 $gf_tracker = unserialize($_COOKIE["GFTrackerQuery"]);
155 $query_id = (int)$gf_tracker[$this->ArtifactType->getID()];
157 $this->query_type = 'query';
158 $this->query_id = $query_id;
162 if (!$this->query_type) {
163 $res = db_query_params ('SELECT artifact_query_id FROM artifact_query
164 WHERE group_artifact_id=$1
166 array($this->ArtifactType->getID()));
167 if (db_numrows($res)>0) {
168 $this->query_type = 'query';
169 $this->query_id = db_result($res, 0, 'artifact_query_id');
173 if (!$this->query_type) {
174 //default to all opened
175 $this->query_type = 'default';
181 if ($this->query_type == 'query') {
182 $aq = new ArtifactQuery($this->ArtifactType, $this->query_id);
183 $this->submitted_by=$aq->getSubmitter();
184 $_assigned_to=$aq->getAssignee();
185 $_status=$aq->getStatus();
186 $_extra_fields=$aq->getExtraFields();
187 $this->moddaterange = $aq->getModDateRange();
188 $this->opendaterange = $aq->getOpenDateRange();
189 $this->closedaterange = $aq->getCloseDateRange();
190 $this->summary = $aq->getSummary();
191 $this->description = $aq->getDescription();
192 $this->followups = $aq->getFollowups();
193 $order_col=$aq->getSortCol();
194 $sort=$aq->getSortOrd();
199 // validate the column names and sort order passed in from user
200 // before saving it to prefs
202 $allowed_order_col = array ('artifact_id',
209 'last_modified_date') ;
210 $efarr = $this->ArtifactType->getExtraFields(array(ARTIFACT_EXTRAFIELDTYPE_TEXT,
211 ARTIFACT_EXTRAFIELDTYPE_TEXTAREA,
212 ARTIFACT_EXTRAFIELDTYPE_INTEGER,
213 ARTIFACT_EXTRAFIELDTYPE_SELECT,
214 ARTIFACT_EXTRAFIELDTYPE_RADIO,
215 ARTIFACT_EXTRAFIELDTYPE_STATUS));
216 $keys=array_keys($efarr);
217 for ($k=0; $k<count($keys); $k++) {
219 $allowed_order_col[] = $efarr[$i]['extra_field_id'];
222 $_order_col = util_ensure_value_in_set ($order_col,
224 $_sort_ord = util_ensure_value_in_set ($sort,
225 array ('ASC', 'DESC')) ;
226 if ($set=='custom') {
227 $this->query_type = 'custom';
228 if (session_loggedin()) {
230 if this custom set is different than the stored one, reset preference
232 if (is_array($_assigned_to)) {
235 $aux_extra_fields = array();
236 if (is_array($_extra_fields)){
237 //print_r($_extra_fields);
238 $keys=array_keys($_extra_fields);
240 foreach ($keys as $key) {
241 if ($_extra_fields[$key] != 'Array') {
242 $aux_extra_fields[$key] = $_extra_fields[$key];
248 if (count($aux_extra_fields)>0) {
249 $extra_pref = '|'.serialize($aux_extra_fields);
252 $pref_=$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.$extra_pref;
253 if ($pref_ != $u->getPreference('art_cust'.$this->ArtifactType->getID())) {
254 $u->setPreference('art_cust'.$this->ArtifactType->getID(),$pref_);
256 $default_query=$u->getPreference('art_query'.$this->ArtifactType->getID());
257 if ($default_query) {
258 $u->deletePreference('art_query'.$this->ArtifactType->getID());
264 $this->sort=$_sort_ord;
265 $this->order_col=$_order_col;
266 $this->status=$_status;
267 $this->assigned_to=$_assigned_to;
268 $this->extra_fields=$_extra_fields;
269 $this->setChangedFrom($_changed);
274 * setChangedFrom - sets up changed-from and last-changed before you call getTasks().
276 * @param int The changed_from - offset time(sec) from now
278 function setChangedFrom($changed_from) {
279 $this->changed_from = ($changed_from <= 0) ? 0x7fffffff : $changed_from;
280 $this->last_changed = time() - $this->changed_from;
284 * getDefaultQuery - get the default query
288 function getDefaultQuery() {
289 if ($this->query_type == 'query')
290 return $this->query_id;
296 * getArtifacts - get an array of Artifact objects.
298 * @return array The array of Artifact objects.
300 function getArtifacts() {
301 if (!empty($this->artifacts)) {
302 return $this->artifacts;
308 $selectsql = 'SELECT DISTINCT ON (group_artifact_id, artifact_id) artifact_vw.* FROM artifact_vw';
310 $wheresql = ' WHERE group_artifact_id=$'.$paramcount++ ;
311 $params[] = $this->ArtifactType->getID() ;
313 if (is_array($this->extra_fields) && !empty($this->extra_fields)) {
314 $keys=array_keys($this->extra_fields);
315 $vals=array_values($this->extra_fields);
316 for ($i=0; $i<count($keys); $i++) {
317 if (empty($vals[$i])) {
320 $selectsql .= ', artifact_extra_field_data aefd'.$i;
321 $wheresql .= ' AND aefd'.$i.'.extra_field_id=$'.$paramcount++ ;
322 $params[] = $keys[$i] ;
324 // Hack: Determine the type of the element to get the right search query.
325 $res = db_query_params ('SELECT field_type FROM artifact_extra_field_list WHERE extra_field_id=$1',
327 $type = db_result($res,0,'field_type');
328 if ($type == 4 or $type == 6) {
329 $wheresql .= ' AND aefd'.$i.'.field_data LIKE $'.$paramcount++ ;
330 $params[] = $vals[$i];
332 if (is_array($vals[$i])) {
333 $wheresql .= ' AND aefd'.$i.'.field_data = ANY ($'.$paramcount++ .')' ;
334 $params[] = db_string_array_to_any_clause ($vals[$i]) ;
336 $wheresql .= ' AND aefd'.$i.'.field_data = $'.$paramcount++ ;
337 $params[] = $vals[$i];
340 $wheresql .= ' AND aefd'.$i.'.artifact_id=artifact_vw.artifact_id' ;
344 //if status selected, and more to where clause
345 if ($this->status && ($this->status != 100)) {
346 //for open tasks, add status=100 to make sure we show all
347 $wheresql .= ' AND status_id=$'.$paramcount++ ;
348 $params[] = $this->status;
351 // Add filter if submitted_by is selected.
352 if ($this->submitted_by) {
353 if (is_array($this->submitted_by)) {
354 $wheresql .= ' AND submitted_by = ANY ($'.$paramcount++ ;
355 $params[] = db_int_array_to_any_clause ($this->submitted_by) ;
358 $wheresql .= ' AND submitted_by = $'.$paramcount++ ;
359 $params[] = $this->submitted_by ;
363 //if assigned to selected, and more to where clause
364 if ($this->assigned_to) {
365 if (is_array($this->assigned_to)) {
366 $wheresql .= ' AND assigned_to = ANY ($'.$paramcount++ ;
367 $params[] = db_int_array_to_any_clause ($this->assigned_to) ;
370 $wheresql .= ' AND assigned_to = $'.$paramcount++ ;
371 $params[] = $this->assigned_to ;
375 if ($this->last_changed > 0) {
376 $wheresql .= ' AND last_modified_date > $'.$paramcount++ ;
377 $params[] = $this->last_changed ;
380 //add constraint of range of modified dates
381 if ($this->moddaterange) {
382 $range_arr=explode(' ',$this->moddaterange);
383 $begin_int = strtotime($range_arr[0]);
384 $end_int=strtotime($range_arr[1])+(24*60*60);
385 $wheresql .= ' AND (last_modified_date BETWEEN $'.$paramcount++ ;
386 $params[] = $begin_int ;
387 $wheresql .= ' AND $'.$paramcount++ ;
388 $params[] = $end_int ;
391 //add constraint of range of open dates
392 if ($this->opendaterange) {
393 $range_arr=explode(' ',$this->opendaterange);
394 $begin_int = strtotime($range_arr[0]);
395 $end_int=strtotime($range_arr[1])+(24*60*60);
396 $wheresql .= ' AND (open_date BETWEEN $'.$paramcount++ ;
397 $params[] = $begin_int ;
398 $wheresql .= ' AND $'.$paramcount++ ;
399 $params[] = $end_int ;
402 //add constraint of range of close dates
403 if ($this->closedaterange) {
404 $range_arr=explode(' ',$this->closedaterange);
405 $begin_int = strtotime($range_arr[0]);
406 $end_int=strtotime($range_arr[1])+(24*60*60);
407 $wheresql .= ' AND (close_date BETWEEN $'.$paramcount++ ;
408 $params[] = $begin_int ;
409 $wheresql .= ' AND $'.$paramcount++ ;
410 $params[] = $end_int ;
414 //add constraint on the summary string.
415 if ($this->summary) {
416 $wheresql .= ' AND summary LIKE $'.$paramcount++ ;
417 $params[] = $this->summary;
419 //add constraint on the description string.
420 if ($this->description) {
421 $wheresql .= ' AND details LIKE $'.$paramcount++ ;
422 $params[] = $this->description;
424 //add constraint on the followups string.
425 if ($this->followups) {
426 $selectsql .= ' LEFT OUTER JOIN artifact_message am USING (artifact_id)';
427 $wheresql .= ' AND am.body LIKE $'.$paramcount++;
428 $params[] = $this->followups;
431 $sortorder = util_ensure_value_in_set ($this->sort,
432 array ('ASC', 'DESC')) ;
434 $sortcol = util_ensure_value_in_set ($this->order_col,
444 if ($sortcol != 'extra') {
445 $ordersql = " ORDER BY Artifacts.group_artifact_id $sortorder, Artifacts.$sortcol $sortorder" ;
450 $result = db_query_params ('SELECT * FROM (' . $selectsql . $wheresql . ') AS Artifacts' . $ordersql,
452 $rows = db_numrows($result);
453 $this->fetched_rows=$rows;
455 $this->setError('Database Error: '.db_error());
458 while ($arr = db_fetch_array($result)) {
459 $this->artifacts[] = new Artifact($this->ArtifactType, $arr);
462 if ($sortcol == 'extra') {
463 sortArtifactList ($this->artifacts, $this->order_col, $this->sort) ;
465 return $this->artifacts;
469 * getArtifactsByReleases - get an array of Artifact objects.
471 * @return array The array of Artifact objects.
473 function getArtifactsByReleases($extra_field_id, $releases) {
474 $artifacts = array();
477 FROM artifact_extra_field_data aefd, artifact_extra_field_elements aefe, artifact_vw a
478 WHERE aefd.extra_field_id=aefe.extra_field_id
479 AND CAST (aefd.field_data AS integer)=aefe.element_id
480 AND aefd.artifact_id=a.artifact_id
481 AND aefd.extra_field_id=$1';
483 $query_params = array($extra_field_id);
486 $query_params[] = db_string_array_to_any_clause($releases);
487 $sql .= ' AND aefe.element_name = ANY ($2)';
490 $sql .= ' ORDER BY a.artifact_id';
492 $result = db_query_params($sql, $query_params);
493 if ($result && db_numrows($result)) {
494 while ($arr = db_fetch_array($result)) {
495 $artifacts[] = new Artifact($this->ArtifactType, $arr);
506 // c-file-style: "bsd"