is_scalar($v) ? (string) $v : ''; $evergreen = ($settings['countdown_type'] ?? 'due_date') === 'evergreen'; $units = []; foreach (array_keys(Countdown::UNITS) as $unit) { if (!empty($settings['show_' . $unit])) { $units[] = $unit; } } if (!$units) { $units = ['seconds']; } $default_labels = ['days' => __('Days', 'zadex'), 'hours' => __('Hours', 'zadex'), 'minutes' => __('Minutes', 'zadex'), 'seconds' => __('Seconds', 'zadex')]; $labels = []; foreach ($units as $unit) { $label = trim($str($settings['label_' . $unit] ?? '')); $labels[$unit] = $label !== '' ? $label : $default_labels[$unit]; } $actions = array_values(array_intersect(['hide', 'message', 'redirect', 'popup'], is_array($settings['expire_actions'] ?? null) ? array_map('strval', $settings['expire_actions']) : [])); $config = ['type' => $evergreen ? 'evergreen' : 'due', 'id' => (string) ($element['id'] ?? ''), 'actions' => $actions]; if ($evergreen) { $hours = max(0, (int) ($settings['evergreen_hours'] ?? 0)); $minutes = max(0, min(59, (int) ($settings['evergreen_minutes'] ?? 0))); $duration = ($hours * 3600 + $minutes * 60); $config['duration'] = $duration * 1000; $config['reset'] = max(0, (int) ($settings['evergreen_reset'] ?? 0)) * 3600000; $remaining = $duration; } else { $due = Countdown::due_timestamp($str($settings['due_date'] ?? '')); $config['due'] = $due === null ? 0 : $due * 1000; $remaining = $due === null ? 0 : $due - time(); } if (in_array('redirect', $actions, true)) { $redirect = is_array($settings['expire_redirect'] ?? null) ? $str($settings['expire_redirect']['url'] ?? '') : ''; $config['redirect'] = esc_url_raw($redirect); } if (in_array('popup', $actions, true)) { $config['popup'] = preg_replace('/[^0-9]/', '', $str($settings['popup_id'] ?? '')) ?? ''; } /* translators: %s: e.g. "2 Days, 5 Hours, 10 Minutes" */ $config['sr'] = __('%s remaining', 'zadex'); $expired = !$evergreen && $remaining <= 0; $values = Countdown::breakdown((int) $remaining, $units); $message = in_array('message', $actions, true) ? wp_kses_post($str($settings['expire_message'] ?? '')) : ''; $hide = $expired && in_array('hide', $actions, true); $layout = ($settings['layout'] ?? 'block') === 'inline' ? 'inline' : 'block'; $classes = 'zx-countdown--' . $layout . (!empty($settings['stretch']) ? ' zx-countdown--stretch' : '') . ($expired ? ' zx-countdown--expired' : ''); $attrs = (string) preg_replace('/class="/', 'class="' . esc_attr($classes) . ' ', $attrs, 1); $attrs .= ' data-zx-countdown="' . esc_attr((string) wp_json_encode($config)) . '"'; if ($hide && $message === '') { $attrs .= ' hidden'; } $show_labels = !empty($settings['show_labels']); $separator = !empty($settings['separator']) ? $str($settings['separator_text'] ?? ':') : ''; $sr_parts = []; $items = ''; foreach ($units as $i => $unit) { if ($i > 0 && $separator !== '') { $items .= ''; } $items .= '
'; } // Screen-reader text (same rules as srText() in countdown.ts): no seconds unless they are the only unit. $sr_units = count($units) > 1 ? array_values(array_diff($units, ['seconds'])) : $units; foreach ($sr_units as $unit) { $n = (int) $values[$unit]; if ($unit === 'seconds' && count($units) === 1) { $n = (int) (ceil($n / 10) * 10); } $sr_parts[] = $n . ' ' . $labels[$unit]; } $sr = sprintf($config['sr'], implode(', ', $sr_parts)); $zx_html = '