Integrate markasjunk2 features into markasjunk - marking as non-junk + learning engine (#6504)

pull/6517/head
Aleksander Machniak 6 years ago committed by GitHub
parent 70657e34b0
commit cb6c79e2dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,133 @@
Roundcube Webmail MarkAsJunk Plugin
===================================
This plugin adds "mark as spam" or "mark as not spam" button to the message
menu.
When not in the Junk mailbox:
Messages are moved into the Junk mailbox and marked as read
When in the Junk mailbox:
The buttons are changed to "mark as not spam" or "this message is not spam"
and the message is moved to the Inbox
License
-------
This plugin is released under the [GNU General Public License Version 3+][gpl].
Even if skins might contain some programming work, they are not considered
as a linked part of the plugin and therefore skins DO NOT fall under the
provisions of the GPL license. See the README file located in the core skins
folder for details on the skin license.
Configuration
-------------
The default config file is plugins/markasjunk/config.inc.php.dist
Rename this to plugins/markasjunk/config.inc.php
All config parameters are optional.
The Learning Driver
-------------------
The learning driver allows you to perform additional processing on each message
marked as spam/ham. A driver must contain a class named markasjunk_{driver
file name}. The class must contain 3 functions:
**spam:** This function should take 2 arguments: an array of UIDs of message(s)
being marked as spam, the name of the mailbox containing those messages
**ham:** This function should take 2 arguments: an array of UIDs of message(s)
being marked as ham, the name of the mailbox containing those messages
**init:** Optional, this function should take 0 arguments. eg: allows drivers
to add JS to the page to control which of the spam/ham options are displayed.
The `jsevents` driver is available to show how to use the JS events.
Several drivers are provided by default they are:
**cmd_learn:** This driver calls an external command (for example salearn) to
process the message
**dir_learn:** This driver places a copy of the message in a predefined folder,
for example to allow for processing later
**email_learn:** This driver emails the message either as an attachment or
directly to a set address. This driver requires Roundcube 1.4 or above.
**sa_blacklist:** This driver adds the sender address of a spam message to the
users blacklist (or whitelist of ham messages) Requires SAUserPrefs plugin
**amavis_blacklist:** This driver adds the sender address of a spam message to
the users blacklist (or whitelist of ham messages) Requires Amacube plugin.
Driver by Der-Jan
**sa_detach:** If the message is a Spamassassin spam report with the original
email attached then this is detached and saved in the Inbox, the spam report is
deleted
**edit_headers:** Edit the message headers. Headers are edited using
preg_replace.
**WARNING:** Be sure to match the entire header line, including the name of the
header, and include the ^ and $ and test carefully before use on real messages.
This driver alters the message source
Running multiple drivers
------------------------
**WARNING:** This is very dangerous please always test carefully. Run multiple
drivers at your own risk! It may be safer to create one driver that does
everything you want.
It is possible to run multiple drivers when marking a message as spam/ham. For
example running sa_blacklist followed by cmd_learn or edit_headers and
cmd_learn. An [example multi-driver][multidriver] is available. This is a
starting point only, it requires modification for individual cases.
Spam learning commands
----------------------
Spamassassin:
```sa-learn --spam --username=%u %f``` or
```sa-learn --spam --prefs-file=/var/mail/%d/%l/.spamassassin/user_prefs %f```
Ham learning commands
---------------------
Spamassassin:
```sa-learn --ham --username=%u %f``` or
```sa-learn --ham --prefs-file=/var/mail/%d/%l/.spamassassin/user_prefs %f```
edit_headers example config
---------------------------
**WARNING:** These are simple examples of how to configure the driver options,
use at your own risk
```php
$config['markasjunk_spam_patterns'] = array(
'patterns' => array('/^(Subject:\s*)(.*)$/m'),
'replacements' => array('$1[SPAM] $2')
);
```
```php
$config['markasjunk_ham_patterns'] = array(
'patterns' => array('/^(Subject:\s*)\[SPAM\](.*)$/m'),
'replacements' => array('$1$2')
);
```
[gpl]: https://www.gnu.org/licenses/gpl.html
[multidriver]: https://gist.github.com/johndoh/8173505

@ -1,14 +1,19 @@
{
"name": "roundcube/markasjunk",
"type": "roundcube-plugin",
"description": "Adds a new button to the mailbox toolbar to mark the selected messages as Junk and move them to the configured Junk folder.",
"description": "Adds buttons to mark messages as Junk/Non-Junk with moving to the Junk folder and Spam/Ham learning.",
"license": "GPLv3+",
"version": "1.2",
"version": "2.0",
"authors": [
{
"name": "Thomas Bruederli",
"email": "roundcube@gmail.com",
"role": "Lead"
},
{
"name": "Philip Weir",
"email": "roundcube@tehinterweb.co.uk",
"role": "Developer"
}
],
"repositories": [

@ -0,0 +1,167 @@
<?php
// Learning driver
// Use an external process such as sa-learn to learn from spam/ham messages. Default: null.
// Please see the README for more information
$config['markasjunk_learning_driver'] = null;
// Ham mailbox
// Mailbox messages should be moved to when they are marked as ham. null = INBOX
// set to FALSE to disable message moving
$config['markasjunk_ham_mbox'] = null;
// Spam mailbox
// Mailbox messages should be moved to when they are marked as spam.
// null = the mailbox assigned as the spam folder in Roundcube settings
// set to FALSE to disable message moving
$config['markasjunk_spam_mbox'] = null;
// Mark messages as read when reporting them as spam
$config['markasjunk_read_spam'] = false;
// Mark messages as unread when reporting them as ham
$config['markasjunk_unread_ham'] = false;
// Add flag to messages marked as spam (flag will be removed when marking as ham)
// If you do not want to use message flags set this to false
$config['markasjunk_spam_flag'] = 'Junk';
// Add flag to messages marked as ham (flag will be removed when marking as spam)
// If you do not want to use message flags set this to false
$config['markasjunk_ham_flag'] = 'NonJunk';
// Write output from spam/ham commands to the log for debug
$config['markasjunk_debug'] = false;
// The mark as spam/ham icon can either be displayed on the toolbar or as part of the mark messages menu.
// Set to False to use Mark menu instead of the toolbar. Default: true.
$config['markasjunk_toolbar'] = true;
// Learn any message moved to the spam mailbox as spam (not just when the button is pressed)
$config['markasjunk_move_spam'] = false;
// Learn any message moved from the spam mailbox to the ham mailbox as ham (not just when the button is pressed)
$config['markasjunk_move_ham'] = false;
// Some drivers create new copies of the target message(s), in this case the original message(s) will be deleted
// Rather than deleting the message(s) (moving to Trash) setting this option true will cause the original message(s) to be permanently removed
$config['markasjunk_permanently_remove'] = false;
// Display only a mark as spam button
$config['markasjunk_spam_only'] = false;
// Activate markasjunk for selected mail hosts only. If this is not set all mail hosts are allowed.
// Example: $config['markasjunk_allowed_hosts'] = array('mail1.domain.tld', 'mail2.domain.tld');
$config['markasjunk_allowed_hosts'] = null;
// Load specific config for different mail hosts
// Example: $config['markasjunk_host_config'] = array(
// 'mail1.domain.tld' => 'mail1_config.inc.php',
// 'mail2.domain.tld' => 'mail2_config.inc.php',
// );
$config['markasjunk_host_config'] = null;
// cmd_learn Driver options
// ------------------------
// The command used to learn that a message is spam
// The command can contain the following macros that will be expanded as follows:
// %u is replaced with the username (from the session info)
// %l is replaced with the local part of the username (if the username is an email address)
// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
// %i is replaced with the email address from the user's default identity
// %s is replaced with the email address the message is from
// %f is replaced with the path to the message file
// %h:<header name> is replaced with the content of that header from the message (lower case) eg: %h:x-dspam-signature
// If you do not want to run the command set this to null
$config['markasjunk_spam_cmd'] = null;
// The command used to learn that a message is ham
// The command can contain the following macros that will be expanded as follows:
// %u is replaced with the username (from the session info)
// %l is replaced with the local part of the username (if the username is an email address)
// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
// %i is replaced with the email address from the user's default identity
// %s is replaced with the email address the message is from
// %f is replaced with the path to the message file
// %h:<header name> is replaced with the content of that header from the message (lower case) eg: %h:x-dspam-signature
// If you do not want to run the command set this to null
$config['markasjunk_ham_cmd'] = null;
// dir_learn Driver options
// ------------------------
// The full path of the directory used to store spam (must be writable by webserver)
$config['markasjunk_spam_dir'] = null;
// The full path of the directory used to store ham (must be writable by webserver)
$config['markasjunk_ham_dir'] = null;
// The filename prefix
// The filename can contain the following macros that will be expanded as follows:
// %u is replaced with the username (from the session info)
// %l is replaced with the local part of the username (if the username is an email address)
// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
// %t is replaced with the type of message (spam/ham)
$config['markasjunk_filename'] = null;
// email_learn Driver options
// --------------------------
// The email address that spam messages will be sent to
// The address can contain the following macros that will be expanded as follows:
// %u is replaced with the username (from the session info)
// %l is replaced with the local part of the username (if the username is an email address)
// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
// %i is replaced with the email address from the user's default identity
// If you do not want to send an email set this to null
$config['markasjunk_email_spam'] = null;
// The email address that ham messages will be sent to
// The address can contain the following macros that will be expanded as follows:
// %u is replaced with the username (from the session info)
// %l is replaced with the local part of the username (if the username is an email address)
// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
// %i is replaced with the email address from the user's default identity
// If you do not want to send an email set this to null
$config['markasjunk_email_ham'] = null;
// Should the spam/ham message be sent as an attachment
$config['markasjunk_email_attach'] = true;
// The email subject (when sending as attachment)
// The subject can contain the following macros that will be expanded as follows:
// %u is replaced with the username (from the session info)
// %l is replaced with the local part of the username (if the username is an email address)
// %d is replaced with the domain part of the username (if the username is an email address or default mail domain if not)
// %t is replaced with the type of message (spam/ham)
$config['markasjunk_email_subject'] = 'learn this message as %t';
// sa_blacklist Driver options
// ---------------------------
// Path to SAUserPrefs config file
$config['markasjunk_sauserprefs_config'] = '../sauserprefs/config.inc.php';
// amavis_blacklist Driver options
// ---------------------------
// Path to amacube config file
$config['markasjunk_amacube_config'] = '../amacube/config.inc.php';
// edit_headers Driver options
// ---------------------------
// Patterns to match and replace headers for spam messages
// Replacement method uses preg_replace - http://www.php.net/manual/function.preg-replace.php
// WARNING: Be sure to match the entire header line, including the name of the header, also use ^ and $ and the 'm' flag
// see the README for an example
// TEST CAREFULLY BEFORE USE ON REAL MESSAGES
$config['markasjunk_spam_patterns'] = array(
'patterns' => array(),
'replacements' => array()
);
// Patterns to match and replace headers for spam messages
// Replacement method uses preg_replace - http://www.php.net/manual/function.preg-replace.php
// WARNING: Be sure to match the entire header line, including the name of the header, also use ^ and $ and the 'm' flag
// see the README for an example
// TEST CAREFULLY BEFORE USE ON REAL MESSAGES
$config['markasjunk_ham_patterns'] = array(
'patterns' => array(),
'replacements' => array()
);

@ -0,0 +1,148 @@
<?php
/**
* AmavisD Blacklist driver
*
* @version 1.0
* @requires Amacube plugin
*
* @author Der-Jan
*
* Copyright (C) 2014 Der-Jan
*
* This driver is part of the MarkASJunk plugin for Roundcube.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see https://www.gnu.org/licenses/.
*/
/* # 'SELECT wb'.
* # ' FROM wblist JOIN mailaddr ON wblist.sid=mailaddr.id'.
* # ' WHERE wblist.rid=? AND mailaddr.email IN (%k)'.
* # ' ORDER BY mailaddr.priority DESC';
*/
class markasjunk_amavis_blacklist
{
private $user_email = '';
public function spam($uids, $src_mbox, $dst_mbox)
{
$this->_do_list($uids, true);
}
public function ham($uids, $src_mbox, $dst_mbox)
{
$this->_do_list($uids, false);
}
private function _do_list($uids, $spam)
{
$rcube = rcube::get_instance();
$this->user_email = $rcube->user->data['username'];
if (is_file($rcube->config->get('markasjunk_amacube_config')) && !$rcube->config->load_from_file($rcube->config->get('markasjunk_amacube_config'))) {
rcube::raise_error(array('code' => 527, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Failed to load config from " . $rcube->config->get('markasjunk_amacube_config')
), true, false);
return false;
}
$db = rcube_db::factory($rcube->config->get('amacube_db_dsn'), '', true);
$db->set_debug((bool) $rcube->config->get('sql_debug'));
$db->db_connect('w');
$debug = $rcube->config->get('markasjunk_debug');
// check DB connections and exit on failure
if ($err_str = $db->is_error()) {
rcube::raise_error(array(
'code' => 603,
'type' => 'db',
'message' => $err_str
), false, true);
}
$sql_result = $db->query("SELECT `id` FROM `users` WHERE `email` = ?", $this->user_email);
if ($sql_result && ($res_array = $db->fetch_assoc($sql_result))) {
$rid = $res_array['id'];
}
else {
if ($debug) {
rcube::write_log('markasjunk', $this->user_email . ' not found in users table');
}
return false;
}
foreach ($uids as $uid) {
$message = new rcube_message($uid);
$email = $message->sender['mailto'];
$sql_result = $db->query("SELECT `id` FROM `mailaddr` WHERE `email` = ? ORDER BY `priority` DESC", $email);
if ($sql_result && ($res_array = $db->fetch_assoc($sql_result))) {
$sid = $res_array['id'];
}
else {
if ($debug) {
rcube::write_log('markasjunk', $email . ' not found in mailaddr table - add it');
}
$sql_result = $db->query("INSERT INTO `mailaddr` ( `priority`, `email` ) VALUES ( 20, ? )", $email);
if ($sql_result) {
$sid = $db->insert_id();
}
else {
if ($debug) {
rcube::write_log('markasjunk', 'Cannot add ' . $email . ' to mailaddr table: ' . $db->is_error($sql_result));
}
return false;
}
}
$wb = '';
$sql_result = $db->query("SELECT `wb` FROM `wblist` WHERE `sid` = ? AND `rid` =?", $sid, $rid);
if ($sql_result && ($res_array = $db->fetch_assoc($sql_result))) {
$wb = $res_array['wb'];
}
if (!$wb || (!$spam && preg_match('/^([BbNnFf])[\s]*\z/', $wb)) || ($spam && preg_match('/^([WwYyTt])[\s]*\z/', $wb))) {
$newwb = 'w';
if ($spam) {
$newwb = 'b';
}
if ($wb) {
$sql_result = $db->query('UPDATE `wblist` SET `wb` = ? WHERE `sid` = ? AND `rid` = ?',
$newwb, $sid, $rid);
}
else {
$sql_result = $db->query('INSERT INTO `wblist` (`sid`, `rid`, `wb`) VALUES (?,?,?)',
$sid, $rid, $newwb);
}
if (!$sql_result) {
if ($debug) {
rcube::write_log('markasjunk', 'Cannot update wblist for user ' . $this->user_email . ' with ' . $email);
}
return false;
}
}
}
}
}

@ -0,0 +1,114 @@
<?php
/**
* Command line learn driver
*
* @version 3.0
*
* @author Philip Weir
* Patched by Julien Vehent to support DSPAM
* Enhanced support for DSPAM by Stevan Bajic <stevan@bajic.ch>
*
* Copyright (C) 2009-2018 Philip Weir
*
* This driver is part of the MarkASJunk plugin for Roundcube.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see https://www.gnu.org/licenses/.
*/
class markasjunk_cmd_learn
{
public function spam($uids, $src_mbox, $dst_mbox)
{
$this->_do_salearn($uids, true, $src_mbox);
}
public function ham($uids, $src_mbox, $dst_mbox)
{
$this->_do_salearn($uids, false, $src_mbox);
}
private function _do_salearn($uids, $spam, $src_mbox)
{
$rcube = rcube::get_instance();
$temp_dir = realpath($rcube->config->get('temp_dir'));
$command = $rcube->config->get($spam ? 'markasjunk_spam_cmd' : 'markasjunk_ham_cmd');
$debug = $rcube->config->get('markasjunk_debug');
if (!$command) {
return;
}
// backwards compatibility %xds removed in markasjunk v1.12
$command = str_replace('%xds', '%h:x-dspam-signature', $command);
$command = str_replace('%u', $_SESSION['username'], $command);
$command = str_replace('%l', $rcube->user->get_username('local'), $command);
$command = str_replace('%d', $rcube->user->get_username('domain'), $command);
if (strpos($command, '%i') !== false) {
$identity_arr = $rcube->user->get_identity();
$command = str_replace('%i', $identity_arr['email'], $command);
}
foreach ($uids as $uid) {
// reset command for next message
$tmp_command = $command;
if (strpos($tmp_command, '%s') !== false) {
$message = new rcube_message($uid);
$tmp_command = str_replace('%s', escapeshellarg($message->sender['mailto']), $tmp_command);
}
if (strpos($command, '%h') !== false) {
$storage = $rcube->get_storage();
$storage->check_connection();
$storage->conn->select($src_mbox);
preg_match_all('/%h:([\w-_]+)/', $tmp_command, $header_names, PREG_SET_ORDER);
foreach ($header_names as $header) {
$val = null;
if ($msg = $storage->conn->fetchHeader($src_mbox, $uid, true, false, array($header[1]))) {
$val = $msg->{$header[1]} ?: $msg->others[$header[1]];
}
if (!empty($val)) {
$tmp_command = str_replace($header[0], escapeshellarg($val), $tmp_command);
}
else {
if ($debug) {
rcube::write_log('markasjunk', 'header ' . $header[1] . ' not found in message ' . $src_mbox . '/' . $uid);
}
continue 2;
}
}
}
if (strpos($command, '%f') !== false) {
$tmpfname = tempnam($temp_dir, 'rcmSALearn');
file_put_contents($tmpfname, $rcube->storage->get_raw_body($uid));
$tmp_command = str_replace('%f', escapeshellarg($tmpfname), $tmp_command);
}
$output = shell_exec($tmp_command);
if ($debug) {
rcube::write_log('markasjunk', $tmp_command);
rcube::write_log('markasjunk', $output);
}
if (strpos($command, '%f') !== false) {
unlink($tmpfname);
}
}
}
}

@ -0,0 +1,64 @@
<?php
/**
* Copy spam/ham messages to a direcotry for learning later
*
* @version 2.0
*
* @author Philip Weir
*
* Copyright (C) 2009-2014 Philip Weir
*
* This driver is part of the MarkASJunk plugin for Roundcube.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see https://www.gnu.org/licenses/.
*/
class markasjunk_dir_learn
{
public function spam($uids, $src_mbox, $dst_mbox)
{
$this->_do_messagemove($uids, true);
}
public function ham($uids, $src_mbox, $dst_mbox)
{
$this->_do_messagemove($uids, false);
}
private function _do_messagemove($uids, $spam)
{
$rcube = rcube::get_instance();
$dest_dir = unslashify($rcube->config->get($spam ? 'markasjunk_spam_dir' : 'markasjunk_ham_dir'));
if (!$dest_dir) {
return;
}
$debug = $rcube->config->get('markasjunk_debug');
$filename = $rcube->config->get('markasjunk_filename');
$filename = str_replace('%u', $_SESSION['username'], $filename);
$filename = str_replace('%t', ($spam) ? 'spam' : 'ham', $filename);
$filename = str_replace('%l', $rcube->user->get_username('local'), $filename);
$filename = str_replace('%d', $rcube->user->get_username('domain'), $filename);
foreach ($uids as $uid) {
$tmpfname = tempnam($dest_dir, $filename);
file_put_contents($tmpfname, $rcube->storage->get_raw_body($uid));
if ($debug) {
rcube::write_log('markasjunk', $tmpfname);
}
}
}
}

@ -0,0 +1,68 @@
<?php
/**
* Edit headers
*
* @version 1.0
*
* @author Philip Weir
*
* Copyright (C) 2012-2014 Philip Weir
*
* This driver is part of the MarkASJunk plugin for Roundcube.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see https://www.gnu.org/licenses/.
*/
class markasjunk_edit_headers
{
public function spam(&$uids, $src_mbox, $dst_mbox)
{
$this->_edit_headers($uids, true, $dst_mbox);
}
public function ham(&$uids, $src_mbox, $dst_mbox)
{
$this->_edit_headers($uids, false, $dst_mbox);
}
private function _edit_headers(&$uids, $spam, $dst_mbox)
{
$rcube = rcube::get_instance();
$args = $rcube->config->get($spam ? 'markasjunk_spam_patterns' : 'markasjunk_ham_patterns');
if (count($args['patterns']) == 0) {
return;
}
$new_uids = array();
foreach ($uids as $uid) {
$raw_message = $rcube->storage->get_raw_body($uid);
$raw_headers = $rcube->storage->get_raw_headers($uid);
$updated_headers = preg_replace($args['patterns'], $args['replacements'], $raw_headers);
$raw_message = str_replace($raw_headers, $updated_headers, $raw_message);
$saved = $rcube->storage->save_message($dst_mbox, $raw_message);
if ($saved !== false) {
$rcube->output->command('rcmail_markasjunk_move', null, $uid);
array_push($new_uids, $saved);
}
}
if (count($new_uids) > 0) {
$uids = $new_uids;
}
}
}

@ -0,0 +1,173 @@
<?php
/**
* Email learn driver
*
* @version 3.0
*
* @author Philip Weir
*
* Copyright (C) 2009-2017 Philip Weir
*
* This driver is part of the MarkASJunk plugin for Roundcube.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see https://www.gnu.org/licenses/.
*/
class markasjunk_email_learn
{
private $rcube;
public function spam($uids, $src_mbox, $dst_mbox)
{
$this->_do_emaillearn($uids, true);
}
public function ham($uids, $src_mbox, $dst_mbox)
{
$this->_do_emaillearn($uids, false);
}
private function _do_emaillearn($uids, $spam)
{
$this->rcube = rcube::get_instance();
$identity_arr = $this->rcube->user->get_identity();
$from = $identity_arr['email'];
$from_string = format_email_recipient($identity_arr['email'], $identity_arr['name']);
$attach = $this->rcube->config->get('markasjunk_email_attach', false);
$temp_dir = unslashify($this->rcube->config->get('temp_dir'));
$mailto = $this->rcube->config->get($spam ? 'markasjunk_email_spam' : 'markasjunk_email_ham');
$mailto = $this->_parse_vars($mailto, $spam, $from);
// no address to send to, exit
if (!$mailto) {
return;
}
$subject = $this->rcube->config->get('markasjunk_email_subject');
$subject = $this->_parse_vars($subject, $spam, $from);
foreach ($uids as $uid) {
$MESSAGE = new rcube_message($uid);
$message_file = null;
// set message charset as default
if (!empty($MESSAGE->headers->charset)) {
$this->rcube->storage->set_charset($MESSAGE->headers->charset);
}
$OUTPUT = $this->rcube->output;
$SENDMAIL = new rcmail_sendmail(null, array(
'sendmail' => true,
'from' => $from,
'mailto' => $mailto,
'dsn_enabled' => false,
'charset' => 'UTF-8',
'error_handler' => function() use ($OUTPUT) {
call_user_func_array(array($OUTPUT, 'show_message'), func_get_args());
$OUTPUT->send();
}
));
if ($attach) {
$headers = array(
'Date' => $this->rcube->user_date(),
'From' => $from_string,
'To' => $mailto,
'Subject' => $subject,
'User-Agent' => $this->rcube->config->get('useragent'),
'Message-ID' => $this->rcube->gen_message_id($from),
'X-Sender' => $from
);
$message_text = ($spam ? 'Spam' : 'Ham') . ' report from ' . $this->rcube->config->get('product_name');
// create attachment
$orig_subject = $MESSAGE->get_header('subject');
$disp_name = (!empty($orig_subject) ? $orig_subject : 'message_rfc822') . '.eml';
$message_file = tempnam($temp_dir, 'rcm');
$attachment = array();
if ($fp = fopen($message_file, 'w')) {
$this->rcube->storage->get_raw_body($uid, $fp);
fclose($fp);
$attachment = array(
'name' => $disp_name,
'mimetype' => 'message/rfc822',
'path' => $message_file,
'size' => filesize($message_file),
'charset' => $MESSAGE->headers->charset
);
}
// create message
$MAIL_MIME = $SENDMAIL->create_message($headers, $message_text, false, array($attachment));
if (count($attachment) > 0) { // sanity check incase creating the attachment failed
$folding = (int) $this->rcube->config->get('mime_param_folding');
$MAIL_MIME->addAttachment($attachment['path'],
$attachment['mimetype'], $attachment['name'], true,
'8bit', 'attachment', $attachment['charset'], '', '',
$folding ? 'quoted-printable' : null,
$folding == 2 ? 'quoted-printable' : null,
'', RCUBE_CHARSET
);
}
}
else {
$headers = array(
'Resent-From' => $from_string,
'Resent-To' => $mailto,
'Resent-Date' => $this->rcube->user_date(),
'Resent-Message-ID' => $this->rcube->gen_message_id($from)
);
// create the bounce message
$MAIL_MIME = new rcmail_resend_mail(array(
'bounce_message' => $MESSAGE,
'bounce_headers' => $headers,
));
}
$SENDMAIL->deliver_message($MAIL_MIME);
$message_file = $message_file ?: $MAIL_MIME->mailbody_file;
// clean up
if ($message_file) {
unlink($message_file);
}
if ($this->rcube->config->get('markasjunk_debug')) {
rcube::write_log('', $uid . ($spam ? ' SPAM ' : ' HAM ') . $mailto . ' (' . $subject . ')');
if ($smtp_error['vars']) {
rcube::write_log('', $smtp_error['vars']);
}
}
}
}
private function _parse_vars($data, $spam, $from)
{
$data = str_replace('%u', $_SESSION['username'], $data);
$data = str_replace('%t', $spam ? 'spam' : 'ham', $data);
$data = str_replace('%l', $this->rcube->user->get_username('local'), $data);
$data = str_replace('%d', $this->rcube->user->get_username('domain'), $data);
$data = str_replace('%i', $from, $data);
return $data;
}
}

@ -0,0 +1,81 @@
<?php
/**
* MarkAsJunk JS events example
* This is an example of how to interact with the markasjunk JS event
* markasjunk-update to change the spam/ham options shown for specific
* folders
*
* @version 0.1
* @author Philip Weir
*
* Copyright (C) 2016 Philip Weir
*
* This driver is part of the MarkASJunk plugin for Roundcube.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see http://www.gnu.org/licenses/.
*/
class markasjunk_jsevent
{
private $addition_spam_folders = array('spam2', 'spam3');
private $suspicious_folders = array('unknown1', 'unknown2');
public function init()
{
$js_addition_spam_folders = json_encode($this->addition_spam_folders);
$js_suspicious_folders = json_encode($this->suspicious_folders);
$script = <<<EOL
rcmail.addEventListener('markasjunk-update', function(props) {
var addition_spam_folders = {$js_addition_spam_folders};
var suspicious_folders = {$js_suspicious_folders};
// ignore this special code when in a multifolder listing
if (rcmail.is_multifolder_listing())
return;
if ($.inArray(rcmail.env.mailbox, addition_spam_folders) > -1) {
props.disp.spam = false;
props.disp.ham = true;
}
else if ($.inArray(rcmail.env.mailbox, suspicious_folders) > -1) {
props.disp.spam = true;
props.disp.ham = true;
// from here it is also possible to alter the buttons themselves...
props.objs.spamobj.find('a > span').text('As possibly spam');
}
else {
props.objs.spamobj.find('a > span').text(rcmail.get_label('markasjunk.markasjunk'));
}
return props;
});
EOL;
$rcmail = rcmail::get_instance();
$rcmail->output->add_script($script, 'docready');
}
public function spam(&$uids, $mbox)
{
// Treat message as spam...
}
public function ham(&$uids, $mbox)
{
// Treat message as ham...
}
}

@ -0,0 +1,145 @@
<?php
/**
* SpamAssassin Blacklist driver
*
* @version 2.0
* @requires SAUserPrefs plugin
*
* @author Philip Weir
*
* Copyright (C) 2010-2014 Philip Weir
*
* This driver is part of the MarkASJunk plugin for Roundcube.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see https://www.gnu.org/licenses/.
*/
class markasjunk_sa_blacklist
{
private $sa_user;
private $sa_table;
private $sa_username_field;
private $sa_preference_field;
private $sa_value_field;
public function spam($uids, $src_mbox, $dst_mbox)
{
$this->_do_list($uids, true);
}
public function ham($uids, $src_mbox, $dst_mbox)
{
$this->_do_list($uids, false);
}
private function _do_list($uids, $spam)
{
$rcube = rcube::get_instance();
$this->sa_user = $rcube->config->get('sauserprefs_userid', "%u");
$this->sa_table = $rcube->config->get('sauserprefs_sql_table_name');
$this->sa_username_field = $rcube->config->get('sauserprefs_sql_username_field');
$this->sa_preference_field = $rcube->config->get('sauserprefs_sql_preference_field');
$this->sa_value_field = $rcube->config->get('sauserprefs_sql_value_field');
$identity_arr = $rcube->user->get_identity();
$identity = $identity_arr['email'];
$this->sa_user = str_replace('%u', $_SESSION['username'], $this->sa_user);
$this->sa_user = str_replace('%l', $rcube->user->get_username('local'), $this->sa_user);
$this->sa_user = str_replace('%d', $rcube->user->get_username('domain'), $this->sa_user);
$this->sa_user = str_replace('%i', $identity, $this->sa_user);
if (is_file($rcube->config->get('markasjunk_sauserprefs_config')) && !$rcube->config->load_from_file($rcube->config->get('markasjunk_sauserprefs_config'))) {
rcube::raise_error(array('code' => 527, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "Failed to load config from " . $rcube->config->get('markasjunk_sauserprefs_config')
), true, false);
return false;
}
$db = rcube_db::factory($rcube->config->get('sauserprefs_db_dsnw'), $rcube->config->get('sauserprefs_db_dsnr'), $rcube->config->get('sauserprefs_db_persistent'));
$db->set_debug((bool) $rcube->config->get('sql_debug'));
$db->db_connect('w');
// check DB connections and exit on failure
if ($err_str = $db->is_error()) {
rcube::raise_error(array(
'code' => 603,
'type' => 'db',
'message' => $err_str
), false, true);
}
foreach ($uids as $uid) {
$message = new rcube_message($uid);
$email = $message->sender['mailto'];
if ($spam) {
// delete any whitelisting for this address
$db->query(
"DELETE FROM `{$this->sa_table}` WHERE `{$this->sa_username_field}` = ? AND `{$this->sa_preference_field}` = ? AND `{$this->sa_value_field}` = ?",
$this->sa_user,
'whitelist_from',
$email);
// check address is not already blacklisted
$sql_result = $db->query(
"SELECT `value` FROM `{$this->sa_table}` WHERE `{$this->sa_username_field}` = ? AND `{$this->sa_preference_field}` = ? AND `{$this->sa_value_field}` = ?",
$this->sa_user,
'blacklist_from',
$email);
if (!$db->fetch_array($sql_result)) {
$db->query(
"INSERT INTO `{$this->sa_table}` (`{$this->sa_username_field}`, `{$this->sa_preference_field}`, `{$this->sa_value_field}`) VALUES (?, ?, ?)",
$this->sa_user,
'blacklist_from',
$email);
if ($rcube->config->get('markasjunk_debug')) {
rcube::write_log('markasjunk', $this->sa_user . ' blacklist ' . $email);
}
}
}
else {
// delete any blacklisting for this address
$db->query(
"DELETE FROM `{$this->sa_table}` WHERE `{$this->sa_username_field}` = ? AND `{$this->sa_preference_field}` = ? AND `{$this->sa_value_field}` = ?",
$this->sa_user,
'blacklist_from',
$email);
// check address is not already whitelisted
$sql_result = $db->query(
"SELECT `value` FROM `{$this->sa_table}` WHERE `{$this->sa_username_field}` = ? AND `{$this->sa_preference_field}` = ? AND `{$this->sa_value_field}` = ?",
$this->sa_user,
'whitelist_from',
$email);
if (!$db->fetch_array($sql_result)) {
$db->query(
"INSERT INTO `{$this->sa_table}` (`{$this->sa_username_field}`, `{$this->sa_preference_field}`, `{$this->sa_value_field}`) VALUES (?, ?, ?)",
$this->sa_user,
'whitelist_from',
$email);
if ($rcube->config->get('markasjunk_debug')) {
rcube::write_log('markasjunk', $this->sa_user . ' whitelist ' . $email);
}
}
}
}
}
}

@ -0,0 +1,62 @@
<?php
/**
* SpamAssassin detach ham driver
*
* @version 2.0
*
* @author Philip Weir
*
* Copyright (C) 2011-2014 Philip Weir
*
* This driver is part of the MarkASJunk plugin for Roundcube.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see https://www.gnu.org/licenses/.
*/
class markasjunk_sa_detach
{
public function spam($uids, $src_mbox, $dst_mbox)
{
// do nothing
}
public function ham(&$uids, $src_mbox, $dst_mbox)
{
$rcube = rcube::get_instance();
$storage = $rcube->storage;
$new_uids = array();
foreach ($uids as $uid) {
$saved = false;
$message = new rcube_message($uid);
if (count($message->attachments) > 0) {
foreach ($message->attachments as $part) {
if ($part->ctype_primary == 'message' && $part->ctype_secondary == 'rfc822' && $part->ctype_parameters['x-spam-type'] == 'original') {
$orig_message_raw = $message->get_part_body($part->mime_id);
if ($saved = $storage->save_message($dst_mbox, $orig_message_raw)) {
$rcube->output->command('rcmail_markasjunk_move', null, $uid);
array_push($new_uids, $saved);
}
}
}
}
}
if (count($new_uids) > 0) {
$uids = $new_uids;
}
}
}

@ -5,7 +5,7 @@
| plugins/markasjunk/localization/<lang>.inc |
| |
| Localization file of the Roundcube Webmail Mark-As-Junk plugin |
| Copyright (C) 2012-2013, The Roundcube Dev Team |
| Copyright (C) 2012-2018, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -17,8 +17,14 @@
*/
$labels = array();
$labels['buttontext'] = 'Junk';
$labels['buttontitle'] = 'Mark as Junk';
$labels['reportedasjunk'] = 'Successfully reported as Junk';
$labels['buttonjunk'] = 'This message is junk';
$labels['asjunk'] = 'As junk';
$labels['markasjunk'] = 'Mark as junk';
$labels['buttonnotjunk'] = 'This message is not junk';
$labels['asnotjunk'] = 'As not junk';
$labels['markasnotjunk'] = 'Mark as not junk';
$labels['notjunk'] = 'Not junk';
?>
$messages = array();
$messages['reportedasjunk'] = 'Successfully reported as junk';
$messages['reportedasnotjunk'] = 'Successfully reported as not junk';

@ -4,7 +4,8 @@
* @licstart The following is the entire license notice for the
* JavaScript code in this file.
*
* Copyright (c) 2013, The Roundcube Dev Team
* Copyright (c) 2013-2018 The Roundcube Dev Team
* Copyright (C) 2009-2018 Philip Weir
*
* The JavaScript code in this page is free software: you can redistribute it
* and/or modify it under the terms of the GNU General Public License
@ -15,29 +16,117 @@
* for the JavaScript code in this file.
*/
function rcmail_markasjunk(prop)
{
if (!rcmail.env.uid && (!rcmail.message_list || !rcmail.message_list.get_selection().length))
return;
rcube_webmail.prototype.markasjunk_mark = function(is_spam) {
var uids = this.env.uid ? [this.env.uid] : this.message_list.get_selection();
if (!uids)
return;
var uids = rcmail.env.uid ? rcmail.env.uid : rcmail.message_list.get_selection().join(','),
lock = rcmail.set_busy(true, 'loading');
var lock = this.set_busy(true, 'loading');
this.http_post('plugin.markasjunk.' + (is_spam ? 'junk' : 'not_junk'), this.selection_post_data({_uid: uids}), lock);
}
rcube_webmail.prototype.rcmail_markasjunk_move = function(mbox, uids) {
var prev_uid = this.env.uid, a_uids = $.isArray(uids) ? uids : uids.split(",");
if (this.message_list && a_uids.length == 1 && !this.message_list.in_selection([a_uids[0]]))
this.env.uid = a_uids[0];
rcmail.http_post('plugin.markasjunk', '_uid='+uids+'&_mbox='+urlencode(rcmail.env.mailbox), lock);
if (mbox)
this.move_messages(mbox);
else if (this.env.markasjunk_permanently_remove == true)
this.permanently_remove_messages();
else
this.delete_messages();
this.env.uid = prev_uid;
}
// callback for app-onload event
if (window.rcmail) {
rcmail.addEventListener('init', function(evt) {
rcube_webmail.prototype.markasjunk_toggle_button = function() {
var spamobj = $('a.junk'),
hamobj = $('a.notjunk'),
disp = {spam: true, ham: true};
if (this.env.markasjunk_spam_only) {
disp.ham = false;
}
else if (!this.is_multifolder_listing() && this.env.markasjunk_spam_mailbox) {
if (this.env.mailbox != this.env.markasjunk_spam_mailbox)
disp.ham = false;
else
disp.spam = false;
}
// register command (directly enable in message view mode)
rcmail.register_command('plugin.markasjunk', rcmail_markasjunk, rcmail.env.uid);
// if only 1 button is visible make sure its the last one (for styling)
// allow for multiple instances of the buttons, eg toolbar and contextmenu
$.each(spamobj, function(i) {
var cur_spamobj = spamobj.eq(i),
cur_hamobj = hamobj.eq(i),
cur_index = spamobj.eq(i).index();
// add event-listener to message list
if (rcmail.message_list)
rcmail.message_list.addEventListener('select', function(list){
rcmail.enable_command('plugin.markasjunk', list.get_selection().length > 0);
});
})
if (cur_spamobj.parent('li').length > 0) {
cur_spamobj = cur_spamobj.parent();
cur_hamobj = cur_hamobj.parent();
}
var evt_rtn = rcmail.triggerEvent('markasjunk-update', {objs: {spamobj: cur_spamobj, hamobj: cur_hamobj}, disp: disp});
if (evt_rtn && evt_rtn.abort)
return;
disp = evt_rtn ? evt_rtn.disp : disp;
disp.spam ? cur_spamobj.show() : cur_spamobj.hide();
disp.ham ? cur_hamobj.show() : cur_hamobj.hide();
if (disp.spam && !disp.ham) {
if (cur_index < cur_hamobj.index()) {
cur_spamobj.insertAfter(cur_hamobj);
}
}
else if (cur_index > cur_hamobj.index()) {
cur_hamobj.insertAfter(cur_spamobj);
}
});
}
rcube_webmail.prototype.markasjunk_is_spam_mbox = function() {
return !this.is_multifolder_listing() && this.env.mailbox == this.env.markasjunk_spam_mailbox;
}
if (window.rcmail) {
rcmail.addEventListener('init', function() {
// register command (directly enable in message view mode)
rcmail.register_command('plugin.markasjunk.junk', function() { rcmail.markasjunk_mark(true); }, !rcmail.markasjunk_is_spam_mbox() && rcmail.env.uid);
rcmail.register_command('plugin.markasjunk.not_junk', function() { rcmail.markasjunk_mark(false); }, rcmail.env.uid);
if (rcmail.message_list) {
rcmail.message_list.addEventListener('select', function(list) {
rcmail.enable_command('plugin.markasjunk.junk', !rcmail.markasjunk_is_spam_mbox() && list.get_selection(false).length > 0);
rcmail.enable_command('plugin.markasjunk.not_junk', list.get_selection(false).length > 0);
});
}
// make sure the correct icon is displayed even when there is no listupdate event
rcmail.markasjunk_toggle_button();
});
rcmail.addEventListener('listupdate', function() { rcmail.markasjunk_toggle_button(); });
rcmail.addEventListener('beforemoveto', function(mbox) {
if (mbox && typeof mbox === 'object')
mbox = mbox.id;
var is_spam = null;
// check if destination mbox equals junk box (and we're not already in the junk box)
if (rcmail.env.markasjunk_move_spam && mbox && mbox == rcmail.env.markasjunk_spam_mailbox && mbox != rcmail.env.mailbox)
is_spam = true;
// or if destination mbox equals ham box and we are in the junk box
else if (rcmail.env.markasjunk_move_ham && mbox && mbox == rcmail.env.markasjunk_ham_mailbox && rcmail.env.mailbox == rcmail.env.markasjunk_spam_mailbox)
is_spam = false;
if (is_spam !== null) {
rcmail.markasjunk_mark(is_spam);
return false;
}
});
}

@ -1,73 +1,321 @@
<?php
/**
* Mark as Junk
* MarkAsJunk
*
* Sample plugin that adds a new button to the mailbox toolbar
* A plugin that adds a new button to the mailbox toolbar
* to mark the selected messages as Junk and move them to the Junk folder
* or to move messages in the Junk folder to the inbox - moving only the
* attachment if it is a Spamassassin spam report email
*
* @license GNU GPLv3+
* @author Philip Weir
* @author Thomas Bruederli
*
* Copyright (C) 2009-2018 The Roundcube Dev Team
* Copyright (C) 2009-2018 Philip Weir
*
* This program is a Roundcube (https://roundcube.net) plugin.
* For more information see README.md.
* For configuration see config.inc.php.dist.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Roundcube. If not, see https://www.gnu.org/licenses/.
*/
class markasjunk extends rcube_plugin
{
public $task = 'mail';
function init()
private $rcube;
private $spam_mbox;
private $ham_mbox;
private $flags = array(
'JUNK' => 'Junk',
'NONJUNK' => 'NonJunk'
);
public function init()
{
$rcmail = rcmail::get_instance();
$this->register_action('plugin.markasjunk.junk', array($this, 'mark_message'));
$this->register_action('plugin.markasjunk.not_junk', array($this, 'mark_message'));
$this->register_action('plugin.markasjunk', array($this, 'request_action'));
$this->add_hook('storage_init', array($this, 'storage_init'));
$this->rcube = rcube::get_instance();
$this->load_config();
$this->_load_host_config();
if ($rcmail->action == '' || $rcmail->action == 'show') {
$this->add_texts('localization', true);
// Host exceptions
$hosts = $this->rcube->config->get('markasjunk_allowed_hosts');
if (!empty($hosts) && !in_array($_SESSION['storage_host'], (array) $hosts)) {
return;
}
$this->ham_mbox = $this->rcube->config->get('markasjunk_ham_mbox', 'INBOX');
$this->spam_mbox = $this->rcube->config->get('markasjunk_spam_mbox', $this->rcube->config->get('junk_mbox'));
$toolbar = $this->rcube->config->get('markasjunk_toolbar', true);
$this->_init_flags();
if ($this->rcube->action == '' || $this->rcube->action == 'show') {
$this->include_script('markasjunk.js');
$this->add_texts('localization', true);
$this->include_stylesheet($this->local_skin_path() . '/markasjunk.css');
$this->add_button(array(
'type' => 'link',
'label' => 'buttontext',
'command' => 'plugin.markasjunk',
'title' => 'buttontitle',
'domain' => 'markasjunk',
'class' => 'button buttonPas junk disabled',
'classact' => 'button junk',
'innerclass' => 'inner',
),'toolbar');
if ($toolbar) {
// add the buttons to the main toolbar
$this->add_button(array(
'command' => 'plugin.markasjunk.junk',
'type' => 'link',
'class' => 'button buttonPas junk disabled',
'classact' => 'button junk',
'classsel' => 'button junk pressed',
'title' => 'markasjunk.buttonjunk',
'innerclass' => 'inner',
'label' => 'junk'
), 'toolbar');
$this->add_button(array(
'command' => 'plugin.markasjunk.not_junk',
'type' => 'link',
'class' => 'button buttonPas notjunk disabled',
'classact' => 'button notjunk',
'classsel' => 'button notjunk pressed',
'title' => 'markasjunk.buttonnotjunk',
'innerclass' => 'inner',
'label' => 'markasjunk.notjunk'
), 'toolbar');
}
else {
// add the buttons to the mark message menu
$this->add_button(array(
'command' => 'plugin.markasjunk.junk',
'type' => 'link-menuitem',
'label' => 'markasjunk.asjunk',
'id' => 'markasjunk',
'class' => 'icon junk',
'classact' => 'icon junk active',
'innerclass' => 'icon junk'
), 'markmenu');
$this->add_button(array(
'command' => 'plugin.markasjunk.not_junk',
'type' => 'link-menuitem',
'label' => 'markasjunk.asnotjunk',
'id' => 'markasnotjunk',
'class' => 'icon notjunk',
'classact' => 'icon notjunk active',
'innerclass' => 'icon notjunk'
), 'markmenu');
}
// add markasjunk folder settings to the env for JS
$this->rcube->output->set_env('markasjunk_ham_mailbox', $this->ham_mbox);
$this->rcube->output->set_env('markasjunk_spam_mailbox', $this->spam_mbox);
$this->rcube->output->set_env('markasjunk_move_spam', $this->rcube->config->get('markasjunk_move_spam', false));
$this->rcube->output->set_env('markasjunk_move_ham', $this->rcube->config->get('markasjunk_move_ham', false));
$this->rcube->output->set_env('markasjunk_permanently_remove', $this->rcube->config->get('markasjunk_permanently_remove', false));
$this->rcube->output->set_env('markasjunk_spam_only', $this->rcube->config->get('markasjunk_spam_only', false));
// check for init method from driver
$this->_call_driver('init');
}
}
public function mark_message()
{
$this->add_texts('localization');
$is_spam = $this->rcube->action == 'plugin.markasjunk.junk' ? true : false;
$messageset = rcmail::get_uids(null, null, $multifolder, rcube_utils::INPUT_POST);
$mbox_name = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST);
$dest_mbox = $is_spam ? $this->spam_mbox : $this->ham_mbox;
$result = $is_spam ? $this->_spam($messageset, $dest_mbox) : $this->_ham($messageset, $dest_mbox);
if ($result) {
if ($dest_mbox && ($mbox_name !== $dest_mbox || $multifolder)) {
$this->rcube->output->command('rcmail_markasjunk_move', $dest_mbox, $this->_messageset_to_uids($messageset, $multifolder));
}
else {
$this->rcube->output->command('command', 'list', $mbox_name);
}
$this->rcube->output->command('display_message', $is_spam ? $this->gettext('reportedasjunk') : $this->gettext('reportedasnotjunk'), 'confirmation');
}
$this->rcube->output->send();
}
public function set_flags($p)
{
$p['message_flags'] = array_merge((array) $p['message_flags'], $this->flags);
return $p;
}
function storage_init($args)
private function _spam(&$messageset, $dest_mbox = null)
{
$flags = array(
'JUNK' => 'Junk',
'NONJUNK' => 'NonJunk',
);
$storage = $this->rcube->get_storage();
$result = true;
// register message flags
$args['message_flags'] = array_merge((array)$args['message_flags'], $flags);
foreach ($messageset as $source_mbox => &$uids) {
$storage->set_folder($source_mbox);
return $args;
$result = $this->_call_driver('spam', $uids, $source_mbox, $dest_mbox);
// abort function of the driver says so
if (!$result) {
break;
}
if ($this->rcube->config->get('markasjunk_read_spam', false)) {
$storage->set_flag($uids, 'SEEN', $source_mbox);
}
if (array_key_exists('JUNK', $this->flags)) {
$storage->set_flag($uids, 'JUNK', $source_mbox);
}
if (array_key_exists('NONJUNK', $this->flags)) {
$storage->unset_flag($uids, 'NONJUNK', $source_mbox);
}
}
return $result;
}
function request_action()
private function _ham(&$messageset, $dest_mbox = null)
{
$this->add_texts('localization');
$storage = $this->rcube->get_storage();
$result = true;
foreach ($messageset as $source_mbox => &$uids) {
$storage->set_folder($source_mbox);
$result = $this->_call_driver('ham', $uids, $source_mbox, $dest_mbox);
$rcmail = rcmail::get_instance();
$storage = $rcmail->get_storage();
// abort function of the driver says so
if (!$result) {
break;
}
foreach (rcmail::get_uids(null, null, $multifolder, rcube_utils::INPUT_POST) as $mbox => $uids) {
$storage->unset_flag($uids, 'NONJUNK', $mbox);
$storage->set_flag($uids, 'JUNK', $mbox);
if ($this->rcube->config->get('markasjunk_unread_ham', false)) {
$storage->unset_flag($uids, 'SEEN', $source_mbox);
}
if (array_key_exists('JUNK', $this->flags)) {
$storage->unset_flag($uids, 'JUNK', $source_mbox);
}
if (array_key_exists('NONJUNK', $this->flags)) {
$storage->set_flag($uids, 'NONJUNK', $source_mbox);
}
}
return $result;
}
private function _call_driver($action, &$uids = null, $source_mbox = null, $dest_mbox = null)
{
$driver_name = $this->rcube->config->get('markasjunk_learning_driver');
if (empty($driver_name)) {
return true;
}
$driver = $this->home . "/drivers/$driver_name.php";
$class = "markasjunk_$driver_name";
if (!is_readable($driver)) {
rcube::raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__,
'line' => __LINE__,
'message' => "markasjunk plugin: Unable to open driver file $driver"
), true, false);
}
include_once $driver;
if (!class_exists($class, false) || !method_exists($class, 'spam') || !method_exists($class, 'ham')) {
rcube::raise_error(array(
'code' => 600,
'type' => 'php',
'file' => __FILE__,
'line' => __LINE__,
'message' => "markasjunk plugin: Broken driver: $driver"
), true, false);
}
// call the relevant function from the driver
$object = new $class();
if ($action == 'spam') {
$object->spam($uids, $source_mbox, $dest_mbox);
}
elseif ($action == 'ham') {
$object->ham($uids, $source_mbox, $dest_mbox);
}
elseif ($action == 'init' && method_exists($object, 'init')) { // method_exists check here for backwards compatibility
$object->init();
}
return $object->is_error ? false : true;
}
private function _messageset_to_uids($messageset, $multifolder)
{
$a_uids = array();
foreach ($messageset as $mbox => $uids) {
foreach ($uids as $uid) {
$a_uids[] = $multifolder ? $uid . '-' . $mbox : $uid;
}
}
if (($junk_mbox = $rcmail->config->get('junk_mbox'))) {
$rcmail->output->command('move_messages', $junk_mbox);
return $a_uids;
}
private function _load_host_config()
{
$configs = $this->rcube->config->get('markasjunk_host_config');
if (empty($configs) || !array_key_exists($_SESSION['storage_host'], (array) $configs)) {
return;
}
$rcmail->output->command('display_message', $this->gettext('reportedasjunk'), 'confirmation');
$rcmail->output->send();
$file = $configs[$_SESSION['storage_host']];
$this->load_config($file);
}
private function _init_flags()
{
$spam_flag = $this->rcube->config->get('markasjunk_spam_flag');
$ham_flag = $this->rcube->config->get('markasjunk_ham_flag');
if ($spam_flag === false) {
unset($this->flags['JUNK']);
}
elseif (!empty($spam_flag)) {
$this->flags['JUNK'] = $spam_flag;
}
if ($ham_flag === false) {
unset($this->flags['NONJUNK']);
}
elseif (!empty($ham_flag)) {
$this->flags['NONJUNK'] = $ham_flag;
}
if (count($this->flags) > 0) {
// register the ham/spam flags with the core
$this->add_hook('storage_init', array($this, 'set_flags'));
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

@ -1,6 +1,43 @@
#messagetoolbar a.junk,
#messagetoolbar a.notjunk
{
text-indent: -5000px;
background-image: url(images/mail_toolbar.png);
}
#messagetoolbar a.junk
{
background-position: -32px 0;
}
#messagetoolbar a.junk.pressed
{
background-position: -32px -32px;
}
#messagetoolbar a.notjunk
{
background-position: 0 0;
}
#messagetoolbar a.notjunk.pressed
{
background-position: 0 -32px;
}
#messagetoolbar a.button.junk {
text-indent: -5000px;
background: url(junk_act.png) 0 0 no-repeat;
ul.toolbarmenu li a.junk,
ul.toolbarmenu li a.notjunk
{
background-image: url(images/messageactions.png) !important;
background-repeat: no-repeat;
}
ul.toolbarmenu li a.junk
{
background-position: 6px -17px !important;
}
ul.toolbarmenu li a.notjunk
{
background-position: 6px 1px !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

@ -0,0 +1,31 @@
#messagetoolbar a.junk,
#messagetoolbar a.notjunk
{
background-image: url(images/mail_toolbar.png);
}
#messagetoolbar a.junk
{
background-position: center -14px;
}
#messagetoolbar a.notjunk
{
background-position: center -61px;
}
ul.toolbarmenu li a.junk span.icon,
ul.toolbarmenu li a.notjunk span.icon
{
background-image: url(images/messageactions.png) !important;
}
ul.toolbarmenu li a.junk span.icon
{
background-position: 1px -17px !important;
}
ul.toolbarmenu li a.notjunk span.icon
{
background-position: 1px 4px !important;
}

@ -108,6 +108,9 @@
&.junk:before {
content: @fa-var-fire;
}
&.notjunk:before {
content: @fa-var-inbox;
}
&.enigma:before,
&.encrypt:before {
content: @fa-var-lock;
@ -615,6 +618,12 @@
a.encrypt.sign:before {
content: @fa-var-lock; // TODO
}
a.junk:before {
content: @fa-var-fire;
}
a.notjunk:before {
content: @fa-var-inbox;
}
}
.toolbarmenu.listing li {

Loading…
Cancel
Save