X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Faddressbook.php;h=fa53c7e30c5e591f678331c921b1de314ec45640;hb=4afa7206a144844010fde445235b2ee752de8692;hp=738be3ffa7d0d11ecd209a5fd39d65569fc7c9e7;hpb=0d273153834be125b51772ca39ffdcbda213b7e1;p=squirrelmail.git diff --git a/functions/addressbook.php b/functions/addressbook.php index 738be3ff..fa53c7e3 100644 --- a/functions/addressbook.php +++ b/functions/addressbook.php @@ -5,13 +5,18 @@ ** ** Functions and classes for the addressbook system. ** + ** $Id$ **/ $addressbook_php = true; // Include backends here. - include("../functions/abook_local_file.php"); - include("../functions/abook_ldap_server.php"); + include('../functions/abook_local_file.php'); + include('../functions/abook_ldap_server.php'); + + // Un-comment if you're using database backend + // include('../functions/abook_database.php'); + // Create and initialize an addressbook object. // Returns the created object @@ -22,35 +27,65 @@ $abook = new AddressBook; // Always add a local backend - $filename = sprintf("%s%s.abook", $data_dir, $username); - $r = $abook->add_backend("local_file", Array("filename" => $filename, - "create" => true)); + + // Use *either* file-based *or* database addressbook. Remove + // and insert comments to enable the one you want. + + // ------ BEGIN Initialize file-based personal addressbook ------ + $filename = sprintf('%s%s.abook', $data_dir, $username); + $r = $abook->add_backend('local_file', Array('filename' => $filename, + 'create' => true)); + if(!$r && $showerr) { printf(_("Error opening file %s"), $filename); exit; } + // ------ END Initialize file-based personal addressbook ------ + + // ------ BEGIN Initialize database-based personal addressbook ------ + // $r = $abook->add_backend('database', Array('dsn' => 'mysql://dbuser@host/dbname', + // 'owner' => $username, + // 'table' => 'address')); + // if(!$r && $showerr) { + // printf(_("Error initializing addressbook: %s"), $filename); + // exit; + // } + // ------ END Initialize database-based personal addressbook ------ if($onlylocal) return $abook; - // Load configured LDAP servers - reset($ldap_server); - while(list($key,$param) = each($ldap_server)) { - if(is_array($param)) { - $r = $abook->add_backend("ldap_server", $param); - if(!$r && $showerr) { - printf(" "._("Error initializing LDAP server %s:")."
\n", - $param["host"]); - printf(" ".$abook->error); - exit; - } - } + // Load configured LDAP servers (if PHP has LDAP support) + if(isset($ldap_server) && is_array($ldap_server) && + function_exists('ldap_connect')) { + reset($ldap_server); + while(list($undef,$param) = each($ldap_server)) { + if(is_array($param)) { + $r = $abook->add_backend('ldap_server', $param); + if(!$r && $showerr) { + printf(' ' . _("Error initializing LDAP server %s:") . + "
\n", $param['host']); + print(' ' . $abook->error); + exit; + } + } + } } // Return the initialized object return $abook; } + + // Had to move this function outside of the Addressbook Class + // PHP 4.0.4 Seemed to be having problems with inline functions. + function addressbook_cmp($a,$b) { + if($a['backend'] > $b['backend']) + return 1; + else if($a['backend'] < $b['backend']) + return -1; + return (strtolower($a['name']) > strtolower($b['name'])) ? 1 : -1; + } /** @@ -58,18 +93,22 @@ ** backends and provide services to the functions above. ** **/ + class AddressBook { var $backends = array(); var $numbackends = 0; - var $error = ""; + var $error = ''; + var $localbackend = 0; + var $localbackendname = ''; // Constructor function. function AddressBook() { + $localbackendname = _("Personal address book"); } // Return an array of backends of a given type, // or all backends if no type is specified. - function get_backend_list($type = "") { + function get_backend_list($type = '') { $ret = array(); for($i = 1 ; $i <= $this->numbackends ; $i++) { if(empty($type) || $type == $this->backends[$i]->btype) { @@ -86,9 +125,9 @@ // (without the abook_ prefix), and $param is an optional // mixed variable that is passed to the backend constructor. // See each of the backend classes for valid parameters. - function add_backend($backend, $param = "") { - $backend_name = "abook_".$backend; - eval("\$newback = new $backend_name(\$param);"); + function add_backend($backend, $param = '') { + $backend_name = 'abook_' . $backend; + eval('$newback = new ' . $backend_name . '($param);'); if(!empty($newback->error)) { $this->error = $newback->error; return false; @@ -98,72 +137,92 @@ $newback->bnum = $this->numbackends; $this->backends[$this->numbackends] = $newback; + + // Store ID of first local backend added + if($this->localbackend == 0 && $newback->btype == 'local') { + $this->localbackend = $this->numbackends; + $this->localbackendname = $newback->sname; + } + return $this->numbackends; } // Return a list of addresses matching expression in // all backends of a given type. - function search($expression, $btype = "") { + function search($expression, $bnum = -1) { $ret = array(); - $this->error = ""; - - $sel = $this->get_backend_list($btype); - $failed = 0; - for($i = 0 ; $i < sizeof($sel) ; $i++) { - $backend = &$sel[$i]; - $backend->error = ""; - $res = $backend->search($expression); - if(is_array($res)) { - $ret = array_merge($ret, $res); - } else { - $this->error = $this->error . "
\n". $backend->error; - $failed++; + $this->error = ''; + + // Search all backends + if($bnum == -1) { + $sel = $this->get_backend_list(''); + $failed = 0; + for($i = 0 ; $i < sizeof($sel) ; $i++) { + $backend = &$sel[$i]; + $backend->error = ''; + $res = $backend->search($expression); + if(is_array($res)) { + $ret = array_merge($ret, $res); + } else { + $this->error .= "
\n" . $backend->error; + $failed++; + } } + + // Only fail if all backends failed + if($failed >= sizeof($sel)) + return false; + } - // Only fail if all backends failed - if($failed >= sizeof($sel)) - return false; + // Search only one backend + else { + $ret = $this->backends[$bnum]->search($expression); + if(!is_array($ret)) { + $this->error .= "
\n" . $this->backends[$bnum]->error; + return false; + } + } return $ret; } - + // Return a sorted search - function s_search($expression, $btype = "") { - - $ret = $this->search($expression, $btype); - if(!is_array($ret)) - return $ret; - - // Inline function - Not nice, but still.. - function cmp($a,$b) { - if($a["backend"] > $b["backend"]) - return 1; - else if($a["backend"] < $b["backend"]) - return -1; - - return (strtolower($a["name"]) > strtolower($b["name"])) ? 1 : -1; - } - - usort($ret, 'cmp'); - return $ret; + function s_search($expression, $bnum = -1) { + + $ret = $this->search($expression, $bnum); + if(!is_array($ret)) + return $ret; + usort($ret, 'addressbook_cmp'); + return $ret; } // Lookup an address by alias. Only possible in // local backends. - function lookup($alias) { + function lookup($alias, $bnum = -1) { $ret = array(); - $sel = $this->get_backend_list("local"); + if($bnum > -1) { + $res = $this->backends[$bnum]->lookup($alias); + if(is_array($res)) { + return $res; + } else { + $this->error = $backend->error; + return false; + } + } + + $sel = $this->get_backend_list('local'); for($i = 0 ; $i < sizeof($sel) ; $i++) { $backend = &$sel[$i]; - $backend->error = ""; + $backend->error = ''; $res = $backend->lookup($alias); if(is_array($res)) { - return $res; + if(!empty($res)) + return $res; } else { $this->error = $backend->error; return false; @@ -175,13 +234,17 @@ // Return all addresses - function list_addr() { + function list_addr($bnum = -1) { $ret = array(); - $sel = $this->get_backend_list("local"); + if($bnum == -1) + $sel = $this->get_backend_list('local'); + else + $sel = array(0 => &$this->backends[$bnum]); + for($i = 0 ; $i < sizeof($sel) ; $i++) { $backend = &$sel[$i]; - $backend->error = ""; + $backend->error = ''; $res = $backend->list_addr(); if(is_array($res)) { $ret = array_merge($ret, $res); @@ -205,17 +268,22 @@ $this->error = _("Invalid input data"); return false; } - if(empty($userdata["fullname"]) && - empty($userdata["lastname"])) { + if(empty($userdata['firstname']) && + empty($userdata['lastname'])) { $this->error = _("Name is missing"); return false; } - if(empty($userdata["email"])) { + if(empty($userdata['email'])) { $this->error = _("E-mail address is missing"); return false; } - if(empty($userdata["nickname"])) { - $userdata["nickname"] = $userdata["email"]; + if(empty($userdata['nickname'])) { + $userdata['nickname'] = $userdata['email']; + } + + if(eregi('[ \\:\\|\\#\\"\\!]', $userdata['nickname'])) { + $this->error = _("Nickname contain illegal characters"); + return false; } // Check that specified backend accept new entries @@ -234,10 +302,92 @@ } return false; // Not reached - } + } // end of add() - } + // Remove the user identified by $alias from backend $bnum + // If $alias is an array, all users in the array are removed. + function remove($alias, $bnum) { + + // Check input + if(empty($alias)) + return true; + + // Convert string to single element array + if(!is_array($alias)) + $alias = array(0 => $alias); + + // Check that specified backend is writable + if(!$this->backends[$bnum]->writeable) { + $this->error = _("Addressbook is read-only"); + return false; + } + + // Remove user from backend + $res = $this->backends[$bnum]->remove($alias); + if($res) { + return $bnum; + } else { + $this->error = $this->backends[$bnum]->error; + return false; + } + + return false; // Not reached + } // end of remove() + + + // Remove the user identified by $alias from backend $bnum + // If $alias is an array, all users in the array are removed. + function modify($alias, $userdata, $bnum) { + + // Check input + if(empty($alias) || !is_string($alias)) + return true; + + // Validate data + if(!is_array($userdata)) { + $this->error = _("Invalid input data"); + return false; + } + if(empty($userdata['firstname']) && + empty($userdata['lastname'])) { + $this->error = _("Name is missing"); + return false; + } + if(empty($userdata['email'])) { + $this->error = _("E-mail address is missing"); + return false; + } + + if(eregi('[\\: \\|\\#"\\!]', $userdata['nickname'])) { + $this->error = _("Nickname contain illegal characters"); + return false; + } + + if(empty($userdata['nickname'])) { + $userdata['nickname'] = $userdata['email']; + } + + // Check that specified backend is writable + if(!$this->backends[$bnum]->writeable) { + $this->error = _("Addressbook is read-only");; + return false; + } + + // Modify user in backend + $res = $this->backends[$bnum]->modify($alias, $userdata); + if($res) { + return $bnum; + } else { + $this->error = $this->backends[$bnum]->error; + return false; + } + + return false; // Not reached + } // end of modify() + + + } // End of class Addressbook /** ** Generic backend that all other backends extend @@ -245,18 +395,18 @@ class addressbook_backend { // Variables that all backends must provide. - var $btype = "dummy"; - var $bname = "dummy"; - var $sname = "Dummy backend"; + var $btype = 'dummy'; + var $bname = 'dummy'; + var $sname = 'Dummy backend'; // Variables common for all backends, but that // should not be changed by the backends. var $bnum = -1; - var $error = ""; + var $error = ''; var $writeable = false; function set_error($string) { - $this->error = "[" . $this->sname . "] " . $string; + $this->error = '[' . $this->sname . '] ' . $string; return false; } @@ -264,22 +414,32 @@ // ========================== Public ======================== function search($expression) { - $this->set_error("search not implemented"); + $this->set_error('search not implemented'); return false; } function lookup($alias) { - $this->set_error("lookup not implemented"); + $this->set_error('lookup not implemented'); return false; } function list_addr() { - $this->set_error("list_addr not implemented"); + $this->set_error('list_addr not implemented'); return false; } function add($userdata) { - $this->set_error("add not implemented"); + $this->set_error('add not implemented'); + return false; + } + + function remove($alias) { + $this->set_error('delete not implemented'); + return false; + } + + function modify($alias, $newuserdata) { + $this->set_error('modify not implemented'); return false; }