wzp
2026-04-03 c90776d50aa7275744657ee934dcdd61fb9e3db4
Ó³ÐǽÌÓý/snippet-4-admin.php
@@ -16,6 +16,29 @@
defined('ABSPATH') || exit;
/**
 * æ ¼å¼åŒ–ç”± MySQL CURRENT_TIMESTAMP(或纯 SQL å†™å…¥ï¼‰äº§ç”Ÿçš„ DATETIME。
 * æ­¤ç±»å€¼éš MySQL ä¼šè¯æ—¶åŒºè€Œå®šï¼Œæ‰˜ç®¡çŽ¯å¢ƒå¤šä¸º UTC;先按该时区解析为瞬间,再用站点时区显示。
 *
 * å¯é€šè¿‡è¿‡æ»¤å™¨ im_mysql_datetime_timezone æ”¹ä¸ºä¸Žæ•°æ®åº“一致的时区标识,例如 'America/Toronto'。
 *
 * @param string|null $mysql_datetime
 */
function im_wp_format_mysql_clock_datetime($mysql_datetime, string $format): string
{
    if ($mysql_datetime === null || $mysql_datetime === '' || $mysql_datetime === '0000-00-00 00:00:00') {
        return '';
    }
    $tz_id = apply_filters('im_mysql_datetime_timezone', 'UTC');
    try {
        $tz = new DateTimeZone($tz_id);
        $dt = new DateTimeImmutable($mysql_datetime, $tz);
    } catch (Exception $e) {
        return '';
    }
    return wp_date($format, $dt->getTimestamp());
}
/* ============================================================
   æ³¨å†Œèœå•
   ============================================================ */
@@ -903,7 +926,7 @@
                                <?php endif; ?>
                            </td>
                            <td><a href="mailto:<?= esc_attr($c->email) ?>"><?= esc_html($c->email) ?></a></td>
                            <td style="font-size:13px"><?= esc_html(date('Y-m-d H:i', strtotime($c->updated_at))) ?></td>
                            <td style="font-size:13px"><?= esc_html(im_wp_format_mysql_clock_datetime($c->updated_at, 'Y-m-d H:i')) ?></td>
                            <td>
                                <span class="im-badge"
                                    style="background:<?= $color ?>18;color:<?= $color ?>;border-color:<?= $color ?>44"><?= $clabel ?></span>
@@ -929,7 +952,7 @@
                                    <?php endif; ?>
                                <?php elseif ($c->status === 'trained'): ?>
                                    <?php if (!empty($c->training_completed_at)): ?>
                                        <div style="font-size:12px;color:#059669;margin-top:4px">✓ <?= date('m/d H:i', strtotime($c->training_completed_at)) ?> Completed</div>
                                        <div style="font-size:12px;color:#059669;margin-top:4px">✓ <?= esc_html(mysql2date('m/d H:i', $c->training_completed_at, false) ?: '') ?> Completed</div>
                                    <?php endif; ?>
                                <?php endif; ?>
                            </td>
@@ -1298,7 +1321,7 @@
                        <h3 style="color:#c2410c">Training In Progress</h3>
                        <p style="color:#ea580c">Candidate is completing training modules</p>
                        <?php if (!empty($c->training_opened_at)): ?>
                            <div style="font-size:13px;color:#059669;margin-bottom:12px;font-weight:600">✓ Opened training page at <?= date('Y/m/d H:i', strtotime($c->training_opened_at)) ?></div>
                            <div style="font-size:13px;color:#059669;margin-bottom:12px;font-weight:600">✓ Opened training page at <?= esc_html(im_wp_format_mysql_clock_datetime($c->training_opened_at, 'Y/m/d H:i')) ?></div>
                        <?php else: ?>
                            <div style="font-size:13px;color:#9ca3af;margin-bottom:12px">○ Training page not opened yet</div>
                        <?php endif; ?>
@@ -1313,7 +1336,7 @@
                        <h3 style="color:#0e7490">Training Completed</h3>
                        <p style="color:#0891b2">Candidate has passed all training modules</p>
                        <?php if (!empty($c->training_completed_at)): ?>
                            <div style="font-size:13px;color:#059669;font-weight:600;margin-bottom:12px">✓ Completed training at <?= date('Y/m/d H:i', strtotime($c->training_completed_at)) ?></div>
                            <div style="font-size:13px;color:#059669;font-weight:600;margin-bottom:12px">✓ Completed training at <?= esc_html(mysql2date('Y/m/d H:i', $c->training_completed_at, false) ?: '') ?></div>
                        <?php endif; ?>
                        <button class="im-btn-primary im-action-btn" data-action="resend_trained_email" data-id="<?= $c->id ?>"
                            data-name="<?= esc_attr($full_name) ?>">
@@ -1396,7 +1419,7 @@
                        <?php if ($tokens):
                            foreach ($tokens as $tk):
                                $used = (bool) $tk->is_used;
                                $expired = strtotime($tk->expires_at) < time();
                                $expired = empty($tk->expires_at) ? true : (int) mysql2date('U', $tk->expires_at, false) < time();
                                if ($used) {
                                    $bs = '#dcfce7';
                                    $bc = '#86efac';
@@ -1419,14 +1442,14 @@
                                        <span class="im-badge"
                                            style="background:<?= $bs ?>;color:<?= $bt ?>;border-color:<?= $bc ?>"><?= $bl ?></span>
                                    </div>
                                    <div class="im-token-date"><?= date('Y/m/d H:i', strtotime($tk->created_at)) ?> Sent</div>
                                    <div class="im-token-date"><?= esc_html(im_wp_format_mysql_clock_datetime($tk->created_at, 'Y/m/d H:i')) ?> Sent</div>
                                    <div class="im-token-exp" style="margin-bottom:8px">Valid until
                                        <?= date('m/d H:i', strtotime($tk->expires_at)) ?>
                                        <?= esc_html(mysql2date('m/d H:i', $tk->expires_at, false) ?: '') ?>
                                    </div>
                                    <?php if (!empty($tk->opened_at)): ?>
                                        <div class="im-token-exp" style="color:#059669;font-weight:600">
                                            âœ“ Viewed questions at <?= date('Y/m/d H:i', strtotime($tk->opened_at)) ?> <?= $used ? '' : '(countdown active)' ?>
                                            âœ“ Viewed questions at <?= esc_html(mysql2date('Y/m/d H:i', $tk->opened_at, false) ?: '') ?> <?= $used ? '' : '(countdown active)' ?>
                                        </div>
                                    <?php else: ?>
                                        <div class="im-token-exp" style="color:#f59e0b">○ Candidate has not opened the link</div>
@@ -1452,13 +1475,13 @@
                                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>Download
                                            </a>
                                        </div>
                                        <div style="margin-top:6px;font-size:12px;color:#94a3b8"><?= date('m/d H:i', strtotime($tk->submitted_at)) ?> submitted</div>
                                        <div style="margin-top:6px;font-size:12px;color:#94a3b8"><?= esc_html(mysql2date('m/d H:i', $tk->submitted_at, false) ?: '') ?> submitted</div>
                                        <?php else: ?>
                                        <video controls class="im-video-player" preload="metadata">
                                            <source src="<?= esc_url($vurl) ?>">
                                        </video>
                                        <div class="im-video-footer">
                                            <span><?= date('m/d H:i', strtotime($tk->submitted_at)) ?> submitted</span>
                                            <span><?= esc_html(mysql2date('m/d H:i', $tk->submitted_at, false) ?: '') ?> submitted</span>
                                            <a href="<?= esc_url($vurl) ?>" download class="im-video-dl">
                                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor"
                                                    stroke-width="2">