6 * Copyright (c) 1999-2001 The Squirrelmail Development 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.
33 require_once('DB.php');
35 class abook_database
extends addressbook_backend
{
37 var $bname = 'database';
44 var $writeable = true;
46 /* ========================== Private ======================= */
49 function abook_database($param) {
50 $this->sname
= _("Personal address book");
52 if (is_array($param)) {
53 if (empty($param['dsn']) ||
54 empty($param['table']) ||
55 empty($param['owner'])) {
56 return $this->set_error('Invalid parameters');
59 $this->dsn
= $param['dsn'];
60 $this->table
= $param['table'];
61 $this->owner
= $param['owner'];
63 if (!empty($param['name'])) {
64 $this->sname
= $param['name'];
67 if (isset($param['writeable'])) {
68 $this->writeable
= $param['writeable'];
74 return $this->set_error('Invalid argument to constructor');
79 /* Open the database. New connection if $new is true */
80 function open($new = false) {
83 /* Return true is file is open and $new is unset */
84 if ($this->dbh
&& !$new) {
88 /* Close old file, if any */
93 $dbh = DB
::connect($this->dsn
, true);
95 if (DB
::isError($dbh) || DB
::isWarning($dbh)) {
96 return $this->set_error(sprintf(_("Database error: %s"),
97 DB
::errorMessage($dbh)));
104 /* Close the file and forget the filehandle */
106 $this->dbh
->disconnect();
110 /* ========================== Public ======================== */
112 /* Search the file */
113 function &search($expr) {
119 /* To be replaced by advanded search expression parsing */
120 if (is_array($expr)) {
124 /* Make regexp from glob'ed expression */
125 $expr = str_replace('?', '_', $expr);
126 $expr = str_replace('*', '%', $expr);
127 $expr = $this->dbh
->quoteString($expr);
130 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND " .
131 "(firstname LIKE '%s' OR lastname LIKE '%s')",
132 $this->table
, $this->owner
, $expr, $expr);
133 $res = $this->dbh
->query($query);
135 if (DB
::isError($res)) {
136 return $this->set_error(sprintf(_("Database error: %s"),
137 DB
::errorMessage($res)));
140 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
141 array_push($ret, array('nickname' => $row['nickname'],
142 'name' => "$row[firstname] $row[lastname]",
143 'firstname' => $row['firstname'],
144 'lastname' => $row['lastname'],
145 'email' => $row['email'],
146 'label' => $row['label'],
147 'backend' => $this->bnum
,
148 'source' => &$this->sname
));
154 function &lookup($alias) {
159 $alias = strtolower($alias);
161 if (!$this->open()) {
165 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND nickname='%s'",
166 $this->table
, $this->owner
, $alias);
168 $res = $this->dbh
->query($query);
170 if (DB
::isError($res)) {
171 return $this->set_error(sprintf(_("Database error: %s"),
172 DB
::errorMessage($res)));
175 if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
176 return array('nickname' => $row['nickname'],
177 'name' => "$row[firstname] $row[lastname]",
178 'firstname' => $row['firstname'],
179 'lastname' => $row['lastname'],
180 'email' => $row['email'],
181 'label' => $row['label'],
182 'backend' => $this->bnum
,
183 'source' => &$this->sname
);
188 /* List all addresses */
189 function &list_addr() {
191 if (!$this->open()) {
195 $query = sprintf("SELECT * FROM %s WHERE owner='%s'",
196 $this->table
, $this->owner
);
198 $res = $this->dbh
->query($query);
200 if (DB
::isError($res)) {
201 return $this->set_error(sprintf(_("Database error: %s"),
202 DB
::errorMessage($res)));
205 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC
)) {
206 array_push($ret, array('nickname' => $row['nickname'],
207 'name' => "$row[firstname] $row[lastname]",
208 'firstname' => $row['firstname'],
209 'lastname' => $row['lastname'],
210 'email' => $row['email'],
211 'label' => $row['label'],
212 'backend' => $this->bnum
,
213 'source' => &$this->sname
));
219 function add($userdata) {
220 if (!$this->writeable
) {
221 return $this->set_error(_("Addressbook is read-only"));
224 if (!$this->open()) {
228 /* See if user exist already */
229 $ret = $this->lookup($userdata['nickname']);
231 return $this->set_error(sprintf(_("User '%s' already exist"),
236 $query = sprintf("INSERT INTO %s (owner, nickname, firstname, " .
237 "lastname, email, label) VALUES('%s','%s','%s'," .
239 $this->table
, $this->owner
,
240 $this->dbh
->quoteString($userdata['nickname']),
241 $this->dbh
->quoteString($userdata['firstname']),
242 $this->dbh
->quoteString($userdata['lastname']),
243 $this->dbh
->quoteString($userdata['email']),
244 $this->dbh
->quoteString($userdata['label']) );
247 $r = $this->dbh
->simpleQuery($query);
253 return $this->set_error(sprintf(_("Database error: %s"),
254 DB
::errorMessage($r)));
258 function remove($alias) {
259 if (!$this->writeable
) {
260 return $this->set_error(_("Addressbook is read-only"));
263 if (!$this->open()) {
268 $query = sprintf("DELETE FROM %s WHERE owner='%s' AND (",
269 $this->table
, $this->owner
);
272 while (list($undef, $nickname) = each($alias)) {
273 $query .= sprintf("%s nickname='%s' ", $sepstr,
274 $this->dbh
->quoteString($nickname));
280 $r = $this->dbh
->simpleQuery($query);
286 return $this->set_error(sprintf(_("Database error: %s"),
287 DB
::errorMessage($r)));
291 function modify($alias, $userdata) {
292 if (!$this->writeable
) {
293 return $this->set_error(_("Addressbook is read-only"));
296 if (!$this->open()) {
300 /* See if user exist */
301 $ret = $this->lookup($alias);
303 return $this->set_error(sprintf(_("User '%s' does not exist"),
308 $query = sprintf("UPDATE %s SET nickname='%s', firstname='%s', ".
309 "lastname='%s', email='%s', label='%s' ".
310 "WHERE owner='%s' AND nickname='%s'",
312 $this->dbh
->quoteString($userdata['nickname']),
313 $this->dbh
->quoteString($userdata['firstname']),
314 $this->dbh
->quoteString($userdata['lastname']),
315 $this->dbh
->quoteString($userdata['email']),
316 $this->dbh
->quoteString($userdata['label']),
318 $this->dbh
->quoteString($alias) );
321 $r = $this->dbh
->simpleQuery($query);
327 return $this->set_error(sprintf(_("Database error: %s"),
328 DB
::errorMessage($r)));
330 } /* End of class abook_database */