| 1: | <?php |
| 2: | |
| 3: | |
| 4: | |
| 5: | |
| 6: | |
| 7: | |
| 8: | |
| 9: | |
| 10: | |
| 11: | |
| 12: | |
| 13: | class Hm_Output_search_from_folder_list extends Hm_Output_Module { |
| 14: | |
| 15: | |
| 16: | |
| 17: | protected function output() { |
| 18: | $res = '<li class="menu_search mb-2"><form method="get">'; |
| 19: | $res .= '<div class="input-group">'; |
| 20: | if (!$this->get('hide_folder_icons')) { |
| 21: | $res .= '<a href="?page=search" class="input-group-text" id="basic-addon1">' . |
| 22: | '<i class="bi bi-search"></i>' . |
| 23: | '</a>'; |
| 24: | } |
| 25: | $res .= '<input type="hidden" name="page" value="search" />'. |
| 26: | '<input type="search" class="search_terms form-control form-control-sm" aria-describedby="basic-addon1" '. |
| 27: | 'name="search_terms" placeholder="'.$this->trans('Search').'" /></div></form></li>'; |
| 28: | if ($this->format == 'HTML5') { |
| 29: | return $res; |
| 30: | } |
| 31: | $this->concat('formatted_folder_list', $res); |
| 32: | } |
| 33: | } |
| 34: | |
| 35: | |
| 36: | |
| 37: | |
| 38: | |
| 39: | class Hm_Output_search_content_start extends Hm_Output_Module { |
| 40: | |
| 41: | |
| 42: | |
| 43: | protected function output() { |
| 44: | return '<div class="search_content px-0"><div class="content_title px-3 d-flex align-items-center">'. |
| 45: | message_controls($this).$this->trans('Search'); |
| 46: | } |
| 47: | } |
| 48: | |
| 49: | |
| 50: | |
| 51: | |
| 52: | |
| 53: | class Hm_Output_search_content_end extends Hm_Output_Module { |
| 54: | |
| 55: | |
| 56: | |
| 57: | protected function output() { |
| 58: | return '</div>'; |
| 59: | } |
| 60: | } |
| 61: | |
| 62: | |
| 63: | |
| 64: | |
| 65: | |
| 66: | class Hm_Output_save_reminder extends Hm_Output_Module { |
| 67: | protected function output() { |
| 68: | if ($this->get('single_server_mode')) { |
| 69: | return ''; |
| 70: | } |
| 71: | $changed = $this->get('changed_settings', array()); |
| 72: | if (!empty($changed)) { |
| 73: | return '<div class="save_reminder"><a title="'.$this->trans('You have unsaved changes'). |
| 74: | '" href="?page=save"><i class="bi bi-save2-fill fs-4"></i></a></div>'; |
| 75: | } |
| 76: | return ''; |
| 77: | } |
| 78: | } |
| 79: | |
| 80: | |
| 81: | |
| 82: | |
| 83: | |
| 84: | class Hm_Output_search_form_start extends Hm_Output_Module { |
| 85: | protected function output() { |
| 86: | return '<div class="search_form"><form class="d-flex align-items-center" method="get">'; |
| 87: | } |
| 88: | } |
| 89: | |
| 90: | |
| 91: | |
| 92: | |
| 93: | |
| 94: | class Hm_Output_search_form_content extends Hm_Output_Module { |
| 95: | protected function output() { |
| 96: | $terms = $this->get('search_terms', ''); |
| 97: | |
| 98: | return '<input type="hidden" name="page" value="search" />'. |
| 99: | ' <label class="screen_reader" for="search_terms">'.$this->trans('Search Terms').'</label>'. |
| 100: | '<input required placeholder="'.$this->trans('Search Terms').'" id="search_terms" type="search" class="search_terms form-control form-control-sm" name="search_terms" value="'.$this->html_safe($terms).'" />'. |
| 101: | ' <label class="screen_reader" for="search_fld">'.$this->trans('Search Field').'</label>'. |
| 102: | search_field_selection($this->get('search_fld', DEFAULT_SEARCH_FLD), $this). |
| 103: | ' <label class="screen_reader" for="search_since">'.$this->trans('Search Since').'</label>'. |
| 104: | message_since_dropdown($this->get('search_since', DEFAULT_SEARCH_SINCE), 'search_since', $this). |
| 105: | combined_sort_dialog($this). |
| 106: | ' | <input type="submit" class="search_update btn btn-primary btn-sm" value="'.$this->trans('Update').'" />'. |
| 107: | ' <input type="button" class="search_reset btn btn-light border btn-sm" value="'.$this->trans('Reset').'" />'; |
| 108: | } |
| 109: | } |
| 110: | |
| 111: | |
| 112: | |
| 113: | |
| 114: | |
| 115: | class Hm_Output_search_form_end extends Hm_Output_Module { |
| 116: | protected function output() { |
| 117: | $source_link = '<a href="#" title="'.$this->trans('Sources').'" class="source_link"><i class="bi bi-folder-fill refresh_list"></i></a>'; |
| 118: | $refresh_link = '<a class="refresh_link ms-3" title="'.$this->trans('Refresh').'" href="#"><i class="bi bi-arrow-clockwise refresh_list"></i></a>'; |
| 119: | return '</form></div>'. |
| 120: | list_controls($refresh_link, false, $source_link).list_sources($this->get('data_sources', array()), $this).'</div>'; |
| 121: | } |
| 122: | } |
| 123: | |
| 124: | |
| 125: | |
| 126: | |
| 127: | |
| 128: | class Hm_Output_search_results_table_end extends Hm_Output_Module { |
| 129: | |
| 130: | |
| 131: | protected function output() { |
| 132: | return '</tbody></table>'; |
| 133: | } |
| 134: | } |
| 135: | |
| 136: | |
| 137: | |
| 138: | |
| 139: | |
| 140: | class Hm_Output_js_search_data extends Hm_Output_Module { |
| 141: | |
| 142: | |
| 143: | |
| 144: | protected function output() { |
| 145: | return '<script type="text/javascript" id="search-data">'. |
| 146: | 'var hm_search_terms = function() { return "'.$this->html_safe($this->get('search_terms', ''), true).'"; };'. |
| 147: | 'var hm_run_search = function() { return "'.$this->html_safe($this->get('run_search', 0)).'"; };'. |
| 148: | '</script>'; |
| 149: | } |
| 150: | } |
| 151: | |
| 152: | |
| 153: | |
| 154: | |
| 155: | |
| 156: | class Hm_Output_login_end extends Hm_Output_Module { |
| 157: | |
| 158: | |
| 159: | |
| 160: | protected function output() { |
| 161: | $fancy_login= $this->get('fancy_login_allowed'); |
| 162: | if(!$fancy_login){ |
| 163: | return '</form>'; |
| 164: | } |
| 165: | return '</form></div>'; |
| 166: | } |
| 167: | } |
| 168: | |
| 169: | |
| 170: | |
| 171: | |
| 172: | |
| 173: | class Hm_Output_login_start extends Hm_Output_Module { |
| 174: | |
| 175: | |
| 176: | |
| 177: | protected function output() { |
| 178: | $fancy_login = $this->get('fancy_login_allowed'); |
| 179: | if (!$fancy_login) { |
| 180: | if (!$this->get('router_login_state')) { |
| 181: | return '<form class="login_form" method="POST">'; |
| 182: | } |
| 183: | else { |
| 184: | return '<form class="logout_form" method="POST">'; |
| 185: | } |
| 186: | } else { |
| 187: | if (!$this->get('router_login_state')) { |
| 188: | $css = '<style type="text/css">body,html{max-width:100vw !important; max-height:100vh !important; overflow:hidden !important;}.form-container{background-color:#f1f1f1;'. |
| 189: | 'background: linear-gradient( rgba(4, 26, 0, 0.85), rgba(4, 26, 0, 0.85)), url('.WEB_ROOT.'modules/core/assets/images/cloud.jpg);'. |
| 190: | 'background-attachment: fixed;background-position: center;background-repeat: no-repeat;background-size: cover;'. |
| 191: | 'display:grid; place-items:center; height:100vh; width:100vw;} .logged_out{display:block !important;}.sys_messages'. |
| 192: | '{position:fixed;right:20px;top:15px;min-height:30px;display:none;background-color:#fff;color:teal;'. |
| 193: | 'margin-top:0px;padding:15px;padding-bottom:5px;white-space:nowrap;border:solid 1px #999;border-radius:'. |
| 194: | '5px;filter:drop-shadow(4px 4px 4px #ccc);z-index:101;}.g-recaptcha{margin:0px 10px 10px 10px;}.mobile .g-recaptcha{'. |
| 195: | 'margin:0px 10px 5px 10px;}.title{font-weight:normal;padding:0px;margin:0px;margin-left:20px;'. |
| 196: | 'margin-bottom:20px;letter-spacing:-1px;color:#999;}html,body{min-width:100px !important;'. |
| 197: | 'background-color:#fff;}body{background:linear-gradient(180deg,#faf6f5,#faf6f5,#faf6f5,#faf6f5,'. |
| 198: | '#fff);font-size:1em;color:#333;font-family:Arial;padding:0px;margin:0px;min-width:700px;'. |
| 199: | 'font-size:100%;}input,option,select{font-size:100%;padding:3px;}textarea,select,input{border:solid '. |
| 200: | '1px #ddd;background-color:#fff;color:#333;border-radius:3px;}.screen_reader{position:absolute'. |
| 201: | ';top:auto;width:1px;height:1px;overflow:hidden;}.login_form{display:flex; justify-content:space-evenly; align-items:center; flex-direction:column;font-size:90%;'. |
| 202: | 'padding-top:60px;height:360px;border-radius:20px 20px 20px 20px;margin:0px;background-color:rgba(0,0,0,.6);'. |
| 203: | 'min-width:300px;}.login_form input{clear:both;float:left;padding:4px;'. |
| 204: | 'margin-top:10px;margin-bottom:10px;}#username,#password{width:200px; height:25px;} .err{color:red !important;}.long_session'. |
| 205: | '{float:left;}.long_session input{padding:0px;float:none;font-size:18px;}.mobile .long_session{float:left;clear:both;} @media screen and (min-width:400px){.login_form{min-width:400px;}}'. |
| 206: | '.user-icon_signin{display:block; background-color:white; border-radius:100%; padding:10px; height:40px; margin-top:-120px; box-shadow: #6eb549 .4px 2.4px 6.2px; }'. |
| 207: | '.label_signin{width:210px; margin:0px 0px -18px 0px;color:#fff;opacity:0.7;} @media (max-height : 500px){ .user-icon_signin{display:none;}} |
| 208: | </style>'; |
| 209: | |
| 210: | return $css.'<div class="form-container"><form class="login_form" method="POST">'; |
| 211: | } |
| 212: | else { |
| 213: | return '<div class="form-container"><form class="logout_form" method="POST">'; |
| 214: | } |
| 215: | } |
| 216: | } |
| 217: | } |
| 218: | |
| 219: | |
| 220: | |
| 221: | |
| 222: | |
| 223: | class Hm_Output_login extends Hm_Output_Module { |
| 224: | |
| 225: | |
| 226: | |
| 227: | protected function output() { |
| 228: | $stay_logged_in = ''; |
| 229: | if ($this->get('allow_long_session')) { |
| 230: | $stay_logged_in = '<div class="form-check form-switch long-session"> |
| 231: | <input type="checkbox" id="stay_logged_in" value="1" name="stay_logged_in" class="form-check-input"> |
| 232: | <label class="form-check-label" for="stay_logged_in">'.$this->trans('Stay logged in').'</label> |
| 233: | </div>'; |
| 234: | } |
| 235: | if (!$this->get('router_login_state')) { |
| 236: | $fancy_login = $this->get('fancy_login_allowed'); |
| 237: | if(!$fancy_login){ |
| 238: | return '<div class="bg-light"><div class="d-flex align-items-center justify-content-center vh-100 p-3"> |
| 239: | <div class="card col-12 col-md-6 col-lg-4 p-3"> |
| 240: | <div class="card-body"> |
| 241: | <p class="text-center"><img class="w-50" src="'.WEB_ROOT. 'modules/core/assets/images/logo_dark.svg"></p> |
| 242: | <div class="mt-5"> |
| 243: | <div class="mb-3 form-floating"> |
| 244: | <input autofocus required type="text" placeholder="'.$this->trans('Username').'" id="username" name="username" class="form-control"> |
| 245: | <label for="username" class="form-label screen-reader">'.$this->trans('Username').'</label> |
| 246: | </div> |
| 247: | <div class="mb-3 form-floating"> |
| 248: | <input required type="password" id="password" placeholder="'.$this->trans('Password').'" name="password" class="form-control"> |
| 249: | <label for="password" class="form-label screen-reader">'.$this->trans('Password').'</label> |
| 250: | </div>'. |
| 251: | '<div class="d-grid">'.$stay_logged_in. |
| 252: | '<input type="hidden" name="hm_page_key" value="'.Hm_Request_Key::generate().'" /> |
| 253: | <input type="submit" id="login" class="btn btn-primary btn-lg" value="'.$this->trans('Login').'"> |
| 254: | </div> |
| 255: | </div> |
| 256: | </div> |
| 257: | </div> |
| 258: | </div></div>'; |
| 259: | } else { |
| 260: | return '<svg class="user-icon_signin" viewBox="0 0 20 20"><path d="M12.075,10.812c1.358-0.853,2.242-2.507,2.242-4.037c0-2.181-1.795-4.618-4.198-4.618S5.921,4.594,5.921,6.775c0,1.53,0.884,3.185,2.242,4.037c-3.222,0.865-5.6,3.807-5.6,7.298c0,0.23,0.189,0.42,0.42,0.42h14.273c0.23,0,0.42-0.189,0.42-0.42C17.676,14.619,15.297,11.677,12.075,10.812 M6.761,6.775c0-2.162,1.773-3.778,3.358-3.778s3.359,1.616,3.359,3.778c0,2.162-1.774,3.778-3.359,3.778S6.761,8.937,6.761,6.775 M3.415,17.69c0.218-3.51,3.142-6.297,6.704-6.297c3.562,0,6.486,2.787,6.705,6.297H3.415z"></path></svg>'. |
| 261: | '<img src="'.WEB_ROOT. 'modules/core/assets/images/logo.svg" style="height:90px;">'. |
| 262: | '<!--h1 class="title">'.$this->html_safe($this->get('router_app_name', '')).'</h1-->'. |
| 263: | ' <input type="hidden" name="hm_page_key" value="'.Hm_Request_Key::generate().'" />'. |
| 264: | ' <label class="label_signin" for="username">'.$this->trans('Username').'</label>'. |
| 265: | '<input autofocus required type="text" placeholder="'.$this->trans('Username').'" id="username" name="username" value="">'. |
| 266: | ' <label class="label_signin" for="password">'.$this->trans('Password').'</label>'. |
| 267: | '<input required type="password" id="password" placeholder="'.$this->trans('Password').'" name="password">'. |
| 268: | $stay_logged_in.' <input style="cursor:pointer; display:block; width:210px; background-color:#6eb549; color:white; height:40px;" type="submit" id="login" value="'.$this->trans('Login').'" />'; |
| 269: | } |
| 270: | |
| 271: | } |
| 272: | else { |
| 273: | $settings = $this->get('changed_settings', array()); |
| 274: | $single = $this->get('single_server_mode'); |
| 275: | $changed = 0; |
| 276: | if (!$single && count($settings) > 0) { |
| 277: | $changed = 1; |
| 278: | } |
| 279: | |
| 280: | return '<div class="modal fade" id="confirmLogoutModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="confirmLogoutModalLabel" aria-hidden="true"> |
| 281: | <div class="modal-dialog"> |
| 282: | <div class="modal-content"> |
| 283: | <div class="modal-header"> |
| 284: | <h5 class="modal-title" id="confirmLogoutModalLabel">'.$this->trans('Do you want to log out?').'</h5> |
| 285: | <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> |
| 286: | </div> |
| 287: | <div class="modal-body"> |
| 288: | <input type="hidden" name="hm_page_key" value="'.Hm_Request_Key::generate().'" /> |
| 289: | <p class="text-wrap">'.$this->trans('Unsaved changes will be lost! Re-enter your password to save and exit.').' <a href="?page=save">'.$this->trans('More info').'</a></p> |
| 290: | <input type="text" value="'.$this->html_safe($this->get('username', 'cypht_user')).'" autocomplete="username" style="display: none;"/> |
| 291: | <div class="my-3 form-floating"> |
| 292: | <input id="logout_password" autocomplete="current-password" name="password" class="form-control warn_on_paste" type="password" placeholder="'.$this->trans('Password').'"> |
| 293: | <label for="logout_password" class="form-label screen-reader">'.$this->trans('Password').'</label> |
| 294: | </div> |
| 295: | </div> |
| 296: | <div class="modal-footer"> |
| 297: | <input class="cancel_logout save_settings btn btn-secondary" data-bs-dismiss="modal" type="button" value="'.$this->trans('Cancel').'" /> |
| 298: | <input class="save_settings btn btn-primary" id="logout_without_saving" type="submit" name="logout" value="'.$this->trans('Just Logout').'" /> |
| 299: | <input class="save_settings btn btn-primary" type="submit" name="save_and_logout" value="'.$this->trans('Save and Logout').'" /> |
| 300: | </div> |
| 301: | </div> |
| 302: | </div> |
| 303: | </div>'; |
| 304: | } |
| 305: | } |
| 306: | } |
| 307: | |
| 308: | |
| 309: | |
| 310: | |
| 311: | |
| 312: | class Hm_Output_server_content_start extends Hm_Output_Module { |
| 313: | |
| 314: | |
| 315: | |
| 316: | protected function output() { |
| 317: | return '<div class="content_title">'.$this->trans('Servers'). |
| 318: | '</div><div class="server_content">'; |
| 319: | } |
| 320: | } |
| 321: | |
| 322: | |
| 323: | |
| 324: | |
| 325: | |
| 326: | class Hm_Output_server_content_end extends Hm_Output_Module { |
| 327: | |
| 328: | |
| 329: | |
| 330: | protected function output() { |
| 331: | return '</div>'; |
| 332: | } |
| 333: | } |
| 334: | |
| 335: | |
| 336: | |
| 337: | |
| 338: | |
| 339: | class Hm_Output_date extends Hm_Output_Module { |
| 340: | |
| 341: | |
| 342: | |
| 343: | protected function output() { |
| 344: | return '<div class="date">'.$this->html_safe($this->get('date')).'</div>'; |
| 345: | } |
| 346: | } |
| 347: | |
| 348: | |
| 349: | |
| 350: | |
| 351: | |
| 352: | class Hm_Output_msgs extends Hm_Output_Module { |
| 353: | |
| 354: | |
| 355: | |
| 356: | protected function output() { |
| 357: | $res = ''; |
| 358: | $msgs = Hm_Msgs::getRaw(); |
| 359: | $logged_out_class = ''; |
| 360: | if (!$this->get('router_login_state') && !empty($msgs)) { |
| 361: | $logged_out_class = ' logged_out'; |
| 362: | } |
| 363: | $res .= '<div class="position-fixed top-0 col-sm-4 col-md-3 end-0 mt-3 me-3 sys_messages'.$logged_out_class.'"></div>'; |
| 364: | $res .= '<script type="text/javascript">var hm_msgs = '.json_encode($msgs).'</script>'; |
| 365: | return $res; |
| 366: | } |
| 367: | } |
| 368: | |
| 369: | |
| 370: | |
| 371: | |
| 372: | |
| 373: | class Hm_Output_header_start extends Hm_Output_Module { |
| 374: | |
| 375: | |
| 376: | |
| 377: | protected function output() { |
| 378: | $lang = 'en'; |
| 379: | $dir = 'ltr'; |
| 380: | if ($this->lang) { |
| 381: | $lang = mb_strtolower(str_replace('_', '-', $this->lang)); |
| 382: | } |
| 383: | if ($this->dir) { |
| 384: | $dir = $this->dir; |
| 385: | } |
| 386: | $class = $dir."_page"; |
| 387: | $res = '<!DOCTYPE html><html dir="'.$this->html_safe($dir).'" class="'. |
| 388: | $this->html_safe($class).'" lang='.$this->html_safe($lang).'><head>'. |
| 389: | '<meta name="apple-mobile-web-app-capable" content="yes" />'. |
| 390: | '<meta name="mobile-web-app-capable" content="yes" />'. |
| 391: | '<meta name="apple-mobile-web-app-status-bar-style" content="black" />'. |
| 392: | '<meta name="theme-color" content="#888888" /><meta charset="utf-8" />'; |
| 393: | |
| 394: | if ($this->get('router_login_state')) { |
| 395: | $res .= '<meta name="referrer" content="no-referrer" />'; |
| 396: | } |
| 397: | return $res; |
| 398: | } |
| 399: | } |
| 400: | |
| 401: | |
| 402: | |
| 403: | |
| 404: | |
| 405: | class Hm_Output_header_end extends Hm_Output_Module { |
| 406: | |
| 407: | |
| 408: | |
| 409: | protected function output() { |
| 410: | return '</head>'; |
| 411: | } |
| 412: | } |
| 413: | |
| 414: | |
| 415: | |
| 416: | |
| 417: | |
| 418: | class Hm_Output_content_start extends Hm_Output_Module { |
| 419: | |
| 420: | |
| 421: | |
| 422: | |
| 423: | protected function output() { |
| 424: | $res = '<body class="'.($this->get('is_mobile', false) ? 'mobile' : '').'"><noscript class="noscript">'. |
| 425: | sprintf($this->trans('You need to have Javascript enabled to use %s, sorry about that!'), |
| 426: | $this->html_safe($this->get('router_app_name'))).'</noscript>'; |
| 427: | $res .= '<script type="text/javascript">window.inAppContext = true;</script>'; |
| 428: | if (!$this->get('router_login_state')) { |
| 429: | $res .= '<script type="text/javascript">sessionStorage.clear();</script>'; |
| 430: | } |
| 431: | else { |
| 432: | $res .= '<input type="hidden" id="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'; |
| 433: | } |
| 434: | if (!$this->get('single_server_mode') && count($this->get('changed_settings', array())) > 0) { |
| 435: | $res .= '<a class="unsaved_icon" href="?page=save" title="'.$this->trans('Unsaved Changes'). |
| 436: | '"><i class="bi bi-save2-fill fs-5 unsaved_reminder"></i></a>'; |
| 437: | } |
| 438: | $res .= '<div class="cypht-layout">'; |
| 439: | return $res; |
| 440: | } |
| 441: | } |
| 442: | |
| 443: | |
| 444: | |
| 445: | |
| 446: | |
| 447: | class Hm_Output_header_content extends Hm_Output_Module { |
| 448: | |
| 449: | |
| 450: | |
| 451: | protected function output() { |
| 452: | $title = ''; |
| 453: | if (!$this->get('router_login_state')) { |
| 454: | $title = $this->get('router_app_name'); |
| 455: | } |
| 456: | elseif ($this->exists('page_title')) { |
| 457: | $title .= $this->get('page_title'); |
| 458: | } |
| 459: | elseif ($this->exists('mailbox_list_title')) { |
| 460: | $title .= ' '.implode('-', $this->get('mailbox_list_title', array())); |
| 461: | } |
| 462: | if (!trim((string) $title) && $this->exists('router_page_name')) { |
| 463: | $title = ''; |
| 464: | if ($this->get('list_path') == 'message_list') { |
| 465: | $title .= ' '.ucwords(str_replace('_', ' ', $this->get('list_path'))); |
| 466: | } |
| 467: | elseif ($this->get('router_page_name') == 'notfound') { |
| 468: | $title .= ' Nope'; |
| 469: | } |
| 470: | else { |
| 471: | $title .= ' '.ucwords(str_replace('_', ' ', $this->get('router_page_name'))); |
| 472: | } |
| 473: | } |
| 474: | return '<title>'.$this->trans(trim((string) $title)).'</title>'. |
| 475: | '<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">'. |
| 476: | '<link rel="icon" class="tab_icon" type="image/png" href="data:image/png;base64,iVBORw0KGgo'. |
| 477: | 'AAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAFVJR'. |
| 478: | 'EFUOI3NkkEKACEMA2d92fpzfVn3oHhYqAF7qIFeSpImUMjGA1jEoEQTFKAC/UDbp3bhBRqj0m7a5C78F56Rx5MEdUB'. |
| 479: | 'HFMlkV09ogN3xB7kG+fgA0tc160Jy09wAAAAASUVORK5CYII=" >'. |
| 480: | '<base href="'.$this->html_safe($this->get('router_url_path')).'" />'; |
| 481: | } |
| 482: | } |
| 483: | |
| 484: | |
| 485: | |
| 486: | |
| 487: | |
| 488: | class Hm_Output_header_css extends Hm_Output_Module { |
| 489: | |
| 490: | |
| 491: | |
| 492: | protected function output() { |
| 493: | $res = ''; |
| 494: | $mods = $this->get('router_module_list'); |
| 495: | if (! $this->get('theme')) { |
| 496: | $res .= '<link href="' . WEB_ROOT . 'modules/themes/assets/default/css/default.css?v=' . CACHE_ID . '" media="all" rel="stylesheet" type="text/css" />'; |
| 497: | } |
| 498: | if (DEBUG_MODE) { |
| 499: | $res .= '<link href="'.WEB_ROOT.'vendor/twbs/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet" type="text/css" />'; |
| 500: | foreach (glob(APP_PATH.'modules'.DIRECTORY_SEPARATOR.'**', GLOB_ONLYDIR | GLOB_MARK) as $name) { |
| 501: | $rel_name = str_replace(APP_PATH, '', $name); |
| 502: | $mod = str_replace(array('modules', DIRECTORY_SEPARATOR), '', $rel_name); |
| 503: | if (in_array($mod, $mods, true) && is_readable(sprintf("%ssite.css", $name))) { |
| 504: | $res .= '<link href="'.WEB_ROOT.sprintf("%ssite.css", $rel_name).'" media="all" rel="stylesheet" type="text/css" />'; |
| 505: | } |
| 506: | } |
| 507: | |
| 508: | if(count(array_intersect(['contacts','local_contacts','ldap_contacts','gmail_contacts'], $mods)) > 0){ |
| 509: | $res .= '<link href="'.WEB_ROOT.'third_party/contact-group.css" media="all" rel="stylesheet" type="text/css" />'; |
| 510: | } |
| 511: | $res .= '<link href="'.WEB_ROOT.'third_party/nprogress.css" media="all" rel="stylesheet" type="text/css" />'; |
| 512: | } |
| 513: | else { |
| 514: | $res .= '<link href="'.WEB_ROOT.'site.css?v='.CACHE_ID.'" '; |
| 515: | if (defined('CSS_HASH') && CSS_HASH) { |
| 516: | $res .= 'integrity="'.CSS_HASH.'" '; |
| 517: | } |
| 518: | $res .= 'media="all" rel="stylesheet" type="text/css" />'; |
| 519: | } |
| 520: | $res .= '<style type="text/css">@font-face {font-family:"Behdad";'. |
| 521: | 'src:url("'.WEB_ROOT.'modules/core/assets/fonts/Behdad/Behdad-Regular.woff2") format("woff2"),'. |
| 522: | 'url("'.WEB_ROOT.'modules/core/assets/fonts/Behdad/Behdad-Regular.woff") format("woff");</style>'; |
| 523: | return $res; |
| 524: | } |
| 525: | } |
| 526: | |
| 527: | |
| 528: | |
| 529: | |
| 530: | |
| 531: | class Hm_Output_page_js extends Hm_Output_Module { |
| 532: | |
| 533: | |
| 534: | |
| 535: | |
| 536: | protected function output() { |
| 537: | if (DEBUG_MODE) { |
| 538: | $res = ''; |
| 539: | $js_exclude_dependencies = explode(',', $this->get('router_js_exclude_deps', '')); |
| 540: | $js_lib = get_js_libs($js_exclude_dependencies); |
| 541: | if ($this->get('encrypt_ajax_requests', '') || $this->get('encrypt_local_storage', '')) { |
| 542: | $js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.'third_party/forge.min.js"></script>'; |
| 543: | } |
| 544: | $core = false; |
| 545: | $mods = $this->get('router_module_list'); |
| 546: | foreach (glob(APP_PATH.'modules'.DIRECTORY_SEPARATOR.'**', GLOB_ONLYDIR | GLOB_MARK) as $name) { |
| 547: | $rel_name = str_replace(APP_PATH, '', $name); |
| 548: | $mod = str_replace(array('modules', DIRECTORY_SEPARATOR), '', $rel_name); |
| 549: | if (in_array($mod, $mods, true)) { |
| 550: | $directoriesPattern = str_replace('/', DIRECTORY_SEPARATOR, "{*,*/*}"); |
| 551: | foreach (glob($name.'js_modules' . DIRECTORY_SEPARATOR . $directoriesPattern . "*.js", GLOB_BRACE) as $js) { |
| 552: | if (preg_match('/\[(.+)\]/', $js, $matches)) { |
| 553: | $dep = $matches[1]; |
| 554: | if (in_array($dep, $js_exclude_dependencies)) { |
| 555: | continue; |
| 556: | } |
| 557: | } |
| 558: | $res .= '<script type="text/javascript" src="'.WEB_ROOT.str_replace(APP_PATH, '', $js).'"></script>'; |
| 559: | } |
| 560: | |
| 561: | if ($rel_name == 'modules'.DIRECTORY_SEPARATOR.'core'.DIRECTORY_SEPARATOR) { |
| 562: | $core = $rel_name; |
| 563: | continue; |
| 564: | } |
| 565: | |
| 566: | if (is_readable(sprintf("%ssite.js", $name))) { |
| 567: | $res .= '<script type="text/javascript" src="'.WEB_ROOT.sprintf("%ssite.js", $rel_name).'"></script>'; |
| 568: | } |
| 569: | } |
| 570: | } |
| 571: | if ($core) { |
| 572: | $res = |
| 573: | '<script type="text/javascript" src="' . WEB_ROOT . 'modules/core/navigation/utils.js"></script>'. |
| 574: | '<script type="text/javascript" src="'.WEB_ROOT.sprintf("%ssite.js", $core).'"></script>'. |
| 575: | $res; |
| 576: | |
| 577: | |
| 578: | |
| 579: | |
| 580: | |
| 581: | foreach (['routes', 'navigation', 'navbar'] as $js) { |
| 582: | $res .= '<script type="text/javascript" src="'.WEB_ROOT.sprintf("%snavigation/%s.js", $core, $js).'"></script>'; |
| 583: | } |
| 584: | } |
| 585: | return $js_lib.$res; |
| 586: | } |
| 587: | else { |
| 588: | $res = '<script type="text/javascript" '; |
| 589: | if (defined('JS_HASH') && JS_HASH) { |
| 590: | $res .= 'integrity="'.JS_HASH.'" '; |
| 591: | } |
| 592: | $res .= 'src="'.WEB_ROOT.'site.js?v='.CACHE_ID.'" async></script>'; |
| 593: | return $res; |
| 594: | } |
| 595: | } |
| 596: | } |
| 597: | |
| 598: | |
| 599: | |
| 600: | |
| 601: | |
| 602: | class Hm_Output_content_end extends Hm_Output_Module { |
| 603: | |
| 604: | |
| 605: | |
| 606: | protected function output() { |
| 607: | return '</div></body></html>'; |
| 608: | } |
| 609: | } |
| 610: | |
| 611: | |
| 612: | |
| 613: | |
| 614: | |
| 615: | class Hm_Output_js_data extends Hm_Output_Module { |
| 616: | |
| 617: | |
| 618: | |
| 619: | protected function output() { |
| 620: | $settings = $this->get('user_settings', array()); |
| 621: | $enable_snooze = $settings['enable_snooze'] ?? DEFAULT_ENABLE_SNOOZE; |
| 622: | $enable_collect_address_on_send = $settings['enable_collect_address_on_send_setting'] ?? DEFAULT_ENABLE_COLLECT_ADDRESS_ON_SEND; |
| 623: | $res = '<script type="text/javascript" id="data-store">'. |
| 624: | 'var globals = {};'. |
| 625: | 'var hm_is_logged = function () { return '.($this->get('is_logged') ? '1' : '0').'; };'. |
| 626: | 'var hm_empty_folder = function() { return "'.$this->trans('So alone').'"; };'. |
| 627: | 'var hm_mobile = function() { return '.($this->get('is_mobile') ? '1' : '0').'; };'. |
| 628: | 'var hm_debug = function() { return "' . ((DEBUG_MODE || DEFAULT_DEBUG_LOG) ? '1' : '0') . '"; };'. |
| 629: | 'var hm_mailto = function() { return '.($this->get('mailto_handler') ? '1' : '0').'; };'. |
| 630: | 'var hm_page_name = function() { return "'.$this->html_safe($this->get('router_page_name')).'"; };'. |
| 631: | 'var hm_language_direction = function() { return "'.$this->html_safe($this->dir).'"; };'. |
| 632: | 'var hm_list_path = function() { return "'.$this->html_safe($this->get('list_path', '')).'"; };'. |
| 633: | 'var hm_list_parent = function() { return "'.$this->html_safe($this->get('list_parent', '')).'"; };'. |
| 634: | 'var hm_msg_uid = function() { return Hm_Utils.get_from_global("msg_uid", "'.$this->html_safe($this->get('uid', '')).'"); };'. |
| 635: | 'var hm_encrypt_ajax_requests = function() { return "'.$this->html_safe($this->get('encrypt_ajax_requests', '')).'"; };'. |
| 636: | 'var hm_encrypt_local_storage = function() { return "'.$this->html_safe($this->get('encrypt_local_storage', '')).'"; };'. |
| 637: | 'var hm_web_root_path = function() { return "'.WEB_ROOT.'"; };'. |
| 638: | 'var hm_flag_image_src = function() { return "<i class=\"bi bi-star-half\"></i>"; };'. |
| 639: | 'var hm_check_dirty_flag = function() { return '.($this->get('warn_for_unsaved_changes', '') ? '1' : '0').'; };'. |
| 640: | format_data_sources($this->get('data_sources', array()), $this); |
| 641: | |
| 642: | if (!$this->get('disable_delete_prompt', DEFAULT_DISABLE_DELETE_PROMPT)) { |
| 643: | $res .= 'var hm_delete_prompt = function() { return confirm("'.$this->trans('This action cannot be undone. Are you sure you want to delete this?').'"); };'; |
| 644: | } |
| 645: | else { |
| 646: | $res .= 'var hm_delete_prompt = function() { return true; };'; |
| 647: | } |
| 648: | $res .= 'window.hm_current_lang = "'.$this->lang.'";'. |
| 649: | 'window.hm_translations = '.json_encode($this->all_trans()).';'. |
| 650: | 'var hm_trans = function(key, lang = window.hm_current_lang) {'. |
| 651: | ' const langTranslations = window.hm_translations && window.hm_translations[lang];'. |
| 652: | ' if (langTranslations && langTranslations[key] !== undefined && langTranslations[key] !== false) {'. |
| 653: | ' return langTranslations[key];'. |
| 654: | ' }'. |
| 655: | ' return key;'. |
| 656: | '};'; |
| 657: | $res .= 'window.hm_default_timezone = "'.$this->get('default_timezone','UTC').'";'; |
| 658: | $res .= 'window.hm_default_setting_enable_snooze = ' . ($enable_snooze ? 'true' : 'false') . ';' . PHP_EOL; |
| 659: | $res .= 'window.hm_enable_collect_address_on_send = ' . ($enable_collect_address_on_send ? 'true' : 'false') . ';' . PHP_EOL; |
| 660: | $res .= 'var hm_module_is_supported = function(module) {'. |
| 661: | ' return '.json_encode($this->get('enabled_modules', array())).'.indexOf(module) !== -1;'. |
| 662: | '};'; |
| 663: | $res .= '</script>'; |
| 664: | return $res; |
| 665: | } |
| 666: | } |
| 667: | |
| 668: | |
| 669: | |
| 670: | |
| 671: | |
| 672: | |
| 673: | class Hm_Output_start_settings_form extends Hm_Output_Module { |
| 674: | |
| 675: | |
| 676: | |
| 677: | protected function output() { |
| 678: | return '<div class="user_settings px-0"><div class="content_title px-3">'.$this->trans('Site Settings').'</div>'. |
| 679: | '<form method="POST"><input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'. |
| 680: | '<div class="px-3"><table class="settings_table table table-borderless"><colgroup>'. |
| 681: | '<col class="label_col"><col class="setting_col"></colgroup>'; |
| 682: | } |
| 683: | } |
| 684: | |
| 685: | |
| 686: | |
| 687: | |
| 688: | |
| 689: | class Hm_Output_start_page_setting extends Hm_Output_Module { |
| 690: | |
| 691: | |
| 692: | |
| 693: | protected function output() { |
| 694: | $options = start_page_opts(); |
| 695: | $settings = $this->get('user_settings', array()); |
| 696: | $res = ''; |
| 697: | $reset = ''; |
| 698: | |
| 699: | if (array_key_exists('start_page', $settings)) { |
| 700: | $start_page = $settings['start_page']; |
| 701: | } |
| 702: | else { |
| 703: | $start_page = DEFAULT_START_PAGE; |
| 704: | } |
| 705: | $res = '<tr class="general_setting"><td><label for="start_page">'. |
| 706: | $this->trans('First page after login').'</label></td>'. |
| 707: | '<td><select class="form-select form-select-sm w-auto" id="start_page" name="start_page">'; |
| 708: | foreach ($options as $label => $val) { |
| 709: | $res .= '<option '; |
| 710: | if ($start_page == $val) { |
| 711: | $res .= 'selected="selected" '; |
| 712: | if ($start_page != DEFAULT_START_PAGE) { |
| 713: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_select"></i></span>'; |
| 714: | } |
| 715: | } |
| 716: | $res .= 'value="'.$val.'">'.$this->trans($label).'</option>'; |
| 717: | } |
| 718: | $res .= '</select>'.$reset.'</td></tr>'; |
| 719: | return $res; |
| 720: | } |
| 721: | } |
| 722: | |
| 723: | |
| 724: | |
| 725: | |
| 726: | |
| 727: | class Hm_Output_default_sort_order_setting extends Hm_Output_Module { |
| 728: | |
| 729: | |
| 730: | |
| 731: | protected function output() { |
| 732: | $options = default_sort_order_opts(); |
| 733: | $settings = $this->get('user_settings', array()); |
| 734: | $reset = ''; |
| 735: | |
| 736: | if (array_key_exists('default_sort_order', $settings)) { |
| 737: | $default_sort_order = $settings['default_sort_order']; |
| 738: | } |
| 739: | else { |
| 740: | $default_sort_order = null; |
| 741: | } |
| 742: | $res = '<tr class="general_setting"><td><label for="default_sort_order">'. |
| 743: | $this->trans('Default message sort order').'</label></td>'. |
| 744: | '<td><select class="form-select form-select-sm w-auto" id="default_sort_order" name="default_sort_order">'; |
| 745: | foreach ($options as $val => $label) { |
| 746: | $res .= '<option '; |
| 747: | if ($default_sort_order == $val) { |
| 748: | $res .= 'selected="selected" '; |
| 749: | if ($default_sort_order != 'arrival') { |
| 750: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_select"></i></span>'; |
| 751: | } |
| 752: | } |
| 753: | $res .= 'value="'.$val.'">'.$this->trans($label).'</option>'; |
| 754: | } |
| 755: | $res .= '</select>'.$reset.'</td></tr>'; |
| 756: | return $res; |
| 757: | } |
| 758: | } |
| 759: | |
| 760: | |
| 761: | |
| 762: | |
| 763: | |
| 764: | class Hm_Output_list_style_setting extends Hm_Output_Module { |
| 765: | |
| 766: | |
| 767: | |
| 768: | protected function output() { |
| 769: | $options = array('email_style' => 'Email', 'news_style' => 'News'); |
| 770: | $settings = $this->get('user_settings', array()); |
| 771: | $reset = ''; |
| 772: | |
| 773: | if (array_key_exists('list_style', $settings)) { |
| 774: | $list_style = $settings['list_style']; |
| 775: | } |
| 776: | else { |
| 777: | $list_style = DEFAULT_LIST_STYLE; |
| 778: | } |
| 779: | $res = '<tr class="general_setting"><td><label for="list_style">'. |
| 780: | $this->trans('Message list style').'</label></td>'. |
| 781: | '<td><select class="form-select form-select-sm w-auto" id="list_style" name="list_style" data-default-value="'.DEFAULT_LIST_STYLE.'">'; |
| 782: | foreach ($options as $val => $label) { |
| 783: | $res .= '<option '; |
| 784: | if ($list_style == $val) { |
| 785: | $res .= 'selected="selected" '; |
| 786: | if ($list_style != DEFAULT_LIST_STYLE) { |
| 787: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_select"></i></span>'; |
| 788: | } |
| 789: | } |
| 790: | $res .= 'value="'.$val.'">'.$this->trans($label).'</option>'; |
| 791: | } |
| 792: | $res .= '</select>'.$reset.'</td></tr>'; |
| 793: | return $res; |
| 794: | } |
| 795: | } |
| 796: | |
| 797: | |
| 798: | |
| 799: | |
| 800: | class Hm_Output_mailto_handler_setting extends Hm_Output_Module { |
| 801: | protected function output() { |
| 802: | $settings = $this->get('user_settings'); |
| 803: | if (array_key_exists('mailto_handler', $settings) && $settings['mailto_handler']) { |
| 804: | $checked = ' checked="checked"'; |
| 805: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_checkbox"></i></span>'; |
| 806: | } |
| 807: | else { |
| 808: | $checked = ''; |
| 809: | $reset = ''; |
| 810: | } |
| 811: | return '<tr class="general_setting"><td><label class="form-check-label" for="mailto_handler">'.$this->trans('Allow handling of mailto links').'</label></td>'. |
| 812: | '<td><input class="form-check-input" type="checkbox" '.$checked.' value="1" id="mailto_handler" name="mailto_handler" data-default-value="false" />'.$reset.'</td></tr>'; |
| 813: | } |
| 814: | } |
| 815: | |
| 816: | |
| 817: | |
| 818: | |
| 819: | class Hm_Output_no_folder_icon_setting extends Hm_Output_Module { |
| 820: | protected function output() { |
| 821: | $settings = $this->get('user_settings'); |
| 822: | if (array_key_exists('no_folder_icons', $settings) && $settings['no_folder_icons']) { |
| 823: | $checked = ' checked="checked"'; |
| 824: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_checkbox"></i></span>'; |
| 825: | } |
| 826: | else { |
| 827: | $checked = ''; |
| 828: | $reset = ''; |
| 829: | } |
| 830: | return '<tr class="general_setting"><td><label class="form-check-label" for="no_folder_icons">'.$this->trans('Hide folder list icons').'</label></td>'. |
| 831: | '<td><input class="form-check-input" type="checkbox" '.$checked.' value="1" id="no_folder_icons" name="no_folder_icons" data-default-value="false" />'.$reset.'</td></tr>'; |
| 832: | } |
| 833: | } |
| 834: | |
| 835: | |
| 836: | |
| 837: | |
| 838: | class Hm_Output_no_password_setting extends Hm_Output_Module { |
| 839: | protected function output() { |
| 840: | $settings = $this->get('user_settings'); |
| 841: | $reset = ''; |
| 842: | if (array_key_exists('no_password_save', $settings) && $settings['no_password_save']) { |
| 843: | $checked = ' checked="checked"'; |
| 844: | } |
| 845: | else { |
| 846: | $checked = ''; |
| 847: | } |
| 848: | if(isset($settings['no_password_save']) && $settings['no_password_save'] !== DEFAULT_NO_PASSWORD_SAVE) { |
| 849: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_checkbox"></i></span>'; |
| 850: | } |
| 851: | return '<tr class="general_setting"><td><label class="form-check-label" for="no_password_save">'.$this->trans('Don\'t save account passwords between logins').'</label></td>'. |
| 852: | '<td><input class="form-check-input" type="checkbox" '.$checked.' value="1" id="no_password_save" name="no_password_save" data-default-value="'.(DEFAULT_NO_PASSWORD_SAVE ? 'true' : 'false') . '" />'.$reset.'</td></tr>'; |
| 853: | } |
| 854: | } |
| 855: | |
| 856: | |
| 857: | |
| 858: | |
| 859: | class Hm_Output_delete_prompt_setting extends Hm_Output_Module { |
| 860: | protected function output() { |
| 861: | $settings = $this->get('user_settings'); |
| 862: | $reset = ''; |
| 863: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_checkbox"></i></span>'; |
| 864: | if (array_key_exists('disable_delete_prompt', $settings) && $settings['disable_delete_prompt']) { |
| 865: | $checked = ' checked="checked"'; |
| 866: | } |
| 867: | else { |
| 868: | $checked = ''; |
| 869: | } |
| 870: | if(isset($settings['disable_delete_prompt']) && $settings['disable_delete_prompt'] !== DEFAULT_DISABLE_DELETE_PROMPT) { |
| 871: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_checkbox"></i></span>'; |
| 872: | } |
| 873: | return '<tr class="general_setting"><td><label class="form-check-label" for="disable_delete_prompt">'.$this->trans('Disable prompts when deleting').'</label></td>'. |
| 874: | '<td><input class="form-check-input" type="checkbox" '.$checked.' value="1" id="disable_delete_prompt" name="disable_delete_prompt" data-default-value="'.(DEFAULT_DISABLE_DELETE_PROMPT ? 'true' : 'false') . '" />'.$reset.'</td></tr>'; |
| 875: | } |
| 876: | } |
| 877: | |
| 878: | |
| 879: | |
| 880: | |
| 881: | class Hm_Output_delete_attachment_setting extends Hm_Output_Module { |
| 882: | protected function output() { |
| 883: | $checked = ''; |
| 884: | $reset = ''; |
| 885: | $settings = $this->get('user_settings'); |
| 886: | if (array_key_exists('allow_delete_attachment', $settings) && $settings['allow_delete_attachment']) { |
| 887: | $checked = ' checked="checked"'; |
| 888: | } |
| 889: | else { |
| 890: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_checkbox"></i></span>'; |
| 891: | } |
| 892: | return '<tr class="general_setting"><td><label class="form-check-label" for="allow_delete_attachment">'.$this->trans('Allow delete attachment').'</label></td>'. |
| 893: | '<td><input class="form-check-input" type="checkbox" '.$checked.' value="1" id="allow_delete_attachment" name="allow_delete_attachment" data-default-value="false" />'.$reset.'</td></tr>'; |
| 894: | } |
| 895: | } |
| 896: | |
| 897: | |
| 898: | |
| 899: | |
| 900: | |
| 901: | class Hm_Output_start_flagged_settings extends Hm_Output_Module { |
| 902: | |
| 903: | |
| 904: | |
| 905: | protected function output() { |
| 906: | return '<tr><td data-target=".flagged_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 907: | '<i class="bi bi-flag-fill fs-5 me-2"></i>'. |
| 908: | $this->trans('Flagged').'</td></tr>'; |
| 909: | } |
| 910: | } |
| 911: | |
| 912: | |
| 913: | |
| 914: | |
| 915: | |
| 916: | class Hm_Output_start_everything_settings extends Hm_Output_Module { |
| 917: | |
| 918: | |
| 919: | |
| 920: | protected function output() { |
| 921: | if ($this->get('single_server_mode')) { |
| 922: | return ''; |
| 923: | } |
| 924: | return '<tr><td data-target=".all_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 925: | '<i class="bi bi-box2-fill fs-5 me-2"></i>'. |
| 926: | $this->trans('Everything').'</td></tr>'; |
| 927: | } |
| 928: | } |
| 929: | |
| 930: | |
| 931: | |
| 932: | |
| 933: | |
| 934: | class Hm_Output_start_unread_settings extends Hm_Output_Module { |
| 935: | |
| 936: | |
| 937: | |
| 938: | protected function output() { |
| 939: | return '<tr><td data-target=".unread_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 940: | '<i class="bi bi-envelope-fill fs-5 me-2"></i>'. |
| 941: | $this->trans('Unread').'</td></tr>'; |
| 942: | } |
| 943: | } |
| 944: | |
| 945: | |
| 946: | |
| 947: | |
| 948: | |
| 949: | class Hm_Output_start_all_email_settings extends Hm_Output_Module { |
| 950: | |
| 951: | |
| 952: | |
| 953: | |
| 954: | protected function output() { |
| 955: | if (!email_is_active($this->get('router_module_list'))) { |
| 956: | return ''; |
| 957: | } |
| 958: | if ($this->get('single_server_mode')) { |
| 959: | return ''; |
| 960: | } |
| 961: | return '<tr><td data-target=".email_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 962: | '<i class="bi bi-envelope-fill fs-5 me-2"></i>'. |
| 963: | $this->trans('All Email').'</td></tr>'; |
| 964: | } |
| 965: | } |
| 966: | |
| 967: | |
| 968: | |
| 969: | |
| 970: | |
| 971: | class Hm_Output_start_search_settings extends Hm_Output_Module { |
| 972: | |
| 973: | |
| 974: | |
| 975: | protected function output() { |
| 976: | return '<tr><td colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2 py-4">'. |
| 977: | '<form><input type="search" id="settingsSearch" class="form-control" placeholder="'.$this->trans('Type a setting').'">'. |
| 978: | '<div id="noSettingsFound" class="d-none mt-3">'.$this->trans('No settings found!').'</div>'. |
| 979: | '</td></tr>'; |
| 980: | } |
| 981: | } |
| 982: | |
| 983: | |
| 984: | |
| 985: | |
| 986: | |
| 987: | class Hm_Output_start_general_settings extends Hm_Output_Module { |
| 988: | |
| 989: | |
| 990: | |
| 991: | protected function output() { |
| 992: | return '<tr><td data-target=".general_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 993: | '<i class="bi bi-gear-wide-connected fs-5 me-2"></i>'. |
| 994: | $this->trans('General').'</td></tr>'; |
| 995: | } |
| 996: | } |
| 997: | |
| 998: | |
| 999: | |
| 1000: | |
| 1001: | |
| 1002: | class Hm_Output_unread_source_max_setting extends Hm_Output_Module { |
| 1003: | |
| 1004: | |
| 1005: | |
| 1006: | protected function output() { |
| 1007: | $sources = DEFAULT_UNREAD_PER_SOURCE; |
| 1008: | $settings = $this->get('user_settings', array()); |
| 1009: | $reset = ''; |
| 1010: | if (array_key_exists('unread_per_source', $settings)) { |
| 1011: | $sources = $settings['unread_per_source']; |
| 1012: | } |
| 1013: | if ($sources != DEFAULT_UNREAD_PER_SOURCE) { |
| 1014: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_input"></i></span>'; |
| 1015: | } |
| 1016: | return '<tr class="unread_setting"><td><label for="unread_per_source">'. |
| 1017: | $this->trans('Max messages per source').'</label></td>'. |
| 1018: | '<td class="d-flex"><input class="form-control form-control-sm w-auto" type="text" size="2" id="unread_per_source" name="unread_per_source" value="'.$this->html_safe($sources).'" data-default-value="'.DEFAULT_UNREAD_PER_SOURCE.'" />'.$reset.'</td></tr>'; |
| 1019: | } |
| 1020: | } |
| 1021: | |
| 1022: | |
| 1023: | |
| 1024: | |
| 1025: | |
| 1026: | class Hm_Output_unread_since_setting extends Hm_Output_Module { |
| 1027: | |
| 1028: | |
| 1029: | |
| 1030: | protected function output() { |
| 1031: | $settings = $this->get('user_settings', array()); |
| 1032: | $since = DEFAULT_UNREAD_SINCE; |
| 1033: | if (array_key_exists('unread_since', $settings) && $settings['unread_since']) { |
| 1034: | $since = $settings['unread_since']; |
| 1035: | } |
| 1036: | return '<tr class="unread_setting"><td><label for="unread_since">'. |
| 1037: | $this->trans('Show messages received since').'</label></td>'. |
| 1038: | '<td>'.message_since_dropdown($since, 'unread_since', $this,DEFAULT_UNREAD_SINCE).'</td></tr>'; |
| 1039: | } |
| 1040: | } |
| 1041: | |
| 1042: | |
| 1043: | |
| 1044: | |
| 1045: | |
| 1046: | class Hm_Output_flagged_source_max_setting extends Hm_Output_Module { |
| 1047: | |
| 1048: | |
| 1049: | |
| 1050: | protected function output() { |
| 1051: | $sources = DEFAULT_FLAGGED_PER_SOURCE; |
| 1052: | $settings = $this->get('user_settings', array()); |
| 1053: | $reset = ''; |
| 1054: | if (array_key_exists('flagged_per_source', $settings)) { |
| 1055: | $sources = $settings['flagged_per_source']; |
| 1056: | } |
| 1057: | if ($sources != DEFAULT_FLAGGED_PER_SOURCE) { |
| 1058: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_input"></i></span>'; |
| 1059: | } |
| 1060: | return '<tr class="flagged_setting"><td><label for="flagged_per_source">'. |
| 1061: | $this->trans('Max messages per source').'</label></td>'. |
| 1062: | '<td class="d-flex"><input class="form-control form-control-sm w-auto" type="text" size="2" id="flagged_per_source" name="flagged_per_source" value="'.$this->html_safe($sources).'" data-default-value="'.DEFAULT_FLAGGED_PER_SOURCE.'" />'.$reset.'</td></tr>'; |
| 1063: | } |
| 1064: | } |
| 1065: | |
| 1066: | |
| 1067: | |
| 1068: | |
| 1069: | |
| 1070: | class Hm_Output_flagged_since_setting extends Hm_Output_Module { |
| 1071: | protected function output() { |
| 1072: | |
| 1073: | |
| 1074: | |
| 1075: | $since = DEFAULT_FLAGGED_SINCE; |
| 1076: | $settings = $this->get('user_settings', array()); |
| 1077: | if (array_key_exists('flagged_since', $settings) && $settings['flagged_since']) { |
| 1078: | $since = $settings['flagged_since']; |
| 1079: | } |
| 1080: | return '<tr class="flagged_setting"><td><label for="flagged_since">'. |
| 1081: | $this->trans('Show messages received since').'</label></td>'. |
| 1082: | '<td>'.message_since_dropdown($since, 'flagged_since', $this, DEFAULT_FLAGGED_SINCE).'</td></tr>'; |
| 1083: | } |
| 1084: | } |
| 1085: | |
| 1086: | |
| 1087: | |
| 1088: | |
| 1089: | |
| 1090: | class Hm_Output_all_email_source_max_setting extends Hm_Output_Module { |
| 1091: | |
| 1092: | |
| 1093: | |
| 1094: | protected function output() { |
| 1095: | if (!email_is_active($this->get('router_module_list'))) { |
| 1096: | return ''; |
| 1097: | } |
| 1098: | $sources = DEFAULT_ALL_EMAIL_PER_SOURCE; |
| 1099: | $settings = $this->get('user_settings', array()); |
| 1100: | $reset = ''; |
| 1101: | if (array_key_exists('all_email_per_source', $settings)) { |
| 1102: | $sources = $settings['all_email_per_source']; |
| 1103: | } |
| 1104: | if ($sources != DEFAULT_ALL_EMAIL_PER_SOURCE) { |
| 1105: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_input"></i></span>'; |
| 1106: | } |
| 1107: | return '<tr class="email_setting"><td><label for="all_email_per_source">'. |
| 1108: | $this->trans('Max messages per source').'</label></td>'. |
| 1109: | '<td class="d-flex"><input class="form-control form-control-sm w-auto" type="text" size="2" id="all_email_per_source" name="all_email_per_source" value="'.$this->html_safe($sources).'" data-default-value="'.DEFAULT_ALL_EMAIL_PER_SOURCE.'" />'.$reset.'</td></tr>'; |
| 1110: | } |
| 1111: | } |
| 1112: | |
| 1113: | |
| 1114: | |
| 1115: | |
| 1116: | |
| 1117: | class Hm_Output_all_source_max_setting extends Hm_Output_Module { |
| 1118: | |
| 1119: | |
| 1120: | |
| 1121: | protected function output() { |
| 1122: | $sources = DEFAULT_ALL_PER_SOURCE; |
| 1123: | $settings = $this->get('user_settings', array()); |
| 1124: | $reset = ''; |
| 1125: | if (array_key_exists('all_per_source', $settings)) { |
| 1126: | $sources = $settings['all_per_source']; |
| 1127: | } |
| 1128: | if ($sources != DEFAULT_ALL_PER_SOURCE) { |
| 1129: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_input"></i></span>'; |
| 1130: | } |
| 1131: | return '<tr class="all_setting"><td><label for="all_per_source">'. |
| 1132: | $this->trans('Max messages per source').'</label></td>'. |
| 1133: | '<td class="d-flex"><input class="form-control form-control-sm w-auto" type="text" size="2" id="all_per_source" name="all_per_source" value="'.$this->html_safe($sources).'" data-default-value="'.DEFAULT_ALL_PER_SOURCE.'" />'.$reset.'</td></tr>'; |
| 1134: | } |
| 1135: | } |
| 1136: | |
| 1137: | |
| 1138: | |
| 1139: | |
| 1140: | |
| 1141: | class Hm_Output_all_email_since_setting extends Hm_Output_Module { |
| 1142: | |
| 1143: | |
| 1144: | |
| 1145: | protected function output() { |
| 1146: | if (!email_is_active($this->get('router_module_list'))) { |
| 1147: | return ''; |
| 1148: | } |
| 1149: | $since = DEFAULT_ALL_EMAIL_SINCE; |
| 1150: | $settings = $this->get('user_settings', array()); |
| 1151: | if (array_key_exists('all_email_since', $settings) && $settings['all_email_since']) { |
| 1152: | $since = $settings['all_email_since']; |
| 1153: | } |
| 1154: | return '<tr class="email_setting"><td><label for="all_email_since">'. |
| 1155: | $this->trans('Show messages received since').'</label></td>'. |
| 1156: | '<td>'.message_since_dropdown($since, 'all_email_since', $this, DEFAULT_ALL_EMAIL_SINCE).'</td></tr>'; |
| 1157: | } |
| 1158: | } |
| 1159: | |
| 1160: | |
| 1161: | |
| 1162: | |
| 1163: | |
| 1164: | class Hm_Output_all_since_setting extends Hm_Output_Module { |
| 1165: | |
| 1166: | |
| 1167: | |
| 1168: | protected function output() { |
| 1169: | $since = DEFAULT_ALL_SINCE; |
| 1170: | $settings = $this->get('user_settings', array()); |
| 1171: | if (array_key_exists('all_since', $settings) && $settings['all_since']) { |
| 1172: | $since = $settings['all_since']; |
| 1173: | } |
| 1174: | return '<tr class="all_setting"><td><label for="all_since">'. |
| 1175: | $this->trans('Show messages received since').'</label></td>'. |
| 1176: | '<td>'.message_since_dropdown($since, 'all_since', $this, DEFAULT_ALL_SINCE).'</td></tr>'; |
| 1177: | } |
| 1178: | } |
| 1179: | |
| 1180: | |
| 1181: | |
| 1182: | |
| 1183: | |
| 1184: | class Hm_Output_language_setting extends Hm_Output_Module { |
| 1185: | |
| 1186: | |
| 1187: | |
| 1188: | protected function output() { |
| 1189: | $langs = interface_langs(); |
| 1190: | $translated = array(); |
| 1191: | $reset = ''; |
| 1192: | foreach ($langs as $code => $name) { |
| 1193: | $translated[$code] = $this->trans($name); |
| 1194: | } |
| 1195: | asort($translated); |
| 1196: | $mylang = $this->get('language', ''); |
| 1197: | $res = '<tr class="general_setting"><td><label for="language">'. |
| 1198: | $this->trans('Language').'</label></td>'. |
| 1199: | '<td><select id="language" class="form-select form-select-sm w-auto" name="language">'; |
| 1200: | foreach ($translated as $id => $lang) { |
| 1201: | $res .= '<option '; |
| 1202: | if ($id == $mylang) { |
| 1203: | $res .= 'selected="selected" '; |
| 1204: | if ($id != 'en') { |
| 1205: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_select"></i></span>'; |
| 1206: | } |
| 1207: | } |
| 1208: | $res .= 'value="'.$id.'">'.$lang.'</option>'; |
| 1209: | } |
| 1210: | $res .= '</select>'.$reset.'</td></tr>'; |
| 1211: | return $res; |
| 1212: | } |
| 1213: | } |
| 1214: | |
| 1215: | |
| 1216: | |
| 1217: | |
| 1218: | |
| 1219: | class Hm_Output_timezone_setting extends Hm_Output_Module { |
| 1220: | |
| 1221: | |
| 1222: | |
| 1223: | protected function output() { |
| 1224: | $zones = timezone_identifiers_list(); |
| 1225: | $settings = $this->get('user_settings', array()); |
| 1226: | $reset = ''; |
| 1227: | if (array_key_exists('timezone', $settings)) { |
| 1228: | $myzone = $settings['timezone']; |
| 1229: | } |
| 1230: | else { |
| 1231: | $myzone = $this->get('default_timezone','UTC'); |
| 1232: | } |
| 1233: | $res = '<tr class="general_setting"><td><label for="timezone">'. |
| 1234: | $this->trans('Timezone').'</label></td><td><select class="w-auto form-select form-select-sm" id="timezone" name="timezone">'; |
| 1235: | foreach ($zones as $zone) { |
| 1236: | $res .= '<option '; |
| 1237: | if ($zone == $myzone) { |
| 1238: | $res .= 'selected="selected" '; |
| 1239: | if ($zone != $this->get('default_timezone','UTC')) { |
| 1240: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_timezone"></i></span>'; |
| 1241: | } |
| 1242: | } |
| 1243: | $res .= 'value="'.$zone.'">'.$zone.'</option>'; |
| 1244: | } |
| 1245: | $res .= '</select>'.$reset.'</td></tr>'; |
| 1246: | return $res; |
| 1247: | } |
| 1248: | } |
| 1249: | |
| 1250: | |
| 1251: | |
| 1252: | |
| 1253: | |
| 1254: | class Hm_Output_msg_list_icons_setting extends Hm_Output_Module { |
| 1255: | protected function output() { |
| 1256: | $checked = ''; |
| 1257: | $settings = $this->get('user_settings', array()); |
| 1258: | $reset = ''; |
| 1259: | if (array_key_exists('show_list_icons', $settings) && $settings['show_list_icons']) { |
| 1260: | $checked = ' checked="checked"'; |
| 1261: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_checkbox"></i></span>'; |
| 1262: | } |
| 1263: | return '<tr class="general_setting"><td><label class="form-check-label" for="show_list_icons">'. |
| 1264: | $this->trans('Show icons in message lists').'</label></td>'. |
| 1265: | '<td><input class="form-check-input" type="checkbox" '.$checked.' id="show_list_icons" name="show_list_icons" data-default-value="false" value="1" />'.$reset.'</td></tr>'; |
| 1266: | } |
| 1267: | } |
| 1268: | |
| 1269: | |
| 1270: | |
| 1271: | |
| 1272: | |
| 1273: | class Hm_Output_end_settings_form extends Hm_Output_Module { |
| 1274: | |
| 1275: | |
| 1276: | |
| 1277: | protected function output() { |
| 1278: | return '<tr><td class="submit_cell" colspan="2">'. |
| 1279: | '<input class="save_settings btn btn-primary" type="submit" name="save_settings" value="'.$this->trans('Save').'" />'. |
| 1280: | '</td></tr></table></div></form>'. |
| 1281: | '<div class="px-3 d-flex justify-content-end"><form method="POST"><input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'. |
| 1282: | '<input class="reset_factory_button btn btn-light border" type="submit" name="reset_factory" value="'.$this->trans('Restore Defaults').'" /></form></div>'. |
| 1283: | '</div>'; |
| 1284: | } |
| 1285: | } |
| 1286: | |
| 1287: | |
| 1288: | |
| 1289: | |
| 1290: | |
| 1291: | class Hm_Output_folder_list_start extends Hm_Output_Module { |
| 1292: | |
| 1293: | |
| 1294: | |
| 1295: | protected function output() { |
| 1296: | $res = '<nav class="folder_cell"><div class="folder_list">'; |
| 1297: | return $res; |
| 1298: | } |
| 1299: | } |
| 1300: | |
| 1301: | |
| 1302: | |
| 1303: | |
| 1304: | |
| 1305: | class Hm_Output_folder_list_content_start extends Hm_Output_Module { |
| 1306: | |
| 1307: | |
| 1308: | |
| 1309: | protected function output() { |
| 1310: | if ($this->format == 'HTML5') { |
| 1311: | return ''; |
| 1312: | } |
| 1313: | $this->out('formatted_folder_list', '', false); |
| 1314: | } |
| 1315: | } |
| 1316: | |
| 1317: | |
| 1318: | |
| 1319: | |
| 1320: | |
| 1321: | class Hm_Output_main_menu_start extends Hm_Output_Module { |
| 1322: | |
| 1323: | |
| 1324: | |
| 1325: | protected function output() { |
| 1326: | $res = ''; |
| 1327: | if (DEBUG_MODE or DEFAULT_DEBUG_LOG) { |
| 1328: | $res .= '<span title="'. |
| 1329: | $this->trans('Running in debug mode. See https://cypht.org/install.html Section 6 for more detail.'). |
| 1330: | '" class="debug_title">'.$this->trans('Debug').'</span>'; |
| 1331: | } |
| 1332: | $theme = $this->get('theme'); |
| 1333: | $logo = $theme === 'darkly' ? 'modules/core/assets/images/logo.svg' : 'modules/core/assets/images/logo_dark.svg' ; |
| 1334: | $res .= '<a href="?page=home" class="menu_home"><img class="app-logo" src="'.WEB_ROOT.$logo.'"></a>'; |
| 1335: | $res .= '<div class="main"><ul class="folders">'; |
| 1336: | if ($this->format == 'HTML5') { |
| 1337: | return $res; |
| 1338: | } |
| 1339: | $this->concat('formatted_folder_list', $res); |
| 1340: | } |
| 1341: | } |
| 1342: | |
| 1343: | |
| 1344: | |
| 1345: | |
| 1346: | |
| 1347: | class Hm_Output_main_menu_content extends Hm_Output_Module { |
| 1348: | |
| 1349: | |
| 1350: | |
| 1351: | |
| 1352: | protected function output() { |
| 1353: | $res = ''; |
| 1354: | $email = false; |
| 1355: | if (array_key_exists('email_folders', merge_folder_list_details($this->get('folder_sources', array())))) { |
| 1356: | $email = true; |
| 1357: | } |
| 1358: | $total_accounts = count($this->get('imap_servers', array())) + count($this->get('feeds', array())); |
| 1359: | if ($total_accounts > 1) { |
| 1360: | $res .= '<li class="menu_combined_inbox"><a class="unread_link" href="?page=message_list&list_path=combined_inbox">'; |
| 1361: | if (!$this->get('hide_folder_icons')) { |
| 1362: | $res .= '<i class="bi bi-box2-fill menu-icon"></i>'; |
| 1363: | } |
| 1364: | $res .= '<span class="nav-label">'.$this->trans('Everything').'</span</a><span class="combined_inbox_count"></span></li>'; |
| 1365: | } |
| 1366: | $res .= '<li class="menu_unread d-flex align-items-center"><a class="unread_link d-flex align-items-center" href="?page=message_list&list_path=unread">'; |
| 1367: | if (!$this->get('hide_folder_icons')) { |
| 1368: | $res .= '<i class="bi bi-envelope-fill menu-icon"></i>'; |
| 1369: | } |
| 1370: | $res .= '<span class="nav-label">'.$this->trans('Unread').'</span></a><span class="total_unread_count badge rounded-pill text-bg-info ms-2 px-1"></span></li>'; |
| 1371: | $res .= '<li class="menu_flagged"><a class="unread_link" href="?page=message_list&list_path=flagged">'; |
| 1372: | if (!$this->get('hide_folder_icons')) { |
| 1373: | $res .= '<i class="bi bi-flag-fill menu-icon"></i>'; |
| 1374: | } |
| 1375: | $res .= '<span class="nav-label">'.$this->trans('Flagged').'</span></a> <span class="flagged_count"></span></li>'; |
| 1376: | $res .= '<li class="menu_junk"><a class="unread_link" href="?page=message_list&list_path=junk">'; |
| 1377: | if (!$this->get('hide_folder_icons')) { |
| 1378: | $res .= '<i class="bi bi-envelope-x-fill menu-icon"></i>'; |
| 1379: | } |
| 1380: | $res .= '<span class="nav-label">'.$this->trans('Junk').'</span></a></li>'; |
| 1381: | $res .= '<li class="menu_trash"><a class="unread_link" href="?page=message_list&list_path=trash">'; |
| 1382: | if (!$this->get('hide_folder_icons')) { |
| 1383: | $res .= '<i class="bi bi-trash3-fill menu-icon"></i>'; |
| 1384: | } |
| 1385: | $res .= '<span class="nav-label">'.$this->trans('Trash').'</span></a></li>'; |
| 1386: | $res .= '<li class="menu_drafts"><a class="unread_link" href="?page=message_list&list_path=drafts">'; |
| 1387: | if (!$this->get('hide_folder_icons')) { |
| 1388: | $res .= '<i class="bi bi-pencil-square menu-icon"></i>'; |
| 1389: | } |
| 1390: | $res .= '<span class="nav-label">'.$this->trans('Drafts').'</span></a></li>'; |
| 1391: | $settings = $this->get('user_settings', array()); |
| 1392: | if (array_key_exists('enable_snooze_setting', $settings) && $settings['enable_snooze_setting']) { |
| 1393: | $res .= '<li class="menu_snoozed"><a class="unread_link" href="?page=message_list&list_path=snoozed">'; |
| 1394: | if (!$this->get('hide_folder_icons')) { |
| 1395: | $res .= '<i class="bi bi-clock-fill menu-icon"></i>'; |
| 1396: | } |
| 1397: | $res .= '<span class="nav-label">'.$this->trans('Snoozed').'</span></a></li>'; |
| 1398: | } |
| 1399: | |
| 1400: | if ($this->format == 'HTML5') { |
| 1401: | return $res; |
| 1402: | } |
| 1403: | $this->concat('formatted_folder_list', $res); |
| 1404: | } |
| 1405: | } |
| 1406: | |
| 1407: | |
| 1408: | |
| 1409: | |
| 1410: | |
| 1411: | class Hm_Output_main_menu_end extends Hm_Output_Module { |
| 1412: | protected function output() { |
| 1413: | $res = '</ul></div>'; |
| 1414: | if ($this->format == 'HTML5') { |
| 1415: | return $res; |
| 1416: | } |
| 1417: | $this->concat('formatted_folder_list', $res); |
| 1418: | } |
| 1419: | } |
| 1420: | |
| 1421: | |
| 1422: | |
| 1423: | |
| 1424: | |
| 1425: | class Hm_Output_email_menu_content extends Hm_Output_Module { |
| 1426: | |
| 1427: | |
| 1428: | |
| 1429: | protected function output() { |
| 1430: | $res = ''; |
| 1431: | $folder_sources = merge_folder_list_details($this->get('folder_sources')); |
| 1432: | $single = $this->get('single_server_mode'); |
| 1433: | foreach ($folder_sources as $src => $content) { |
| 1434: | $parts = explode('_', $src); |
| 1435: | array_pop($parts); |
| 1436: | $name = ucwords(implode(' ', $parts)); |
| 1437: | $class = $this->html_safe($src); |
| 1438: | if (!$single) { |
| 1439: | $res .= '<div class="src_name d-flex justify-content-between pe-2" data-bs-toggle="collapse" role="button" data-bs-target=".'.$this->html_safe($src).'">'.$this->trans($name). |
| 1440: | '<i class="bi bi-chevron-down"></i></div>'; |
| 1441: | $class .= ' collapse'; |
| 1442: | } |
| 1443: | |
| 1444: | $res .= '<div class="'.$class.'"><ul class="folders">'; |
| 1445: | if ($name == 'Email' && count($this->get('imap_servers', array())) > 1) { |
| 1446: | $res .= '<li class="menu_email"><a class="unread_link" href="?page=message_list&list_path=email">'; |
| 1447: | if (!$this->get('hide_folder_icons')) { |
| 1448: | $res .= '<i class="bi bi-globe-americas menu-icon"></i>'; |
| 1449: | } |
| 1450: | $res .= $this->trans('All').'</a> <span class="unread_mail_count"></span></li>'; |
| 1451: | } |
| 1452: | $res .= $content.'</ul></div>'; |
| 1453: | } |
| 1454: | if ($this->format == 'HTML5') { |
| 1455: | return $res; |
| 1456: | } |
| 1457: | $this->concat('formatted_folder_list', $res); |
| 1458: | } |
| 1459: | } |
| 1460: | |
| 1461: | |
| 1462: | |
| 1463: | |
| 1464: | |
| 1465: | class Hm_Output_settings_menu_start extends Hm_Output_Module { |
| 1466: | |
| 1467: | |
| 1468: | |
| 1469: | protected function output() { |
| 1470: | $res = '<div class="src_name d-flex justify-content-between pe-2" data-bs-toggle="collapse" role="button" data-bs-target=".settings">'.$this->trans('Settings'). |
| 1471: | '<i class="bi bi-chevron-down"></i></div>'. |
| 1472: | '<ul id="settings-menu-start" class="collapse settings folders">'; |
| 1473: | if ($this->format == 'HTML5') { |
| 1474: | return $res; |
| 1475: | } |
| 1476: | $this->concat('formatted_folder_list', $res); |
| 1477: | } |
| 1478: | } |
| 1479: | |
| 1480: | |
| 1481: | |
| 1482: | |
| 1483: | |
| 1484: | class Hm_Output_save_form extends Hm_Output_Module { |
| 1485: | |
| 1486: | |
| 1487: | |
| 1488: | protected function output() { |
| 1489: | $changed = $this->get('changed_settings', array()); |
| 1490: | $res = '<div class="save_settings_page p-0"><div class="content_title px-3">'.$this->trans('Save Settings').'</div>'; |
| 1491: | $res .= '<div class="save_details p-3">'.$this->trans('Settings are not saved permanently on the server unless you explicitly allow it. '. |
| 1492: | 'If you don\'t save your settings, any changes made since you last logged in will be deleted when your '. |
| 1493: | 'session expires or you logout. You must re-enter your password for security purposes to save your settings '. |
| 1494: | 'permanently.'); |
| 1495: | $res .= '<div class="save_subtitle mt-3"><b>'.$this->trans('Unsaved Changes').'</b></div>'; |
| 1496: | $res .= '<ul class="unsaved_settings">'; |
| 1497: | if (!empty($changed)) { |
| 1498: | $changed = array_count_values($changed); |
| 1499: | foreach ($changed as $change => $num) { |
| 1500: | $res .= '<li>'.$this->trans($change).' ('.$this->html_safe($num).'X)</li>'; |
| 1501: | } |
| 1502: | } |
| 1503: | else { |
| 1504: | $res .= '<li>'.$this->trans('No changes need to be saved').'</li>'; |
| 1505: | } |
| 1506: | $res .= '</ul></div><div class="save_perm_form px-3"><form method="post">'. |
| 1507: | '<input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'. |
| 1508: | '<input type="text" value="'.$this->html_safe($this->get('username', 'cypht_user')).'" autocomplete="username" style="display: none;"/>'. |
| 1509: | '<label class="screen_reader" for="password">Password</label><input required id="password" '. |
| 1510: | 'name="password" autocomplete="current-password" class="save_settings_password form-control mb-2 warn_on_paste" type="password" placeholder="'.$this->trans('Password').'" />'. |
| 1511: | '<input class="save_settings btn btn-primary me-2" type="submit" name="save_settings_permanently" value="'.$this->trans('Save').'" />'. |
| 1512: | '<input class="save_settings btn btn-outline-secondary me-2" type="submit" name="save_settings_permanently_then_logout" value="'.$this->trans('Save and Logout').'" />'. |
| 1513: | '</form><form method="post"><input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" />'. |
| 1514: | '<input class="save_settings btn btn-outline-secondary" type="submit" name="logout" value="'.$this->trans('Just Logout').'" />'. |
| 1515: | '</form></div>'; |
| 1516: | |
| 1517: | $res .= '</div>'; |
| 1518: | return $res; |
| 1519: | } |
| 1520: | } |
| 1521: | |
| 1522: | |
| 1523: | |
| 1524: | |
| 1525: | |
| 1526: | class Hm_Output_settings_servers_link extends Hm_Output_Module { |
| 1527: | |
| 1528: | |
| 1529: | |
| 1530: | protected function output() { |
| 1531: | $res = '<li class="menu_servers"><a class="unread_link" href="?page=servers">'; |
| 1532: | if (!$this->get('hide_folder_icons')) { |
| 1533: | $res .= '<i class="bi bi-pc-display-horizontal menu-icon"></i>'; |
| 1534: | } |
| 1535: | $res .= $this->trans('Servers').'</a></li>'; |
| 1536: | $this->concat('formatted_folder_list', $res); |
| 1537: | } |
| 1538: | } |
| 1539: | |
| 1540: | |
| 1541: | |
| 1542: | |
| 1543: | |
| 1544: | class Hm_Output_settings_site_link extends Hm_Output_Module { |
| 1545: | |
| 1546: | |
| 1547: | |
| 1548: | protected function output() { |
| 1549: | $res = '<li class="menu_settings"><a class="unread_link" href="?page=settings">'; |
| 1550: | if (!$this->get('hide_folder_icons')) { |
| 1551: | $res .= '<i class="bi bi-gear-wide-connected menu-icon"></i>'; |
| 1552: | } |
| 1553: | $res .= $this->trans('Site').'</a></li>'; |
| 1554: | $this->concat('formatted_folder_list', $res); |
| 1555: | } |
| 1556: | } |
| 1557: | |
| 1558: | |
| 1559: | |
| 1560: | |
| 1561: | |
| 1562: | class Hm_Output_settings_save_link extends Hm_Output_Module { |
| 1563: | |
| 1564: | |
| 1565: | |
| 1566: | protected function output() { |
| 1567: | if ($this->get('single_server_mode')) { |
| 1568: | return; |
| 1569: | } |
| 1570: | $res = '<li class="menu_save"><a class="unread_link" href="?page=save">'; |
| 1571: | if (!$this->get('hide_folder_icons')) { |
| 1572: | $res .= '<i class="bi bi-download menu-icon"></i>'; |
| 1573: | } |
| 1574: | $res .= $this->trans('Save').'</a></li>'; |
| 1575: | $this->concat('formatted_folder_list', $res); |
| 1576: | } |
| 1577: | } |
| 1578: | |
| 1579: | |
| 1580: | |
| 1581: | |
| 1582: | |
| 1583: | class Hm_Output_settings_menu_end extends Hm_Output_Module { |
| 1584: | |
| 1585: | |
| 1586: | |
| 1587: | protected function output() { |
| 1588: | $res = '</ul>'; |
| 1589: | if ($this->format == 'HTML5') { |
| 1590: | return $res; |
| 1591: | } |
| 1592: | $this->concat('formatted_folder_list', $res); |
| 1593: | } |
| 1594: | } |
| 1595: | |
| 1596: | |
| 1597: | |
| 1598: | |
| 1599: | |
| 1600: | class Hm_Output_folder_list_content_end extends Hm_Output_Module { |
| 1601: | |
| 1602: | |
| 1603: | |
| 1604: | protected function output() { |
| 1605: | $res = '<div class="sidebar-footer">'; |
| 1606: | $res .= '<a class="logout_link" href="#" title="'. $this->trans('Logout') .'">'; |
| 1607: | if (!$this->get('hide_folder_icons')) { |
| 1608: | $res .= '<i class="bi bi-power menu-icon"></i>'; |
| 1609: | } |
| 1610: | $res .= '<span class="nav-label">' . $this->trans('Logout') .'</span>'; |
| 1611: | $res .= '</a>'; |
| 1612: | $res .= '<a href="#" class="update_message_list" title="'. $this->trans('Reload') .'">'; |
| 1613: | if (!$this->get('hide_folder_icons')) { |
| 1614: | $res .= '<i class="bi bi-arrow-clockwise menu-icon"></i>'; |
| 1615: | } |
| 1616: | $res .= '<span class="nav-label">' . $this->trans('Reload') . '</span>'; |
| 1617: | $res .= '</a>'; |
| 1618: | |
| 1619: | |
| 1620: | $res .= '<div class="menu-toggle fw-bold cursor-pointer no_mobile"><i class="bi bi-list fs-5 fw-bold"></i></div>'; |
| 1621: | |
| 1622: | |
| 1623: | |
| 1624: | |
| 1625: | if ($this->format == 'HTML5') { |
| 1626: | return $res; |
| 1627: | } |
| 1628: | $this->concat('formatted_folder_list', $res); |
| 1629: | } |
| 1630: | } |
| 1631: | |
| 1632: | |
| 1633: | |
| 1634: | |
| 1635: | |
| 1636: | class Hm_Output_folder_list_end extends Hm_Output_Module { |
| 1637: | |
| 1638: | |
| 1639: | |
| 1640: | protected function output() { |
| 1641: | return '</div></nav>'; |
| 1642: | } |
| 1643: | } |
| 1644: | |
| 1645: | |
| 1646: | |
| 1647: | |
| 1648: | |
| 1649: | class Hm_Output_content_section_start extends Hm_Output_Module { |
| 1650: | |
| 1651: | |
| 1652: | |
| 1653: | protected function output() { |
| 1654: | return '<main class="container-fluid content_cell" id="cypht-main"><div class="offline">'.$this->trans('Offline').'</div><div class="row m-0">'; |
| 1655: | } |
| 1656: | } |
| 1657: | |
| 1658: | |
| 1659: | |
| 1660: | |
| 1661: | |
| 1662: | class Hm_Output_content_section_end extends Hm_Output_Module { |
| 1663: | |
| 1664: | |
| 1665: | |
| 1666: | protected function output() { |
| 1667: | return '</div></main>'; |
| 1668: | } |
| 1669: | } |
| 1670: | |
| 1671: | |
| 1672: | |
| 1673: | |
| 1674: | |
| 1675: | class Hm_Output_modals extends Hm_Output_Module { |
| 1676: | |
| 1677: | |
| 1678: | |
| 1679: | protected function output() { |
| 1680: | $share_folder_modal = '<div class="modal fade" id="shareFolderModal" tabindex="-1" aria-labelledby="shareFolderModalLabel" aria-hidden="true">'; |
| 1681: | $share_folder_modal .= '<div class="modal-dialog modal-lg">'; |
| 1682: | $share_folder_modal .= '<div class="modal-content">'; |
| 1683: | $share_folder_modal .= '<div class="modal-header">'; |
| 1684: | $share_folder_modal .= '<h5 class="modal-title" id="shareFolderModalLabel">'.$this->trans('Edit Permissions').'</h5>'; |
| 1685: | $share_folder_modal .= '<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>'; |
| 1686: | $share_folder_modal .= '</div>'; |
| 1687: | |
| 1688: | $share_folder_modal .= '<div class="modal-body">'; |
| 1689: | $share_folder_modal .= '<div class="row">'; |
| 1690: | |
| 1691: | $share_folder_modal .= '<div class="col-lg-8 col-md-12">'; |
| 1692: | |
| 1693: | $share_folder_modal .= '<div id="loadingSpinner" class="text-center">'; |
| 1694: | $share_folder_modal .= '<div class="spinner-border text-primary" role="status">'; |
| 1695: | $share_folder_modal .= '<span class="visually-hidden">Loading...</span>'; |
| 1696: | $share_folder_modal .= '</div>'; |
| 1697: | $share_folder_modal .= '</div>'; |
| 1698: | |
| 1699: | $share_folder_modal .= '<table class="table table-striped" id="permissionTable" style="display:none;">'; |
| 1700: | $share_folder_modal .= '<thead>'; |
| 1701: | $share_folder_modal .= '<tr>'; |
| 1702: | $share_folder_modal .= '<th>'.$this->trans('User').'</th>'; |
| 1703: | $share_folder_modal .= '<th>'.$this->trans('Permissions').'</th>'; |
| 1704: | $share_folder_modal .= '<th>'.$this->trans('Actions').'</th>'; |
| 1705: | $share_folder_modal .= '</tr>'; |
| 1706: | $share_folder_modal .= '</thead>'; |
| 1707: | $share_folder_modal .= '<tbody></tbody>'; |
| 1708: | $share_folder_modal .= '</table>'; |
| 1709: | |
| 1710: | $share_folder_modal .= '</div>'; |
| 1711: | |
| 1712: | $share_folder_modal .= '<div class="col-lg-4 col-md-12">'; |
| 1713: | $share_folder_modal .= '<form id="shareForm" action="" method="POST">'; |
| 1714: | $share_folder_modal .= '<input type="hidden" name="server_id" id="server_id" value="">'; |
| 1715: | $share_folder_modal .= '<input type="hidden" name="folder_uid" id="folder_uid" value="">'; |
| 1716: | $share_folder_modal .= '<input type="hidden" name="folder" id="folder" value="">'; |
| 1717: | |
| 1718: | $share_folder_modal .= '<div class="mb-3 row">'; |
| 1719: | $share_folder_modal .= '<div class="col-12">'; |
| 1720: | $share_folder_modal .= '<label class="form-label">'.$this->trans('Identifier').'</label>'; |
| 1721: | $share_folder_modal .= '<div>'; |
| 1722: | $share_folder_modal .= '<input type="radio" name="identifier" value="user" id="identifierUser" checked>'; |
| 1723: | $share_folder_modal .= '<label for="identifierUser">'.$this->trans('User').':</label>'; |
| 1724: | $share_folder_modal .= '<input type="text" class="form-control d-inline-block" id="email" name="email" required placeholder="Enter email">'; |
| 1725: | $share_folder_modal .= '</div>'; |
| 1726: | $share_folder_modal .= '<div>'; |
| 1727: | $share_folder_modal .= '<input type="radio" name="identifier" value="all" id="identifierAll">'; |
| 1728: | $share_folder_modal .= '<label for="identifierAll">'.$this->trans('All users (anyone)').'</label>'; |
| 1729: | $share_folder_modal .= '</div>'; |
| 1730: | $share_folder_modal .= '<div>'; |
| 1731: | $share_folder_modal .= '<input type="radio" name="identifier" value="guests" id="identifierGuests">'; |
| 1732: | $share_folder_modal .= '<label for="identifierGuests">'.$this->trans('Guests (anonymous)').'</label>'; |
| 1733: | $share_folder_modal .= '</div>'; |
| 1734: | $share_folder_modal .= '</div>'; |
| 1735: | $share_folder_modal .= '</div>'; |
| 1736: | |
| 1737: | $share_folder_modal .= '<div class="mb-3 row">'; |
| 1738: | $share_folder_modal .= '<div class="col-12">'; |
| 1739: | $share_folder_modal .= '<label class="form-label">'.$this->trans('Access Rights').'</label>'; |
| 1740: | $share_folder_modal .= '<div>'; |
| 1741: | $share_folder_modal .= '<input type="checkbox" name="access_read" id="accessRead" checked>'; |
| 1742: | $share_folder_modal .= '<label for="accessRead">'.$this->trans('Read').'</label>'; |
| 1743: | $share_folder_modal .= '</div>'; |
| 1744: | $share_folder_modal .= '<div>'; |
| 1745: | $share_folder_modal .= '<input type="checkbox" name="access_write" id="accessWrite">'; |
| 1746: | $share_folder_modal .= '<label for="accessWrite">'.$this->trans('Write').'</label>'; |
| 1747: | $share_folder_modal .= '</div>'; |
| 1748: | $share_folder_modal .= '<div>'; |
| 1749: | $share_folder_modal .= '<input type="checkbox" name="access_delete" id="accessDelete">'; |
| 1750: | $share_folder_modal .= '<label for="accessDelete">'.$this->trans('Delete').'</label>'; |
| 1751: | $share_folder_modal .= '</div>'; |
| 1752: | $share_folder_modal .= '<div>'; |
| 1753: | $share_folder_modal .= '<input type="checkbox" name="access_other" id="accessOther">'; |
| 1754: | $share_folder_modal .= '<label for="accessOther">'.$this->trans('Other').'</label>'; |
| 1755: | $share_folder_modal .= '</div>'; |
| 1756: | $share_folder_modal .= '</div>'; |
| 1757: | $share_folder_modal .= '</div>'; |
| 1758: | |
| 1759: | $share_folder_modal .= '<div class="modal-footer">'; |
| 1760: | $share_folder_modal .= '<button type="submit" class="btn btn-primary">'.$this->trans('Save').'</button>'; |
| 1761: | $share_folder_modal .= '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">'.$this->trans('Cancel').'</button>'; |
| 1762: | $share_folder_modal .= '</div>'; |
| 1763: | $share_folder_modal .= '</form>'; |
| 1764: | $share_folder_modal .= '</div>'; |
| 1765: | |
| 1766: | $share_folder_modal .= '</div>'; |
| 1767: | $share_folder_modal .= '</div>'; |
| 1768: | |
| 1769: | $share_folder_modal .= '</div>'; |
| 1770: | $share_folder_modal .= '</div>'; |
| 1771: | $share_folder_modal .= '</div>'; |
| 1772: | |
| 1773: | return $share_folder_modal; |
| 1774: | } |
| 1775: | } |
| 1776: | |
| 1777: | |
| 1778: | |
| 1779: | |
| 1780: | |
| 1781: | class Hm_Output_message_start extends Hm_Output_Module { |
| 1782: | |
| 1783: | |
| 1784: | |
| 1785: | protected function output() { |
| 1786: | if ($this->in('list_parent', array('advanced_search', 'github_all', 'sent', 'search', 'flagged', 'combined_inbox', 'unread', 'feeds', 'email'))) { |
| 1787: | if ($this->get('list_parent') == 'combined_inbox') { |
| 1788: | $list_name = $this->trans('Everything'); |
| 1789: | } |
| 1790: | elseif ($this->get('list_parent') == 'email') { |
| 1791: | $list_name = $this->trans('All Email'); |
| 1792: | } |
| 1793: | else { |
| 1794: | $list_name = $this->trans(ucwords(str_replace('_', ' ', $this->get('list_parent', '')))); |
| 1795: | } |
| 1796: | $additional = ''; |
| 1797: | if ($this->get('list_parent') == 'advanced_search') { |
| 1798: | $page = 'advanced_search'; |
| 1799: | } |
| 1800: | elseif ($this->get('list_parent') == 'search') { |
| 1801: | $page = 'search'; |
| 1802: | foreach (['list_page', 'list_sort', 'search_terms', 'search_fld', 'search_since'] as $field) { |
| 1803: | if ($value = $this->get($field)) { |
| 1804: | $field = $field == 'list_sort' ? 'sort' : $field; |
| 1805: | $additional .= "&$field=" . $this->html_safe($value); |
| 1806: | } |
| 1807: | } |
| 1808: | } |
| 1809: | else { |
| 1810: | $page = 'message_list'; |
| 1811: | } |
| 1812: | $title = '<a href="?page='.$page.'&list_path='.$this->html_safe($this->get('list_parent')).$additional.'">'.$list_name.'</a>'; |
| 1813: | if (count($this->get('mailbox_list_title', array())) > 0) { |
| 1814: | $mb_title = array_map( function($v) { return $this->trans($v); }, $this->get('mailbox_list_title', array())); |
| 1815: | if (($key = array_search($list_name, $mb_title)) !== false) { |
| 1816: | unset($mb_title[$key]); |
| 1817: | } |
| 1818: | $title .= '<i class="bi bi-caret-right-fill path_delim"></i>'. |
| 1819: | '<a href="?page=message_list&list_path='.$this->html_safe($this->get('list_path')).'">'. |
| 1820: | implode('<i class="bi bi-caret-right-fill path_delim"></i>', |
| 1821: | array_map( function($v) { return $this->trans($v); }, $mb_title)).'</a>'; |
| 1822: | } |
| 1823: | } |
| 1824: | elseif ($this->get('mailbox_list_title')) { |
| 1825: | $url = '?page=message_list&list_path='.$this->html_safe($this->get('list_path')); |
| 1826: | if ($this->get('list_page', 0)) { |
| 1827: | $url .= '&list_page='.$this->html_safe($this->get('list_page')); |
| 1828: | } |
| 1829: | if ($this->get('list_filter', '')) { |
| 1830: | $url .= '&filter='.$this->html_safe($this->get('list_filter')); |
| 1831: | } |
| 1832: | if ($this->get('list_sort', '')) { |
| 1833: | $url .= '&sort='.$this->html_safe($this->get('list_sort')); |
| 1834: | } |
| 1835: | $title = '<a href="'.$url.'">'. |
| 1836: | implode('<i class="bi bi-caret-right-fill path_delim"></i>', |
| 1837: | array_map( function($v) { return $this->trans($v); }, $this->get('mailbox_list_title', array()))).'</a>'; |
| 1838: | } |
| 1839: | else { |
| 1840: | $title = ''; |
| 1841: | } |
| 1842: | $res = ''; |
| 1843: | if ($this->get('uid')) { |
| 1844: | $res .= '<input type="hidden" class="msg_uid" value="'.$this->html_safe($this->get('uid')).'" />'; |
| 1845: | } |
| 1846: | $res .= '<div class="content_title">'.$title.'</div>'; |
| 1847: | $res .= '<div class="msg_text">'; |
| 1848: | return $res; |
| 1849: | } |
| 1850: | } |
| 1851: | |
| 1852: | |
| 1853: | |
| 1854: | |
| 1855: | |
| 1856: | class Hm_Output_message_end extends Hm_Output_Module { |
| 1857: | |
| 1858: | |
| 1859: | |
| 1860: | protected function output() { |
| 1861: | return '</div>'; |
| 1862: | } |
| 1863: | } |
| 1864: | |
| 1865: | |
| 1866: | |
| 1867: | |
| 1868: | |
| 1869: | class Hm_Output_notfound_content extends Hm_Output_Module { |
| 1870: | |
| 1871: | |
| 1872: | |
| 1873: | protected function output() { |
| 1874: | $res = '<div class="content_title">'.$this->trans('Page Not Found!').'</div>'; |
| 1875: | $res .= '<div class="empty_list"><br />'.$this->trans('Nothingness').'</div>'; |
| 1876: | return $res; |
| 1877: | } |
| 1878: | } |
| 1879: | |
| 1880: | |
| 1881: | |
| 1882: | |
| 1883: | |
| 1884: | class Hm_Output_message_list_start extends Hm_Output_Module { |
| 1885: | |
| 1886: | |
| 1887: | |
| 1888: | protected function output() { |
| 1889: | |
| 1890: | $col_flds = array(); |
| 1891: | $header_flds = array(); |
| 1892: | foreach ($this->get('message_list_fields', array()) as $vals) { |
| 1893: | if ($vals[0]) { |
| 1894: | $col_flds[] = sprintf('<col class="%s">', $vals[0]); |
| 1895: | } |
| 1896: | if ($vals[1] && $vals[2]) { |
| 1897: | $header_flds[] = sprintf('<th class="%s">%s</th>', $vals[1], $this->trans($vals[2])); |
| 1898: | } |
| 1899: | else { |
| 1900: | $header_flds[] = '<th></th>'; |
| 1901: | } |
| 1902: | } |
| 1903: | $res = '<div class="p-3">'; |
| 1904: | $res .= '<table class="message_table table">'; |
| 1905: | if (!$this->get('no_message_list_headers')) { |
| 1906: | if (!empty($col_flds)) { |
| 1907: | $res .= '<colgroup>'.implode('', $col_flds).'</colgroup>'; |
| 1908: | } |
| 1909: | if (!empty($header_flds)) { |
| 1910: | $res .= '<thead><tr>'.implode('', $header_flds).'</tr></thead>'; |
| 1911: | } |
| 1912: | } |
| 1913: | $res .= '<tbody class="message_table_body">'; |
| 1914: | return $res; |
| 1915: | } |
| 1916: | } |
| 1917: | |
| 1918: | |
| 1919: | |
| 1920: | |
| 1921: | |
| 1922: | class Hm_Output_home_heading extends Hm_Output_Module { |
| 1923: | |
| 1924: | |
| 1925: | protected function output() { |
| 1926: | return '<div class="content_title">'.$this->trans('Home').'</div>'; |
| 1927: | } |
| 1928: | } |
| 1929: | |
| 1930: | |
| 1931: | |
| 1932: | |
| 1933: | |
| 1934: | class Hm_Output_home_password_dialogs extends Hm_Output_Module { |
| 1935: | |
| 1936: | |
| 1937: | |
| 1938: | protected function output() { |
| 1939: | $missing = $this->get('missing_pw_servers', array()); |
| 1940: | if (count($missing) > 0) { |
| 1941: | $res = '<div class="home_password_dialogs mt-3 col-lg-6 col-md-5 col-sm-12">'; |
| 1942: | $res .= '<div class="card"><div class="card-body">'; |
| 1943: | $res .= '<div class="card_title"><h4>Passwords</h4></div><p>'.$this->trans('You have elected to not store passwords between logins.'). |
| 1944: | ' '.$this->trans('Enter your passwords below to gain access to these services during this session.').'</p>'; |
| 1945: | |
| 1946: | foreach ($missing as $vals) { |
| 1947: | $id = $this->html_safe(sprintf('%s_%s', mb_strtolower($vals['type']), $vals['id'])); |
| 1948: | $res .= '<div class="div_'.$id.' mt-3">'.$this->html_safe($vals['type']).' '.$this->html_safe($vals['name']). |
| 1949: | ' '.$this->html_safe($vals['user']).' '.$this->html_safe($vals['server']).' <div class="input-group mt-2"><input placeholder="'.$this->trans('Password'). |
| 1950: | '" type="password" class="form-control pw_input" id="update_pw_'.$id.'" /> <input type="button" class="pw_update btn btn-primary" data-id="'.$id. |
| 1951: | '" value="'.$this->trans('Update').'" /></div></div>'; |
| 1952: | } |
| 1953: | $res .= '</div></div></div>'; |
| 1954: | return $res; |
| 1955: | } |
| 1956: | } |
| 1957: | } |
| 1958: | |
| 1959: | |
| 1960: | |
| 1961: | |
| 1962: | |
| 1963: | class Hm_Output_message_list_heading extends Hm_Output_Module { |
| 1964: | |
| 1965: | |
| 1966: | |
| 1967: | protected function output() { |
| 1968: | $search_field = ''; |
| 1969: | $terms = $this->get('search_terms', ''); |
| 1970: | if ($this->get('custom_list_controls', '')) { |
| 1971: | $config_link = $this->get('custom_list_controls'); |
| 1972: | $source_link = ''; |
| 1973: | $refresh_link = '<a class="refresh_link" title="'.$this->trans('Refresh').'" href="#"><i class="bi bi-arrow-clockwise refresh_list"></i></a>'; |
| 1974: | } |
| 1975: | elseif (!$this->get('no_list_controls', false)) { |
| 1976: | $source_link = '<a href="#" title="'.$this->trans('Sources').'" class="source_link"><i class="bi bi-folder-fill refresh_list"></i></a>'; |
| 1977: | if ($this->get('list_path') == 'combined_inbox') { |
| 1978: | $path = 'all'; |
| 1979: | } |
| 1980: | else { |
| 1981: | $path = $this->get('list_path'); |
| 1982: | } |
| 1983: | $config_link = '<a title="'.$this->trans('Configure').'" href="?page=settings#'.$path.'_setting"><i class="bi bi-gear-wide refresh_list"></i></a>'; |
| 1984: | $refresh_link = '<a class="refresh_link" title="'.$this->trans('Refresh').'" href="#"><i class="bi bi-arrow-clockwise refresh_list"></i></a>'; |
| 1985: | |
| 1986: | |
| 1987: | |
| 1988: | |
| 1989: | |
| 1990: | } |
| 1991: | else { |
| 1992: | $config_link = ''; |
| 1993: | $source_link = ''; |
| 1994: | $refresh_link = ''; |
| 1995: | $search_field = ''; |
| 1996: | } |
| 1997: | $res = ''; |
| 1998: | $res .= '<div class="message_list p-0 '.$this->html_safe($this->get('list_path')).'_list"><div class="content_title d-flex flex-wrap justify-content-between px-3 align-items-center">'; |
| 1999: | $res .= '<div class="d-flex align-items-center gap-1 flex-wrap mb-2 mb-md-0">' . message_controls($this).'<div class="mailbox_list_title ms-2">'. |
| 2000: | implode('<i class="bi bi-caret-right-fill path_delim"></i>', array_map( function($v) { return $this->trans($v); }, |
| 2001: | $this->get('mailbox_list_title', array()))).'</div>'; |
| 2002: | if (!$this->get('is_mobile') && mb_substr((string) $this->get('list_path'), 0, 5) != 'imap_') { |
| 2003: | $res .= combined_sort_dialog($this); |
| 2004: | } |
| 2005: | $res .= '</div>'; |
| 2006: | $res .= message_list_meta($this->module_output(), $this); |
| 2007: | $res .= list_controls($refresh_link, $config_link, $source_link, $search_field); |
| 2008: | $res .= list_sources($this->get('data_sources', array()), $this); |
| 2009: | $res .= '</div>'; |
| 2010: | return $res; |
| 2011: | } |
| 2012: | } |
| 2013: | |
| 2014: | |
| 2015: | |
| 2016: | |
| 2017: | |
| 2018: | class Hm_Output_message_list_end extends Hm_Output_Module { |
| 2019: | |
| 2020: | |
| 2021: | |
| 2022: | protected function output() { |
| 2023: | $res = '</tbody></table></div></div>'; |
| 2024: | return $res; |
| 2025: | } |
| 2026: | } |
| 2027: | |
| 2028: | |
| 2029: | |
| 2030: | |
| 2031: | |
| 2032: | class Hm_Output_search_move_copy_controls extends Hm_Output_Module { |
| 2033: | protected function output() { |
| 2034: | $res = '<span class="ctr_divider"></span> <div class="d-flex align-items-start gap-1 dropdown"><a class="imap_move disabled_input btn btn-sm btn-secondary" href="#" data-action="copy" data-bs-toggle="dropdown">'.$this->trans('Copy').'</a>'; |
| 2035: | $res .= '<a class="imap_move disabled_input btn btn-sm btn-secondary" href="#" data-action="move" data-bs-toggle="dropdown">'.$this->trans('Move').'</a>'; |
| 2036: | $res .= '<div class="move_to_location dropdown-menu" data-bs-auto-close="outside"></div>'; |
| 2037: | $res .= '<input type="hidden" class="move_to_type" value="" />'; |
| 2038: | $res .= '<input type="hidden" class="move_to_string1" value="'.$this->trans('Move to ...').'" />'; |
| 2039: | $res .= '<input type="hidden" class="move_to_string2" value="'.$this->trans('Copy to ...').'" />'; |
| 2040: | $res .= '<input type="hidden" class="move_to_string3" value="'.$this->trans('Removed non-IMAP messages from selection. They cannot be moved or copied').'" /></div>'; |
| 2041: | |
| 2042: | $this->concat('msg_controls_extra', $res); |
| 2043: | } |
| 2044: | } |
| 2045: | |
| 2046: | |
| 2047: | |
| 2048: | |
| 2049: | |
| 2050: | class Hm_Output_start_junk_settings extends Hm_Output_Module { |
| 2051: | |
| 2052: | |
| 2053: | |
| 2054: | protected function output() { |
| 2055: | return '<tr><td data-target=".junk_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 2056: | '<i class="bi bi-envelope-x-fill fs-5 me-2"></i>'. |
| 2057: | $this->trans('Junk').'</td></tr>'; |
| 2058: | } |
| 2059: | } |
| 2060: | |
| 2061: | |
| 2062: | |
| 2063: | |
| 2064: | |
| 2065: | class Hm_Output_junk_source_max_setting extends Hm_Output_Module { |
| 2066: | |
| 2067: | |
| 2068: | |
| 2069: | protected function output() { |
| 2070: | $sources = DEFAULT_JUNK_PER_SOURCE; |
| 2071: | $settings = $this->get('user_settings', array()); |
| 2072: | $reset = ''; |
| 2073: | if (array_key_exists('junk_per_source', $settings)) { |
| 2074: | $sources = $settings['junk_per_source']; |
| 2075: | } |
| 2076: | if ($sources != DEFAULT_JUNK_PER_SOURCE) { |
| 2077: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_input"></i></span>'; |
| 2078: | } |
| 2079: | return '<tr class="junk_setting"><td><label for="junk_per_source">'. |
| 2080: | $this->trans('Max messages per source').'</label></td>'. |
| 2081: | '<td class="d-flex"><input class="form-control form-control-sm w-auto" type="text" size="2" id="junk_per_source" name="junk_per_source" value="'.$this->html_safe($sources).'" data-default-value="'.DEFAULT_JUNK_PER_SOURCE.'" />'.$reset.'</td></tr>'; |
| 2082: | } |
| 2083: | } |
| 2084: | |
| 2085: | |
| 2086: | |
| 2087: | |
| 2088: | |
| 2089: | class Hm_Output_junk_since_setting extends Hm_Output_Module { |
| 2090: | |
| 2091: | |
| 2092: | |
| 2093: | protected function output() { |
| 2094: | $since = DEFAULT_JUNK_SINCE; |
| 2095: | $settings = $this->get('user_settings', array()); |
| 2096: | if (array_key_exists('junk_since', $settings) && $settings['junk_since']) { |
| 2097: | $since = $settings['junk_since']; |
| 2098: | } |
| 2099: | return '<tr class="junk_setting"><td><label for="junk_since">'. |
| 2100: | $this->trans('Show junk messages since').'</label></td>'. |
| 2101: | '<td>'.message_since_dropdown($since, 'junk_since', $this, DEFAULT_JUNK_SINCE).'</td></tr>'; |
| 2102: | } |
| 2103: | } |
| 2104: | |
| 2105: | |
| 2106: | |
| 2107: | |
| 2108: | |
| 2109: | class Hm_Output_start_trash_settings extends Hm_Output_Module { |
| 2110: | |
| 2111: | |
| 2112: | |
| 2113: | protected function output() { |
| 2114: | return '<tr><td data-target=".trash_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 2115: | '<i class="bi bi-trash3-fill fs-5 me-2"></i>'. |
| 2116: | $this->trans('Trash').'</td></tr>'; |
| 2117: | } |
| 2118: | } |
| 2119: | |
| 2120: | |
| 2121: | |
| 2122: | |
| 2123: | |
| 2124: | class Hm_Output_trash_source_max_setting extends Hm_Output_Module { |
| 2125: | |
| 2126: | |
| 2127: | |
| 2128: | protected function output() { |
| 2129: | $sources = DEFAULT_TRASH_PER_SOURCE; |
| 2130: | $settings = $this->get('user_settings', array()); |
| 2131: | $reset = ''; |
| 2132: | if (array_key_exists('trash_per_source', $settings)) { |
| 2133: | $sources = $settings['trash_per_source']; |
| 2134: | } |
| 2135: | if ($sources != DEFAULT_TRASH_PER_SOURCE) { |
| 2136: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_input"></i></span>'; |
| 2137: | } |
| 2138: | return '<tr class="trash_setting"><td><label for="trash_per_source">'. |
| 2139: | $this->trans('Max messages per source').'</label></td>'. |
| 2140: | '<td class="d-flex"><input class="form-control form-control-sm w-auto" type="text" size="2" id="trash_per_source" name="trash_per_source" value="'.$this->html_safe($sources).'" data-default-value="'.DEFAULT_TRASH_PER_SOURCE.'" />'.$reset.'</td></tr>'; |
| 2141: | } |
| 2142: | } |
| 2143: | |
| 2144: | |
| 2145: | |
| 2146: | |
| 2147: | |
| 2148: | class Hm_Output_trash_since_setting extends Hm_Output_Module { |
| 2149: | |
| 2150: | |
| 2151: | |
| 2152: | protected function output() { |
| 2153: | $since = DEFAULT_TRASH_SINCE; |
| 2154: | $settings = $this->get('user_settings', array()); |
| 2155: | if (array_key_exists('trash_since', $settings) && $settings['trash_since']) { |
| 2156: | $since = $settings['trash_since']; |
| 2157: | } |
| 2158: | return '<tr class="trash_setting"><td><label for="trash_since">'. |
| 2159: | $this->trans('Show trash messages since').'</label></td>'. |
| 2160: | '<td>'.message_since_dropdown($since, 'trash_since', $this, DEFAULT_TRASH_SINCE).'</td></tr>'; |
| 2161: | } |
| 2162: | } |
| 2163: | |
| 2164: | |
| 2165: | |
| 2166: | |
| 2167: | class Hm_Output_start_snoozed_settings extends Hm_Output_Module { |
| 2168: | |
| 2169: | |
| 2170: | |
| 2171: | protected function output() { |
| 2172: | return '<tr><td data-target=".snoozed_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 2173: | '<i class="bi bi-clock-fill fs-5 me-2"></i>'. |
| 2174: | $this->trans('Snoozed').'</td></tr>'; |
| 2175: | } |
| 2176: | } |
| 2177: | |
| 2178: | |
| 2179: | |
| 2180: | |
| 2181: | class Hm_Output_snoozed_source_max_setting extends Hm_Output_Module { |
| 2182: | |
| 2183: | |
| 2184: | |
| 2185: | protected function output() { |
| 2186: | $sources = DEFAULT_SNOOZED_PER_SOURCE; |
| 2187: | $settings = $this->get('user_settings', array()); |
| 2188: | $reset = ''; |
| 2189: | if (array_key_exists('snoozed_per_source', $settings)) { |
| 2190: | $sources = $settings['snoozed_per_source']; |
| 2191: | } |
| 2192: | if ($sources != DEFAULT_SNOOZED_PER_SOURCE) { |
| 2193: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_input"></i></span>'; |
| 2194: | } |
| 2195: | return '<tr class="snoozed_setting"><td><label for="snoozed_per_source">'. |
| 2196: | $this->trans('Max messages per source for Snoozed').'</label></td>' . |
| 2197: | '<td class="d-flex"><input class="form-control form-control-sm w-auto" type="text" size="2" id="snoozed_per_source" name="snoozed_per_source" value="'.$this->html_safe($sources).'" data-default-value="'.DEFAULT_SNOOZED_PER_SOURCE.'" />'.$reset.'</td></tr>'; |
| 2198: | } |
| 2199: | } |
| 2200: | |
| 2201: | |
| 2202: | |
| 2203: | |
| 2204: | class Hm_Output_snoozed_since_setting extends Hm_Output_Module { |
| 2205: | |
| 2206: | |
| 2207: | |
| 2208: | protected function output() { |
| 2209: | $since = DEFAULT_SNOOZED_SINCE; |
| 2210: | $settings = $this->get('user_settings', array()); |
| 2211: | if (array_key_exists('snoozed_since', $settings) && $settings['snoozed_since']) { |
| 2212: | $since = $settings['snoozed_since']; |
| 2213: | } |
| 2214: | return '<tr class="snoozed_setting"><td><label for="snoozed_since">'. |
| 2215: | $this->trans('Show snoozed messages since').'</label></td>'. |
| 2216: | '<td>'.message_since_dropdown($since, 'snoozed_since', $this, DEFAULT_SNOOZED_SINCE).'</td></tr>'; |
| 2217: | } |
| 2218: | } |
| 2219: | |
| 2220: | |
| 2221: | |
| 2222: | |
| 2223: | class Hm_Output_start_drafts_settings extends Hm_Output_Module { |
| 2224: | |
| 2225: | |
| 2226: | |
| 2227: | protected function output() { |
| 2228: | return '<tr><td data-target=".drafts_setting" colspan="2" class="settings_subtitle cursor-pointer border-bottom p-2">'. |
| 2229: | '<i class="bi bi-pencil-square fs-5 me-2"></i>'. |
| 2230: | $this->trans('Drafts').'</td></tr>'; |
| 2231: | } |
| 2232: | } |
| 2233: | |
| 2234: | |
| 2235: | |
| 2236: | |
| 2237: | |
| 2238: | class Hm_Output_drafts_source_max_setting extends Hm_Output_Module { |
| 2239: | |
| 2240: | |
| 2241: | |
| 2242: | protected function output() { |
| 2243: | $sources = DEFAULT_DRAFT_PER_SOURCE; |
| 2244: | $settings = $this->get('user_settings', array()); |
| 2245: | $reset = ''; |
| 2246: | if (array_key_exists('drafts_per_source', $settings)) { |
| 2247: | $sources = $settings['drafts_per_source']; |
| 2248: | } |
| 2249: | if ($sources != DEFAULT_DRAFT_PER_SOURCE) { |
| 2250: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_input"></i></span>'; |
| 2251: | } |
| 2252: | return '<tr class="drafts_setting"><td><label for="drafts_per_source">'. |
| 2253: | $this->trans('Max messages per source').'</label></td>'. |
| 2254: | '<td class="d-flex"><input class="form-control form-control-sm w-auto" type="text" size="2" id="drafts_per_source" name="drafts_per_source" value="'.$this->html_safe($sources).'" data-default-value="'.DEFAULT_DRAFT_PER_SOURCE.'" />'.$reset.'</td></tr>'; |
| 2255: | } |
| 2256: | } |
| 2257: | |
| 2258: | |
| 2259: | |
| 2260: | |
| 2261: | |
| 2262: | class Hm_Output_drafts_since_setting extends Hm_Output_Module { |
| 2263: | |
| 2264: | |
| 2265: | |
| 2266: | protected function output() { |
| 2267: | $since = DEFAULT_DRAFT_SINCE; |
| 2268: | $settings = $this->get('user_settings', array()); |
| 2269: | if (array_key_exists('drafts_since', $settings) && $settings['drafts_since']) { |
| 2270: | $since = $settings['drafts_since']; |
| 2271: | } |
| 2272: | return '<tr class="drafts_setting"><td><label for="drafts_since">'. |
| 2273: | $this->trans('Show draft messages since').'</label></td>'. |
| 2274: | '<td>'.message_since_dropdown($since, 'drafts_since', $this, DEFAULT_DRAFT_SINCE).'</td></tr>'; |
| 2275: | } |
| 2276: | } |
| 2277: | |
| 2278: | |
| 2279: | |
| 2280: | |
| 2281: | |
| 2282: | class Hm_Output_warn_for_unsaved_changes_setting extends Hm_Output_Module { |
| 2283: | protected function output() { |
| 2284: | $checked = ''; |
| 2285: | $settings = $this->get('user_settings', array()); |
| 2286: | $reset = ''; |
| 2287: | if (array_key_exists('warn_for_unsaved_changes', $settings) && $settings['warn_for_unsaved_changes']) { |
| 2288: | $checked = ' checked="checked"'; |
| 2289: | $reset = '<span class="tooltip_restore" restore_aria_label="Restore default value"><i class="bi bi-arrow-counterclockwise refresh_list reset_default_value_checkbox"></i></span>'; |
| 2290: | } |
| 2291: | return '<tr class="general_setting"><td><label class="form-check-label" for="warn_for_unsaved_changes">'. |
| 2292: | $this->trans('Warn for unsaved changes').'</label></td>'. |
| 2293: | '<td><input type="checkbox" '.$checked.' id="warn_for_unsaved_changes" name="warn_for_unsaved_changes" class="form-check-input" value="1" data-default-value="false" />'.$reset.'</td></tr>'; |
| 2294: | } |
| 2295: | } |
| 2296: | |
| 2297: | class Hm_Output_server_config_stepper extends Hm_Output_Module { |
| 2298: | protected function output() { |
| 2299: | $accordionTitle = ''; |
| 2300: | $configuredText = $this->trans('Configured') .' '; |
| 2301: | $hasEssentialModuleActivated = false; |
| 2302: | |
| 2303: | $hasImapActivated = in_array('imap', $this->get('router_module_list'), true); |
| 2304: | $hasSmtpActivated = in_array('smtp', $this->get('router_module_list'), true); |
| 2305: | $hasJmapActivated = in_array('jmap', $this->get('router_module_list'), true); |
| 2306: | |
| 2307: | if($hasImapActivated){ |
| 2308: | $servers = array_filter($this->get('imap_servers', array()), fn($s) => ($s['type'] ?? null) !== 'ews'); |
| 2309: | $imap_servers_count = count($servers); |
| 2310: | $accordionTitle .= 'IMAP'; |
| 2311: | $configuredText .= '<span class="imap_server_count"> ' . $imap_servers_count .'</span> IMAP'; |
| 2312: | $hasEssentialModuleActivated = true; |
| 2313: | } |
| 2314: | |
| 2315: | if($hasJmapActivated){ |
| 2316: | |
| 2317: | $jmap_servers_count = count(array_filter($this->get('imap_servers', array()), function($v) { return array_key_exists('type', $v) && $v['type'] == 'jmap'; })); |
| 2318: | if($accordionTitle != ''){ |
| 2319: | $accordionTitle .= ' - '; |
| 2320: | $configuredText .= ' / '; |
| 2321: | } |
| 2322: | $accordionTitle .= 'JMAP'; |
| 2323: | $configuredText .= '<span class="jmap_server_count">' . $jmap_servers_count .'</span> JMAP'; |
| 2324: | $hasEssentialModuleActivated = true; |
| 2325: | } |
| 2326: | |
| 2327: | if($hasSmtpActivated){ |
| 2328: | $servers = array_filter($this->get('smtp_servers', array()), fn($s) => ($s['type'] ?? null) !== 'ews'); |
| 2329: | $smtp_servers_count = count($servers); |
| 2330: | if($accordionTitle != ''){ |
| 2331: | $accordionTitle .= ' - '; |
| 2332: | $configuredText .= ' / '; |
| 2333: | } |
| 2334: | $accordionTitle .= 'SMTP'; |
| 2335: | $configuredText .= '<span class="smtp_server_count">' . $smtp_servers_count .'</span> SMTP'; |
| 2336: | $hasEssentialModuleActivated = true; |
| 2337: | } |
| 2338: | |
| 2339: | $accordionTitle .= ' Servers'; |
| 2340: | |
| 2341: | |
| 2342: | if(!$hasEssentialModuleActivated) return ''; |
| 2343: | |
| 2344: | $serverList = null; |
| 2345: | |
| 2346: | if(class_exists('Nux_Quick_Services')){ |
| 2347: | $serverList = Nux_Quick_Services::option_list(false, $this); |
| 2348: | } |
| 2349: | |
| 2350: | $hideClass = 'd-none'; |
| 2351: | |
| 2352: | |
| 2353: | if($hasImapActivated || $hasSmtpActivated || $hasJmapActivated){ |
| 2354: | $hideClass = ''; |
| 2355: | } |
| 2356: | |
| 2357: | $res = '<div class="smtp_imap_server_setup '. $hideClass .'"> |
| 2358: | <div data-target=".server_config_section" class="server_section border-bottom cursor-pointer px-1 py-3 pe-auto"> |
| 2359: | <a href="#" class="pe-auto"> |
| 2360: | <i class="bi bi-envelope-fill me-3"></i> |
| 2361: | <b> '.$accordionTitle.'</b> |
| 2362: | </a> |
| 2363: | <div class="server_count">'.$configuredText.'</div> |
| 2364: | </div> |
| 2365: | <div class="server_config_section px-4 pt-3 me-0"> |
| 2366: | <div class="stepper col-12 col-xl-7 mb-4" id="srv_setup_stepper_stepper"> |
| 2367: | <div class="step-container"> |
| 2368: | <div id="step_config_1" class="step step_config"> |
| 2369: | <div class="step_config-title"> |
| 2370: | <h2>'.$this->trans('Step 1').'</h2> |
| 2371: | <span>('.$this->trans('Authentication').')</span> |
| 2372: | </div> |
| 2373: | <div> |
| 2374: | <form class=" me-0" method="POST"> |
| 2375: | <input type="hidden" name="hm_page_key" value="'.$this->html_safe(Hm_Request_Key::generate()).'" /> |
| 2376: | <input type="hidden" name="srv_setup_stepper_imap_server_id" id="srv_setup_stepper_imap_server_id" /> |
| 2377: | <input type="hidden" name="srv_setup_stepper_smtp_server_id" id="srv_setup_stepper_smtp_server_id" /> |
| 2378: | <div class="form-floating mb-3"> |
| 2379: | <input required type="text" id="srv_setup_stepper_profile_name" name="srv_setup_stepper_profile_name" class="txt_fld form-control" value="" placeholder="'.$this->trans('Name').'"> |
| 2380: | <label class="" for="srv_setup_stepper_profile_name">'.$this->trans('Name').'</label> |
| 2381: | <span id="srv_setup_stepper_profile_name-error" class="invalid-feedback"></span> |
| 2382: | </div> |
| 2383: | <div class="form-floating mb-3"> |
| 2384: | <input required type="text" id="srv_setup_stepper_email" name="srv_setup_stepper_email" class="txt_fld form-control warn_on_paste" value="" placeholder="'.$this->trans('Email or Username').'" autocomplete="username"> |
| 2385: | <label class="" for="srv_setup_stepper_email">'.$this->trans('Email or Username').'</label> |
| 2386: | <span id="srv_setup_stepper_email-error" class="invalid-feedback"></span> |
| 2387: | </div> |
| 2388: | <div class="form-floating mb-3"> |
| 2389: | <input required type="password" id="srv_setup_stepper_password" name="srv_setup_stepper_password" class="txt_fld form-control warn_on_paste" value="" placeholder="'.$this->trans('Password').'" autocomplete="new-password"> |
| 2390: | <label class="" for="srv_setup_stepper_password">'.$this->trans('Password').'</label> |
| 2391: | <span id="srv_setup_stepper_password-error" class="invalid-feedback"></span> |
| 2392: | </div> |
| 2393: | </form> |
| 2394: | </div> |
| 2395: | <div class="step_config-actions mt-4 d-flex justify-content-between"> |
| 2396: | <button class="btn btn-primary px-5" onclick="display_config_step(0);resetQuickSetupForm();">'.$this->trans('Cancel').'</button> |
| 2397: | <button class="btn btn-primary px-5" id="step_config_action_next" onclick="display_config_step(2)">'.$this->trans('Next').'</button> |
| 2398: | </div> |
| 2399: | </div> |
| 2400: | <div id="step_config_2" class="step step_config"> |
| 2401: | <div class="step_config-title"> |
| 2402: | <h2>'.$this->trans('Step 2').'</h2> |
| 2403: | <span>('.$this->trans('Mail server configuration').')</span> |
| 2404: | </div> |
| 2405: | <div> |
| 2406: | <form> |
| 2407: | <div class="form-floating mb-3"> |
| 2408: | <select class="form-select" id="srv_setup_stepper_provider" onchange="handleProviderChange(this)" label="'.$this->trans('Provider').'"> |
| 2409: | <option value="">'.$this->trans('Other').'</option>'.$serverList.' |
| 2410: | </select> |
| 2411: | <label for="srv_setup_stepper_provider">'.$this->trans('Provider').'</label> |
| 2412: | </div>'; |
| 2413: | |
| 2414: | if($hasSmtpActivated && $hasImapActivated) { |
| 2415: | $res .= ' |
| 2416: | <div class="form-check form-switch"> |
| 2417: | <input class="form-check-input" type="checkbox" role="switch" onchange="handleSmtpImapCheckboxChange(this)" id="srv_setup_stepper_is_sender" checked> |
| 2418: | <label class="form-check-label" for="srv_setup_stepper_is_sender">'.$this->trans('Sender account').'</label> |
| 2419: | </div> |
| 2420: | <div class="form-check form-switch"> |
| 2421: | <input class="form-check-input" type="checkbox" role="switch" onchange="handleSmtpImapCheckboxChange(this)" id="srv_setup_stepper_is_receiver" checked> |
| 2422: | <label class="form-check-label" for="srv_setup_stepper_is_receiver">'.$this->trans('Receiver account').'</label> |
| 2423: | </div> |
| 2424: | <span id="srv_setup_stepper_serve_type-error" class="invalid-feedback"></span> |
| 2425: | '; |
| 2426: | } |
| 2427: | |
| 2428: | $res .= '<div class="step_config-smtp_imap_bloc">'; |
| 2429: | |
| 2430: | return $res; |
| 2431: | } |
| 2432: | } |
| 2433: | |
| 2434: | class Hm_Output_server_config_stepper_end_part extends Hm_Output_Module { |
| 2435: | protected function output() { |
| 2436: | $res = '</div>'; |
| 2437: | |
| 2438: | if(in_array('profiles', $this->get('router_module_list'), true)) { |
| 2439: | $res .= ' |
| 2440: | <div class="form-check form-switch mt-3" id="srv_setup_stepper_profile_checkbox_bloc"> |
| 2441: | <input class="form-check-input" type="checkbox" role="switch" onchange="handleCreateProfileCheckboxChange(this)" id="srv_setup_stepper_create_profile" checked> |
| 2442: | <label class="form-check-label" for="srv_setup_stepper_create_profile">'.$this->trans('Create Profile').'</label> |
| 2443: | </div> |
| 2444: | <div class="ms-3" id="srv_setup_stepper_profile_bloc"> |
| 2445: | <div class="form-floating mb-2"> |
| 2446: | <input required type="text" id="srv_setup_stepper_profile_reply_to" name="srv_setup_stepper_profile_reply_to" class="txt_fld form-control" value="" placeholder="'.$this->trans('Reply to').'"> |
| 2447: | <label class="" for="srv_setup_stepper_profile_reply_to">'.$this->trans('Reply to').'</label> |
| 2448: | </div> |
| 2449: | <div class="form-floating mb-2"> |
| 2450: | <input required type="text" id="srv_setup_stepper_profile_signature" name="srv_setup_stepper_profile_signature" class="txt_fld form-control" value="" placeholder="'.$this->trans('Signature').'"> |
| 2451: | <label class="" for="srv_setup_stepper_profile_signature">'.$this->trans('Signature').'</label> |
| 2452: | </div> |
| 2453: | <div class="form-check" id="srv_setup_stepper_profile_checkbox_bloc"> |
| 2454: | <input class="form-check-input" type="checkbox" role="switch" id="srv_setup_stepper_profile_is_default" checked> |
| 2455: | <label class="form-check-label" for="srv_setup_stepper_profile_is_default">'.$this->trans('Set this profile default').'</label> |
| 2456: | </div> |
| 2457: | </div> |
| 2458: | '; |
| 2459: | } |
| 2460: | |
| 2461: | $res .= '</form> |
| 2462: | </div> |
| 2463: | <div class="step_config-actions mt-4 d-flex justify-content-between"> |
| 2464: | <button class="btn btn-danger px-3" onclick="display_config_step(0);resetQuickSetupForm();">'.$this->trans('Cancel').'</button> |
| 2465: | <button class="btn btn-primary px-4" onclick="display_config_step(1)">'.$this->trans('Previous').'</button> |
| 2466: | <button class="btn btn-primary px-3" id="step_config_action_finish" onclick="display_config_step(3)" id="stepper-action-finish">'.$this->trans('Finish').'</button> |
| 2467: | </div> |
| 2468: | </div> |
| 2469: | <div id="step_config_0" class="step_config current_config_step"> |
| 2470: | <button class="imap-jmap-smtp-btn btn btn-primary px-4" id="add_new_server_button" onclick="display_config_step(1)"><i class="bi bi-plus-square-fill me-2"></i> '.$this->trans('Add a new server').'</button> |
| 2471: | </div> |
| 2472: | </div> |
| 2473: | </div> |
| 2474: | <div class="d-block">'; |
| 2475: | |
| 2476: | return $res; |
| 2477: | } |
| 2478: | } |
| 2479: | |
| 2480: | class Hm_Output_server_config_stepper_accordion_end_part extends Hm_Output_Module { |
| 2481: | protected function output() { |
| 2482: | return '</div></div></div>'; |
| 2483: | } |
| 2484: | } |
| 2485: | |
| 2486: | class Hm_Output_privacy_settings extends Hm_Output_Module { |
| 2487: | static $settings = [ |
| 2488: | 'images_whitelist' => [ |
| 2489: | 'type' => 'text', |
| 2490: | 'label' => 'External images whitelist', |
| 2491: | 'description' => 'Cypht automatically prevents untrusted external images from loading in messages. Add senders from whom you want to allow images to load.', |
| 2492: | 'separator' => ',' |
| 2493: | ] |
| 2494: | ]; |
| 2495: | |
| 2496: | protected function output() |
| 2497: | { |
| 2498: | return getSettingsSectionOutput('privacy', $this->trans('Privacy'), 'shield', self::$settings, $this->get('user_settings', array())); |
| 2499: | } |
| 2500: | } |
| 2501: | |
| 2502: | class Hm_output_combined_message_list extends Hm_Output_Module { |
| 2503: | protected function output() { |
| 2504: | $messageList = []; |
| 2505: | $style = $this->get('news_list_style') || $this->get('is_mobile') ? 'news' : 'email'; |
| 2506: | if ($this->get('imap_combined_inbox_data')) { |
| 2507: | $messageList = array_merge($messageList, format_imap_message_list($this->get('imap_combined_inbox_data'), $this, 'combined_inbox', $style)); |
| 2508: | } |
| 2509: | if ($this->get('feed_list_data')) { |
| 2510: | $messageList = array_merge($messageList, $this->get('feed_list_data'), Hm_Output_filter_feed_list_data::formatMessageList($this)); |
| 2511: | } |
| 2512: | $this->out('formatted_message_list', $messageList); |
| 2513: | } |
| 2514: | } |
| 2515: | |