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.
 
  11 // | There are only two ways to violate the license:
 
  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).
 
  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).
 
  21 // | This license applies to this document only, not any other software
 
  22 // | that it may be combined with.
 
  24 // +----------------------------------------------------------------------+
 
  26 // | https://www.anuko.com/time_tracker/credits.htm
 
  27 // +----------------------------------------------------------------------+
 
  31   // Definitions of custom field types.
 
  33   const TYPE_TEXT = 1;     // A text field.
 
  34   const TYPE_DROPDOWN = 2; // A dropdown field with pre-defined values.
 
  36   var $fields = array();  // Array of custom fields for group.
 
  37   var $options = array(); // Array of options for a dropdown custom field.
 
  40   function __construct() {
 
  42     $mdb2 = getConnection();
 
  44     $group_id = $user->getGroup();
 
  45     $org_id = $user->org_id;
 
  48     $sql = "select id, type, label, required from tt_custom_fields".
 
  49       " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0";
 
  50     $res = $mdb2->query($sql);
 
  51     if (!is_a($res, 'PEAR_Error')) {
 
  52       while ($val = $res->fetchRow()) {
 
  53         $this->fields[] = array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label'],'required'=>$val['required'],'value'=>'');
 
  57     // If we have a dropdown obtain options for it.
 
  58     if ((count($this->fields) > 0) && ($this->fields[0]['type'] == CustomFields::TYPE_DROPDOWN)) {
 
  60       $sql = "select id, value from tt_custom_field_options".
 
  61         " where field_id = ".$this->fields[0]['id']." and group_id = $group_id and org_id = $org_id and status = 1 order by value";
 
  62       $res = $mdb2->query($sql);
 
  63       if (!is_a($res, 'PEAR_Error')) {
 
  64         while ($val = $res->fetchRow()) {
 
  65           $this->options[$val['id']] = $val['value'];
 
  71   function insert($log_id, $field_id, $option_id, $value) {
 
  73     $mdb2 = getConnection();
 
  75     $group_id = $user->getGroup();
 
  76     $org_id = $user->org_id;
 
  78     $sql = "insert into tt_custom_field_log (group_id, org_id, log_id, field_id, option_id, value)".
 
  79       " values($group_id, $org_id, $log_id, $field_id, ".$mdb2->quote($option_id).", ".$mdb2->quote($value).")";
 
  80     $affected = $mdb2->exec($sql);
 
  81     return (!is_a($affected, 'PEAR_Error'));
 
  84   function update($log_id, $field_id, $option_id, $value) {
 
  86       return true; // Nothing to update.
 
  88     // Remove older custom field values, if any.
 
  89     $res = $this->delete($log_id);
 
  93     if (!$value && !$option_id)
 
  94       return true; // Do not insert NULL values.
 
  96     return $this->insert($log_id, $field_id, $option_id, $value);
 
  99   function delete($log_id) {
 
 101     $mdb2 = getConnection();
 
 103     $group_id = $user->getGroup();
 
 104     $org_id = $user->org_id;
 
 106     $sql = "update tt_custom_field_log set status = null".
 
 107       " where log_id = $log_id and group_id = $group_id and org_id = $org_id";
 
 108     $affected = $mdb2->exec($sql);
 
 109     return (!is_a($affected, 'PEAR_Error'));
 
 112   function get($log_id) {
 
 114     $mdb2 = getConnection();
 
 116     $group_id = $user->getGroup();
 
 117     $org_id = $user->org_id;
 
 119     $sql = "select id, field_id, option_id, value from tt_custom_field_log".
 
 120       " where log_id = $log_id and group_id = $group_id and org_id = $org_id and status = 1";
 
 121     $res = $mdb2->query($sql);
 
 122     if (!is_a($res, 'PEAR_Error')) {
 
 124       while ($val = $res->fetchRow()) {
 
 132   // insertOption adds a new option to a custom field.
 
 133   static function insertOption($field_id, $option_name) {
 
 135     $mdb2 = getConnection();
 
 137     $group_id = $user->getGroup();
 
 138     $org_id = $user->org_id;
 
 140     // Check if the option exists.
 
 142     $sql = "select id from tt_custom_field_options".
 
 143       " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = ".$mdb2->quote($option_name);
 
 144     $res = $mdb2->query($sql);
 
 145     if (is_a($res, 'PEAR_Error'))
 
 147     if ($val = $res->fetchRow()) $id = $val['id'];
 
 151       $sql = "insert into tt_custom_field_options (group_id, org_id, field_id, value)".
 
 152         " values($group_id, $org_id, $field_id, ".$mdb2->quote($option_name).")";
 
 153       $affected = $mdb2->exec($sql);
 
 154       if (is_a($affected, 'PEAR_Error'))
 
 160   // updateOption updates option name.
 
 161   static function updateOption($id, $option_name) {
 
 163     $mdb2 = getConnection();
 
 165     $group_id = $user->getGroup();
 
 166     $org_id = $user->org_id;
 
 168     $sql = "update tt_custom_field_options set value = ".$mdb2->quote($option_name).
 
 169        " where id = $id and group_id = $group_id and org_id = $org_id";
 
 170     $affected = $mdb2->exec($sql);
 
 171     return (!is_a($affected, 'PEAR_Error'));
 
 174   // delete Option deletes an option and all custom field log entries that used it.
 
 175   static function deleteOption($id) {
 
 177     $mdb2 = getConnection();
 
 179     $group_id = $user->getGroup();
 
 180     $org_id = $user->org_id;
 
 182     $field_id = CustomFields::getFieldIdForOption($id);
 
 183     if (!$field_id) return false;
 
 185     // Delete log entries with this option. TODO: why? Research impact.
 
 186     $sql = "update tt_custom_field_log set status = null".
 
 187       " where field_id = $field_id and group_id = $group_id and org_id = $org_id and value = ".$mdb2->quote($id);
 
 188     $affected = $mdb2->exec($sql);
 
 189     if (is_a($affected, 'PEAR_Error'))
 
 192     // Delete the option.
 
 193     $sql = "update tt_custom_field_options set status = null".
 
 194       " where id = $id and group_id = $group_id and org_id = $org_id";
 
 195     $affected = $mdb2->exec($sql);
 
 196     return (!is_a($affected, 'PEAR_Error'));
 
 199   // getOptions returns an array of options for a custom field.
 
 200   static function getOptions($field_id) {
 
 202     $mdb2 = getConnection();
 
 204     $group_id = $user->getGroup();
 
 205     $org_id = $user->org_id;
 
 208     $sql = "select id, value from tt_custom_field_options".
 
 209       " where field_id = $field_id and group_id = $group_id and org_id = $org_id and status = 1 order by value";
 
 210     $res = $mdb2->query($sql);
 
 211     if (!is_a($res, 'PEAR_Error')) {
 
 213       while ($val = $res->fetchRow()) {
 
 214         $options[$val['id']] = $val['value'];
 
 221   // getOptionName returns an option name for a custom field.
 
 222   static function getOptionName($id) {
 
 224     $mdb2 = getConnection();
 
 226     $group_id = $user->getGroup();
 
 227     $org_id = $user->org_id;
 
 229     $sql = "select value from tt_custom_field_options".
 
 230       " where id = $id and group_id = $group_id and org_id = $org_id and status = 1";
 
 231     $res = $mdb2->query($sql);
 
 232     if (!is_a($res, 'PEAR_Error')) {
 
 233       $val = $res->fetchRow();
 
 234       $name = $val['value'];
 
 240   // getFields returns an array of custom fields for group.
 
 241   static function getFields() {
 
 243     $mdb2 = getConnection();
 
 245     $group_id = $user->getGroup();
 
 246     $org_id = $user->org_id;
 
 249     $sql = "select id, type, label from tt_custom_fields".
 
 250       " where group_id = $group_id and org_id = $org_id and status = 1 and type > 0";
 
 251     $res = $mdb2->query($sql);
 
 252     if (!is_a($res, 'PEAR_Error')) {
 
 253       while ($val = $res->fetchRow()) {
 
 254         $fields[] = array('id'=>$val['id'],'type'=>$val['type'],'label'=>$val['label']);
 
 261   // getField returns a custom field.
 
 262   static function getField($id) {
 
 264     $mdb2 = getConnection();
 
 266     $group_id = $user->getGroup();
 
 267     $org_id = $user->org_id;
 
 269     $sql = "select label, type, required from tt_custom_fields".
 
 270       " where id = $id and group_id = $group_id and org_id = $org_id";
 
 271     $res = $mdb2->query($sql);
 
 272     if (!is_a($res, 'PEAR_Error')) {
 
 273       $val = $res->fetchRow();
 
 281   // getFieldIdForOption returns field id from an associated option id.
 
 282   static function getFieldIdForOption($option_id) {
 
 284     $mdb2 = getConnection();
 
 286     $group_id = $user->getGroup();
 
 287     $org_id = $user->org_id;
 
 289     $sql = "select field_id from tt_custom_field_options".
 
 290       " where id = $option_id and group_id = $group_id and org_id = $org_id";
 
 291     $res = $mdb2->query($sql);
 
 292     if (!is_a($res, 'PEAR_Error')) {
 
 293       $val = $res->fetchRow();
 
 294       $field_id = $val['field_id'];
 
 300   // The insertField inserts a custom field for group.
 
 301   static function insertField($field_name, $field_type, $required) {
 
 303     $mdb2 = getConnection();
 
 305     $group_id = $user->getGroup();
 
 306     $org_id = $user->org_id;
 
 308     $sql = "insert into tt_custom_fields (group_id, org_id, type, label, required, status)".
 
 309       " values($group_id, $org_id, $field_type, ".$mdb2->quote($field_name).", $required, 1)";
 
 310     $affected = $mdb2->exec($sql);
 
 311     return (!is_a($affected, 'PEAR_Error'));
 
 314   // The updateField updates custom field for group.
 
 315   static function updateField($id, $name, $type, $required) {
 
 317     $mdb2 = getConnection();
 
 319     $group_id = $user->getGroup();
 
 320     $org_id = $user->org_id;
 
 322     $sql = "update tt_custom_fields set label = ".$mdb2->quote($name).", type = $type, required = $required".
 
 323       " where id = $id and group_id = $group_id and org_id = $org_id";
 
 324     $affected = $mdb2->exec($sql);
 
 325     return (!is_a($affected, 'PEAR_Error'));
 
 328   // The deleteField deletes a custom field, its options and log entries for group.
 
 329   static function deleteField($field_id) {
 
 331     $mdb2 = getConnection();
 
 333     $group_id = $user->getGroup();
 
 334     $org_id = $user->org_id;
 
 336     // Mark log entries as deleted. TODO: why are we doing this? Research impact.
 
 337     $sql = "update tt_custom_field_log set status = null".
 
 338       " where field_id = $field_id and group_id = $group_id and org_id = $org_id";
 
 339     $affected = $mdb2->exec($sql);
 
 340     if (is_a($affected, 'PEAR_Error'))
 
 343     // Mark field options as deleted.
 
 344     $sql = "update tt_custom_field_options set status = null".
 
 345       " where field_id = $field_id and group_id = $group_id and org_id = $org_id";
 
 346     $affected = $mdb2->exec($sql);
 
 347     if (is_a($affected, 'PEAR_Error'))
 
 350     // Mark custom field as deleted.
 
 351     $sql = "update tt_custom_fields set status = null".
 
 352       " where id = $field_id and group_id = $group_id and org_id = $org_id";
 
 353     $affected = $mdb2->exec($sql);
 
 354     return (!is_a($affected, 'PEAR_Error'));