adding three global variables. Allows to use correct alignment without html_tag function
[squirrelmail.git] / functions / abook_database.php
CommitLineData
9b9474d6 1<?php
7902aca2 2
35586184 3/**
4 * abook_database.php
5 *
76911253 6 * Copyright (c) 1999-2003 The SquirrelMail Project Team
35586184 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$
d6c32258 31 * @package squirrelmail
35586184 32 */
d6c32258 33
34/** Needs the DB functions */
35586184 35require_once('DB.php');
d6c32258 36
37/**
38 * Undocumented class - stores the addressbook in a sql database
39 * @package squirrelmail
40 */
9b9474d6 41class abook_database extends addressbook_backend {
42 var $btype = 'local';
43 var $bname = 'database';
7902aca2 44
9b9474d6 45 var $dsn = '';
46 var $table = '';
47 var $owner = '';
48 var $dbh = false;
7902aca2 49
9b9474d6 50 var $writeable = true;
7902aca2 51
9b9474d6 52 /* ========================== Private ======================= */
7902aca2 53
9b9474d6 54 /* Constructor */
55 function abook_database($param) {
56 $this->sname = _("Personal address book");
7902aca2 57
9b9474d6 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');
63 }
7902aca2 64
91be2362 65 $this->dsn = $param['dsn'];
66 $this->table = $param['table'];
67 $this->owner = $param['owner'];
7902aca2 68
9b9474d6 69 if (!empty($param['name'])) {
91be2362 70 $this->sname = $param['name'];
9b9474d6 71 }
7902aca2 72
9b9474d6 73 if (isset($param['writeable'])) {
91be2362 74 $this->writeable = $param['writeable'];
9b9474d6 75 }
7902aca2 76
77 $this->open(true);
9b9474d6 78 }
79 else {
91be2362 80 return $this->set_error('Invalid argument to constructor');
9b9474d6 81 }
82 }
7902aca2 83
84
9b9474d6 85 /* Open the database. New connection if $new is true */
86 function open($new = false) {
87 $this->error = '';
7902aca2 88
9b9474d6 89 /* Return true is file is open and $new is unset */
90 if ($this->dbh && !$new) {
7902aca2 91 return true;
9b9474d6 92 }
7902aca2 93
9b9474d6 94 /* Close old file, if any */
95 if ($this->dbh) {
96 $this->close();
97 }
7902aca2 98
9b9474d6 99 $dbh = DB::connect($this->dsn, true);
7902aca2 100
286fe80b 101 if (DB::isError($dbh)) {
701c9c6b 102 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 103 DB::errorMessage($dbh)));
9b9474d6 104 }
7902aca2 105
9b9474d6 106 $this->dbh = $dbh;
107 return true;
108 }
7902aca2 109
9b9474d6 110 /* Close the file and forget the filehandle */
111 function close() {
112 $this->dbh->disconnect();
113 $this->dbh = false;
114 }
7902aca2 115
9b9474d6 116 /* ========================== Public ======================== */
7902aca2 117
9b9474d6 118 /* Search the file */
119 function &search($expr) {
120 $ret = array();
121 if(!$this->open()) {
7902aca2 122 return false;
9b9474d6 123 }
7902aca2 124
9b9474d6 125 /* To be replaced by advanded search expression parsing */
126 if (is_array($expr)) {
127 return;
128 }
129
130 /* Make regexp from glob'ed expression */
131 $expr = str_replace('?', '_', $expr);
132 $expr = str_replace('*', '%', $expr);
133 $expr = $this->dbh->quoteString($expr);
134 $expr = "%$expr%";
135
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);
140
141 if (DB::isError($res)) {
701c9c6b 142 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 143 DB::errorMessage($res)));
9b9474d6 144 }
7902aca2 145
9b9474d6 146 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 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));
9b9474d6 155 }
156 return $ret;
157 }
7902aca2 158
9b9474d6 159 /* Lookup alias */
160 function &lookup($alias) {
161 if (empty($alias)) {
7902aca2 162 return array();
9b9474d6 163 }
7902aca2 164
9b9474d6 165 $alias = strtolower($alias);
7902aca2 166
9b9474d6 167 if (!$this->open()) {
7902aca2 168 return false;
9b9474d6 169 }
7902aca2 170
9b9474d6 171 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND nickname='%s'",
172 $this->table, $this->owner, $alias);
7902aca2 173
9b9474d6 174 $res = $this->dbh->query($query);
7902aca2 175
9b9474d6 176 if (DB::isError($res)) {
701c9c6b 177 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 178 DB::errorMessage($res)));
9b9474d6 179 }
7902aca2 180
9b9474d6 181 if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 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);
9b9474d6 190 }
191 return array();
192 }
193
194 /* List all addresses */
195 function &list_addr() {
196 $ret = array();
197 if (!$this->open()) {
7902aca2 198 return false;
9b9474d6 199 }
7902aca2 200
9b9474d6 201 $query = sprintf("SELECT * FROM %s WHERE owner='%s'",
202 $this->table, $this->owner);
7902aca2 203
9b9474d6 204 $res = $this->dbh->query($query);
205
206 if (DB::isError($res)) {
701c9c6b 207 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 208 DB::errorMessage($res)));
9b9474d6 209 }
7902aca2 210
9b9474d6 211 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 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));
9b9474d6 220 }
221 return $ret;
222 }
7902aca2 223
9b9474d6 224 /* Add address */
225 function add($userdata) {
226 if (!$this->writeable) {
701c9c6b 227 return $this->set_error(_("Addressbook is read-only"));
9b9474d6 228 }
7902aca2 229
9b9474d6 230 if (!$this->open()) {
7902aca2 231 return false;
9b9474d6 232 }
7902aca2 233
9b9474d6 234 /* See if user exist already */
235 $ret = $this->lookup($userdata['nickname']);
236 if (!empty($ret)) {
b9bfd165 237 return $this->set_error(sprintf(_("User '%s' already exist"),
91be2362 238 $ret['nickname']));
9b9474d6 239 }
240
241 /* Create query */
242 $query = sprintf("INSERT INTO %s (owner, nickname, firstname, " .
243 "lastname, email, label) VALUES('%s','%s','%s'," .
244 "'%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']) );
251
252 /* Do the insert */
7902aca2 253 $r = $this->dbh->simpleQuery($query);
9b9474d6 254 if ($r == DB_OK) {
255 return true;
256 }
7902aca2 257
9b9474d6 258 /* Fail */
701c9c6b 259 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 260 DB::errorMessage($r)));
9b9474d6 261 }
7902aca2 262
9b9474d6 263 /* Delete address */
264 function remove($alias) {
265 if (!$this->writeable) {
701c9c6b 266 return $this->set_error(_("Addressbook is read-only"));
9b9474d6 267 }
7902aca2 268
9b9474d6 269 if (!$this->open()) {
7902aca2 270 return false;
9b9474d6 271 }
7902aca2 272
9b9474d6 273 /* Create query */
274 $query = sprintf("DELETE FROM %s WHERE owner='%s' AND (",
275 $this->table, $this->owner);
7902aca2 276
9b9474d6 277 $sepstr = '';
278 while (list($undef, $nickname) = each($alias)) {
16a973d7 279 $query .= sprintf("%s nickname='%s' ", $sepstr,
7902aca2 280 $this->dbh->quoteString($nickname));
91be2362 281 $sepstr = 'OR';
9b9474d6 282 }
283 $query .= ')';
7902aca2 284
9b9474d6 285 /* Delete entry */
286 $r = $this->dbh->simpleQuery($query);
287 if ($r == DB_OK) {
288 return true;
289 }
7902aca2 290
9b9474d6 291 /* Fail */
292 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 293 DB::errorMessage($r)));
9b9474d6 294 }
7902aca2 295
9b9474d6 296 /* Modify address */
297 function modify($alias, $userdata) {
298 if (!$this->writeable) {
701c9c6b 299 return $this->set_error(_("Addressbook is read-only"));
9b9474d6 300 }
7902aca2 301
9b9474d6 302 if (!$this->open()) {
7902aca2 303 return false;
9b9474d6 304 }
7902aca2 305
9b9474d6 306 /* See if user exist */
307 $ret = $this->lookup($alias);
308 if (empty($ret)) {
701c9c6b 309 return $this->set_error(sprintf(_("User '%s' does not exist"),
7902aca2 310 $alias));
9b9474d6 311 }
312
313 /* Create query */
314 $query = sprintf("UPDATE %s SET nickname='%s', firstname='%s', ".
315 "lastname='%s', email='%s', label='%s' ".
316 "WHERE owner='%s' AND nickname='%s'",
317 $this->table,
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']),
323 $this->owner,
324 $this->dbh->quoteString($alias) );
325
326 /* Do the insert */
327 $r = $this->dbh->simpleQuery($query);
328 if ($r == DB_OK) {
329 return true;
330 }
7902aca2 331
9b9474d6 332 /* Fail */
333 return $this->set_error(sprintf(_("Database error: %s"),
334 DB::errorMessage($r)));
335 }
336} /* End of class abook_database */
7902aca2 337
9b9474d6 338?>