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()) {
101 //echo "<br />offset: $offset| order: $order|max_rows: $max_rows|_assigned_to: $_assigned_to|_status: $_status";
103 if ((!$offset) || ($offset < 0)) {
106 $this->offset=$offset;
109 if (session_loggedin()) {
110 $u =& session_get_user();
112 if (!is_array($_extra_fields)) {
113 $_extra_fields=array();
119 if no set is passed in, see if a preference was set
120 if no preference or not logged in, use open set
122 $this->query_type = '';
123 if (session_loggedin()) {
124 $query_id=$u->getPreference('art_query'.$this->ArtifactType->getID());
126 $this->query_type = 'query';
127 $this->query_id = $query_id;
129 $custom_pref=$u->getPreference('art_cust'.$this->ArtifactType->getID());
131 //$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.'|'.serialize($_extra_fields);
132 $this->query_type = 'custom';
133 $pref_arr=explode('|',$custom_pref);
134 $_assigned_to=$pref_arr[0];
135 $_status=$pref_arr[1];
136 $order_col=$pref_arr[2];
138 $_changed=$pref_arr[4];
139 if ($this->ArtifactType->usesCustomStatuses()) {
140 $_extra_fields=unserialize($pref_arr[5]);
142 $_status=$pref_arr[1];
147 } elseif (isset($_COOKIE["GFTrackerQuery"])) {
148 $gf_tracker = unserialize($_COOKIE["GFTrackerQuery"]);
149 $query_id = (int)$gf_tracker[$this->ArtifactType->getID()];
151 $this->query_type = 'query';
152 $this->query_id = $query_id;
156 if (!$this->query_type) {
157 $res = db_query_params ('SELECT artifact_query_id FROM artifact_query
158 WHERE group_artifact_id=$1
160 array($this->ArtifactType->getID()));
161 if (db_numrows($res)>0) {
162 $this->query_type = 'query';
163 $this->query_id = db_result($res, 0, 'artifact_query_id');
167 if (!$this->query_type) {
168 //default to all opened
169 $this->query_type = 'default';
175 if ($this->query_type == 'query') {
176 $aq = new ArtifactQuery($this->ArtifactType, $this->query_id);
177 $_assigned_to=$aq->getAssignee();
178 $_status=$aq->getStatus();
179 $_extra_fields=$aq->getExtraFields();
180 $this->moddaterange = $aq->getModDateRange();
181 $this->opendaterange = $aq->getOpenDateRange();
182 $this->closedaterange = $aq->getCloseDateRange();
183 $this->summary = $aq->getSummary();
184 $this->description = $aq->getDescription();
185 $this->followups = $aq->getFollowups();
186 $order_col=$aq->getSortCol();
187 $sort=$aq->getSortOrd();
192 // validate the column names and sort order passed in from user
193 // before saving it to prefs
195 $_order_col = util_ensure_value_in_set ($order_col,
196 array ('artifact_id',
203 $_sort_ord = util_ensure_value_in_set ($sort,
204 array ('ASC', 'DESC')) ;
205 if ($set=='custom') {
206 $this->query_type = 'custom';
207 if (session_loggedin()) {
209 if this custom set is different than the stored one, reset preference
211 if (is_array($_assigned_to)) {
214 $aux_extra_fields = array();
215 if (is_array($_extra_fields)){
216 //print_r($_extra_fields);
217 $keys=array_keys($_extra_fields);
219 foreach ($keys as $key) {
220 if ($_extra_fields[$key] != 'Array') {
221 $aux_extra_fields[$key] = $_extra_fields[$key];
227 if (count($aux_extra_fields)>0) {
228 $extra_pref = '|'.serialize($aux_extra_fields);
231 $pref_=$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.$extra_pref;
232 if ($pref_ != $u->getPreference('art_cust'.$this->ArtifactType->getID())) {
233 $u->setPreference('art_cust'.$this->ArtifactType->getID(),$pref_);
235 $default_query=$u->getPreference('art_query'.$this->ArtifactType->getID());
236 if ($default_query) {
237 $u->deletePreference('art_query'.$this->ArtifactType->getID());
243 $this->sort=$_sort_ord;
244 $this->order_col=$_order_col;
245 $this->status=$_status;
246 if (gettype($_assigned_to) === 'integer' ||
247 gettype($_assigned_to) === 'string') {
248 $this->assigned_to=$_assigned_to;
250 $this->extra_fields=$_extra_fields;
251 $this->setChangedFrom($_changed);
253 // if $max_rows == 0 it means we want all the rows
254 if (is_null($max_rows) || $max_rows < 0) {
257 if ($this->query_type == 'query') {
260 $this->max_rows=$max_rows;
266 * setChangedFrom - sets up changed-from and last-changed before you call getTasks().
268 * @param int 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 array The array of Artifact objects.
292 function &getArtifacts() {
293 global $sys_database_type;
295 if (!empty($this->artifacts)) {
296 return $this->artifacts;
302 $selectsql = 'SELECT DISTINCT ON (group_artifact_id, artifact_id) artifact_vw.* FROM artifact_vw';
304 $wheresql = ' WHERE group_artifact_id=$'.$paramcount++ ;
305 $params[] = $this->ArtifactType->getID() ;
307 if (is_array($this->extra_fields) && !empty($this->extra_fields)) {
308 $keys=array_keys($this->extra_fields);
309 $vals=array_values($this->extra_fields);
310 for ($i=0; $i<count($keys); $i++) {
311 if (empty($vals[$i])) {
314 $selectsql .= ', artifact_extra_field_data aefd'.$i;
315 $wheresql .= ' AND aefd'.$i.'.extra_field_id=$'.$paramcount++ ;
316 $params[] = $keys[$i] ;
318 // Hack: Determine the type of the element to get the right search query.
319 $res = db_query_params ('SELECT field_type FROM artifact_extra_field_list WHERE extra_field_id=$1',
321 $type = db_result($res,0,'field_type');
322 if ($type == 4 or $type == 6) {
323 $wheresql .= ' AND aefd'.$i.'.field_data LIKE $'.$paramcount++ ;
324 $params[] = $vals[$i];
326 if (is_array($vals[$i])) {
327 $wheresql .= ' AND aefd'.$i.'.field_data = ANY ($'.$paramcount++ .')' ;
328 $params[] = db_string_array_to_any_clause ($vals[$i]) ;
330 $wheresql .= ' AND aefd'.$i.'.field_data = $'.$paramcount++ ;
331 $params[] = $vals[$i];
334 $wheresql .= ' AND aefd'.$i.'.artifact_id=artifact_vw.artifact_id' ;
338 //if status selected, and more to where clause
339 if ($this->status && ($this->status != 100)) {
340 //for open tasks, add status=100 to make sure we show all
341 $wheresql .= ' AND status_id=$'.$paramcount++ ;
342 $params[] = $this->status;
345 //if assigned to selected, and more to where clause
346 if ($this->assigned_to) {
347 if (is_array($this->assigned_to)) {
348 $wheresql .= 'AND assigned_to = ANY ($'.$paramcount++ ;
349 $params[] = db_int_array_to_any_clause ($this->assigned_to) ;
352 $wheresql .= 'AND assigned_to = $'.$paramcount++ ;
353 $params[] = $this->assigned_to ;
357 if ($this->last_changed > 0) {
358 $wheresql .= ' AND last_modified_date > $'.$paramcount++ ;
359 $params[] = $this->last_changed ;
362 //add constraint of range of modified dates
363 if ($this->moddaterange) {
364 $range_arr=explode(' ',$this->moddaterange);
365 $begin_int = strtotime($range_arr[0]);
366 $end_int=strtotime($range_arr[1])+(24*60*60);
367 $wheresql .= ' AND (last_modified_date BETWEEN $'.$paramcount++ ;
368 $params[] = $begin_int ;
369 $wheresql .= ' AND $'.$paramcount++ ;
370 $params[] = $end_int ;
373 //add constraint of range of open dates
374 if ($this->opendaterange) {
375 $range_arr=explode(' ',$this->opendaterange);
376 $begin_int = strtotime($range_arr[0]);
377 $end_int=strtotime($range_arr[1])+(24*60*60);
378 $wheresql .= ' AND (open_date BETWEEN $'.$paramcount++ ;
379 $params[] = $begin_int ;
380 $wheresql .= ' AND $'.$paramcount++ ;
381 $params[] = $end_int ;
384 //add constraint of range of close dates
385 if ($this->closedaterange) {
386 $range_arr=explode(' ',$this->closedaterange);
387 $begin_int = strtotime($range_arr[0]);
388 $end_int=strtotime($range_arr[1])+(24*60*60);
389 $wheresql .= ' AND (close_date BETWEEN $'.$paramcount++ ;
390 $params[] = $begin_int ;
391 $wheresql .= ' AND $'.$paramcount++ ;
392 $params[] = $end_int ;
396 //add constraint on the summary string.
397 if ($this->summary) {
398 $wheresql .= ' AND summary LIKE $'.$paramcount++ ;
399 $params[] = $this->summary;
401 //add constraint on the description string.
402 if ($this->description) {
403 $wheresql .= ' AND details LIKE $'.$paramcount++ ;
404 $params[] = $this->description;
406 //add constraint on the followups string.
407 if ($this->followups) {
408 $wheresql .= 'LEFT OUTER JOIN artifact_message am USING (artifact_id)
409 WHERE am.body LIKE $'.$paramcount++;
410 $params[] = $this->followups;
413 $sortorder = util_ensure_value_in_set ($this->sort,
414 array ('ASC', 'DESC')) ;
416 $sortcol = util_ensure_value_in_set ($this->order_col,
417 array ('artifact_id',
424 $ordersql = " ORDER BY Artifacts.group_artifact_id $sortorder, Artifacts.$sortcol $sortorder" ;
426 $result = db_query_params ('SELECT * FROM (' . $selectsql . $wheresql . ') AS Artifacts' . $ordersql,
428 $rows = db_numrows($result);
429 $this->fetched_rows=$rows;
431 $this->setError('Database Error: '.db_error());
434 while ($arr =& db_fetch_array($result)) {
435 $this->artifacts[] = new Artifact($this->ArtifactType, $arr);
438 return $this->artifacts;
445 // c-file-style: "bsd"