6 * @copyright © 1999-2006 The SquirrelMail Project Team
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
9 * @package squirrelmail
10 * @subpackage addressbook
13 /** Needs the DB functions */
14 if (!include_once('DB.php')) {
15 // same error also in db_prefs.php
16 require_once(SM_PATH
. 'functions/display_messages.php');
17 $error = _("Could not include PEAR database functions required for the database backend.") . "<br />\n";
18 $error .= sprintf(_("Is PEAR installed, and is the include path set correctly to find %s?"),
19 '<tt>DB.php</tt>') . "<br />\n";
20 $error .= _("Please contact your system administrator and report this error.");
21 error_box($error, $color);
26 * Address book in a database backend
28 * Backend for personal/shared address book stored in a database,
29 * accessed using the DB-classes in PEAR.
31 * IMPORTANT: The PEAR modules must be in the include path
32 * for this class to work.
34 * An array with the following elements must be passed to
35 * the class constructor (elements marked ? are optional):
37 * dsn => database DNS (see PEAR for syntax)
38 * table => table to store addresses in (must exist)
39 * owner => current user (owner of address data)
40 * ? name => name of address book
41 * ? writeable => set writeable flag (true/false)
42 * ? listing => enable/disable listing
44 * The table used should have the following columns:
45 * owner, nickname, firstname, lastname, email, label
46 * The pair (owner,nickname) should be unique (primary key).
48 * NOTE. This class should not be used directly. Use the
49 * "AddressBook" class instead.
50 * @package squirrelmail
51 * @subpackage addressbook
53 class abook_database
extends addressbook_backend
{
63 var $bname = 'database';
66 * Data Source Name (connection description)
71 * Table that stores addresses
78 * Limits list of database entries visible to end user
88 * Enable/disable writing into address book
91 var $writeable = true;
93 * Enable/disable address book listing
98 /* ========================== Private ======================= */
102 * @param array $param address book backend options
104 function abook_database($param) {
105 $this->sname
= _("Personal address book");
107 if (is_array($param)) {
108 if (empty($param['dsn']) ||
109 empty($param['table']) ||
110 empty($param['owner'])) {
111 return $this->set_error('Invalid parameters');
114 $this->dsn
= $param['dsn'];
115 $this->table
= $param['table'];
116 $this->owner
= $param['owner'];
118 if (!empty($param['name'])) {
119 $this->sname
= $param['name'];
122 if (isset($param['writeable'])) {
123 $this->writeable
= $param['writeable'];
126 if (isset($param['listing'])) {
127 $this->listing
= $param['listing'];
133 return $this->set_error('Invalid argument to constructor');
140 * @param bool $new new connection if it is true
143 function open($new = false) {
146 /* Return true is file is open and $new is unset */
147 if ($this->dbh
&& !$new) {
151 /* Close old file, if any */
156 $dbh = DB
::connect($this->dsn
, true);
158 if (DB
::isError($dbh)) {
159 return $this->set_error(sprintf(_("Database error: %s"),
160 DB
::errorMessage($dbh)));
168 * Close the file and forget the filehandle
171 $this->dbh
->disconnect();
175 /* ========================== Public ======================== */
178 * Search the database
179 * @param string $expr search expression
180 * @return array search results
182 function search($expr) {
188 /* To be replaced by advanded search expression parsing */
189 if (is_array($expr)) {
193 // don't allow wide search when listing is disabled.
194 if ($expr=='*' && ! $this->listing
)
197 /* Make regexp from glob'ed expression */
198 $expr = str_replace('?', '_', $expr);
199 $expr = str_replace('*', '%', $expr);
200 $expr = $this->dbh
->quoteString($expr);
203 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND " .
204 "(firstname LIKE '%s' OR lastname LIKE '%s')",
205 $this->table
, $this->owner
, $expr, $expr);
206 $res = $this->dbh
->query($query);
208 if (DB
::isError($res)) {
209 return $this->set_error(sprintf(_("Database error: %s"),
210 DB
::errorMessage($res)));
213 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
214 array_push($ret, array('nickname' => $row['nickname'],
215 'name' => "$row[firstname] $row[lastname]",
216 'firstname' => $row['firstname'],
217 'lastname' => $row['lastname'],
218 'email' => $row['email'],
219 'label' => $row['label'],
220 'backend' => $this->bnum
,
221 'source' => &$this->sname
));
228 * @param string $alias alias
229 * @return array search results
231 function lookup($alias) {
236 $alias = strtolower($alias);
238 if (!$this->open()) {
242 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND LOWER(nickname)='%s'",
243 $this->table
, $this->owner
, $this->dbh
->quoteString($alias));
245 $res = $this->dbh
->query($query);
247 if (DB
::isError($res)) {
248 return $this->set_error(sprintf(_("Database error: %s"),
249 DB
::errorMessage($res)));
252 if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
253 return array('nickname' => $row['nickname'],
254 'name' => "$row[firstname] $row[lastname]",
255 'firstname' => $row['firstname'],
256 'lastname' => $row['lastname'],
257 'email' => $row['email'],
258 'label' => $row['label'],
259 'backend' => $this->bnum
,
260 'source' => &$this->sname
);
267 * @return array search results
269 function list_addr() {
271 if (!$this->open()) {
275 if(isset($this->listing
) && !$this->listing
) {
280 $query = sprintf("SELECT * FROM %s WHERE owner='%s'",
281 $this->table
, $this->owner
);
283 $res = $this->dbh
->query($query);
285 if (DB
::isError($res)) {
286 return $this->set_error(sprintf(_("Database error: %s"),
287 DB
::errorMessage($res)));
290 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
291 array_push($ret, array('nickname' => $row['nickname'],
292 'name' => "$row[firstname] $row[lastname]",
293 'firstname' => $row['firstname'],
294 'lastname' => $row['lastname'],
295 'email' => $row['email'],
296 'label' => $row['label'],
297 'backend' => $this->bnum
,
298 'source' => &$this->sname
));
305 * @param array $userdata added data
308 function add($userdata) {
309 if (!$this->writeable
) {
310 return $this->set_error(_("Addressbook is read-only"));
313 if (!$this->open()) {
317 /* See if user exist already */
318 $ret = $this->lookup($userdata['nickname']);
320 return $this->set_error(sprintf(_("User \"%s\" already exists"),$ret['nickname']));
324 $query = sprintf("INSERT INTO %s (owner, nickname, firstname, " .
325 "lastname, email, label) VALUES('%s','%s','%s'," .
327 $this->table
, $this->owner
,
328 $this->dbh
->quoteString($userdata['nickname']),
329 $this->dbh
->quoteString($userdata['firstname']),
330 $this->dbh
->quoteString((!empty($userdata['lastname'])?
$userdata['lastname']:'')),
331 $this->dbh
->quoteString($userdata['email']),
332 $this->dbh
->quoteString((!empty($userdata['label'])?
$userdata['label']:'')) );
335 $r = $this->dbh
->simpleQuery($query);
341 return $this->set_error(sprintf(_("Database error: %s"),
342 DB
::errorMessage($r)));
347 * @param string $alias alias that has to be deleted
350 function remove($alias) {
351 if (!$this->writeable
) {
352 return $this->set_error(_("Addressbook is read-only"));
355 if (!$this->open()) {
360 $query = sprintf("DELETE FROM %s WHERE owner='%s' AND (",
361 $this->table
, $this->owner
);
364 while (list($undef, $nickname) = each($alias)) {
365 $query .= sprintf("%s nickname='%s' ", $sepstr,
366 $this->dbh
->quoteString($nickname));
372 $r = $this->dbh
->simpleQuery($query);
378 return $this->set_error(sprintf(_("Database error: %s"),
379 DB
::errorMessage($r)));
384 * @param string $alias modified alias
385 * @param array $userdata new data
388 function modify($alias, $userdata) {
389 if (!$this->writeable
) {
390 return $this->set_error(_("Addressbook is read-only"));
393 if (!$this->open()) {
397 /* See if user exist */
398 $ret = $this->lookup($alias);
400 return $this->set_error(sprintf(_("User \"%s\" does not exist"),$alias));
404 $query = sprintf("UPDATE %s SET nickname='%s', firstname='%s', ".
405 "lastname='%s', email='%s', label='%s' ".
406 "WHERE owner='%s' AND nickname='%s'",
408 $this->dbh
->quoteString($userdata['nickname']),
409 $this->dbh
->quoteString($userdata['firstname']),
410 $this->dbh
->quoteString((!empty($userdata['lastname'])?
$userdata['lastname']:'')),
411 $this->dbh
->quoteString($userdata['email']),
412 $this->dbh
->quoteString((!empty($userdata['label'])?
$userdata['label']:'')),
414 $this->dbh
->quoteString($alias) );
417 $r = $this->dbh
->simpleQuery($query);
423 return $this->set_error(sprintf(_("Database error: %s"),
424 DB
::errorMessage($r)));
426 } /* End of class abook_database */