• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cypht-org / cypht / 26230827274

21 May 2026 02:01PM UTC coverage: 72.803% (-5.4%) from 78.201%
26230827274

push

travis-ci

web-flow
Merge pull request #1972 from IrAlfred/remove-duplicate-testdox-flag-in-coverage-report

fix(workflow): remove duplicate --testdox flag causing coverage job exit code 1

4797 of 6589 relevant lines covered (72.8%)

7.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.19
/modules/core/message_list_functions.php
1
<?php
2

3
/**
4
 * Core modules
5
 * @package modules
6
 * @subpackage core
7
 */
8

9
/**
10
 * get basic message list settings
11
 * @subpackage core/functions
12
 * @param string $path message list path
13
 * @param object $handler hm handler module
14
 * @return array
15
 */
16
if (!hm_exists('get_message_list_settings')) {
17
function get_message_list_settings($path, $handler) {
18
    $list_path = $path;
2✔
19
    $mailbox_list_title = array();
2✔
20
    $message_list_since = DEFAULT_SINCE;
2✔
21
    $per_source_limit = DEFAULT_PER_SOURCE;
2✔
22

23
    if ($path == 'unread') {
2✔
24
        $list_path = 'unread';
2✔
25
        $mailbox_list_title = array('Unread');
2✔
26
        $message_list_since = $handler->user_config->get('unread_since_setting', DEFAULT_UNREAD_SINCE);
2✔
27
        $per_source_limit = $handler->user_config->get('unread_per_source_setting', DEFAULT_UNREAD_PER_SOURCE);
2✔
28
    }
29
    elseif ($path == 'email') {
1✔
30
        $message_list_since = $handler->user_config->get('all_email_since_setting', DEFAULT_ALL_EMAIL_SINCE);
1✔
31
        $per_source_limit = $handler->user_config->get('all_email_per_source_setting', DEFAULT_ALL_EMAIL_PER_SOURCE);
1✔
32
        $list_path = 'email';
1✔
33
        $mailbox_list_title = array('All Email');
1✔
34
    }
35
    elseif ($path == 'flagged') {
1✔
36
        $list_path = 'flagged';
1✔
37
        $message_list_since = $handler->user_config->get('flagged_since_setting', DEFAULT_FLAGGED_SINCE);
1✔
38
        $per_source_limit = $handler->user_config->get('flagged_per_source_setting', DEFAULT_FLAGGED_PER_SOURCE);
1✔
39
        $mailbox_list_title = array('Flagged');
1✔
40
    }
41
    elseif ($path == 'combined_inbox') {
1✔
42
        $list_path = 'combined_inbox';
1✔
43
        $message_list_since = $handler->user_config->get('all_since_setting', DEFAULT_ALL_SINCE);
1✔
44
        $per_source_limit = $handler->user_config->get('all_per_source_setting', DEFAULT_ALL_PER_SOURCE);
1✔
45
        $mailbox_list_title = array('Everything');
1✔
46
    }
47
    elseif ($path == 'junk') {
1✔
48
        $list_path = 'junk';
×
49
        $message_list_since = $handler->user_config->get('junk_since_setting', DEFAULT_JUNK_SINCE);
×
50
        $per_source_limit = $handler->user_config->get('junk_per_source_setting', DEFAULT_JUNK_PER_SOURCE);
×
51
        $mailbox_list_title = array('Junk');
×
52
    }
53
    elseif ($path == 'snoozed') {
1✔
54
        $list_path = 'snoozed';
×
55
        $message_list_since = $handler->user_config->get('snoozed_since_setting', DEFAULT_SNOOZED_SINCE);
×
56
        $per_source_limit = $handler->user_config->get('snoozed_per_source_setting', DEFAULT_SNOOZED_PER_SOURCE);
×
57
        $mailbox_list_title = array('Snoozed');
×
58
    }
59
    elseif ($path == 'trash') {
1✔
60
        $list_path = 'trash';
×
61
        $message_list_since = $handler->user_config->get('trash_since_setting', DEFAULT_TRASH_SINCE);
×
62
        $per_source_limit = $handler->user_config->get('trash_per_source_setting', DEFAULT_TRASH_PER_SOURCE);
×
63
        $mailbox_list_title = array('Trash');
×
64
    }
65
    elseif ($path == 'sent') {
1✔
66
        $list_path = 'sent';
×
67
        $message_list_since = $handler->user_config->get('sent_since_setting', DEFAULT_SENT_SINCE);
×
68
        $per_source_limit = $handler->user_config->get('sent_per_source_setting', DEFAULT_SENT_PER_SOURCE);
×
69
        $mailbox_list_title = array('Sent');
×
70
    }
71
    elseif ($path == 'drafts') {
1✔
72
        $list_path = 'drafts';
×
73
        $message_list_since = $handler->user_config->get('drafts_since_setting', DEFAULT_DRAFT_SINCE);
×
74
        $per_source_limit = $handler->user_config->get('drafts_per_source_setting', DEFAULT_DRAFT_PER_SOURCE);
×
75
        $mailbox_list_title = array('Drafts');
×
76
    }
77
    elseif ($path == 'tag' && $handler->module_is_supported('tags')) {
1✔
78
        $list_path = 'tag';
×
79
        $message_list_since = $handler->user_config->get('tag_since_setting', DEFAULT_TAGS_SINCE);
×
80
        $per_source_limit = $handler->user_config->get('tag_per_source_setting', DEFAULT_TAGS_PER_SOURCE);
×
81
        $mailbox_list_title = array('Tag');
×
82
    }
83
    return array($list_path, $mailbox_list_title, $message_list_since, $per_source_limit);
2✔
84
}}
85

