Style police.
[squirrelmail.git] / functions / abook_database.php
CommitLineData
9b9474d6 1<?php
7902aca2 2
35586184 3/**
4 * abook_database.php
5 *
6 * Copyright (c) 1999-2001 The Squirrelmail Development Team
7 * Licensed under the GNU GPL. For full terms see the file COPYING.
8 *
9 * Backend for personal addressbook stored in a database,
10 * accessed using the DB-classes in PEAR.
11 *
12 * IMPORTANT: The PEAR modules must be in the include path
13 * for this class to work.
14 *
15 * An array with the following elements must be passed to
16 * the class constructor (elements marked ? are optional):
17 *
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)
22 *
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).
26 *
27 * NOTE. This class should not be used directly. Use the
28 * "AddressBook" class instead.
29 *
30 * $Id$
31 */
7902aca2 32
35586184 33require_once('DB.php');
7902aca2 34
9b9474d6 35class abook_database extends addressbook_backend {
36 var $btype = 'local';
37 var $bname = 'database';
7902aca2 38
9b9474d6 39 var $dsn = '';
40 var $table = '';
41 var $owner = '';
42 var $dbh = false;
7902aca2 43
9b9474d6 44 var $writeable = true;
7902aca2 45
9b9474d6 46 /* ========================== Private ======================= */
7902aca2 47
9b9474d6 48 /* Constructor */
49 function abook_database($param) {
50 $this->sname = _("Personal address book");
7902aca2 51
9b9474d6 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');
57 }
7902aca2 58
91be2362 59 $this->dsn = $param['dsn'];
60 $this->table = $param['table'];
61 $this->owner = $param['owner'];
7902aca2 62
9b9474d6 63 if (!empty($param['name'])) {
91be2362 64 $this->sname = $param['name'];
9b9474d6 65 }
7902aca2 66
9b9474d6 67 if (isset($param['writeable'])) {
91be2362 68 $this->writeable = $param['writeable'];
9b9474d6 69 }
7902aca2 70
71 $this->open(true);
9b9474d6 72 }
73 else {
91be2362 74 return $this->set_error('Invalid argument to constructor');
9b9474d6 75 }
76 }
7902aca2 77
78
9b9474d6 79 /* Open the database. New connection if $new is true */
80 function open($new = false) {
81 $this->error = '';
7902aca2 82
9b9474d6 83 /* Return true is file is open and $new is unset */
84 if ($this->dbh && !$new) {
7902aca2 85 return true;
9b9474d6 86 }
7902aca2 87
9b9474d6 88 /* Close old file, if any */
89 if ($this->dbh) {
90 $this->close();
91 }
7902aca2 92
9b9474d6 93 $dbh = DB::connect($this->dsn, true);
7902aca2 94
9b9474d6 95 if (DB::isError($dbh) || DB::isWarning($dbh)) {
701c9c6b 96 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 97 DB::errorMessage($dbh)));
9b9474d6 98 }
7902aca2 99
9b9474d6 100 $this->dbh = $dbh;
101 return true;
102 }
7902aca2 103
9b9474d6 104 /* Close the file and forget the filehandle */
105 function close() {
106 $this->dbh->disconnect();
107 $this->dbh = false;
108 }
7902aca2 109
9b9474d6 110 /* ========================== Public ======================== */
7902aca2 111
9b9474d6 112 /* Search the file */
113 function &search($expr) {
114 $ret = array();
115 if(!$this->open()) {
7902aca2 116 return false;
9b9474d6 117 }
7902aca2 118
9b9474d6 119 /* To be replaced by advanded search expression parsing */
120 if (is_array($expr)) {
121 return;
122 }
123
124 /* Make regexp from glob'ed expression */
125 $expr = str_replace('?', '_', $expr);
126 $expr = str_replace('*', '%', $expr);
127 $expr = $this->dbh->quoteString($expr);
128 $expr = "%$expr%";
129
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);
134
135 if (DB::isError($res)) {
701c9c6b 136 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 137 DB::errorMessage($res)));
9b9474d6 138 }
7902aca2 139
9b9474d6 140 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 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));
9b9474d6 149 }
150 return $ret;
151 }
7902aca2 152
9b9474d6 153 /* Lookup alias */
154 function &lookup($alias) {
155 if (empty($alias)) {
7902aca2 156 return array();
9b9474d6 157 }
7902aca2 158
9b9474d6 159 $alias = strtolower($alias);
7902aca2 160
9b9474d6 161 if (!$this->open()) {
7902aca2 162 return false;
9b9474d6 163 }
7902aca2 164
9b9474d6 165 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND nickname='%s'",
166 $this->table, $this->owner, $alias);
7902aca2 167
9b9474d6 168 $res = $this->dbh->query($query);
7902aca2 169
9b9474d6 170 if (DB::isError($res)) {
701c9c6b 171 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 172 DB::errorMessage($res)));
9b9474d6 173 }
7902aca2 174
9b9474d6 175 if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 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);
9b9474d6 184 }
185 return array();
186 }
187
188 /* List all addresses */
189 function &list_addr() {
190 $ret = array();
191 if (!$this->open()) {
7902aca2 192 return false;
9b9474d6 193 }
7902aca2 194
9b9474d6 195 $query = sprintf("SELECT * FROM %s WHERE owner='%s'",
196 $this->table, $this->owner);
7902aca2 197
9b9474d6 198 $res = $this->dbh->query($query);
199
200 if (DB::isError($res)) {
701c9c6b 201 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 202 DB::errorMessage($res)));
9b9474d6 203 }
7902aca2 204
9b9474d6 205 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 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));
9b9474d6 214 }
215 return $ret;
216 }
7902aca2 217
9b9474d6 218 /* Add address */
219 function add($userdata) {
220 if (!$this->writeable) {
701c9c6b 221 return $this->set_error(_("Addressbook is read-only"));
9b9474d6 222 }
7902aca2 223
9b9474d6 224 if (!$this->open()) {
7902aca2 225 return false;
9b9474d6 226 }
7902aca2 227
9b9474d6 228 /* See if user exist already */
229 $ret = $this->lookup($userdata['nickname']);
230 if (!empty($ret)) {
b9bfd165 231 return $this->set_error(sprintf(_("User '%s' already exist"),
91be2362 232 $ret['nickname']));
9b9474d6 233 }
234
235 /* Create query */
236 $query = sprintf("INSERT INTO %s (owner, nickname, firstname, " .
237 "lastname, email, label) VALUES('%s','%s','%s'," .
238 "'%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']) );
245
246 /* Do the insert */
7902aca2 247 $r = $this->dbh->simpleQuery($query);
9b9474d6 248 if ($r == DB_OK) {
249 return true;
250 }
7902aca2 251
9b9474d6 252 /* Fail */
701c9c6b 253 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 254 DB::errorMessage($r)));
9b9474d6 255 }
7902aca2 256
9b9474d6 257 /* Delete address */
258 function remove($alias) {
259 if (!$this->writeable) {
701c9c6b 260 return $this->set_error(_("Addressbook is read-only"));
9b9474d6 261 }
7902aca2 262
9b9474d6 263 if (!$this->open()) {
7902aca2 264 return false;
9b9474d6 265 }
7902aca2 266
9b9474d6 267 /* Create query */
268 $query = sprintf("DELETE FROM %s WHERE owner='%s' AND (",
269 $this->table, $this->owner);
7902aca2 270
9b9474d6 271 $sepstr = '';
272 while (list($undef, $nickname) = each($alias)) {
16a973d7 273 $query .= sprintf("%s nickname='%s' ", $sepstr,
7902aca2 274 $this->dbh->quoteString($nickname));
91be2362 275 $sepstr = 'OR';
9b9474d6 276 }
277 $query .= ')';
7902aca2 278
9b9474d6 279 /* Delete entry */
280 $r = $this->dbh->simpleQuery($query);
281 if ($r == DB_OK) {
282 return true;
283 }
7902aca2 284
9b9474d6 285 /* Fail */
286 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 287 DB::errorMessage($r)));
9b9474d6 288 }
7902aca2 289
9b9474d6 290 /* Modify address */
291 function modify($alias, $userdata) {
292 if (!$this->writeable) {
701c9c6b 293 return $this->set_error(_("Addressbook is read-only"));
9b9474d6 294 }
7902aca2 295
9b9474d6 296 if (!$this->open()) {
7902aca2 297 return false;
9b9474d6 298 }
7902aca2 299
9b9474d6 300 /* See if user exist */
301 $ret = $this->lookup($alias);
302 if (empty($ret)) {
701c9c6b 303 return $this->set_error(sprintf(_("User '%s' does not exist"),
7902aca2 304 $alias));
9b9474d6 305 }
306
307 /* Create query */
308 $query = sprintf("UPDATE %s SET nickname='%s', firstname='%s', ".
309 "lastname='%s', email='%s', label='%s' ".
310 "WHERE owner='%s' AND nickname='%s'",
311 $this->table,
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']),
317 $this->owner,
318 $this->dbh->quoteString($alias) );
319
320 /* Do the insert */
321 $r = $this->dbh->simpleQuery($query);
322 if ($r == DB_OK) {
323 return true;
324 }
7902aca2 325
9b9474d6 326 /* Fail */
327 return $this->set_error(sprintf(_("Database error: %s"),
328 DB::errorMessage($r)));
329 }
330} /* End of class abook_database */
7902aca2 331
9b9474d6 332?>