Operation "foo_once".
[squirrelmail.git] / functions / abook_database.php
CommitLineData
7902aca2 1<?php {
2
3 /**
4 ** abook_database.php
5 **
6 ** Backend for personal addressbook stored in a database,
f435778e 7 ** accessed using the DB-classes in PEAR.
7902aca2 8 **
9 ** IMPORTANT: The PEAR modules must be in the include path
10 ** for this class to work.
11 **
12 ** An array with the following elements must be passed to
13 ** the class constructor (elements marked ? are optional):
14 **
15 ** dsn => database DNS (see PEAR for syntax)
16 ** table => table to store addresses in (must exist)
17 ** owner => current user (owner of address data)
18 ** ? writeable => set writeable flag (true/false)
19 **
20 ** The table used should have the following columns:
21 ** owner, nickname, firstname, lastname, email, label
22 ** The pair (owner,nickname) should be unique (primary key).
23 **
24 ** NOTE. This class should not be used directly. Use the
25 ** "AddressBook" class instead.
245a6892 26 **
27 ** $Id$
7902aca2 28 **/
29
b9bfd165 30 require_once('DB.php');
7902aca2 31
32 class abook_database extends addressbook_backend {
b9bfd165 33 var $btype = 'local';
34 var $bname = 'database';
7902aca2 35
b9bfd165 36 var $dsn = '';
37 var $table = '';
38 var $owner = '';
7902aca2 39 var $dbh = false;
40
41 var $writeable = true;
42
43 // ========================== Private =======================
44
45 // Constructor
46 function abook_database($param) {
701c9c6b 47 $this->sname = _("Personal address book");
7902aca2 48
49 if(is_array($param)) {
91be2362 50 if(empty($param['dsn']) ||
51 empty($param['table']) ||
52 empty($param['owner']))
53 return $this->set_error('Invalid parameters');
7902aca2 54
91be2362 55 $this->dsn = $param['dsn'];
56 $this->table = $param['table'];
57 $this->owner = $param['owner'];
7902aca2 58
91be2362 59 if(!empty($param['name']))
60 $this->sname = $param['name'];
7902aca2 61
91be2362 62 if(isset($param['writeable']))
63 $this->writeable = $param['writeable'];
7902aca2 64
65 $this->open(true);
66 } else {
91be2362 67 return $this->set_error('Invalid argument to constructor');
7902aca2 68 }
69 }
70
71
72 // Open the database. New connection if $new is true
73 function open($new = false) {
91be2362 74 $this->error = '';
7902aca2 75
76 // Return true is file is open and $new is unset
77 if($this->dbh && !$new)
78 return true;
79
80 // Close old file, if any
81 if($this->dbh) $this->close();
82
83 $dbh = DB::connect($this->dsn, true);
84
85 if(DB::isError($dbh) || DB::isWarning($dbh))
701c9c6b 86 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 87 DB::errorMessage($dbh)));
88
89 $this->dbh = $dbh;
90 return true;
91 }
92
93 // Close the file and forget the filehandle
94 function close() {
95 $this->dbh->disconnect();
96 $this->dbh = false;
97 }
98
99 // ========================== Public ========================
100
101 // Search the file
102 function &search($expr) {
103 $ret = array();
104 if(!$this->open())
105 return false;
106
107 // To be replaced by advanded search expression parsing
108 if(is_array($expr)) return;
109
110 // Make regexp from glob'ed expression
16a973d7 111 $expr = str_replace('?', '_', $expr);
112 $expr = str_replace('*', '%', $expr);
7902aca2 113 $expr = $this->dbh->quoteString($expr);
114 $expr = "%$expr%";
115
16a973d7 116 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND " .
117 "(firstname LIKE '%s' OR lastname LIKE '%s')",
7902aca2 118 $this->table, $this->owner, $expr, $expr);
119 $res = $this->dbh->query($query);
120
121 if(DB::isError($res))
701c9c6b 122 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 123 DB::errorMessage($res)));
124
125 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 126 array_push($ret, array('nickname' => $row['nickname'],
127 'name' => "$row[firstname] $row[lastname]",
128 'firstname' => $row['firstname'],
129 'lastname' => $row['lastname'],
130 'email' => $row['email'],
131 'label' => $row['label'],
132 'backend' => $this->bnum,
133 'source' => &$this->sname));
7902aca2 134 }
135 return $ret;
136 }
137
138 // Lookup alias
139 function &lookup($alias) {
140 if(empty($alias))
141 return array();
142
143 $alias = strtolower($alias);
144
145 if(!$this->open())
146 return false;
147
16a973d7 148 $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND nickname='%s'",
7902aca2 149 $this->table, $this->owner, $alias);
150
151 $res = $this->dbh->query($query);
152
153 if(DB::isError($res))
701c9c6b 154 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 155 DB::errorMessage($res)));
156
157 if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 158 return array('nickname' => $row['nickname'],
159 'name' => "$row[firstname] $row[lastname]",
160 'firstname' => $row['firstname'],
161 'lastname' => $row['lastname'],
162 'email' => $row['email'],
163 'label' => $row['label'],
164 'backend' => $this->bnum,
165 'source' => &$this->sname);
7902aca2 166 }
167
168 return array();
169 }
170
171 // List all addresses
172 function &list_addr() {
173 $ret = array();
174 if(!$this->open())
175 return false;
176
16a973d7 177 $query = sprintf("SELECT * FROM %s WHERE owner='%s'",
7902aca2 178 $this->table, $this->owner);
179
180 $res = $this->dbh->query($query);
181
182 if(DB::isError($res))
701c9c6b 183 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 184 DB::errorMessage($res)));
185
186 while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
91be2362 187 array_push($ret, array('nickname' => $row['nickname'],
188 'name' => "$row[firstname] $row[lastname]",
189 'firstname' => $row['firstname'],
190 'lastname' => $row['lastname'],
191 'email' => $row['email'],
192 'label' => $row['label'],
193 'backend' => $this->bnum,
194 'source' => &$this->sname));
7902aca2 195 }
196 return $ret;
197 }
198
199 // Add address
200 function add($userdata) {
91be2362 201 if(!$this->writeable)
701c9c6b 202 return $this->set_error(_("Addressbook is read-only"));
7902aca2 203
204 if(!$this->open())
205 return false;
206
207 // See if user exist already
91be2362 208 $ret = $this->lookup($userdata['nickname']);
7902aca2 209 if(!empty($ret))
b9bfd165 210 return $this->set_error(sprintf(_("User '%s' already exist"),
91be2362 211 $ret['nickname']));
7902aca2 212
213 // Create query
16a973d7 214 $query = sprintf("INSERT INTO %s (owner, nickname, firstname, " .
91be2362 215 "lastname, email, label) VALUES('%s','%s','%s'," .
7902aca2 216 "'%s','%s','%s')",
217 $this->table, $this->owner,
91be2362 218 $this->dbh->quoteString($userdata['nickname']),
219 $this->dbh->quoteString($userdata['firstname']),
220 $this->dbh->quoteString($userdata['lastname']),
221 $this->dbh->quoteString($userdata['email']),
222 $this->dbh->quoteString($userdata['label']) );
7902aca2 223
224 // Do the insert
225 $r = $this->dbh->simpleQuery($query);
226 if($r == DB_OK) return true;
227
228 // Fail
701c9c6b 229 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 230 DB::errorMessage($r)));
231 }
232
233 // Delete address
234 function remove($alias) {
235 if(!$this->writeable)
701c9c6b 236 return $this->set_error(_("Addressbook is read-only"));
7902aca2 237
238 if(!$this->open())
239 return false;
240
241 // Create query
16a973d7 242 $query = sprintf("DELETE FROM %s WHERE owner='%s' AND (",
7902aca2 243 $this->table, $this->owner);
244
91be2362 245 $sepstr = '';
7902aca2 246 while(list($undef, $nickname) = each($alias)) {
16a973d7 247 $query .= sprintf("%s nickname='%s' ", $sepstr,
7902aca2 248 $this->dbh->quoteString($nickname));
91be2362 249 $sepstr = 'OR';
7902aca2 250 }
91be2362 251 $query .= ')';
7902aca2 252
253 // Delete entry
254 $r = $this->dbh->simpleQuery($query);
255 if($r == DB_OK) return true;
256
257 // Fail
701c9c6b 258 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 259 DB::errorMessage($r)));
260 }
261
262 // Modify address
263 function modify($alias, $userdata) {
264 if(!$this->writeable)
701c9c6b 265 return $this->set_error(_("Addressbook is read-only"));
7902aca2 266
267 if(!$this->open())
268 return false;
269
270 // See if user exist
271 $ret = $this->lookup($alias);
272 if(empty($ret))
701c9c6b 273 return $this->set_error(sprintf(_("User '%s' does not exist"),
7902aca2 274 $alias));
275
276 // Create query
277 $query = sprintf("UPDATE %s SET nickname='%s', firstname='%s', ".
278 "lastname='%s', email='%s', label='%s' ".
279 "WHERE owner='%s' AND nickname='%s'",
280 $this->table,
91be2362 281 $this->dbh->quoteString($userdata['nickname']),
282 $this->dbh->quoteString($userdata['firstname']),
283 $this->dbh->quoteString($userdata['lastname']),
284 $this->dbh->quoteString($userdata['email']),
285 $this->dbh->quoteString($userdata['label']),
7902aca2 286 $this->owner,
287 $this->dbh->quoteString($alias) );
288
289 // Do the insert
290 $r = $this->dbh->simpleQuery($query);
291 if($r == DB_OK) return true;
292
293 // Fail
701c9c6b 294 return $this->set_error(sprintf(_("Database error: %s"),
7902aca2 295 DB::errorMessage($r)));
296 }
297 } // End of class abook_database
298
299} ?>