86
/**
87
 * Build meta information for a message list
88
 * @subpackage core/functions
89
 * @param array $input module output
90
 * @param object $output_mod Hm_Output_Module
91
 * @return string
92
 */
93
if (!hm_exists('message_list_meta')) {
94
function message_list_meta($input, $output_mod) {
95
    if (!array_key_exists('list_meta', $input) || !$input['list_meta']) {
2✔
96
        return '';
2✔
97
    }
98
    $limit = 0;
1✔
99
    $since = false;
1✔
100
    $times = array(
1✔
101
        'today' => 'Today',
1✔
102
        '-1 week' => 'Last 7 days',
1✔
103
        '-2 weeks' => 'Last 2 weeks',
1✔
104
        '-4 weeks' => 'Last 4 weeks',
1✔
105
        '-6 weeks' => 'Last 6 weeks',
1✔
106
        '-6 months' => 'Last 6 months',
1✔
107
        '-1 year' => 'Last year',
1✔
108
        '-5 years' => 'Last 5 years'
1✔
109
    );
1✔
110
    if (array_key_exists('per_source_limit', $input)) {
1✔
111
        $limit = $input['per_source_limit'];
1✔
112
    }
113
    if (!$limit) {
1✔
114
        $limit = DEFAULT_PER_SOURCE;
1✔
115
    }
116
    if (array_key_exists('message_list_since', $input)) {
1✔
117
        $since = $input['message_list_since'];
1✔
118
    }
119
    if (!$since) {
1✔
120
        $since = DEFAULT_SINCE;
1✔
121
    }
122
    $date = sprintf('%s', mb_strtolower($output_mod->trans($times[$since])));
1✔
123
    $max = sprintf($output_mod->trans('%d items per source'), $limit);
1✔
124
    $sources = '<span class="src_count">0</span>&nbsp;' . $output_mod->trans('sources');
1✔
125
    $total = '<span class="total">0</span>&nbsp;' .$output_mod->trans('total');
1✔
126

127
    return '<div class="list_meta d-flex align-items-center fs-6 text-nowrap me-auto mb-2 mb-md-0">'.$date.':&nbsp;'.$sources.',&nbsp;'.$max.',&nbsp;'.$total.'</div>';
1✔
128
}}
129

130
/**
131
 * Build sort dialog for a combined list
132
 * @subpackage core/functions
133
 * @param object $output_mod Hm_Output_Module
134
 * @return string
135
 */
