Compare commits

...
Sign in to create a new pull request.

5 commits

Author SHA1 Message Date
Noah Lancien
e8d24cd36a Merge branch 'develop' into add-seo-to-ranges 2024-07-17 12:22:41 +02:00
Noah Lancien
fab7138905 fix: cleaned some routes 2024-07-17 12:09:58 +02:00
Noah Lancien
e912af7ecc Deleted staticPage for 1 range 2024-01-05 16:41:41 +01:00
Noah Lancien
1a0a865e83 Fixed phpcs 2024-01-05 15:15:47 +00:00
Noah Lancien
7831ff3bee Added seo title and description to ranges 2024-01-05 16:08:23 +01:00
17 changed files with 203 additions and 78 deletions

View file

@ -13,7 +13,6 @@ enum StaticPageType: int
case confidentiality = 3;
case home = 4;
case ranges = 5;
case range = 6;
case klub = 7;
case klub_register = 8;
case history = 9;
@ -29,7 +28,6 @@ enum StaticPageType: int
self::confidentiality->name => 'Confidentialité',
self::home->name => 'Accueil',
self::ranges->name => 'Nos gammes',
self::range->name => 'Une gamme',
self::klub->name => 'Le Klub',
self::klub_register->name => 'Le Klub - Inscription',
self::history->name => 'Notre Histoire',

View file

@ -38,13 +38,13 @@ class NewsController extends Controller
/**
* Show a specific resource.
*
* @param \App\Models\News $frontNews
* @param \App\Models\News $publishedNews
* @return \Illuminate\Contracts\View\View
*/
public function show(News $frontNews): \Illuminate\Contracts\View\View
public function show(News $publishedNews): \Illuminate\Contracts\View\View
{
return view('fo.pages.news.show', [
'newsModel' => $frontNews
'newsModel' => $publishedNews
]);
}
}

View file

@ -13,30 +13,25 @@ class ProductController extends Controller
/**
* Show a specific resource.
*
* @param string $slug
* @param Product $product
* @return \Illuminate\Contracts\View\View
*/
public function show(string $slug): \Illuminate\Contracts\View\View
public function show(Product $product): \Illuminate\Contracts\View\View
{
$productModel = Product::query()
->with('range')
->where('slug', $slug)
->where('published', true)
->firstOrFail();
$productModels = Product::query()
->where('slug', '!=', $slug)
->whereNot('id', $product->id)
->where('published', true)
->inRandomOrder()->limit(2)->get();
$klubBloc = KlubBloc::query()->first();
$rangeModels = Range::query()->whereNot('id', $productModel->range->id)->limit(2)
$rangeModels = Range::query()->whereNot('id', $product->range->id)->limit(2)
->inRandomOrder()->get();
return view('fo.pages.products.show', compact(
'productModel',
'productModels',
'klubBloc',
'rangeModels'
));
return view('fo.pages.products.show', [
'productModel' => $product,
'productModels' => $productModels,
'klubBloc' => $klubBloc,
'rangeModels' => $rangeModels,
]);
}
/**

View file

@ -27,30 +27,27 @@ class RangeController extends Controller
/**
* Show a specific resource.
*
* @param string $slug
* @param \App\Models\Range $range
* @return \Illuminate\Contracts\View\View
*/
public function show(string $slug): \Illuminate\Contracts\View\View
public function show(Range $range): \Illuminate\Contracts\View\View
{
$rangeModel = Range::query()->where('slug', $slug)->firstOrFail();
$rangeModels = Range::query()->where('slug', '!=', $slug)->limit(2)->inRandomOrder()->get();
$productModels = Product::query()->where('range_id', $rangeModel->id)
$rangeModels = Range::query()->whereNot('id', $range->id)->limit(2)->inRandomOrder()->get();
$productModels = Product::query()->where('range_id', $range->id)
->where('published', true)
->orderBy('order', 'asc')
->paginate(9);
$staticPageModel = StaticPage::query()->where('type', StaticPageType::range)->first();
$newsModels = News::query()
$newsModels = News::query()
->where('published', true)
->orderBy('created_at', 'desc')
->limit(6)
->get();
return view('fo.pages.ranges.show', compact(
'rangeModel',
'rangeModels',
'productModels',
'staticPageModel',
'newsModels'
));
return view('fo.pages.ranges.show', [
'rangeModel' => $range,
'rangeModels' => $rangeModels,
'productModels' => $productModels,
'newsModels' => $newsModels,
]);
}
}

