Skip to content
Merged

Dev #3264

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
35 changes: 31 additions & 4 deletions app/Http/Controllers/ResourcesImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Services\ResourcesUploadValidator;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Storage;
use Illuminate\View\View;
use Maatwebsite\Excel\Facades\Excel;
Expand Down Expand Up @@ -131,26 +132,52 @@ public function preview(Request $request): View|RedirectResponse
->with('info', 'No preview data found. Please upload and verify a file first.');
}

$path = $request->session()->get(self::SESSION_FILE_PATH);
$importPayload = $path ? Crypt::encryptString(json_encode([
'path' => $path,
'focus' => $focus,
])) : '';

return view('admin.resources-import.preview', [
'rows' => $rows,
'focus' => $focus,
'import_payload' => $importPayload,
]);
}

/**
* Run import with session file and request edits; clear session; redirect to report.
* Run import with file path (from form payload or session) and request edits; redirect to report.
* Uses encrypted form payload so import works when session is not shared (e.g. load-balanced servers).
*/
public function import(Request $request): RedirectResponse
{
$path = $request->session()->get(self::SESSION_FILE_PATH);
$path = null;
$focus = false;

$payload = $request->input('import_payload');
if (is_string($payload) && $payload !== '') {
try {
$decoded = json_decode(Crypt::decryptString($payload), true);
if (is_array($decoded) && ! empty($decoded['path'])) {
$path = $decoded['path'];
$focus = (bool) ($decoded['focus'] ?? false);
}
} catch (\Throwable $e) {
// Invalid or expired payload, fall back to session
}
}

if (! $path) {
$path = $request->session()->get(self::SESSION_FILE_PATH);
$focus = $request->session()->get(self::SESSION_FOCUS, false);
}

if (! $path || ! Storage::exists($path)) {
$request->session()->forget([self::SESSION_FILE_PATH, self::SESSION_ROWS, self::SESSION_FOCUS]);

return redirect()->route('admin.resources-import.index')
->withErrors(['import' => 'No verified file found. Please upload and verify a file first.']);
}

$focus = $request->session()->get(self::SESSION_FOCUS, false);
$edits = $request->input('edits', []);
if (! is_array($edits)) {
$edits = [];
Expand Down
12 changes: 10 additions & 2 deletions resources/views/admin/resources-import/preview.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
</section>

<section class="codeweek-content-wrapper">
<p class="mb-4">Review and edit the parsed rows below. All fields are editable. Then click <strong>Import</strong> to run the import.</p>
<p class="mb-4">Review and edit the parsed rows below. All fields are editable. Then click <strong>Import</strong> to run the import. Complete the import soon; if you see &ldquo;419 Page Expired&rdquo;, your session timed out — go back to <a href="{{ route('admin.resources-import.index') }}">Upload &amp; verify</a> and try again.</p>

@if ($errors->any())
<div class="mb-4 p-4 rounded bg-red-50 border border-red-200">
Expand All @@ -20,8 +20,9 @@
</div>
@endif

<form method="POST" action="{{ route('admin.resources-import.import') }}" class="codeweek-form">
<form id="resources-import-form" method="POST" action="{{ route('admin.resources-import.import') }}" class="codeweek-form">
@csrf
<input type="hidden" name="import_payload" value="{{ $import_payload ?? '' }}">

<div class="overflow-x-auto mb-4">
<table class="w-full border-collapse border border-gray-300">
Expand Down Expand Up @@ -119,6 +120,13 @@ class="w-full min-w-[160px] px-2 py-1 border rounded text-sm" placeholder="https
</div>
</div>
</form>
<script>
document.getElementById('resources-import-form').addEventListener('submit', function () {
var meta = document.querySelector('meta[name="csrf-token"]');
var tokenInput = this.querySelector('input[name="_token"]');
if (meta && tokenInput) tokenInput.value = meta.getAttribute('content');
});
</script>
</section>
</section>
@endsection
Loading