136
if (!hm_exists('combined_sort_dialog')) {
137
function combined_sort_dialog($mod) {
138
    $sorts = [
2✔
139
        'arrival' => $mod->trans('Arrival Date'),
2✔
140
        'date' => $mod->trans('Sent Date'),
2✔
141
        'from' => $mod->trans('From'),
2✔
142
        'to' => $mod->trans('To'),
2✔
143
        'subject' => $mod->trans('Subject')
2✔
144
    ];
2✔
145

146
    $res = '<select name="sort" style="width: 150px" class="combined_sort form-select form-select-sm ms-2">';
2✔
147
    foreach ($sorts as $name => $val) {
2✔
148
        $res .= '<option value="'.$name.'"'.($mod->get('list_sort') == $name ? ' selected' : '').'>'.$val.' &darr;</option>';
2✔
149
        $res .= '<option value="-'.$name.'"'.($mod->get('list_sort') == '-'.$name ? ' selected' : '').'>'.$val.' &uarr;</option>';
2✔
150
    }
151
    $res .= '</select>';
2✔
152
    return $res;
2✔
153
}}
154

155
/**
156
 * Build a human readable interval string
157
 * @subpackage core/functions
158
 * @param string $date_str date string parsable by strtotime()
159
 * @return string
160
 */
161
if (!hm_exists('human_readable_interval')) {
162
function human_readable_interval($date_str) {
163
    if (!$date_str) {
2✔
164
        return 'Unknown';
1✔
165
    }
166
    $precision     = 2;
2✔
167
    $interval_time = array();
2✔
168
    $date          = strtotime($date_str);
2✔
169
    $interval      = time() - $date;
2✔
170
    $res           = array();
2✔
171

172
    $t['second'] = 1;
2✔
173
    $t['minute'] = $t['second']*60;
2✔
174
    $t['hour']   = $t['minute']*60;
2✔
175
    $t['day']    = $t['hour']*24;
2✔
176
    $t['week']   = $t['day']*7;
2✔
177
    $t['month']  = $t['day']*30;
2✔
178
    $t['year']   = $t['week']*52;
2✔
179

180
    if ($interval < -300) {
2✔
181
        return 'From the future!';
1✔
182
    }
183
    elseif ($interval <= 0) {
2✔
184
        return 'Just now';
2✔
185
    }
186
    foreach (array_reverse($t) as $name => $val) {
1✔
187
        if ($interval_time[$name] = ($interval/$val > 0) ? floor($interval/$val) : false) {
1✔
188
            $interval -= $val*$interval_time[$name];
1✔
189
        }
190
    }
191
    $interval_time = array_slice(array_filter($interval_time, function($v) { return $v > 0; }), 0, $precision);
1✔
192
    foreach($interval_time as $name => $val) {
1✔
193
        if ($val > 1) {
1✔
194
            $res[] = sprintf('%d %ss', $val, $name);
1✔
195
        }
196
        else {
197
            $res[] = sprintf('%d %s', $val, $name);
1✔
198
        }
199
    }
200
    return implode(', ', $res);
1✔
201
}}
202

203
/**
204
 * Output a message list row of data using callbacks
205
 * @subpackage core/functions
206
 * @param array $values data and callbacks for each cell
207
 * @param string $id unique id for the message
208
 * @param string $style message list style (news or email)
209
 * @param object $output_mod Hm_Output_Module
210
 * @param string $row_class optional table row css class
211
 * @return array
212
 */
213
if (!hm_exists('message_list_row')) {
214
function message_list_row($values, $id, $style, $output_mod, $row_class='', $msgId = '', $inReplyTo = '') {
215
    $res = '<tr class="'.$output_mod->html_safe($id);
1✔
216
    if ($row_class) {
1✔
217
        $res .= ' '.$output_mod->html_safe($row_class);
1✔
218
    }
219
    if (!empty($msgId)) {
1✔
220
        $res .= '" data-msg-id="'.$output_mod->html_safe($msgId);
×
221
    }
222
    if (!empty($inReplyTo)) {
1✔
223
        $res .= '" data-in-reply-to="'.$output_mod->html_safe($inReplyTo);
×
224
    }
225
    $data_uid = "";
1✔
226
    if ($uids = explode("_", $id)) {
1✔
227
        if (isset($uids[2])) {
1✔
228
            $data_uid = 'data-uid="'. $uids[2] .'"';
×
229
        }
230
    }
231
    if (!empty($data_uid)) {
1✔
232
        $res .= '" '.$data_uid.'>';
×
233
    } else {
234
        $res .= '">';
1✔
235
    }
236
    
237
    if ($style == 'news') {
1✔
238
        $res .= '<td class="news_cell checkbox_cell">';
1✔
239
    }
240
    foreach ($values as $vals) {
1✔
241
        if (function_exists($vals[0])) {
1✔
242
            $function = array_shift($vals);
1✔
243
            $res .= $function($vals, $style, $output_mod);
1✔
244
        }
245
    }
246
    if ($style == 'news') {
1✔
247
        $res .= '</td>';
1✔
248
    }
249
    $res .= '</tr>';
1✔
250
    return array($res, $id);
1✔
251
}}
252

