Skip to content
Snippets Groups Projects
Commit 6bc2e00f authored by Sofiane Lasri's avatar Sofiane Lasri
Browse files

Merge branch '15-ajouter-mentions-legales' into 'master'

Resolve "Ajouter mentions légales"

Closes #15

See merge request !56
parents 4dabbbdb 6c991ca3
Branches
No related tags found
1 merge request!56Resolve "Ajouter mentions légales"
Pipeline #1010 passed
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\LegalMention;
use App\Models\Translation;
use App\Models\TranslationKey;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\View\View;
class LegalMentionController extends Controller
{
protected array $headerRoutes = [
[
'route' => 'admin.legal_mentions.index',
'label' => 'Liste des mentions légales',
'icon' => 'list',
],
[
'route' => 'admin.legal_mentions.create',
'label' => 'Créer une mention légale',
'icon' => 'plus',
],
];
public function index(): View
{
$mentions = LegalMention::with('contentTransKey.translations')->get();
return view('admin.legal_mentions.index', [
'headerRoutes' => $this->headerRoutes,
'mentions' => $mentions,
]);
}
public function createPage(): View
{
return view('admin.legal_mentions.edit', [
'title' => 'Créer une mention légale',
'headerRoutes' => $this->headerRoutes,
]);
}
public function editPage(Request $request, int $id): View
{
$request->validate([
'lang' => 'sometimes|string|in:fr,en',
]);
$lang = $request->input('lang', 'fr');
$mention = LegalMention::findOrFail($id);
$content = $mention->contentTransKey->getTranslation($lang);
return view('admin.legal_mentions.edit', [
'title' => 'Modifier une mention légale',
'headerRoutes' => $this->headerRoutes,
'mention' => $mention,
'content' => $content,
'lang' => $lang,
'active' => $mention->active,
]);
}
public function store(Request $request): RedirectResponse
{
$request->validate([
'lang' => 'required|string|in:fr,en',
'content' => 'required|string',
'active' => 'sometimes|string|in:on',
]);
$contentTransKey = TranslationKey::create(['key' => 'legal_content_'.Str::uuid()]);
Translation::create(['translation_key_id' => $contentTransKey->id, 'locale' => $request->input('lang'), 'text' => $request->input('content')]);
$mention = LegalMention::create([
'content_trans_key_id' => $contentTransKey->id,
'active' => $request->has('active'),
]);
$this->updateActiveStatus($mention, $request->has('active'));
$mention->save();
return redirect()->route('admin.legal_mentions.index')->with('success', 'Mention légale créée avec succès.');
}
public function update(Request $request, int $id): RedirectResponse
{
$request->validate([
'lang' => 'required|string|in:fr,en',
'content' => 'required|string',
'active' => 'sometimes|string|in:on',
]);
$mention = LegalMention::findOrFail($id);
Translation::updateOrCreate(
['translation_key_id' => $mention->contentTransKey->id, 'locale' => $request->input('lang')],
['text' => $request->input('content')]
);
$this->updateActiveStatus($mention, $request->has('active'));
$mention->save();
return redirect()->route('admin.legal_mentions.edit', [
'id' => $mention->id,
'lang' => $request->input('lang'),
])->with('success', 'Mention légale mise à jour avec succès.');
}
public function delete(int $id): RedirectResponse
{
$mention = LegalMention::findOrFail($id);
$mention->delete();
return redirect()->route('admin.legal_mentions.index')->with('success', 'Mention légale supprimée avec succès.');
}
private function updateActiveStatus(LegalMention $mention, bool $active): void
{
if ($active) {
LegalMention::where('id', '!=', $mention->id)->update(['active' => false]);
$mention->active = true;
} else {
$mention->active = false;
}
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class LegalMention extends Model
{
use HasFactory;
protected $fillable = [
'content_trans_key_id',
'active',
];
public function contentTransKey(): BelongsTo
{
return $this->belongsTo(TranslationKey::class, 'content_trans_key_id');
}
protected function casts(): array
{
return [
'active' => 'boolean',
];
}
}
......@@ -44,6 +44,11 @@
'route' => 'admin.terms.index',
'icon' => 'file-contract',
],
[
'title' => 'Mentions légales',
'route' => 'admin.legal_mentions.index',
'icon' => 'file-contract',
],
],
],
];
<?php
namespace Database\Factories;
use App\Models\LegalMention;
use App\Models\TranslationKey;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Carbon;
class LegalMentionFactory extends Factory
{
protected $model = LegalMention::class;
public function definition(): array
{
return [
'active' => $this->faker->boolean(),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
'content_trans_key_id' => TranslationKey::factory(),
];
}
}
<?php
use App\Models\TranslationKey;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('legal_mentions', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(TranslationKey::class, 'content_trans_key_id');
$table->boolean('active');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('legal_mentions');
}
};
@extends('layouts.admin', ['title' => $title, 'headerRoutes' => $headerRoutes])
@section('content')
<div class="grid">
<div class="g-col-12 g-col-md-6">
<h5>Information</h5>
<p>Gérez le contenu des mentions légales.</p>
<form action="{{ !empty($mention) ? route('admin.legal_mentions.update', $mention->id) : route('admin.legal_mentions.store') }}"
method="post">
@csrf
@if(!empty($mention))
@method('PUT')
@endif
<x-bs.select id="lang-select" label="Langue" name="lang"
:options="['fr' => 'Français', 'en' => 'Anglais']"
class="mb-3" :selected="old('lang', $lang ?? 'fr')"/>
<x-admin.markdown-editor label="Contenu" name="content" class="mb-3"
:value="old('content', $content ?? '')"
required/>
<x-bs.checkbox name="active" label="Activer cette mention légale"
:checked="old('active', $active ?? false)" class="mb-3"/>
<x-bs.button type="submit">Enregistrer</x-bs.button>
</form>
@if (!empty($errors) && $errors->any())
<x-bs.alert type="danger" class="mt-3">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</x-bs.alert>
@endif
@if (session('success'))
<x-bs.alert type="success" class="mt-3">
{{ session('success') }}
</x-bs.alert>
@endif
</div>
</div>
@endsection
@pushonce('scripts')
<script type="text/javascript">
const langSelect = document.getElementById('lang-select');
const url = new URL(window.location.href);
if (url.pathname.endsWith('/edit') && !url.searchParams.has('lang') && langSelect) {
url.searchParams.set('lang', langSelect.value);
window.location.href = url.toString();
}
if (url.pathname.endsWith('/edit') && langSelect) {
langSelect.addEventListener('change', function () {
url.searchParams.set('lang', langSelect.value);
window.location.href = url.toString();
});
}
</script>
@endpushonce
@extends('layouts.admin', ['title' => 'Mentions légales', 'headerRoutes' => $headerRoutes])
@section('content')
<h5>Mentions légales</h5>
<p>Gérez les mentions légales.</p>
@if (session('success'))
<x-bs.alert type="success" class="mt-3">
{{ session('success') }}
</x-bs.alert>
@endif
<table class="table">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Contenu (Français)</th>
<th scope="col">Contenu (Anglais)</th>
<th scope="col">Active</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
@foreach($mentions as $mention)
<tr>
<th scope="row">{{ $mention->id }}</th>
<td>{{ $mention->contentTransKey->getTranslation('fr') }}</td>
<td>{{ $mention->contentTransKey->getTranslation('en') }}</td>
<td>{{ $mention->active ? 'Oui' : 'Non' }}</td>
<td>
<x-bs.button size="sm" tag="a" href="{{ route('admin.legal_mentions.edit', $mention->id) }}"
variant="primary">
Modifier
</x-bs.button>
<x-bs.button href="{{ route('admin.legal_mentions.delete', $mention->id) }}" size="sm" tag="a"
variant="danger">
Supprimer
</x-bs.button>
</td>
</tr>
@endforeach
@if($mentions->isEmpty())
<tr>
<td colspan="5" class="text-center">Aucune mention légale
trouvée. {{ \Spatie\Emoji\Emoji::desert() }}</td>
</tr>
@endif
</tbody>
</table>
@endsection
......@@ -2,7 +2,7 @@
@section('content')
<h5>Information</h5>
<p>Gérez les sections des Conditions Générales de Vente.</p>
<p>Gérez les sections des Conditions générales de vente.</p>
@if (session('success'))
<x-bs.alert type="success" class="mt-3">
......
......@@ -5,6 +5,7 @@
use App\Http\Controllers\Admin\CreationController;
use App\Http\Controllers\Admin\EventController;
use App\Http\Controllers\Admin\HomeController;
use App\Http\Controllers\Admin\LegalMentionController;
use App\Http\Controllers\Admin\PrestationController;
use App\Http\Controllers\Admin\SettingsController;
use App\Http\Controllers\Admin\SocialMediaLinksController;
......@@ -134,6 +135,14 @@
Route::get('/{section}/delete', [TermsSectionController::class, 'delete'])->name('delete');
});
Route::prefix('legal-mentions')->name('legal_mentions.')->group(function () {
Route::get('/', [LegalMentionController::class, 'index'])->name('index');
Route::get('/create', [LegalMentionController::class, 'createPage'])->name('create');
Route::post('/', [LegalMentionController::class, 'store'])->name('store');
Route::get('/{id}/edit', [LegalMentionController::class, 'editPage'])->name('edit');
Route::put('/{id}', [LegalMentionController::class, 'update'])->name('update');
Route::get('/{id}/delete', [LegalMentionController::class, 'delete'])->name('delete');
});
});
Route::get('/logout', function () {
......
<?php
namespace Tests\Feature\Controller;
use App\Http\Controllers\Admin\LegalMentionController;
use App\Models\LegalMention;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use PHPUnit\Framework\Attributes\CoversClass;
use Tests\TestCase;
#[CoversClass(LegalMentionController::class)]
class LegalMentionTest extends TestCase
{
use RefreshDatabase, WithoutMiddleware;
public function test_it_can_list_legal_mentions()
{
LegalMention::factory()->count(3)->create();
$response = $this->get(route('admin.legal_mentions.index'));
$response->assertStatus(200);
$response->assertViewIs('admin.legal_mentions.index');
$response->assertViewHas('mentions');
$this->assertCount(3, $response->viewData('mentions'));
}
public function test_it_can_create_a_legal_mention()
{
$data = [
'lang' => 'fr',
'content' => 'Contenu des mentions légales',
'active' => 'on',
];
$response = $this->post(route('admin.legal_mentions.store'), $data);
$response->assertRedirect(route('admin.legal_mentions.index'));
$this->assertDatabaseHas('translations', ['text' => 'Contenu des mentions légales', 'locale' => 'fr']);
$this->assertDatabaseHas('legal_mentions', ['active' => true]);
}
public function test_it_fails_to_create_a_legal_mention_without_content()
{
$response = $this->post(route('admin.legal_mentions.store'), [
'lang' => 'fr',
]);
$response->assertSessionHasErrors('content');
}
public function test_it_can_edit_a_legal_mention()
{
$mention = LegalMention::factory()->create();
$response = $this->get(route('admin.legal_mentions.edit', ['id' => $mention->id]));
$response->assertStatus(200);
$response->assertViewIs('admin.legal_mentions.edit');
$response->assertViewHas('mention', $mention);
}
public function test_it_can_update_a_legal_mention()
{
$mention = LegalMention::factory()->create();
$data = [
'lang' => 'fr',
'content' => 'Nouveau contenu',
'active' => 'on',
];
$response = $this->put(route('admin.legal_mentions.update', ['id' => $mention->id]), $data);
$response->assertRedirect(route('admin.legal_mentions.edit', ['id' => $mention->id, 'lang' => 'fr']));
$this->assertDatabaseHas('translations', ['text' => 'Nouveau contenu', 'locale' => 'fr']);
$this->assertDatabaseHas('legal_mentions', ['id' => $mention->id, 'active' => true]);
}
public function test_it_can_delete_a_legal_mention()
{
$mention = LegalMention::factory()->create();
$response = $this->get(route('admin.legal_mentions.delete', ['id' => $mention->id]));
$response->assertRedirect(route('admin.legal_mentions.index'));
$this->assertDatabaseMissing('legal_mentions', ['id' => $mention->id]);
}
public function test_it_cannot_delete_a_nonexistent_legal_mention()
{
$response = $this->get(route('admin.legal_mentions.delete', ['id' => 999]));
$response->assertStatus(404);
}
public function test_it_can_delete_an_active_legal_mention()
{
$mention = LegalMention::factory()->create(['active' => true]);
$response = $this->get(route('admin.legal_mentions.delete', ['id' => $mention->id]));
$response->assertRedirect(route('admin.legal_mentions.index'));
$this->assertDatabaseMissing('legal_mentions', ['id' => $mention->id]);
}
}
......@@ -66,4 +66,21 @@ public function test_it_can_delete_a_terms_section()
$response->assertRedirect(route('admin.terms.index'));
$this->assertDatabaseMissing('terms_sections', ['id' => $section->id]);
}
public function test_it_cannot_delete_a_nonexistent_terms_section()
{
$response = $this->get(route('admin.terms.delete', 999));
$response->assertStatus(404);
}
public function test_it_can_delete_an_active_terms_section()
{
$section = TermsSection::factory()->create(['active' => true]);
$response = $this->get(route('admin.terms.delete', $section->id));
$response->assertRedirect(route('admin.terms.index'));
$this->assertDatabaseMissing('terms_sections', ['id' => $section->id]);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment