6 * Copyright (c) 1999-2003 The SquirrelMail Project Team
7 * Licensed under the GNU GPL. For full terms see the file COPYING.
9 * Backend for personal addressbook stored in a database,
10 * accessed using the DB-classes in PEAR.
12 * IMPORTANT: The PEAR modules must be in the include path
13 * for this class to work.
15 * An array with the following elements must be passed to
16 * the class constructor (elements marked ? are optional):
18 * dsn => database DNS (see PEAR for syntax)
19 * table => table to store addresses in (must exist)
20 * owner => current user (owner of address data)
21 * ? writeable => set writeable flag (true/false)
23 * The table used should have the following columns:
24 * owner, nickname, firstname, lastname, email, label
25 * The pair (owner,nickname) should be unique (primary key).
27 * NOTE. This class should not be used directly. Use the
28 * "AddressBook" class instead.
31 * @package squirrelmail
34 /** Needs the DB functions */
35 require_once('DB.php');
38 * Undocumented class - stores the addressbook in a sql database
39 * @package squirrelmail
41 class abook_database
extends addressbook_backend
{
43 var $bname = 'database';
50 var $writeable = true;
52 /* ========================== Private ======================= */
55 function abook_database($param) {
56 $this->sname
= _("Personal address book");
58 if (is_array($param)) {
59 if (empty($param['dsn']) ||
60 empty($param['table']) ||
61 empty($param['owner'])) {
62 return $this->set_error('Invalid parameters');
65 $this->dsn
= $param['dsn'];
66 $this->table
= $param['table'];
67 $this->owner
= $param['owner'];
69 if (!empty($param['name'])) {
70 $this->sname
= $param['name'];
73 if (isset($param['writeable'])) {
74 $this->writeable
= $param['writeable'];
80 return $this->set_error('Invalid argument to constructor');
85 /* Open the database. New connection if $new is true */
86 function open($new = false) {
89 /* Return true is file is open and $new is unset */
90 if ($this->dbh
&& !$new) {
94 /* Close old file, if any */
99 $dbh = DB
::connect($this->dsn
, true);
101 if (DB
::isError($dbh)) {
102 return $this->set_error(sprintf(_("Database error: %s"),
103 DB
::errorMessage($dbh)));
110 /* Close the file and forget the filehandle */
112 $this->dbh
->disconnect();
116 /* ========================== Public ======================== */
118 /* Search the file */
119 function &search($expr) {
125 /* To be replaced by advanded search expression parsing */
126 if (is_array($expr)) {
130 /* Make regexp from glob'ed expression */
131 $expr = str_replace('?', '_', $expr);
132 $expr = str_replace('*', '%', $expr);
133 $expr = $this->dbh
->quoteString($expr);
136 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND " .
137 "(firstname LIKE '%s' OR lastname LIKE '%s')",
138 $this->table
, $this->owner
, $expr, $expr);
139 $res = $this->dbh
->query($query);
141 if (DB
::isError($res)) {
142 return $this->set_error(sprintf(_("Database error: %s"),
143 DB
::errorMessage($res)));
146 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
147 array_push($ret, array('nickname' => $row['nickname'],
148 'name' => "$row[firstname] $row[lastname]",
149 'firstname' => $row['firstname'],
150 'lastname' => $row['lastname'],
151 'email' => $row['email'],
152 'label' => $row['label'],
153 'backend' => $this->bnum
,
154 'source' => &$this->sname
));
160 function &lookup($alias) {
165 $alias = strtolower($alias);
167 if (!$this->open()) {
171 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND nickname='%s'",
172 $this->table
, $this->owner
, $alias);
174 $res = $this->dbh
->query($query);
176 if (DB
::isError($res)) {
177 return $this->set_error(sprintf(_("Database error: %s"),
178 DB
::errorMessage($res)));
181 if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
182 return array('nickname' => $row['nickname'],
183 'name' => "$row[firstname] $row[lastname]",
184 'firstname' => $row['firstname'],
185 'lastname' => $row['lastname'],
186 'email' => $row['email'],
187 'label' => $row['label'],
188 'backend' => $this->bnum
,
189 'source' => &$this->sname
);
194 /* List all addresses */
195 function &list_addr() {
197 if (!$this->open()) {
201 $query = sprintf("SELECT * FROM %s WHERE owner='%s'",
202 $this->table
, $this->owner
);
204 $res = $this->dbh
->query($query);
206 if (DB
::isError($res)) {
207 return $this->set_error(sprintf(_("Database error: %s"),
208 DB
::errorMessage($res)));
211 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
212 array_push($ret, array('nickname' => $row['nickname'],
213 'name' => "$row[firstname] $row[lastname]",
214 'firstname' => $row['firstname'],
215 'lastname' => $row['lastname'],
216 'email' => $row['email'],
217 'label' => $row['label'],
218 'backend' => $this->bnum
,
219 'source' => &$this->sname
));
225 function add($userdata) {
226 if (!$this->writeable
) {
227 return $this->set_error(_("Addressbook is read-only"));
230 if (!$this->open()) {
234 /* See if user exist already */
235 $ret = $this->lookup($userdata['nickname']);
237 return $this->set_error(sprintf(_("User '%s' already exist"),
242 $query = sprintf("INSERT INTO %s (owner, nickname, firstname, " .
243 "lastname, email, label) VALUES('%s','%s','%s'," .
245 $this->table
, $this->owner
,
246 $this->dbh
->quoteString($userdata['nickname']),
247 $this->dbh
->quoteString($userdata['firstname']),
248 $this->dbh
->quoteString($userdata['lastname']),
249 $this->dbh
->quoteString($userdata['email']),
250 $this->dbh
->quoteString($userdata['label']) );
253 $r = $this->dbh
->simpleQuery($query);
259 return $this->set_error(sprintf(_("Database error: %s"),
260 DB
::errorMessage($r)));
264 function remove($alias) {
265 if (!$this->writeable
) {
266 return $this->set_error(_("Addressbook is read-only"));
269 if (!$this->open()) {
274 $query = sprintf("DELETE FROM %s WHERE owner='%s' AND (",
275 $this->table
, $this->owner
);
278 while (list($undef, $nickname) = each($alias)) {
279 $query .= sprintf("%s nickname='%s' ", $sepstr,
280 $this->dbh
->quoteString($nickname));
286 $r = $this->dbh
->simpleQuery($query);
292 return $this->set_error(sprintf(_("Database error: %s"),
293 DB
::errorMessage($r)));
297 function modify($alias, $userdata) {
298 if (!$this->writeable
) {
299 return $this->set_error(_("Addressbook is read-only"));
302 if (!$this->open()) {
306 /* See if user exist */
307 $ret = $this->lookup($alias);
309 return $this->set_error(sprintf(_("User '%s' does not exist"),
314 $query = sprintf("UPDATE %s SET nickname='%s', firstname='%s', ".
315 "lastname='%s', email='%s', label='%s' ".
316 "WHERE owner='%s' AND nickname='%s'",
318 $this->dbh
->quoteString($userdata['nickname']),
319 $this->dbh
->quoteString($userdata['firstname']),
320 $this->dbh
->quoteString($userdata['lastname']),
321 $this->dbh
->quoteString($userdata['email']),
322 $this->dbh
->quoteString($userdata['label']),
324 $this->dbh
->quoteString($alias) );
327 $r = $this->dbh
->simpleQuery($query);
333 return $this->set_error(sprintf(_("Database error: %s"),
334 DB
::errorMessage($r)));
336 } /* End of class abook_database */