253
/**
254
 * Generic callback for a message list table cell
255
 * @subpackage core/functions
256
 * @param array $vals data for the cell
257
 * @param string $style message list style
258
 * @param object $output_mod Hm_Output_Module
259
 * @return string
260
 */
261
if (!hm_exists('safe_output_callback')) {
262
function safe_output_callback($vals, $style, $output_mod) {
263
    $img = '';
1✔
264
    $title = '';
1✔
265
    if (count($vals) > 2) {
1✔
266
        if ($vals[2]){
1✔
267
            $img = '<i class="bi bi-filetype-'.$vals[2].'"></i>';
1✔
268
        }
269
        if (count($vals) > 3) {
1✔
270
            $title = $output_mod->html_safe($vals[3]);
×
271
        } else {
272
            $title = $output_mod->html_safe($vals[1]);
1✔
273
        }
274
    }
275
    if ($style == 'news') {
1✔
276
        return sprintf('<div class="%s" data-title="%s">%s%s</div>', $output_mod->html_safe($vals[0]), $title, $img, $output_mod->html_safe($vals[1]));
1✔
277
    }
278
    return sprintf('<td class="%s" data-title="%s">%s%s</td>', $output_mod->html_safe($vals[0]), $title, $img, $output_mod->html_safe($vals[1]));
1✔
279
}}
280

281
/**
282
 * Callback for a message list checkbox
283
 * @subpackage core/functions
284
 * @param array $vals data for the cell
285
 * @param string $style message list style
286
 * @param object $output_mod Hm_Output_Module
287
 * @return string
288
 */
289
if (!hm_exists('checkbox_callback')) {
290
function checkbox_callback($vals, $style, $output_mod) {
291
    if ($style == 'news') {
1✔
292
        return sprintf('<input type="checkbox" id="%s" value="%s" />'.
1✔
293
            '<label class="checkbox_label" for="%s"></label>'.
1✔
294
            '</td><td class="news_cell">', $output_mod->html_safe($vals[0]),
1✔
295
            $output_mod->html_safe($vals[0]), $output_mod->html_safe($vals[0]));
1✔
296
    }
297
    return sprintf('<td class="checkbox_cell">'.
1✔
298
        '<input id="'.$output_mod->html_safe($vals[0]).'" type="checkbox" value="%s" />'.
1✔
299
        '<label class="checkbox_label" for="'.$output_mod->html_safe($vals[0]).'"></label>'.
1✔
300
        '</td>', $output_mod->html_safe($vals[0]));
1✔
301
}}
302

303
/**
304
 * Callback for a subject cell in a message list
305
 * @subpackage core/functions
306
 * @param array $vals data for the cell
307
 * @param string $style message list style
308
 * @param object $output_mod Hm_Output_Module
309
 * @return string
310
 */
