Some more refactoring for subgroups.
[timetracker.git] / WEB-INF / lib / ttTeamHelper.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 import('ttUserHelper');
30 import('DateAndTime');
31 import('ttInvoiceHelper');
32
33 // Class ttTeamHelper - contains helper functions that operate with groups.
34 class ttTeamHelper {
35
36   // The getUsersForClient obtains all active and inactive users in a group that are relevant to a client.
37   static function getUsersForClient() {
38     global $user;
39     $mdb2 = getConnection();
40
41     $sql = "select u.id, u.name from tt_user_project_binds upb".
42       " inner join tt_client_project_binds cpb on (upb.project_id = cpb.project_id and cpb.client_id = $user->client_id)".
43       " inner join tt_users u on (u.id = upb.user_id)".
44       " where (u.status = 1 or u.status = 0)".
45       " group by u.id".
46       " order by upper(u.name)";
47     $res = $mdb2->query($sql);
48     $user_list = array();
49     if (is_a($res, 'PEAR_Error'))
50       return false;
51     while ($val = $res->fetchRow()) {
52       $user_list[] = $val;
53     }
54     return $user_list;
55   }
56
57   // The getActiveUsers obtains all active users in a given group.
58   static function getActiveUsers($options = null) {
59     global $user;
60     global $i18n;
61     $mdb2 = getConnection();
62
63     $group_id = $user->getGroup();
64     $org_id = $user->org_id;
65
66     if (isset($options['getAllFields']))
67       $sql = "select u.*, r.name as role_name, r.rank from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.org_id = $org_id and u.status = 1 order by upper(u.name)";
68     else
69       $sql = "select id, name from tt_users where group_id = $group_id and org_id = $org_id and status = 1 order by upper(name)";
70     $res = $mdb2->query($sql);
71     $user_list = array();
72     if (is_a($res, 'PEAR_Error'))
73       return false;
74     while ($val = $res->fetchRow()) {
75       // Localize top manager role name, as it is not localized in db.
76       if ($val['rank'] == 512)
77         $val['role_name'] = $i18n->get('role.top_manager.label');
78       $user_list[] = $val;
79     }
80
81     if (isset($options['putSelfFirst'])) {
82       // Put own entry at the front.
83       $cnt = count($user_list);
84       for($i = 0; $i < $cnt; $i++) {
85         if ($user_list[$i]['id'] == $user->id) {
86           $self = $user_list[$i]; // Found self.
87           array_unshift($user_list, $self); // Put own entry at the front.
88           array_splice($user_list, $i+1, 1); // Remove duplicate.
89         }
90       }
91     }
92     return $user_list;
93   }
94
95   // The swapRolesWith swaps existing user role with that of another user.
96   static function swapRolesWith($user_id) {
97     global $user;
98     $mdb2 = getConnection();
99
100     // Obtain role id for the user we are swapping ourselves with.
101     $sql = "select u.id, u.role_id from tt_users u left join tt_roles r on (u.role_id = r.id) where u.id = $user_id and u.group_id = $user->group_id and u.status = 1 and r.rank < $user->rank";
102     $res = $mdb2->query($sql);
103     if (is_a($res, 'PEAR_Error'))
104       return false;
105     $val = $res->fetchRow();
106     if (!$val['id'] || !$val['role_id'])
107       return false;
108
109     $modified_part = ', modified = now(), modified_ip = '.$mdb2->quote($_SERVER['REMOTE_ADDR']).', modified_by = '.$user->id;
110
111     // Promote user.
112     $sql = "update tt_users set role_id = $user->role_id".$modified_part." where id = $user_id and group_id = $user->group_id";
113     $affected = $mdb2->exec($sql);
114     if (is_a($affected, 'PEAR_Error')) return false;
115
116     // Demote self.
117     $role_id = $val['role_id'];
118     $sql = "update tt_users set role_id = $role_id".$modified_part." where id = $user->id and group_id = $user->group_id";
119     $affected = $mdb2->exec($sql);
120     if (is_a($affected, 'PEAR_Error')) return false;
121
122     return true;
123   }
124
125   // The getUsersForSwap obtains all users a current user can swap roles with.
126   static function getUsersForSwap() {
127     global $user;
128     $mdb2 = getConnection();
129
130     $sql = "select u.id, u.name, r.rank, r.rights from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $user->group_id and u.status = 1 and r.rank < $user->rank order by upper(u.name)";
131     $res = $mdb2->query($sql);
132     $user_list = array();
133     if (is_a($res, 'PEAR_Error'))
134       return false;
135     while ($val = $res->fetchRow()) {
136       $isClient = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right.
137       if ($isClient)
138         continue; // Skip adding clients.
139       $user_list[] = $val;
140     }
141
142     return $user_list;
143   }
144
145   // The getUsers obtains all active and inactive (but not deleted) users in a group.
146   static function getUsers() {
147     global $user;
148     $mdb2 = getConnection();
149     $sql = "select id, name from tt_users where group_id = $user->group_id and (status = 1 or status = 0) order by upper(name)";
150     $res = $mdb2->query($sql);
151     $user_list = array();
152     if (is_a($res, 'PEAR_Error'))
153       return false;
154     while ($val = $res->fetchRow()) {
155       $user_list[] = $val;
156     }
157     return $user_list;
158   }
159
160   // The getInactiveUsers obtains all inactive users in a group.
161   static function getInactiveUsers($group_id, $all_fields = false) {
162     $mdb2 = getConnection();
163
164     if ($all_fields)
165       $sql = "select u.*, r.name as role_name from tt_users u left join tt_roles r on (u.role_id = r.id) where u.group_id = $group_id and u.status = 0 order by upper(u.name)";
166     else
167       $sql = "select id, name from tt_users where group_id = $group_id and status = 0 order by upper(name)";
168     $res = $mdb2->query($sql);
169     $result = array();
170     if (!is_a($res, 'PEAR_Error')) {
171       while ($val = $res->fetchRow()) {
172         $result[] = $val;
173       }
174       return $result;
175     }
176     return false;
177   }
178
179   // getActiveProjects - returns an array of active projects for a group.
180   static function getActiveProjects($group_id)
181   {
182     $result = array();
183     $mdb2 = getConnection();
184
185     $sql = "select id, name, description, tasks from tt_projects
186       where group_id = $group_id and status = 1 order by upper(name)";
187     $res = $mdb2->query($sql);
188     $result = array();
189     if (!is_a($res, 'PEAR_Error')) {
190       while ($val = $res->fetchRow()) {
191         $result[] = $val;
192       }
193     }
194     return $result;
195   }
196
197   // The getAllProjects obtains all projects in a group.
198   static function getAllProjects($group_id, $all_fields = false) {
199     $mdb2 = getConnection();
200
201     if ($all_fields)
202       $sql = "select * from tt_projects where group_id = $group_id order by status, upper(name)";
203     else
204       $sql = "select id, name from tt_projects where group_id = $group_id order by status, upper(name)";
205     $res = $mdb2->query($sql);
206     $result = array();
207     if (!is_a($res, 'PEAR_Error')) {
208       while ($val = $res->fetchRow()) {
209         $result[] = $val;
210       }
211       return $result;
212     }
213     return false;
214   }
215
216   // getActiveTasks - returns an array of active tasks for a group.
217   static function getActiveTasks($group_id)
218   {
219     $result = array();
220     $mdb2 = getConnection();
221
222     $sql = "select id, name, description from tt_tasks where group_id = $group_id and status = 1 order by upper(name)";
223     $res = $mdb2->query($sql);
224     $result = array();
225     if (!is_a($res, 'PEAR_Error')) {
226       while ($val = $res->fetchRow()) {
227         $result[] = $val;
228       }
229     }
230     return $result;
231   }
232
233   // getInactiveTasks - returns an array of inactive tasks for a group.
234   static function getInactiveTasks($group_id)
235   {
236     $result = array();
237     $mdb2 = getConnection();
238
239     $sql = "select id, name, description from tt_tasks
240       where group_id = $group_id and status = 0 order by upper(name)";
241     $res = $mdb2->query($sql);
242     $result = array();
243     if (!is_a($res, 'PEAR_Error')) {
244       while ($val = $res->fetchRow()) {
245         $result[] = $val;
246       }
247     }
248     return $result;
249   }
250
251   // The getAllTasks obtains all tasks in a group.
252   static function getAllTasks($group_id, $all_fields = false) {
253     $mdb2 = getConnection();
254
255     if ($all_fields)
256       $sql = "select * from tt_tasks where group_id = $group_id order by status, upper(name)";
257     else
258       $sql = "select id, name from tt_tasks where group_id = $group_id order by status, upper(name)";
259     $res = $mdb2->query($sql);
260     $result = array();
261     if (!is_a($res, 'PEAR_Error')) {
262       while ($val = $res->fetchRow()) {
263         $result[] = $val;
264       }
265       return $result;
266     }
267     return false;
268   }
269
270   // getActiveRolesForUser - returns an array of relevant active roles for user with rank less than self.
271   // "Relevant" means that client roles are filtered out if Client plugin is disabled.
272   static function getActiveRolesForUser()
273   {
274     global $user;
275     $result = array();
276     $mdb2 = getConnection();
277
278     $group_id = $user->getGroup();
279     $org_id = $user->org_id;
280
281     // Determine max rank. If we are working in on behalf group
282     // then rank restriction does not apply.
283     $max_rank = $user->behalfGroup ? MAX_RANK : $user->rank;
284
285     $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and org_id = $org_id and rank < $max_rank and status = 1 order by rank";
286     $res = $mdb2->query($sql);
287     $result = array();
288     if (!is_a($res, 'PEAR_Error')) {
289       while ($val = $res->fetchRow()) {
290         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right.
291         if ($val['is_client'] && !$user->isPluginEnabled('cl'))
292           continue; // Skip adding a client role.
293         $result[] = $val;
294       }
295     }
296     return $result;
297   }
298
299   // getActiveRoles - returns an array of active roles for a group.
300   static function getActiveRoles($group_id)
301   {
302     $result = array();
303     $mdb2 = getConnection();
304
305     $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and status = 1 order by rank";
306     $res = $mdb2->query($sql);
307     $result = array();
308     if (!is_a($res, 'PEAR_Error')) {
309       while ($val = $res->fetchRow()) {
310         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have track_own_time right.
311         $result[] = $val;
312       }
313     }
314     return $result;
315   }
316
317   // getInactiveRoles - returns an array of inactive roles for a group.
318   static function getInactiveRoles($group_id)
319   {
320     $result = array();
321     $mdb2 = getConnection();
322
323     $sql = "select id, name, rank, description from tt_roles
324       where group_id = $group_id and status = 0 order by rank";
325     $res = $mdb2->query($sql);
326     $result = array();
327     if (!is_a($res, 'PEAR_Error')) {
328       while ($val = $res->fetchRow()) {
329         $result[] = $val;
330       }
331     }
332     return $result;
333   }
334
335   // getInactiveRolesForUser - returns an array of relevant active roles for user with rank less than self.
336   // "Relevant" means that client roles are filtered out if Client plugin is disabled.
337   static function getInactiveRolesForUser()
338   {
339     global $user;
340     $result = array();
341     $mdb2 = getConnection();
342
343     $group_id = $user->getGroup();
344     $org_id = $user->org_id;
345
346     // Determine max rank. If we are working in on behalf group
347     // then rank restriction does not apply.
348     $max_rank = $user->behalfGroup ? MAX_RANK : $user->rank;
349
350     $sql = "select id, name, description, rank, rights from tt_roles where group_id = $group_id and org_id = $org_id and rank < $max_rank and status = 0 order by rank";
351     $res = $mdb2->query($sql);
352     $result = array();
353     if (!is_a($res, 'PEAR_Error')) {
354       while ($val = $res->fetchRow()) {
355         $val['is_client'] = in_array('track_own_time', explode(',', $val['rights'])) ? 0 : 1; // Clients do not have data entry right.
356         if ($val['is_client'] && !$user->isPluginEnabled('cl'))
357           continue; // Skip adding a client role.
358         $result[] = $val;
359       }
360     }
361     return $result;
362   }
363
364   // The getAllClients obtains all clients in a group.
365   static function getAllClients($group_id, $all_fields = false) {
366     $mdb2 = getConnection();
367
368     if ($all_fields)
369       $sql = "select * from tt_clients where group_id = $group_id order by status, upper(name)";
370     else
371       $sql = "select id, name from tt_clients where group_id = $group_id order by status, upper(name)";
372
373     $res = $mdb2->query($sql);
374     $result = array();
375     if (!is_a($res, 'PEAR_Error')) {
376       while ($val = $res->fetchRow()) {
377         $result[] = $val;
378       }
379       return $result;
380     }
381     return false;
382   }
383
384   // The getActiveInvoices returns an array of active invoices for a group.
385   static function getActiveInvoices($localizeDates = true)
386   {
387     global $user;
388     $addPaidStatus = $user->isPluginEnabled('ps');
389
390     $result = array();
391     $mdb2 = getConnection();
392
393     if ($user->isClient())
394       $client_part = " and i.client_id = $user->client_id";
395
396     $sql = "select i.id, i.name, i.date, i.client_id, i.status, c.name as client_name from tt_invoices i
397       left join tt_clients c on (c.id = i.client_id)
398       where i.status = 1 and i.group_id = $user->group_id $client_part order by i.name";
399     $res = $mdb2->query($sql);
400     $result = array();
401     if (!is_a($res, 'PEAR_Error')) {
402       $dt = new DateAndTime(DB_DATEFORMAT);
403       while ($val = $res->fetchRow()) {
404         if ($localizeDates) {
405           $dt->parseVal($val['date']);
406           $val['date'] = $dt->toString($user->date_format);
407         }
408         if ($addPaidStatus)
409           $val['paid'] = ttInvoiceHelper::isPaid($val['id']);
410         $result[] = $val;
411       }
412     }
413     return $result;
414   }
415
416   // The getAllInvoices returns an array of all invoices for a group.
417   static function getAllInvoices()
418   {
419     global $user;
420
421     $result = array();
422     $mdb2 = getConnection();
423
424     $sql = "select * from tt_invoices where group_id = $user->group_id";
425     $res = $mdb2->query($sql);
426     $result = array();
427     if (!is_a($res, 'PEAR_Error')) {
428       $dt = new DateAndTime(DB_DATEFORMAT);
429       while ($val = $res->fetchRow()) {
430         $result[] = $val;
431       }
432     }
433     return $result;
434   }
435
436   // The getRecentInvoices returns an array of recent invoices (max 3) for a client.
437   static function getRecentInvoices($group_id, $client_id)
438   {
439     global $user;
440
441     $result = array();
442     $mdb2 = getConnection();
443
444     $sql = "select i.id, i.name from tt_invoices i
445       left join tt_clients c on (c.id = i.client_id)
446       where i.group_id = $group_id and i.status = 1 and c.id = $client_id
447       order by i.id desc limit 3";
448     $res = $mdb2->query($sql);
449     $result = array();
450     if (!is_a($res, 'PEAR_Error')) {
451       $dt = new DateAndTime(DB_DATEFORMAT);
452       while ($val = $res->fetchRow()) {
453         $result[] = $val;
454       }
455     }
456     return $result;
457   }
458
459   // getUserToProjectBinds - obtains all user to project binds for a group.
460   static function getUserToProjectBinds($group_id) {
461     $mdb2 = getConnection();
462
463     $result = array();
464     $sql = "select * from tt_user_project_binds where user_id in (select id from tt_users where group_id = $group_id) order by user_id, status, project_id";
465     $res = $mdb2->query($sql);
466     $result = array();
467     if (!is_a($res, 'PEAR_Error')) {
468       while ($val = $res->fetchRow()) {
469         $result[] = $val;
470       }
471       return $result;
472     }
473     return false;
474   }
475
476   // The getAllCustomFields obtains all custom fields in a group.
477   static function getAllCustomFields($group_id) {
478     $mdb2 = getConnection();
479
480     $sql = "select * from tt_custom_fields where group_id = $group_id order by status";
481
482     $res = $mdb2->query($sql);
483     $result = array();
484     if (!is_a($res, 'PEAR_Error')) {
485       while ($val = $res->fetchRow()) {
486         $result[] = $val;
487       }
488       return $result;
489     }
490     return false;
491   }
492
493   // The getAllCustomFieldOptions obtains all custom field options in a group.
494   static function getAllCustomFieldOptions($group_id) {
495     $mdb2 = getConnection();
496
497     $sql = "select * from tt_custom_field_options where field_id in (select id from tt_custom_fields where group_id = $group_id) order by id";
498
499     $res = $mdb2->query($sql);
500     $result = array();
501     if (!is_a($res, 'PEAR_Error')) {
502       while ($val = $res->fetchRow()) {
503         $result[] = $val;
504       }
505       return $result;
506     }
507     return false;
508   }
509
510   // The getCustomFieldLog obtains all custom field log entries for a group.
511   static function getCustomFieldLog($group_id) {
512     $mdb2 = getConnection();
513
514     $sql = "select * from tt_custom_field_log where field_id in (select id from tt_custom_fields where group_id = $group_id) order by id";
515
516     $res = $mdb2->query($sql);
517     $result = array();
518     if (!is_a($res, 'PEAR_Error')) {
519       while ($val = $res->fetchRow()) {
520         $result[] = $val;
521       }
522       return $result;
523     }
524     return false;
525   }
526
527   // getFavReports - obtains all favorite reports for all users in a group.
528   static function getFavReports($group_id) {
529     $mdb2 = getConnection();
530
531     $result = array();
532     $sql = "select * from tt_fav_reports where user_id in (select id from tt_users where group_id = $group_id)";
533     $res = $mdb2->query($sql);
534     $result = array();
535     if (!is_a($res, 'PEAR_Error')) {
536       while ($val = $res->fetchRow()) {
537         $result[] = $val;
538       }
539       return $result;
540     }
541     return false;
542   }
543
544   // getExpenseItems - obtains all expense items for all users in a group.
545   static function getExpenseItems($group_id) {
546     $mdb2 = getConnection();
547
548     $result = array();
549     $sql = "select * from tt_expense_items where user_id in (select id from tt_users where group_id = $group_id)";
550     $res = $mdb2->query($sql);
551     $result = array();
552     if (!is_a($res, 'PEAR_Error')) {
553       while ($val = $res->fetchRow()) {
554         $result[] = $val;
555       }
556       return $result;
557     }
558     return false;
559   }
560
561   // getPredefinedExpenses - obtains predefined expenses for a group.
562   static function getPredefinedExpenses($group_id) {
563     global $user;
564     $replaceDecimalMark = ('.' != $user->decimal_mark);
565
566     $mdb2 = getConnection();
567
568     $result = array();
569     $sql = "select id, name, cost from tt_predefined_expenses where group_id = $group_id";
570     $res = $mdb2->query($sql);
571     $result = array();
572     if (!is_a($res, 'PEAR_Error')) {
573       while ($val = $res->fetchRow()) {
574         if ($replaceDecimalMark)
575           $val['cost'] = str_replace('.', $user->decimal_mark, $val['cost']);
576         $result[] = $val;
577       }
578       return $result;
579     }
580     return false;
581   }
582
583   // getNotifications - obtains notification descriptions for a group.
584   static function getNotifications($group_id) {
585     $mdb2 = getConnection();
586
587     $result = array();
588     $sql = "select c.id, c.cron_spec, c.email, c.report_condition, fr.name from tt_cron c
589       left join tt_fav_reports fr on (fr.id = c.report_id)
590       where c.group_id = $group_id and c.status = 1 and fr.status = 1";
591     $res = $mdb2->query($sql);
592     $result = array();
593     if (!is_a($res, 'PEAR_Error')) {
594       while ($val = $res->fetchRow()) {
595         $result[] = $val;
596       }
597       return $result;
598     }
599     return false;
600   }
601
602   // getMonthlyQuotas - obtains monthly quotas for a group.
603   static function getMonthlyQuotas($group_id) {
604     $mdb2 = getConnection();
605
606     $result = array();
607     $sql = "select year, month, minutes from tt_monthly_quotas where group_id = $group_id";
608     $res = $mdb2->query($sql);
609     $result = array();
610     if (!is_a($res, 'PEAR_Error')) {
611       while ($val = $res->fetchRow()) {
612         $result[] = $val;
613       }
614       return $result;
615     }
616     return false;
617   }
618
619   // The delete function permanently deletes all data for a group.
620   static function delete($group_id) {
621     $mdb2 = getConnection();
622
623     // Delete users.
624     $sql = "select id from tt_users where group_id = $group_id";
625     $res = $mdb2->query($sql);
626     if (is_a($res, 'PEAR_Error')) return false;
627     while ($val = $res->fetchRow()) {
628       $user_id = $val['id'];
629       if (!ttUserHelper::delete($user_id)) return false;
630     }
631
632     // Delete tasks.
633     if (!ttTeamHelper::deleteTasks($group_id)) return false;
634
635     // Delete client to project binds.
636     $sql = "delete from tt_client_project_binds where client_id in (select id from tt_clients where group_id = $group_id)";
637     $affected = $mdb2->exec($sql);
638     if (is_a($affected, 'PEAR_Error')) return false;
639
640     // Delete projects.
641     $sql = "delete from tt_projects where group_id = $group_id";
642     $affected = $mdb2->exec($sql);
643     if (is_a($affected, 'PEAR_Error')) return false;
644
645     // Delete clients.
646     $sql = "delete from tt_clients where group_id = $group_id";
647     $affected = $mdb2->exec($sql);
648     if (is_a($affected, 'PEAR_Error')) return false;
649
650     // Delete invoices.
651     $sql = "delete from tt_invoices where group_id = $group_id";
652     $affected = $mdb2->exec($sql);
653     if (is_a($affected, 'PEAR_Error')) return false;
654
655     // Delete custom fields.
656     if (!ttTeamHelper::deleteCustomFields($group_id)) return false;
657
658     // Delete roles.
659     $sql = "delete from tt_roles where group_id = $group_id";
660     $affected = $mdb2->exec($sql);
661     if (is_a($affected, 'PEAR_Error')) return false;
662
663     // Delete cron entries.
664     $sql = "delete from tt_cron where group_id = $group_id";
665     $affected = $mdb2->exec($sql);
666     if (is_a($affected, 'PEAR_Error')) return false;
667
668     // Delete predefined expenses.
669     $sql = "delete from tt_predefined_expenses where group_id = $group_id";
670     $affected = $mdb2->exec($sql);
671     if (is_a($affected, 'PEAR_Error')) return false;
672
673     // Delete monthly quotas.
674     $sql = "delete from tt_monthly_quotas where group_id = $group_id";
675     $affected = $mdb2->exec($sql);
676     if (is_a($affected, 'PEAR_Error')) return false;
677
678     // Delete group.
679     $sql = "delete from tt_groups where id = $group_id";
680     $affected = $mdb2->exec($sql);
681     if (is_a($affected, 'PEAR_Error')) return false;
682
683     return true;
684   }
685
686   // The deleteTasks deletes all tasks and task binds for an inactive group.
687   static function deleteTasks($group_id) {
688     $mdb2 = getConnection();
689     $sql = "select id from tt_tasks where group_id = $group_id";
690     $res = $mdb2->query($sql);
691     if (is_a($res, 'PEAR_Error')) return false;
692
693     while ($val = $res->fetchRow()) {
694
695       // Delete task binds.
696       $task_id = $val['id'];
697       $sql = "delete from tt_project_task_binds where task_id = $task_id";
698       $affected = $mdb2->exec($sql);
699       if (is_a($affected, 'PEAR_Error')) return false;
700
701       // Delete task.
702       $sql = "delete from tt_tasks where id = $task_id";
703       $affected = $mdb2->exec($sql);
704       if (is_a($affected, 'PEAR_Error')) return false;
705     }
706
707     return true;
708   }
709
710   // The deleteCustomFields cleans up tt_custom_field_log, tt_custom_field_options and tt_custom_fields tables for an inactive group.
711   static function deleteCustomFields($group_id) {
712     $mdb2 = getConnection();
713     $sql = "select id from tt_custom_fields where group_id = $group_id";
714     $res = $mdb2->query($sql);
715     if (is_a($res, 'PEAR_Error')) return false;
716
717     while ($val = $res->fetchRow()) {
718       $field_id = $val['id'];
719
720       // Clean up tt_custom_field_log.
721       $sql = "delete from tt_custom_field_log where field_id = $field_id";
722       $affected = $mdb2->exec($sql);
723       if (is_a($affected, 'PEAR_Error')) return false;
724
725       // Clean up tt_custom_field_options.
726       $sql = "delete from tt_custom_field_options where field_id = $field_id";
727       $affected = $mdb2->exec($sql);
728       if (is_a($affected, 'PEAR_Error')) return false;
729
730       // Delete custom field.
731       $sql = "delete from tt_custom_fields where id = $field_id";
732       $affected = $mdb2->exec($sql);
733       if (is_a($affected, 'PEAR_Error')) return false;
734     }
735
736     return true;
737   }
738 }