Reworked custom fields a bit to mark things deleted instead of deleting.
[timetracker.git] / plugins / CustomFields.class.php
1 <?php
2 // +----------------------------------------------------------------------+
3 // | Anuko Time Tracker
4 // +----------------------------------------------------------------------+
5 // | Copyright (c) Anuko International Ltd. (https://www.anuko.com)
6 // +----------------------------------------------------------------------+
7 // | LIBERAL FREEWARE LICENSE: This source code document may be used
8 // | by anyone for any purpose, and freely redistributed alone or in
9 // | combination with other software, provided that the license is obeyed.
10 // |
11 // | There are only two ways to violate the license:
12 // |
13 // | 1. To redistribute this code in source form, with the copyright
14 // |    notice or license removed or altered. (Distributing in compiled
15 // |    forms without embedded copyright notices is permitted).
16 // |
17 // | 2. To redistribute modified versions of this code in *any* form
18 // |    that bears insufficient indications that the modifications are
19 // |    not the work of the original author(s).
20 // |
21 // | This license applies to this document only, not any other software
22 // | that it may be combined with.
23 // |
24 // +----------------------------------------------------------------------+
25 // | Contributors:
26 // | https://www.anuko.com/time_tracker/credits.htm
27 // +----------------------------------------------------------------------+
28
29 class CustomFields {
30
31   // Definitions of custom field types.
32
33   const TYPE_TEXT = 1;     // A text field.
34   const TYPE_DROPDOWN = 2; // A dropdown field with pre-defined values.
35
36   var $fields = array();  // Array of custom fields for group.
37   var $options = array(); // Array of options for a dropdown custom field.
38
39   // Constructor.
40   function __construct($group_id) {
41     $mdb2 = getConnection();
42
43     // Get fields.
44     $sql = "select id, type, label, required from tt_custom_fields where group_id = $group_id and status = 1 and type > 0";
45     $res = $mdb2->query($sql);
46     if (!is_a($res, 'PEAR_Error')) {
47       while ($val = $res->fetchRow()) {
48         $this->fields[] = array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label'],'required'=>$val['required'],'value'=>'');
49       }
50     }
51
52     // If we have a dropdown obtain options for it.
53     if ((count($this->fields) > 0) && ($this->fields[0]['type'] == CustomFields::TYPE_DROPDOWN)) {
54
55       $sql = "select id, value from tt_custom_field_options where field_id = ".$this->fields[0]['id']." and status = 1 order by value";
56       $res = $mdb2->query($sql);
57       if (!is_a($res, 'PEAR_Error')) {
58         while ($val = $res->fetchRow()) {
59           $this->options[$val['id']] = $val['value'];
60         }
61       }
62     }
63   }
64
65   function insert($log_id, $field_id, $option_id, $value) {
66     global $user;
67     $mdb2 = getConnection();
68
69     $group_id = $user->getActiveGroup();
70     $org_id = $user->org_id;
71
72     $sql = "insert into tt_custom_field_log (group_id, org_id, log_id, field_id, option_id, value)".
73       " values($group_id, $org_id, $log_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).")";
74     $affected = $mdb2->exec($sql);
75     return (!is_a($affected, 'PEAR_Error'));
76   }
77
78   function update($log_id, $field_id, $option_id, $value) {
79     if (!$field_id)
80       return true; // Nothing to update.
81
82     // Remove older custom field values, if any.
83     $res = $this->delete($log_id);
84     if (!$res)
85       return false;
86
87     if (!$value && !$option_id)
88       return true; // Do not insert NULL values.
89
90     return $this->insert($log_id, $field_id, $option_id, $value);
91   }
92
93   function delete($log_id) {
94
95     $mdb2 = getConnection();
96     $sql = "update tt_custom_field_log set status = NULL where log_id = $log_id";
97     $affected = $mdb2->exec($sql);
98     return (!is_a($affected, 'PEAR_Error'));
99   }
100
101   function get($log_id) {
102     $fields = array();
103
104     $mdb2 = getConnection();
105     $sql = "select id, field_id, option_id, value from tt_custom_field_log where log_id = $log_id and status = 1";
106     $res = $mdb2->query($sql);
107     if (!is_a($res, 'PEAR_Error')) {
108       while ($val = $res->fetchRow()) {
109         $fields[] = $val;
110       }
111       return $fields;
112     }
113     return false;
114   }
115
116   // insertOption adds a new option to a custom field.
117   static function insertOption($field_id, $option_name) {
118     global $user;
119     $mdb2 = getConnection();
120
121     $group_id = $user->getActiveGroup();
122     $org_id = $user->org_id;
123
124     // Check if the option exists.
125     $id = 0;
126     $sql = "select id from tt_custom_field_options where field_id = $field_id and value = ".$mdb2->quote($option_name);
127     $res = $mdb2->query($sql);
128     if (is_a($res, 'PEAR_Error'))
129       return false;
130     if ($val = $res->fetchRow()) $id = $val['id'];
131
132     // Insert option.
133     if (!$id) {
134       $sql = "insert into tt_custom_field_options (group_id, org_id, field_id, value)".
135         " values($group_id, $org_id, $field_id, ".$mdb2->quote($option_name).")";
136       $affected = $mdb2->exec($sql);
137       if (is_a($affected, 'PEAR_Error'))
138         return false;
139     }
140     return true;
141   }
142
143   // updateOption updates option name.
144   static function updateOption($id, $option_name) {
145
146     $mdb2 = getConnection();
147
148     $sql = "update tt_custom_field_options set value = ".$mdb2->quote($option_name)." where id = $id";
149     $affected = $mdb2->exec($sql);
150     return (!is_a($affected, 'PEAR_Error'));
151   }
152
153   // delete Option deletes an option and all custom field log entries that used it.
154   static function deleteOption($id) {
155     global $user;
156     $mdb2 = getConnection();
157
158     $field_id = CustomFields::getFieldIdForOption($id);
159
160     // First make sure that the field is ours.
161     $sql = "select group_id from tt_custom_fields where id = $field_id";
162     $res = $mdb2->query($sql);
163     if (is_a($res, 'PEAR_Error'))
164       return false;
165     $val = $res->fetchRow();
166     if ($user->group_id != $val['group_id'])
167       return false;
168
169     // Delete log entries with this option.
170     $sql = "update tt_custom_field_log set status = NULL where field_id = $field_id and value = ".$mdb2->quote($id);
171     $affected = $mdb2->exec($sql);
172     if (is_a($affected, 'PEAR_Error'))
173       return false;
174
175     // Delete the option.
176     $sql = "update tt_custom_field_options set status = NULL where id = $id";
177     $affected = $mdb2->exec($sql);
178     return (!is_a($affected, 'PEAR_Error'));
179   }
180
181   // getOptions returns an array of options for a custom field.
182   static function getOptions($field_id) {
183     global $user;
184     $mdb2 = getConnection();
185     $options = array();
186
187     // First make sure that the field is ours.
188     $sql = "select group_id from tt_custom_fields where id = $field_id";
189     $res = $mdb2->query($sql);
190     if (is_a($res, 'PEAR_Error'))
191       return false;
192     $val = $res->fetchRow();
193     if ($user->group_id != $val['group_id'])
194       return false;
195
196     // Get options.
197     $sql = "select id, value from tt_custom_field_options where field_id = $field_id and status = 1 order by value";
198     $res = $mdb2->query($sql);
199     if (!is_a($res, 'PEAR_Error')) {
200       while ($val = $res->fetchRow()) {
201         $options[$val['id']] = $val['value'];
202       }
203       return $options;
204     }
205     return false;
206   }
207
208   // getOptionName returns an option name for a custom field.
209   static function getOptionName($id) {
210     global $user;
211     $mdb2 = getConnection();
212
213     $field_id = CustomFields::getFieldIdForOption($id);
214
215     // First make sure that the field is ours.
216     $sql = "select group_id from tt_custom_fields where id = $field_id";
217     $res = $mdb2->query($sql);
218     if (is_a($res, 'PEAR_Error'))
219       return false;
220     $val = $res->fetchRow();
221     if ($user->group_id != $val['group_id'])
222       return false;
223
224     // Get option name.
225     $sql = "select value from tt_custom_field_options where id = $id";
226     $res = $mdb2->query($sql);
227     if (!is_a($res, 'PEAR_Error')) {
228       $val = $res->fetchRow();
229       $name = $val['value'];
230       return $name;
231     }
232     return false;
233   }
234
235   // getFields returns an array of custom fields for group.
236   static function getFields() {
237     global $user;
238     $mdb2 = getConnection();
239
240     $fields = array();
241     $sql = "select id, type, label from tt_custom_fields where group_id = $user->group_id and status = 1 and type > 0";
242     $res = $mdb2->query($sql);
243     if (!is_a($res, 'PEAR_Error')) {
244       while ($val = $res->fetchRow()) {
245         $fields[] = array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label']);
246       }
247       return $fields;
248     }
249     return false;
250   }
251
252   // getField returns a custom field.
253   static function getField($id) {
254     global $user;
255     $mdb2 = getConnection();
256
257     $sql = "select label, type, required from tt_custom_fields where id = $id and group_id = $user->group_id";
258     $res = $mdb2->query($sql);
259     if (!is_a($res, 'PEAR_Error')) {
260       $val = $res->fetchRow();
261       if (!$val)
262         return false;
263       return $val;
264     }
265     return false;
266   }
267
268   // getFieldIdForOption returns field id from an associated option id.
269   static function getFieldIdForOption($option_id) {
270     $mdb2 = getConnection();
271
272     $sql = "select field_id from tt_custom_field_options where id = $option_id";
273     $res = $mdb2->query($sql);
274     if (!is_a($res, 'PEAR_Error')) {
275       $val = $res->fetchRow();
276       $field_id = $val['field_id'];
277       return $field_id;
278     }
279     return false;
280   }
281
282   // The insertField inserts a custom field for group.
283   static function insertField($field_name, $field_type, $required) {
284     global $user;
285     $mdb2 = getConnection();
286     $group_id = $user->getActiveGroup();
287     $org_id = $user->org_id;
288     $sql = "insert into tt_custom_fields (group_id, org_id, type, label, required, status)".
289       " values($group_id, $org_id, $field_type, ".$mdb2->quote($field_name).", $required, 1)";
290     $affected = $mdb2->exec($sql);
291     return (!is_a($affected, 'PEAR_Error'));
292   }
293
294   // The updateField updates custom field for group.
295   static function updateField($id, $name, $type, $required) {
296     global $user;
297     $mdb2 = getConnection();
298     $sql = "update tt_custom_fields set label = ".$mdb2->quote($name).", type = $type, required = $required where id = $id and group_id = $user->group_id";
299     $affected = $mdb2->exec($sql);
300     return (!is_a($affected, 'PEAR_Error'));
301   }
302
303   // The deleteField deletes a custom field, its options and log entries for group.
304   static function deleteField($field_id) {
305
306     global $user;
307     $mdb2 = getConnection();
308
309     // First make sure that the field is ours so that we can safely delete it.
310     $sql = "select group_id from tt_custom_fields where id = $field_id";
311     $res = $mdb2->query($sql);
312     if (is_a($res, 'PEAR_Error'))
313       return false;
314     $val = $res->fetchRow();
315     if ($user->group_id != $val['group_id'])
316       return false;
317
318     // Mark log entries as deleted.
319     $sql = "update tt_custom_field_log set status = NULL where field_id = $field_id";
320     $affected = $mdb2->exec($sql);
321     if (is_a($affected, 'PEAR_Error'))
322       return false;
323
324     // Mark field options as deleted.
325     $sql = "update tt_custom_field_options set status = NULL where field_id = $field_id";
326     $affected = $mdb2->exec($sql);
327     if (is_a($affected, 'PEAR_Error'))
328       return false;
329
330     // Mark custom field as deleted.
331     $sql = "update tt_custom_fields set status = NULL where id = $field_id and group_id = $user->group_id";
332     $affected = $mdb2->exec($sql);
333     return (!is_a($affected, 'PEAR_Error'));
334   }
335 }