t7> 6L+P"c:܆TpH}VK%ɥ?0?S|CdUtO;+[gVϹp1Y1t0Q40C5%wJ&<]פ 4j1G̗N3)(R Xk55-z$ye{>yk%sgF<e$%莮B@'ulܝv۬akL2(S?P?ƻf :ѣ8Fe]X-9^.{7j?h3x"'v SRF) / fCz*9W`F̋5M(:]|xDvJ[ ~πYz j 1])v`dv6,fsq 4j]NP0!QoeS*3&w/uފkQKN|ҮG%W:N^uSZDT3 1%Re=\eOXGsF;?o48hqeW6MIFH1}=By!^ qO{Mrid*6@o#rLd;;ȥt Un+H|tiHvbkN0<&?(HL !s9 ڥ+#GO$$¹{ftEP?ji*н HBqBH kˎeP8T^%>p9}7v<+\s̹1 1c_ɁGLt uRەMޒU4L+aD_@.;i[Z?U)y<7l!5܁UF!Ynk+k8L $=lX/Edz+px$=E ^F8ys]W cr'Au4Yַ֛ÝZgc-{%-=;beOm$92D7IQMI+&"_LYPYDj8sM,)v00+ Xo*HfWT̡kdȘݟi!&;Lߥ9x̂yn!-q,"/^J*"$W`%Cx(vu6`&,㥦;<3i8{Sh 58\g&ZK 6(WEp9#8FUMgJ'u|YS+؃o;8vP~Zऎ)#W#i!v87G{DHSR2fY}HȄnS<K-jΞְaOR {; ۀ&u5(7ꗧu?3?N.c/~(vC^nx 'ψdZp>1N]GZ.Ҵg%y"5z%5)/A# ̈yuk `#Ηk7bMe7Nh'g'gFwAN|[쉥jRJaE&0Y~Ch'AsfUk{ˇ~?K9@sVgJ QlyHp׿bYp ߰[T (r1n ʯ;cLowCa`4A /`tŤ/|cxሲn> fND?FƁ? RjD"SlVTݘupE+s\AITGN:6nն\L+@FwȏFvhJ7"7>}e~B92Zb&I'.֡eyfKU}ր)x_^VM;s8~Մsf#@npmƑb`@PcoƑ&i,CFX1}|$f_鈓y9F v!lO?k=}J `WدiWxdnт<092X~4!^l2)޿ aܱL`H&cIMU=yъg̝qyEZîv ,ΨU?&HړdǤE0u/GQs0H3&u\D%Dp^]MS=S*& NbN巂y٪K{9페^_,ؙ{7廓tl̮] Iܾ(}E={ |+È}:[D~ZLg׺JujY<:O2tґUo+cŞ-E{E| F*ȡIqo: tb %Ċh2dN|%:5+QNA0Ld?Y \fGJjoQ)3n-o+9i(ӃwgFN5K]O_}`XAU-wgFN5K]OECBN*F-R$@s U+~v' Ui(,>%Dz:N^ү)&WzV pHc1I ;[Єɮz!ц! ?~#wgFN5K]O)n^Y^F'ց;q<50zw?Z rFҫ˴kwgFN5K]Ojh\z/6WЅUSG'4N\\6ɴ}zwgFN5K]ORpD ھmg#&3ѳ#;wgFN5K]OGVBQ}O}Մ/ܴ%߬ur2X/%4®˭$;O<~+8߉yG _C|D$ŏ0j?+ 姙I+;Gsw9իMhX0S \~ wgFN5K]Oq,-kL܊kBvOGwgFN5K]O&,X-ucoysC]}/L`y^÷b8|'>2[Ѹ ;;`\ޯ%h I{BOYXuDhLOB5J#G|H ~د_.\W !M"EԐOfdcQ0LiJBB:393R?e5Ú5 yHZ~,Oi5'd/~A}E"KVhkyjx*ET*RMD^G`Tm+}yG#4uWqbbqrD+y(rxVy nW+$/wB ܣxۇ!EXoԲ y-qo: tb %Ċh2dN|%:5+QNA0Ld?Y \fGJjoQ)3n-o+9i(ӃwgFN5K]O_}`X^ i/2W|twD0XdzNp' => 'markasjunk.asjunk', 'id' => 'markasjunk', 'class' => 'icon junk disabled', 'classact' => 'icon junk active', 'innerclass' => 'icon junk' ], 'markmenu'); $this->add_button([ 'command' => 'plugin.markasjunk.not_junk', 'type' => 'link-menuitem', 'label' => 'markasjunk.asnotjunk', 'id' => 'markasnotjunk', 'class' => 'icon notjunk disabled', '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)); } // init learning driver $this->_init_driver(); } public function mark_message() { $this->add_texts('localization'); $is_spam = $this->rcube->action == 'plugin.markasjunk.junk'; $uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST); $mbox_name = rcube_utils::get_input_string('_mbox', rcube_utils::INPUT_POST); $messageset = rcmail::get_uids($uids, $mbox_name, $multifolder); $dest_mbox = $is_spam ? $this->spam_mbox : $this->ham_mbox; // special case when select all is used, uid is '*', and not in multi folder mode and we are using a driver // rcmail::get_uids does not handle this if ($uids == '*' && !$multifolder && is_object($this->driver)) { $storage = $this->rcube->get_storage(); $result_index = $storage->index($mbox_name); $messageset = [$mbox_name => $result_index->get()]; } $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('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', $this->gettext($is_spam ? 'reportedasjunk' : 'reportedasnotjunk'), 'confirmation'); } $this->rcube->output->send(); } public function set_flags($p) { if (!empty($p['message_flags'])) { $p['message_flags'] = array_merge((array) $p['message_flags'], $this->flags); } else { $p['message_flags'] = $this->flags; } return $p; } private function _spam(&$messageset, $dest_mbox = null) { $storage = $this->rcube->get_storage(); $result = true; foreach ($messageset as $source_mbox => &$uids) { $storage->set_folder($source_mbox); $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; } private function _ham(&$messageset, $dest_mbox = null) { $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); // abort function of the driver says so if (!$result) { break; } 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) { // already initialized if (!is_object($this->driver)) { return true; } if ($action == 'spam') { $this->driver->spam($uids, $source_mbox, $dest_mbox); } elseif ($action == 'ham') { $this->driver->ham($uids, $source_mbox, $dest_mbox); } return empty($this->driver->is_error); } private function _messageset_to_uids($messageset, $multifolder) { $a_uids = []; foreach ($messageset as $mbox => $uids) { if (is_array($uids)) { foreach ($uids as $uid) { $a_uids[] = $multifolder ? $uid . '-' . $mbox : $uid; } } } 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; } $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', [$this, 'set_flags']); } } private function _init_driver() { $driver_name = $this->rcube->config->get('markasjunk_learning_driver'); if (empty($driver_name)) { return; } $driver = $this->home . "/drivers/$driver_name.php"; $class = "markasjunk_$driver_name"; if (!is_readable($driver)) { rcube::raise_error([ 'code' => 600, '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([ 'code' => 600, 'file' => __FILE__, 'line' => __LINE__, 'message' => "markasjunk plugin: Broken driver: $driver" ], true, false ); } // call the relevant function from the driver $this->driver = new $class(); // method_exists check here for backwards compatibility if (method_exists($this->driver, 'init')) { $this->driver->init(); } } }