From 8e3a6039cfefb8f351d2696ebdcfa26cc5d4cef9 Mon Sep 17 00:00:00 2001 From: thomascube <thomas@roundcube.net> Date: Tue, 13 Apr 2010 03:24:09 -0400 Subject: [PATCH] Assign newly created contacts to the active group (#1486626) and fix group selection display (#1486619) --- program/include/rcube_contacts.php | 259 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 242 insertions(+), 17 deletions(-) diff --git a/program/include/rcube_contacts.php b/program/include/rcube_contacts.php index 23f86e8..dd37972 100644 --- a/program/include/rcube_contacts.php +++ b/program/include/rcube_contacts.php @@ -39,8 +39,10 @@ /** public properties */ var $primary_key = 'contact_id'; var $readonly = false; + var $groups = false; var $list_page = 1; var $page_size = 10; + var $group_id = 0; var $ready = false; @@ -56,6 +58,9 @@ $this->db_name = get_table_name('contacts'); $this->user_id = $user; $this->ready = $this->db && !$this->db->is_error(); + + if (in_array('contactgroups', $this->db->list_tables())) + $this->groups = true; } @@ -82,6 +87,16 @@ /** + * Setter for the current group + * (empty, has to be re-implemented by extending class) + */ + function set_group($gid) + { + $this->group_id = $gid; + } + + + /** * Reset all saved results and search parameters */ function reset() @@ -92,35 +107,72 @@ $this->search_string = null; } + /** + * List all active contact groups of this source + * + * @param string Search string to match group name + * @return array Indexed list of contact groups, each a hash array + */ + function list_groups($search = null) + { + $results = array(); + + if (!$this->groups) + return $results; + + $sql_filter = $search ? "AND " . $this->db->ilike('name', '%'.$search.'%') : ''; + + $sql_result = $this->db->query( + "SELECT * FROM ".get_table_name('contactgroups')." + WHERE del<>1 + AND user_id=? + $sql_filter + ORDER BY name", + $this->user_id); + + while ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) { + $sql_arr['ID'] = $sql_arr['contactgroup_id']; + $results[] = $sql_arr; + } + + return $results; + } /** * List the current set of contact records * - * @param array List of cols to show - * @param int Only return this number of records, use negative values for tail + * @param array List of cols to show + * @param int Only return this number of records, use negative values for tail + * @param boolean True to skip the count query (select only) * @return array Indexed list of contact records, each a hash array */ - function list_records($cols=null, $subset=0) + function list_records($cols=null, $subset=0, $nocount=false) { // count contacts for this user - $this->result = $this->count(); + $this->result = $nocount ? new rcube_result_set(1) : $this->count(); $sql_result = NULL; // get contacts from DB if ($this->result->count) { + if ($this->group_id) + $join = "LEFT JOIN ".get_table_name('contactgroupmembers')." AS m". + " ON (m.contact_id=c.".$this->primary_key.")"; + $start_row = $subset < 0 ? $this->result->first + $this->page_size + $subset : $this->result->first; $length = $subset != 0 ? abs($subset) : $this->page_size; $sql_result = $this->db->limitquery( - "SELECT * FROM ".$this->db_name." - WHERE del<>1 - AND user_id=?" . + "SELECT * FROM ".$this->db_name." AS c ".$join." + WHERE c.del<>1 + AND c.user_id=?" . + ($this->group_id ? " AND m.contactgroup_id=?" : ""). ($this->filter ? " AND (".$this->filter.")" : "") . - " ORDER BY name", + " ORDER BY c.name", $start_row, $length, - $this->user_id); + $this->user_id, + $this->group_id); } while ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) @@ -131,6 +183,9 @@ $sql_arr['name'] = $sql_arr['email']; $this->result->add($sql_arr); } + + if ($nocount) + $this->result->count = count($this->result->records); return $this->result; } @@ -143,9 +198,10 @@ * @param string Search value * @param boolean True for strict (=), False for partial (LIKE) matching * @param boolean True if results are requested, False if count only + * @param boolean True to skip the count query (select only) * @return Indexed list of contact records and 'count' value */ - function search($fields, $value, $strict=false, $select=true) + function search($fields, $value, $strict=false, $select=true, $nocount=false) { if (!is_array($fields)) $fields = array($fields); @@ -156,7 +212,7 @@ if ($col == 'ID' || $col == $this->primary_key) { $ids = !is_array($value) ? explode(',', $value) : $value; - $add_where[] = $this->primary_key.' IN ('.join(',', $ids).')'; + $add_where[] = 'c.' . $this->primary_key.' IN ('.join(',', $ids).')'; } else if ($strict) $add_where[] = $this->db->quoteIdentifier($col).'='.$this->db->quote($value); @@ -168,7 +224,7 @@ { $this->set_search_set(join(' OR ', $add_where)); if ($select) - $this->list_records(); + $this->list_records(null, 0, $nocount); else $this->result = $this->count(); } @@ -184,14 +240,20 @@ */ function count() { + if ($this->group_id) + $join = "LEFT JOIN ".get_table_name('contactgroupmembers')." AS m". + " ON (m.contact_id=c.".$this->primary_key.")"; + // count contacts for this user $sql_result = $this->db->query( - "SELECT COUNT(contact_id) AS rows - FROM ".$this->db_name." - WHERE del<>1 - AND user_id=?". + "SELECT COUNT(c.contact_id) AS rows + FROM ".$this->db_name." AS c ".$join." + WHERE c.del<>1 + AND c.user_id=?". + ($this->group_id ? " AND m.contactgroup_id=?" : ""). ($this->filter ? " AND (".$this->filter.")" : ""), - $this->user_id); + $this->user_id, + $this->group_id); $sql_arr = $this->db->fetch_assoc($sql_result); return new rcube_result_set($sql_arr['rows'], ($this->list_page-1) * $this->page_size);; @@ -274,6 +336,10 @@ $insert_id = $this->db->insert_id('contacts'); } + + // also add the newly created contact to the active group + if ($insert_id && $this->group_id) + $this->add_to_group($this->group_id, $insert_id); return $insert_id; } @@ -337,6 +403,13 @@ if (is_array($ids)) $ids = join(',', $ids); + // delete all group members linked with these contacts + if ($this->groups) { + $this->db->query( + "DELETE FROM ".get_table_name('contactgroupmembers')." + WHERE contact_id IN (".$ids.")"); + } + $this->db->query( "UPDATE ".$this->db_name." SET del=1 @@ -357,4 +430,156 @@ return $this->db->affected_rows(); } + + /** + * Create a contact group with the given name + * + * @param string The group name + * @return False on error, array with record props in success + */ + function create_group($name) + { + $result = false; + + // make sure we have a unique name + $name = $this->unique_groupname($name); + + $this->db->query( + "INSERT INTO ".get_table_name('contactgroups')." (user_id, changed, name) + VALUES (".intval($this->user_id).", ".$this->db->now().", ".$this->db->quote($name).")" + ); + + if ($insert_id = $this->db->insert_id('contactgroups')) + $result = array('id' => $insert_id, 'name' => $name); + + return $result; + } + + /** + * Delete the given group and all linked group members + * + * @param string Group identifier + * @return boolean True on success, false if no data was changed + */ + function delete_group($gid) + { + $sql_result = $this->db->query( + "DELETE FROM ".get_table_name('contactgroupmembers')." + WHERE contactgroup_id=?", + $gid); + + $sql_result = $this->db->query( + "UPDATE ".get_table_name('contactgroups')." + SET del=1, changed=".$this->db->now()." + WHERE contactgroup_id=?", + $gid); + + return $this->db->affected_rows(); + } + + /** + * Rename a specific contact group + * + * @param string Group identifier + * @param string New name to set for this group + * @return boolean New name on success, false if no data was changed + */ + function rename_group($gid, $newname) + { + // make sure we have a unique name + $name = $this->unique_groupname($newname); + + $sql_result = $this->db->query( + "UPDATE ".get_table_name('contactgroups')." + SET name=".$this->db->quote($name).", changed=".$this->db->now()." + WHERE contactgroup_id=?", + $gid); + + return $this->db->affected_rows() ? $name : false; + } + + /** + * Add the given contact records the a certain group + * + * @param string Group identifier + * @param array List of contact identifiers to be added + * @return int Number of contacts added + */ + function add_to_group($group_id, $ids) + { + if (!is_array($ids)) + $ids = explode(',', $ids); + + $added = 0; + + foreach ($ids as $contact_id) { + $sql_result = $this->db->query( + "SELECT 1 FROM ".get_table_name('contactgroupmembers')." + WHERE contactgroup_id=? + AND contact_id=?", + $group_id, + $contact_id); + + if (!$this->db->num_rows($sql_result)) { + $this->db->query( + "INSERT INTO ".get_table_name('contactgroupmembers')." (contactgroup_id, contact_id, created) + VALUES (".intval($group_id).", ".intval($contact_id).", ".$this->db->now().")" + ); + if (!$this->db->db_error) + $added++; + } + } + + return $added; + } + + + /** + * Remove the given contact records from a certain group + * + * @param string Group identifier + * @param array List of contact identifiers to be removed + * @return int Number of deleted group members + */ + function remove_from_group($group_id, $ids) + { + if (!is_array($ids)) + $ids = explode(',', $ids); + + $sql_result = $this->db->query( + "DELETE FROM ".get_table_name('contactgroupmembers')." + WHERE contactgroup_id=? + AND contact_id IN (".join(',', array_map(array($this->db, 'quote'), $ids)).")", + $group_id); + + return $this->db->affected_rows(); + } + + /** + * Check for existing groups with the same name + * + * @param string Name to check + * @return string A group name which is unique for the current use + */ + private function unique_groupname($name) + { + $checkname = $name; + $num = 2; $hit = false; + + do { + $sql_result = $this->db->query( + "SELECT 1 FROM ".get_table_name('contactgroups')." + WHERE del<>1 + AND user_id=? + AND name LIKE ?", + $this->user_id, + $checkname); + + // append number to make name unique + if ($hit = $this->db->num_rows($sql_result)) + $checkname = $name . ' ' . $num++; + } while ($hit > 0); + + return $checkname; + } } -- Gitblit v1.9.1