1: <?php
2:
3: /**
4: * IMAP folder management
5: * @package modules
6: * @subpackage imap_folders
7: */
8:
9: if (!defined('DEBUG_MODE')) { die(); }
10:
11: // require_once APP_PATH.'modules/sievefilters/modules.php';
12:
13: /**
14: * @subpackage imap_folders/handler
15: */
16: class Hm_Handler_fix_folder_assignments extends Hm_Handler_Module {
17: public function process() {
18: /* only run on login */
19: if (!$this->session->loaded) {
20: return;
21: }
22: /* check for already fixed settings */
23: $specials = $this->user_config->get('special_imap_folders', array());
24: if (count($specials) == 0 || array_key_exists('imap_server', reset($specials))) {
25: return;
26: }
27: $updated = array();
28: $count = 0;
29:
30: /* update special folders with imap details */
31: foreach ($specials as $index => $vals) {
32: if (!array_key_exists('imap_server', $vals)) {
33: $count++;
34: $server = Hm_IMAP_List::dump($index);
35: if (!is_array($server) || !array_key_exists('server', $server)) {
36: continue;
37: }
38: $vals['imap_user'] = $server['user'];
39: $vals['imap_server'] = $server['server'];
40: $updated[$index] = $vals;
41: }
42: }
43:
44: /* save permanently if we updated anything */
45: if ($count) {
46: $this->user_config->set('special_imap_folders', $updated);
47: $this->user_config->save_on_login = true;
48: }
49: }
50: }
51:
52: /**
53: * @subpackage imap_folders/handler
54: */
55: class Hm_Handler_add_folder_manage_link extends Hm_Handler_Module {
56: public function process() {
57: $server = false;
58: $folder = false;
59: if (array_key_exists('imap_server_id', $this->request->post)) {
60: $server = $this->request->post['imap_server_id'];
61: }
62: if (array_key_exists('folder', $this->request->post)) {
63: $folder = $this->request->post['folder'];
64: }
65: if (($server || $server === 0) && !$folder) {
66: $this->out('imap_folder_manage_link', sprintf('?page=folders&imap_server_id=%s', $server));
67: }
68: }
69: }
70:
71: /**
72: * @subpackage imap_folders/handler
73: */
74: class Hm_Handler_process_clear_special_folder extends Hm_Handler_Module {
75: public function process() {
76: list($success, $form) = $this->process_form(array('special_folder_type', 'imap_server_id'));
77: if (!$success || !in_array($form['special_folder_type'], array('sent', 'draft', 'trash', 'archive'), true)) {
78: return;
79: }
80: $specials = $this->user_config->get('special_imap_folders', array());
81: if (array_key_exists($form['imap_server_id'], $specials)) {
82: $specials[$form['imap_server_id']][$form['special_folder_type']] = '';
83: }
84: $this->user_config->set('special_imap_folders', $specials);
85:
86: Hm_Msgs::add('Special folder unassigned');
87: $this->session->record_unsaved('Special folder unassigned');
88: $this->out('imap_special_name', '');
89: }
90: }
91:
92: /**
93: * @subpackage imap_folders/handler
94: */
95: class Hm_Handler_process_special_folder extends Hm_Handler_Module {
96: public function process() {
97: list($success, $form) = $this->process_form(array('special_folder_type', 'folder', 'imap_server_id'));
98: if (!$success || !in_array($form['special_folder_type'], array('sent', 'draft', 'trash', 'archive', 'junk'), true)) {
99: return;
100: }
101: $mailbox = Hm_IMAP_List::get_connected_mailbox($form['imap_server_id'], $this->cache);
102: if (!is_object($mailbox) || ! $mailbox->authed()) {
103: Hm_Msgs::add('Unable to connect to the selected IMAP server', 'danger');
104: return;
105: }
106: $new_folder = $mailbox->prep_folder_name($form['folder']);
107: if (! $new_folder || ! $mailbox->get_folder_status($new_folder)) {
108: Hm_Msgs::add('Selected folder not found', 'warning');
109: return;
110: }
111: $specials = $this->user_config->get('special_imap_folders', array());
112: if (!array_key_exists($form['imap_server_id'], $specials)) {
113: $specials[$form['imap_server_id']] = array('sent' => '', 'draft' => '', 'trash' => '', 'archive' => '', 'junk' => '');
114: }
115: $specials[$form['imap_server_id']][$form['special_folder_type']] = $new_folder;
116: $this->user_config->set('special_imap_folders', $specials);
117:
118: Hm_Msgs::add('Special folder assigned');
119:
120: $this->session->record_unsaved('Special folder assigned');
121: $this->out('imap_special_name', $new_folder);
122: }
123: }
124:
125: /**
126: * @subpackage imap_folders/handler
127: */
128: class Hm_Handler_process_accept_special_folders extends Hm_Handler_Module {
129: public function process() {
130:
131: list($success, $form) = $this->process_form(array('imap_server_id', 'imap_service_name'));
132: if ($success) {
133: $mailbox = Hm_IMAP_List::get_connected_mailbox($form['imap_server_id'], $this->cache);
134: if (!is_object($mailbox) || ! $mailbox->authed()) {
135: Hm_Msgs::add('Unable to connect to the selected IMAP server', 'danger');
136: return;
137: }
138: $specials = $this->user_config->get('special_imap_folders', array());
139: $exposed = $mailbox->get_special_use_mailboxes();
140: if ($form['imap_service_name'] == 'gandi') {
141: $specials[$form['imap_server_id']] = array(
142: 'sent' => 'Sent',
143: 'draft' => 'Drafts',
144: 'trash' => 'Trash',
145: 'archive' => 'Archive',
146: 'junk' => 'Junk'
147: );
148: } else {
149: $specials[$form['imap_server_id']] = array(
150: 'sent' => $exposed['sent'] ?? '',
151: 'draft' => $exposed['drafts'] ?? '',
152: 'trash' => $exposed['trash'] ?? '',
153: 'archive' => $exposed['archive'] ?? '',
154: 'junk' => $exposed['junk'] ?? ''
155: );
156: }
157: $this->user_config->set('special_imap_folders', $specials);
158:
159: $user_data = $this->user_config->dump();
160: $this->session->set('user_data', $user_data);
161:
162: Hm_Msgs::add('Special folders assigned');
163: $this->session->record_unsaved('Special folders assigned');
164: $this->session->close_early();
165: }
166: }
167: }
168:
169: /**
170: * @subpackage imap_folders/handler
171: */
172: class Hm_Handler_process_folder_create extends Hm_Handler_Module {
173: public function process() {
174: list($success, $form) = $this->process_form(array('folder', 'imap_server_id'));
175: if ($success) {
176: $parent = false;
177: if (array_key_exists('parent', $this->request->post) && trim($this->request->post['parent'])) {
178: $parent = decode_folder_str($this->request->post['parent']);
179: }
180: $mailbox = Hm_IMAP_List::get_connected_mailbox($form['imap_server_id'], $this->cache);
181: if ($mailbox && $mailbox->authed()) {
182: if ($form['folder'] && $mailbox->create_folder($form['folder'], $parent)) {
183: Hm_Msgs::add('Folder created');
184: $this->cache->del('imap_folders_imap_'.$form['imap_server_id'].'_');
185: $this->out('imap_folders_success', true);
186: }
187: else {
188: Hm_Msgs::add('Failed to create folder '.$form['folder'].'. It might already exist. Please check and try again.', 'danger');
189: }
190: }
191: }
192: }
193: }
194:
195: /**
196: * @subpackage imap_folders/handler
197: */
198: class Hm_Handler_process_folder_rename extends Hm_Handler_Module {
199: public function process() {
200: list($success, $form) = $this->process_form(array('imap_server_id', 'folder', 'new_folder'));
201: if ($success) {
202: $parent = false;
203: if (array_key_exists('parent', $this->request->post)) {
204: $parent = $this->request->post['parent'];
205: }
206: $mailbox = Hm_IMAP_List::get_connected_mailbox($form['imap_server_id'], $this->cache);
207: if ($mailbox && $mailbox->authed()) {
208: if ($form['folder'] && $form['new_folder'] && $mailbox->rename_folder($form['folder'], $form['new_folder'], $parent)) {
209: Hm_Msgs::add('Folder renamed');
210: $this->cache->del('imap_folders_imap_'.$form['imap_server_id'].'_');
211: $this->out('imap_folders_success', true);
212: }
213: else {
214: Hm_Msgs::add('An error occurred renaming the folder', 'danger');
215: }
216: }
217: }
218: }
219: }
220:
221: /**
222: * @subpackage imap_folders/handler
223: */
224: class Hm_Handler_process_folder_delete extends Hm_Handler_Module {
225: public function process() {
226: list($success, $form) = $this->process_form(array('imap_server_id', 'folder'));
227: if ($success) {
228: $mailbox = Hm_IMAP_List::get_connected_mailbox($form['imap_server_id'], $this->cache);
229: if ($mailbox && $mailbox->authed()) {
230: if ($this->get('sieve_can_delete_folder') === false) {
231: return;
232: }
233: if ($form['folder'] && $mailbox->delete_folder($form['folder'])) {
234: Hm_Msgs::add('Folder deleted');
235: $this->cache->del('imap_folders_imap_'.$form['imap_server_id'].'_');
236: $this->out('imap_folders_success', true);
237: }
238: else {
239: Hm_Msgs::add('An error occurred deleting the folder', 'danger');
240: }
241: }
242: }
243: }
244: }
245:
246: /**
247: * @subpackage imap_folders/handler
248: */
249: class Hm_Handler_special_folders extends Hm_Handler_Module {
250: public function process() {
251: if (array_key_exists('imap_server_id', $this->request->get)) {
252: $specials = $this->user_config->get('special_imap_folders', array());
253: if (array_key_exists($this->request->get['imap_server_id'], $specials)) {
254: $this->out('sent_folder', $specials[$this->request->get['imap_server_id']]['sent']);
255: $this->out('trash_folder', $specials[$this->request->get['imap_server_id']]['trash']);
256: $this->out('archive_folder', $specials[$this->request->get['imap_server_id']]['archive']);
257: $this->out('draft_folder', $specials[$this->request->get['imap_server_id']]['draft']);
258: $this->out('junk_folder', $specials[$this->request->get['imap_server_id']]['junk']);
259: $mailbox = Hm_IMAP_List::get_connected_mailbox($this->request->get['imap_server_id'], $this->cache);
260: if ($mailbox && $mailbox->authed()) {
261: $folder_names = [];
262: foreach ($specials[$this->request->get['imap_server_id']] as $name => $folder) {
263: $folder_names[$name] = $mailbox->get_folder_name($folder);
264: }
265: $this->out('special_folder_names', $folder_names);
266: }
267: }
268: }
269: else {
270: $this->out('special_imap_folders', $this->user_config->get('special_imap_folders'));
271: }
272: }
273: }
274:
275: /**
276: * @subpackage imap_folders/handler
277: */
278: class Hm_Handler_folders_server_id extends Hm_Handler_Module {
279: public function process() {
280: if (array_key_exists('imap_server_id', $this->request->get)) {
281: $this->out('folder_server', $this->request->get['imap_server_id']);
282: $this->out('page', $this->request->get['page']);
283: $this->out('trigger_default_submit', false);
284: }
285: }
286: }
287:
288: /**
289: * @subpackage imap_folders/handler
290: */
291: class Hm_Handler_imap_folder_check extends Hm_Handler_Module {
292: public function process() {
293: $this->out('imap_support', $this->module_is_supported('imap'));
294: }
295: }
296:
297: /**
298: * @subpackage imap_folders/handler
299: */
300: class Hm_Handler_process_imap_folder_subscription extends Hm_Handler_Module {
301: public function process() {
302: list($success, $form) = $this->process_form(array('folder', 'subscription_state'));
303: if ($success) {
304: $imap_server_id = $this->request->get['imap_server_id'];
305: $mailbox = Hm_IMAP_List::get_connected_mailbox($imap_server_id, $this->cache);
306: if ($mailbox && $mailbox->authed()) {
307: $folder = hex2bin($form['folder']);
308: $success = $mailbox->folder_subscription($folder, $form['subscription_state']);
309: if ($success) {
310: Hm_Msgs::add(sprintf('%s to %s', $form['subscription_state']? 'Subscribed': 'Unsubscribed', $mailbox->get_folder_name($folder)));
311: $this->cache->del('imap_folders_imap_'.$imap_server_id.'_');
312: } else {
313: Hm_Msgs::add(sprintf('An error occurred %s to %s', $form['subscription_state']? 'subscribing': 'unsubscribing', $folder), 'danger');
314: }
315: $this->out('imap_folder_subscription', $success);
316: }
317: }
318: }
319: }
320:
321: /**
322: * Process input from the folder subscription setting in the settings page
323: * @subpackage imap/handler
324: */
325: class Hm_Handler_process_only_subscribed_folders_setting extends Hm_Handler_Module {
326: public function process() {
327: function only_subscribed_folders_setting_callback($val) {
328: return $val;
329: }
330: process_site_setting('only_subscribed_folders', $this, 'only_subscribed_folders_setting_callback', false, true);
331: }
332: }
333:
334: /**
335: * @subpackage imap_folders/output
336: */
337: class Hm_Output_folders_server_select extends Hm_Output_Module {
338: protected function output() {
339: $server_id = $this->get('folder_server', '');
340: $data_auto_submit = !empty($this->get('trigger_default_submit')) ? ' data-auto-submit="1"' : 'data-auto-submit="0"';
341: $res = '<div class="folders_page mt-4 row mb-4"><div class="col-xl-6 col-sm-12"><form id="form_folder_imap" method="get"'.$data_auto_submit.'>';
342: $res .= '<input type="hidden" name="page" value="'.$this->get('page', 'folders').'" />';
343: $res .= '<div class="form-floating"><select class="form-select" id="imap_server_folder" name="imap_server_id">';
344: $res .= '<option ';
345: if (empty($server_id)) {
346: $res .= 'selected="selected" ';
347: }
348: $res .= 'value="">'.$this->trans('Select a Mail Account').'</option>';
349: foreach ($this->get('imap_servers', array()) as $id => $server) {
350: $res .= '<option ';
351: if ($server_id == $id) {
352: $res .= 'selected="selected" ';
353: }
354: $res .= 'value="'.$this->html_safe($id).'">';
355: $res .= $this->html_safe($server['name']);
356: }
357: $res .= '</select><label for="imap_server_folder">'.$this->trans('Mail Account').'</label></div></form></div></div>';
358: $res .= '<input type="hidden" id="server_error" value="'.$this->trans('You must select a mail account first').'" />';
359: $res .= '<input type="hidden" id="folder_name_error" value="'.$this->trans('New folder name is required').'" />';
360: $res .= '<input type="hidden" id="delete_folder_error" value="'.$this->trans('Folder to delete is required').'" />';
361: $res .= '<input type="hidden" id="delete_folder_confirm" value="'.$this->trans('Are you sure you want to delete this folder, and all the messages in it?').'" />';
362: $res .= '<input type="hidden" id="rename_folder_error" value="'.$this->trans('Folder to rename is required').'" />';
363: return $res;
364: }
365: }
366:
367: /**
368: * @subpackage imap_folders/output
369: */
370: class Hm_Output_folders_delete_dialog extends Hm_Output_Module {
371: protected function output() {
372: if ($this->get('folder_server') !== NULL) {
373: $res = '<div class="row m-0 px-3 mt-3">';
374: $res .= '<div data-target=".delete_dialog" class="settings_subtitle col-12 border-bottom px-0">
375: <a href="#" class="pe-auto"><i class="bi bi-folder-x fs-5 me-2"></i>'.$this->trans('Delete a Folder').'</a>
376: </div>';
377: $res .= '<div class="delete_dialog folder_dialog col-lg-4 col-md-6 col-sm-12 py-1 px-0">
378: <div class="folder_row">
379: <a href="#" class="select_delete_folder">'.$this->trans('Select Folder').'</a>:
380: <span class="selected_delete"></span>
381: </div>
382: <ul class="folders delete_folder_select">
383: <li class="delete_title">
384: <a href="#" class="close">'.$this->trans('Cancel').'</a>
385: </li>
386: </ul>
387: <input type="hidden" value="" id="children_number" />
388: <input type="hidden" value="" id="delete_source" />
389: <input type="button" id="delete_folder" class="btn btn-danger" value="'.$this->trans('Delete').'">
390: </div></div>';
391:
392: return $res;
393: }
394: }
395: }
396:
397: /**
398: * @subpackage imap_folders/output
399: */
400: class Hm_Output_folders_rename_dialog extends Hm_Output_Module {
401: protected function output() {
402: if ($this->get('folder_server') !== NULL) {
403: $res = '<div class="row m-0 px-3 mt-3">
404: <div data-target=".rename_dialog" class="settings_subtitle col-12 border-bottom px-0">
405: <a href="#" class="pe-auto"><i class="bi bi-folder-check fs-5 me-2"></i>'.$this->trans('Rename a Folder').'</a>
406: </div>
407: <div class="rename_dialog folder_dialog col-lg-4 col-md-6 col-sm-12 py-3 px-0">
408: <div class="folder_row">
409: <a href="#" class="select_rename_folder">'.$this->trans('Select Folder').'</a>:
410: <span class="selected_rename"></span>
411: </div>
412: <div class="form-floating mb-3">
413: <input id="rename_value" type="text" class="form-control" value="" placeholder="'.$this->trans('New Folder Name').'">
414: <label for="rename_value">'.$this->trans('New Folder Name').'</label>
415: </div>
416: <ul class="folders rename_folder_select">
417: <li class="rename_title">
418: <a href="#" class="close">'.$this->trans('Cancel').'</a>
419: </li>
420: </ul>
421: <div class="folder_row">
422: <a href="#" class="select_rename_parent_folder">'.$this->trans('Select Parent Folder (optional)').'</a>:
423: <span class="selected_rename_parent"></span>
424: </div>
425: <ul class="folders rename_parent_folder_select">
426: <li class="rename_parent_title">
427: <a href="#" class="close">'.$this->trans('Cancel').'</a>
428: </li>
429: </ul>
430: <input type="hidden" value="" id="rename_parent_source" />
431: <input type="hidden" value="" id="rename_source" />
432: <input type="button" id="rename_folder" class="btn btn-primary" value="'.$this->trans('Rename').'">
433: </div>
434: </div>';
435:
436: return $res;
437: }
438: }
439: }
440:
441: /**
442: * @subpackage imap_folders/output
443: */
444: class Hm_Output_folders_sent_dialog extends Hm_Output_Module {
445: protected function output() {
446: if ($this->get('folder_server') === NULL) {
447: return;
448: }
449:
450: $sent_folder = $this->get('sent_folder', $this->trans('Not set'));
451: if (! $sent_folder) {
452: $folder_name = $this->trans('Not set');
453: } else {
454: $folder_name = $this->get('special_folder_names')['sent'] ?? $sent_folder;
455: }
456:
457: $res = '<div class="row m-0 px-3 mt-3">';
458: $res .= '<div data-target=".sent_folder_dialog" class="settings_subtitle col-12 border-bottom px-0">
459: <a href="#" class="pe-auto"><i class="bi bi-send-check-fill fs-5 me-2"></i>'.$this->trans('Sent Folder').':<span id="sent_val">'.$folder_name.'</span></a>
460: </div>';
461: $res .= '<div class="folder_dialog sent_folder_dialog col-lg-6 col-md-6 col-sm-12 py-3 px-0">
462: <div class="folder_row">
463: <div class="sp_description">'.$this->trans('If set, a copy of outbound mail sent with a profile tied to this IMAP account, will be saved in this folder').'</div>
464: </div>
465: <div class="folder_row">
466: <a href="#" class="select_sent_folder">'.$this->trans('Select Folder').'</a>:
467: <span class="selected_sent"></span>
468: </div>
469: <ul class="folders sent_folder_select">
470: <li class="sent_title">
471: <a href="#" class="close">'.$this->trans('Cancel').'</a>
472: </li>
473: </ul>
474: <input type="hidden" value="" id="sent_source" />
475: <div class="btn-group mt-3" role="group" aria-label="Sent Folder Actions">
476: <input type="button" id="set_sent_folder" class="btn btn-primary" value="'.$this->trans('Update').'" />
477: <input type="button" id="clear_sent_folder" class="btn btn-secondary" value="'.$this->trans('Remove').'" />
478: </div>
479: <br /><br />
480: </div>
481: </div>';
482:
483: return $res;
484: }
485: }
486:
487: /**
488: * @subpackage imap_folders/output
489: */
490: class Hm_Output_folders_archive_dialog extends Hm_Output_Module {
491: protected function output() {
492: if ($this->get('folder_server') === NULL) {
493: return;
494: }
495:
496: $archive_folder = $this->get('archive_folder', $this->trans('Not set'));
497: if (! $archive_folder) {
498: $folder_name = $this->trans('Not set');
499: } else {
500: $folder_name = $this->get('special_folder_names')['archive'] ?? $archive_folder;
501: }
502:
503: $res = '<div class="row m-0 px-3 mt-3">';
504: $res .= '<div data-target=".archive_folder_dialog" class="settings_subtitle col-12 border-bottom px-0">
505: <a href="#" class="pe-auto"><i class="bi bi-archive fs-5 me-2"></i>'.$this->trans('Archive Folder').':<span id="archive_val">'.$folder_name.'</span></a>
506: </div>';
507: $res .= '<div class="folder_dialog archive_folder_dialog col-lg-6 col-md-6 col-sm-12 py-3 px-0">
508: <div class="folder_row">
509: <div class="sp_description">'.$this->trans('If set, archived messages for this account will be moved to this folder').'</div>
510: </div>
511: <div class="folder_row">
512: <a href="#" class="select_archive_folder">'.$this->trans('Select Folder').'</a>:
513: <span class="selected_archive"></span>
514: </div>
515: <ul class="folders archive_folder_select">
516: <li class="archive_title">
517: <a href="#" class="close">'.$this->trans('Cancel').'</a>
518: </li>
519: </ul>
520: <input type="hidden" value="" id="archive_source" />
521: <div class="btn-group mt-3" role="group" aria-label="Archive Folder Actions">
522: <input type="button" id="set_archive_folder" class="btn btn-primary" value="'.$this->trans('Update').'" />
523: <input type="button" id="clear_archive_folder" class="btn btn-secondary" value="'.$this->trans('Remove').'" />
524: </div>
525: <br /><br />
526: </div>
527: </div>';
528:
529: return $res;
530: }
531: }
532:
533: /**
534: * @subpackage imap_folders/output
535: */
536: class Hm_Output_folders_draft_dialog extends Hm_Output_Module {
537: protected function output() {
538: if ($this->get('folder_server') === NULL) {
539: return;
540: }
541:
542: $draft_folder = $this->get('draft_folder', $this->trans('Not set'));
543: if (! $draft_folder) {
544: $folder_name = $this->trans('Not set');
545: } else {
546: $folder_name = $this->get('special_folder_names')['draft'] ?? $draft_folder;
547: }
548:
549: $res = '<div class="row m-0 px-3 mt-3">';
550: $res .= '<div data-target=".draft_folder_dialog" class="settings_subtitle col-12 border-bottom px-0">
551: <a href="#" class="pe-auto"><i class="bi bi-pencil-square fs-5 me-2"></i>'.$this->trans('Draft Folder').':<span id="draft_val">'.$folder_name.'</span></a>
552: </div>';
553: $res .= '<div class="folder_dialog draft_folder_dialog col-lg-6 col-md-6 col-sm-12 py-3 px-0">
554: <div class="folder_row">
555: <div class="sp_description">'.$this->trans('If set, drafts will be saved in this folder').'</div>
556: </div>
557: <div class="folder_row">
558: <a href="#" class="select_draft_folder">'.$this->trans('Select Folder').'</a>:
559: <span class="selected_draft"></span>
560: </div>
561: <ul class="folders draft_folder_select">
562: <li class="draft_title">
563: <a href="#" class="close">'.$this->trans('Cancel').'</a>
564: </li>
565: </ul>
566: <input type="hidden" value="" id="draft_source" />
567: <div class="btn-group mt-3" role="group" aria-label="Draft Folder Actions">
568: <input type="button" id="set_draft_folder" class="btn btn-primary" value="'.$this->trans('Update').'" />
569: <input type="button" id="clear_draft_folder" class="btn btn-secondary" value="'.$this->trans('Remove').'" />
570: </div>
571: <br /><br />
572: </div>
573: </div>';
574:
575: return $res;
576: }
577: }
578:
579: /**
580: * @subpackage imap_folders/output
581: */
582: class Hm_Output_folders_trash_dialog extends Hm_Output_Module {
583: protected function output() {
584: if ($this->get('folder_server') === NULL) {
585: return;
586: }
587:
588: $trash_folder = $this->get('trash_folder', $this->trans('Not set'));
589: if (! $trash_folder) {
590: $folder_name = $this->trans('Not set');
591: } else {
592: $folder_name = $this->get('special_folder_names')['trash'] ?? $trash_folder;
593: }
594:
595: $res = '<div class="row m-0 px-3 mt-3">';
596: $res .= '<div data-target=".trash_folder_dialog" class="settings_subtitle col-12 border-bottom px-0">
597: <a href="#" class="pe-auto"><i class="bi bi-trash3 fs-5 me-2"></i>'.$this->trans('Trash Folder').':<span id="trash_val">'.$folder_name.'</span></a>
598: </div>';
599: $res .= '<input type="hidden" id="not_set_string" value="'.$this->trans('Not set').'" />';
600: $res .= '<div class="folder_dialog trash_folder_dialog col-lg-6 col-md-6 col-sm-12 py-3 px-0">
601: <div class="sp_description">'.$this->trans('If set, deleted messages for this account will be moved to this folder').'</div>
602: <div class="folder_row">
603: <a href="#" class="select_trash_folder">'.$this->trans('Select Folder').'</a>:
604: <span class="selected_trash"></span>
605: </div>
606: <ul class="folders trash_folder_select">
607: <li class="trash_title">
608: <a href="#" class="close">'.$this->trans('Cancel').'</a>
609: </li>
610: </ul>
611: <input type="hidden" value="" id="trash_source" />
612: <div class="btn-group mt-1" role="group" aria-label="Trash Folder Actions">
613: <input type="button" id="set_trash_folder" class="btn btn-primary" value="'.$this->trans('Update').'" />
614: <input type="button" id="clear_trash_folder" class="btn btn-secondary" value="'.$this->trans('Remove').'" />
615: </div>
616: </div></div>';
617:
618: return $res;
619: }
620: }
621:
622: /**
623: * @subpackage imap_folders/output
624: */
625: class Hm_Output_folders_junk_dialog extends Hm_Output_Module {
626: protected function output() {
627: if ($this->get('folder_server') === NULL) {
628: return;
629: }
630:
631: $junk_folder = $this->get('junk_folder', $this->trans('Not set'));
632: if (! $junk_folder) {
633: $folder_name = $this->trans('Not set');
634: } else {
635: $folder_name = $this->get('special_folder_names')['junk'] ?? $junk_folder;
636: }
637:
638: $res = '<div class="row m-0 px-3 mt-3">';
639: $res .= '<div data-target=".junk_folder_dialog" class="settings_subtitle col-12 border-bottom px-0">
640: <a href="#" class="pe-auto"><i class="bi bi-envelope-x-fill fs-5 me-2"></i>'.$this->trans('Junk Folder').':<span id="junk_val">'.$folder_name.'</span></a>
641: </div>';
642:
643: $res .= '<input type="hidden" id="not_set_string" value="'.$this->trans('Not set').'" />';
644: $res .= '<div class="folder_dialog junk_folder_dialog col-lg-6 col-md-6 col-sm-12 py-3 px-0">
645: <div class="sp_description">'.$this->trans('If set, spams will be saved in this folder').'</div>
646: <div class="folder_row">
647: <a href="#" class="select_junk_folder">'.$this->trans('Select Folder').'</a>:
648: <span class="selected_junk"></span>
649: </div>
650: <ul class="folders junk_folder_select">
651: <li class="junk_title">
652: <a href="#" class="close">'.$this->trans('Cancel').'</a>
653: </li>
654: </ul>
655: <input type="hidden" value="" id="junk_source" />
656: <div class="btn-group mt-3" role="group" aria-label="Junk Folder Actions">
657: <input type="button" id="set_junk_folder" class="btn btn-primary" value="'.$this->trans('Update').'" />
658: <input type="button" id="clear_junk_folder" class="btn btn-secondary" value="'.$this->trans('Remove').'" />
659: </div>
660: <br /><br />
661: </div>
662: </div>';
663:
664: $res .= '</div>';
665: return $res;
666: }
667: }
668:
669: class Hm_Output_folders_folder_subscription extends Hm_Output_Module {
670: protected function output() {
671: if ($this->get('only_subscribed_folders_setting', 0) && ($server = $this->get('folder_server')) !== NULL) {
672: $res = '<div class="folder_row"><a href="#" class="subscribe_parent_folder" style="display:none;">';
673: $res .= $this->trans('Select Folder').'</a><span class="subscribe_parent"></span></div>';
674: $res .= '<ul class="folders subscribe_parent_folder_select"><li class="subscribe_title"></li></ul>';
675: $res .= '<input type="hidden" value="" id="subscribe_parent" />';
676: return $res;
677: }
678: }
679: }
680:
681: /**
682: * @subpackage imap_folders/handler
683: */
684: class Hm_Handler_get_only_subscribed_folders_setting extends Hm_Handler_Module {
685: public function process() {
686: $this->out('only_subscribed_folders_setting', $this->user_config->get('only_subscribed_folders_setting', 0));
687: }
688: }
689:
690: /**
691: * @subpackage imap_folders/output
692: */
693: class Hm_Output_folders_folder_subscription_button extends Hm_Output_Module {
694: protected function output() {
695: if ($this->get('only_subscribed_folders_setting', 0)) {
696: $server = $this->get('folder_server');
697: $results = '<div class="folder_subscription_btn"><a href="?page=folders_subscription';
698: $results .= !is_null($server)? '&imap_server_id='.$server: '';
699: $results .= '" title="'.$this->trans('Folders subscription').'"><i class="bi bi-gear-fill account_icon float-end"></i> ';
700: $results .= '</a></div>';
701: return $results;
702: }
703: }
704: }
705:
706: /**
707: * @subpackage imap_folders/output
708: */
709: class Hm_Output_folders_create_dialog extends Hm_Output_Module {
710: protected function output() {
711: if ($this->get('folder_server') !== NULL) {
712: $res = '<div class="row m-0 px-3 mt-3">
713: <div data-target=".create_dialog" class="settings_subtitle col-12 border-bottom px-0">
714: <a href="#" class="pe-auto"><i class="bi bi-folder-plus fs-5 me-2"></i>'.$this->trans('Create a New Folder').'</a>
715: </div>
716: <div class="create_dialog folder_dialog col-lg-4 col-md-6 col-sm-12 py-3 px-0">
717: <div class="form-floating mb-3">
718: <input class="form-control create_folder_name" id="create_value" type="text" value="" placeholder="'.$this->trans('New Folder Name').'">
719: <label for="create_value">'.$this->trans('New Folder Name').'</label>
720: </div>
721: <div class="folder_row">
722: <a href="#" class="select_parent_folder">'.$this->trans('Select Parent Folder (optional)').'</a>:
723: <span class="selected_parent"></span>
724: </div>
725: <ul class="folders parent_folder_select">
726: <li class="parent_title">
727: <a href="#" class="close">'.$this->trans('Cancel').'</a>
728: </li>
729: </ul>
730: <input type="hidden" value="" id="create_parent" />
731: <input type="button" id="create_folder" class="btn btn-primary mt-3" value="'.$this->trans('Create').'">
732: </div>
733: </div>';
734:
735: return $res;
736: }
737: }
738: }
739:
740: /**
741: * @subpackage imap_folders/output
742: */
743: class Hm_Output_folders_subscription_content_start extends Hm_Output_Module {
744: protected function output() {
745: $res = '<div class="content_title">'.$this->trans('Folders subscription').'</div>';
746: return $res;
747: }
748: }
749:
750: /**
751: * @subpackage imap_folders/output
752: */
753: class Hm_Output_folders_content_start extends Hm_Output_Module {
754: protected function output() {
755: $res = '<div class="content_title">'.$this->trans('Folders').'</div>';
756: return $res;
757: }
758: }
759:
760: /**
761: * @subpackage imap_folders/output
762: */
763: class Hm_Output_folders_page_link extends Hm_Output_Module {
764: protected function output() {
765: if ($this->get('imap_support')) {
766: $res = '<li class="menu_folders"><a class="unread_link" href="?page=folders">';
767: if (!$this->get('hide_folder_icons')) {
768: $res .= '<i class="bi bi-folder-fill menu-icon"></i>';
769: }
770: $res .= $this->trans('Folders').'</a></li>';
771: if ($this->format == 'HTML5') {
772: return $res;
773: }
774: $this->concat('formatted_folder_list', $res);
775: }
776: }
777: }
778:
779: /**
780: * Option to enable/disable showing only subscribed folders
781: * @subpackage imap/output
782: */
783: class Hm_Output_imap_only_subscribed_folders_setting extends Hm_Output_Module {
784: protected function output() {
785: $checked = '';
786: $reset = '';
787: $settings = $this->get('user_settings', array());
788: if (array_key_exists('only_subscribed_folders', $settings) && $settings['only_subscribed_folders']) {
789: $checked = ' checked="checked"';
790: $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>';
791: }
792: return '<tr class="general_setting"><td><label for="only_subscribed_folders">'.
793: $this->trans('Showing subscribed folders only').'</label></td>'.
794: '<td><input type="checkbox" '.$checked.' id="only_subscribed_folders" name="only_subscribed_folders" data-default-value="false" value="1" class="form-check-input" />'.$reset.'</td></tr>';
795: }
796: }
797: