3 * ArtifactExtraField.class.php - Class to handle user defined artifacts
5 * Copyright 2004 (c) Anthony J. Pugliese
9 * This file is part of GForge.
11 * GForge is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * GForge is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with GForge; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US
25 require_once('common/include/Error.class.php');
27 define('ARTIFACT_EXTRAFIELD_FILTER_INT','1,2,3,5,7');
28 define('ARTIFACT_EXTRAFIELDTYPE_SELECT',1);
29 define('ARTIFACT_EXTRAFIELDTYPE_CHECKBOX',2);
30 define('ARTIFACT_EXTRAFIELDTYPE_RADIO',3);
31 define('ARTIFACT_EXTRAFIELDTYPE_TEXT',4);
32 define('ARTIFACT_EXTRAFIELDTYPE_MULTISELECT',5);
33 define('ARTIFACT_EXTRAFIELDTYPE_TEXTAREA',6);
34 define('ARTIFACT_EXTRAFIELDTYPE_STATUS',7);
35 //define('ARTIFACT_EXTRAFIELDTYPE_ASSIGNEE',8);
37 class ArtifactExtraField extends Error {
40 * The artifact type object.
42 * @var object $ArtifactType.
44 var $ArtifactType; //object
47 * Array of artifact data.
49 * @var array $data_array.
54 * ArtifactExtraField - Constructer
56 * @param object ArtifactType object.
57 * @param array (all fields from artifact_file_user_vw) OR id from database.
58 * @return boolean success.
60 function ArtifactExtraField(&$ArtifactType, $data=false) {
63 //was ArtifactType legit?
64 if (!$ArtifactType || !is_object($ArtifactType)) {
65 $this->setError('ArtifactExtraField: No Valid ArtifactType');
68 //did ArtifactType have an error?
69 if ($ArtifactType->isError()) {
70 $this->setError('ArtifactExtraField: '.$Artifact->getErrorMessage());
73 $this->ArtifactType =& $ArtifactType;
76 if (is_array($data)) {
77 $this->data_array =& $data;
80 if (!$this->fetchData($data)) {
90 * create - create a row in the table that stores box names for a
91 * a tracker. This function is only used to create rows for boxes
92 * configured by the admin.
94 * @param string Name of the extra field.
95 * @param int The type of field - radio, select, text, textarea
96 * @param int Attribute1 - for text (size) and textarea (rows)
97 * @param int Attribute2 - for text (maxlength) and textarea (cols)
98 * @param int is_required - true or false whether this is a required field or not.
99 * @param string alias - alias for this extra field (optional)
100 * @return true on success / false on failure.
102 function create($name,$field_type,$attribute1,$attribute2,$is_required=0,$alias='') {
109 $this->setError(_('a field name is required'));
112 if (!$this->ArtifactType->userIsAdmin()) {
113 $this->setPermissionDeniedError();
122 if (!($alias = $this->generateAlias($alias,$name))) {
126 $sql="INSERT INTO artifact_extra_field_list (group_artifact_id,field_name,
127 field_type,attribute1,attribute2,is_required,alias)
128 VALUES ('".$this->ArtifactType->getID()."','".htmlspecialchars($name)."',
129 '$field_type','$attribute1','$attribute2','$is_required','$alias')";
132 $result=db_query($sql);
134 if ($result && db_affected_rows($result) > 0) {
136 $id=db_insertid($result,'artifact_extra_field_list','extra_field_id');
138 // Now set up our internal data structures
140 if (!$this->fetchData($id)) {
144 if ($field_type == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
145 if (!$this->ArtifactType->setCustomStatusField($id)) {
150 // Must insert some default statuses for each artifact
152 $reso=db_query("INSERT INTO artifact_extra_field_elements(extra_field_id,element_name,status_id)
153 values ('$id','Open','1')");
157 $resoid=db_insertid($reso,'artifact_extra_field_elements','element_id');
158 db_query("INSERT INTO artifact_extra_field_data(artifact_id,field_data,extra_field_id)
159 SELECT artifact_id,$resoid,$id FROM artifact
160 WHERE group_artifact_id='".$this->ArtifactType->getID()."'
163 $resc=db_query("INSERT INTO artifact_extra_field_elements(extra_field_id,element_name,status_id)
164 values ('$id','Closed','2')");
168 $rescid=db_insertid($resc,'artifact_extra_field_elements','element_id');
169 db_query("INSERT INTO artifact_extra_field_data(artifact_id,field_data,extra_field_id)
170 SELECT artifact_id,$rescid,$id FROM artifact
171 WHERE group_artifact_id='".$this->ArtifactType->getID()."'
172 AND status_id != 1");
175 } elseif (strstr(ARTIFACT_EXTRAFIELD_FILTER_INT,$field_type) !== false) {
177 // Must insert some default 100 rows for the data table so None queries will work right
179 $resdefault=db_query("INSERT INTO artifact_extra_field_data(artifact_id,field_data,extra_field_id)
180 SELECT artifact_id,100,$id FROM artifact WHERE group_artifact_id='".$this->ArtifactType->getID()."'");
188 $this->setError(db_error());
195 * fetchData - re-fetch the data for this ArtifactExtraField from the database.
197 * @param int ID of the Box.
198 * @return boolean success.
200 function fetchData($id) {
202 $res=db_query("SELECT * FROM artifact_extra_field_list WHERE extra_field_id='$id'");
204 if (!$res || db_numrows($res) < 1) {
205 $this->setError('ArtifactExtraField: Invalid ArtifactExtraField ID');
208 $this->data_array =& db_fetch_array($res);
209 db_free_result($res);
214 * getArtifactType - get the ArtifactType Object this ArtifactExtraField is associated with.
216 * @return object ArtifactType.
218 function &getArtifactType() {
219 return $this->ArtifactType;
223 * getID - get this ArtifactExtraField ID.
225 * @return int The id #.
228 return $this->data_array['extra_field_id'];
232 * getName - get the name.
234 * @return string The name.
237 return $this->data_array['field_name'];
241 * getAttribute1 - get the attribute1 field.
243 * @return int The first attribute.
245 function getAttribute1() {
246 return $this->data_array['attribute1'];
250 * getAttribute2 - get the attribute2 field.
252 * @return int The second attribute.
254 function getAttribute2() {
255 return $this->data_array['attribute2'];
259 * getType - the type of field.
264 return $this->data_array['field_type'];
268 * getTypeName - the name of type of field.
270 * @return string type.
272 function getTypeName() {
273 $arr=&$this->getAvailableTypes();
274 return $arr[$this->data_array['field_type']];
278 * isRequired - whether this field is required or not.
280 * @return boolean required.
282 function isRequired() {
283 return $this->data_array['is_required'];
287 * getAvailableTypes - the types of text fields and their names available.
289 * @return array types.
291 function getAvailableTypes() {
296 3=>_('Radio Buttons'),
298 5=>_('Multi-Select Box'),
305 * getAlias - the alias that is used for this field
307 * @return string alias
309 function getAlias() {
310 return $this->data_array['alias'];
314 * getAvailableValues - Get the list of available values for this extra field
318 function getAvailableValues() {
319 $sql = "SELECT * FROM artifact_extra_field_elements WHERE extra_field_id=".$this->getID();
320 $res = db_query($sql);
323 while ($row = db_fetch_array($res)) {
330 * update - update a row in the table used to store box names
331 * for a tracker. This function is only to update rowsf
332 * for boxes configured by
335 * @param string Name of the field.
336 * @param int Attribute1 - for text (size) and textarea (rows)
337 * @param int Attribute2 - for text (maxlength) and textarea (cols)
338 * @param int is_required - true or false whether this is a required field or not.
339 * @param string Alias for this field
340 * @return boolean success.
342 function update($name,$attribute1,$attribute2,$is_required=0,$alias="") {
345 if (!$this->ArtifactType->userIsAdmin()) {
346 $this->setPermissionDeniedError();
353 $this->setError(_('a field name is required'));
362 if (!($alias = $this->generateAlias($alias,$name))) {
366 $sql="UPDATE artifact_extra_field_list
368 field_name='".htmlspecialchars($name)."',
369 attribute1='$attribute1',
370 attribute2='$attribute2',
371 is_required='$is_required',
373 WHERE extra_field_id='". $this->getID() ."'
374 AND group_artifact_id='".$this->ArtifactType->getID()."'";
375 $result=db_query($sql);
376 if ($result && db_affected_rows($result) > 0) {
379 $this->setError(db_error());
388 function delete($sure, $really_sure) {
389 if (!$sure || !$really_sure) {
390 $this->setMissingParamsError();
393 if (!$this->ArtifactType->userIsAdmin()) {
394 $this->setPermissionDeniedError();
398 $sql="DELETE FROM artifact_extra_field_data
399 WHERE extra_field_id='".$this->getID()."'";
400 $result=db_query($sql);
402 $sql="DELETE FROM artifact_extra_field_elements
403 WHERE extra_field_id='".$this->getID()."'";
404 $result=db_query($sql);
406 $sql="DELETE FROM artifact_extra_field_list
407 WHERE extra_field_id='".$this->getID()."'";
408 $result=db_query($sql);
410 if ($this->getType() == ARTIFACT_EXTRAFIELDTYPE_STATUS) {
411 if (!$this->ArtifactType->setCustomStatusField(0)) {
419 $this->setError(db_error());
424 $this->setError(db_error());
429 $this->setError(db_error());
438 * Note that this function does not check for conflicts.
439 * @param string alias - alias to validate
440 * @return bool true if alias is valid, false otherwise and it sets the corresponding error
442 function validateAlias($alias) {
445 // these are reserved alias names
446 static $reserved_alias = array(
455 if (strlen($alias) == 0) return true; // empty alias
458 if (preg_match("/[^[:alnum:]_\\-]/", $alias)) {
459 $this->setError(_('The alias contains invalid characters. Only letters, numbers, hypens (-) and underscores (_) allowed.'));
461 } else if (in_array($alias, $reserved_alias)) { // alias is reserved?
462 $this->setError(sprintf(_('\'%1$s\' is a reserved alias. Please provide another name.'), $alias));
470 * Generate an alias for this field. The alias can be entered by the user or
471 * be generated automatically from the name of the field.
472 * @param string Alias entered by the user
473 * @param string Name of the field entered by the user (it'll be used when $alias is empty)
476 function generateAlias($alias, $name) {
477 $alias = strtolower(trim($alias));
478 if (strlen($alias) == 0) { // no alias was entered, generate alias from $name
479 $name = strtolower(trim($name));
480 // Convert the original name to a valid alias (i.e., if the extra field is
481 // called "Quality test", make an alias called "quality_test").
482 // The alias can be seen as a "unix name" for this field
483 $alias = preg_replace("/ /", "_", $name);
484 $alias = preg_replace("/[^[:alnum:]_]/", "", $alias);
485 $alias = strtolower($alias);
486 } elseif (!$this->validateAlias($alias)) {
487 // alias is invalid...
490 // check if the name conflicts with another alias in the same artifact type
491 // in that case append a serial number to the alias
495 $sql = "SELECT * FROM artifact_extra_field_list ".
496 "WHERE LOWER(alias)='".$alias."' AND ".
497 "group_artifact_id=".$this->ArtifactType->getID();
498 if ($this->data_array['extra_field_id']) {
499 $sql .= " AND extra_field_id <> ".$this->data_array['extra_field_id'];
501 $res = db_query($sql);
504 $this->setError(db_error());
506 } else if (db_numrows($res) > 0) { // found another field with the same alias
509 $alias = $alias.$serial;
515 // at this point, the alias is valid and unique