1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
16: class IMP_Spam
17: {
18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
33: static public function reportSpam(IMP_Indices $indices, $action,
34: array $opts = array())
35: {
36: global $conf, $injector, $notification, $prefs, $registry;
37:
38: 39:
40: if (empty($conf[$action]['reporting']) ||
41: !count($indices)) {
42: return 0;
43: }
44:
45: $report_count = $result = 0;
46:
47: foreach ($indices as $ob) {
48: try {
49: $ob->mbox->uidvalid;
50: } catch (IMP_Exception $e) {
51: continue;
52: }
53:
54: foreach ($ob->uids as $idx) {
55: 56:
57: try {
58: $imp_contents = $injector->getInstance('IMP_Factory_Contents')->create($ob->mbox->getIndicesOb($idx));
59: } catch (IMP_Exception $e) {
60: continue;
61: }
62:
63: $raw_msg = $to = null;
64: $report_flag = false;
65:
66: 67:
68: if (!empty($conf[$action]['program'])) {
69: $raw_msg = $imp_contents->fullMessageText(array('stream' => true));
70:
71: 72:
73: $prog = str_replace(array('%u','%l', '%d'),
74: array(
75: escapeshellarg($registry->getAuth()),
76: escapeshellarg($registry->getAuth('bare')),
77: escapeshellarg($registry->getAuth('domain'))
78: ), $conf[$action]['program']);
79: $proc = proc_open($prog,
80: array(
81: 0 => array('pipe', 'r'),
82: 1 => array('pipe', 'w'),
83: 2 => array('pipe', 'w')
84: ), $pipes);
85: if (!is_resource($proc)) {
86: Horde::logMessage('Cannot open process ' . $prog, 'ERR');
87: return 0;
88: }
89: stream_copy_to_stream($raw_msg, $pipes[0]);
90: fclose($pipes[0]);
91: $stderr = '';
92: while (!feof($pipes[2])) {
93: $stderr .= fgets($pipes[2]);
94: }
95: fclose($pipes[2]);
96: if (!empty($stderr)) {
97: Horde::logMessage('Error reporting spam: ' . $stderr, 'ERR');
98: }
99: proc_close($proc);
100: $report_flag = true;
101: }
102:
103: 104:
105: if (!empty($conf[$action]['email'])) {
106: $to = $conf[$action]['email'];
107: } else {
108:
109: try {
110: $to = Horde::callHook('spam_email', array($action), 'imp');
111: } catch (Horde_Exception_HookNotSet $e) {}
112: }
113:
114: if ($to) {
115: if (!isset($imp_compose)) {
116: $imp_compose = $injector->getInstance('IMP_Factory_Compose')->create();
117: }
118:
119: if (!isset($conf[$action]['email_format'])) {
120: $conf[$action]['email_format'] = 'digest';
121: }
122:
123: switch ($conf[$action]['email_format']) {
124: case 'redirect':
125: $index = new IMP_Indices($ob->mbox, $idx);
126: $imp_compose->redirectMessage($index);
127:
128:
129: try {
130: $imp_compose->sendRedirectMessage($to, false);
131: $report_flag = true;
132: } catch (IMP_Compose_Exception $e) {
133: $e->log();
134: }
135: break;
136:
137: case 'digest':
138: default:
139: try {
140: $from_line = $injector->getInstance('IMP_Identity')->getFromLine();
141: } catch (Horde_Exception $e) {
142: $from_line = null;
143: }
144:
145: if (!isset($raw_msg)) {
146: $raw_msg = $imp_contents->fullMessageText(array('stream' => true));
147: }
148:
149:
150: $mime = new Horde_Mime_Part();
151: $mime->setType('multipart/digest');
152:
153: $rfc822 = new Horde_Mime_Part();
154: $rfc822->setType('message/rfc822');
155: $rfc822->setContents($raw_msg);
156: $mime->addPart($rfc822);
157:
158: $spam_headers = new Horde_Mime_Headers();
159: $spam_headers->addMessageIdHeader();
160: $spam_headers->addHeader('Date', date('r'));
161: $spam_headers->addHeader('To', $to);
162: if (!is_null($from_line)) {
163: $spam_headers->addHeader('From', $from_line);
164: }
165: $spam_headers->addHeader('Subject', sprintf(_("%s report from %s"), $action, $registry->getAuth()));
166:
167:
168: try {
169: $recip_list = $imp_compose->recipientList(array('to' => $to));
170: $imp_compose->sendMessage($recip_list['list'], $spam_headers, $mime, 'UTF-8');
171: $report_flag = true;
172: } catch (IMP_Compose_Exception $e) {
173: $e->log();
174: }
175: break;
176: }
177: }
178:
179: if ($report_flag) {
180: ++$report_count;
181: }
182: }
183: }
184:
185: if (!$report_count) {
186: return 0;
187: }
188:
189:
190: if ($report_count == 1) {
191: $hdrs = $imp_contents->getHeader();
192: if ($subject = $hdrs->getValue('subject')) {
193: $subject = Horde_String::truncate($subject, 30);
194: } elseif ($from = $hdrs->getValue('from')) {
195: $from = Horde_String::truncate($from, 30);
196: } else {
197: $subject = '[' . _("No Subject") . ']';
198: }
199:
200: switch ($action) {
201: case 'spam':
202: $msg = $subject
203: ? sprintf(_("The message \"%s\" has been reported as spam."), $subject)
204: : sprintf(_("The message from \"%s\" has been reported as spam."), $from);
205: break;
206:
207: case 'notspam':
208: $msg = $subject
209: ? sprintf(_("The message \"%s\" has been reported as innocent."), $subject)
210: : sprintf(_("The message from \"%s\" has been reported as innocent."), $from);
211: break;
212: }
213: } elseif ($action == 'spam') {
214: $msg = sprintf(_("%d messages have been reported as spam."), $report_count);
215: } else {
216: $msg = sprintf(_("%d messages have been reported as innocent."), $report_count);
217: }
218: $notification->push($msg, 'horde.message');
219:
220: $mbox_args = array();
221: if (isset($opts['mailboxob'])) {
222: $mbox_args['mailboxob'] = $opts['mailboxob'];
223: }
224:
225:
226: try {
227: Horde::callHook('post_spam', array($action, $indices), 'imp');
228: } catch (Horde_Exception_HookNotSet $e) {}
229:
230: if (!empty($opts['noaction'])) {
231: return $result;
232: }
233:
234:
235: switch ($action) {
236: case 'spam':
237:
238: $imp_message = $injector->getInstance('IMP_Message');
239: $imp_message->flag(array('$junk'), $indices, true);
240: $imp_message->flag(array('$notjunk'), $indices, false);
241:
242: if ($result = $prefs->getValue('delete_spam_after_report')) {
243: switch ($result) {
244: case 1:
245: $msg_count = $imp_message->delete($indices, $mbox_args);
246: if ($msg_count === false) {
247: $result = 0;
248: } else {
249: if ($msg_count == 1) {
250: $notification->push(_("The message has been deleted."), 'horde.message');
251: } else {
252: $notification->push(sprintf(_("%d messages have been deleted."), $msg_count), 'horde.message');
253: }
254: }
255: break;
256:
257: case 2:
258: if ($targetMbox = IMP_Mailbox::getPref('spam_folder')) {
259: if (!$imp_message->copy($targetMbox, 'move', $indices, array_merge($mbox_args, array('create' => true)))) {
260: $result = 0;
261: }
262: } else {
263: $notification->push(_("Could not move message to spam mailbox - no spam mailbox defined in preferences."), 'horde.error');
264: $result = 0;
265: }
266: break;
267: }
268: }
269: break;
270:
271: case 'notspam':
272:
273: $imp_message = $injector->getInstance('IMP_Message');
274: $imp_message->flag(array('$notjunk'), $indices, true);
275: $imp_message->flag(array('$junk'), $indices, false);
276:
277: if (($result = $prefs->getValue('move_ham_after_report')) &&
278: !$imp_message->copy('INBOX', 'move', $indices, $mbox_args)) {
279: $result = 0;
280: }
281: break;
282: }
283:
284: return $result;
285: }
286:
287: }
288: