[Svn] r3425 - in trunk/roundcubemail: . SQL config program/include program/js program/localization/de_CH program/localization/en_US program/steps/addressbook program/steps/mail skins/default skins/default/images skins/default/images/icons skins/default/templates

trac at roundcube.net trac at roundcube.net
Fri Mar 26 17:38:21 CET 2010


Author: thomasb
Date: 2010-03-26 11:38:20 -0500 (Fri, 26 Mar 2010)
New Revision: 3425

Added:
   trunk/roundcubemail/program/steps/addressbook/groups.inc
   trunk/roundcubemail/skins/default/images/icons/groupactions.png
Modified:
   trunk/roundcubemail/CHANGELOG
   trunk/roundcubemail/SQL/mysql.initial.sql
   trunk/roundcubemail/SQL/mysql.update.sql
   trunk/roundcubemail/SQL/sqlite.initial.sql
   trunk/roundcubemail/SQL/sqlite.update.sql
   trunk/roundcubemail/config/db.inc.php.dist
   trunk/roundcubemail/index.php
   trunk/roundcubemail/program/include/rcmail.php
   trunk/roundcubemail/program/include/rcube_addressbook.php
   trunk/roundcubemail/program/include/rcube_contacts.php
   trunk/roundcubemail/program/js/app.js
   trunk/roundcubemail/program/localization/de_CH/labels.inc
   trunk/roundcubemail/program/localization/de_CH/messages.inc
   trunk/roundcubemail/program/localization/en_US/labels.inc
   trunk/roundcubemail/program/localization/en_US/messages.inc
   trunk/roundcubemail/program/steps/addressbook/func.inc
   trunk/roundcubemail/program/steps/mail/autocomplete.inc
   trunk/roundcubemail/skins/default/addressbook.css
   trunk/roundcubemail/skins/default/functions.js
   trunk/roundcubemail/skins/default/images/icons/folders.png
   trunk/roundcubemail/skins/default/images/listheader.gif
   trunk/roundcubemail/skins/default/mail.css
   trunk/roundcubemail/skins/default/templates/addressbook.html
   trunk/roundcubemail/skins/default/templates/mail.html
Log:
Added basic contact groups feature

