From 4272758c9044ecd074df9013482003b93fbd474c Mon Sep 17 00:00:00 2001 From: tokul Date: Mon, 1 Nov 2004 17:59:53 +0000 Subject: [PATCH] adding phpdoc blocks in addressbook classes (one more backend to go) adding global file based address book support. global_file backend removed (code reuse) administrator plugin still need some mods, but it is dark outside and i'll finish it later. git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@8317 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- config/conf.pl | 61 +++++++++- config/config_default.php | 11 ++ functions/abook_global_file.php | 194 ------------------------------- functions/abook_local_file.php | 85 +++++++++++--- functions/addressbook.php | 197 ++++++++++++++++++++++++++------ 5 files changed, 291 insertions(+), 257 deletions(-) delete mode 100644 functions/abook_global_file.php diff --git a/config/conf.pl b/config/conf.pl index 73781d56..becfae1e 100755 --- a/config/conf.pl +++ b/config/conf.pl @@ -299,6 +299,8 @@ $prefs_val_field = 'prefval' if ( !$prefs_val_field ); $addrbook_global_table = 'global_abook' if ( !$addrbook_global_table ); $addrbook_global_writeable = 'false' if ( !$addrbook_global_writeable ); $addrbook_global_listing = 'false' if ( !$addrbook_global_listing ); +$abook_global_file = '' if ( !$abook_global_file); +$abook_global_file_writeable = 'false' if ( !$abook_global_file_writeable); $use_smtp_tls= 'false' if ( !$use_smtp_tls); $smtp_auth_mech = 'none' if ( !$smtp_auth_mech ); $use_imap_tls = 'false' if ( !$use_imap_tls ); @@ -357,7 +359,7 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) ) { print "3. Folder Defaults\n"; print "4. General Options\n"; print "5. Themes\n"; - print "6. Address Books (LDAP)\n"; + print "6. Address Books\n"; print "7. Message of the Day (MOTD)\n"; print "8. Plugins\n"; print "9. Database\n"; @@ -498,13 +500,14 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) ) { print "\n"; print "R Return to Main Menu\n"; } elsif ( $menu == 6 ) { - print $WHT. "Address Books (LDAP)\n" . $NRM; - print "1. Change Servers\n"; + print $WHT. "Address Books\n" . $NRM; + print "1. Change LDAP Servers\n"; for ( $count = 0 ; $count <= $#ldap_host ; $count++ ) { print " > $ldap_host[$count]\n"; } - print - "2. Use Javascript Address Book Search : $WHT$default_use_javascript_addr_book$NRM\n"; + print "2. Use Javascript address book search : $WHT$default_use_javascript_addr_book$NRM\n"; + print "3. Use global file address book : $WHT$abook_global_file$NRM\n"; + print "4. Allow writing into global file address book : $WHT$abook_global_file_writeable$NRM\n"; print "\n"; print "R Return to Main Menu\n"; } elsif ( $menu == 7 ) { @@ -713,6 +716,8 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) ) { } elsif ( $menu == 6 ) { if ( $command == 1 ) { command61(); } elsif ( $command == 2 ) { command62(); } + elsif ( $command == 3 ) { $abook_global_file=command63(); } + elsif ( $command == 4 ) { command64(); } } elsif ( $menu == 7 ) { if ( $command == 1 ) { $motd = command71(); } } elsif ( $menu == 8 ) { @@ -2565,6 +2570,46 @@ sub command62 { return $default_use_javascript_addr_book; } +# global filebased address book +sub command63 { + print "If you want to use global file address book, then you\n"; + print "must set this option to a valid value. If option does\n"; + print "not have path elements, system assumes that file is\n"; + print "stored in data directory. If relative path is set, it is\n"; + print "relative to main squirrelmail directory. If value is empty,\n"; + print "address book is not enabled.\n"; + print "\n"; + + print "[$WHT$abook_global_file$NRM]: $WHT"; + $new_abook_global_file = ; + if ( $new_abook_global_file eq "\n" ) { + $new_abook_global_file = $abook_global_file; + } else { + $new_abook_global_file =~ s/[\r\n]//g; + } + return $new_abook_global_file; +} + +# writing into global filebased abook control +sub command64 { + print "\n"; + + if ( lc($abook_global_file_writeable) eq 'true' ) { + $default_value = "y"; + } else { + $abook_global_file_writeable = 'false'; + $default_value = "n"; + } + print "Allow writting into global file address book (y/n) [$WHT$default_value$NRM]: $WHT"; + $new_show = ; + if ( ( $new_show =~ /^y\n/i ) || ( ( $new_show =~ /^\n/ ) && ( $default_value eq "y" ) ) ) { + $abook_global_file_writeable = 'true'; + } else { + $abook_global_file_writeable = 'false'; + } + return $abook_global_file_writeable; +} + sub command91 { print "If you want to store your users address book details in a database then\n"; print "you need to set this DSN to a valid value. The format for this is:\n"; @@ -3258,9 +3303,13 @@ sub save_data { # string print CF "\$addrbook_global_table = '$addrbook_global_table';\n"; # boolean - print CF "\$addrbook_global_writeable = $addrbook_global_writeable;\n\n"; + print CF "\$addrbook_global_writeable = $addrbook_global_writeable;\n"; # boolean print CF "\$addrbook_global_listing = $addrbook_global_listing;\n\n"; + # string + print CF "\$abook_global_file = '$abook_global_file';\n"; + # boolean + print CF "\$abook_global_file_writeable = $abook_global_file_writeable;\n\n"; # boolean print CF "\$no_list_for_subscribe = $no_list_for_subscribe;\n"; diff --git a/config/config_default.php b/config/config_default.php index 6a6676e4..a526f6e7 100644 --- a/config/config_default.php +++ b/config/config_default.php @@ -734,6 +734,17 @@ $theme[36]['NAME'] = 'Redmond'; */ $default_use_javascript_addr_book = false; +/** + * Shared filebased address book + * @global string $abook_global_file + */ +$abook_global_file = ''; + +/** + * Writing into shared address book control + * @global bool $abook_global_file_writeable + */ +$abook_global_file_writeable = false; /** * MOTD diff --git a/functions/abook_global_file.php b/functions/abook_global_file.php deleted file mode 100644 index ef1f30a5..00000000 --- a/functions/abook_global_file.php +++ /dev/null @@ -1,194 +0,0 @@ -global_filename = $address_book_global_filename; - - $this->sname = _("Global address book"); - - $this->open(true); - } - - /* Open the addressbook file and store the file pointer. - * Use $file as the file to open, or the class' own - * filename property. If $param is empty and file is - * open, do nothing. */ - function open($new = false) { - $this->error = ''; - - /* Return true is file is open and $new is unset */ - if($this->filehandle && !$new) { - return true; - } - - /* Check that new file exists */ - if (! file_exists($this->global_filename) || - ! is_readable($this->global_filename)) { - return $this->set_error($this->global_filename . ': ' . - _("No such file or directory")); - } - - /* Close old file, if any */ - if ($this->filehandle) { - $this->close(); - } - - /* Open file, read only. */ - $fh = @fopen($this->global_filename, 'r'); - $this->writeable = false; - if(! $fh) { - return $this->set_error($this->global_filename . ': ' . - _("Open failed")); - } - - $this->filehandle = &$fh; - return true; - } - - /* Close the file and forget the filehandle */ - function close() { - @fclose($this->filehandle); - $this->filehandle = 0; - $this->global_filename = ''; - $this->writable = false; - } - - /* ========================== Public ======================== */ - - /* Search the file */ - function search($expr) { - - /* To be replaced by advanded search expression parsing */ - if(is_array($expr)) { - return; - } - - /* Make regexp from glob'ed expression - * May want to quote other special characters like (, ), -, [, ], etc. */ - $expr = str_replace('?', '.', $expr); - $expr = str_replace('*', '.*', $expr); - - $res = array(); - if(!$this->open()) { - return false; - } - - @rewind($this->filehandle); - - while ($row = @fgetcsv($this->filehandle, 2048, '|')) { - $line = join(' ', $row); - if (eregi($expr, $line)) { - $res[] = array('nickname' => $row[0], - 'name' => $row[1] . ' ' . $row[2], - 'firstname' => $row[1], - 'lastname' => $row[2], - 'email' => $row[3], - 'label' => $row[4], - 'backend' => $this->bnum, - 'source' => &$this->sname); - } - } - - return $res; - } - - /* Lookup alias */ - function lookup($alias) { - if (empty($alias)) { - return array(); - } - - $alias = strtolower($alias); - - $this->open(); - @rewind($this->filehandle); - - while ($row = @fgetcsv($this->filehandle, 2048, '|')) { - if (strtolower($row[0]) == $alias) { - return array('nickname' => $row[0], - 'name' => $row[1] . ' ' . $row[2], - 'firstname' => $row[1], - 'lastname' => $row[2], - 'email' => $row[3], - 'label' => $row[4], - 'backend' => $this->bnum, - 'source' => &$this->sname); - } - } - - return array(); - } - - /* List all addresses */ - function list_addr() { - $res = array(); - $this->open(); - @rewind($this->filehandle); - - while ($row = @fgetcsv($this->filehandle, 2048, '|')) { - $res[] = array('nickname' => $row[0], - 'name' => $row[1] . ' ' . $row[2], - 'firstname' => $row[1], - 'lastname' => $row[2], - 'email' => $row[3], - 'label' => $row[4], - 'backend' => $this->bnum, - 'source' => &$this->sname); - } - return $res; - } - - /* Add address */ - function add($userdata) { - $this->set_error(_("Can not modify global address book")); - return false; - } - - /* Delete address */ - function remove($alias) { - $this->set_error(_("Can not modify global address book")); - return false; - } - - /* Modify address */ - function modify($alias, $userdata) { - $this->set_error(_("Can not modify global address book")); - return false; - } - -} /* End of class abook_local_file */ -?> \ No newline at end of file diff --git a/functions/abook_local_file.php b/functions/abook_local_file.php index a841c035..c7a5bb7e 100644 --- a/functions/abook_local_file.php +++ b/functions/abook_local_file.php @@ -28,18 +28,48 @@ * @package squirrelmail */ class abook_local_file extends addressbook_backend { - /** @var string backend type */ + /** + * Backend type + * @var string + */ var $btype = 'local'; - /** @var string backend name */ + /** + * Backend name + * @var string + */ var $bname = 'local_file'; - /** @var string file used to store data */ - var $filename = ''; - /** @var object file handle */ + /** + * File used to store data + * @var string + */ + var $filename = ''; + /** + * File handle + * @var object + */ var $filehandle = 0; - /** @var bool create file if it is not present */ - var $create = false; - /** @var string umask of the file */ + /** + * Create file, if it not present + * @var bool + */ + var $create = false; + /** + * Detect, if address book is writeable by checking file permisions + * @var bool + */ + var $detect_writeable = true; + /** + * Control write access to address book + * + * Option does not have any effect, if 'detect_writeable' is 'true' + * @var bool + */ + var $writeable = false; + /** + * Umask of the file + * @var string + */ var $umask; /* ========================== Private ======================= */ @@ -70,9 +100,15 @@ class abook_local_file extends addressbook_backend { if(isset($param['umask'])) { $this->umask = $param['umask']; } - if(!empty($param['name'])) { + if(isset($param['name'])) { $this->sname = $param['name']; } + if(isset($param['detect_writeable'])) { + $this->detect_writeable = $param['detect_writeable']; + } + if(!empty($param['writeable'])) { + $this->writeable = $param['writeable']; + } $this->open(true); } else { @@ -92,6 +128,7 @@ class abook_local_file extends addressbook_backend { $this->error = ''; $file = $this->filename; $create = $this->create; + $fopenmode = ($this->writeable ? 'a+' : 'r'); /* Return true is file is open and $new is unset */ if($this->filehandle && !$new) { @@ -106,22 +143,32 @@ class abook_local_file extends addressbook_backend { /* Close old file, if any */ if($this->filehandle) { $this->close(); } - /* Open file. First try to open for reading and writing, - * but fall back to read only. */ umask($this->umask); - $fh = @fopen($file, 'a+'); - if($fh) { - $this->filehandle = &$fh; - $this->filename = $file; - $this->writeable = true; + if (! $this->detect_writeable) { + $fh = @fopen($file,$fopenmode); + if ($fh) { + $this->filehandle = &$fh; + $this->filename = $file; + } else { + return $this->set_error("$file: " . _("Open failed")); + } } else { - $fh = @fopen($file, 'r'); + /* Open file. First try to open for reading and writing, + * but fall back to read only. */ + $fh = @fopen($file, 'a+'); if($fh) { $this->filehandle = &$fh; $this->filename = $file; - $this->writeable = false; + $this->writeable = true; } else { - return $this->set_error("$file: " . _("Open failed")); + $fh = @fopen($file, 'r'); + if($fh) { + $this->filehandle = &$fh; + $this->filename = $file; + $this->writeable = false; + } else { + return $this->set_error("$file: " . _("Open failed")); + } } } return true; diff --git a/functions/addressbook.php b/functions/addressbook.php index 4ffed913..f5efb80d 100644 --- a/functions/addressbook.php +++ b/functions/addressbook.php @@ -39,6 +39,7 @@ global $addrbook_dsn, $addrbook_global_dsn; function addressbook_init($showerr = true, $onlylocal = false) { global $data_dir, $username, $ldap_server, $address_book_global_filename; global $addrbook_dsn, $addrbook_table; + global $abook_global_file, $abook_global_file_writeable; global $addrbook_global_dsn, $addrbook_global_table, $addrbook_global_writeable, $addrbook_global_listing; /* Create a new addressbook object */ @@ -74,8 +75,22 @@ function addressbook_init($showerr = true, $onlylocal = false) { } /* This would be for the global addressbook */ - if (isset($address_book_global_filename)) { - $r = $abook->add_backend('global_file'); + if (isset($abook_global_file) && isset($abook_global_file_writeable) + && trim($abook_global_file)!=''){ + // Detect place of address book + if (! preg_match("/[\/\\\]/",$abook_global_file)) { + // no path chars + $abook_global_filename=$data_dir . $abook_global_file; + } elseif (preg_match("/^\/|\w:/",$abook_global_file)) { + // full path is set in options (starts with slash or x:) + $abook_global_filename=$abook_global_file; + } else { + $abook_global_filename=SM_PATH . $abook_global_file; + } + $r = $abook->add_backend('local_file',array('filename'=>$abook_global_filename, + 'name' => _("Global address book"), + 'detect_writeable' => false, + 'writeable'=> $abook_global_file_writeable)); if (!$r && $showerr) { echo _("Error initializing global addressbook."); exit; @@ -367,21 +382,44 @@ function show_abook_sort_button($abook_sort_order, $alt_tag, $Down, $Up ) { * @subpackage addressbook */ class AddressBook { - + /** + * Enabled address book backends + * @var array + */ var $backends = array(); + /** + * Number of enabled backends + * @var integer + */ var $numbackends = 0; + /** + * Error messages + * @var string + */ var $error = ''; + /** + * id of backend with personal address book + * @var integer + */ var $localbackend = 0; + /** + * Name of backend with personal address book + * @var string + */ var $localbackendname = ''; - // Constructor function. + /** + * Constructor function. + */ function AddressBook() { $this->localbackendname = _("Personal address book"); } - /* + /** * Return an array of backends of a given type, * or all backends if no type is specified. + * @param string $type backend type + * @return array list of backends */ function get_backend_list($type = '') { $ret = array(); @@ -394,13 +432,15 @@ class AddressBook { } - /* - ========================== Public ======================== + /* ========================== Public ======================== */ - Add a new backend. $backend is the name of a backend - (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. + /** + * Add a new backend. + * + * @param string $backend backend name (without the abook_ prefix) + * @param mixed optional variable that is passed to the backend constructor. + * See each of the backend classes for valid parameters + * @return integer number of backends */ function add_backend($backend, $param = '') { $backend_name = 'abook_' . $backend; @@ -425,12 +465,15 @@ class AddressBook { } - /* + /** + * create string with name and email address + * * This function takes a $row array as returned by the addressbook * search and returns an e-mail address with the full name or * nickname optionally prepended. + * @param array $row address book entry + * @return string email address with real name prepended */ - function full_address($row) { global $addrsrch_fullname, $data_dir, $username; $prefix = getPref($data_dir, $username, 'addrsrch_fullname'); @@ -443,10 +486,15 @@ class AddressBook { } } - /* - Return a list of addresses matching expression in - all backends of a given type. - */ + /** + * Search for entries in address books + * + * Return a list of addresses matching expression in + * all backends of a given type. + * @param string $expression search expression + * @param integer $bnum backend number. default to search in all backends + * @return array search results + */ function search($expression, $bnum = -1) { $ret = array(); $this->error = ''; @@ -487,7 +535,12 @@ class AddressBook { } - /* Return a sorted search */ + /** + * Sorted search + * @param string $expression search expression + * @param integer $bnum backend number. default to search in all backends + * @return array search results + */ function s_search($expression, $bnum = -1) { $ret = $this->search($expression, $bnum); @@ -498,9 +551,12 @@ class AddressBook { } - /* - * Lookup an address by alias. Only possible in - * local backends. + /** + * Lookup an address by alias. + * Only possible in local backends. + * @param string $alias + * @param integer backend number + * @return array lookup results. False, if not found. */ function lookup($alias, $bnum = -1) { @@ -534,12 +590,16 @@ class AddressBook { } - /* Return all addresses */ + /** + * Return all addresses + * @param integer $bnum backend number + * @return array search results + */ function list_addr($bnum = -1) { $ret = array(); if ($bnum == -1) { - $sel = $this->get_backend_list('local'); + $sel = $this->get_backend_list(''); } else { $sel = array(0 => &$this->backends[$bnum]); } @@ -559,9 +619,11 @@ class AddressBook { return $ret; } - /* - * Create a new address from $userdata, in backend $bnum. - * Return the backend number that the/ address was added + /** + * Create a new address + * @param array $userdata added address record + * @param integer $bnum backend number + * @return integer the backend number that the/ address was added * to, or false if it failed. */ function add($userdata, $bnum) { @@ -607,9 +669,11 @@ class AddressBook { } /* end of add() */ - /* - * Remove the user identified by $alias from backend $bnum - * If $alias is an array, all users in the array are removed. + /** + * Remove the entries from address book + * @param mixed $alias entries that have to be removed. Can be string with nickname or array with list of nicknames + * @param integer $bnum backend number + * @return bool true if removed successfully. false if there s an error. $this->error contains error message */ function remove($alias, $bnum) { @@ -642,9 +706,11 @@ class AddressBook { } /* end of remove() */ - /* - * Remove the user identified by $alias from backend $bnum - * If $alias is an array, all users in the array are removed. + /** + * Modify entry in address book + * @param string $alias nickname + * @param array $userdata newdata + * @param integer $bnum backend number */ function modify($alias, $userdata, $bnum) { @@ -705,18 +771,49 @@ class AddressBook { class addressbook_backend { /* Variables that all backends must provide. */ + /** + * Backend type + * + * Can be 'local' or 'remote' + * @var string backend type + */ var $btype = 'dummy'; + /** + * Internal backend name + * @var string + */ var $bname = 'dummy'; + /** + * Displayed backend name + * @var string + */ var $sname = 'Dummy backend'; /* * Variables common for all backends, but that * should not be changed by the backends. */ + /** + * Backend number + * @var integer + */ var $bnum = -1; + /** + * Error messages + * @var string + */ var $error = ''; + /** + * Writeable flag + * @var bool + */ var $writeable = false; + /** + * Set error message + * @param string $string error message + * @return bool + */ function set_error($string) { $this->error = '[' . $this->sname . '] ' . $string; return false; @@ -725,36 +822,65 @@ class addressbook_backend { /* ========================== Public ======================== */ + /** + * Search for entries in backend + * @param string $expression + * @return bool + */ function search($expression) { $this->set_error('search not implemented'); return false; } + /** + * Find entry in backend by alias + * @param string $alias name used for id + * @return bool + */ function lookup($alias) { $this->set_error('lookup not implemented'); return false; } + /** + * List all entries in backend + * @return bool + */ function list_addr() { $this->set_error('list_addr not implemented'); return false; } + /** + * Add entry to backend + * @param array userdata + * @return bool + */ function add($userdata) { $this->set_error('add not implemented'); return false; } + /** + * Remove entry from backend + * @param string $alias name used for id + * @return bool + */ function remove($alias) { $this->set_error('delete not implemented'); return false; } + /** + * Modify entry in backend + * @param string $alias name used for id + * @param array $newuserdata new data + * @return bool + */ function modify($alias, $newuserdata) { $this->set_error('modify not implemented'); return false; } - } /* @@ -765,11 +891,6 @@ class addressbook_backend { require_once(SM_PATH . 'functions/abook_local_file.php'); require_once(SM_PATH . 'functions/abook_ldap_server.php'); -/* Use this if you wanna have a global address book */ -if (isset($address_book_global_filename)) { - include_once(SM_PATH . 'functions/abook_global_file.php'); -} - /* Only load database backend if database is configured */ if((isset($addrbook_dsn) && !empty($addrbook_dsn)) || (isset($addrbook_global_dsn) && !empty($addrbook_global_dsn)) ) { -- 2.25.1