5 * Copyright 2002, GForge, LLC
7 * This file is part of FusionForge.
9 * FusionForge is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published
11 * by the Free Software Foundation; either version 2 of the License,
12 * or (at your option) any later version.
14 * FusionForge is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with FusionForge; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 require_once $gfcommon.'include/Error.class.php';
26 require_once $gfcommon.'tracker/Artifact.class.php';
27 require_once $gfcommon.'tracker/ArtifactType.class.php';
28 require_once $gfcommon.'tracker/ArtifactQuery.class.php';
30 class ArtifactFactory extends Error {
33 * The ArtifactType object.
35 * @var object $ArtifactType.
40 * The artifacts array.
42 * @var array artifacts.
44 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 ArtifactFactory(&$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 $_assigned_to=$aq->getAssignee();
184 $_status=$aq->getStatus();
185 $_extra_fields=$aq->getExtraFields();
186 $this->moddaterange = $aq->getModDateRange();
187 $this->opendaterange = $aq->getOpenDateRange();
188 $this->closedaterange = $aq->getCloseDateRange();
189 $this->summary = $aq->getSummary();
190 $this->description = $aq->getDescription();
191 $this->followups = $aq->getFollowups();
192 $order_col=$aq->getSortCol();
193 $sort=$aq->getSortOrd();
198 // validate the column names and sort order passed in from user
199 // before saving it to prefs
201 $_order_col = util_ensure_value_in_set ($order_col,
202 array ('artifact_id',
209 $_sort_ord = util_ensure_value_in_set ($sort,
210 array ('ASC', 'DESC')) ;
211 if ($set=='custom') {
212 $this->query_type = 'custom';
213 if (session_loggedin()) {
215 if this custom set is different than the stored one, reset preference
217 if (is_array($_assigned_to)) {
220 $aux_extra_fields = array();
221 if (is_array($_extra_fields)){
222 //print_r($_extra_fields);
223 $keys=array_keys($_extra_fields);
225 foreach ($keys as $key) {
226 if ($_extra_fields[$key] != 'Array') {
227 $aux_extra_fields[$key] = $_extra_fields[$key];
233 if (count($aux_extra_fields)>0) {
234 $extra_pref = '|'.serialize($aux_extra_fields);
237 $pref_=$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.$extra_pref;
238 if ($pref_ != $u->getPreference('art_cust'.$this->ArtifactType->getID())) {
239 $u->setPreference('art_cust'.$this->ArtifactType->getID(),$pref_);
241 $default_query=$u->getPreference('art_query'.$this->ArtifactType->getID());
242 if ($default_query) {
243 $u->deletePreference('art_query'.$this->ArtifactType->getID());
249 $this->sort=$_sort_ord;
250 $this->order_col=$_order_col;
251 $this->status=$_status;
252 if (gettype($_assigned_to) === 'integer' ||
253 gettype($_assigned_to) === 'string') {
254 $this->assigned_to=$_assigned_to;
256 $this->extra_fields=$_extra_fields;
257 $this->setChangedFrom($_changed);
262 * setChangedFrom - sets up changed-from and last-changed before you call getTasks().
264 * @param int The changed_from - offset time(sec) from now
266 function setChangedFrom($changed_from) {
267 $this->changed_from = ($changed_from <= 0) ? 0x7fffffff : $changed_from;
268 $this->last_changed = time() - $this->changed_from;
272 * getDefaultQuery - get the default query
276 function getDefaultQuery() {
277 if ($this->query_type == 'query')
278 return $this->query_id;
284 * getArtifacts - get an array of Artifact objects.
286 * @return array The array of Artifact objects.
288 function &getArtifacts() {
289 if (!empty($this->artifacts)) {
290 return $this->artifacts;
296 $selectsql = 'SELECT DISTINCT ON (group_artifact_id, artifact_id) artifact_vw.* FROM artifact_vw';
298 $wheresql = ' WHERE group_artifact_id=$'.$paramcount++ ;
299 $params[] = $this->ArtifactType->getID() ;
301 if (is_array($this->extra_fields) && !empty($this->extra_fields)) {
302 $keys=array_keys($this->extra_fields);
303 $vals=array_values($this->extra_fields);
304 for ($i=0; $i<count($keys); $i++) {
305 if (empty($vals[$i])) {
308 $selectsql .= ', artifact_extra_field_data aefd'.$i;
309 $wheresql .= ' AND aefd'.$i.'.extra_field_id=$'.$paramcount++ ;
310 $params[] = $keys[$i] ;
312 // Hack: Determine the type of the element to get the right search query.
313 $res = db_query_params ('SELECT field_type FROM artifact_extra_field_list WHERE extra_field_id=$1',
315 $type = db_result($res,0,'field_type');
316 if ($type == 4 or $type == 6) {
317 $wheresql .= ' AND aefd'.$i.'.field_data LIKE $'.$paramcount++ ;
318 $params[] = $vals[$i];
320 if (is_array($vals[$i])) {
321 $wheresql .= ' AND aefd'.$i.'.field_data = ANY ($'.$paramcount++ .')' ;
322 $params[] = db_string_array_to_any_clause ($vals[$i]) ;
324 $wheresql .= ' AND aefd'.$i.'.field_data = $'.$paramcount++ ;
325 $params[] = $vals[$i];
328 $wheresql .= ' AND aefd'.$i.'.artifact_id=artifact_vw.artifact_id' ;
332 //if status selected, and more to where clause
333 if ($this->status && ($this->status != 100)) {
334 //for open tasks, add status=100 to make sure we show all
335 $wheresql .= ' AND status_id=$'.$paramcount++ ;
336 $params[] = $this->status;
339 //if assigned to selected, and more to where clause
340 if ($this->assigned_to) {
341 if (is_array($this->assigned_to)) {
342 $wheresql .= 'AND assigned_to = ANY ($'.$paramcount++ ;
343 $params[] = db_int_array_to_any_clause ($this->assigned_to) ;
346 $wheresql .= 'AND assigned_to = $'.$paramcount++ ;
347 $params[] = $this->assigned_to ;
351 if ($this->last_changed > 0) {
352 $wheresql .= ' AND last_modified_date > $'.$paramcount++ ;
353 $params[] = $this->last_changed ;
356 //add constraint of range of modified dates
357 if ($this->moddaterange) {
358 $range_arr=explode(' ',$this->moddaterange);
359 $begin_int = strtotime($range_arr[0]);
360 $end_int=strtotime($range_arr[1])+(24*60*60);
361 $wheresql .= ' AND (last_modified_date BETWEEN $'.$paramcount++ ;
362 $params[] = $begin_int ;
363 $wheresql .= ' AND $'.$paramcount++ ;
364 $params[] = $end_int ;
367 //add constraint of range of open dates
368 if ($this->opendaterange) {
369 $range_arr=explode(' ',$this->opendaterange);
370 $begin_int = strtotime($range_arr[0]);
371 $end_int=strtotime($range_arr[1])+(24*60*60);
372 $wheresql .= ' AND (open_date BETWEEN $'.$paramcount++ ;
373 $params[] = $begin_int ;
374 $wheresql .= ' AND $'.$paramcount++ ;
375 $params[] = $end_int ;
378 //add constraint of range of close dates
379 if ($this->closedaterange) {
380 $range_arr=explode(' ',$this->closedaterange);
381 $begin_int = strtotime($range_arr[0]);
382 $end_int=strtotime($range_arr[1])+(24*60*60);
383 $wheresql .= ' AND (close_date BETWEEN $'.$paramcount++ ;
384 $params[] = $begin_int ;
385 $wheresql .= ' AND $'.$paramcount++ ;
386 $params[] = $end_int ;
390 //add constraint on the summary string.
391 if ($this->summary) {
392 $wheresql .= ' AND summary LIKE $'.$paramcount++ ;
393 $params[] = $this->summary;
395 //add constraint on the description string.
396 if ($this->description) {
397 $wheresql .= ' AND details LIKE $'.$paramcount++ ;
398 $params[] = $this->description;
400 //add constraint on the followups string.
401 if ($this->followups) {
402 $wheresql .= 'LEFT OUTER JOIN artifact_message am USING (artifact_id)
403 WHERE am.body LIKE $'.$paramcount++;
404 $params[] = $this->followups;
407 $sortorder = util_ensure_value_in_set ($this->sort,
408 array ('ASC', 'DESC')) ;
410 $sortcol = util_ensure_value_in_set ($this->order_col,
411 array ('artifact_id',
418 $ordersql = " ORDER BY Artifacts.group_artifact_id $sortorder, Artifacts.$sortcol $sortorder" ;
420 $result = db_query_params ('SELECT * FROM (' . $selectsql . $wheresql . ') AS Artifacts' . $ordersql,
422 $rows = db_numrows($result);
423 $this->fetched_rows=$rows;
425 $this->setError('Database Error: '.db_error());
428 while ($arr =& db_fetch_array($result)) {
429 $this->artifacts[] = new Artifact($this->ArtifactType, $arr);
432 return $this->artifacts;
439 // c-file-style: "bsd"