311
if (!hm_exists('subject_callback')) {
312
function subject_callback($vals, $style, $output_mod) {
313
    $img = '';
1✔
314
    $subject = '';
1✔
315
    $preview_msg = '';
1✔
316
    $icon_type_msg = '';
1✔
317
    if (isset($vals[3]) && $vals[3]) {
1✔
318
        $img = '<i class="bi bi-filetype-'.$vals[3].'"></i>';
1✔
319
    }
320
    $subject = $output_mod->html_safe($vals[0]);
1✔
321
    if (isset($vals[4]) && $vals[4]) {
1✔
322
        $lines = explode("\n", $vals[4]);
×
323
        $clean = array_filter(array_map('trim', $lines), function ($line) {
×
324
            return $line !== ''
×
325
                && stripos($line, 'boundary=') === false
×
326
                && !preg_match('/^-{2,}==/', $line)
×
327
                && stripos($line, 'content-type:') !== 0
×
328
                && stripos($line, 'charset=') === false
×
329
                && stripos($line, 'content-transfer-encoding:') !== 0;
×
330
        });
×
331
        $clean_text = implode("\n", $clean);
×
332
        $preview_msg = $output_mod->html_safe($clean_text);
×
333
    }
334

335
    if (isset($vals[5]) && $vals[5]) {
1✔
336
        if ($vals[5] == 'calendar') {
×
337
            $icon_type_msg = '<span class="bi bi-calendar4-event"></span>';
×
338
        }
339
    }
340
    
341
    $hl_subject = preg_replace("/^(\[[^\]]+\])/", '<span class="s_pre">$1</span>', $subject);
1✔
342

343
    $safe_url = $output_mod->html_safe($vals[1]);
1✔
344
    $inline_active = $output_mod->get('inline_message_setting') && !$output_mod->get('is_mobile');
1✔
345
    $link_href = $inline_active ? '#' : $safe_url;
1✔
346
    $data_src_attr = $inline_active ? ' data-src="' . $safe_url . '"' : '';
1✔
347

348
    if ($style == 'news') {
1✔
349
        if ($output_mod->get('is_mobile')) {
1✔
350
            return sprintf('<div class="subject"><div class="%s" title="%s">%s %s <a href="%s">%s</a></div></div>', $output_mod->html_safe(implode(' ', $vals[2])), $subject, $img, $icon_type_msg, $safe_url, $hl_subject);
×
351
        }
352
        return sprintf('<div class="subject"><div class="%s" title="%s">%s %s <a%s href="%s">%s</a><p class="fw-light">%s</p></div></div>', $output_mod->html_safe(implode(' ', $vals[2])), $subject, $icon_type_msg, $img, $data_src_attr, $link_href, $hl_subject, $preview_msg);
1✔
353
    }
354

355
    if ($output_mod->get('is_mobile')) {
1✔
356
        return sprintf('<td class="subject"><div class="%s"> %s <a title="%s" href="%s">%s</a></div></td>', $output_mod->html_safe(implode(' ', $vals[2])), $icon_type_msg, $subject, $safe_url, $hl_subject);
×
357
    }
358
    return sprintf('<td class="subject"><div class="%s"> %s <a title="%s"%s href="%s">%s</a><p class="fw-light">%s</p></div></td>', $output_mod->html_safe(implode(' ', $vals[2])), $icon_type_msg, $subject, $data_src_attr, $link_href, $hl_subject, $preview_msg);
1✔
359
}}
360

361
/**
362
 * Callback for a date cell in a message list
363
 * @subpackage core/functions
364
 * @param array $vals data for the cell
365
 * @param string $style message list style
366
 * @param object $output_mod Hm_Output_Module
367
 * @return string
368
 */
369
if (!hm_exists('date_callback')) {
370
function date_callback($vals, $style, $output_mod) {
371
    $delayed_class = isset($vals[2]) && $vals[2]? ' delayed_date': '';
1✔
372
    if ($style == 'news') {
1✔
373
        return sprintf('<div class="msg_date%s">%s<input type="hidden" class="msg_timestamp" value="%s" /></div>', $delayed_class, $output_mod->html_safe($vals[0]), $output_mod->html_safe($vals[1]));
1✔
374
    }
375
    return sprintf('<td class="msg_date%s" title="%s">%s%s<input type="hidden" class="msg_timestamp" value="%s" /></td>', $delayed_class, $output_mod->html_safe(date('r', $vals[1])), ($delayed_class ? '<span class="badge bg-secondary-subtle text-body"><i class="bi bi-alarm"></i></span>': ''), $output_mod->html_safe($vals[0]), $output_mod->html_safe($vals[1]));
1✔
376
}}
377

378
function dates_holders_callback($vals) {
379
    $res = '<td class="dates d-none">';
×
380
    $res .= '<input type="hidden" name="arrival" class="arrival" value="'. $vals[0] .'" arial-label="Arrival date" />';
×
381
    $res .= '<input type="hidden" name="date" class="date" value="'. $vals[1] .'" arial-label="Sent date" />';
×
382
    $res .= '</td>';
×
383
    return $res;
×
384
}
385