View file

@ -40,6 +40,8 @@ class StoreRangeRequest extends FormRequest
public function rules(): array
{
$rules = [
'seo_title' => 'required|between:45,70',
'seo_description' => 'required|between:50,160',
'label' => 'required|string|between:3,255',
'picture_alt' => 'required|string|between:3,255',
'picture_title' => 'required|string|between:3,255',
@ -71,6 +73,8 @@ class StoreRangeRequest extends FormRequest
public function attributes(): array
{
return [
'seo_title' => trans('validation.custom.seo_title'),
'seo_description' => trans('validation.custom.seo_description'),
'label' => trans('validation.custom.label'),
'picture_alt' => trans('validation.custom.attribute_alt'),
'picture_title' => trans('validation.attributes.attribute_title'),

View file

@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
/**
* @property integer $id ID.
* @property string $seo_title Utilisé pour la balise title de la page.
* @property string $seo_description Utilisé pour la balise meta description
* de la page.

View file

@ -11,6 +11,9 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
/**
* @property integer $id ID.
* @property string $seo_title Utilisé pour la balise title de la page.
* @property string $seo_description Utilisé pour la balise meta description
* @property string $label Label de la gamme.
* @property string $slug Slug à partir du label de la gamme.
* @property string $picture Path de l'image de la gamme (579px * 579px).
@ -46,6 +49,8 @@ class Range extends Model
* @var array<int, string>
*/
protected $fillable = [
'seo_title',
'seo_description',
'label',
'picture',
'picture_alt',

View file

@ -48,7 +48,21 @@ class RouteServiceProvider extends ServiceProvider
->group(base_path('routes/web-fo.php'));
});
Route::bind('frontNews', fn ($value) => News::query()->where('slug', $value)->firstOrFail());
Route::bind('frontRange', fn ($value) => Range::query()->where('slug', $value)->firstOrFail());
Route::bind(
'publishedNews',
fn ($value) => News::query()
->where('published', true)
->where('slug', $value)
->firstOrFail()
);
Route::bind(
'publishedProduct',
fn ($value) => Product::query()
->where('published', true)
->where('slug', $value)
->firstOrFail()
);
Route::model('user', User::class);
Route::model('picto', Picto::class);
Route::model('range', Range::class);

View file

@ -9,7 +9,7 @@
"diglactic/laravel-breadcrumbs": "^8.0",
"guzzlehttp/guzzle": "^7.2",
"jenssegers/agent": "^2.6",
"laravel/framework": "^10.0",
"laravel/framework": "^10.34",
"laravel/tinker": "^2.8",
"laravel/ui": "^4.2",
"ldc/ldccrmv4client": "^4.0",

50
composer.lock generated
View file

@ -8277,16 +8277,16 @@
},
{
"name": "composer/semver",
"version": "3.4.0",
"version": "3.4.2",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
"reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
"url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6",
"reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6",
"shasum": ""
},
"require": {
@ -8338,7 +8338,7 @@
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.4.0"
"source": "https://github.com/composer/semver/tree/3.4.2"
},
"funding": [
{
@ -8354,7 +8354,7 @@
"type": "tidelift"
}
],
"time": "2023-08-31T09:50:34+00:00"
"time": "2024-07-12T11:35:52+00:00"
},
{
"name": "dealerdirect/phpcodesniffer-composer-installer",
@ -10261,26 +10261,26 @@
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
"myclabs/deep-copy": "^1.10.1",
"phar-io/manifest": "^2.0.3",
"phar-io/version": "^3.0.2",
"myclabs/deep-copy": "^1.12.0",
"phar-io/manifest": "^2.0.4",
"phar-io/version": "^3.2.1",
"php": ">=8.1",
"phpunit/php-code-coverage": "^10.1.5",
"phpunit/php-file-iterator": "^4.0",
"phpunit/php-invoker": "^4.0",
"phpunit/php-text-template": "^3.0",
"phpunit/php-timer": "^6.0",
"sebastian/cli-parser": "^2.0",
"sebastian/code-unit": "^2.0",
"sebastian/comparator": "^5.0",
"sebastian/diff": "^5.0",
"sebastian/environment": "^6.0",
"sebastian/exporter": "^5.1",
"sebastian/global-state": "^6.0.1",
"sebastian/object-enumerator": "^5.0",
"sebastian/recursion-context": "^5.0",
"sebastian/type": "^4.0",
"sebastian/version": "^4.0"
"phpunit/php-code-coverage": "^10.1.15",
"phpunit/php-file-iterator": "^4.1.0",
"phpunit/php-invoker": "^4.0.0",
"phpunit/php-text-template": "^3.0.1",
"phpunit/php-timer": "^6.0.0",
"sebastian/cli-parser": "^2.0.1",
"sebastian/code-unit": "^2.0.0",
"sebastian/comparator": "^5.0.1",
"sebastian/diff": "^5.1.1",
"sebastian/environment": "^6.1.0",
"sebastian/exporter": "^5.1.2",
"sebastian/global-state": "^6.0.2",
"sebastian/object-enumerator": "^5.0.0",
"sebastian/recursion-context": "^5.0.0",
"sebastian/type": "^4.0.0",
"sebastian/version": "^4.0.1"
},
"suggest": {
"ext-soap": "To be able to generate mocks based on WSDL files"

View file

@ -16,6 +16,8 @@ class RangeFactory extends Factory
{
$label = fake()->text(15);
return [
'seo_title' => fake()->sentence(),
'seo_description' => fake()->sentence(),
'label' => $label,
'slug' => Str::slug($label),
'picture_alt' => fake()->sentence(),

View file

@ -0,0 +1,47 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up(): void
{
$ranges = DB::table('ranges')->get();
Schema::table('ranges', function (Blueprint $table) {
$table->string('seo_title')->after('id')
->comment('Utilisé pour la balise title de la page de gamme');
$table->string('seo_description')->after('seo_title')
->comment('Utilisé pour la balise meta description de la page de gamme');
});
$ranges->each(function (object $range) {
DB::table('ranges')->where('id', $range->id)
->update([
'seo_title' => $range->label,
'seo_description' => $range->label,
]);
});
// The 6th value in the StaticPageType Enum has been removed, so we need to use the value instead of the enum.
DB::table('static_pages')->where('type', 6)->delete();
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down(): void
{
Schema::table('ranges', function (Blueprint $table) {
$table->dropColumn('seo_title');
$table->dropColumn('seo_description');
});
}
};

View file

@ -69,16 +69,6 @@ class StaticPageSeeder extends Seeder
'content' => \clean(\fake()->randomHtml(2, 3)),
]
)->saveQuietly();
StaticPage::query()->make(
[
'seo_title' => 'Seo title pour la page Une Gamme',
'seo_description' => 'Seo description pour la page Une Gamme',
'title' => 'Une Gamme',
'slug' => Str::slug('Une Gamme'),
'type' => StaticPageType::range,
'content' => \clean(\fake()->randomHtml(2, 3)),
]
)->saveQuietly();
StaticPage::query()->make(
[
'seo_title' => 'Seo title pour la page Actualités',

View file

@ -1,4 +1,76 @@
<div class="row">
{{-- SEO --}}
<div class="col-12 pb-3">
<fieldset class="h-100 border p-3">
<legend>{{ Str::ucfirst(__('validation.custom.seo')) }}</legend>
<div class="row mb-3">
{{-- SEO_TITLE --}}
<div class="col-12 col-md-6 m-md-0 mb-3">
@include('bo.partials.inputs.varchar', [
'id' => 'rangeSeoTitle',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_title')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.range'),
]),
'hasWordCounter' => true,
'name' => 'seo_title',
'required' => true,
'model' => $rangeModel ?? null,
'helper' => sprintf(
'%s %s',
__('crud.helpers.seo_title'),
__('validation.between.string', [
'attribute' => __(':field :inter:model', [
'field' => __('validation.custom.seo_title'),
'inter' => __('validation.custom.of_the.female'),
'model' => __('models.classes.range'),
]),
'min' => 45,
'max' => 70,
])),
'placeholder' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_title')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.range'),
]),
])
</div>
{{-- SEO_DESCRIPTION --}}
<div class="col-12 col-md-6 m-md-0 mb-3">
@include('bo.partials.inputs.varchar-multiline', [
'id' => 'rangeSeoDescription',
'label' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_description')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.range'),
]),
'hasWordCounter' => true,
'name' => 'seo_description',
'required' => true,
'model' => $rangeModel ?? null,
'helper' => sprintf(
'%s %s',
__('crud.helpers.seo_description'),
__('validation.between.string', [
'attribute' => __(':field :inter:model', [
'field' => __('validation.custom.seo_description'),
'inter' => __('validation.custom.of_the.female'),
'model' => __('models.classes.range'),
]),
'min' => 50,
'max' => 160,
])),
'placeholder' => __(':field :inter:model', [
'field' => Str::ucfirst(__('validation.custom.seo_description')),
'inter' => __('validation.custom.of_the.male'),
'model' => __('models.classes.range'),
]),
])
</div>
</div>
</fieldset>
</div>
{{-- LABEL --}}
<div class="col-12 col-md-6 mb-3">
<fieldset class="h-100 border p-3">

