Adding Shared Contacts to RoundCube Email

After using Roundcube for some time I thought it would be neat to expand the Addressbook functionality to include things like actual physical addresses and phone numbers to each contact record. Additionally, since Roundcube is a hosted email solution, I thought it would be nice to be able to share contacts amongst other users on the same system. By adding a flag to each record, users can share their contacts amongst one another. This is nice because it cuts down on duplicate records and allows people to look up contact information with less work.

To modify RoundCube Email to allow for expanded contacts you first need to create new fields in the database. Here are the MySQL commands, but I’m sure you can replicate them through another interface:

 
ALTER TABLE contacts ADD COLUMN phone VARCHAR(20) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN mobile VARCHAR(20) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN work VARCHAR(20) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN fax VARCHAR(20) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN address1 VARCHAR(50) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN address2 VARCHAR(50) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN city VARCHAR(50) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN state VARCHAR(50) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN zip VARCHAR(11) DEFAULT NULL;
ALTER TABLE contacts ADD COLUMN is_shared TINYINT(4) DEFAULT 0;

Next you have to modify a bunch of the files to enable the new fields and the sharing.

in roundcube/program/localization/en_US/labels.inc after the line:

 
$labesl['email'] = 'E-Mail';

add the following labels:

$labels['phone']     = 'Phone';
$labels['mobile']     = 'Mobile';
$labels['fax']         = 'Fax';
$labels['work']         = 'Work';
$labels['address1']     = 'Address';
$labels['address2']     = ' ';
$labels['city']         = 'City';
$labels['state']     = 'State';
$labels['zip']         = 'Zip';
$labels['is_shared'] = 'Shared Contact?'; 

Next:

In the file roundcube/program/steps/addressbook/edit.inc

change the line that reads:

$DB->query("SELECT * FROM ".get_table_name('contacts')."
WHERE  contact_id=?
AND    user_id=?
AND    del<>1″,
$cid,
$_SESSION[’user_id’]);

to:

 
$DB->query("SELECT * FROM ".get_table_name('contacts')."
WHERE  contact_id=?
AND    ( user_id=? OR is_shared = '1')
AND    del<>1″,
$cid,
$_SESSION[’user_id’]);

Change the line that reads:

$a_show_cols = array('name', 'firstname', 'surname', 'email');

to:

$a_show_cols = array('name', 'firstname', 'surname', 'email', 'phone', 'mobile', 'work', 'fax', 'address1', 'address2', 'city', 'state', 'zip', 'is_shared'); 

After the line:

 $title = rcube_label($col); 

add the following:

if ($col == 'is_shared')
$type = 'checkbox';
else
$type = ''; 

Change the line:

 
$value = rcmail_get_edit_field($col, $CONTACT_RECORD[$col], $attrib);

to:

 
$value = rcmail_get_edit_field($col, $CONTACT_RECORD[$col], $attrib, $type);

In the file roundcube/program/steps/addressbook/save.inc change the line that reads:

 
$a_save_cols = array('name', 'firstname', 'surname', 'email');

to:

 
$a_save_cols = array('name', 'firstname', 'surname', 'email', 'phone', 'mobile', 'work', 'fax', 'address1', 'address2', 'city', 'state', 'zip',
'is_shared');

Change the line:

 
$DB->query("UPDATE $contacts_table
SET    changed=now(), ".join(', ', $a_write_sql)."
WHERE  contact_id=?
AND    user_id=?
AND    del<>1″,
$_POST[’_cid’],
$_SESSION[’user_id’]);

to:

 
$DB->query("UPDATE $contacts_table
SET    changed=now(), ".join(', ', $a_write_sql)."
WHERE  contact_id=?
AND    ( user_id=? OR is_shared = '1')
AND    del<>1″,
$_POST[’_cid’],
$_SESSION[’user_id’]);

change the line:

 
$sql_result = $DB->query("SELECT * FROM $contacts_table
WHERE  contact_id=?
AND    user_id=?
AND    del<>1″,
$_POST[’_cid’],
$_SESSION[’user_id’]);

to:

 
$sql_result = $DB->query("SELECT * FROM $contacts_table
WHERE  contact_id=?
AND    ( user_id=? OR is_shared = '1')
AND    del<>1″,
$_POST[’_cid’],
$_SESSION[’user_id’]);

change the line:

 
$sql = "SELECT 1 FROM $contacts_table
WHERE  user_id = {$_SESSION['user_id']}
AND del <> ‘1′ “;

to:

$sql = "SELECT 1 FROM $contacts_table
WHERE  (user_id = {$_SESSION['user_id']} OR is_shared = 1)
AND del <> ‘1′ “;

change the line:

 
$sql_result = $DB->query("SELECT * FROM $contacts_table
WHERE  contact_id=?
AND user_id=?",
$insert_id,
$_SESSION['user_id']);

to:

 
$sql_result = $DB->query("SELECT * FROM $contacts_table
WHERE  contact_id=?
AND    ( user_id=? OR is_shared = '1')",
$insert_id,
$_SESSION['user_id']);

change the line:

 $sql_result = $DB->query("SELECT * FROM $contacts_table
WHERE  contact_id = $id
AND user_id = {$_SESSION['user_id']}");

to:

 
$sql_result = $DB->query("SELECT * FROM $contacts_table
WHERE  contact_id = $id
AND    (user_id    = {$_SESSION['user_id']} or is_shared = 1)");

In the file roundcube/program/steps/addressbook/show.inc

change the line:

 
$DB->query("SELECT * FROM ".get_table_name('contacts')."
WHERE  contact_id=?
AND    user_id=?
AND    del<>1″,
$cid,
$_SESSION[’user_id’]);

to:

 
$DB->query("SELECT * FROM ".get_table_name('contacts')."
WHERE  contact_id=?
AND    ( user_id=? OR is_shared = '1')
AND    del<>1″,
$cid,
$_SESSION[’user_id’]);

change the line:

 
$a_show_cols = array('name', 'firstname', 'surname', 'email');

to:

 
$a_show_cols = array('name', 'firstname', 'surname', 'email', 'phone', 'mobile', 'work', 'fax', 'address1', 'address2', 'city', 'state', 'zip', 'is_shared');

change the line that reads:

 
else
	$value = rep_specialchars_output($CONTACT_RECORD[$col]);

to:

 
elseif ($col=='is_shared')
	$value = ($CONTACT_RECORD[$col] == '1') ? 'Yes' : 'No';
else
	$value = rep_specialchars_output($CONTACT_RECORD[$col]);

In the file roundcube/program/steps/addressbook/list.inc change the line:

 
$sql_result = $DB->query("SELECT COUNT(contact_id) AS rows
FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    user_id=?”,
$_SESSION[’user_id’]);

to:

 
$sql_result = $DB->query("SELECT COUNT(contact_id) AS rows
FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    (user_id=? OR is_shared = 1)”,
$_SESSION[’user_id’]);

change the line:

 $sql_result = $DB->limitquery("SELECT * FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    user_id=?
ORDER BY name”,
$start_row,
$CONFIG[’pagesize’],
$_SESSION[’user_id’]);

to:

 $sql_result = $DB->limitquery("SELECT * FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    (user_id=? OR is_shared = 1)
ORDER BY name”,
$start_row,
$CONFIG[’pagesize’],
$_SESSION[’user_id’]);

In the file roundcube/program/steps/addressbook/func.inc

change the line:

 $sql_result = $DB->query("SELECT COUNT(contact_id) AS rows
FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    user_id=?”,
$_SESSION[’user_id’]);

to:

 $sql_result = $DB->query("SELECT COUNT(contact_id) AS rows
FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    ( user_id=? OR is_shared = ‘1′)”,
$_SESSION[’user_id’]);

change the line:

 $sql_result = $DB->limitquery("SELECT * FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    user_id=?
ORDER BY name”,
$start_row,
$CONFIG[’pagesize’],
$_SESSION[’user_id’]);

to:

 $sql_result = $DB->limitquery("SELECT * FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    ( user_id=? OR is_shared = ‘1′)
ORDER BY name”,
$start_row,
$CONFIG[’pagesize’],
$_SESSION[’user_id’]);

change the line:

 $sql_result = $DB->query("SELECT 1 FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    user_id=?”,
$_SESSION[’user_id’]);

to:

 $sql_result = $DB->query("SELECT 1 FROM ".get_table_name('contacts')."
WHERE  del<>1
AND    ( user_id=? OR is_shared = ‘1′)”,
$_SESSION[’user_id’]);

In the file roundcube/program/steps/addressbook/addcontact.inc

change the line:

 $sql_result = $DB->query("SELECT 1 FROM ".get_table_name('contacts')."
WHERE  user_id=?
AND    email=?
AND    del<>1″,
$_SESSION[’user_id’],$contact[’mailto’]);

to:

 $sql_result = $DB->query("SELECT 1 FROM ".get_table_name('contacts')."
WHERE  ( user_id=? OR is_shared = '1')
AND    email=?
AND    del<>1″,
$_SESSION[’user_id’],$contact[’mailto’]);

In the file roundcube/program/steps/mail/compose.inc

change the line:

 $sql_result = $DB->query("SELECT name, email
FROM ".get_table_name('contacts')."
WHERE user_id=?
AND    del<>1
AND    contact_id IN (”.$_GET[’_to’].”)”,
$_SESSION[’user_id’]);

to:

 $sql_result = $DB->query("SELECT name, email
FROM ".get_table_name('contacts')."
WHERE ( user_id=? OR is_shared = '1')
AND    del<>1
AND    contact_id IN (”.$_GET[’_to’].”)”,
$_SESSION[’user_id’]);

change the line:

 $sql_result = $DB->query("SELECT name, email
FROM ".get_table_name('contacts')." WHERE  user_id=?
AND  del<>1″,$_SESSION[’user_id’]);

to:

 $sql_result = $DB->query("SELECT name, email
FROM ".get_table_name('contacts')." WHERE  ( user_id=? OR is_shared = '1')
AND  del<>1″,$_SESSION[’user_id’]);

And you’re done :) I’m sure you see that most of this is simply to include the shared contacts feature.

Great Mod

Thanks for the great instructions. When i started following them I realized it was for the older version of RoundCube than I had installed, but after poking around the php files (I don't know php) I found the relevant parts in the new files and managed to get it to work 95% - which is enough! Great job...

Now I wonder why your excellent mod wasn't put in RoundCube? You didn't contribute this to the code? It's a HUGE feature that many people are looking for.... I googled for a long time before finding your site.

I think RoundCube is abandoned

I would have contributed my mod but I think the roundcube project has been abandoned (or that's the latest I heard). You're right though, I need to get it working on the new version!

[edit]
I was wrong, according to the project website (http://roundcube.net) the project was last updated 2007-07-03. I'm going to download and mod the latest copy then I'll post new instructions.

Help

Hi, since i am using the new RC i am facing problems to find out the codes because some of them they do not exists the older place so can u tell me the new
places of the lines in new version of RC for example the following line does not exists in edit.inc

$DB->query("SELECT * FROM ".get_table_name('contacts')."
WHERE contact_id=?
AND user_id=?
AND del<>1″,
$cid,
$_SESSION[’user_id’]);

help please

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <abbr> <acronym> <pre> <h1> <h2> <h3> <h4> <img>
  • Lines and paragraphs break automatically.

More information about formatting options