386
/**
387
 * Callback for an icon in a message list row
388
 * @subpackage core/functions
389
 * @param array $vals data for the cell
390
 * @param string $style message list style
391
 * @param object $output_mod Hm_Output_Module
392
 * @return string
393
 */
394
if (!hm_exists('icon_callback')) {
395
function icon_callback($vals, $style, $output_mod) {
396
    $icons = '';
1✔
397
    $title = array();
1✔
398
    $show_icons = $output_mod->get('msg_list_icons');
1✔
399
    if (in_array('flagged', $vals[0])) {
1✔
400
        $icons .= $show_icons ? '<i class="bi bi-star-half"></i>' : ' F';
1✔
401
        $title[] = $output_mod->trans('Flagged');
1✔
402
    }
403
    if (in_array('draft', $vals[0])) {
1✔
404
        $icons .= $show_icons ? '<i class="bi bi-star-half"></i>' : ' D';
×
405
        $title[] = $output_mod->trans('Draft');
×
406
    }
407
    if (in_array('answered', $vals[0])) {
1✔
408
        $icons .= $show_icons ? '<i class="bi bi-check-circle-fill"></i>' : ' A';
1✔
409
        $title[] = $output_mod->trans('Answered');
1✔
410
    }
411
    if (in_array('attachment', $vals[0])) {
1✔
412
        $icons .= $show_icons ? '<i class="bi bi-paperclip"></i>' : ' <i class="bi bi-plus-circle"></i>';
1✔
413
        $title[] = $output_mod->trans('Attachment');
1✔
414
    }
415
    $title = implode(', ', $title);
1✔
416
    if ($style == 'news') {
1✔
417
        return sprintf('<div class="icon" title="%s">%s</div>', $title, $icons);
1✔
418
    }
419
    return sprintf('<td class="icon" title="%s">%s</td>', $title, $icons);
1✔
420
}}
421

422
/**
423
 * Output message controls
424
 * @subpackage core/functions
425
 * @param object $output_mod Hm_Output_Module
426
 * @return string
427
 */
428
if (!hm_exists('message_controls')) {
429
function message_controls($output_mod) {
430
    $txt = '';
3✔
431
    $controls = ['read', 'unread', 'flag', 'unflag', 'delete', 'archive', 'junk', 'restore'];
3✔
432
    $controls = array_filter($controls, function($val) use ($output_mod) {
3✔
433
        if (in_array($val, [$output_mod->get('list_path', ''), strtolower($output_mod->get('core_msg_control_folder', ''))])) {
3✔
434
            return false;
×
435
        }
436
        if ($val == 'flag' && $output_mod->get('list_path', '') == 'flagged') {
3✔
437
            return false;
×
438
        }
439
        $is_trash_folder = $output_mod->get('is_trash_folder', false);
3✔
440

441
        if ($val == 'restore' && !$is_trash_folder) {
3✔
442
            return false;
3✔
443
        }
444

445
        return true;
3✔
446
    });
3✔
447

448
    $res = '<a class="toggle_link" href="#"><i class="bi bi-check-square-fill"></i></a>'.
3✔
449
        '<div class="msg_controls fs-6 d-none gap-1 align-items-center">'.
3✔
450
            '<div class="dropdown on_mobile">'.
3✔
451
                '<button type="button" class="btn btn-outline-secondary btn-sm dropdown-toggle" id="coreMsgControlDropdown" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="true">Actions</button>'.
3✔
452
                '<ul class="dropdown-menu" aria-labelledby="coreMsgControlDropdown">';
3✔
453
    foreach ($controls as $control) {
3✔
454
        $res .= '<li><a class="dropdown-item msg_'.$control.' core_msg_control btn btn-sm btn-light text-black-50" href="#" data-action="'.$control.'">'.$output_mod->trans(ucfirst($control)).'</a></li>';
3✔
455
    }
456
    $res .= '</ul>'.
3✔
457
            '</div>';
3✔
458

459
    foreach ($controls as $control) {
3✔
460
        $res .= '<a class="msg_'.$control.' core_msg_control btn btn-sm btn-light no_mobile border text-black-50" href="#" data-action="'.$control.'">'.$output_mod->trans(ucfirst($control)).'</a>';
3✔
461
    }
462

463
    if ($output_mod->get('msg_controls_extra')) {
3✔
464
        $res .= $output_mod->get('msg_controls_extra');
1✔
465
    }
466
    if(!empty($output_mod->get('tags'))) {
3✔
467
        $res .= tags_dropdown($output_mod, []);
×
468
    }
469

470
    if ($output_mod->get('msg_controls_custom_actions')) {
3✔
471
        $res .= $output_mod->get('msg_controls_custom_actions');
×
472
    }
473

474
    $res .= '</div>';
3✔
475
    return $res;
3✔
476
}}
477

