| 1: | <?php |
| 2: | |
| 3: | |
| 4: | |
| 5: | |
| 6: | |
| 7: | |
| 8: | |
| 9: | if (!defined('DEBUG_MODE')) { die(); } |
| 10: | |
| 11: | |
| 12: | |
| 13: | |
| 14: | class Hm_Handler_highlight_list_data extends Hm_Handler_Module { |
| 15: | public function process() { |
| 16: | $this->out('highlight_rules', $this->user_config->get('highlight_rules', array())); |
| 17: | $this->out('github_repos', $this->user_config->get('github_repos', array())); |
| 18: | } |
| 19: | } |
| 20: | |
| 21: | |
| 22: | |
| 23: | |
| 24: | class Hm_Handler_highlight_page_data extends Hm_Handler_Module { |
| 25: | public function process() { |
| 26: | |
| 27: | $imap = false; |
| 28: | $feeds = false; |
| 29: | $github = false; |
| 30: | |
| 31: | $modules = $this->config->get_modules(); |
| 32: | |
| 33: | if ($this->module_is_supported('imap')) { |
| 34: | $imap = Hm_IMAP_List::dump(false); |
| 35: | } |
| 36: | if ($this->module_is_supported('feeds')) { |
| 37: | $feeds = Hm_Feed_List::dump(false); |
| 38: | } |
| 39: | if ($this->module_is_supported('github')) { |
| 40: | $github = $this->user_config->get('github_repos', array()); |
| 41: | } |
| 42: | $this->out('highlight_sources', array( |
| 43: | 'imap' => $imap, |
| 44: | 'feeds' => $feeds, |
| 45: | 'github' => $github |
| 46: | )); |
| 47: | $this->out('highlight_rules', $this->user_config->get('highlight_rules', array())); |
| 48: | } |
| 49: | } |
| 50: | |
| 51: | |
| 52: | |
| 53: | |
| 54: | class Hm_Handler_highlight_process_form extends Hm_Handler_Module { |
| 55: | public function process() { |
| 56: | if (array_key_exists('rule_del_id', $this->request->post)) { |
| 57: | $rules = $this->user_config->get('highlight_rules', array()); |
| 58: | unset($rules[$this->request->post['rule_del_id']]); |
| 59: | $rules = array_merge($rules); |
| 60: | $this->user_config->set('highlight_rules', $rules); |
| 61: | $this->session->record_unsaved('Highlight rule deleted'); |
| 62: | Hm_Msgs::add('Hightlight rule deleted'); |
| 63: | return; |
| 64: | } |
| 65: | list($success, $form) = $this->process_form(array('hl_source_type', 'hl_target', 'hl_color')); |
| 66: | if (!$success) { |
| 67: | return; |
| 68: | } |
| 69: | if (!in_array($form['hl_source_type'], array('imap', 'feeds', 'github'))) { |
| 70: | return; |
| 71: | } |
| 72: | if (!preg_match("/^#[0-9abcdef]{6}$/", mb_strtolower($form['hl_color']))) { |
| 73: | return; |
| 74: | } |
| 75: | foreach (array('hl_important', 'hl_imap_flags', 'hl_imap_sources', 'hl_feeds_sources', 'hl_github_sources') as $fld) { |
| 76: | if (array_key_exists($fld, $this->request->post) && $this->request->post[$fld]) { |
| 77: | $form[$fld] = $this->request->post[$fld]; |
| 78: | } |
| 79: | } |
| 80: | if ($form['hl_source_type'] == 'github' && |
| 81: | array_key_exists('hl_github_unseen', $this->request->post) && |
| 82: | $this->request->post['hl_github_unseen']) { |
| 83: | $form['hl_imap_flags'] = array('unseen'); |
| 84: | } |
| 85: | elseif ($form['hl_source_type'] == 'feeds' && |
| 86: | array_key_exists('hl_feeds_unseen', $this->request->post) && |
| 87: | $this->request->post['hl_feeds_unseen']) { |
| 88: | $form['hl_imap_flags'] = array('unseen'); |
| 89: | } |
| 90: | switch ($form['hl_source_type']) { |
| 91: | case 'imap': |
| 92: | $new_rule = hl_imap_rule($form); |
| 93: | break; |
| 94: | case 'feeds': |
| 95: | $new_rule = hl_feeds_rule($form); |
| 96: | break; |
| 97: | case 'github': |
| 98: | $new_rule = hl_github_rule($form, $this); |
| 99: | break; |
| 100: | } |
| 101: | $rules = $this->user_config->get('highlight_rules', array()); |
| 102: | $rules[] = $new_rule; |
| 103: | $this->user_config->set('highlight_rules', $rules); |
| 104: | $this->session->record_unsaved('Highlight rule created'); |
| 105: | Hm_Msgs::add('Hightlight rule created'); |
| 106: | } |
| 107: | } |
| 108: | |
| 109: | |
| 110: | |
| 111: | |
| 112: | class Hm_Output_highlight_css extends Hm_Output_Module { |
| 113: | protected function output() { |
| 114: | $css = array(); |
| 115: | $repos = $this->get('github_repos', array()); |
| 116: | $rules = $this->get('highlight_rules', array()); |
| 117: | $defaults = array('imap' => '.email', 'feeds' => '.feeds', 'github' => '.github'); |
| 118: | foreach ($rules as $rule) { |
| 119: | $ids = get_rule_ids($rule['sources'], $rule['type'], $repos); |
| 120: | if (!$ids) { |
| 121: | $ids = array($defaults[$rule['type']]); |
| 122: | } |
| 123: | if ($rule['types']) { |
| 124: | if (!$ids) { |
| 125: | foreach ($rule['types'] as $type) { |
| 126: | $ids[] = '.'.$type; |
| 127: | } |
| 128: | } |
| 129: | else { |
| 130: | $updated = array(); |
| 131: | foreach ($ids as $id) { |
| 132: | foreach ($rule['types'] as $type) { |
| 133: | $updated[] = $id.'.'.$type; |
| 134: | } |
| 135: | } |
| 136: | $ids = $updated; |
| 137: | } |
| 138: | } |
| 139: | foreach ($ids as $id) { |
| 140: | $css[] = sprintf('.message_table %s td {%s: %s !important;}', |
| 141: | $id, |
| 142: | ($rule['target'] == 'text' ? 'color': 'background-color'), |
| 143: | $rule['color'], ($rule['important'] ? '!important' : '') |
| 144: | ); |
| 145: | if ($rule['target'] == 'text') { |
| 146: | $css[] = sprintf('.message_table %s td a {color: %s !important;}', |
| 147: | $id, $rule['color'], ($rule['important'] ? '!important' : '')); |
| 148: | } |
| 149: | else { |
| 150: | $css[] = sprintf('.message_table %s td div {background-color: %s !important;}', |
| 151: | $id, $rule['color'], ($rule['important'] ? '!important' : '')); |
| 152: | } |
| 153: | } |
| 154: | } |
| 155: | $res = '<style type="text/css">'.implode(' ', $css).'</style>'; |
| 156: | return $res; |
| 157: | } |
| 158: | } |
| 159: | |
| 160: | |
| 161: | |
| 162: | |
| 163: | class Hm_Output_highlight_config_page extends Hm_Output_Module { |
| 164: | protected function output() { |
| 165: | $rules = $this->get('highlight_rules', array()); |
| 166: | $sources = $this->get('highlight_sources', array()); |
| 167: | $source_types = array('E-mail' => 'imap'); |
| 168: | if ($sources['feeds'] !== false) { |
| 169: | $source_types['RSS'] = 'feeds'; |
| 170: | } |
| 171: | if ($sources['github'] !== false) { |
| 172: | $source_types['Github'] = 'github'; |
| 173: | } |
| 174: | $email_types = array( |
| 175: | 'Unseen' => 'unseen', |
| 176: | 'Seen' => 'seen', |
| 177: | 'Flagged' => 'flagged', |
| 178: | 'Deleted' => 'deleted', |
| 179: | 'Anwered' => 'answered' |
| 180: | ); |
| 181: | $targets = array( |
| 182: | 'Text' => 'text', |
| 183: | 'Background' => 'background' |
| 184: | ); |
| 185: | $res = '<div class="content_title">'.$this->trans('Message highlighting').'</div>'; |
| 186: | $res .= '<div class="settings_subtitle mt-3 mb-2"><b>'.$this->trans('Existing rules').'</b></div>'; |
| 187: | if (!$rules) { |
| 188: | $res .= '<div class="empty_list">'.$this->trans('No rules').'</div>'; |
| 189: | } |
| 190: | else { |
| 191: | $res .= '<div class="px-3"><table class="hl_rules table table-striped">'. |
| 192: | '<th>'.$this->trans('Type').'</th>'. |
| 193: | '<th>'.$this->trans('Target').'</th>'. |
| 194: | '<th>'.$this->trans('Color').'</th>'. |
| 195: | '<th>'.$this->trans('Sources').'</th>'. |
| 196: | '<th>'.$this->trans('Flags').'</th><th>'.$this->trans('Force').'</th><th></th></tr>'; |
| 197: | foreach ($rules as $index => $rule) { |
| 198: | if ($rule['types']) { |
| 199: | $types = implode(' ', $rule['types']); |
| 200: | } |
| 201: | else { |
| 202: | $types = '*'; |
| 203: | } |
| 204: | if ($rule['sources']) { |
| 205: | $src = array(); |
| 206: | foreach ($rule['sources'] as $vals) { |
| 207: | $src[] = $vals['name']; |
| 208: | } |
| 209: | $src = implode(' ', $src); |
| 210: | } |
| 211: | else { |
| 212: | $src = '*'; |
| 213: | } |
| 214: | $res .= '<tr>'. |
| 215: | '<td>'.$this->html_safe($rule['type']).'</td>'. |
| 216: | '<td>'.$this->html_safe($rule['target']).'</td>'. |
| 217: | '<td style="'.($rule['target'] == 'text' ? 'color' : 'background-color').': '. |
| 218: | $this->html_safe($rule['color']).' !important;">'.$this->html_safe($rule['color']).'</td>'. |
| 219: | '<td>'.$this->html_safe($src).'</td>'. |
| 220: | '<td>'.$this->html_safe($types).'</td>'. |
| 221: | '<td>'.$this->html_safe($rule['important'] ? 'true' : 'false').'</td>'. |
| 222: | '<td><form method="POST">'. |
| 223: | '<input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'. |
| 224: | '<input type="hidden" name="rule_del_id" value="'.$this->html_safe($index).'" />'. |
| 225: | '<button type="submit" class="rule_del btn btn-light"><i class="bi bi-x-circle-fill"></i></button></form>'. |
| 226: | '</tr>'; |
| 227: | } |
| 228: | } |
| 229: | $res .= '</table></div>'; |
| 230: | |
| 231: | $res .= '<div class="settings_subtitle mt-3 px-3"><b>'.$this->trans('Add a new rule').'</b></div>'; |
| 232: | $res .= '<div class="col-12 col-lg-5 mt-2 px-3">'; |
| 233: | $res .= '<form method="POST">'; |
| 234: | |
| 235: | |
| 236: | $res .= '<div class="form-floating mb-3">'; |
| 237: | $res .= '<select name="hl_source_type" required class="form-select hl_source_type">'; |
| 238: | $res .= '<option selected="selected">'.$this->trans('Select source type').'</option>'; |
| 239: | foreach ($source_types as $name => $val) { |
| 240: | $res .= '<option value="'.$this->html_safe($val).'">'.$this->trans($name).'</option>'; |
| 241: | } |
| 242: | $res .= '</select>'; |
| 243: | $res .= '<label>'.$this->trans('Source type').'</label></div>'; |
| 244: | |
| 245: | |
| 246: | if ($sources['imap']) { |
| 247: | $res .= '<div class="form-floating mb-3 imap_row d-none">'; |
| 248: | $res .= '<select style="min-height: 8rem" name="hl_imap_flags[]" size="4" multiple="multiple" class="form-select imap_flags">'; |
| 249: | foreach ($email_types as $index => $value) { |
| 250: | $res .= '<option value="'.$this->html_safe($value).'">'.$this->trans($index).'</option>'; |
| 251: | } |
| 252: | $res .= '</select>'; |
| 253: | $res .= '<label>'.$this->trans('Flags').'</label></div>'; |
| 254: | |
| 255: | |
| 256: | $res .= '<div class="form-floating mb-3 imap_row d-none">'; |
| 257: | $res .= '<select style="min-height: 8rem" name="hl_imap_sources[]" size="4" multiple="multiple" class="form-select imap_source">'; |
| 258: | foreach ($sources['imap'] as $index => $vals) { |
| 259: | $res .= '<option value="'.$this->html_safe($index).'">'.$this->trans($vals['name']).'</option>'; |
| 260: | } |
| 261: | $res .= '</select>'; |
| 262: | $res .= '<label>'.$this->trans('Accounts').'</label></div>'; |
| 263: | } |
| 264: | |
| 265: | |
| 266: | if ($sources['feeds']) { |
| 267: | |
| 268: | $res .= '<div class="form-floating mb-3 feeds_row d-none">'; |
| 269: | $res .= '<select style="min-height: 8rem" name="hl_feeds_sources[]" size="4" multiple="multiple" class="form-select feeds_source">'; |
| 270: | foreach ($sources['feeds'] as $index => $vals) { |
| 271: | $res .= '<option value="'.$this->html_safe($index).'">'.$this->trans($vals['name']).'</option>'; |
| 272: | } |
| 273: | $res .= '</select>'; |
| 274: | $res .= '<label>'.$this->trans('Feeds').'</label></div>'; |
| 275: | |
| 276: | |
| 277: | $res .= '<div class="form-check mb-3 feeds_row d-none">'; |
| 278: | $res .= '<input name="hl_feeds_unseen" type="checkbox" value="true" class="form-check-input" />'; |
| 279: | $res .= '<label class="form-check-label">'.$this->trans('Unseen').'</label></div>'; |
| 280: | } |
| 281: | |
| 282: | |
| 283: | if ($sources['github']) { |
| 284: | |
| 285: | $res .= '<div class="form-floating mb-3 github_row d-none">'; |
| 286: | $res .= '<select style="min-height: 8rem" name="hl_github_sources[]" size="4" multiple="multiple" class="form-select github_source">'; |
| 287: | foreach ($sources['github'] as $repo) { |
| 288: | $res .= '<option value="'.$this->html_safe($repo).'">'.$this->trans($repo).'</option>'; |
| 289: | } |
| 290: | $res .= '</select>'; |
| 291: | $res .= '<label>'.$this->trans('Repos').'</label></div>'; |
| 292: | |
| 293: | |
| 294: | $res .= '<div class="form-check mb-3 github_row d-none">'; |
| 295: | $res .= '<input name="hl_github_unseen" type="checkbox" value="true" class="form-check-input" />'; |
| 296: | $res .= '<label class="form-check-label">'.$this->trans('Unseen').'</label></div>'; |
| 297: | } |
| 298: | |
| 299: | |
| 300: | $res .= '<div class="form-floating mb-3">'; |
| 301: | $res .= '<select name="hl_target" class="form-select">'; |
| 302: | foreach ($targets as $name => $val) { |
| 303: | $res .= '<option value="'.$this->html_safe($val).'">'.$this->trans($name).'</option>'; |
| 304: | } |
| 305: | $res .= '</select>'; |
| 306: | $res .= '<label>'.$this->trans('Highlight target').'</label></div>'; |
| 307: | |
| 308: | |
| 309: | $res .= '<div class="mb-3">'; |
| 310: | $res .= '<label>'.$this->trans('Highlight color').'</label>'; |
| 311: | $res .= '<input style="min-height: 3rem" name="hl_color" type="color" class="form-control p-1" /></div>'; |
| 312: | |
| 313: | |
| 314: | $res .= '<div class="form-check mb-3">'; |
| 315: | $res .= '<input value="true" type="checkbox" name="hl_important" class="form-check-input" />'; |
| 316: | $res .= '<label class="form-check-label">'.$this->trans('CSS override').'</label></div>'; |
| 317: | |
| 318: | |
| 319: | $res .= '<div class="submit_row">'; |
| 320: | $res .= '<input type="submit" value="'.$this->trans('Add').'" class="btn btn-primary px-5" />'; |
| 321: | $res .= '<input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'; |
| 322: | $res .= '</div></form></div>'; |
| 323: | |
| 324: | return $res; |
| 325: | |
| 326: | } |
| 327: | } |
| 328: | |
| 329: | |
| 330: | |
| 331: | |
| 332: | class Hm_Output_highlight_link extends Hm_Output_Module { |
| 333: | protected function output() { |
| 334: | $res = '<li class="menu_highlights"><a class="unread_link" href="?page=highlights">'; |
| 335: | if (!$this->get('hide_folder_icons')) { |
| 336: | $res .= '<i class="bi bi-highlighter fs-5 me-2"></i>'; |
| 337: | } |
| 338: | $res .= $this->trans('Highlights').'</a></li>'; |
| 339: | if ($this->format == 'HTML5') { |
| 340: | return $res; |
| 341: | } |
| 342: | $this->concat('formatted_folder_list', $res); |
| 343: | } |
| 344: | } |
| 345: | |
| 346: | |
| 347: | |
| 348: | |
| 349: | function hl_base_rule($form, $type) { |
| 350: | if (array_key_exists('hl_important', $form) && $form['hl_important']) { |
| 351: | $important = true; |
| 352: | } |
| 353: | else { |
| 354: | $important = false; |
| 355: | } |
| 356: | return array( |
| 357: | 'important' => $important, |
| 358: | 'type' => $type, |
| 359: | 'color' => $form['hl_color'], |
| 360: | 'target' => $form['hl_target'], |
| 361: | 'sources' => array(), |
| 362: | 'types' => array() |
| 363: | ); |
| 364: | } |
| 365: | |
| 366: | |
| 367: | |
| 368: | |
| 369: | function hl_imap_rule($form) { |
| 370: | $rule = hl_base_rule($form, 'imap'); |
| 371: | if (array_key_exists('hl_imap_sources', $form)) { |
| 372: | foreach ($form['hl_imap_sources'] as $id) { |
| 373: | $server = Hm_IMAP_List::dump($id); |
| 374: | if (!$server) { |
| 375: | continue; |
| 376: | } |
| 377: | $rule['sources'][] = array('name' => $server['name'], |
| 378: | 'user' => $server['user'], 'server' => $server['server']); |
| 379: | } |
| 380: | } |
| 381: | if (array_key_exists('hl_imap_flags', $form)) { |
| 382: | $rule['types'] = $form['hl_imap_flags']; |
| 383: | } |
| 384: | return $rule; |
| 385: | } |
| 386: | |
| 387: | |
| 388: | |
| 389: | |
| 390: | function hl_feeds_rule($form) { |
| 391: | $rule = hl_base_rule($form, 'feeds'); |
| 392: | if (array_key_exists('hl_feeds_sources', $form)) { |
| 393: | foreach ($form['hl_feeds_sources'] as $id) { |
| 394: | $server = Hm_Feed_List::dump($id); |
| 395: | if (!$server) { |
| 396: | continue; |
| 397: | } |
| 398: | $rule['sources'][] = array('server' => $server['server'], |
| 399: | 'name' => $server['name']); |
| 400: | } |
| 401: | } |
| 402: | if (array_key_exists('hl_imap_flags', $form)) { |
| 403: | $rule['types'] = $form['hl_imap_flags']; |
| 404: | } |
| 405: | return $rule; |
| 406: | } |
| 407: | |
| 408: | |
| 409: | |
| 410: | |
| 411: | function hl_github_rule($form, $mod) { |
| 412: | $rule = hl_base_rule($form, 'github'); |
| 413: | if (array_key_exists('hl_github_sources', $form)) { |
| 414: | $repos = $mod->user_config->get('github_repos', array()); |
| 415: | foreach ($form['hl_github_sources'] as $id) { |
| 416: | foreach ($repos as $repo) { |
| 417: | if ($id == $repo) { |
| 418: | $rule['sources'][] = array('server' => $repo, 'name' => $repo); |
| 419: | } |
| 420: | } |
| 421: | } |
| 422: | } |
| 423: | if (array_key_exists('hl_imap_flags', $form)) { |
| 424: | $rule['types'] = $form['hl_imap_flags']; |
| 425: | } |
| 426: | return $rule; |
| 427: | } |
| 428: | |
| 429: | |
| 430: | |
| 431: | |
| 432: | function get_rule_ids($sources, $type, $repos) { |
| 433: | if ($type == 'imap') { |
| 434: | return get_imap_ids($sources); |
| 435: | } |
| 436: | elseif ($type == 'feeds') { |
| 437: | return get_feed_ids($sources); |
| 438: | } |
| 439: | elseif ($type == 'github') { |
| 440: | return get_github_ids($sources, $repos); |
| 441: | } |
| 442: | else { |
| 443: | return array(); |
| 444: | } |
| 445: | } |
| 446: | |
| 447: | |
| 448: | |
| 449: | |
| 450: | function get_imap_ids($sources) { |
| 451: | $ids = array(); |
| 452: | foreach (Hm_IMAP_List::dump() as $index => $vals) { |
| 453: | foreach ($sources as $src) { |
| 454: | if ($src['user'] == $vals['user'] && $src['server'] == $vals['server']) { |
| 455: | $ids[] = sprintf('[class^="imap_%s_"]', $index); |
| 456: | } |
| 457: | } |
| 458: | } |
| 459: | return $ids; |
| 460: | } |
| 461: | |
| 462: | |
| 463: | |
| 464: | |
| 465: | function get_feed_ids($sources) { |
| 466: | $ids = array(); |
| 467: | foreach (Hm_Feed_List::dump() as $index => $vals) { |
| 468: | foreach ($sources as $src) { |
| 469: | if ($src['name'] == $vals['name'] && $src['server'] == $vals['server']) { |
| 470: | $ids[] = sprintf('[class^="feeds_%s_"]', $index); |
| 471: | } |
| 472: | } |
| 473: | } |
| 474: | return $ids; |
| 475: | } |
| 476: | |
| 477: | |
| 478: | |
| 479: | |
| 480: | function get_github_ids($sources, $repos) { |
| 481: | $ids = array(); |
| 482: | foreach ($repos as $index => $val) { |
| 483: | foreach ($sources as $src) { |
| 484: | if ($src['server'] == $val) { |
| 485: | $ids[] = sprintf('[class^="github_%s_"]', $index); |
| 486: | } |
| 487: | } |
| 488: | } |
| 489: | return $ids; |
| 490: | } |
| 491: | |