Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions app/Console/Commands/CertificateSendWindow.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,16 @@ private function sendWindowForType(int $edition, string $type, int $limit, bool

$queued = 0;
$failed = 0;
$failures = [];

foreach ($rows as $excellence) {
$bar->advance();
$user = $excellence->user;
if (! $user || ! $user->email) {
$err = 'No user or email';
$failed++;
$excellence->update(['certificate_sent_error' => 'No user or email']);
$excellence->update(['certificate_sent_error' => $err]);
$failures[] = ['id' => $excellence->id, 'email' => $user?->email ?? '-', 'error' => $err];
continue;
}

Expand All @@ -105,14 +108,19 @@ private function sendWindowForType(int $edition, string $type, int $limit, bool
]);
$queued++;
} catch (\Throwable $e) {
$err = $e->getMessage();
$failed++;
$excellence->update(['certificate_sent_error' => $e->getMessage()]);
$excellence->update(['certificate_sent_error' => $err]);
$failures[] = ['id' => $excellence->id, 'email' => $user->email, 'error' => $err];
}
}

$bar->finish();
$this->newLine();
$this->line(" [{$type}] Done. Queued: {$queued}, Failed: {$failed}.");
if ($failed > 0 && count($failures) > 0) {
$this->table(['id', 'email', 'error'], $failures);
}
return ['processed' => $rows->count(), 'queued' => $queued, 'failed' => $failed];
}

Expand Down
4 changes: 4 additions & 0 deletions app/Http/Controllers/CertificateBackendController.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public function listRecipients(Request $request): JsonResponse
->where('edition', $edition)
->where('type', $type)
->with('user')
->orderByRaw('CASE WHEN certificate_sent_error IS NOT NULL THEN 0 ELSE 1 END')
->orderByRaw('CASE WHEN certificate_generation_error IS NOT NULL THEN 0 ELSE 1 END')
->orderBy('id');

if ($search !== '') {
Expand Down Expand Up @@ -352,6 +354,8 @@ public function errorsList(Request $request)
$q->whereNotNull('certificate_generation_error')->orWhereNotNull('certificate_sent_error');
})
->with('user')
->orderByRaw('CASE WHEN certificate_sent_error IS NOT NULL THEN 0 ELSE 1 END')
->orderByRaw('CASE WHEN certificate_generation_error IS NOT NULL THEN 0 ELSE 1 END')
->orderBy('id')
->get();

Expand Down
57 changes: 55 additions & 2 deletions app/Nova/HomeSlide.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,36 @@ public static function localeOptions(): array

private const OVERRIDE_KEYS = ['title', 'description', 'button_text', 'button2_text'];

private static function isAbsoluteImageUrl(?string $value): bool
{
if (! is_string($value) || trim($value) === '') {
return false;
}

return str_starts_with($value, 'http://') || str_starts_with($value, 'https://');
}

private static function fillImageFromInputs($request, $model): void
{
$path = trim((string) $request->get('image_path_input', ''));
$url = trim((string) $request->get('image_url_input', ''));

// URL wins when both are provided.
if ($url !== '') {
$model->image = $url;
return;
}

if ($path !== '') {
$model->image = ltrim($path, '/');
return;
}

if ($request->exists('image_path_input') || $request->exists('image_url_input')) {
$model->image = null;
}
}

private static function parseOverrideAttribute(string $attribute): ?array
{
if (! str_starts_with($attribute, 'override_') || strlen($attribute) < 12) {
Expand Down Expand Up @@ -227,9 +257,32 @@ public function fields(Request $request): array
->help('Leave empty to hide second button. Lang key or plain text.'),
Boolean::make('Open second link in new tab', 'open_second_new_tab')
->help('Open the second button link in a new window/tab.'),
Text::make('Image', 'image')
Text::make('Image (saved value)', 'image')
->exceptOnForms()
->nullable()
->help('Path from site root e.g. images/dream-jobs/dream_jobs_bg.png (no leading slash), or full URL. Used as slide background.'),
->help('Stored image reference used by the homepage slider.'),
Text::make('Image path (site root)', 'image_path_input')
->onlyOnForms()
->nullable()
->resolveUsing(function () {
$image = $this->resource->image;
return self::isAbsoluteImageUrl($image) ? '' : (string) ($image ?? '');
})
->fillUsing(function ($request, $model) {
self::fillImageFromInputs($request, $model);
})
->help('Option 1: local path like images/dream-jobs/dream_jobs_bg.png (no leading slash).'),
Text::make('Image URL (full)', 'image_url_input')
->onlyOnForms()
->nullable()
->resolveUsing(function () {
$image = $this->resource->image;
return self::isAbsoluteImageUrl($image) ? (string) $image : '';
})
->fillUsing(function ($request, $model) {
self::fillImageFromInputs($request, $model);
})
->help('Option 2: full URL, e.g. https://codeweek-resources.s3.eu-west-1.amazonaws.com/...'),
Number::make('Position', 'position')
->min(0)
->default(0)
Expand Down
Loading