View file

@ -1,7 +1,7 @@
@extends('fo.layout')
@section('title', __($staticPageModel->seo_title))
@section('description', __($staticPageModel->seo_description))
@section('title', __($rangeModel->seo_title))
@section('description', __($rangeModel->seo_description))
@section('breadcrumb',
request()->route()->getName())

View file

@ -5,11 +5,11 @@
}
window.__SYSTEM._routes.fo = {
ranges: {
show: "{{ route('fo.ranges.show', ['slug' => 'SLUG']) }}"
show: "{{ route('fo.ranges.show', ['frontRange' => 'SLUG']) }}"
},
products: {
filtered: "{{ route('fo.products.filtered') }}",
show: "{{ route('fo.products.show', ['slug' => 'SLUG']) }}"
show: "{{ route('fo.products.show', ['publishedProduct' => 'SLUG']) }}"
},
};
</script>

View file

@ -58,15 +58,15 @@ Route::middleware(['throttle:credentials'])->name('fo.')->group(function () {
// * NEWS
Route::get('/actualites', [NewsController::class, 'index'])->name('news.index');
Route::get('/actualites/{frontNews:slug}', [NewsController::class, 'show'])->name('news.show');
Route::get('/actualites/{publishedNews:slug}', [NewsController::class, 'show'])->name('news.show');
// * RANGES
Route::get('/gammes', [RangeController::class, 'index'])->name('ranges.index');
Route::get('/gamme/{slug}', [RangeController::class, 'show'])->name('ranges.show');
Route::get('/gamme/{frontRange:slug}', [RangeController::class, 'show'])->name('ranges.show');
// * PRODUCTS
Route::get('/produit/filtered', [ProductController::class, 'productsFiltered'])->name('products.filtered');
Route::get('/produit/{slug}', [ProductController::class, 'show'])->name('products.show');
Route::get('/produit/{publishedProduct:slug}', [ProductController::class, 'show'])->name('products.show');
// * COMMITMENTS
Route::get('/nos-engagements', [CommitmentController::class, 'show'])->name('commitments.show');