478
/**
479
 * Output select element for "received since" options
480
 * @subpackage core/functions
481
 * @param string $since current value to pre-select
482
 * @param string $name name used as the elements id and name
483
 * @param object $output_mod Hm_Output_Module
484
 * @return string
485
 */
486
if (!hm_exists('message_since_dropdown')) {
487
function message_since_dropdown($since, $name, $output_mod, $original_default_value = '-1 week') {
488
    $times = array(
9✔
489
        'today' => 'Today',
9✔
490
        '-1 week' => 'Last 7 days',
9✔
491
        '-2 weeks' => 'Last 2 weeks',
9✔
492
        '-4 weeks' => 'Last 4 weeks',
9✔
493
        '-6 weeks' => 'Last 6 weeks',
9✔
494
        '-6 months' => 'Last 6 months',
9✔
495
        '-1 year' => 'Last year',
9✔
496
        '-5 years' => 'Last 5 years'
9✔
497
    );
9✔
498
    $res = '<select name="'.$name.'" id="'.$name.'" class="message_list_since form-select form-select-sm" data-default-value="'.$original_default_value.'">';
9✔
499
    $reset = '';
9✔
500
    foreach ($times as $val => $label) {
9✔
501
        $res .= '<option';
9✔
502
        if ($val == $since) {
9✔
503
            $res .= ' selected="selected"';
9✔
504
            if ($val != $original_default_value) {
9✔
505
                $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>';
7✔
506
            }
507

508
        }
509
        $res .= ' value="'.$val.'">'.$output_mod->trans($label).'</option>';
9✔
510
    }
511
    $res .= '</select>'.$reset;
9✔
512
    return $res;
9✔
513
}}
514

515
/**
516
 * Output a source list for a message list
517
 * @subpackage core/functions
518
 * @param array $sources source of the list
519
 * @param object $output_mod Hm_Output_Module
520
 */
521
if (!hm_exists('list_sources')) {
522
function list_sources($sources, $output_mod) {
523
    $res = '<div class="list_sources w-100 mt-2">';
3✔
524
    $res .= '<div class="src_title fs-5 mb-2">'.$output_mod->html_safe('Sources').'</div>';
3✔
525
    foreach ($sources as $src) {
3✔
526
        if (array_key_exists('group', $src) && $src['group'] == 'background') {
1✔
527
            continue;
1✔
528
        }
529
        if (array_key_exists('nodisplay', $src) && $src['nodisplay']) {
1✔
530
            continue;
×
531
        }
532
        if ($src['type'] == 'imap' && !array_key_exists('folder_name', $src)) {
1✔
533
            $folder = 'INBOX';
1✔
534
        }
535
        elseif (!array_key_exists('folder_name', $src)) {
1✔
536
            $folder = '';
×
537
        }
538
        else {
539
            $folder = $src['folder_name'];
1✔
540
        }
541
        $res .= '<div class="list_src">'.$output_mod->html_safe($src['type']).' '.$output_mod->html_safe($src['name']);
1✔
542
        $res .= ' '.$output_mod->html_safe($folder);
1✔
543
        $res .= '</div>';
1✔
544
    }
545
    $res .= '</div>';
3✔
546
    return $res;
3✔
547
}}
548

549

550

551
/**
552
 * Output a source list for a message list
553
 * @subpackage core/functions
554
 * @param array $sources source of the list
555
 * @param object $output_mod Hm_Output_Module
556
 */