Modified: trunk/roundcubemail/CHANGELOG
===================================================================
--- trunk/roundcubemail/CHANGELOG	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/CHANGELOG	2010-03-26 16:38:20 UTC (rev 3425)
@@ -1,6 +1,7 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Added contact groups in address book (not finished yet)
 - Added PageUp/PageDown/Home/End keys support on lists (#1486430)
 - Added possibility to select all messages in a folder (#1484756)
 - Added 'imap_force_caps' option for after-login CAPABILITY checking (#1485750)

Modified: trunk/roundcubemail/SQL/mysql.initial.sql
===================================================================
--- trunk/roundcubemail/SQL/mysql.initial.sql	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/SQL/mysql.initial.sql	2010-03-26 16:38:20 UTC (rev 3425)
@@ -94,7 +94,32 @@
  INDEX `user_contacts_index` (`user_id`,`email`)
 ) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
 
+-- Table structure for table `contactgroups`
 
+CREATE TABLE `contactgroups` (
+  `contactgroup_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+  `changed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `del` tinyint(1) NOT NULL DEFAULT '0',
+  `name` varchar(128) NOT NULL DEFAULT '',
+  PRIMARY KEY(`contactgroup_id`),
+  CONSTRAINT `user_id_fk_contactgroups` FOREIGN KEY (`user_id`)
+    REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+  INDEX `contactgroups_user_index` (`user_id`,`del`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+CREATE TABLE `contactgroupmembers` (
+  `contactgroup_id` int(10) UNSIGNED NOT NULL,
+  `contact_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  PRIMARY KEY (`contactgroup_id`, `contact_id`),
+  CONSTRAINT `contactgroup_id_fk_contactgroups` FOREIGN KEY (`contactgroup_id`)
+    REFERENCES `contactgroups`(`contactgroup_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `contact_id_fk_contacts` FOREIGN KEY (`contact_id`)
+    REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE ON UPDATE CASCADE
+) /*!40000 ENGINE=INNODB */;
+
+
 -- Table structure for table `identities`
 
 CREATE TABLE `identities` (

Modified: trunk/roundcubemail/SQL/mysql.update.sql
===================================================================
--- trunk/roundcubemail/SQL/mysql.update.sql	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/SQL/mysql.update.sql	2010-03-26 16:38:20 UTC (rev 3425)
@@ -83,4 +83,27 @@
 
 ALTER TABLE `identities` ADD INDEX `user_identities_index` (`user_id`, `del`);
 
+CREATE TABLE `contactgroups` (
+  `contactgroup_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
+  `user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+  `changed` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  `del` tinyint(1) NOT NULL DEFAULT '0',
+  `name` varchar(128) NOT NULL DEFAULT '',
+  PRIMARY KEY(`contactgroup_id`),
+  CONSTRAINT `user_id_fk_contactgroups` FOREIGN KEY (`user_id`)
+    REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+  INDEX `contactgroups_user_index` (`user_id`,`del`)
+) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
+
+CREATE TABLE `contactgroupmembers` (
+  `contactgroup_id` int(10) UNSIGNED NOT NULL,
+  `contact_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
+  `created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
+  PRIMARY KEY (`contactgroup_id`, `contact_id`),
+  CONSTRAINT `contactgroup_id_fk_contactgroups` FOREIGN KEY (`contactgroup_id`)
+    REFERENCES `contactgroups`(`contactgroup_id`) ON DELETE CASCADE ON UPDATE CASCADE,
+  CONSTRAINT `contact_id_fk_contacts` FOREIGN KEY (`contact_id`)
+    REFERENCES `contacts`(`contact_id`) ON DELETE CASCADE ON UPDATE CASCADE
+) /*!40000 ENGINE=INNODB */;
+
 /*!40014 SET FOREIGN_KEY_CHECKS=1 */;

Modified: trunk/roundcubemail/SQL/sqlite.initial.sql
===================================================================
--- trunk/roundcubemail/SQL/sqlite.initial.sql	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/SQL/sqlite.initial.sql	2010-03-26 16:38:20 UTC (rev 3425)
@@ -19,7 +19,7 @@
 -- --------------------------------------------------------
 
 -- 
--- Table structure for table contacts
+-- Table structure for table contacts and related
 -- 
 
 CREATE TABLE contacts (
@@ -36,6 +36,26 @@
 
 CREATE INDEX ix_contacts_user_id ON contacts(user_id, email);
 
+
+CREATE TABLE contactgroups (
+  contactgroup_id integer NOT NULL PRIMARY KEY,
+  user_id integer NOT NULL default '0',
+  changed datetime NOT NULL default '0000-00-00 00:00:00',
+  del tinyint NOT NULL default '0',
+  name varchar(128) NOT NULL default ''
+);
+
+CREATE INDEX ix_contactgroups_user_id ON contactgroups(user_id, del);
+
+
+CREATE TABLE contactgroupmembers (
+  contactgroup_id integer NOT NULL,
+  contact_id integer NOT NULL default '0',
+  created datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY (contactgroup_id, contact_id)
+);
+
+
 -- --------------------------------------------------------
 
 -- 

Modified: trunk/roundcubemail/SQL/sqlite.update.sql
===================================================================
--- trunk/roundcubemail/SQL/sqlite.update.sql	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/SQL/sqlite.update.sql	2010-03-26 16:38:20 UTC (rev 3425)
@@ -47,3 +47,21 @@
 
 DROP INDEX ix_identities_user_id;
 CREATE INDEX ix_identities_user_id ON identities (user_id, del);
+
+CREATE TABLE contactgroups (
+  contactgroup_id integer NOT NULL PRIMARY KEY,
+  user_id integer NOT NULL default '0',
+  changed datetime NOT NULL default '0000-00-00 00:00:00',
+  del tinyint NOT NULL default '0',
+  name varchar(128) NOT NULL default ''
+);
+
+CREATE INDEX ix_contactgroups_user_id ON contactgroups(user_id, del);
+
+CREATE TABLE contactgroupmembers (
+  contactgroup_id integer NOT NULL,
+  contact_id integer NOT NULL default '0',
+  created datetime NOT NULL default '0000-00-00 00:00:00',
+  PRIMARY KEY (contactgroup_id, contact_id)
+);
+

Modified: trunk/roundcubemail/config/db.inc.php.dist
===================================================================
--- trunk/roundcubemail/config/db.inc.php.dist	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/config/db.inc.php.dist	2010-03-26 16:38:20 UTC (rev 3425)
@@ -44,6 +44,10 @@
 
 $rcmail_config['db_table_contacts'] = 'contacts';
 
+$rcmail_config['db_table_contactgroups'] = 'contactgroups';
+
+$rcmail_config['db_table_contactgroupmembers'] = 'contactgroupmembers';
+
 $rcmail_config['db_table_session'] = 'session';
 
 $rcmail_config['db_table_cache'] = 'cache';

Modified: trunk/roundcubemail/index.php
===================================================================
--- trunk/roundcubemail/index.php	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/index.php	2010-03-26 16:38:20 UTC (rev 3425)
@@ -217,6 +217,10 @@
   
   'addressbook' => array(
     'add' => 'edit.inc',
+    'create-group' => 'groups.inc',
+    'delete-group' => 'groups.inc',
+    'removefromgroup' => 'groups.inc',
+    'add2group' => 'groups.inc',
   ),
   
   'settings' => array(

Modified: trunk/roundcubemail/program/include/rcmail.php
===================================================================
--- trunk/roundcubemail/program/include/rcmail.php	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/program/include/rcmail.php	2010-03-26 16:38:20 UTC (rev 3425)
@@ -300,19 +300,21 @@
     if ($abook_type != 'ldap') {
       $list['0'] = array(
         'id' => 0,
-	'name' => rcube_label('personaladrbook'),
+        'name' => rcube_label('personaladrbook'),
+        'groups' => true,
         'readonly' => false,
-	'autocomplete' => in_array('sql', $autocomplete)
+        'autocomplete' => in_array('sql', $autocomplete)
       );
     }
 
     if (is_array($ldap_config)) {
       foreach ($ldap_config as $id => $prop)
         $list[$id] = array(
-	  'id' => $id,
-	  'name' => $prop['name'],
-	  'readonly' => !$prop['writable'],
-	  'autocomplete' => in_array('sql', $autocomplete)
+          'id' => $id,
+          'name' => $prop['name'],
+          'groups' => false,
+          'readonly' => !$prop['writable'],
+          'autocomplete' => in_array('sql', $autocomplete)
         );
     }
 

Modified: trunk/roundcubemail/program/include/rcube_addressbook.php
===================================================================
--- trunk/roundcubemail/program/include/rcube_addressbook.php	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/program/include/rcube_addressbook.php	2010-03-26 16:38:20 UTC (rev 3425)
@@ -29,6 +29,7 @@
 {
     /** public properties */
     var $primary_key;
+    var $groups = false;
     var $readonly = true;
     var $ready = false;
     var $list_page = 1;
@@ -63,6 +64,13 @@
     abstract function list_records($cols=null, $subset=0);
 
     /**
+     * List all active contact groups of this source
+     *
+     * @return array  Indexed list of contact groups, each a hash array
+     */
+    function list_groups() { }
+
+    /**
      * Search records
      *
      * @param array   List of fields to search in
@@ -124,6 +132,12 @@
     }
 
     /**
+     * Setter for the current group
+     * (empty, has to be re-implemented by extending class)
+     */
+    function set_group($gid) { }
+
+    /**
      * Create a new contact record
      *
      * @param array Assoziative array with save data

Modified: trunk/roundcubemail/program/include/rcube_contacts.php
===================================================================
--- trunk/roundcubemail/program/include/rcube_contacts.php	2010-03-26 13:44:46 UTC (rev 3424)
+++ trunk/roundcubemail/program/include/rcube_contacts.php	2010-03-26 16:38:20 UTC (rev 3425)
@@ -39,8 +39,10 @@
   /** public properties */
   var $primary_key = 'contact_id';
   var $readonly = false;
+  var $groups = true;
   var $list_page = 1;
   var $page_size = 10;
+  var $group_id = 0;
   var $ready = false;
 
   
@@ -82,6 +84,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,6 +104,32 @@
     $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();
+    $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
@@ -109,18 +147,24 @@
     // get contacts from DB
     if ($this->result->count)
     {
+      if ($this->group_id)
+        $join = "LEFT JOIN ".get_table_name('contactgroupmembers')." AS rcmgrouplinks".
+          " ON (rcmgrouplinks.contact_id=rcmcontacts.".$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 rcmcontacts ".$join."
+         WHERE  rcmcontacts.del<>1
+         AND    rcmcontacts.user_id=?" .
+        ($this->group_id ? " AND rcmgrouplinks.contactgroup_id=?" : "").
         ($this->filter ? " AND (".$this->filter.")" : "") .
-        " ORDER BY name"