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