abook_database.php 11 KB

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