1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11: class Vilma_Driver_Sql extends Vilma_Driver
12: {
13: 14: 15:
16: protected $_db;
17:
18: 19: 20: 21: 22:
23: public function __construct($params)
24: {
25: parent::__construct($params);
26: $this->_initialize();
27: }
28:
29: 30: 31: 32: 33:
34: public function getDomains()
35: {
36: $sql = 'SELECT ' . $this->_getTableFields('domains')
37: . ' FROM ' . $this->_params['tables']['domains']
38: . ' ORDER BY ' . $this->_getTableField('domains', 'domain_name');
39: Horde::logMessage($sql, 'DEBUG');
40: return $this->_db->getAll($sql, null, DB_FETCHMODE_ASSOC);
41: }
42:
43: 44: 45: 46: 47: 48: 49:
50: public function getDomain($domain_id)
51: {
52: $sql = 'SELECT ' . $this->_getTableFields('domains')
53: . ' FROM ' . $this->_params['tables']['domains']
54: . ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?';
55: Horde::logMessage($sql, 'DEBUG');
56: return $this->_db->getRow($sql, array((int)$domain_id), DB_FETCHMODE_ASSOC);
57: }
58:
59: 60: 61: 62: 63: 64: 65:
66: public function getDomainByName($domain_name)
67: {
68: $sql = 'SELECT ' . $this->_getTableFields('domains')
69: . ' FROM ' . $this->_params['tables']['domains']
70: . ' WHERE ' . $this->_getTableField('domains', 'domain_name') . ' = ?';
71: Horde::logMessage($sql, 'DEBUG');
72: return $this->_db->getRow($sql, array($domain_name), DB_FETCHMODE_ASSOC);
73: }
74:
75: 76: 77: 78: 79:
80: protected function _saveDomain($info)
81: {
82: $record = array('domain_name' => $info['name'],
83: 'domain_transport' => $info['transport'],
84: 'domain_max_users' => (int)$info['max_users'],
85: 'domain_quota' => (int)$info['quota']);
86:
87: if (empty($info['domain_id'])) {
88: $record['domain_id'] = $this->_db->nextId($this->_params['tables']['domains']);
89: $values = $this->_prepareRecord('domains', $record);
90: $sql = sprintf('INSERT INTO %s (%s) VALUES (%s)',
91: $this->_params['tables']['domains'],
92: implode(', ', array_keys($values)),
93: implode(', ', array_fill(0, count($values), '?')));
94: $this->_db->insert($sql, $values);
95: } else {
96: $values = $this->_prepareRecord('domains', $record);
97: $sql = sprintf('UPDATE %s SET %s WHERE %s = ?',
98: $this->_params['tables']['domains'],
99: implode(' = ?, ', array_keys($values)) . ' = ?',
100: $this->_getTableField('domains', 'domain_id'));
101: $values[] = (int)$info['domain_id'];
102: $this->_db->update($sql, $values);
103: }
104: }
105:
106: 107: 108: 109: 110: 111: 112:
113: protected function _deleteDomain($domain_id)
114: {
115: $domain_record = $this->getDomain($domain_id);
116: $domain_name = $domain_record['domain_name'];
117:
118:
119: $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] .
120: ' WHERE ' . $this->_getTableField('virtuals', 'virtual_email') . ' LIKE ?';
121: $values = array('%@' . $domain_name);
122: Horde_Exception_Pear::catchError($this->_db->query($sql, $values));
123:
124:
125: $sql = 'DELETE FROM ' . $this->_params['tables']['users'] .
126: ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?';
127: $values = array('%@' . $domain_name);
128: Horde_Exception_Pear::catchError($this->_db->query($sql, $values));
129:
130:
131: $sql = 'DELETE FROM ' . $this->_params['tables']['domains'] .
132: ' WHERE ' . $this->_getTableField('domains', 'domain_id') . ' = ?';
133: $values = array((int)$domain_id);
134:
135: Horde::logMessage($sql, 'DEBUG');
136: return $this->_db->query($sql, $values);
137: }
138:
139: 140: 141: 142: 143: 144: 145: 146:
147: public function getDomainNumUsers($domain_name)
148: {
149: $sql = 'SELECT count(' . $this->_getTableField('users', 'user_name') . ')'
150: . ' FROM ' . $this->_params['tables']['users']
151: . ' WHERE ' . $this->_getTableField('users', 'user_name') . ' LIKE ?';
152: Horde::logMessage($sql, 'DEBUG');
153: return $this->_db->getOne($sql, array('%@' . $domain_name));
154: }
155:
156: 157: 158: 159: 160: 161: 162: 163: 164:
165: public function getUsers($domain = null)
166: {
167:
168: if (is_null($domain)) {
169:
170: $sql = 'SELECT ' . $this->_getTableFields('users')
171: . ' FROM ' . $this->_params['tables']['users'];
172: $values = array();
173: } else {
174:
175: $user_field = $this->_getTableField('users', 'user_name');
176: $sql = 'SELECT ' . $this->_getTableFields('users')
177: . ' FROM ' . $this->_params['tables']['users']
178: . ' WHERE ' . $user_field . ' LIKE ?'
179: . ' ORDER BY ' . $user_field;
180: $values = array('%@' . $domain);
181: }
182: Horde::logMessage($sql, 'DEBUG');
183: return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC);
184: }
185:
186: 187: 188: 189: 190: 191: 192: 193:
194: public function getUser($user_id)
195: {
196: $sql = 'SELECT ' . $this->_getTableFields('users')
197: . ' FROM ' . $this->_params['tables']['users']
198: . ' WHERE ' . $this->_getTableField('users', 'user_id') . ' = ?';
199: Horde::logMessage($sql, 'DEBUG');
200: return $this->_db->getRow($sql, array((int)$user_id), DB_FETCHMODE_ASSOC);
201: }
202:
203: 204: 205: 206: 207: 208: 209: 210:
211: protected function _saveUser($info)
212: {
213:
214: $domain = Vilma::stripDomain($info['user_name']);
215: $this->getDomainByName($domain);
216:
217: if (empty($info['user_id'])) {
218: $info['user_id'] = $this->_db->nextId($this->_params['tables']['users']);
219: $create = true;
220: } else {
221: $create = false;
222: }
223:
224:
225: $mailboxes = Vilma_MailboxDriver::factory();
226: $mail_dir_base = $mailboxes->getParam('mail_dir_base');
227: if (is_null($mail_dir_base)) {
228: $mail_dir_base = '?';
229: }
230:
231: $tuple = array(
232: 'user_id' => (int)$info['user_id'],
233: 'user_name' => $info['user_name'],
234: 'user_full_name' => $info['user_full_name'],
235: 'user_home_dir' => $mail_dir_base,
236: 'user_mail_dir' => $domain . '/' . Vilma::stripUser($info['user_name']) . '/',
237: 'user_mail_quota' => $this->getDomainQuota($domain) * 1024 * 1024,
238: 'user_enabled' => (int)$info['user_enabled']);
239:
240:
241: $tuple['user_uid'] = $mailboxes->getParam('uid');
242: if (is_null($tuple['user_uid'])) {
243: $tuple['user_uid'] = -1;
244: }
245: $tuple['user_gid'] = $mailboxes->getParam('gid');
246: if (is_null($tuple['user_gid'])) {
247: $tuple['user_gid'] = -1;
248: }
249:
250: if (!empty($info['password'])) {
251: $tuple['user_clear'] = $info['password'];
252: $tuple['user_crypt'] = crypt($info['password'],
253: substr($info['password'], 0, 2));
254: } elseif ($create) {
255: throw new Vilma_Exception(_("Password must be supplied when creating a new user."));
256: }
257:
258: $values = $this->_prepareRecord('users', $tuple);
259: if ($create) {
260: $sql = sprintf('INSERT INTO %s (%s) VALUES (%s)',
261: $this->_params['tables']['users'],
262: implode(', ', array_keys($values)),
263: implode(', ', array_fill(0, count($values), '?')));
264: $this->_db->insert($sql, $values);
265: } else {
266: $sql = sprintf('UPDATE %s SET %s WHERE %s = ?',
267: $this->_params['tables']['users'],
268: implode(' = ?, ', array_keys($values)) . ' = ?',
269: $this->_getTableField('users', 'user_id'));
270: $values[] = (int)$info['user_id'];
271: $this->_db->update($sql, $values);
272: }
273:
274: return $info['user_id'];
275: }
276:
277: 278: 279: 280: 281: 282: 283:
284: public function deleteUser($user_id)
285: {
286: Horde_Exception_Pear::catchError($user = $this->getUser($user_id));
287:
288:
289: $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals'] .
290: ' WHERE ' . $this->_getTableField('virtuals', 'virtual_destination') . ' = ?';
291: $values = array($user['user_name']);
292:
293: Horde::logMessage($sql, 'DEBUG');
294: Horde_Exception_Pear::catchError($this->_db->query($sql, $values));
295:
296:
297: $sql = 'DELETE FROM ' . $this->_params['tables']['users'] .
298: ' WHERE ' . $this->_getTableField('users', 'user_id') . ' = ?';
299: $values = array((int)$user_id);
300:
301: Horde::logMessage($sql, 'DEBUG');
302: Horde_Exception_Pear::catchError($this->_db->query($sql, $values));
303:
304: Vilma_MailboxDriver::factory()
305: ->deleteMailbox(Vilma::stripUser($user['user_name']),
306: Vilma::stripDomain($user['user_name']));
307: }
308:
309: 310: 311: 312: 313: 314: 315: 316: 317: 318: 319: 320:
321: protected function _getAddresses($domain, $type = 'all')
322: {
323: $addresses = array();
324: if ($type == 'all' || $type == 'user') {
325: $addresses += $this->getUsers($domain);
326: }
327: if ($type == 'all' || $type == 'alias') {
328: $addresses += $this->getVirtuals($domain);
329: }
330: return $addresses;
331: }
332:
333: 334: 335: 336: 337: 338: 339: 340: 341:
342: public function getVirtuals($filter)
343: {
344: $email_field = $this->_getTableField('virtuals', 'virtual_email');
345: $destination_field = $this->_getTableField('virtuals', 'virtual_destination');
346:
347:
348: if (strpos($filter, '@') === false) {
349: $where = $email_field . ' LIKE ?';
350: $values = array('%@' . $filter);
351: } else {
352: $where = $destination_field . ' = ?';
353: $values = array($filter);
354: }
355:
356: $sql = 'SELECT ' . $this->_getTableFields('virtuals')
357: . ' FROM ' . $this->_params['tables']['virtuals']
358: . ' WHERE ' . $where
359: . ' ORDER BY ' . $destination_field . ', ' . $email_field;
360:
361: Horde::logMessage($sql, 'DEBUG');
362: return $this->_db->getAll($sql, $values, DB_FETCHMODE_ASSOC);
363: }
364:
365: 366: 367: 368: 369: 370: 371: 372:
373: public function getVirtual($virtual_id)
374: {
375: $sql = 'SELECT ' . $this->_getTableFields('virtuals')
376: . ' FROM ' . $this->_params['tables']['virtuals']
377: . ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?';
378:
379: Horde::logMessage($sql, 'DEBUG');
380: $virtual = $this->_db->getRow($sql, array((int)$virtual_id), DB_FETCHMODE_ASSOC);
381: $virtual['stripped_email'] = Vilma::stripUser($virtual['virtual_email']);
382:
383: return $virtual;
384: }
385:
386: 387: 388: 389: 390: 391: 392: 393:
394: public function saveVirtual($info, $domain)
395: {
396:
397: $this->getDomainByName($domain);
398:
399: if (empty($info['virtual_id'])) {
400: $info['virtual_id'] = $this->_db->nextId($this->_params['tables']['virtuals']);
401: $sql = 'INSERT INTO ' . $this->_params['tables']['virtuals']
402: . ' (' . $this->_getTableField('virtuals', 'virtual_email') . ', '
403: . $this->_getTableField('virtuals', 'virtual_destination') . ', '
404: . $this->_getTableField('virtuals', 'virtual_id') . ') VALUES (?, ?, ?)';
405: } else {
406: $sql = 'UPDATE ' . $this->_params['tables']['virtuals']
407: . ' SET ' . $this->_getTableField('virtuals', 'virtual_email') . ' = ?, '
408: . $this->_getTableField('virtuals', 'virtual_destination') . ' = ?'
409: . ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?';
410: }
411: $values = array($info['stripped_email'] . '@' . $domain,
412: $info['virtual_destination'],
413: $info['virtual_id']);
414:
415: Horde::logMessage($sql, 'DEBUG');
416: return $this->_db->query($sql, $values);
417: }
418:
419: 420: 421: 422: 423:
424: public function deleteVirtual($virtual_id)
425: {
426: $sql = 'DELETE FROM ' . $this->_params['tables']['virtuals']
427: . ' WHERE ' . $this->_getTableField('virtuals', 'virtual_id') . ' = ?';
428: Horde::logMessage($sql, 'DEBUG');
429: return $this->_db->query($sql, array($virtual_id));
430: }
431:
432: 433: 434: 435: 436:
437: protected function _getTableFields($table)
438: {
439: if (empty($this->_params['tables'][$table . '_fields'])) {
440: switch ($table) {
441: case 'domains':
442: return 'domain_id, domain_name, domain_transport, domain_max_users, domain_quota';
443: default:
444: return '*';
445: }
446: }
447:
448: $domainsFields = $this->_params['tables'][$table . '_fields'];
449: foreach ($domainsFields as $defaultName => $customName) {
450: $fields[] = $customName . ' AS ' . $defaultName;
451: }
452:
453: return implode(', ', $fields);
454: }
455:
456: 457: 458: 459: 460: 461:
462: protected function _getTableField($table, $field)
463: {
464: if (empty($this->_params['tables'][$table . '_fields'])) {
465: return $field;
466: }
467: return $this->_params['tables'][$table . '_fields'][$field];
468: }
469:
470: 471: 472: 473: 474:
475: protected function _prepareRecord($table, $record)
476: {
477: if (empty($this->_params['tables'][$table . '_fields'])) {
478: return $record;
479: }
480:
481: $domainsFields = $this->_params['tables'][$table . '_fields'];
482: $newRecord = array();
483: foreach ($record as $defaultName => $value) {
484: $newRecord[$domainsFields[$defaultName]] = $record[$defaultName];
485: }
486: return $newRecord;
487: }
488:
489: 490: 491: 492: 493:
494: protected function _initialize()
495: {
496: try {
497: $this->_db = $GLOBALS['injector']->getInstance('Horde_Core_Factory_DbPear')->create('rw', 'vilma', 'storage');
498: } catch (Exception $e) {
499: throw new Vilma_Exception($e);
500: }
501:
502:
503: if (!isset($this->_params['tables']['domains'])) {
504: $this->_params['tables']['domains'] = 'vilma_domains';
505: }
506: if (!isset($this->_params['tables']['users'])) {
507: $this->_params['tables']['users'] = 'vilma_users';
508: }
509: if (!isset($this->_params['tables']['virtuals'])) {
510: $this->_params['tables']['virtuals'] = 'vilma_virtuals';
511: }
512: }
513: }
514: