abook_database.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  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. /*****************************************************************/
  32. /*** THIS FILE NEEDS TO HAVE ITS FORMATTING FIXED!!! ***/
  33. /*** PLEASE DO SO AND REMOVE THIS COMMENT SECTION. ***/
  34. /*** + Base level indent should begin at left margin, as ***/
  35. /*** the require_once below looks. ***/
  36. /*** + All identation should consist of four space blocks ***/
  37. /*** + Tab characters are evil. ***/
  38. /*** + all comments should use "slash-star ... star-slash" ***/
  39. /*** style -- no pound characters, no slash-slash style ***/
  40. /*** + FLOW CONTROL STATEMENTS (if, while, etc) SHOULD ***/
  41. /*** ALWAYS USE { AND } CHARACTERS!!! ***/
  42. /*** + Please use ' instead of ", when possible. Note " ***/
  43. /*** should always be used in _( ) function calls. ***/
  44. /*** Thank you for your help making the SM code more readable. ***/
  45. /*****************************************************************/
  46. require_once('DB.php');
  47. class abook_database extends addressbook_backend {
  48. var $btype = 'local';
  49. var $bname = 'database';
  50. var $dsn = '';
  51. var $table = '';
  52. var $owner = '';
  53. var $dbh = false;
  54. var $writeable = true;
  55. // ========================== Private =======================
  56. // Constructor
  57. function abook_database($param) {
  58. $this->sname = _("Personal address book");
  59. if(is_array($param)) {
  60. if(empty($param['dsn']) ||
  61. empty($param['table']) ||
  62. empty($param['owner']))
  63. return $this->set_error('Invalid parameters');
  64. $this->dsn = $param['dsn'];
  65. $this->table = $param['table'];
  66. $this->owner = $param['owner'];
  67. if(!empty($param['name']))
  68. $this->sname = $param['name'];
  69. if(isset($param['writeable']))
  70. $this->writeable = $param['writeable'];
  71. $this->open(true);
  72. } else {
  73. return $this->set_error('Invalid argument to constructor');
  74. }
  75. }
  76. // Open the database. New connection if $new is true
  77. function open($new = false) {
  78. $this->error = '';
  79. // Return true is file is open and $new is unset
  80. if($this->dbh && !$new)
  81. return true;
  82. // Close old file, if any
  83. if($this->dbh) $this->close();
  84. $dbh = DB::connect($this->dsn, true);
  85. if(DB::isError($dbh) || DB::isWarning($dbh))
  86. return $this->set_error(sprintf(_("Database error: %s"),
  87. DB::errorMessage($dbh)));
  88. $this->dbh = $dbh;
  89. return true;
  90. }
  91. // Close the file and forget the filehandle
  92. function close() {
  93. $this->dbh->disconnect();
  94. $this->dbh = false;
  95. }
  96. // ========================== Public ========================
  97. // Search the file
  98. function &search($expr) {
  99. $ret = array();
  100. if(!$this->open())
  101. return false;
  102. // To be replaced by advanded search expression parsing
  103. if(is_array($expr)) return;
  104. // Make regexp from glob'ed expression
  105. $expr = str_replace('?', '_', $expr);
  106. $expr = str_replace('*', '%', $expr);
  107. $expr = $this->dbh->quoteString($expr);
  108. $expr = "%$expr%";
  109. $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND " .
  110. "(firstname LIKE '%s' OR lastname LIKE '%s')",
  111. $this->table, $this->owner, $expr, $expr);
  112. $res = $this->dbh->query($query);
  113. if(DB::isError($res))
  114. return $this->set_error(sprintf(_("Database error: %s"),
  115. DB::errorMessage($res)));
  116. while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
  117. array_push($ret, array('nickname' => $row['nickname'],
  118. 'name' => "$row[firstname] $row[lastname]",
  119. 'firstname' => $row['firstname'],
  120. 'lastname' => $row['lastname'],
  121. 'email' => $row['email'],
  122. 'label' => $row['label'],
  123. 'backend' => $this->bnum,
  124. 'source' => &$this->sname));
  125. }
  126. return $ret;
  127. }
  128. // Lookup alias
  129. function &lookup($alias) {
  130. if(empty($alias))
  131. return array();
  132. $alias = strtolower($alias);
  133. if(!$this->open())
  134. return false;
  135. $query = sprintf("SELECT * FROM %s WHERE owner='%s' AND nickname='%s'",
  136. $this->table, $this->owner, $alias);
  137. $res = $this->dbh->query($query);
  138. if(DB::isError($res))
  139. return $this->set_error(sprintf(_("Database error: %s"),
  140. DB::errorMessage($res)));
  141. if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
  142. return array('nickname' => $row['nickname'],
  143. 'name' => "$row[firstname] $row[lastname]",
  144. 'firstname' => $row['firstname'],
  145. 'lastname' => $row['lastname'],
  146. 'email' => $row['email'],
  147. 'label' => $row['label'],
  148. 'backend' => $this->bnum,
  149. 'source' => &$this->sname);
  150. }
  151. return array();
  152. }
  153. // List all addresses
  154. function &list_addr() {
  155. $ret = array();
  156. if(!$this->open())
  157. return false;
  158. $query = sprintf("SELECT * FROM %s WHERE owner='%s'",
  159. $this->table, $this->owner);
  160. $res = $this->dbh->query($query);
  161. if(DB::isError($res))
  162. return $this->set_error(sprintf(_("Database error: %s"),
  163. DB::errorMessage($res)));
  164. while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
  165. array_push($ret, array('nickname' => $row['nickname'],
  166. 'name' => "$row[firstname] $row[lastname]",
  167. 'firstname' => $row['firstname'],
  168. 'lastname' => $row['lastname'],
  169. 'email' => $row['email'],
  170. 'label' => $row['label'],
  171. 'backend' => $this->bnum,
  172. 'source' => &$this->sname));
  173. }
  174. return $ret;
  175. }
  176. // Add address
  177. function add($userdata) {
  178. if(!$this->writeable)
  179. return $this->set_error(_("Addressbook is read-only"));
  180. if(!$this->open())
  181. return false;
  182. // See if user exist already
  183. $ret = $this->lookup($userdata['nickname']);
  184. if(!empty($ret))
  185. return $this->set_error(sprintf(_("User '%s' already exist"),
  186. $ret['nickname']));
  187. // Create query
  188. $query = sprintf("INSERT INTO %s (owner, nickname, firstname, " .
  189. "lastname, email, label) VALUES('%s','%s','%s'," .
  190. "'%s','%s','%s')",
  191. $this->table, $this->owner,
  192. $this->dbh->quoteString($userdata['nickname']),
  193. $this->dbh->quoteString($userdata['firstname']),
  194. $this->dbh->quoteString($userdata['lastname']),
  195. $this->dbh->quoteString($userdata['email']),
  196. $this->dbh->quoteString($userdata['label']) );
  197. // Do the insert
  198. $r = $this->dbh->simpleQuery($query);
  199. if($r == DB_OK) return true;
  200. // Fail
  201. return $this->set_error(sprintf(_("Database error: %s"),
  202. DB::errorMessage($r)));
  203. }
  204. // Delete address
  205. function remove($alias) {
  206. if(!$this->writeable)
  207. return $this->set_error(_("Addressbook is read-only"));
  208. if(!$this->open())
  209. return false;
  210. // Create query
  211. $query = sprintf("DELETE FROM %s WHERE owner='%s' AND (",
  212. $this->table, $this->owner);
  213. $sepstr = '';
  214. while(list($undef, $nickname) = each($alias)) {
  215. $query .= sprintf("%s nickname='%s' ", $sepstr,
  216. $this->dbh->quoteString($nickname));
  217. $sepstr = 'OR';
  218. }
  219. $query .= ')';
  220. // Delete entry
  221. $r = $this->dbh->simpleQuery($query);
  222. if($r == DB_OK) return true;
  223. // Fail
  224. return $this->set_error(sprintf(_("Database error: %s"),
  225. DB::errorMessage($r)));
  226. }
  227. // Modify address
  228. function modify($alias, $userdata) {
  229. if(!$this->writeable)
  230. return $this->set_error(_("Addressbook is read-only"));
  231. if(!$this->open())
  232. return false;
  233. // See if user exist
  234. $ret = $this->lookup($alias);
  235. if(empty($ret))
  236. return $this->set_error(sprintf(_("User '%s' does not exist"),
  237. $alias));
  238. // Create query
  239. $query = sprintf("UPDATE %s SET nickname='%s', firstname='%s', ".
  240. "lastname='%s', email='%s', label='%s' ".
  241. "WHERE owner='%s' AND nickname='%s'",
  242. $this->table,
  243. $this->dbh->quoteString($userdata['nickname']),
  244. $this->dbh->quoteString($userdata['firstname']),
  245. $this->dbh->quoteString($userdata['lastname']),
  246. $this->dbh->quoteString($userdata['email']),
  247. $this->dbh->quoteString($userdata['label']),
  248. $this->owner,
  249. $this->dbh->quoteString($alias) );
  250. // Do the insert
  251. $r = $this->dbh->simpleQuery($query);
  252. if($r == DB_OK) return true;
  253. // Fail
  254. return $this->set_error(sprintf(_("Database error: %s"),
  255. DB::errorMessage($r)));
  256. }
  257. } // End of class abook_database
  258. } ?>