url($isUpdate ? 'update.html' : 'create.html'); $intent = $isUpdate ? 'update:' . $id : 'create'; $csrf = $ctx->csrfField($intent); $hiddenId = $isUpdate ? '' : ''; return '
' . $csrf . $hiddenId . '

' . AppContext::e($ctx->t('Response content')) . '

' . AppContext::e($ctx->t('Original subject suffix')) . '
' . '
' . render_reply_frequency_select($ctx, $replyFrequency) . '
' . '
' . '
' . render_calendar_picker($ctx, 'start_value', $ctx->t('Start date'), $startValue) . render_calendar_picker($ctx, 'end_value', $ctx->t('End date'), $endValue) . '
' . AppContext::e($ctx->t('Cancel')) . '
' . '
'; } /** @param array|null $rule */ function selected_reply_frequency(?array $rule): string { if ($rule === null) { return '1440'; } if (!empty($rule['reply_every_message'])) { return 'every'; } $minutes = (string)(int)($rule['repeat_minutes'] ?? 1440); return in_array($minutes, ['30', '60', '120', '360', '720', '1440', '2880', '10080'], true) ? $minutes : '1440'; } function render_reply_frequency_select(AppContext $ctx, string $selected): string { $options = [ 'every' => 'Send automatic reply for every message', '30' => '30 minutes', '60' => '1 hour', '120' => '2 hours', '360' => '6 hours', '720' => '12 hours', '1440' => '1 day', '2880' => '2 days', '10080' => '7 days', ]; $html = ''; } /** @param array $post @return array */ function normalize_rule_post(array $post): array { foreach (['start_value', 'end_value'] as $key) { $date = trim((string)($post[$key . '_date'] ?? '')); $time = trim((string)($post[$key . '_time'] ?? '')); $period = trim((string)($post[$key . '_period'] ?? '')); if ($date !== '' && preg_match('/^[0-9]{2}:[0-9]{2}$/', $time)) { $post[$key] = $date . 'T' . $time; } elseif ($date !== '' && preg_match('/^(morning|afternoon|evening)$/', $period)) { $post[$key] = $date . '|' . $period; } } return $post; } /** @param array $rule @return array */ function attach_rule_scope(AppContext $ctx, array $rule): array { if (empty($rule['dynamic_scope'])) { $rule['mailbox_snapshot'] = (new MailboxDirectory())->mailboxesForUser($ctx->daUser->username()); } return $rule; } /** @param array $rule */ function enforce_rule_backend_constraints(AppContext $ctx, ?string $currentId, array $rule): void { if ($ctx->settings->backendMode() !== 'da' || empty($rule['enabled'])) { return; } foreach ($ctx->rules->all($ctx->daUser->username()) as $existing) { if (empty($existing['enabled'])) { continue; } if ($currentId !== null && (string)($existing['id'] ?? '') === $currentId) { continue; } throw new RuntimeException($ctx->t('DirectAdmin backend supports only one enabled global rule.')); } } function render_calendar_picker(AppContext $ctx, string $name, string $title, string $value): string { $mode = $ctx->settings->scheduleMode(); $selectedDate = substr($value, 0, 10); if (!preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $selectedDate)) { $selectedDate = date('Y-m-d'); } $selectedTime = '09:00'; $selectedPeriod = 'morning'; if ($mode === 'exact_hour' && preg_match('/T([0-9]{2}:[0-9]{2})$/', $value, $m)) { $selectedTime = $m[1]; } elseif ($mode === 'directadmin_period' && preg_match('/\|(morning|afternoon|evening)$/', $value, $m)) { $selectedPeriod = $m[1]; } $selectedDt = DateTimeImmutable::createFromFormat('!Y-m-d', $selectedDate) ?: new DateTimeImmutable('today'); $monthStart = $selectedDt->modify('first day of this month'); $days = render_calendar_days($name, $selectedDate, $monthStart); $visibleMonth = $monthStart->format('Y-m'); $monthLabel = calendar_month_label($ctx, $monthStart); if ($mode === 'exact_hour') { $timeControl = ''; } else { $timeControl = ''; } return '

' . AppContext::e($title) . '

' . AppContext::e($title) . '

' . AppContext::e($monthLabel) . '
' . '' . render_weekday_headers($ctx) . '' . $days . '
' . '
' . AppContext::e($ctx->t('Selected')) . ': ' . AppContext::e($selectedDate) . '
' . '

' . AppContext::e($ctx->t('Time')) . '

' . $timeControl . '
' . '
'; } function render_preview_box(AppContext $ctx, array $rule): string { $subjectPrefix = (string)($rule['subject_prefix'] ?? $rule['subject'] ?? ''); return '
' . AppContext::e($ctx->t('Subject prefix')) . ': ' . AppContext::e($subjectPrefix) . '

' . nl2br(AppContext::e((string)$rule['body'])) . '
'; } function render_weekday_headers(AppContext $ctx): string { $html = ''; foreach (['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] as $day) { $html .= '' . AppContext::e($ctx->t($day)) . ''; } return $html; } function render_calendar_days(string $name, string $selectedDate, DateTimeImmutable $monthStart): string { $offset = ((int)$monthStart->format('N')) - 1; $daysInMonth = (int)$monthStart->format('t'); $html = ''; $day = 1; for ($week = 0; $week < 6; $week++) { $html .= ''; for ($i = 0; $i < 7; $i++) { if (($week === 0 && $i < $offset) || $day > $daysInMonth) { $html .= ''; continue; } $date = $monthStart->setDate((int)$monthStart->format('Y'), (int)$monthStart->format('m'), $day)->format('Y-m-d'); $class = $date === $selectedDate ? ' is-selected' : ''; $html .= ''; $day++; } $html .= ''; if ($day > $daysInMonth) { break; } } return $html; } function calendar_month_label(AppContext $ctx, DateTimeImmutable $monthStart): string { $pl = ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień']; $en = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; $months = $ctx->lang->code() === 'pl' ? $pl : $en; return $months[((int)$monthStart->format('n')) - 1] . ' ' . $monthStart->format('Y'); }