557
if (!hm_exists('update_search_label_field')) {
558
function update_search_label_field($search_term, $output_mod) {
559
    $res = '<div class="update_search_label_field">';
1✔
560
    $res .= '<div class="update_saved_search_title">'.$output_mod->html_safe('Update saved search label') .'</div>';
1✔
561
    $res .= '<div>
1✔
562
    <input type="hidden" name="'. $output_mod->get('page_param_name') .'" value="search">
1✔
563
    <input type="hidden" name="search_terms" value="'. $search_term .'">
1✔
564
    <label class="screen_reader" for="search_terms_label">Current Search Label</label>
565
    <input required="" disabled id="old_search_terms_label" type="search" value="' . $search_term . '" class="old_search_terms_label form-control form-control-sm" name="old_search_terms_label">
1✔
566
    <label class="screen_reader" for="search_terms_label">New Search Terms</label>
567
    <input required="" placeholder="New search terms label" id="search_terms_label" type="search" class="search_terms_label form-control form-control-sm" name="search_terms_label">
568
    <div>
569
        <input type="button" class="search_label_update btn w-100 btn-primary btn-sm" value="Update">
570
    </div>
571
    </div>';
1✔
572
    $res .= '</div>';
1✔
573
    return $res;
1✔
574
}}
575

576

577

578

579

580

581

582

583

584

585

586

587

588

589

590

591

592

593

594
/**
595
 * Output message list controls
596
 * @subpackage core/functions
597
 * @param string $refresh_link refresh link tag
598
 * @param string $config_link configuration link tag
599
 * @param string $source_link source link tag
600
 * @return string
601
 */
602
if (!hm_exists('list_controls')) {
603
function list_controls($refresh_link, $config_link, $source_link = false, $search_field = '') {
604
    return '<div class="list_controls no_mobile d-flex gap-3 align-items-center">' .
3✔
605
                $refresh_link . $source_link . $config_link . $search_field .
3✔
606
           '</div>' .
3✔
607
           '<div class="list_controls on_mobile">' .
3✔
608
                $search_field .
3✔
609
                '<i class="bi bi-filter-circle" onclick="listControlsMenu()"></i>' .
3✔
610
                '<div id="list_controls_menu" class="list_controls_menu">' .
3✔
611
                    $refresh_link . $source_link . $config_link .
3✔
612
                '</div>' .
3✔
613
           '</div>';
3✔
614
}}
615

616
/**
617
 * Validate search terms
618
 * @subpackage core/functions
619
 * @param string $terms search terms to validate
620
 * @return string
621
 */
622
if (!hm_exists('validate_search_terms')) {
623
function validate_search_terms($terms) {
624
    $terms = trim(strip_tags($terms));
2✔
625
    if (!$terms) {
2✔
626
        $terms = '';
1✔
627
    }
628
    return $terms;
2✔
629
}}
630

631
/**
632
 * Validate the name of a search field
633
 * @subpackage core/functions
634
 * @param string $fld name to validate
635
 * @return mixed
636
 */
637
if (!hm_exists('validate_search_fld')) {
638
function validate_search_fld($fld) {
639
    if (in_array($fld, array('TEXT', 'BODY', 'FROM', 'SUBJECT', 'TO', 'CC'))) {
2✔
640
        return $fld;
2✔
641
    }
642
    return false;
1✔
643
}}
644

645
/**
646
 * Output a select element for the search field
647
 * @subpackage core/functions
648
 * @param string $current currently selected field
649
 * @param object $output_mod Hm_Output_Module
650
 * @return string
651
 */
652
if (!hm_exists('search_field_selection')) {
653
function search_field_selection($current, $output_mod) {
654
    $flds = array(
2✔
655
        'TEXT' => 'Entire message',
2✔
656
        'BODY' => 'Message body',
2✔
657
        'SUBJECT' => 'Subject',
2✔
658
        'FROM' => 'From',
2✔
659
        'TO' => 'To',
2✔
660
        'CC' => 'Cc',
2✔
661
    );
2✔
662
    $res = '<select class="form-select form-select-sm" id="search_fld" name="search_fld">';
2✔
663
    foreach ($flds as $val => $name) {
2✔
664
        $res .= '<option ';
2✔
665
        if ($current == $val) {
2✔
666
            $res .= 'selected="selected" ';
2✔
667
        }
668
        $res .= 'value="'.$val.'">'.$output_mod->trans($name).'</option>';
2✔
669
    }
670
    $res .= '</select>';
2✔
671
    return $res;
2✔
672
}}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc