1<?php 2 3/** 4 * SAUserPrefs 5 * 6 * Plugin to allow the user to manage their SpamAssassin settings using an SQL database 7 * 8 * @version @package_version@ 9 * @author Philip Weir 10 */ 11class sauserprefs extends rcube_plugin 12{ 13 public $task = 'mail|addressbook|settings'; 14 private $storage; 15 private $sections = array(); 16 private $cur_section; 17 private $global_prefs; 18 private $user_prefs; 19 private $addressbook = '0'; 20 private $sa_locales = array('en', 'ja', 'ko', 'ru', 'th', 'zh'); 21 private $sa_user; 22 static $deprecated_prefs = array('required_hits' => 'required_score'); 23 24 function init() 25 { 26 $rcmail = rcube::get_instance(); 27 $this->load_config(); 28 $this->sa_user = $rcmail->config->get('sauserprefs_userid', "%u"); 29 30 $identity_arr = $rcmail->user->get_identity(); 31 $identity = $identity_arr['email']; 32 $this->sa_user = str_replace('%u', $_SESSION['username'], $this->sa_user); 33 $this->sa_user = str_replace('%l', $rcmail->user->get_username('local'), $this->sa_user); 34 $this->sa_user = str_replace('%d', $rcmail->user->get_username('domain'), $this->sa_user); 35 $this->sa_user = str_replace('%i', $identity, $this->sa_user); 36 37 // init storage 38 include('include/rcube_sauserprefs_storage.php'); 39 $this->storage = new rcube_sauserprefs_storage($rcmail->config->get('sauserprefs_db_dsnw'), $rcmail->config->get('sauserprefs_db_dsnr'), $rcmail->config->get('sauserprefs_db_persistent'), 40 $this->sa_user, $rcmail->config->get('sauserprefs_sql_table_name'), $rcmail->config->get('sauserprefs_sql_username_field'), $rcmail->config->get('sauserprefs_sql_preference_field'), 41 $rcmail->config->get('sauserprefs_sql_value_field'), $rcmail->config->get('sauserprefs_bayes_delete_query')); 42 43 if ($rcmail->config->get('sauserprefs_whitelist_abook_id', false)) 44 $this->addressbook = $rcmail->config->get('sauserprefs_whitelist_abook_id'); 45 46 if ($rcmail->task == 'settings') { 47 $this->add_texts('localization/', array('sauserprefs', 'managespam')); 48 $this->include_stylesheet($this->local_skin_path() . '/tabstyles.css'); 49 50 $this->sections = array( 51 'general' => array('id' => 'general', 'section' => $this->gettext('spamgeneralsettings')), 52 'tests' => array('id' => 'tests', 'section' => $this->gettext('spamtests')), 53 'bayes' => array('id' => 'bayes', 'section' => $this->gettext('bayes')), 54 'headers' => array('id' => 'headers', 'section' => $this->gettext('headers')), 55 'report' => array('id' => 'report','section' => $this->gettext('spamreportsettings')), 56 'addresses' => array('id' => 'addresses', 'section' => $this->gettext('spamaddressrules')), 57 ); 58 $this->cur_section = rcube_utils::get_input_value('_section', rcube_utils::INPUT_GPC); 59 60 $this->register_action('plugin.sauserprefs', array($this, 'init_html')); 61 $this->register_action('plugin.sauserprefs.edit', array($this, 'init_html')); 62 $this->register_action('plugin.sauserprefs.save', array($this, 'save')); 63 $this->register_action('plugin.sauserprefs.whitelist_import', array($this, 'whitelist_import')); 64 $this->register_action('plugin.sauserprefs.purge_bayes', array($this, 'purge_bayes')); 65 $this->include_script('sauserprefs.js'); 66 } 67 elseif ($rcmail->config->get('sauserprefs_whitelist_sync')) { 68 $this->add_hook('contact_create', array($this, 'contact_add')); 69 $this->add_hook('contact_update', array($this, 'contact_save')); 70 $this->add_hook('contact_delete', array($this, 'contact_delete')); 71 } 72 } 73 74 function init_html() 75 { 76 $this->_load_global_prefs(); 77 $this->_load_user_prefs(); 78 79 $this->api->output->set_pagetitle($this->gettext('sauserprefssettings')); 80 81 if (rcube::get_instance()->action == 'plugin.sauserprefs.edit') { 82 $this->user_prefs = array_merge($this->global_prefs, $this->user_prefs); 83 $this->api->output->add_handler('userprefs', array($this, 'gen_form')); 84 $this->api->output->add_handler('sectionname', array($this, 'prefs_section_name')); 85 $this->api->output->send('sauserprefs.settingsedit'); 86 } 87 else { 88 $this->api->output->add_handler('sasectionslist', array($this, 'section_list')); 89 $this->api->output->add_handler('saprefsframe', array($this, 'preference_frame')); 90 $this->api->output->send('sauserprefs.sauserprefs'); 91 } 92 } 93 94 function section_list($attrib) 95 { 96 $no_override = array_flip(rcube::get_instance()->config->get('sauserprefs_dont_override')); 97 98 // add id to message list table if not specified 99 if (!strlen($attrib['id'])) 100 $attrib['id'] = 'rcmsectionslist'; 101 102 $sections = array(); 103 $blocks = $attrib['sections'] ? preg_split('/[\s,;]+/', strip_quotes($attrib['sections'])) : array_keys($this->sections); 104 foreach ($blocks as $block) { 105 if (!isset($no_override['{' . $block . '}'])) 106 $sections[$block] = $this->sections[$block]; 107 } 108 109 // create XHTML table 110 $out = rcube::get_instance()->table_output($attrib, $sections, array('section'), 'id'); 111 112 // set client env 113 $this->api->output->add_gui_object('sectionslist', $attrib['id']); 114 $this->api->output->include_script('list.js'); 115 116 return $out; 117 } 118 119 function preference_frame($attrib) 120 { 121 if (!$attrib['id']) 122 $attrib['id'] = 'rcmprefsframe'; 123 124 return $this->api->output->frame($attrib, true); 125 } 126 127 function gen_form($attrib) 128 { 129 $this->api->output->add_label( 130 'sauserprefs.spamaddressexists', 'sauserprefs.spamenteraddress', 131 'sauserprefs.spamaddresserror', 'sauserprefs.spamaddressdelete', 132 'sauserprefs.spamaddressdeleteall', 'sauserprefs.enabled', 'sauserprefs.disabled', 133 'sauserprefs.importingaddresses', 'sauserprefs.usedefaultconfirm', 'sauserprefs.purgebayesconfirm', 134 'sauserprefs.whitelist_from'); 135 136 // output global prefs as default in env 137 foreach($this->global_prefs as $key => $val) 138 $this->api->output->set_env(str_replace(" ", "_", $key), $val); 139 140 unset($attrib['form']); 141 142 list($form_start, $form_end) = get_form_tags($attrib, 'plugin.sauserprefs.save', null, 143 array('name' => '_section', 'value' => $this->cur_section)); 144 145 $out = $form_start; 146 147 $out .= $this->_prefs_block($this->cur_section, $attrib); 148 149 return $out . $form_end; 150 } 151 152 function prefs_section_name() 153 { 154 return $this->sections[$this->cur_section]['section']; 155 } 156 157 function save() 158 { 159 $rcmail = rcube::get_instance(); 160 $this->_load_global_prefs(); 161 $this->_load_user_prefs(); 162 163 $no_override = array_flip($rcmail->config->get('sauserprefs_dont_override')); 164 $new_prefs = array(); 165 $result = true; 166 167 switch ($this->cur_section) 168 { 169 case 'general': 170 if (!isset($no_override['required_hits'])) 171 $new_prefs['required_hits'] = rcube_utils::get_input_value('_spamthres', rcube_utils::INPUT_POST); 172 173 if (!isset($no_override['rewrite_header Subject'])) 174 $new_prefs['rewrite_header Subject'] = rcube_utils::get_input_value('_spamsubject', rcube_utils::INPUT_POST); 175 176 if (!isset($no_override['ok_locales'])) { 177 $new_prefs['ok_locales'] = ''; 178 if (is_array(rcube_utils::get_input_value('_spamlang', rcube_utils::INPUT_POST))) { 179 $locales = array_intersect(rcube_utils::get_input_value('_spamlang', rcube_utils::INPUT_POST), $this->sa_locales); 180 $new_prefs['ok_locales'] = implode(" ", $locales); 181 } 182 } 183 184 if (!isset($no_override['ok_languages'])) 185 $new_prefs['ok_languages'] = is_array(rcube_utils::get_input_value('_spamlang', rcube_utils::INPUT_POST)) ? implode(" ", rcube_utils::get_input_value('_spamlang', rcube_utils::INPUT_POST)) : ''; 186 187 break; 188 189 case 'headers': 190 if (!isset($no_override['fold_headers'])) 191 $new_prefs['fold_headers'] = empty($_POST['_spamfoldheaders']) ? "0" : "1"; 192 193 if (!isset($no_override['add_header all Level'])) { 194 $spamchar = empty($_POST['_spamlevelchar']) ? "*" : rcube_utils::get_input_value('_spamlevelchar', rcube_utils::INPUT_POST); 195 196 if (rcube_utils::get_input_value('_spamlevelstars', rcube_utils::INPUT_POST) == "1") { 197 $new_prefs['add_header all Level'] = "_STARS(". $spamchar .")_"; 198 $new_prefs['remove_header all'] = "0"; 199 } 200 else { 201 $new_prefs['add_header all Level'] = ""; 202 $new_prefs['remove_header all'] = "Level"; 203 } 204 } 205 206 break; 207 208 case 'tests': 209 if (!isset($no_override['use_razor1'])) 210 $new_prefs['use_razor1'] = empty($_POST['_spamuserazor1']) ? "0" : "1"; 211 212 if (!isset($no_override['use_razor2'])) 213 $new_prefs['use_razor2'] = empty($_POST['_spamuserazor2']) ? "0" : "1"; 214 215 if (!isset($no_override['use_pyzor'])) 216 $new_prefs['use_pyzor'] = empty($_POST['_spamusepyzor']) ? "0" : "1"; 217 218 if (!isset($no_override['use_dcc'])) 219 $new_prefs['use_dcc'] = empty($_POST['_spamusedcc']) ? "0" : "1"; 220 221 if (!isset($no_override['skip_rbl_checks'])) 222 $new_prefs['skip_rbl_checks'] = empty($_POST['_spamskiprblchecks']) ? "1" : "0"; 223 224 break; 225 226 case 'bayes': 227 if (!isset($no_override['use_bayes'])) 228 $new_prefs['use_bayes'] = empty($_POST['_spamusebayes']) ? "0" : "1"; 229 230 if (!isset($no_override['bayes_auto_learn'])) 231 $new_prefs['bayes_auto_learn'] = empty($_POST['_spambayesautolearn']) ? "0" : "1"; 232 233 if (!isset($no_override['bayes_auto_learn_threshold_nonspam']) && !empty($_POST['_bayesnonspam'])) 234 $new_prefs['bayes_auto_learn_threshold_nonspam'] = rcube_utils::get_input_value('_bayesnonspam', rcube_utils::INPUT_POST); 235 236 if (!isset($no_override['bayes_auto_learn_threshold_spam']) && !empty($_POST['_bayesspam'])) 237 $new_prefs['bayes_auto_learn_threshold_spam'] = rcube_utils::get_input_value('_bayesspam', rcube_utils::INPUT_POST); 238 239 if (!isset($no_override['use_bayes_rules'])) 240 $new_prefs['use_bayes_rules'] = empty($_POST['_spambayesrules']) ? "0" : "1"; 241 242 break; 243 244 case 'report': 245 if (!isset($no_override['report_safe'])) 246 $new_prefs['report_safe'] = rcube_utils::get_input_value('_spamreport', rcube_utils::INPUT_POST); 247 248 break; 249 250 case 'addresses': 251 $acts = rcube_utils::get_input_value('_address_rule_act', rcube_utils::INPUT_POST); 252 $prefs = rcube_utils::get_input_value('_address_rule_field', rcube_utils::INPUT_POST); 253 $vals = rcube_utils::get_input_value('_address_rule_value', rcube_utils::INPUT_POST); 254 255 foreach ($acts as $idx => $act) 256 $new_prefs['addresses'][] = array('field' => $prefs[$idx], 'value' => $vals[$idx], 'action' => $act); 257 258 break; 259 } 260 261 // allow additional actions before prefs are saved 262 $data = $rcmail->plugins->exec_hook('sauserprefs_save', array( 263 'section' => $this->cur_section, 'cur_prefs' => $this->user_prefs, 'new_prefs' => $new_prefs, 'global_prefs' => $this->global_prefs)); 264 265 if (!$data['abort']) { 266 // save prefs 267 if ($this->storage->save_prefs($data['new_prefs'], $this->user_prefs, $this->global_prefs)) 268 $this->api->output->command('display_message', $this->gettext('sauserprefchanged'), 'confirmation'); 269 else 270 $this->api->output->command('display_message', $this->gettext('sauserpreffailed'), 'error'); 271 } 272 else { 273 $this->api->output->command('display_message', $data['message'] ? $data['message'] : $this->gettext('sauserpreffailed'), 'error'); 274 } 275 276 // go to next step 277 $rcmail->overwrite_action('plugin.sauserprefs.edit'); 278 $this->_load_user_prefs(); 279 $this->init_html(); 280 } 281 282 function whitelist_import() 283 { 284 $contacts = rcube::get_instance()->get_address_book($this->addressbook); 285 $contacts->set_page(1); 286 $contacts->set_pagesize(99999); 287 $result = $contacts->list_records(null, 0, true); 288 289 if (empty($result) || $result->count == 0) 290 return; 291 292 $records = $result->records; 293 foreach ($records as $row_data) { 294 foreach ($this->_gen_email_arr($row_data) as $email) 295 $this->api->output->command('sauserprefs_addressrule_import', $email, '', ''); 296 } 297 298 $contacts->close(); 299 } 300 301 function purge_bayes() 302 { 303 $rcmail = rcube::get_instance(); 304 305 if (!$rcmail->config->get('sauserprefs_bayes_delete', false)) { 306 $this->api->output->command('display_message', $this->gettext('servererror'), 'error'); 307 return; 308 } 309 310 if ($this->storage->purge_bayes()) 311 $this->api->output->command('display_message', $this->gettext('done'), 'confirmation'); 312 else 313 $this->api->output->command('display_message', $this->gettext('servererror'), 'error'); 314 } 315 316 function contact_add($args) 317 { 318 $rcmail = rcube::get_instance(); 319 320 // only works with specified address book 321 if ($args['source'] != $this->addressbook && $args['source'] != null) 322 return; 323 324 $emails = $this->_gen_email_arr($args['record']); 325 $this->storage->whitelist_add($emails); 326 } 327 328 function contact_save($args) 329 { 330 $this->contact_delete($args); 331 $this->contact_add($args); 332 } 333 334 function contact_delete($args) 335 { 336 $rcmail = rcube::get_instance(); 337 338 // only works with specified address book 339 if ($args['source'] != $this->addressbook && $args['source'] != null) 340 return; 341 342 if (!is_array($args['id'])) 343 $args['id'] = array($args['id']); 344 345 $contacts = $rcmail->get_address_book($this->addressbook); 346 foreach ($args['id'] as $id) { 347 $emails = $this->_gen_email_arr($contacts->get_record($id, true)); 348 $this->storage->whitelist_delete($emails); 349 } 350 351 $contacts->close(); 352 } 353 354 private function _load_global_prefs() 355 { 356 $rcmail = rcube::get_instance(); 357 $this->global_prefs = $this->_load_prefs($rcmail->config->get('sauserprefs_global_userid')); 358 $this->global_prefs = array_merge($rcmail->config->get('sauserprefs_default_prefs'), $this->global_prefs); 359 } 360 361 private function _load_user_prefs() 362 { 363 $this->user_prefs = $this->_load_prefs($this->sa_user); 364 } 365 366 private function _load_prefs($user) 367 { 368 $rcmail = rcube::get_instance(); 369 $prefs = $this->storage->load_prefs($user); 370 371 // sort address rules 372 $prefs['addresses'] = $this->_subval_sort($prefs['addresses'], 'value'); 373 374 return $prefs; 375 } 376 377 private function _prefs_block($part, $attrib) 378 { 379 $rcmail = rcube::get_instance(); 380 $no_override = array_flip($rcmail->config->get('sauserprefs_dont_override')); 381 $locale_info = localeconv(); 382 383 switch ($part) 384 { 385 // General tests 386 case 'general': 387 $out = ''; 388 $data = ''; 389 390 $table = new html_table(array('class' => 'generalprefstable', 'cols' => 2)); 391 392 if (!isset($no_override['required_hits'])) { 393 $field_id = 'rcmfd_spamthres'; 394 $input_spamthres = new html_select(array('name' => '_spamthres', 'id' => $field_id)); 395 $input_spamthres->add($this->gettext('defaultscore'), ''); 396 397 $decPlaces = 0; 398 if ($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc') > 0) 399 $decPlaces = strlen($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc')) - 2; 400 401 $score_found = false; 402 for ($i = 1; $i <= 10; $i = $i + $rcmail->config->get('sauserprefs_score_inc')) { 403 $input_spamthres->add(number_format($i, $decPlaces, $locale_info['decimal_point'], ''), number_format($i, $decPlaces, '.', '')); 404 405 if (!$score_found && $this->user_prefs['required_hits'] && (float)$this->user_prefs['required_hits'] == (float)$i) 406 $score_found = true; 407 } 408 409 if (!$score_found && $this->user_prefs['required_hits']) 410 $input_spamthres->add(str_replace('%s', $this->user_prefs['required_hits'], $this->gettext('otherscore')), (float)$this->user_prefs['required_hits']); 411 412 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('spamthres')))); 413 $table->add(null, $input_spamthres->show(number_format($this->user_prefs['required_hits'], $decPlaces, '.', ''))); 414 $table->add(array('colspan' => 2), rcmail::Q($this->gettext('spamthresexp'))); 415 } 416 417 if (!isset($no_override['rewrite_header Subject'])) { 418 $field_id = 'rcmfd_spamsubject'; 419 $input_spamsubject = new html_inputfield(array('name' => '_spamsubject', 'id' => $field_id, 'value' => $this->user_prefs['rewrite_header Subject'], 'style' => 'width:200px;')); 420 421 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('spamsubject')))); 422 $table->add(null, $input_spamsubject->show()); 423 424 $table->add('title', " "); 425 $table->add(null, rcmail::Q($this->gettext('spamsubjectblank'))); 426 } 427 428 if ($table->size() > 0) 429 $out .= html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $table->show()); 430 431 if (!isset($no_override['ok_languages']) || !isset($no_override['ok_locales'])) { 432 $data = html::p(null, rcmail::Q($this->gettext('spamlangexp'))); 433 434 $table = new html_table(array('class' => 'langprefstable', 'cols' => 1)); 435 436 $select_all = $this->api->output->button(array('command' => 'plugin.sauserprefs.select_all_langs', 'type' => 'link', 'label' => 'all')); 437 $select_none = $this->api->output->button(array('command' => 'plugin.sauserprefs.select_no_langs', 'type' => 'link', 'label' => 'none')); 438 $select_invert = $this->api->output->button(array('command' => 'plugin.sauserprefs.select_invert_langs', 'type' => 'link', 'label' => 'invert')); 439 440 $table->add(array('id' => 'listcontrols'), $this->gettext('select') .": ". $select_all ." ". $select_invert ." ". $select_none); 441 442 $lang_table = new html_table(array('id' => 'spam-langs-table', 'class' => 'records-table', 'cellspacing' => '0', 'cols' => 2)); 443 $lang_table->add_header(array('colspan' => 2), $this->gettext('language')); 444 445 if (!isset($no_override['ok_locales'])) { 446 if ($this->user_prefs['ok_locales'] == "all") 447 $ok_locales = $this->sa_locales; 448 else 449 $ok_locales = explode(" ", $this->user_prefs['ok_locales']); 450 } 451 else { 452 $ok_locales = array(); 453 } 454 455 if (!isset($no_override['ok_languages'])) { 456 if ($this->user_prefs['ok_languages'] == "all") 457 $ok_languages = array_keys($rcmail->config->get('sauserprefs_languages')); 458 else 459 $ok_languages = explode(" ", $this->user_prefs['ok_languages']); 460 } 461 else { 462 $tmp_array = $rcmail->config->get('sauserprefs_languages'); 463 $rcmail->config->set('sauserprefs_languages', array_intersect_key($tmp_array, array_flip($this->sa_locales))); 464 $ok_languages = array(); 465 } 466 467 $i = 0; 468 $locales_langs = array_merge($ok_locales, $ok_languages); 469 foreach ($rcmail->config->get('sauserprefs_languages') as $lang_code => $name) { 470 if (in_array($lang_code, $locales_langs)) 471 $button = $this->api->output->button(array('command' => 'plugin.sauserprefs.message_lang', 'prop' => $lang_code, 'type' => 'link', 'class' => 'enabled', 'id' => 'spam_lang_' . $i, 'title' => 'sauserprefs.enabled', 'content' => ' ')); 472 else 473 $button = $this->api->output->button(array('command' => 'plugin.sauserprefs.message_lang', 'prop' => $lang_code, 'type' => 'link', 'class' => 'disabled', 'id' => 'spam_lang_' . $i, 'title' => 'sauserprefs.disabled', 'content' => ' ')); 474 475 $input_spamlang = new html_checkbox(array('style' => 'display: none;', 'name' => '_spamlang[]', 'value' => $lang_code)); 476 477 $lang_table->add('lang', $name); 478 $lang_table->add('tick', $button . $input_spamlang->show(in_array($lang_code, $locales_langs) ? $lang_code : '')); 479 480 $i++; 481 } 482 483 $table->add('scroller', html::div(array('id' => 'spam-langs-cont'), $lang_table->show())); 484 485 $out .= html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('langoptions'))) . $data . $table->show()); 486 } 487 488 break; 489 490 // Header settings 491 case 'headers': 492 $data = html::p(null, rcmail::Q($this->gettext('headersexp'))); 493 494 $table = new html_table(array('class' => 'headersprefstable', 'cols' => 3)); 495 496 if (!isset($no_override['fold_headers'])) { 497 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 498 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("fold_help");', 'title' => $this->gettext('help')), $help_button); 499 500 $field_id = 'rcmfd_spamfoldheaders'; 501 $input_spamreport = new html_checkbox(array('name' => '_spamfoldheaders', 'id' => $field_id, 'value' => '1')); 502 503 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('foldheaders')))); 504 $table->add(null, $input_spamreport->show($this->user_prefs['fold_headers'])); 505 $table->add('help', $help_button); 506 $table->set_row_attribs(array('id' => 'fold_help', 'style' => 'display: none;')); 507 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('foldhelp'))); 508 } 509 510 if (!isset($no_override['add_header all Level'])) { 511 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 512 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("level_help");', 'title' => $this->gettext('help')), $help_button); 513 514 if ($this->user_prefs['remove_header all'] != 'Level') { 515 $enabled = "1"; 516 $char = $this->user_prefs['add_header all Level']; 517 $char = substr($char, 7, 1); 518 } 519 else { 520 $enabled = "0"; 521 $char = "*"; 522 } 523 524 $field_id = 'rcmfd_spamlevelstars'; 525 $input_spamreport = new html_checkbox(array('name' => '_spamlevelstars', 'id' => $field_id, 'value' => '1', 526 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sauserprefs_toggle_level_char(this)')); 527 528 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('spamlevelstars')))); 529 $table->add(null, $input_spamreport->show($enabled)); 530 $table->add('help', $help_button); 531 $table->set_row_attribs(array('id' => 'level_help', 'style' => 'display: none;')); 532 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('levelhelp'))); 533 534 $field_id = 'rcmfd_spamlevelchar'; 535 $input_spamsubject = new html_inputfield(array('name' => '_spamlevelchar', 'id' => $field_id, 'value' => $char, 536 'style' => 'width:20px;', 'disabled' => $enabled?0:1)); 537 538 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('spamlevelchar')))); 539 $table->add(null, $input_spamsubject->show()); 540 $table->add('help', ' '); 541 } 542 543 $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $data . $table->show()); 544 break; 545 546 // Test settings 547 case 'tests': 548 $data = html::p(null, rcmail::Q($this->gettext('spamtestssexp'))); 549 550 $table = new html_table(array('class' => 'testsprefstable', 'cols' => 3)); 551 552 if (!isset($no_override['use_razor1'])) { 553 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 554 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("raz1_help");', 'title' => $this->gettext('help')), $help_button); 555 556 $field_id = 'rcmfd_spamuserazor1'; 557 $input_spamtest = new html_checkbox(array('name' => '_spamuserazor1', 'id' => $field_id, 'value' => '1')); 558 559 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('userazor1')))); 560 $table->add(null, $input_spamtest->show($this->user_prefs['use_razor1'])); 561 $table->add('help', $help_button); 562 $table->set_row_attribs(array('id' => 'raz1_help', 'style' => 'display: none;')); 563 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('raz1help'))); 564 } 565 566 if (!isset($no_override['use_razor2'])) { 567 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 568 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("raz2_help");', 'title' => $this->gettext('help')), $help_button); 569 570 $field_id = 'rcmfd_spamuserazor2'; 571 $input_spamtest = new html_checkbox(array('name' => '_spamuserazor2', 'id' => $field_id, 'value' => '1')); 572 573 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('userazor2')))); 574 $table->add(null, $input_spamtest->show($this->user_prefs['use_razor2'])); 575 $table->add('help', $help_button); 576 $table->set_row_attribs(array('id' => 'raz2_help', 'style' => 'display: none;')); 577 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('raz2help'))); 578 } 579 580 if (!isset($no_override['use_pyzor'])) { 581 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 582 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("pyz_help");', 'title' => $this->gettext('help')), $help_button); 583 584 $field_id = 'rcmfd_spamusepyzor'; 585 $input_spamtest = new html_checkbox(array('name' => '_spamusepyzor', 'id' => $field_id, 'value' => '1')); 586 587 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('usepyzor')))); 588 $table->add(null, $input_spamtest->show($this->user_prefs['use_pyzor'])); 589 $table->add('help', $help_button); 590 $table->set_row_attribs(array('id' => 'pyz_help', 'style' => 'display: none;')); 591 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('pyzhelp'))); 592 } 593 594 if (!isset($no_override['use_dcc'])) { 595 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 596 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("dcc_help");', 'title' => $this->gettext('help')), $help_button); 597 598 $field_id = 'rcmfd_spamusedcc'; 599 $input_spamtest = new html_checkbox(array('name' => '_spamusedcc', 'id' => $field_id, 'value' => '1')); 600 601 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('usedcc')))); 602 $table->add(null, $input_spamtest->show($this->user_prefs['use_dcc'])); 603 $table->add('help', $help_button); 604 $table->set_row_attribs(array('id' => 'dcc_help', 'style' => 'display: none;')); 605 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('dcchelp'))); 606 } 607 608 if (!isset($no_override['skip_rbl_checks'])) { 609 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 610 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("rbl_help");', 'title' => $this->gettext('help')), $help_button); 611 612 $field_id = 'rcmfd_spamskiprblchecks'; 613 $enabled = $this->user_prefs['skip_rbl_checks'] == "1" ? "0" : "1"; 614 $input_spamtest = new html_checkbox(array('name' => '_spamskiprblchecks', 'id' => $field_id, 'value' => '1')); 615 616 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('skiprblchecks')))); 617 $table->add(null, $input_spamtest->show($enabled)); 618 $table->add('help', $help_button); 619 $table->set_row_attribs(array('id' => 'rbl_help', 'style' => 'display: none;')); 620 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('rblhelp'))); 621 } 622 623 $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $data . $table->show()); 624 break; 625 626 // Bayes settings 627 case 'bayes': 628 $data = html::p(null, rcmail::Q($this->gettext('bayeshelp'))); 629 630 $table = new html_table(array('class' => 'bayesprefstable', 'cols' => 3)); 631 632 if (!isset($no_override['use_bayes'])) { 633 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 634 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("bayes_help");', 'title' => $this->gettext('help')), $help_button); 635 636 $field_id = 'rcmfd_spamusebayes'; 637 $input_spamtest = new html_checkbox(array('name' => '_spamusebayes', 'id' => $field_id, 'value' => '1', 638 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sauserprefs_toggle_bayes(this)')); 639 640 if ($rcmail->config->get('sauserprefs_bayes_delete', false)) 641 $delete_link = " " . html::span(array('id' => 'listcontrols'), $this->api->output->button(array('command' => 'plugin.sauserprefs.purge_bayes', 'type' => 'link', 'label' => 'sauserprefs.purgebayes', 'title' => 'sauserprefs.purgebayesexp'))); 642 643 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('usebayes')))); 644 $table->add(null, $input_spamtest->show($this->user_prefs['use_bayes']) . $delete_link); 645 $table->add('help', ' '); 646 $table->set_row_attribs(array('id' => 'bayes_help', 'style' => 'display: none;')); 647 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('bayeshelp'))); 648 } 649 650 if (!isset($no_override['use_bayes_rules'])) { 651 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 652 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("bayesrules_help");', 'title' => $this->gettext('help')), $help_button); 653 654 $field_id = 'rcmfd_spambayesrules'; 655 $input_spamtest = new html_checkbox(array('name' => '_spambayesrules', 'id' => $field_id, 'value' => '1', 'disabled' => $this->user_prefs['use_bayes']?0:1)); 656 657 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('bayesrules')))); 658 $table->add(null, $input_spamtest->show($this->user_prefs['use_bayes_rules'])); 659 $table->add('help', $help_button); 660 $table->set_row_attribs(array('id' => 'bayesrules_help', 'style' => 'display: none;')); 661 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('bayesruleshlp'))); 662 } 663 664 if (!isset($no_override['bayes_auto_learn'])) { 665 $help_button = html::img(array('class' => $imgclass, 'src' => $attrib['helpicon'], 'alt' => $this->gettext('sieveruleheaders'), 'border' => 0, 'style' => 'margin-left: 4px;')); 666 $help_button = html::a(array('name' => '_headerhlp', 'href' => "#", 'onclick' => 'return '. rcmail_output::JS_OBJECT_NAME .'.sauserprefs_help("bayesauto_help");', 'title' => $this->gettext('help')), $help_button); 667 668 $field_id = 'rcmfd_spambayesautolearn'; 669 $input_spamtest = new html_checkbox(array('name' => '_spambayesautolearn', 'id' => $field_id, 'value' => '1', 670 'onchange' => rcmail_output::JS_OBJECT_NAME . '.sauserprefs_toggle_bayes_auto(this)', 'disabled' => $this->user_prefs['use_bayes']?0:1)); 671 672 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('bayesautolearn')))); 673 $table->add(null, $input_spamtest->show($this->user_prefs['bayes_auto_learn'])); 674 $table->add('help', $help_button); 675 $table->set_row_attribs(array('id' => 'bayesauto_help', 'style' => 'display: none;')); 676 $table->add(array('colspan' => '3'), rcmail::Q($this->gettext('bayesautohelp'))); 677 } 678 679 if ($table->size() > 0) 680 $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $table->show()); 681 682 $table = new html_table(array('class' => 'bayesprefstable', 'cols' => 2)); 683 684 $data = ""; 685 if (!isset($no_override['bayes_auto_learn_threshold_nonspam'])) { 686 $field_id = 'rcmfd_bayesnonspam'; 687 $input_bayesnthres = new html_select(array('name' => '_bayesnonspam', 'id' => $field_id, 'disabled' => (!$this->user_prefs['bayes_auto_learn'] || !$this->user_prefs['use_bayes'])?1:0)); 688 $input_bayesnthres->add($this->gettext('defaultscore'), ''); 689 690 $decPlaces = 1; 691 //if ($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc') > 0) 692 // $decPlaces = strlen($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc')) - 2; 693 694 $score_found = false; 695 for ($i = -1; $i <= 1; $i = $i + 0.1) { 696 $input_bayesnthres->add(number_format($i, $decPlaces, $locale_info['decimal_point'], ''), number_format($i, $decPlaces, '.', '')); 697 698 if (!$score_found && $this->user_prefs['bayes_auto_learn_threshold_nonspam'] && (float)$this->user_prefs['bayes_auto_learn_threshold_nonspam'] == (float)$i) 699 $score_found = true; 700 } 701 702 if (!$score_found && $this->user_prefs['bayes_auto_learn_threshold_nonspam']) 703 $input_bayesnthres->add(str_replace('%s', $this->user_prefs['bayes_auto_learn_threshold_nonspam'], $this->gettext('otherscore')), (float)$this->user_prefs['bayes_auto_learn_threshold_nonspam']); 704 705 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('bayesnonspam')))); 706 $table->add(null, $input_bayesnthres->show(number_format($this->user_prefs['bayes_auto_learn_threshold_nonspam'], $decPlaces, '.', ''))); 707 $table->add(array('colspan' => '2'), rcmail::Q($this->gettext('bayesnonspamexp'))); 708 } 709 710 if (!isset($no_override['bayes_auto_learn_threshold_spam'])) { 711 $field_id = 'rcmfd_bayesspam'; 712 $input_bayesthres = new html_select(array('name' => '_bayesspam', 'id' => $field_id, 'disabled' => (!$this->user_prefs['bayes_auto_learn'] || !$this->user_prefs['use_bayes'])?1:0)); 713 $input_bayesthres->add($this->gettext('defaultscore'), ''); 714 715 $decPlaces = 0; 716 if ($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc') > 0) 717 $decPlaces = strlen($rcmail->config->get('sauserprefs_score_inc') - (int)$rcmail->config->get('sauserprefs_score_inc')) - 2; 718 719 $score_found = false; 720 for ($i = 1; $i <= 20; $i = $i + $rcmail->config->get('sauserprefs_score_inc')) { 721 $input_bayesthres->add(number_format($i, $decPlaces, $locale_info['decimal_point'], ''), number_format($i, $decPlaces, '.', '')); 722 723 if (!$score_found && $this->user_prefs['bayes_auto_learn_threshold_spam'] && (float)$this->user_prefs['bayes_auto_learn_threshold_spam'] == (float)$i) 724 $score_found = true; 725 } 726 727 if (!$score_found && $this->user_prefs['required_hits']) 728 $input_bayesthres->add(str_replace('%s', $this->user_prefs['bayes_auto_learn_threshold_spam'], $this->gettext('otherscore')), (float)$this->user_prefs['bayes_auto_learn_threshold_spam']); 729 730 $table->add('title', html::label($field_id, rcmail::Q($this->gettext('bayesspam')))); 731 $table->add(null, $input_bayesthres->show(number_format($this->user_prefs['bayes_auto_learn_threshold_spam'], $decPlaces, '.', ''))); 732 $table->add(array('colspan' => '2'), rcmail::Q($this->gettext('bayesspamexp'))); 733 } 734 735 if ($table->size() > 0) 736 $out .= html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('bayesautooptions'))) . $table->show()); 737 738 break; 739 740 // Report settings 741 case 'report': 742 $data = html::p(null, rcmail::Q($this->gettext('spamreport'))); 743 744 $table = new html_table(array('class' => 'reportprefstable', 'cols' => 2)); 745 746 if (!isset($no_override['report_safe'])) { 747 $field_id = 'rcmfd_spamreport'; 748 $input_spamreport0 = new html_radiobutton(array('name' => '_spamreport', 'id' => $field_id.'_0', 'value' => '0')); 749 $table->add('title', html::label($field_id.'_0', rcmail::Q($this->gettext('spamreport0')))); 750 $table->add(null, $input_spamreport0->show($this->user_prefs['report_safe'])); 751 752 $input_spamreport1 = new html_radiobutton(array('name' => '_spamreport', 'id' => $field_id.'_1', 'value' => '1')); 753 $table->add('title', html::label($field_id.'_1', rcmail::Q($this->gettext('spamreport1')))); 754 $table->add(null, $input_spamreport1->show($this->user_prefs['report_safe'])); 755 $data .= $input_spamreport1->show($this->user_prefs['report_safe']) ." ". html::label($field_id .'_1', rcmail::Q($this->gettext('spamreport1'))) . "<br />"; 756 757 $input_spamreport2 = new html_radiobutton(array('name' => '_spamreport', 'id' => $field_id.'_2', 'value' => '2')); 758 $table->add('title', html::label($field_id.'_2', rcmail::Q($this->gettext('spamreport2')))); 759 $table->add(null, $input_spamreport2->show($this->user_prefs['report_safe'])); 760 } 761 762 $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $table->show()); 763 break; 764 765 // Address settings 766 case 'addresses': 767 $data = html::p(null, rcmail::Q($this->gettext('whitelistexp'))); 768 769 if ($rcmail->config->get('sauserprefs_whitelist_sync')) 770 $data .= rcmail::Q($this->gettext('autowhitelist')) . "<br /><br />"; 771 772 $table = new html_table(array('class' => 'addressprefstable', 'cols' => 4)); 773 774 $field_id = 'rcmfd_spamaddressrule'; 775 $input_spamaddressrule = new html_select(array('name' => '_spamaddressrule', 'id' => $field_id)); 776 $input_spamaddressrule->add($this->gettext('whitelist_from'),'whitelist_from'); 777 $input_spamaddressrule->add($this->gettext('blacklist_from'), 'blacklist_from'); 778 $input_spamaddressrule->add($this->gettext('whitelist_to'), 'whitelist_to'); 779 780 $field_id = 'rcmfd_spamaddress'; 781 $input_spamaddress = new html_inputfield(array('name' => '_spamaddress', 'id' => $field_id, 'style' => 'width:200px;')); 782 783 $field_id = 'rcmbtn_add_address'; 784 $button_addaddress = $this->api->output->button(array('command' => 'plugin.sauserprefs.addressrule_add', 'type' => 'input', 'class' => 'button', 'label' => 'sauserprefs.addrule')); 785 786 $table->add('ruletype', $input_spamaddressrule->show()); 787 $table->add('address', $input_spamaddress->show()); 788 $table->add('action', $button_addaddress); 789 $table->add(null, " "); 790 791 $import = $this->api->output->button(array('command' => 'plugin.sauserprefs.import_whitelist', 'type' => 'link', 'label' => 'import', 'title' => 'sauserprefs.importfromaddressbook')); 792 $delete_all = $this->api->output->button(array('command' => 'plugin.sauserprefs.whitelist_delete_all', 'type' => 'link', 'label' => 'sauserprefs.deleteall')); 793 794 $table->add(array('colspan' => 4, 'id' => 'listcontrols'), $import ." ". $delete_all); 795 796 $address_table = new html_table(array('id' => 'address-rules-table', 'class' => 'records-table', 'cellspacing' => '0', 'cols' => 3)); 797 $address_table->add_header('rule', $this->gettext('rule')); 798 $address_table->add_header('email', $this->gettext('email')); 799 $address_table->add_header('control', ' '); 800 801 $this->_address_row($address_table, null, null, $attrib); 802 803 if (sizeof($this->user_prefs['addresses']) > 0) 804 $norules = 'display: none;'; 805 806 $address_table->set_row_attribs(array('style' => $norules)); 807 $address_table->add(array('colspan' => '3'), rcube_utils::rep_specialchars_output($this->gettext('noaddressrules'))); 808 809 $this->api->output->set_env('address_rule_count', sizeof($this->user_prefs['addresses'])); 810 foreach ($this->user_prefs['addresses'] as $address) 811 $this->_address_row($address_table, $address['field'], $address['value'], $attrib); 812 813 $table->add(array('colspan' => 4, 'class' => 'scroller'), html::div(array('id' => 'address-rules-cont'), $address_table->show())); 814 815 if ($table->size()) 816 $out = html::tag('fieldset', null, html::tag('legend', null, rcmail::Q($this->gettext('mainoptions'))) . $data . $table->show()); 817 818 break; 819 820 default: 821 $out = ''; 822 } 823 824 return $out; 825 } 826 827 private function _address_row($address_table, $field, $value, $attrib) 828 { 829 if (!isset($field)) 830 $address_table->set_row_attribs(array('style' => 'display: none;')); 831 832 $hidden_action = new html_hiddenfield(array('name' => '_address_rule_act[]', 'value' => '')); 833 $hidden_field = new html_hiddenfield(array('name' => '_address_rule_field[]', 'value' => $field)); 834 $hidden_text = new html_hiddenfield(array('name' => '_address_rule_value[]', 'value' => $value)); 835 836 switch ($field) 837 { 838 case "whitelist_from": 839 $fieldtxt = rcube_utils::rep_specialchars_output($this->gettext('whitelist_from')); 840 break; 841 case "blacklist_from": 842 $fieldtxt = rcube_utils::rep_specialchars_output($this->gettext('blacklist_from')); 843 break; 844 case "whitelist_to": 845 $fieldtxt = rcube_utils::rep_specialchars_output($this->gettext('whitelist_to')); 846 break; 847 } 848 849 $address_table->add(array('class' => $field), $fieldtxt); 850 $address_table->add(array('class' => 'email'), $value); 851 $del_button = $this->api->output->button(array('command' => 'plugin.sauserprefs.addressrule_del', 'type' => 'link', 'class' => 'delete', 'label' => 'delete', 'content' => ' ')); 852 $address_table->add('control', $del_button . $hidden_action->show() . $hidden_field->show() . $hidden_text->show()); 853 854 return $address_table; 855 } 856 857 static function map_pref_name($pref, $reverse = false) 858 { 859 if (!$reverse) { 860 if (array_key_exists($pref, self::$deprecated_prefs)) 861 $pref = self::$deprecated_prefs[$pref]; 862 } 863 else { 864 if (($orig_pref = array_search($pref, self::$deprecated_prefs)) != FALSE) 865 $pref = $orig_pref; 866 } 867 868 return $pref; 869 } 870 871 private function _subval_sort($a, $subkey) 872 { 873 if (sizeof($a) == 0) 874 return array(); 875 876 foreach ($a as $k => $v) 877 $b[$k] = strtolower($v[$subkey]); 878 879 asort($b); 880 881 foreach ($b as $k => $v) 882 $c[] = $a[$k]; 883 884 return $c; 885 } 886 887 private function _gen_email_arr($contact) 888 { 889 $emails = array(); 890 891 if (!is_array($contact)) 892 return $emails; 893 894 foreach ($contact as $key => $value) { 895 if (preg_match('/^email(:(.+))?$/i', $key, $matches)) { 896 foreach ((array)$value as $subkey => $subval) { 897 if ($matches[2]) 898 $emails[$matches[2] . $subkey] = $subval; 899 else 900 $emails['email' . $subkey] = $subval; 901 } 902 } 903 } 904 905 return $emails; 906 } 907} 908 909?>