Implemented delete group feature in group editor.
[timetracker.git] / WEB-INF / lib / ttGroupHelper.class.php
index 41c0311..a6d5fea 100644 (file)
@@ -100,4 +100,109 @@ class ttGroupHelper {
     return (!is_a($affected, 'PEAR_Error'));
     // TODO: design subgroup roles carefully. Perhaps roles are not to be touched in subgroups at all.
   }
+
+  // markGroupDeleted marks a group and everything in it as deleted.
+  // This function is called in context of a logged on user (global $user object).
+  // It uses current user attributes for access checks and in sql queries.
+  // Compare this with admin:
+  //   admin can delete any group.
+  //   user can delete only relevant groups and only if allowed.
+  static function markGroupDeleted($group_id) {
+    global $user;
+
+    $mdb2 = getConnection();
+    $org_id = $user->org_id;
+
+    // Security check.
+    if (!$user->isGroupValid($group_id))
+      return false;
+
+    // Keep the logic simple by returning false on first error.
+
+    // Obtain subgroups and call self recursively on them.
+    $subgroups = $user->getSubgroups($group_id);
+    foreach($subgroups as $subgroup) {
+      if (!$this->markGroupDeleted($subgroup['id']))
+        return false;
+    }
+
+    // Now do actual work with all entities.
+
+    // Some things cannot be marked deleted as we don't have the status field for them.
+    // Just delete such things (until we have a better way to deal with them).
+    $tables_to_delete_from = array(
+      'tt_config',
+      'tt_predefined_expenses',
+      'tt_client_project_binds',
+      'tt_project_task_binds'
+    );
+    foreach($tables_to_delete_from as $table) {
+      if (!ttGroupHelper::deleteGroupEntriesFromTable($group_id, $table))
+        return false;
+    }
+
+    // Now mark status deleted where we can.
+    // Note: we don't mark tt_log, tt_custom_field_lod, or tt_expense_items deleted here.
+    // Reasoning is:
+    //
+    // 1) Users may mark some of them deleted during their work.
+    // If we mark all of them deleted here, we can't recover nicely
+    // as we'll lose track of what was accidentally deleted by user.
+    //
+    // 2) DB maintenance script (Clean up DB from inactive groups) should
+    // get rid of these items permanently eventually.
+    $tables_to_mark_deleted_in = array(
+      'tt_cron',
+      'tt_fav_reports',
+      // 'tt_expense_items',
+      // 'tt_custom_field_log',
+      'tt_custom_field_options',
+      'tt_custom_fields',
+      // 'tt_log',
+      'tt_invoices',
+      'tt_user_project_binds',
+      'tt_users',
+      'tt_clients',
+      'tt_projects',
+      'tt_tasks',
+      'tt_roles'
+    );
+    foreach($tables_to_mark_deleted_in as $table) {
+      if (!ttGroupHelper::markGroupDeletedInTable($group_id, $table))
+        return false;
+    }
+
+    // Mark group deleted.
+    $sql = "update tt_groups set status = null where id = $group_id and org_id = $org_id";
+    $affected = $mdb2->exec($sql);
+    if (is_a($affected, 'PEAR_Error')) return false;
+
+    return true;
+  }
+
+  // markGroupDeletedInTable is a generic helper function for markGroupDeleted.
+  // It updates ONE table by setting status to NULL for all records belonging to a group.
+  static function markGroupDeletedInTable($group_id, $table_name) {
+    global $user;
+    $mdb2 = getConnection();
+
+    // TODO: add modified info to sql for some tables, depending on table name.
+
+    $org_id = $user->org_id; // The only security measure we use here for match.
+    $sql = "update $table_name set status = null where group_id = $group_id and org_id = $org_id";
+    $affected = $mdb2->exec($sql);
+    return (!is_a($affected, 'PEAR_Error'));
+  }
+
+  // deleteGroupEntriesFromTable is a generic helper function for markGroupDeleted.
+  // It deletes entries in ONE table belonging to a given group.
+  static function deleteGroupEntriesFromTable($group_id, $table_name) {
+    global $user;
+    $mdb2 = getConnection();
+
+    $org_id = $user->org_id; // The only security measure we use here for match.
+    $sql = "delete from $table_name where group_id = $group_id and org_id = $org_id";
+    $affected = $mdb2->exec($sql);
+    return (!is_a($affected, 'PEAR_Error'));
+  }
 }