1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: class Sam_Driver_Amavisd_Sql extends Sam_Driver_Base
15: {
16: 17: 18: 19: 20:
21: protected $_db;
22:
23: 24: 25: 26: 27:
28: protected $_capabilities = array('tag_level',
29: 'hit_level',
30: 'kill_level',
31: 'rewrite_sub',
32: 'spam_extension',
33: 'virus_extension',
34: 'banned_extension',
35: 'spam_quarantine',
36: 'allow_virus',
37: 'allow_spam',
38: 'allow_banned',
39: 'allow_header',
40: 'skip_virus',
41: 'skip_spam',
42: 'skip_banned',
43: 'skip_header',
44: 'whitelist_from',
45: 'blacklist_from');
46:
47: 48: 49: 50: 51: 52: 53: 54: 55:
56: public function __construct($user, $params = array())
57: {
58: foreach (array('db', 'table_map') as $param) {
59: if (!isset($params[$param])) {
60: throw new InvalidArgumentException(
61: sprintf('"%s" parameter is missing', $param));
62: }
63: }
64:
65: $this->_db = $params['db'];
66: unset($params['db']);
67:
68: parent::__construct($user, $params);
69: }
70:
71: 72: 73: 74: 75:
76: public function retrieve()
77: {
78:
79: $userID = $this->_lookupUserID();
80:
81:
82: $policyID = $this->_lookupPolicyID();
83:
84:
85: try {
86: $result = $this->_db->selectOne(
87: sprintf('SELECT * FROM %s WHERE %s = ?',
88: $this->_mapNameToTable('policies'),
89: $this->_mapAttributeToField('policies', 'id')),
90: array($policyID));
91: } catch (Horde_Db_Exception $e) {
92: throw new Sam_Exception($e);
93: }
94:
95:
96: if ($result) {
97: foreach ($result as $field => $value) {
98: $attribute = $this->_mapFieldToAttribute('policies', $field);
99: if ($this->hasCapability($attribute) && !is_null($value)) {
100: $this->_options[$attribute] = $value;
101: }
102: }
103: }
104:
105:
106: try {
107: $result = $this->_db->select(
108: sprintf('SELECT %s, %s FROM %s WHERE %s = ?',
109: $this->_mapAttributeToField('wblists', 'sender'),
110: $this->_mapAttributeToField('wblists', 'type'),
111: $this->_mapNameToTable('wblists'),
112: $this->_mapAttributeToField('wblists', 'recipient')),
113: array($userID));
114: } catch (Horde_Db_Exception $e) {
115: throw new Sam_Exception($e);
116: }
117:
118:
119: foreach ($result as $row) {
120: $type = $row[$this->_mapAttributeToField('wblists', 'type')];
121: $senderID = $row[$this->_mapAttributeToField('wblists', 'sender')];
122:
123:
124: if (preg_match('/[WYBN]/i', $type)) {
125: try {
126: $sender = $this->_db->selectValue(
127: sprintf('SELECT %s FROM %s WHERE %s = ?',
128: $this->_mapAttributeToField('senders', 'email'),
129: $this->_mapNameToTable('senders'),
130: $this->_mapAttributeToField('senders', 'id')),
131: array($senderID));
132: } catch (Horde_Db_Exception $e) {
133: throw new Sam_Exception($e);
134: }
135:
136: $list = preg_match('/[WY]/i', $type)
137: ? 'whitelist_from'
138: : 'blacklist_from';
139: if (isset($this->_options[$list])) {
140: if (!in_array($sender, $this->_options[$list])) {
141: $this->_options[$list][] = $sender;
142: }
143: } else {
144: $this->_options[$list] = array($sender);
145: }
146: }
147: }
148: }
149:
150: 151: 152: 153: 154: 155: 156: 157:
158: public function store($defaults = false)
159: {
160:
161: $policyID = $this->_lookupPolicyID();
162:
163:
164: if ($policyID !== false) {
165: try {
166: $this->_db->delete(
167: sprintf('DELETE FROM %s WHERE %s = ?',
168: $this->_mapNameToTable('policies'),
169: $this->_mapAttributeToField('policies', 'name')),
170: array($this->_user));
171: } catch (Horde_Db_Exception $e) {
172: throw new Sam_Exception($e);
173: }
174: }
175:
176:
177: $insertKeys = $insertVals = array();
178: foreach ($this->_options as $attribute => $value) {
179: if ($attribute != 'whitelist_from' &&
180: $attribute != 'blacklist_from') {
181: $insertKeys[] = $this->_mapAttributeToField('policies', $attribute);
182: $insertVals[] = strlen($value) ? $value : null;
183: }
184: }
185: if (count($insertKeys)) {
186: try {
187: $this->_db->insert(
188: sprintf('INSERT INTO %s (%s, %s) VALUES (%s)',
189: $this->_mapNameToTable('policies'),
190: $this->_mapAttributeToField('policies', 'name'),
191: implode(', ', $insertKeys),
192: implode(', ', array_fill(0, count($insertVals) + 1, '?'))),
193: array_merge(array($this->_user), $insertVals));
194: } catch (Horde_Db_Exception $e) {
195: throw new Sam_Exception($e);
196: }
197: }
198:
199:
200: $policyID = $this->_lookupPolicyID();
201:
202:
203: try {
204: $this->_db->update(
205: sprintf('UPDATE %s SET %s = ? WHERE %s = ?',
206: $this->_mapNameToTable('recipients'),
207: $this->_mapAttributeToField('recipients', 'policy_id'),
208: $this->_mapAttributeToField('recipients', 'email')),
209: array($policyID, $this->_user));
210: } catch (Horde_Db_Exception $e) {
211: throw new Sam_Exception($e);
212: }
213:
214:
215: $userID = $this->_lookupUserID();
216:
217:
218: try {
219: $result = $this->_db->select(
220: sprintf('SELECT %s, %s FROM %s WHERE %s = ?',
221: $this->_mapAttributeToField('wblists', 'sender'),
222: $this->_mapAttributeToField('wblists', 'type'),
223: $this->_mapNameToTable('wblists'),
224: $this->_mapAttributeToField('wblists', 'recipient')),
225: array($userID));
226: } catch (Horde_Db_Exception $e) {
227: throw new Sam_Exception($e);
228: }
229:
230:
231: $existing = array('whitelist_from' => array(),
232: 'blacklist_from' => array());
233: foreach ($result as $row) {
234: $type = $row[$this->_mapAttributeToField('wblists', 'type')];
235: $senderID = $row[$this->_mapAttributeToField('wblists', 'sender')];
236:
237:
238: if (preg_match('/[WYBN]/i', $type)) {
239: try {
240: $sender = $this->_db->selectValue(
241: sprintf('SELECT %s FROM %s WHERE %s = ?',
242: $this->_mapAttributeToField('senders', 'email'),
243: $this->_mapNameToTable('senders'),
244: $this->_mapAttributeToField('senders', 'id')),
245: array($senderID));
246: } catch (Horde_Db_Exception $e) {
247: throw new Sam_Exception($e);
248: }
249:
250: $list = preg_match('/[WY]/i', $type)
251: ? 'whitelist_from'
252: : 'blacklist_from';
253:
254: if (isset($this->_options[$list]) &&
255: in_array($sender, $this->_options[$list])) {
256: $existing[$list][] = $sender;
257: } else {
258:
259: try {
260: $this->_db->delete(
261: sprintf('DELETE FROM %s WHERE %s = ? AND %s = ?',
262: $this->_mapNameToTable('wblists'),
263: $this->_mapAttributeToField('wblists', 'sender'),
264: $this->_mapAttributeToField('wblists', 'recipient')),
265: array($senderID, $userID));
266: } catch (Horde_Db_Exception $e) {
267: throw new Sam_Exception($e);
268: }
269:
270: 271:
272: $query = sprintf('SELECT 1 FROM %s WHERE %s = ?',
273: $this->_mapNameToTable('wblists'),
274: $this->_mapAttributeToField('wblists', 'sender'));
275: if (!$this->_db->selectValue($query, array($senderID))) {
276: 277:
278: try {
279: $this->_db->delete(
280: sprintf('DELETE FROM %s WHERE %s = ?',
281: $this->_mapNameToTable('senders'),
282: $this->_mapAttributeToField('senders', 'id')),
283: array($senderID));
284: } catch (Horde_Db_Exception $e) {
285: throw new Sam_Exception($e);
286: }
287: }
288: }
289: }
290: }
291:
292:
293: foreach (array('whitelist_from' => 'W', 'blacklist_from' => 'B') as $list => $type) {
294: if (!isset($this->_options[$list])) {
295: continue;
296: }
297:
298: foreach ($this->_options[$list] as $sender) {
299: if (in_array($sender, $existing[$list])) {
300: continue;
301: }
302:
303:
304: $wb_result = $this->_db->selectValue(
305: sprintf('SELECT %s FROM %s WHERE %s = ?',
306: $this->_mapAttributeToField('senders', 'id'),
307: $this->_mapNameToTable('senders'),
308: $this->_mapAttributeToField('senders', 'email')),
309: array($sender));
310:
311: if ($wb_result !== false) {
312:
313: $senderID = $wb_result;
314: } else {
315:
316: try {
317: $this->_db->insert(
318: sprintf('INSERT INTO %s (%s) VALUES (?)',
319: $this->_mapNameToTable('senders'),
320: $this->_mapAttributeToField('senders', 'email')),
321: array($sender));
322: } catch (Horde_Db_Exception $e) {
323: throw new Sam_Exception($e);
324: }
325:
326: try {
327: $senderID = $this->_db->selectValue(
328: sprintf('SELECT %s FROM %s WHERE %s = ?',
329: $this->_mapAttributeToField('senders', 'id'),
330: $this->_mapNameToTable('senders'),
331: $this->_mapAttributeToField('senders', 'email')),
332: array($sender));
333: } catch (Horde_Db_Exception $e) {
334: throw new Sam_Exception($e);
335: }
336: }
337:
338: try {
339: $this->_db->insert(
340: sprintf('INSERT INTO %s (%s, %s, %s) VALUES (?, ?, ?)',
341: $this->_mapNameToTable('wblists'),
342: $this->_mapAttributeToField('wblists', 'recipient'),
343: $this->_mapAttributeToField('wblists', 'sender'),
344: $this->_mapAttributeToField('wblists', 'type')),
345: array($userID, $senderID, $type));
346: } catch (Horde_Db_Exception $e) {
347: throw new Sam_Exception($e);
348: }
349: }
350: }
351:
352:
353: try {
354: $this->_db->delete(
355: sprintf('DELETE FROM %s WHERE %s = ?',
356: $this->_mapNameToTable('wblists'),
357: $this->_mapAttributeToField('wblists', 'recipient')),
358: array(''));
359: } catch (Horde_Db_Exception $e) {
360: throw new Sam_Exception($e);
361: }
362: }
363:
364: 365: 366: 367: 368: 369: 370:
371: public function booleanToOption($boolean)
372: {
373: return $boolean ? 'Y' : 'N';
374: }
375:
376: 377: 378: 379: 380: 381: 382: 383:
384: protected function _mapNameToTable($table)
385: {
386: return isset($this->_params['table_map'][$table]['name'])
387: ? $this->_params['table_map'][$table]['name']
388: : $table;
389: }
390:
391: 392: 393: 394: 395: 396: 397: 398: 399: 400:
401: protected function _mapAttributeToField($table, $attribute)
402: {
403: return isset($this->_params['table_map'][$table]['field_map'][$attribute])
404: ? $this->_params['table_map'][$table]['field_map'][$attribute]
405: : $attribute;
406: }
407:
408: 409: 410: 411: 412: 413: 414: 415: 416:
417: protected function _mapFieldToAttribute($table, $field)
418: {
419: $attribute_map = array();
420: if (isset($this->_params['table_map'][$table]['field_map'])) {
421: $attribute_map = array_flip($this->_params['table_map'][$table]['field_map']);
422: }
423:
424: return isset($attribute_map[$field]) ? $attribute_map[$field] : $field;
425: }
426:
427: 428: 429: 430: 431: 432: 433:
434: protected function _createUserID()
435: {
436: try {
437: $this->_db->insert(
438: sprintf('INSERT INTO %s (%s) VALUES (?)',
439: $this->_mapNameToTable('recipients'),
440: $this->_mapAttributeToField('recipients', 'email')),
441: array($this->_user));
442: } catch (Horde_Db_Exception $e) {
443: throw new Sam_Exception(sprintf(_("Cannot create recipient %s: %s"),
444: $this->_user, $e->getMessage()));
445: }
446: $GLOBALS['notification']->push(sprintf(_("Recipient created: %s"),
447: $this->_user), 'horde.success');
448: return $this->_lookupUserID();
449: }
450:
451: 452: 453: 454: 455: 456: 457:
458: protected function _lookupUserID()
459: {
460: try {
461: $userID = $this->_db->selectValue(
462: sprintf('SELECT %s FROM %s WHERE %s = ?',
463: $this->_mapAttributeToField('recipients', 'id'),
464: $this->_mapNameToTable('recipients'),
465: $this->_mapAttributeToField('recipients', 'email')),
466: array($this->_user));
467: } catch (Horde_Db_Exception $e) {
468: throw new Sam_Exception($e);
469: }
470:
471: if ($userID === false) {
472: $userID = $this->_createUserID();
473: }
474:
475: return $userID;
476: }
477:
478: 479: 480: 481: 482: 483: 484:
485: protected function _lookupPolicyID()
486: {
487: try {
488: return $this->_db->selectValue(
489: sprintf('SELECT %s FROM %s WHERE %s = ?',
490: $this->_mapAttributeToField('policies', 'id'),
491: $this->_mapNameToTable('policies'),
492: $this->_mapAttributeToField('policies', 'name')),
493: array($this->_user));
494: } catch (Horde_Db_Exception $e) {
495: return false;
496: }
497: }
498: }
499: