3 * GForge Tracker Facility
5 * Copyright 2002 GForge, LLC
10 * This file is part of GForge.
12 * GForge is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * GForge is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with GForge; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US
27 require_once('common/include/Error.class');
28 require_once('common/tracker/Artifact.class');
29 require_once('common/tracker/ArtifactType.class');
30 require_once('common/tracker/ArtifactQuery.class');
32 class ArtifactFactory extends Error {
35 * The ArtifactType object.
37 * @var object $ArtifactType.
42 * The artifacts array.
44 * @var array artifacts.
46 var $artifacts = array();
65 * @param object The ArtifactType object to which this ArtifactFactory is associated.
66 * @return boolean success.
68 function ArtifactFactory(&$ArtifactType) {
70 if (!$ArtifactType || !is_object($ArtifactType)) {
71 $this->setError('ArtifactFactory:: No Valid ArtifactType Object');
74 if ($ArtifactType->isError()) {
75 $this->setError('ArtifactFactory:: '.$ArtifactType->getErrorMessage());
78 $this->ArtifactType =& $ArtifactType;
79 $this->changed_from = 0x7ffffff; // Any
85 * setup - sets up limits and sorts before you call getTasks().
87 * @param int The offset - number of rows to skip.
88 * @param string The column to sort on.
89 * @param string The way to order - ASC or DESC.
90 * @param int The max number of rows to return.
91 * @param string Whether to set these prefs into the user_prefs table - use "custom".
92 * @param int Include this param if you want to limit to a certain assignee.
93 * @param int Include this param if you want to limit to a particular status.
94 * @param array Array of extra fields & elements to limit the query to.
96 function setup($offset,$order_col,$sort,$max_rows,$set,$_assigned_to,$_status,$_extra_fields=array()) {
97 //echo "<BR>offset: $offset| order: $order|max_rows: $max_rows|_assigned_to: $_assigned_to|_status: $_status";
99 if ((!$offset) || ($offset < 0)) {
102 $this->offset=$offset;
105 if (session_loggedin()) {
106 $u =& session_get_user();
108 if (!is_array($_extra_fields)) {
109 $_extra_fields=array();
114 if no set is passed in, see if a preference was set
115 if no preference or not logged in, use open set
117 if (session_loggedin()) {
118 $default_query=$u->getPreference('art_query'.$this->ArtifactType->getID());
119 $this->defaultquery = $default_query;
120 if ($default_query) {
121 $aq = new ArtifactQuery($this->ArtifactType,$default_query);
122 $_extra_fields=$aq->getExtraFields();
123 $order_col=$aq->getSortCol();
124 $sort=$aq->getSortOrd();
125 $_assigned_to=$aq->getAssignee();
126 $_status=$aq->getStatus();
127 $this->moddaterange = $aq->getModDateRange();
128 $this->opendaterange = $aq->getOpenDateRange();
129 $this->closedaterange = $aq->getCloseDateRange();
131 $custom_pref=$u->getPreference('art_cust'.$this->ArtifactType->getID());
133 //$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.'|'.serialize($_extra_fields);
134 $pref_arr=explode('|',$custom_pref);
135 $_assigned_to=$pref_arr[0];
136 $_status=$pref_arr[1];
137 $order_col=$pref_arr[2];
139 $_changed=$pref_arr[4];
140 if ($this->ArtifactType->usesCustomStatuses()) {
141 $_extra_fields=unserialize($pref_arr[5]);
143 $_status=$pref_arr[1];
161 // validate the column names and sort order passed in from user
162 // before saving it to prefs
164 if ($order_col=='artifact_id' || $order_col=='summary' || $order_col=='open_date' ||
165 $order_col=='close_date' || $order_col=='assigned_to' || $order_col=='submitted_by' || $order_col=='priority') {
166 $_order_col=$order_col;
167 if (($sort == 'ASC') || ($sort == 'DESC')) {
173 $_order_col='artifact_id';
177 if ($set=='custom') {
178 if (session_loggedin()) {
180 if this custom set is different than the stored one, reset preference
182 if (is_array($_assigned_to)) {
185 $aux_extra_fields = array();
186 if (is_array($_extra_fields)){
187 //print_r($_extra_fields);
188 $keys=array_keys($_extra_fields);
190 foreach ($keys as $key) {
191 if ($_extra_fields[$key] != 'Array') {
192 $aux_extra_fields[$key] = $_extra_fields[$key];
198 if (count($aux_extra_fields)>0) {
199 $extra_pref = '|'.serialize($aux_extra_fields);
202 $pref_=$_assigned_to.'|'.$_status.'|'.$_order_col.'|'.$_sort_ord.'|'.$_changed.$extra_pref;
203 if ($pref_ != $u->getPreference('art_cust'.$this->ArtifactType->getID())) {
204 $u->setPreference('art_cust'.$this->ArtifactType->getID(),$pref_);
206 $default_query=$u->getPreference('art_query'.$this->ArtifactType->getID());
207 if ($default_query) {
208 $u->deletePreference('art_query'.$this->ArtifactType->getID());
213 $this->sort=$_sort_ord;
214 $this->order_col=$_order_col;
215 $this->status=$_status;
216 if ($_assigned_to != 'Array') {
217 $this->assigned_to=$_assigned_to;
219 $this->extra_fields=$_extra_fields;
220 $this->setChangedFrom($_changed);
222 // if $max_rows == 0 it means we want all the rows
223 if (is_null($max_rows) || $max_rows < 0) {
226 if ($default_query) {
229 $this->max_rows=$max_rows;
235 * setChangedFrom - sets up changed-from and last-changed before you call getTasks().
237 * @param int The changed_from - offset time(sec) from now
239 function setChangedFrom($changed_from) {
240 $this->changed_from = ($changed_from <= 0) ? 0x7fffffff : $changed_from;
241 $this->last_changed = time() - $this->changed_from;
245 * getDefaultQuery - get the default query
249 function getDefaultQuery() {
250 return $this->defaultquery;
254 * getArtifacts - get an array of Artifact objects.
256 * @return array The array of Artifact objects.
258 function &getArtifacts() {
259 global $sys_database_type;
261 if (!empty($this->artifacts)) {
262 return $this->artifacts;
265 //if status selected, and more to where clause
266 if ($this->status && ($this->status != 100)) {
267 //for open tasks, add status=100 to make sure we show all
268 $status_str="AND status_id='".$this->status."'";
270 //no status was chosen, so don't add it to where clause
274 //if assigned to selected, and more to where clause
275 if ($this->assigned_to) {
276 if (is_array($this->assigned_to)) {
277 $assigned_str="AND assigned_to IN (".implode(',',$this->assigned_to).")";
279 $assigned_str="AND assigned_to='".$this->assigned_to."'";
282 //no assigned to was chosen, so don't add it to where clause
286 if (is_array($this->extra_fields) && !empty($this->extra_fields)) {
287 $keys=array_keys($this->extra_fields);
288 $vals=array_values($this->extra_fields);
291 for ($i=0; $i<count($keys); $i++) {
292 if (empty($vals[$i])) {
295 if (is_array($vals[$i]) && !empty($vals[$i])) {
296 $vals[$i]=implode(',',$vals[$i]);
298 $ef_table_str.=", artifact_extra_field_data aefd$i ";
299 $ef_where_str.=" AND aefd$i.extra_field_id='".$keys[$i]."' AND aefd$i.field_data IN (".$vals[$i].") AND aefd$i.artifact_id=artifact_vw.artifact_id ";
306 if ($this->last_changed > 0) {
307 $last_changed_str=" AND last_modified_date > '" . $this->last_changed . "' ";
309 $last_changed_str='';
312 //add constraint of range of modified dates
313 if ($this->moddaterange) {
314 $range_arr=explode(' ',$this->moddaterange);
315 $begin_int = strtotime($range_arr[0]);
316 $end_int=strtotime($range_arr[1])+(24*60*60);
317 $moddatesql= " AND last_modified_date BETWEEN '$begin_int' AND '$end_int' ";
321 //add constraint of range of open dates
322 if ($this->opendaterange) {
323 $range_arr=explode(' ',$this->opendaterange);
324 $begin_int = strtotime($range_arr[0]);
325 $end_int=strtotime($range_arr[1])+(24*60*60);
326 $opendatesql= " AND open_date BETWEEN '$begin_int' AND '$end_int' ";
330 //add constraint of range of close dates
331 if ($this->closedaterange) {
332 $range_arr=explode(' ',$this->closedaterange);
333 $begin_int = strtotime($range_arr[0]);
334 $end_int=strtotime($range_arr[1])+(24*60*60);
335 $closedatesql= " AND close_date BETWEEN '$begin_int' AND '$end_int' ";
340 // these are currently not being used
341 $submitted_by_str = '';
344 // now run the query using the criteria chosen above
346 if ($sys_database_type == "mysql") {
347 $sql="SELECT * FROM (SELECT DISTINCT artifact_vw.* FROM artifact_vw $ef_table_str ";
349 $sql="SELECT * FROM (SELECT DISTINCT ON (group_artifact_id, artifact_id) artifact_vw.* FROM artifact_vw $ef_table_str ";
353 group_artifact_id='". $this->ArtifactType->getID() ."'
354 $opendatesql $moddatesql $closedatesql $submitted_by_str
355 $status_str $assigned_str $last_changed_str $ef_where_str ) AS Artifacts
356 ORDER BY Artifacts.group_artifact_id ".$this->sort.", Artifacts.". $this->order_col ." ".$this->sort;
360 $result=db_query($sql);//,($this->max_rows),$this->offset);
361 $rows = db_numrows($result);
362 $this->fetched_rows=$rows;
364 $this->setError('Database Error: '.db_error());
367 while ($arr =& db_fetch_array($result)) {
368 $this->artifacts[] = new Artifact($this->ArtifactType, $arr);
371 return $this->artifacts;