Compare commits
No commits in common. "develop" and "multiple-issues" have entirely different histories.
develop
...
multiple-i
349 changed files with 10519 additions and 20530 deletions
20
.env.example
20
.env.example
|
|
@ -43,21 +43,5 @@ GOOGLE_RECAPTCHA_PUBLIC=
|
||||||
GOOGLE_RECAPTCHA_PRIVATE=
|
GOOGLE_RECAPTCHA_PRIVATE=
|
||||||
GOOGLE_RECAPTCHA_VERSION=
|
GOOGLE_RECAPTCHA_VERSION=
|
||||||
|
|
||||||
# UWIL ADMIN SECURE
|
# LDC Web Admin Secure
|
||||||
# - LIST SEPARATED WITH ',' (Required)
|
LDC_WEB_API_KEY="MY_KEY"
|
||||||
UWIL_ADMIN_SECURE_CIDR_LIST=""
|
|
||||||
# - LIST SEPARATED WITH ',' (Optional)
|
|
||||||
UWIL_ADMIN_SECURE_CIDR_PROJECT_ALLOWED_LIST=""
|
|
||||||
|
|
||||||
|
|
||||||
# SAML
|
|
||||||
SAML2_DEFAULT_TENANT_UUID=
|
|
||||||
SAML2_SP_CERT_x509=
|
|
||||||
SAML2_SP_CERT_PRIVATEKEY=
|
|
||||||
SAML2_CONTACT_TECHNICAL_EMAIL=
|
|
||||||
SAML2_CONTACT_SUPPORT_EMAIL=
|
|
||||||
|
|
||||||
# CRM
|
|
||||||
CRM_ENDPOINT=
|
|
||||||
CRM_PASSWORD=
|
|
||||||
CRM_TOKEN=
|
|
||||||
|
|
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -23,9 +23,6 @@ Homestead.yaml
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
.npmrc
|
.npmrc
|
||||||
.zshrc
|
|
||||||
.npm/
|
|
||||||
.composer/
|
|
||||||
|
|
||||||
# Ignore public favicon
|
# Ignore public favicon
|
||||||
/public/android-chrome-192x192.png
|
/public/android-chrome-192x192.png
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ include:
|
||||||
file: 'security/security.yml'
|
file: 'security/security.yml'
|
||||||
- project: 'ldc-web/shared-ci'
|
- project: 'ldc-web/shared-ci'
|
||||||
ref: 'main'
|
ref: 'main'
|
||||||
file: 'build/docker-multistage.yml'
|
file: 'build/build.yml'
|
||||||
- project: 'ldc-web/shared-ci'
|
- project: 'ldc-web/shared-ci'
|
||||||
ref: 'main'
|
ref: 'main'
|
||||||
file: 'test/test.yml'
|
file: 'test/test.yml'
|
||||||
|
|
|
||||||
48
Dockerfile
48
Dockerfile
|
|
@ -1,47 +1,5 @@
|
||||||
ARG PHP_8_5_TAG=latest
|
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/ldcweb-production-8.2:latest
|
||||||
|
COPY --chown=www-data:www-data . /app/srcs
|
||||||
FROM composer:2.8 AS vendor
|
|
||||||
|
|
||||||
ARG GITLAB_USER
|
|
||||||
ARG GITLAB_PASSWORD
|
|
||||||
|
|
||||||
COPY database/ database/
|
|
||||||
|
|
||||||
COPY composer.json composer.json
|
|
||||||
COPY composer.lock composer.lock
|
|
||||||
|
|
||||||
RUN composer config gitlab-token.lab.s-web.fr ${GITLAB_USER} ${GITLAB_PASSWORD}
|
|
||||||
RUN composer install \
|
|
||||||
--ignore-platform-reqs \
|
|
||||||
--no-interaction \
|
|
||||||
--no-plugins \
|
|
||||||
--no-scripts \
|
|
||||||
--no-dev \
|
|
||||||
--prefer-dist
|
|
||||||
|
|
||||||
FROM node:20.18 AS frontend
|
|
||||||
|
|
||||||
ARG GITLAB_PASSWORD
|
|
||||||
|
|
||||||
RUN mkdir -p /app/public/build
|
|
||||||
|
|
||||||
COPY package*.json tsconfig.json vite.config.ts .eslintrc.json .stylelintrc.json /app/
|
|
||||||
COPY resources/ /app/resources/
|
|
||||||
WORKDIR /app
|
|
||||||
RUN npm config set @ldc-web:registry https://lab.s-web.fr/api/v4/packages/npm/
|
|
||||||
RUN npm config set -- '//lab.s-web.fr/api/v4/packages/npm/:_authToken' "${GITLAB_PASSWORD}"
|
|
||||||
RUN npm ci && npm run prod
|
|
||||||
|
|
||||||
ARG PHP_8_5_TAG
|
|
||||||
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/uwil-production-8.5:${PHP_8_5_TAG}
|
|
||||||
|
|
||||||
ARG USER=www-data
|
|
||||||
|
|
||||||
COPY --chown=${USER}:${USER} . /app/srcs
|
|
||||||
COPY --chown=${USER}:${USER} ./resources/favicon /app/srcs/public
|
|
||||||
COPY --from=vendor --chown=${USER}:${USER} /app/vendor/ /app/srcs/vendor/
|
|
||||||
COPY --from=frontend --chown=${USER}:${USER} /app/public/build/ /app/srcs/public/build/
|
|
||||||
|
|
||||||
USER root
|
USER root
|
||||||
RUN chmod -R 755 /app/srcs/storage
|
RUN chmod -R 755 /app/srcs/storage
|
||||||
USER ${USER}
|
USER www-data
|
||||||
|
|
@ -15,10 +15,10 @@ class HtmlColor implements CastsAttributes
|
||||||
/**
|
/**
|
||||||
* Cast the given value.
|
* Cast the given value.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Model $model
|
* @param Model $model
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $attributes
|
* @param array $attributes
|
||||||
* @return string
|
* @return string
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
||||||
|
|
@ -32,10 +32,10 @@ class HtmlColor implements CastsAttributes
|
||||||
/**
|
/**
|
||||||
* Prepare the given value for storage.
|
* Prepare the given value for storage.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Model $model
|
* @param Model $model
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $attributes
|
* @param array $attributes
|
||||||
* @return integer
|
* @return integer
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ class RgbaColor extends HtmlColor
|
||||||
/**
|
/**
|
||||||
* Cast the given value.
|
* Cast the given value.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Model $model
|
* @param Model $model
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $attributes
|
* @param array $attributes
|
||||||
* @return string
|
* @return string
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
||||||
|
|
@ -24,7 +24,6 @@ class RgbaColor extends HtmlColor
|
||||||
public function get($model, $key, $value, $attributes)
|
public function get($model, $key, $value, $attributes)
|
||||||
{
|
{
|
||||||
// phpcs:enable
|
// phpcs:enable
|
||||||
/** @var \Illuminate\Support\Collection<array-key,int|float> */
|
|
||||||
$intValues = collect(\str_split($this->zeropad(\dechex(\intval($value)), 8), 2))->map(function ($hex) {
|
$intValues = collect(\str_split($this->zeropad(\dechex(\intval($value)), 8), 2))->map(function ($hex) {
|
||||||
return intval(\hexdec($hex));
|
return intval(\hexdec($hex));
|
||||||
});
|
});
|
||||||
|
|
@ -36,10 +35,10 @@ class RgbaColor extends HtmlColor
|
||||||
/**
|
/**
|
||||||
* Prepare the given value for storage.
|
* Prepare the given value for storage.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Model $model
|
* @param Model $model
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
* @param array $attributes
|
* @param array $attributes
|
||||||
* @return integer
|
* @return integer
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
||||||
|
|
|
||||||
35
app/Console/Commands/TestMail.php
Normal file
35
app/Console/Commands/TestMail.php
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
|
||||||
|
class TestMail extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'mail:test';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Send test email to equipe.web@ldc.fr';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
Mail::raw(sprintf('UWIL mail-test from %s %s', \config('app.name'), \config('app.url')), function ($msg) {
|
||||||
|
$msg->to('equipe.web@ldc.fr')->subject('Test Email');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
|
|
@ -14,7 +15,7 @@ class UserCreate extends Command
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'uwil:user:create';
|
protected $signature = 'user:create';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The console command description.
|
* The console command description.
|
||||||
|
|
@ -24,26 +25,33 @@ class UserCreate extends Command
|
||||||
protected $description = 'Create a backend admin user';
|
protected $description = 'Create a backend admin user';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The first name of the new user.
|
* The firstname of the new user.
|
||||||
*
|
*
|
||||||
* @var string|null
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $firstname;
|
protected $firstname;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last name of the new user.
|
* The lastname of the new user.
|
||||||
*
|
*
|
||||||
* @var string|null
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $lastname;
|
protected $lastname;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The email of the new user.
|
* The email of the new user.
|
||||||
*
|
*
|
||||||
* @var string|null
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $email;
|
protected $email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The password of the new user.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $password;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the console command.
|
* Execute the console command.
|
||||||
*
|
*
|
||||||
|
|
@ -52,18 +60,23 @@ class UserCreate extends Command
|
||||||
public function handle(): int
|
public function handle(): int
|
||||||
{
|
{
|
||||||
$this->firstname = null;
|
$this->firstname = null;
|
||||||
$this->addFirstName();
|
$this->addFirstname();
|
||||||
|
|
||||||
$this->lastname = null;
|
$this->lastname = null;
|
||||||
$this->addLastName();
|
$this->addLastname();
|
||||||
|
|
||||||
$this->email = null;
|
$this->email = null;
|
||||||
$this->addEmail();
|
$this->addEmail();
|
||||||
|
|
||||||
|
$this->password = null;
|
||||||
|
$this->addPassword();
|
||||||
|
|
||||||
$user = new User([
|
$user = new User([
|
||||||
'firstname' => $this->firstname,
|
'firstname' => $this->firstname,
|
||||||
'lastname' => $this->lastname,
|
'lastname' => $this->lastname,
|
||||||
'email' => $this->email
|
'email' => $this->email,
|
||||||
|
'password' => $this->password,
|
||||||
|
'last_connection' => Carbon::now(),
|
||||||
]);
|
]);
|
||||||
$user->saveOrFail();
|
$user->saveOrFail();
|
||||||
|
|
||||||
|
|
@ -73,15 +86,15 @@ class UserCreate extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a first name to the user.
|
* Add a firstname to the user.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function addFirstName(): void
|
private function addFirstname(): void
|
||||||
{
|
{
|
||||||
while (is_null($this->firstname)) {
|
while (is_null($this->firstname)) {
|
||||||
try {
|
try {
|
||||||
$tmp = $this->ask('Type the wanted user first name', 'Admin');
|
$tmp = $this->ask('Type the wanted user firstname', 'Admin');
|
||||||
$validator = Validator::make(['firstname' => $tmp], [
|
$validator = Validator::make(['firstname' => $tmp], [
|
||||||
'firstname' => 'required|min:3|max:255'
|
'firstname' => 'required|min:3|max:255'
|
||||||
]);
|
]);
|
||||||
|
|
@ -89,24 +102,24 @@ class UserCreate extends Command
|
||||||
$this->firstname = $tmp;
|
$this->firstname = $tmp;
|
||||||
} catch (ValidationException $e) {
|
} catch (ValidationException $e) {
|
||||||
$this->error(sprintf(
|
$this->error(sprintf(
|
||||||
'Please provide a valid first name %s',
|
'Please provide a valid firstname %s',
|
||||||
\implode(',', collect($e->errors())->flatten()->all())
|
\implode(',', collect($e->errors())->flatten()->all())
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
} //end try
|
} //end try
|
||||||
};
|
}; //end while
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a last name to the user.
|
* Add a lastname to the user.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private function addLastName(): void
|
private function addLastname(): void
|
||||||
{
|
{
|
||||||
while (is_null($this->lastname)) {
|
while (is_null($this->lastname)) {
|
||||||
try {
|
try {
|
||||||
$tmp = $this->ask('Type the wanted user last name', 'Saïtama');
|
$tmp = $this->ask('Type the wanted user lastname', 'Saïtama');
|
||||||
$validator = Validator::make(['lastname' => $tmp], [
|
$validator = Validator::make(['lastname' => $tmp], [
|
||||||
'lastname' => 'required|min:3|max:255'
|
'lastname' => 'required|min:3|max:255'
|
||||||
]);
|
]);
|
||||||
|
|
@ -119,7 +132,7 @@ class UserCreate extends Command
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
} //end try
|
} //end try
|
||||||
};
|
}; //end while
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -144,6 +157,22 @@ class UserCreate extends Command
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
} //end try
|
} //end try
|
||||||
};
|
}; //end while
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a password to the user.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private function addPassword(): void
|
||||||
|
{
|
||||||
|
while (
|
||||||
|
($this->password = $this->secret(
|
||||||
|
(!\is_null($this->password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||||
|
)) !== $this->secret('Confirm the password')
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}; //end while
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ enum AdviceDifficultyEnum: int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition.
|
* Optionnal labels definition.
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::easy->name => 'Facile',
|
self::easy->name => 'Facile',
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@ enum AdviceTimeEnum: int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition.
|
* Optionnal labels definition.
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::first->name => '0 - 30min',
|
self::first->name => '0 - 30min',
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,16 @@ namespace App\Enums\Advices;
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
use App\Traits\Enums\BaseEnum;
|
||||||
|
|
||||||
enum AdviceTypeEnum: string
|
enum AdviceTypeEnum: int
|
||||||
{
|
{
|
||||||
use BaseEnum;
|
use BaseEnum;
|
||||||
|
|
||||||
case all = '0';
|
case all = 0;
|
||||||
case recipes = '1';
|
case recipes = 1;
|
||||||
case tips = '2';
|
case tips = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition
|
* Optionnal labels definition
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::all->name => 'Recettes / Astuces',
|
self::all->name => 'Recettes / Astuces',
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ enum ContactActivityEnum: int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition.
|
* Optionnal labels definition.
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::distributeur->name => 'Distributeur',
|
self::distributeur->name => 'Distributeur',
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ enum ContactTimeEnum: int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition.
|
* Optionnal labels definition.
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::morning->name => 'Le matin',
|
self::morning->name => 'Le matin',
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ enum ExpertiseProductPageEnum: int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition.
|
* Optionnal labels definition.
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::duck->name => 'Canard',
|
self::duck->name => 'Canard',
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ enum NutriscoreEnum: int
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition.
|
* Optionnal labels definition.
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::noLetter->name => 'Ø',
|
self::noLetter->name => 'Ø',
|
||||||
|
|
|
||||||
|
|
@ -8,36 +8,32 @@ enum ProductSpeciesEnum: int
|
||||||
{
|
{
|
||||||
use BaseEnum;
|
use BaseEnum;
|
||||||
|
|
||||||
case caille = 0;
|
case caille = 0;
|
||||||
case canard = 1;
|
case canard = 1;
|
||||||
case canette = 2;
|
case canette = 2;
|
||||||
case coq = 3;
|
case coq = 3;
|
||||||
case coquelet = 4;
|
case coquelet = 4;
|
||||||
case dinde = 5;
|
case dinde = 5;
|
||||||
case lapin = 6;
|
case lapin = 6;
|
||||||
case pigeonneau = 7;
|
case pigeonneau = 7;
|
||||||
case pintade = 8;
|
case pintade = 8;
|
||||||
case poule = 9;
|
case poule = 9;
|
||||||
case poulet = 10;
|
case poulet = 10;
|
||||||
case volaille_festive = 11;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optionnal labels definition.
|
* Optionnal labels definition.
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
*/
|
||||||
private const LABELS = [
|
private const LABELS = [
|
||||||
self::caille->name => 'Caille',
|
self::caille->name => 'Caille',
|
||||||
self::canard->name => 'Canard',
|
self::canard->name => 'Canard',
|
||||||
self::canette->name => 'Canette',
|
self::canette->name => 'Canette',
|
||||||
self::coq->name => 'Coq',
|
self::coq->name => 'Coq',
|
||||||
self::coquelet->name => 'Coquelet',
|
self::coquelet->name => 'Coquelet',
|
||||||
self::dinde->name => 'Dinde',
|
self::dinde->name => 'Dinde',
|
||||||
self::lapin->name => 'Lapin',
|
self::lapin->name => 'Lapin',
|
||||||
self::pigeonneau->name => 'Pigeonneau',
|
self::pigeonneau->name => 'Pigeonneau',
|
||||||
self::pintade->name => 'Pintade',
|
self::pintade->name => 'Pintade',
|
||||||
self::poule->name => 'Poule',
|
self::poule->name => 'Poule',
|
||||||
self::poulet->name => 'Poulet',
|
self::poulet->name => 'Poulet'
|
||||||
self::volaille_festive->name => 'Volaille festive'
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
|
||||||
|
|
||||||
enum StaticPageType: int
|
|
||||||
{
|
|
||||||
use BaseEnum;
|
|
||||||
|
|
||||||
case contact = 1;
|
|
||||||
case legals = 2;
|
|
||||||
case confidentiality = 3;
|
|
||||||
case expertise_guineafowl = 4;
|
|
||||||
case expertise_turkey = 5;
|
|
||||||
case expertise_chicken = 6;
|
|
||||||
case expertise_duck = 7;
|
|
||||||
case expertise_rabbit = 8;
|
|
||||||
case sitemap = 9;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optionnal labels definition.
|
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
|
||||||
private const LABELS = [
|
|
||||||
self::contact->name => 'Contact',
|
|
||||||
self::legals->name => 'Mentions légales',
|
|
||||||
self::confidentiality->name => 'Confidentialité',
|
|
||||||
self::expertise_guineafowl->name => 'Expertise pintade',
|
|
||||||
self::expertise_turkey->name => 'Expertise dinde',
|
|
||||||
self::expertise_chicken->name => 'Expertise poulet',
|
|
||||||
self::expertise_duck->name => 'Expertise canard',
|
|
||||||
self::expertise_rabbit->name => 'Expertise lapin',
|
|
||||||
self::sitemap->name => 'Plan du site',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Enums;
|
|
||||||
|
|
||||||
use App\Traits\Enums\BaseEnum;
|
|
||||||
|
|
||||||
enum TagTypeEnum: int
|
|
||||||
{
|
|
||||||
use BaseEnum;
|
|
||||||
|
|
||||||
case recipes = 1;
|
|
||||||
case products = 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optionnal labels definition.
|
|
||||||
*
|
|
||||||
* @phpstan-ignore-next-line
|
|
||||||
*/
|
|
||||||
private const LABELS = [
|
|
||||||
self::recipes->name => 'Recettes / Astuces',
|
|
||||||
self::products->name => 'Produits',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
@ -3,40 +3,42 @@
|
||||||
namespace App\Http\Controllers\Bo;
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
use App\Enums\Advices\AdviceTypeEnum;
|
use App\Enums\Advices\AdviceTypeEnum;
|
||||||
use App\Enums\TagTypeEnum;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Bo\Advice\StoreAdviceRequest;
|
use App\Http\Requests\Bo\Advice\StoreAdviceRequest;
|
||||||
use App\Http\Requests\Bo\Advice\UpdateAdviceRequest;
|
use App\Http\Requests\Bo\Advice\UpdateAdviceRequest;
|
||||||
use App\Models\Advice;
|
use App\Models\Advice;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Models\Tag;
|
use App\Models\Tag;
|
||||||
use App\Traits\Controllers\ManagesOrder;
|
use App\Traits\Controllers\UpdateModelStatus;
|
||||||
use App\Traits\Controllers\UpdateModelPublished;
|
|
||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Arr;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class AdviceController extends Controller
|
class AdviceController extends Controller
|
||||||
{
|
{
|
||||||
use UpdateModelPublished;
|
use UpdateModelStatus;
|
||||||
use ManagesOrder;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @param \App\Enums\Advices\AdviceTypeEnum|null $type
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function index(Request $request, AdviceTypeEnum|null $type = null): \Illuminate\Contracts\View\View
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$type = $type ?: AdviceTypeEnum::all;
|
/** @var \Illuminate\Database\Eloquent\Builder $advice */
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $adviceModels */
|
|
||||||
$adviceModels = Advice::query();
|
$adviceModels = Advice::query();
|
||||||
|
$type = $request->input('type');
|
||||||
|
|
||||||
$adviceModels->when(!$type->equals(AdviceTypeEnum::all), fn (Builder $q) => $q->where('type', $type));
|
if (empty($currentType = AdviceTypeEnum::make(\intval($type)))) {
|
||||||
|
abort(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$adviceModels->when(isset($type), function ($adviceModels) use ($currentType) {
|
||||||
|
if ($currentType->value() !== AdviceTypeEnum::all->value()) {
|
||||||
|
$adviceModels->where('type', '=', $currentType->value());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/** @var string|null $search Search field */
|
/** @var string|null $search Search field */
|
||||||
$search = $request->input('search');
|
$search = $request->input('search');
|
||||||
|
|
@ -56,44 +58,47 @@ class AdviceController extends Controller
|
||||||
/** Custom pagination */
|
/** Custom pagination */
|
||||||
$adviceModels = $this->paginate($adviceModels);
|
$adviceModels = $this->paginate($adviceModels);
|
||||||
|
|
||||||
return view('bo.pages.advice.index', [
|
return view('bo.pages.advice.index', compact('adviceModels', 'currentType', 'search', 'searchFields'));
|
||||||
'adviceModels' => $adviceModels,
|
|
||||||
'currentType' => $type,
|
|
||||||
'search' => $search,
|
|
||||||
'searchFields' => $searchFields
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*
|
*
|
||||||
* @param \App\Enums\Advices\AdviceTypeEnum $type
|
* @param Request $request
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function create(AdviceTypeEnum $type): \Illuminate\Contracts\View\View
|
public function create(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$advice = new Advice();
|
$advice = new Advice();
|
||||||
$adviceTags = Tag::query()->where('type', TagTypeEnum::recipes)->select(['id', 'label', 'slug'])->get();
|
$type = $request->type;
|
||||||
|
$currentType = AdviceTypeEnum::make(\intval($type));
|
||||||
|
$adviceTags = Tag::query()->select(['id', 'label', 'slug'])->get();
|
||||||
$adviceProducts = Product::all();
|
$adviceProducts = Product::all();
|
||||||
$recipeList = Advice::query()->where('type', '=', AdviceTypeEnum::recipes)->get();
|
$recipeList = Advice::where('type', '=', AdviceTypeEnum::recipes)->get();
|
||||||
$tipList = Advice::query()->where('type', '=', AdviceTypeEnum::tips)->get();
|
$tipList = Advice::where('type', '=', AdviceTypeEnum::tips)->get();
|
||||||
|
|
||||||
|
$recipeList = collect($recipeList)->each(function (Advice &$value) {
|
||||||
|
$value->label = $value->title;
|
||||||
|
});
|
||||||
|
$tipList = collect($tipList)->each(function (Advice &$value) {
|
||||||
|
$value->label = $value->title;
|
||||||
|
});
|
||||||
|
|
||||||
$recipesSelected = collect();
|
$recipesSelected = collect([]);
|
||||||
$tipsSelected = collect();
|
$tipsSelected = collect([]);
|
||||||
collect($advice->advices)
|
collect($advice->advices)->each(function ($eltAdvice) use (&$recipesSelected, &$tipsSelected) {
|
||||||
// @phpstan-ignore-next-line
|
if ($eltAdvice->type->value == AdviceTypeEnum::recipes->value()) {
|
||||||
->each(function (Advice $eltAdvice) use (&$recipesSelected, &$tipsSelected) {
|
$eltAdvice->label = $eltAdvice->title;
|
||||||
if ($eltAdvice->type->equals(AdviceTypeEnum::recipes)) {
|
$recipesSelected = $recipesSelected->concat([$eltAdvice]);
|
||||||
$recipesSelected = $recipesSelected->concat([$eltAdvice]);
|
} elseif ($eltAdvice->type->value == AdviceTypeEnum::tips->value()) {
|
||||||
} elseif ($eltAdvice->type->equals(AdviceTypeEnum::tips)) {
|
$eltAdvice->label = $eltAdvice->title;
|
||||||
$tipsSelected = $tipsSelected->concat([$eltAdvice]);
|
$tipsSelected = $tipsSelected->concat([$eltAdvice]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return view('bo.pages.advice.create', [
|
return view('bo.pages.advice.create', [
|
||||||
'adviceModel' => $advice,
|
'adviceModel' => $advice,
|
||||||
'currentType' => $type,
|
'currentType' => $currentType,
|
||||||
'adviceTags' => $adviceTags,
|
'adviceTags' => $adviceTags,
|
||||||
'adviceProducts' => $adviceProducts,
|
'adviceProducts' => $adviceProducts,
|
||||||
'recipeList' => $recipeList,
|
'recipeList' => $recipeList,
|
||||||
|
|
@ -113,19 +118,14 @@ class AdviceController extends Controller
|
||||||
{
|
{
|
||||||
return DB::transaction(function () use ($request) {
|
return DB::transaction(function () use ($request) {
|
||||||
$advice = new Advice();
|
$advice = new Advice();
|
||||||
$advice->fill(Arr::except($request->validated(), [
|
$advice->fill($request->validated());
|
||||||
'tags',
|
|
||||||
'products',
|
|
||||||
'associated_tips_list',
|
|
||||||
'associated_recipes_list',
|
|
||||||
]));
|
|
||||||
|
|
||||||
$currentType = AdviceTypeEnum::make(\intval($request->type));
|
$currentType = AdviceTypeEnum::make(\intval($request->type));
|
||||||
|
|
||||||
if ($advice->saveOrFail()) {
|
if ($advice->saveOrFail()) {
|
||||||
$advice->tags()->sync(collect($request->input('tags'))->pluck('id'));
|
$advice->tags()->sync(collect($request->tags)->pluck('id'));
|
||||||
$advice->products()->sync($request->input('products_list'));
|
$advice->products()->sync($request->products_list);
|
||||||
$advice->advices()->sync(array_merge($request->input('recipes_list'), $request->input('tips_list')));
|
$advice->advices()->sync(array_merge($request->recipes_list, $request->tips_list));
|
||||||
|
|
||||||
return redirect()
|
return redirect()
|
||||||
->route('bo.advice.edit', $advice)
|
->route('bo.advice.edit', $advice)
|
||||||
|
|
@ -152,18 +152,37 @@ class AdviceController extends Controller
|
||||||
public function edit(Advice $advice): \Illuminate\Contracts\View\View
|
public function edit(Advice $advice): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$currentType = $advice->type;
|
$currentType = $advice->type;
|
||||||
$adviceTags = Tag::query()->where('type', TagTypeEnum::recipes)
|
$adviceTags = Tag::whereNotIn('id', $advice->tags()->pluck('id'))
|
||||||
->select(['id', 'label', 'slug'])->get();
|
->select(['id', 'label', 'slug'])->get();
|
||||||
$adviceProducts = Product::all();
|
$adviceProducts = Product::all();
|
||||||
$recipeList = Advice::query()->where([
|
$recipeList = Advice::where([
|
||||||
['type', '=', AdviceTypeEnum::recipes],
|
['type', '=', AdviceTypeEnum::recipes],
|
||||||
['id', '!=', $advice->id],
|
['id', '!=', $advice->id],
|
||||||
])->get();
|
])->get();
|
||||||
$tipList = Advice::query()->where([
|
$tipList = Advice::where([
|
||||||
['type', '=', AdviceTypeEnum::tips],
|
['type', '=', AdviceTypeEnum::tips],
|
||||||
['id', '!=', $advice->id],
|
['id', '!=', $advice->id],
|
||||||
])->get();
|
])->get();
|
||||||
|
|
||||||
|
$recipeList = collect($recipeList)->each(function (Advice &$value) {
|
||||||
|
$value->label = $value->title;
|
||||||
|
});
|
||||||
|
$tipList = collect($tipList)->each(function (Advice &$value) {
|
||||||
|
$value->label = $value->title;
|
||||||
|
});
|
||||||
|
|
||||||
|
$recipesSelected = collect([]);
|
||||||
|
$tipsSelected = collect([]);
|
||||||
|
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */
|
||||||
|
$recipesSelected = $advice->recipes()->each(function (Advice &$recipe) {
|
||||||
|
$recipe->label = $recipe->title;
|
||||||
|
});
|
||||||
|
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */
|
||||||
|
$tipsSelected = $advice->tips()->each(function (Advice &$tip) {
|
||||||
|
$tip->label = $tip->title;
|
||||||
|
});
|
||||||
|
|
||||||
return view('bo.pages.advice.edit', [
|
return view('bo.pages.advice.edit', [
|
||||||
'adviceModel' => $advice,
|
'adviceModel' => $advice,
|
||||||
'currentType' => $currentType,
|
'currentType' => $currentType,
|
||||||
|
|
@ -171,8 +190,8 @@ class AdviceController extends Controller
|
||||||
'adviceProducts' => $adviceProducts,
|
'adviceProducts' => $adviceProducts,
|
||||||
'recipeList' => $recipeList,
|
'recipeList' => $recipeList,
|
||||||
'tipList' => $tipList,
|
'tipList' => $tipList,
|
||||||
'recipesSelected' => $advice->recipes,
|
'recipesSelected' => $recipesSelected,
|
||||||
'tipsSelected' => $advice->tips,
|
'tipsSelected' => $tipsSelected,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,16 +205,11 @@ class AdviceController extends Controller
|
||||||
public function update(UpdateAdviceRequest $request, Advice $advice): \Illuminate\Http\RedirectResponse
|
public function update(UpdateAdviceRequest $request, Advice $advice): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
return DB::transaction(function () use ($request, $advice) {
|
return DB::transaction(function () use ($request, $advice) {
|
||||||
$advice->tags()->sync(collect($request->input('tags'))->pluck('id'));
|
$advice->tags()->sync(collect($request->tags)->pluck('id'));
|
||||||
$advice->products()->sync($request->input('products_list'));
|
$advice->products()->sync($request->products_list);
|
||||||
$advice->advices()->sync(array_merge($request->input('recipes_list'), $request->input('tips_list')));
|
$advice->advices()->sync(array_merge($request->recipes_list, $request->tips_list));
|
||||||
|
|
||||||
$advice->fill(Arr::except($request->validated(), [
|
$advice->fill($request->validated());
|
||||||
'tags',
|
|
||||||
'products',
|
|
||||||
'associated_tips_list',
|
|
||||||
'associated_recipes_list',
|
|
||||||
]));
|
|
||||||
|
|
||||||
$currentType = AdviceTypeEnum::make(\intval($request->type));
|
$currentType = AdviceTypeEnum::make(\intval($request->type));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,152 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Bo;
|
|
||||||
|
|
||||||
use App\Http\Requests\Bo\BrigadeSections\StoreBrigadeSectionsRequest;
|
|
||||||
use App\Http\Requests\Bo\BrigadeSections\UpdateBrigadeSectionsRequest;
|
|
||||||
use App\Models\BrigadeSection;
|
|
||||||
use App\Traits\Controllers\ChangesModelOrder;
|
|
||||||
use App\Traits\Controllers\UpdateModelPublished;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Uwil\Laravel\Common\Controllers\Controller;
|
|
||||||
|
|
||||||
class BrigadeSectionController extends Controller
|
|
||||||
{
|
|
||||||
use UpdateModelPublished;
|
|
||||||
use ChangesModelOrder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
|
||||||
{
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $brigadeSectionModels */
|
|
||||||
$brigadeSectionModels = BrigadeSection::query();
|
|
||||||
|
|
||||||
/** @var string $search Search field */
|
|
||||||
$search = $request->search;
|
|
||||||
if ($search) {
|
|
||||||
$this->searchQuery(
|
|
||||||
$brigadeSectionModels,
|
|
||||||
$search,
|
|
||||||
null,
|
|
||||||
'title',
|
|
||||||
'content',
|
|
||||||
'button_text',
|
|
||||||
'button_url'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$searchFields = trans('Titre, Texte, CTA, Lien');
|
|
||||||
|
|
||||||
/** Sort columns with a query */
|
|
||||||
$this->sortQuery($brigadeSectionModels);
|
|
||||||
|
|
||||||
/** Custom pagination */
|
|
||||||
$brigadeSectionModels = $this->paginate($brigadeSectionModels);
|
|
||||||
|
|
||||||
return view('bo.pages.brigade_sections.index', compact('brigadeSectionModels', 'searchFields'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for creating a new resource.
|
|
||||||
*
|
|
||||||
* @param \App\Models\BrigadeSection $brigadeSection
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function create(BrigadeSection $brigadeSection): \Illuminate\Contracts\View\View
|
|
||||||
{
|
|
||||||
$brigadeSection = $brigadeSection->exists() ? $brigadeSection : new BrigadeSection();
|
|
||||||
|
|
||||||
return view('bo.pages.brigade_sections.create', [
|
|
||||||
'brigadeSectionModel' => $brigadeSection,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*
|
|
||||||
* @param \App\Http\Requests\Bo\BrigadeSections\StoreBrigadeSectionsRequest $request
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
|
||||||
public function store(StoreBrigadeSectionsRequest $request): \Illuminate\Http\RedirectResponse
|
|
||||||
{
|
|
||||||
return DB::transaction(function () use ($request) {
|
|
||||||
$brigadeSection = new BrigadeSection();
|
|
||||||
$brigadeSection->fill($request->validated());
|
|
||||||
|
|
||||||
if ($brigadeSection->saveOrFail()) {
|
|
||||||
return redirect()->route('bo.brigade_sections.edit', $brigadeSection->id)
|
|
||||||
->with('success', __('crud.messages.has_been_created', [
|
|
||||||
'model' => trans_choice('models.classes.brigade_section', 1)
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
return redirect()->back()
|
|
||||||
->with('error', __('crud.messages.cannot_be_created', [
|
|
||||||
'model' => trans_choice('models.classes.brigade_section', 1)
|
|
||||||
]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for editing the specified resource.
|
|
||||||
*
|
|
||||||
* @param \App\Models\BrigadeSection $brigadeSection
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function edit(BrigadeSection $brigadeSection): \Illuminate\Contracts\View\View
|
|
||||||
{
|
|
||||||
return view('bo.pages.brigade_sections.edit', [
|
|
||||||
'brigadeSectionModel' => $brigadeSection,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*
|
|
||||||
* @param \App\Http\Requests\Bo\BrigadeSections\UpdateBrigadeSectionsRequest $request
|
|
||||||
* @param \App\Models\BrigadeSection $brigadeSection
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
|
||||||
public function update(UpdateBrigadeSectionsRequest $request, BrigadeSection $brigadeSection): RedirectResponse
|
|
||||||
{
|
|
||||||
return DB::transaction(function () use ($request, $brigadeSection) {
|
|
||||||
$brigadeSection->fill($request->validated());
|
|
||||||
|
|
||||||
if ($brigadeSection->saveOrFail()) {
|
|
||||||
return redirect()->route('bo.brigade_sections.edit', $brigadeSection->id)
|
|
||||||
->with('success', __('crud.messages.has_been_updated', [
|
|
||||||
'model' => trans_choice('models.classes.brigade_section', 1)
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
return redirect()->route('bo.brigade_sections.edit', $brigadeSection->id)
|
|
||||||
->with('error', __('crud.messages.cannot_be_updated', [
|
|
||||||
'model' => trans_choice('models.classes.brigade_section', 1)
|
|
||||||
]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*
|
|
||||||
* @param \App\Models\BrigadeSection $brigadeSection
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
|
||||||
public function destroy(BrigadeSection $brigadeSection): \Illuminate\Http\RedirectResponse
|
|
||||||
{
|
|
||||||
if ($brigadeSection->deleteOrFail()) {
|
|
||||||
return redirect()->route('bo.brigade_sections.index')
|
|
||||||
->with('success', __('crud.messages.has_been_deleted', [
|
|
||||||
'model' => trans_choice('models.classes.brigade_section', 1)
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
return redirect()->back()
|
|
||||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
|
||||||
'model' => trans_choice('models.classes.brigade_section', 1)
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -48,7 +48,7 @@ class ExpertiseProductController extends Controller
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*
|
*
|
||||||
* @param \App\Models\ExpertiseProduct $vip
|
* @param App\Models\ExpertiseProduct $vip
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function create(ExpertiseProduct $vip): \Illuminate\Contracts\View\View
|
public function create(ExpertiseProduct $vip): \Illuminate\Contracts\View\View
|
||||||
|
|
@ -95,8 +95,8 @@ class ExpertiseProductController extends Controller
|
||||||
/**
|
/**
|
||||||
* Update the specified resource in storage.
|
* Update the specified resource in storage.
|
||||||
*
|
*
|
||||||
* @param \App\Http\Requests\Bo\ExpertiseProducts\UpdateExpertiseProductRequest $request
|
* @param \App\Http\Requests\Bo\ExpertiseProduct\UpdateExpertiseProductRequest $request
|
||||||
* @param \App\Models\ExpertiseProduct $vip
|
* @param \App\Models\ExpertiseProduct $vip
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
*/
|
*/
|
||||||
public function update(
|
public function update(
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,14 @@ use App\Http\Requests\Bo\News\UpdateNewsRequest;
|
||||||
use App\Models\News;
|
use App\Models\News;
|
||||||
use App\Models\NewsCategory;
|
use App\Models\NewsCategory;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Traits\Controllers\UpdateModelPublished;
|
use App\Traits\Controllers\UpdateModelStatus;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class NewsController extends Controller
|
class NewsController extends Controller
|
||||||
{
|
{
|
||||||
use UpdateModelPublished;
|
use UpdateModelStatus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
|
|
@ -60,18 +60,18 @@ class NewsController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create(News $news): \Illuminate\Contracts\View\View
|
public function create(News $news): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$news = $news->exists() ? $news : new News();
|
$news = $news ?? new News();
|
||||||
$newsCategories = NewsCategory::all();
|
$newsCategories = NewsCategory::all();
|
||||||
$newsProducts = Product::all();
|
$newsProducts = Product::all();
|
||||||
$newsList = News::all();
|
$newsList = News::all();
|
||||||
|
|
||||||
$newsList = collect($newsList)->each(function (News $value) {
|
$newsList = collect($newsList)->each(function (News &$value) {
|
||||||
$value->setAttribute('label', $value->title);
|
$value->label = $value->title;
|
||||||
});
|
});
|
||||||
|
|
||||||
$newsSelected = collect([]);
|
$newsSelected = collect([]);
|
||||||
collect($news->news ?? [])->each(function (News $value) use (&$newsSelected) {
|
collect($news->news ?? [])->each(function (News &$value) use (&$newsSelected) {
|
||||||
$value->setAttribute('label', $value->title);
|
$value->label = $value->title;
|
||||||
$newsSelected = $newsSelected->concat([$value]);
|
$newsSelected = $newsSelected->concat([$value]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -93,7 +93,7 @@ class NewsController extends Controller
|
||||||
{
|
{
|
||||||
return DB::transaction(function () use ($request) {
|
return DB::transaction(function () use ($request) {
|
||||||
$news = new News();
|
$news = new News();
|
||||||
$news->fill($request->safe()->except(['categories', 'products', 'associated_news_list']));
|
$news->fill($request->validated());
|
||||||
|
|
||||||
if ($news->saveOrFail()) {
|
if ($news->saveOrFail()) {
|
||||||
$news->categories()->sync($request->categories_list);
|
$news->categories()->sync($request->categories_list);
|
||||||
|
|
@ -124,13 +124,13 @@ class NewsController extends Controller
|
||||||
$newsProducts = Product::all();
|
$newsProducts = Product::all();
|
||||||
$newsList = News::where('id', '!=', $news->id)->get();
|
$newsList = News::where('id', '!=', $news->id)->get();
|
||||||
|
|
||||||
$newsList = collect($newsList)->each(function (News $value) {
|
$newsList = collect($newsList)->each(function (\App\Models\News &$value) {
|
||||||
$value->setAttribute('label', $value->title);
|
$value->label = $value->title;
|
||||||
});
|
});
|
||||||
|
|
||||||
$newsSelected = collect([]);
|
$newsSelected = collect([]);
|
||||||
collect($news->news ?? [])->each(function (News $value) use (&$newsSelected) {
|
collect($news->news ?? [])->each(function (\App\Models\News &$value) use (&$newsSelected) {
|
||||||
$value->setAttribute('label', $value->title);
|
$value->label = $value->title;
|
||||||
$newsSelected = $newsSelected->concat([$value]);
|
$newsSelected = $newsSelected->concat([$value]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -156,17 +156,17 @@ class NewsController extends Controller
|
||||||
$news->products()->sync($request->products_list);
|
$news->products()->sync($request->products_list);
|
||||||
$news->news()->sync($request->news_list);
|
$news->news()->sync($request->news_list);
|
||||||
|
|
||||||
$news->fill($request->safe()->except(['categories', 'products', 'associated_news_list']));
|
$news->fill($request->validated());
|
||||||
|
|
||||||
if ($news->saveOrFail()) {
|
if ($news->saveOrFail()) {
|
||||||
return redirect()->route('bo.news.edit', $news->id)
|
return redirect()->route('bo.news.edit', $news->id)
|
||||||
->with('success', __('crud.messages.has_been_updated', [
|
->with('success', __('crud.messages.has_been_updated', [
|
||||||
'model' => Str::singular(__('models.classes.news'))
|
'model' => Str::singular(__('models.classes.news'))
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
return redirect()->route('bo.news.edit', $news->id)
|
return redirect()->route('bo.news.edit', $news->id)
|
||||||
->with('error', __('crud.messages.cannot_be_updated', [
|
->with('error', __('crud.messages.cannot_be_updated', [
|
||||||
'model' => Str::singular(__('models.classes.news'))
|
'model' => Str::singular(__('models.classes.news'))
|
||||||
]));
|
]));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,25 +2,23 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers\Bo;
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
use App\Enums\TagTypeEnum;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Bo\Products\StoreProductRequest;
|
use App\Http\Requests\Bo\Products\StoreProductRequest;
|
||||||
use App\Http\Requests\Bo\Products\UpdateProductRequest;
|
use App\Http\Requests\Bo\Products\UpdateProductRequest;
|
||||||
use App\Lib\Helpers\FileStorageHelper;
|
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Models\Range;
|
|
||||||
use App\Models\Subrange;
|
use App\Models\Subrange;
|
||||||
use App\Models\Tag;
|
use App\Traits\Controllers\HasPicture;
|
||||||
use App\Traits\Controllers\UpdateModelPublished;
|
use App\Traits\Controllers\UpdateModelStatus;
|
||||||
use App\Traits\Controllers\ManagesOrder;
|
use App\Traits\Controllers\ChangesModelOrder;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
class ProductController extends Controller
|
class ProductController extends Controller
|
||||||
{
|
{
|
||||||
use UpdateModelPublished;
|
use ChangesModelOrder;
|
||||||
use ManagesOrder;
|
use UpdateModelStatus;
|
||||||
|
use HasPicture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
|
|
@ -43,13 +41,6 @@ class ProductController extends Controller
|
||||||
'label'
|
'label'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($request->range) {
|
|
||||||
$productModels->whereHas('subrange', function ($q) use ($request) {
|
|
||||||
$q->where('subranges.range_id', '=', $request->range);
|
|
||||||
})->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
$searchFields = trans('Label');
|
$searchFields = trans('Label');
|
||||||
|
|
||||||
/** Sort columns with a query */
|
/** Sort columns with a query */
|
||||||
|
|
@ -58,9 +49,7 @@ class ProductController extends Controller
|
||||||
/** Custom pagination */
|
/** Custom pagination */
|
||||||
$productModels = $this->paginate($productModels);
|
$productModels = $this->paginate($productModels);
|
||||||
|
|
||||||
$ranges = Range::all();
|
return view('bo.pages.products.index', compact('productModels', 'search', 'searchFields'));
|
||||||
|
|
||||||
return view('bo.pages.products.index', compact('productModels', 'search', 'searchFields', 'ranges'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,12 +62,10 @@ class ProductController extends Controller
|
||||||
{
|
{
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $subrangeModels */
|
/** @var \Illuminate\Database\Eloquent\Builder $subrangeModels */
|
||||||
$subrangeModels = Subrange::get();
|
$subrangeModels = Subrange::get();
|
||||||
$productTags = Tag::query()->where('type', TagTypeEnum::products)->select(['id', 'label', 'slug'])->get();
|
|
||||||
|
|
||||||
return view('bo.pages.products.create', [
|
return view('bo.pages.products.create', [
|
||||||
'productModel' => $product,
|
'productModel' => $product,
|
||||||
'subrangeModels' => $subrangeModels,
|
'subrangeModels' => $subrangeModels
|
||||||
'productTags' => $productTags,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,11 +79,10 @@ class ProductController extends Controller
|
||||||
{
|
{
|
||||||
return DB::transaction(function () use ($request) {
|
return DB::transaction(function () use ($request) {
|
||||||
$product = new Product();
|
$product = new Product();
|
||||||
$product->fill($request->safe()->except('tags'));
|
$product->fill($request->validated());
|
||||||
$this->storePictures($request, $product);
|
$this->storePictures($request, $product);
|
||||||
|
|
||||||
if ($product->saveOrFail()) {
|
if ($product->saveOrFail()) {
|
||||||
$product->tags()->sync(collect($request->input('tags'))->pluck('id'));
|
|
||||||
return redirect()->route('bo.products.edit', $product->id)
|
return redirect()->route('bo.products.edit', $product->id)
|
||||||
->with('success', __('crud.messages.has_been_created', [
|
->with('success', __('crud.messages.has_been_created', [
|
||||||
'model' => Str::singular(__('models.classes.products'))
|
'model' => Str::singular(__('models.classes.products'))
|
||||||
|
|
@ -120,13 +106,9 @@ class ProductController extends Controller
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $subrangeModels */
|
/** @var \Illuminate\Database\Eloquent\Builder $subrangeModels */
|
||||||
$subrangeModels = Subrange::get();
|
$subrangeModels = Subrange::get();
|
||||||
|
|
||||||
$productTags = Tag::query()->where('type', TagTypeEnum::products)
|
|
||||||
->select(['id', 'label', 'slug'])->get();
|
|
||||||
|
|
||||||
return view('bo.pages.products.edit', [
|
return view('bo.pages.products.edit', [
|
||||||
'productModel' => $product,
|
'productModel' => $product,
|
||||||
'subrangeModels' => $subrangeModels,
|
'subrangeModels' => $subrangeModels,
|
||||||
'productTags' => $productTags,
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,8 +122,7 @@ class ProductController extends Controller
|
||||||
public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse
|
public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
return DB::transaction(function () use ($request, $product) {
|
return DB::transaction(function () use ($request, $product) {
|
||||||
$product->tags()->sync(collect($request->input('tags'))->pluck('id'));
|
$product->fill($request->validated());
|
||||||
$product->fill($request->safe()->except('tags'));
|
|
||||||
$this->storePictures($request, $product);
|
$this->storePictures($request, $product);
|
||||||
|
|
||||||
if ($product->saveOrFail()) {
|
if ($product->saveOrFail()) {
|
||||||
|
|
@ -167,7 +148,6 @@ class ProductController extends Controller
|
||||||
{
|
{
|
||||||
$product->advices()->sync([]);
|
$product->advices()->sync([]);
|
||||||
$product->news()->sync([]);
|
$product->news()->sync([]);
|
||||||
$product->tags()->sync([]);
|
|
||||||
|
|
||||||
if ($product->deleteOrFail()) {
|
if ($product->deleteOrFail()) {
|
||||||
return redirect()->route('bo.products.index')
|
return redirect()->route('bo.products.index')
|
||||||
|
|
@ -180,22 +160,4 @@ class ProductController extends Controller
|
||||||
'model' => Str::singular(__('models.classes.products'))
|
'model' => Str::singular(__('models.classes.products'))
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Save Model Images
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @param \App\Models\Product $product
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private function storePictures(Request $request, Product $product)
|
|
||||||
{
|
|
||||||
if (is_array($request->input('slider_pictures'))) {
|
|
||||||
$product->slider_pictures = [];
|
|
||||||
$product->slider_pictures = collect($request->file('slider_pictures'))
|
|
||||||
->map(function ($picture) use ($product) {
|
|
||||||
return FileStorageHelper::storeFile($product, $picture, true);
|
|
||||||
})->all();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ use App\Http\Requests\Bo\Slides\StoreSlideRequest;
|
||||||
use App\Http\Requests\Bo\Slides\UpdateSlideRequest;
|
use App\Http\Requests\Bo\Slides\UpdateSlideRequest;
|
||||||
use App\Models\Slide;
|
use App\Models\Slide;
|
||||||
use App\Traits\Controllers\ChangesModelOrder;
|
use App\Traits\Controllers\ChangesModelOrder;
|
||||||
use App\Traits\Controllers\UpdateModelPublished;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
@ -15,7 +14,6 @@ use Illuminate\Support\Str;
|
||||||
class SlideController extends Controller
|
class SlideController extends Controller
|
||||||
{
|
{
|
||||||
use ChangesModelOrder;
|
use ChangesModelOrder;
|
||||||
use UpdateModelPublished;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
|
|
@ -53,7 +51,7 @@ class SlideController extends Controller
|
||||||
/**
|
/**
|
||||||
* Show the form for creating a new resource.
|
* Show the form for creating a new resource.
|
||||||
*
|
*
|
||||||
* @param \App\Models\Slide $slide
|
* @param App\Models\Slide $slide
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function create(Slide $slide): \Illuminate\Contracts\View\View
|
public function create(Slide $slide): \Illuminate\Contracts\View\View
|
||||||
|
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Bo;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Http\Requests\Bo\StaticPages\UpdateStaticPageRequest;
|
|
||||||
use App\Models\StaticPage;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class StaticPageController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Create the controller instance.
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->authorizeResource(StaticPage::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
|
||||||
{
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
|
||||||
$query = StaticPage::query();
|
|
||||||
|
|
||||||
/** @var string $search Search field */
|
|
||||||
$search = $request->search;
|
|
||||||
if ($search) {
|
|
||||||
$this->searchQuery(
|
|
||||||
$query,
|
|
||||||
$search,
|
|
||||||
null,
|
|
||||||
'title',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$searchFields = \implode(', ', [
|
|
||||||
trans('validation.attributes.title'),
|
|
||||||
]);
|
|
||||||
|
|
||||||
/** Sort columns with a query */
|
|
||||||
$this->sortQuery($query);
|
|
||||||
|
|
||||||
/** Custom pagination */
|
|
||||||
$staticPageModelList = $this->paginate($query);
|
|
||||||
|
|
||||||
return view('bo.pages.static_pages.index', compact('staticPageModelList', 'search', 'searchFields'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for editing the specified resource.
|
|
||||||
*
|
|
||||||
* @param \App\Models\StaticPage $static_page
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function edit(StaticPage $static_page): \Illuminate\Contracts\View\View
|
|
||||||
{
|
|
||||||
return view('bo.pages.static_pages.edit', ['staticPageModel' => $static_page]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*
|
|
||||||
* @param \App\Http\Requests\Bo\StaticPages\UpdateStaticPageRequest $request
|
|
||||||
* @param \App\Models\StaticPage $static_page
|
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
|
||||||
*/
|
|
||||||
public function update(UpdateStaticPageRequest $request, StaticPage $static_page): \Illuminate\Http\RedirectResponse
|
|
||||||
{
|
|
||||||
return DB::transaction(function () use ($request, $static_page) {
|
|
||||||
$static_page->fill($request->validated());
|
|
||||||
|
|
||||||
if ($static_page->saveOrFail()) {
|
|
||||||
return redirect()->route('bo.static_pages.edit', $static_page)
|
|
||||||
->with('success', __('crud.messages.has_been_updated', [
|
|
||||||
'model' => Str::ucfirst(\trans_choice('models.classes.static_page', 1))
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
return redirect()->route('bo.static_pages.edit', $static_page)
|
|
||||||
->with('error', __('crud.messages.cannot_be_updated', [
|
|
||||||
'model' => Str::ucfirst(\trans_choice('models.classes.static_page', 1))
|
|
||||||
]));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers\Bo;
|
namespace App\Http\Controllers\Bo;
|
||||||
|
|
||||||
use App\Enums\TagTypeEnum;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Bo\Tags\StoreTagRequest;
|
use App\Http\Requests\Bo\Tags\StoreTagRequest;
|
||||||
use App\Http\Requests\Bo\Tags\UpdateTagRequest;
|
use App\Http\Requests\Bo\Tags\UpdateTagRequest;
|
||||||
|
|
@ -23,7 +22,6 @@ class TagController extends Controller
|
||||||
{
|
{
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $tagModels */
|
/** @var \Illuminate\Database\Eloquent\Builder $tagModels */
|
||||||
$tagModels = Tag::query();
|
$tagModels = Tag::query();
|
||||||
$tagModels = $request->type ? $tagModels->where('type', TagTypeEnum::{$request->type}) : $tagModels;
|
|
||||||
|
|
||||||
/** @var string $search Search field */
|
/** @var string $search Search field */
|
||||||
$search = $request->search;
|
$search = $request->search;
|
||||||
|
|
@ -32,11 +30,10 @@ class TagController extends Controller
|
||||||
$tagModels,
|
$tagModels,
|
||||||
$search,
|
$search,
|
||||||
null,
|
null,
|
||||||
'label',
|
'label'
|
||||||
'type',
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
$searchFields = trans('Nom, Type');
|
$searchFields = trans('Nom');
|
||||||
|
|
||||||
/** Sort columns with a query */
|
/** Sort columns with a query */
|
||||||
$this->sortQuery($tagModels);
|
$this->sortQuery($tagModels);
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use App\Lib\Helpers\ToolboxHelper;
|
||||||
use App\Models\Advice;
|
use App\Models\Advice;
|
||||||
use App\Models\News;
|
use App\Models\News;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
|
|
@ -29,7 +30,7 @@ class Controller extends BaseController
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $query The eloquent query builder.
|
* @param \Illuminate\Database\Eloquent\Builder $query The eloquent query builder.
|
||||||
* @param string $search The query string.
|
* @param string $search The query string.
|
||||||
* @param callable|null $searchQuery The query string.
|
* @param callable $searchQuery The query string.
|
||||||
* @param string ...$fields Either a simple array or a string
|
* @param string ...$fields Either a simple array or a string
|
||||||
* in case of a string the two fields
|
* in case of a string the two fields
|
||||||
* would be concatenate to make the search.
|
* would be concatenate to make the search.
|
||||||
|
|
@ -38,9 +39,9 @@ class Controller extends BaseController
|
||||||
protected function searchQuery(
|
protected function searchQuery(
|
||||||
Builder $query,
|
Builder $query,
|
||||||
string $search,
|
string $search,
|
||||||
callable|null $searchQuery = null,
|
callable $searchQuery = null,
|
||||||
string ...$fields
|
string ...$fields
|
||||||
): \Illuminate\Database\Eloquent\Builder {
|
): Builder {
|
||||||
if (count($fields)) {
|
if (count($fields)) {
|
||||||
// Search using words.
|
// Search using words.
|
||||||
$words = explode(' ', $search);
|
$words = explode(' ', $search);
|
||||||
|
|
@ -69,97 +70,45 @@ class Controller extends BaseController
|
||||||
* @param array $fields
|
* @param array $fields
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
*/
|
*/
|
||||||
private function searchOnFields(
|
private function searchOnFields(Builder $query, string $search, array $fields): Builder
|
||||||
Builder $query,
|
{
|
||||||
string $search,
|
|
||||||
array $fields
|
|
||||||
): \Illuminate\Database\Eloquent\Builder {
|
|
||||||
$table = $query->getModel()->getTable();
|
$table = $query->getModel()->getTable();
|
||||||
foreach ($fields as $field) {
|
foreach ($fields as $f) {
|
||||||
$field = str_replace('?', '\?', $field);
|
$f = str_replace('?', '\?', $f);
|
||||||
if (is_array($field)) {
|
if (is_array($f)) {
|
||||||
$query->orWhereRaw(
|
$query->orWhereRaw(
|
||||||
sprintf("UPPER(CONCAT(%s)) LIKE UPPER(?)", collect($field)->map(function ($q) use ($table) {
|
sprintf("UPPER(CONCAT(%s)) LIKE UPPER(?)", collect($f)->map(function ($q) use ($table) {
|
||||||
return "`$table`.`$q`";
|
return "`$table`.`$q`";
|
||||||
})->implode(', \' \', ')),
|
})->implode(', \' \', ')),
|
||||||
['%' . htmlspecialchars($search) . '%']
|
['%' . filter_var($search, FILTER_SANITIZE_STRING) . '%']
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$query->orWhereRaw(
|
||||||
|
"UPPER(`$table`.`$f`) LIKE UPPER(?)",
|
||||||
|
['%' . filter_var($search, FILTER_SANITIZE_STRING) . '%']
|
||||||
);
|
);
|
||||||
return $query;
|
|
||||||
}
|
}
|
||||||
// Get models woth enum's label.
|
}
|
||||||
if (is_array($this->getSearchValue($query, $search, $field))) {
|
|
||||||
foreach ($this->getSearchValue($query, $search, $field) as $array) {
|
|
||||||
$query->orWhereRaw(
|
|
||||||
"UPPER(`$table`.`$field`) LIKE UPPER(?)",
|
|
||||||
['%' . htmlspecialchars($array->value) . '%']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
// Get models with relation's name/label.
|
|
||||||
if (Str::endsWith($field, '_id')) {
|
|
||||||
$query->orWhereHas(Str::remove('_id', $field), function ($queryRelation) use ($field, $search) {
|
|
||||||
if (Schema::hasColumn(Str::remove('_id', $field) . 's', 'name')) {
|
|
||||||
$queryRelation->where('name', 'like', '%' . $search . '%');
|
|
||||||
} elseif (Schema::hasColumn(Str::remove('_id', $field) . 's', 'label')) {
|
|
||||||
$queryRelation->where('label', 'like', '%' . $search . '%');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
$query->orWhereRaw(
|
|
||||||
"UPPER(`$table`.`$field`) LIKE UPPER(?)",
|
|
||||||
['%' . htmlspecialchars($this->getSearchValue($query, $search, $field)) . '%']
|
|
||||||
);
|
|
||||||
} //end foreach
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the search value (on string or Enum).
|
* Sort columns with a query
|
||||||
*
|
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
|
||||||
* @param string $search
|
|
||||||
* @param string $field
|
|
||||||
* @return string|array
|
|
||||||
*/
|
|
||||||
protected function getSearchValue(Builder $query, string $search, string $field): string|array
|
|
||||||
{
|
|
||||||
$cast = $query->getModel()->getCasts()[$field] ?? null;
|
|
||||||
if (
|
|
||||||
count($query->getModel()->getCasts()) and // Check if the model has casts.
|
|
||||||
$cast and // Check if there is cast about specific field.
|
|
||||||
enum_exists($cast) // Check if the cast is an enum.
|
|
||||||
) {
|
|
||||||
/** @var \App\Traits\Enums $cast */
|
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
$cases = collect($cast::toArray());
|
|
||||||
$enum = $cases->filter(function ($item) use ($search) {
|
|
||||||
return preg_match('/' . Str::lower($search) . '/', Str::lower($item->label));
|
|
||||||
});
|
|
||||||
return $enum->toArray();
|
|
||||||
} else {
|
|
||||||
return $search;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort columns with a query.
|
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||||
* @param array $ignore
|
* @param array $ignore
|
||||||
* @return \Illuminate\Database\Eloquent\Builder
|
* @return \Illuminate\Database\Eloquent\Builder
|
||||||
*/
|
*/
|
||||||
protected function sortQuery(Builder $query, array $ignore = []): \Illuminate\Database\Eloquent\Builder
|
protected function sortQuery(Builder $query, array $ignore = []): Builder
|
||||||
{
|
{
|
||||||
$rName = request()->route()->getName();
|
$rName = request()->route()->getName();
|
||||||
$table = $query->getModel()->getTable();
|
$table = $query->getModel()->getTable();
|
||||||
if (request()->input('sort_col')) {
|
if (request()->sort_col) {
|
||||||
Session::put("$rName.sort_col", request()->input('sort_col'));
|
Session::put("$rName.sort_col", request()->sort_col);
|
||||||
Session::put("$rName.sorted", true);
|
Session::put("$rName.sorted", true);
|
||||||
}
|
}
|
||||||
if (request()->input('sort_way')) {
|
if (request()->sort_way) {
|
||||||
Session::put("$rName.sort_way", request()->input('sort_way'));
|
Session::put("$rName.sort_way", request()->sort_way);
|
||||||
Session::put("$rName.sorted", true);
|
Session::put("$rName.sorted", true);
|
||||||
}
|
}
|
||||||
if (request()->rst) {
|
if (request()->rst) {
|
||||||
|
|
@ -167,29 +116,17 @@ class Controller extends BaseController
|
||||||
Session::remove("$rName.sort_col");
|
Session::remove("$rName.sort_col");
|
||||||
Session::remove("$rName.sort_way");
|
Session::remove("$rName.sort_way");
|
||||||
}
|
}
|
||||||
if (
|
if (request()->sort_col and request()->sort_way and Schema::hasColumn($table, request()->sort_col)) {
|
||||||
request()->input('sort_col') and
|
if (
|
||||||
request()->input('sort_way') and
|
!isset($ignore) or
|
||||||
Schema::hasColumn($table, request()->input('sort_col'))
|
(isset($ignore) and !in_array(request()->sort_col, $ignore))
|
||||||
) {
|
) {
|
||||||
if (!in_array(request()->input('sort_col'), $ignore)) {
|
$query = $query->orderBy(\sprintf("$table.%s", request()->sort_col), request()->sort_way);
|
||||||
$query = $query->orderBy(
|
|
||||||
\sprintf("$table.%s", request()->input('sort_col')),
|
|
||||||
request()->input('sort_way')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} elseif (Schema::hasColumn($table, 'order')) {
|
} elseif (Schema::hasColumn($table, 'order')) {
|
||||||
$query = $query->orderBy('order', 'ASC');
|
$query = $query->orderBy('order', 'ASC');
|
||||||
Session::put("$rName.sort_col", 'order');
|
Session::put("$rName.sort_col", 'order');
|
||||||
Session::put("$rName.sort_way", 'asc');
|
Session::put("$rName.sort_way", 'asc');
|
||||||
} elseif (Schema::hasColumn($table, 'updated_at')) {
|
|
||||||
$query = $query->orderBy('updated_at', 'DESC');
|
|
||||||
Session::put("$rName.sort_col", 'updated_at');
|
|
||||||
Session::put("$rName.sort_way", 'desc');
|
|
||||||
} elseif (Schema::hasColumn($table, 'created_at')) {
|
|
||||||
$query = $query->orderBy('created_at', 'DESC');
|
|
||||||
Session::put("$rName.sort_col", 'created_at');
|
|
||||||
Session::put("$rName.sort_way", 'desc');
|
|
||||||
}
|
}
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
@ -201,17 +138,13 @@ class Controller extends BaseController
|
||||||
* @param \App\Enums\Pagination\ItemsPerPaginationEnum|null $pagination
|
* @param \App\Enums\Pagination\ItemsPerPaginationEnum|null $pagination
|
||||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||||
*/
|
*/
|
||||||
protected function paginate(
|
protected function paginate(Builder $query, ItemsPerPaginationEnum $pagination = null): LengthAwarePaginator
|
||||||
Builder $query,
|
{
|
||||||
ItemsPerPaginationEnum|null $pagination = null
|
|
||||||
): \Illuminate\Contracts\Pagination\LengthAwarePaginator {
|
|
||||||
$currentRoutePath = Str::slug(request()->route()->getName());
|
$currentRoutePath = Str::slug(request()->route()->getName());
|
||||||
$cacheKey = "pagination.{$currentRoutePath}";
|
$cacheKey = "pagination.{$currentRoutePath}";
|
||||||
$pagination = $pagination ?? ItemsPerPaginationEnum::twelve;
|
$pagination = $pagination ?? ItemsPerPaginationEnum::twelve;
|
||||||
$pagination = ToolboxHelper::getValidatedEnum(
|
$pagination = ToolboxHelper::getValidatedPaginate(
|
||||||
Cache::get($cacheKey, $pagination->value()),
|
Cache::get($cacheKey, $pagination->value)
|
||||||
'pagination',
|
|
||||||
'\App\Enums\Pagination\ItemsPerPaginationEnum',
|
|
||||||
);
|
);
|
||||||
if (Cache::get($cacheKey) !== $pagination) {
|
if (Cache::get($cacheKey) !== $pagination) {
|
||||||
Cache::put($cacheKey, $pagination);
|
Cache::put($cacheKey, $pagination);
|
||||||
|
|
@ -237,7 +170,7 @@ class Controller extends BaseController
|
||||||
*/
|
*/
|
||||||
protected function getProductQuery(string $search): Builder
|
protected function getProductQuery(string $search): Builder
|
||||||
{
|
{
|
||||||
return Product::query()->where('published', true)->where(function ($query) use ($search) {
|
return Product::query()->where('status', true)->where(function ($query) use ($search) {
|
||||||
// Par leur désignation.
|
// Par leur désignation.
|
||||||
$query->where('label', 'like', "%{$search}%");
|
$query->where('label', 'like', "%{$search}%");
|
||||||
// Par ingrédients.
|
// Par ingrédients.
|
||||||
|
|
@ -257,12 +190,12 @@ class Controller extends BaseController
|
||||||
// Par espèce.
|
// Par espèce.
|
||||||
if (\strlen($search)) {
|
if (\strlen($search)) {
|
||||||
/** @var \App\Enums\Products\ProductSpeciesEnum|null $specie */
|
/** @var \App\Enums\Products\ProductSpeciesEnum|null $specie */
|
||||||
$specie = \collect(ProductSpeciesEnum::cases())
|
$specie = \collect(ProductSpeciesEnum::toArray())
|
||||||
->filter(function (ProductSpeciesEnum $specie) use ($search) {
|
->filter(function (mixed $specie) use ($search) {
|
||||||
return \strpos(Str::lower($specie->label()), Str::lower($search)) !== false;
|
return \strpos(Str::lower($specie->label), Str::lower($search)) !== false;
|
||||||
})->first();
|
})->first();
|
||||||
if ($specie) {
|
if ($specie) {
|
||||||
$query->orWhere('species', $specie->value());
|
$query->orWhere('species', $specie->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -279,7 +212,7 @@ class Controller extends BaseController
|
||||||
*/
|
*/
|
||||||
protected function getNewsQuery(string $search): Builder
|
protected function getNewsQuery(string $search): Builder
|
||||||
{
|
{
|
||||||
return News::query()->where('published', true)->where(function ($query) use ($search) {
|
return News::query()->where('status', true)->where(function ($query) use ($search) {
|
||||||
$query->where('title', 'like', "%{$search}%");
|
$query->where('title', 'like', "%{$search}%");
|
||||||
$query->orWhere('subtitle', 'like', "%{$search}%");
|
$query->orWhere('subtitle', 'like', "%{$search}%");
|
||||||
$query->orWhere('content', 'like', "%{$search}%");
|
$query->orWhere('content', 'like', "%{$search}%");
|
||||||
|
|
@ -298,7 +231,7 @@ class Controller extends BaseController
|
||||||
*/
|
*/
|
||||||
protected function getRecipeQuery(string $search): Builder
|
protected function getRecipeQuery(string $search): Builder
|
||||||
{
|
{
|
||||||
return Advice::query()->where('published', true)
|
return Advice::query()->where('status', true)
|
||||||
->where('type', '=', AdviceTypeEnum::recipes->value)
|
->where('type', '=', AdviceTypeEnum::recipes->value)
|
||||||
->where(function ($query) use ($search) {
|
->where(function ($query) use ($search) {
|
||||||
$query->where('title', 'like', "%{$search}%");
|
$query->where('title', 'like', "%{$search}%");
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,16 @@ class AdnController extends Controller
|
||||||
return view('fo.pages.adn.adn');
|
return view('fo.pages.adn.adn');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function story(): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
return view('fo.pages.adn.story');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undocumented function
|
* Undocumented function
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Fo;
|
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\BrigadeSection;
|
|
||||||
|
|
||||||
class BrigadeController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function index(): \Illuminate\Contracts\View\View
|
|
||||||
{
|
|
||||||
$sections = BrigadeSection::query()
|
|
||||||
->where('published', true)
|
|
||||||
->orderBy('order')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
return view('fo.pages.brigade', compact(
|
|
||||||
'sections',
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,18 +2,11 @@
|
||||||
|
|
||||||
namespace App\Http\Controllers\Fo;
|
namespace App\Http\Controllers\Fo;
|
||||||
|
|
||||||
use App\Enums\StaticPageType;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Fo\Contact\ContactRequest;
|
use App\Http\Requests\Fo\Contact\ContactRequest;
|
||||||
use App\Mail\ContactFormMail;
|
use App\Mail\ContactFormMail;
|
||||||
use App\Models\StaticPage;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Facades\Mail;
|
use Illuminate\Support\Facades\Mail;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
|
||||||
use LDC\LDCCRM\Exceptions\CrmException;
|
|
||||||
use LDC\LDCCRM\Models\SingleOptin;
|
|
||||||
|
|
||||||
class ContactController extends Controller
|
class ContactController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -24,9 +17,7 @@ class ContactController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index(): \Illuminate\Contracts\View\View
|
public function index(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
/** @var \App\Models\StaticPage */
|
return view('fo.pages.contact');
|
||||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::contact)->firstOrFail();
|
|
||||||
return view('fo.pages.contact', compact('staticPageModel'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -37,63 +28,12 @@ class ContactController extends Controller
|
||||||
*/
|
*/
|
||||||
public function contactSubmit(ContactRequest $request): \Illuminate\Http\RedirectResponse
|
public function contactSubmit(ContactRequest $request): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
$recipients = config('mail.contactsList.contactform');
|
Mail::to(config('mail.contactsList.contactform'))->send(new ContactFormMail($request));
|
||||||
|
|
||||||
if (empty($recipients)) {
|
|
||||||
Log::warning('Aucun destinataire configuré pour le formulaire de contact.');
|
|
||||||
return back()
|
|
||||||
->withErrors(['global' => __('Une erreur est survenue, veuillez réessayer plus tard.')])
|
|
||||||
->withInput();
|
|
||||||
}
|
|
||||||
$redirection = back()->with('success', trans(
|
|
||||||
'Votre message a bien été envoyé, merci de votre intérêt, nous répondrons dans les meilleurs délais.'
|
|
||||||
));
|
|
||||||
|
|
||||||
if ($request->opt_in) {
|
|
||||||
try {
|
|
||||||
SingleOptin::setStatus($request->email, true);
|
|
||||||
} catch (ApiErrorException $e) {
|
|
||||||
\report($e);
|
|
||||||
$redirection = $redirection->withErrors([
|
|
||||||
'opt_in' => trans('Une erreur est survenue,
|
|
||||||
votre inscription à la newsletter n\'a pas été prise en compte.')
|
|
||||||
]);
|
|
||||||
} catch (CrmException $e) {
|
|
||||||
\report($e);
|
|
||||||
$redirection = $redirection->withErrors([
|
|
||||||
'opt_in' => trans('Une erreur est survenue,
|
|
||||||
votre inscription à la newsletter n\'a pas été prise en compte.')
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} //end if
|
|
||||||
|
|
||||||
foreach ($recipients as $recipient) {
|
|
||||||
Mail::to($recipient)->send(new ContactFormMail($request));
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::forget('saveProductInBasket');
|
Session::forget('saveProductInBasket');
|
||||||
|
|
||||||
Session::forget('contact_draft');
|
return back()->with('success', trans(
|
||||||
|
'Votre message a bien été envoyé, merci de votre intérêt, nous répondrons dans les meilleurs délais.'
|
||||||
Session::flash('matomo_generate_lead');
|
));
|
||||||
|
|
||||||
return $redirection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save data form as draft
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @return \Illuminate\Http\JsonResponse
|
|
||||||
*/
|
|
||||||
public function saveDraft(Request $request): \Illuminate\Http\JsonResponse
|
|
||||||
{
|
|
||||||
$request->session()->put('contact_draft', $request->only([
|
|
||||||
'firstname', 'lastname', 'email', 'phone',
|
|
||||||
'activity', 'society', 'postcode', 'city',
|
|
||||||
'message', 'callTime', 'opt_in',
|
|
||||||
]));
|
|
||||||
|
|
||||||
return response()->json(['success' => true]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,125 +5,121 @@ namespace App\Http\Controllers\Fo;
|
||||||
use App\Enums\Advices\AdviceTypeEnum;
|
use App\Enums\Advices\AdviceTypeEnum;
|
||||||
use App\Enums\ExpertiseProducts\ExpertiseProductPageEnum;
|
use App\Enums\ExpertiseProducts\ExpertiseProductPageEnum;
|
||||||
use App\Enums\Products\ProductSpeciesEnum;
|
use App\Enums\Products\ProductSpeciesEnum;
|
||||||
use App\Enums\StaticPageType;
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Advice;
|
use App\Models\Advice;
|
||||||
use App\Models\ExpertiseProduct;
|
use App\Models\ExpertiseProduct;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Models\StaticPage;
|
|
||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
|
||||||
|
|
||||||
class ExpertiseController extends Controller
|
class ExpertiseController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Show expertise page (duck).
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function canard(): \Illuminate\Contracts\View\View
|
public function canard(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('fo.pages.expertise.canard', $this->getExpertiseData(
|
// Get VIP Products for this page.
|
||||||
StaticPageType::expertise_duck,
|
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::duck->value())->get();
|
||||||
ExpertiseProductPageEnum::duck,
|
$products = Product::query()->where('status', true)
|
||||||
ProductSpeciesEnum::canard
|
->where('species', ProductSpeciesEnum::canard->value())
|
||||||
));
|
->inRandomOrder()
|
||||||
|
->limit(3)
|
||||||
|
->with('subrange.range')
|
||||||
|
->get();
|
||||||
|
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||||
|
return $query->where('species', ProductSpeciesEnum::canard->value());
|
||||||
|
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||||
|
|
||||||
|
return view('fo.pages.expertise.canard', compact('vip', 'products', 'recipes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show expertise page (turkey).
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function dinde(): \Illuminate\Contracts\View\View
|
public function dinde(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('fo.pages.expertise.dinde', $this->getExpertiseData(
|
// Get VIP Products for this page.
|
||||||
StaticPageType::expertise_turkey,
|
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::turkey->value())->get();
|
||||||
ExpertiseProductPageEnum::turkey,
|
$products = Product::query()->where('status', true)
|
||||||
ProductSpeciesEnum::dinde
|
->where('species', ProductSpeciesEnum::dinde->value())
|
||||||
));
|
->inRandomOrder()
|
||||||
|
->limit(3)
|
||||||
|
->with('subrange.range')
|
||||||
|
->get();
|
||||||
|
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||||
|
return $query->where('species', ProductSpeciesEnum::dinde->value());
|
||||||
|
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||||
|
|
||||||
|
return view('fo.pages.expertise.dinde', compact('vip', 'products', 'recipes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show expertise page (rabbit).
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function lapin(): \Illuminate\Contracts\View\View
|
public function lapin(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('fo.pages.expertise.lapin', $this->getExpertiseData(
|
// Get VIP Products for this page.
|
||||||
StaticPageType::expertise_rabbit,
|
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::rabbit->value())->get();
|
||||||
ExpertiseProductPageEnum::rabbit,
|
$products = Product::query()->where('status', true)
|
||||||
ProductSpeciesEnum::lapin
|
->where('species', ProductSpeciesEnum::lapin->value())
|
||||||
));
|
->inRandomOrder()
|
||||||
|
->limit(3)
|
||||||
|
->with('subrange.range')
|
||||||
|
->get();
|
||||||
|
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||||
|
return $query->where('species', ProductSpeciesEnum::lapin->value());
|
||||||
|
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||||
|
|
||||||
|
return view('fo.pages.expertise.lapin', compact('vip', 'products', 'recipes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show expertise page (guineafowl).
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function pintade(): \Illuminate\Contracts\View\View
|
public function pintade(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('fo.pages.expertise.pintade', $this->getExpertiseData(
|
// Get VIP Products for this page.
|
||||||
StaticPageType::expertise_guineafowl,
|
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::guineafowl->value())->get();
|
||||||
ExpertiseProductPageEnum::guineafowl,
|
$products = Product::query()->where('status', true)
|
||||||
ProductSpeciesEnum::pintade
|
->where('species', ProductSpeciesEnum::pintade->value())
|
||||||
));
|
->inRandomOrder()
|
||||||
|
->limit(3)
|
||||||
|
->with('subrange.range')
|
||||||
|
->get();
|
||||||
|
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||||
|
return $query->where('species', ProductSpeciesEnum::pintade->value());
|
||||||
|
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||||
|
|
||||||
|
return view('fo.pages.expertise.pintade', compact('vip', 'products', 'recipes'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show expertise page (chicken).
|
* Undocumented function
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
public function poulet(): \Illuminate\Contracts\View\View
|
public function poulet(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
return view('fo.pages.expertise.poulet', $this->getExpertiseData(
|
// Get VIP Products for this page.
|
||||||
StaticPageType::expertise_chicken,
|
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::chicken->value())->get();
|
||||||
ExpertiseProductPageEnum::chicken,
|
$products = Product::query()->where('status', true)
|
||||||
ProductSpeciesEnum::poulet
|
->where('species', ProductSpeciesEnum::poulet->value())
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all expertise data needed.
|
|
||||||
*
|
|
||||||
* @param \App\Enums\StaticPageType $enumStaticPageType
|
|
||||||
* @param \App\Enums\ExpertiseProducts\ExpertiseProductPageEnum $enumExpertiseProductPage
|
|
||||||
* @param \App\Enums\Products\ProductSpeciesEnum $enumProductSpecies
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getExpertiseData(
|
|
||||||
StaticPageType $enumStaticPageType,
|
|
||||||
ExpertiseProductPageEnum $enumExpertiseProductPage,
|
|
||||||
ProductSpeciesEnum $enumProductSpecies
|
|
||||||
): array {
|
|
||||||
/** @var \App\Models\StaticPage $staticPageModel */
|
|
||||||
$staticPageModel = StaticPage::query()->where('type', $enumStaticPageType->value())->first();
|
|
||||||
|
|
||||||
/** @var \App\Models\ExpertiseProduct $productVipModels */
|
|
||||||
$productVipModels = ExpertiseProduct::query()->where('page', $enumExpertiseProductPage->value())->get();
|
|
||||||
|
|
||||||
/** @var \App\Models\Product $productModels */
|
|
||||||
$productModels = Product::query()->where('published', true)
|
|
||||||
->where('species', $enumProductSpecies->value())
|
|
||||||
->inRandomOrder()
|
->inRandomOrder()
|
||||||
->limit(3)
|
->limit(3)
|
||||||
->with('subrange.range')
|
->with('subrange.range')
|
||||||
->get();
|
->get();
|
||||||
|
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||||
|
return $query->where('species', ProductSpeciesEnum::poulet->value());
|
||||||
|
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||||
|
|
||||||
$recipeModels = Advice::query()->with('tags')
|
return view('fo.pages.expertise.poulet', compact('vip', 'products', 'recipes'));
|
||||||
->whereHas('products', function (Builder $q) use ($enumProductSpecies) {
|
|
||||||
return $q->where('species', $enumProductSpecies->value());
|
|
||||||
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
|
||||||
|
|
||||||
return [
|
|
||||||
'staticPageModel' => $staticPageModel,
|
|
||||||
'productVipModels' => $productVipModels,
|
|
||||||
'productModels' => $productModels,
|
|
||||||
'recipeModels' => $recipeModels
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,12 @@
|
||||||
namespace App\Http\Controllers\Fo;
|
namespace App\Http\Controllers\Fo;
|
||||||
|
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Http\Requests\Fo\Newsletter\SingleOptinRequest;
|
|
||||||
use App\Http\Requests\Fo\Newsletter\UnsubscribeNewsletterRequest;
|
|
||||||
use App\Models\News;
|
use App\Models\News;
|
||||||
use App\Models\Product;
|
use App\Models\Product;
|
||||||
use App\Models\Range;
|
use App\Models\Range;
|
||||||
use App\Models\Slide;
|
use App\Models\Slide;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Carbon\Carbon;
|
||||||
use LDC\LDCCRM\Enums\ApiError;
|
use Spatie\CalendarLinks\Link;
|
||||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
|
||||||
use LDC\LDCCRM\Exceptions\CrmException;
|
|
||||||
use LDC\LDCCRM\Models\SingleOptin;
|
|
||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -24,104 +19,43 @@ class HomeController extends Controller
|
||||||
*/
|
*/
|
||||||
public function index(): \Illuminate\Contracts\View\View
|
public function index(): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
|
|
||||||
// Get Slides.
|
// Get Slides.
|
||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Builder $slides */
|
/** @var \Illuminate\Database\Eloquent\Builder $slides */
|
||||||
$slides = Slide::query()
|
$slides = Slide::query();
|
||||||
->where('published', true)
|
$slides->orderBy('order', 'DESC');
|
||||||
->orderBy('order', 'DESC')
|
$slides = $slides->get();
|
||||||
->get();
|
|
||||||
|
|
||||||
// Gammes.
|
// Gammes.
|
||||||
$ranges = Range::all();
|
$ranges = Range::all();
|
||||||
|
|
||||||
// VIP Products.
|
// VIP Products.
|
||||||
$threeproducts = Product::where('published', true)
|
$threeproducts = Product::where('status', true)
|
||||||
->where('is_vip', true)
|
->where('is_vip', true)
|
||||||
->take(3)
|
->take(3)
|
||||||
->orderBy('priority_order', 'DESC')
|
->orderBy('order', 'DESC')
|
||||||
->with('subrange.range')
|
->with('subrange.range')
|
||||||
->get();
|
->get();
|
||||||
|
|
||||||
// Get Agenda.
|
// Get Agenda.
|
||||||
// Events starting in the future.
|
// Events starting in the future.
|
||||||
$events = News::query()->where('published', true)
|
$events = News::where('status', true)
|
||||||
->where('event_start', '>', now())
|
->where('event_start', '>', Carbon::now())
|
||||||
->orderBy('event_start', 'desc')
|
->orderBy('event_start', 'desc')
|
||||||
->take(2)->get()->reverse();
|
->take(2)->get();
|
||||||
|
|
||||||
|
$events = $events->reverse();
|
||||||
|
|
||||||
|
foreach ($events as $event) {
|
||||||
|
$event->cal_link = Link::create($event->title, $event->event_start, $event->event_end)
|
||||||
|
->description($event->event_text)
|
||||||
|
->ics();
|
||||||
|
}
|
||||||
|
|
||||||
// Get last 3 News.
|
// Get last 3 News.
|
||||||
$news = News::query()->latest()->where('published', true)
|
$news = News::latest()->where('status', true)->take(3)->with('categories')->get();
|
||||||
->take(3)->with('categories')->get();
|
|
||||||
|
|
||||||
return view('fo.pages.home', compact(
|
return view('fo.pages.home', compact('slides', 'ranges', 'threeproducts', 'events', 'news'));
|
||||||
'slides',
|
|
||||||
'ranges',
|
|
||||||
'threeproducts',
|
|
||||||
'events',
|
|
||||||
'news'
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call the CRM to add a single optin
|
|
||||||
*
|
|
||||||
* @param \App\Http\Requests\Fo\Newsletter\SingleOptinRequest $request
|
|
||||||
* @return string|array|null|\Illuminate\Contracts\Translation\Translator
|
|
||||||
* @throws \LDC\LDCCRM\Exceptions\ValidationException ValidationException.
|
|
||||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException BindingResolutionException.
|
|
||||||
*/
|
|
||||||
public function addOptIn(SingleOptinRequest $request)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
SingleOptin::setStatus($request->email, true);
|
|
||||||
return \response(trans("Votre inscription à la newsletter a été prise en compte"), 200);
|
|
||||||
} catch (ApiErrorException $e) {
|
|
||||||
\report($e);
|
|
||||||
return \response(trans('Une erreur est survenue, merci de réessayer ultérieurement'), 500);
|
|
||||||
} catch (CrmException $e) {
|
|
||||||
\report($e);
|
|
||||||
return \response(trans('Une erreur est survenue, merci de réessayer ultérieurement'), 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* unsubscribeNewsletter method
|
|
||||||
*
|
|
||||||
* @param \App\Http\Requests\Fo\Newsletter\UnsubscribeNewsletterRequest $request
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function unsubscribeNewsletter(UnsubscribeNewsletterRequest $request): \Illuminate\Contracts\View\View
|
|
||||||
{
|
|
||||||
$error = null;
|
|
||||||
$hashcode = $request->hashcode;
|
|
||||||
|
|
||||||
try {
|
|
||||||
SingleOptin::unsetStatusWithHashcode($hashcode);
|
|
||||||
} catch (ApiErrorException $e) {
|
|
||||||
Log::debug($e->getMessage());
|
|
||||||
if ($e->getApiError()->equals(ApiError::modelNotFound)) {
|
|
||||||
abort(404);
|
|
||||||
} else {
|
|
||||||
if (app()->bound('sentry')) {
|
|
||||||
app('sentry')->captureException($e);
|
|
||||||
}
|
|
||||||
$error = true;
|
|
||||||
}
|
|
||||||
} catch (CrmException $e) {
|
|
||||||
Log::debug($e->getMessage());
|
|
||||||
$error = true;
|
|
||||||
if (app()->bound('sentry')) {
|
|
||||||
app('sentry')->captureException($e);
|
|
||||||
}
|
|
||||||
} //end try
|
|
||||||
|
|
||||||
if (!is_null($error)) {
|
|
||||||
return view('fo.pages.newsletter-unsubscribe')->with(
|
|
||||||
'error',
|
|
||||||
trans('Une erreur est survenue, merci de réessayer ultérieurement')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return view('fo.pages.newsletter-unsubscribe');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ namespace App\Http\Controllers\Fo;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\News;
|
use App\Models\News;
|
||||||
use App\Models\NewsCategory;
|
use App\Models\NewsCategory;
|
||||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class NewsController extends Controller
|
class NewsController extends Controller
|
||||||
|
|
@ -19,31 +18,32 @@ class NewsController extends Controller
|
||||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
// Get NewsCategories.
|
// Get NewsCategories.
|
||||||
$categories = NewsCategory::query()->orderBy('label', 'ASC')->get();
|
$categories = NewsCategory::orderBy('label', 'ASC')->get();
|
||||||
|
|
||||||
// Get News.
|
// Get News.
|
||||||
$filters_activated = collect($request->input('filtered_categorie'));
|
$filters_activated = $request->filtered_categorie;
|
||||||
|
|
||||||
$news = News::query()->with('categories')->when(
|
$news = News::when(
|
||||||
$filters_activated->first() !== 'all',
|
isset($filters_activated) and $filters_activated[0] != 'all',
|
||||||
fn(Builder $q) => $q->with('categories')
|
function ($query) use ($filters_activated) {
|
||||||
->whereRelation('categories', fn(Builder $q) =>
|
$query->with('categories')
|
||||||
$q->where(function (Builder $q) use ($filters_activated) {
|
->whereRelation('categories', function ($query) use ($filters_activated) {
|
||||||
foreach ($filters_activated as $value) {
|
foreach ($filters_activated as $value) {
|
||||||
if (is_string($value)) {
|
$query->orWhere('id', 'like', $value);
|
||||||
$q->orWhere('id', $value);
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}))
|
}
|
||||||
)->where('published', true)->orderByDesc('created_at')->paginate(6);
|
)
|
||||||
|
->where('status', true)
|
||||||
|
->orderBy('created_at')
|
||||||
|
->paginate(6);
|
||||||
|
|
||||||
return view('fo.pages.news.index', compact('categories', 'news', 'filters_activated'));
|
return view('fo.pages.news.index', compact('categories', 'news', 'filters_activated'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show resource
|
* Undocumented function
|
||||||
*
|
* @param News $news
|
||||||
* @param \App\Models\News $news
|
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Contracts\View\View
|
||||||
*/
|
*/
|
||||||
|
|
@ -51,7 +51,7 @@ class NewsController extends Controller
|
||||||
{
|
{
|
||||||
$news->load('categories', 'news.categories', 'products');
|
$news->load('categories', 'news.categories', 'products');
|
||||||
$readingTime = $news->getReadingTime();
|
$readingTime = $news->getReadingTime();
|
||||||
$products = $news->products()->with(['subrange', 'subrange.range'])->get();
|
$products = $news->products()->get();
|
||||||
|
|
||||||
return view('fo.pages.news.post', compact('news', 'readingTime', 'products'));
|
return view('fo.pages.news.post', compact('news', 'readingTime', 'products'));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,7 @@ class ProductsController extends Controller
|
||||||
$search = htmlspecialchars($request->query('search') ?? '');
|
$search = htmlspecialchars($request->query('search') ?? '');
|
||||||
$productsQuery = !empty($search) ? $this->getProductQuery($search) : Product::query();
|
$productsQuery = !empty($search) ? $this->getProductQuery($search) : Product::query();
|
||||||
$productsQuery->with('subrange.range');
|
$productsQuery->with('subrange.range');
|
||||||
$productsQuery->where('published', true);
|
$productsQuery->where('status', true);
|
||||||
$productsQuery->orderBy('priority_order', 'ASC');
|
|
||||||
|
|
||||||
// * Range filter (obligatoire).
|
// * Range filter (obligatoire).
|
||||||
$productsQuery->whereHas('subrange', function (Builder $q) use ($range) {
|
$productsQuery->whereHas('subrange', function (Builder $q) use ($range) {
|
||||||
|
|
@ -85,6 +84,7 @@ class ProductsController extends Controller
|
||||||
if ($request->vip) {
|
if ($request->vip) {
|
||||||
$productsQuery->where('is_vip', $request->vip);
|
$productsQuery->where('is_vip', $request->vip);
|
||||||
}
|
}
|
||||||
|
|
||||||
return \response()->json(new ProductPaginatedCollectionResource($productsQuery->paginate(6)));
|
return \response()->json(new ProductPaginatedCollectionResource($productsQuery->paginate(6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -97,12 +97,12 @@ class ProductsController extends Controller
|
||||||
public function show(Product $publishedProduct): \Illuminate\Contracts\View\View
|
public function show(Product $publishedProduct): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */
|
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */
|
||||||
$recipes = $publishedProduct->recipesQuery()->where('published', true)->with('tags')->get();
|
$recipes = $publishedProduct->recipesQuery()->where('status', true)->get();
|
||||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */
|
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */
|
||||||
$tips = $publishedProduct->tipsQuery()->where('published', true)->get();
|
$tips = $publishedProduct->tipsQuery()->where('status', true)->get();
|
||||||
|
|
||||||
// Force load subrange and range.
|
// Force load subrange and range.
|
||||||
$publishedProduct->load(['subrange.range', 'tags']);
|
$publishedProduct->load('subrange.range');
|
||||||
|
|
||||||
/** @var \App\Models\Subrange */
|
/** @var \App\Models\Subrange */
|
||||||
$subrange = $publishedProduct->subrange;
|
$subrange = $publishedProduct->subrange;
|
||||||
|
|
@ -111,9 +111,8 @@ class ProductsController extends Controller
|
||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Product> */
|
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Product> */
|
||||||
$randomProducts = Product::query()
|
$randomProducts = Product::query()
|
||||||
->with('subrange.range')
|
|
||||||
->where('id', '!=', $publishedProduct->id)
|
->where('id', '!=', $publishedProduct->id)
|
||||||
->where('published', true)
|
->where('status', true)
|
||||||
->whereHas('subrange', function (Builder $q) use ($range) {
|
->whereHas('subrange', function (Builder $q) use ($range) {
|
||||||
$q->whereHas('range', function (Builder $q) use ($range) {
|
$q->whereHas('range', function (Builder $q) use ($range) {
|
||||||
$q->where('id', $range->id);
|
$q->where('id', $range->id);
|
||||||
|
|
@ -122,12 +121,7 @@ class ProductsController extends Controller
|
||||||
|
|
||||||
$product = $publishedProduct;
|
$product = $publishedProduct;
|
||||||
|
|
||||||
return view('fo.pages.products.product', compact(
|
return view('fo.pages.products.product', compact('product', 'recipes', 'tips', 'randomProducts'));
|
||||||
'product',
|
|
||||||
'recipes',
|
|
||||||
'tips',
|
|
||||||
'randomProducts'
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -136,13 +130,13 @@ class ProductsController extends Controller
|
||||||
* @param \App\Models\Product $publishedProduct
|
* @param \App\Models\Product $publishedProduct
|
||||||
* @return \Illuminate\Http\Response
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function printCommercialSheet(Product $publishedProduct): Response
|
public function printCommericalSheet(Product $publishedProduct): Response
|
||||||
{
|
{
|
||||||
$title = trans('Fiche commerciale du produit : :label - :appname', [
|
$title = trans('Fiche commerciale du produit : :label - :appname', [
|
||||||
'label' => $publishedProduct->label,
|
'label' => $publishedProduct->label,
|
||||||
'appname' => \config('app.name', 'Le Gaulois Pro')
|
'appname' => \config('app.name', 'Le Gaulois Pro')
|
||||||
]);
|
]);
|
||||||
$filename = trans('fiche-commerciale-:slug-:date.pdf', [
|
$filename = trans('fiche-commerciale-:slug-:date', [
|
||||||
'slug' => Str::slug($publishedProduct->label),
|
'slug' => Str::slug($publishedProduct->label),
|
||||||
'date' => \now()->format('Y-m-d')
|
'date' => \now()->format('Y-m-d')
|
||||||
]);
|
]);
|
||||||
|
|
@ -153,15 +147,17 @@ class ProductsController extends Controller
|
||||||
* ! apres avoir header et echo dans le corps de la réponse php (Nasty trick)
|
* ! apres avoir header et echo dans le corps de la réponse php (Nasty trick)
|
||||||
*/
|
*/
|
||||||
return \response(
|
return \response(
|
||||||
$this->generateProductCommercialPdf($publishedProduct, $title)->download($filename),
|
$this->generateProductCommercialPdf($publishedProduct, $title)->output(),
|
||||||
200,
|
200,
|
||||||
[
|
[
|
||||||
'Content-Type' => 'application/pdf',
|
'Content-Type' => 'application/pdf',
|
||||||
'Content-disposition' => "inline; filename=\"{$filename}\"",
|
'Content-disposition' => "inline; filename=\"{$filename}\"",
|
||||||
'Cache-Control' => 'public, must-revalidate, max-age=0',
|
'Cache-Control' => 'public, must-revalidate, max-age=0',
|
||||||
'Pragma' => 'public',
|
'Pragma' => 'public',
|
||||||
'Expires' => 'Sat, 26 Jul 1997 05:00:00 GMT',
|
// * For glory
|
||||||
'Last-Modified' => gmdate('D, d M Y H:i:s') . ' GMT',
|
'X-Generator' => 'mPDF',
|
||||||
|
'Expires' => 'Sat, 26 Jul 1997 05:00:00 GMT',
|
||||||
|
'Last-Modified' => gmdate('D, d M Y H:i:s') . ' GMT',
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +230,7 @@ class ProductsController extends Controller
|
||||||
*/
|
*/
|
||||||
private function generateProductCommercialPdf(Product $product, string $title): \Mccarlosen\LaravelMpdf\LaravelMpdf
|
private function generateProductCommercialPdf(Product $product, string $title): \Mccarlosen\LaravelMpdf\LaravelMpdf
|
||||||
{
|
{
|
||||||
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdfWrapper */
|
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */
|
||||||
$mpdf = app('laravel-mpdf');
|
$mpdf = app('laravel-mpdf');
|
||||||
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */
|
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */
|
||||||
$pdf = $mpdf->loadView(
|
$pdf = $mpdf->loadView(
|
||||||
|
|
@ -260,6 +256,7 @@ class ProductsController extends Controller
|
||||||
'margin_bottom' => 0,
|
'margin_bottom' => 0,
|
||||||
'margin_header' => 0,
|
'margin_header' => 0,
|
||||||
'margin_footer' => 0,
|
'margin_footer' => 0,
|
||||||
|
'margin_top' => 0,
|
||||||
'orientation' => 'P',
|
'orientation' => 'P',
|
||||||
'title' => $title,
|
'title' => $title,
|
||||||
'author' => \config('app.name', 'Le Gaulois Pro'),
|
'author' => \config('app.name', 'Le Gaulois Pro'),
|
||||||
|
|
|
||||||
|
|
@ -43,39 +43,39 @@ class RecipesController extends Controller
|
||||||
/** @var \App\Enums\Advices\AdviceTimeEnum|null $cooking_time */
|
/** @var \App\Enums\Advices\AdviceTimeEnum|null $cooking_time */
|
||||||
/** @var \App\Enums\Advices\AdviceTimeEnum|null $preparation_time */
|
/** @var \App\Enums\Advices\AdviceTimeEnum|null $preparation_time */
|
||||||
|
|
||||||
$query = Advice::query()->with('tags')->where('type', 1)->where('published', true)->when(
|
$query = Advice::query()->where('type', 1)->where('status', true)->when(
|
||||||
is_numeric($search_range),
|
is_numeric($search_range),
|
||||||
fn(Builder $q) =>
|
fn (Builder $q) =>
|
||||||
$q->whereHas(
|
$q->whereHas(
|
||||||
'products',
|
'products',
|
||||||
fn(Builder $q) =>
|
fn (Builder $q) =>
|
||||||
$q->whereHas(
|
$q->whereHas(
|
||||||
'subrange',
|
'subrange',
|
||||||
fn(Builder $q) =>
|
fn (Builder $q) =>
|
||||||
$q->whereHas(
|
$q->whereHas(
|
||||||
'range',
|
'range',
|
||||||
fn(Builder $q) =>
|
fn (Builder $q) =>
|
||||||
$q->where('id', 'LIKE', $search_range)
|
$q->where('id', 'LIKE', $search_range)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)->when(
|
)->when(
|
||||||
$cooking_time,
|
$cooking_time,
|
||||||
fn(Builder $q) =>
|
fn (Builder $q) =>
|
||||||
$q->whereBetween('cooking_time', [
|
$q->whereBetween('cooking_time', [
|
||||||
Arr::get($cooking_time->times(), 0),
|
Arr::get($cooking_time->times(), 0),
|
||||||
Arr::get($cooking_time->times(), 1)
|
Arr::get($cooking_time->times(), 1)
|
||||||
])
|
])
|
||||||
)->when(
|
)->when(
|
||||||
$preparation_time,
|
$preparation_time,
|
||||||
fn(Builder $q) =>
|
fn (Builder $q) =>
|
||||||
$q->whereBetween('preparation_time', [
|
$q->whereBetween('preparation_time', [
|
||||||
Arr::get($preparation_time->times(), 0),
|
Arr::get($preparation_time->times(), 0),
|
||||||
Arr::get($preparation_time->times(), 1)
|
Arr::get($preparation_time->times(), 1)
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
$recipes = $query->orderBy('priority_order', 'ASC')->paginate(9);
|
$recipes = $query->orderBy('slug', 'ASC')->paginate(9);
|
||||||
|
|
||||||
return view('fo.pages.ideas.recipes', compact(
|
return view('fo.pages.ideas.recipes', compact(
|
||||||
'ranges',
|
'ranges',
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ class SearchController extends Controller
|
||||||
* Search input txt in products, news and recipes
|
* Search input txt in products, news and recipes
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function search(Request $request): \Illuminate\Contracts\View\View
|
public function search(Request $request): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
|
|
@ -25,8 +25,11 @@ class SearchController extends Controller
|
||||||
$recipes = [];
|
$recipes = [];
|
||||||
$recipesTotal = 0;
|
$recipesTotal = 0;
|
||||||
|
|
||||||
|
if (is_array($search)) {
|
||||||
|
abort(400);
|
||||||
|
}
|
||||||
if (is_string($model)) {
|
if (is_string($model)) {
|
||||||
return $this->searchModel($model, $search);
|
return $this->callAction('searchModel', [$model, $search]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($search)) {
|
if (!empty($search)) {
|
||||||
|
|
@ -60,7 +63,7 @@ class SearchController extends Controller
|
||||||
*
|
*
|
||||||
* @param string $modelName
|
* @param string $modelName
|
||||||
* @param string $search
|
* @param string $search
|
||||||
* @return \Illuminate\Contracts\View\View
|
* @return \Illuminate\Http\Response
|
||||||
*/
|
*/
|
||||||
public function searchModel(string $modelName, string $search): \Illuminate\Contracts\View\View
|
public function searchModel(string $modelName, string $search): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,48 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers\Fo;
|
|
||||||
|
|
||||||
use App\Enums\StaticPageType;
|
|
||||||
use App\Http\Controllers\Controller;
|
|
||||||
use App\Models\StaticPage;
|
|
||||||
use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
|
||||||
|
|
||||||
class StaticPageController extends Controller
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Legal show
|
|
||||||
*
|
|
||||||
* @param \App\Models\StaticPage $legalPage
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function legals(StaticPage $legalPage)
|
|
||||||
{
|
|
||||||
$legalPage = StaticPage::query()->where('type', StaticPageType::legals)->first();
|
|
||||||
return view('fo.pages.legals', ['staticPageModel' => $legalPage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Policies show
|
|
||||||
*
|
|
||||||
* @param \App\Models\StaticPage $policiesPage
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function policies(StaticPage $policiesPage)
|
|
||||||
{
|
|
||||||
$policiesPage = StaticPage::query()->where('type', StaticPageType::confidentiality)->first();
|
|
||||||
return view('fo.pages.legals', ['staticPageModel' => $policiesPage]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sitemap show
|
|
||||||
*
|
|
||||||
* @param \App\Models\StaticPage $sitemap
|
|
||||||
* @return \Illuminate\Contracts\View\View
|
|
||||||
*/
|
|
||||||
public function sitemap(StaticPage $sitemap)
|
|
||||||
{
|
|
||||||
$sitemap = StaticPage::query()->where('type', StaticPageType::sitemap)->first();
|
|
||||||
$singlePages = SitemapHelper::getSinglePages();
|
|
||||||
return view('fo.pages.sitemap', ['staticPageModel' => $sitemap, 'singlePages' => $singlePages]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
18
app/Http/Controllers/Fo/StoryController.php
Normal file
18
app/Http/Controllers/Fo/StoryController.php
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Fo;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
|
||||||
|
class StoryController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Undocumented function
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Contracts\View\View
|
||||||
|
*/
|
||||||
|
public function index(): \Illuminate\Contracts\View\View
|
||||||
|
{
|
||||||
|
return view('fo.pages.story');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -17,7 +17,7 @@ class TipsController extends Controller
|
||||||
{
|
{
|
||||||
$advices = Advice::query()->with('tags')
|
$advices = Advice::query()->with('tags')
|
||||||
->where('type', AdviceTypeEnum::tips)
|
->where('type', AdviceTypeEnum::tips)
|
||||||
->where('published', true)
|
->where('status', true)
|
||||||
->paginate(9);
|
->paginate(9);
|
||||||
return view('fo.pages.ideas.tips', \compact('advices'));
|
return view('fo.pages.ideas.tips', \compact('advices'));
|
||||||
}
|
}
|
||||||
|
|
@ -31,9 +31,7 @@ class TipsController extends Controller
|
||||||
public function show(Advice $publishedAdvice): \Illuminate\Contracts\View\View
|
public function show(Advice $publishedAdvice): \Illuminate\Contracts\View\View
|
||||||
{
|
{
|
||||||
$publishedAdvice->load([
|
$publishedAdvice->load([
|
||||||
'advices',
|
'advices', 'products.subrange', 'tags'
|
||||||
'products.subrange.range',
|
|
||||||
'tags'
|
|
||||||
]);
|
]);
|
||||||
return view('fo.pages.ideas.tip', [
|
return view('fo.pages.ideas.tip', [
|
||||||
'adviceModel' => $publishedAdvice
|
'adviceModel' => $publishedAdvice
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,12 @@ class Kernel extends HttpKernel
|
||||||
\App\Http\Middleware\EncryptCookies::class,
|
\App\Http\Middleware\EncryptCookies::class,
|
||||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||||
\Illuminate\Session\Middleware\StartSession::class,
|
\Illuminate\Session\Middleware\StartSession::class,
|
||||||
|
\Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
\App\Http\Middleware\SecureHeaders::class
|
\App\Http\Middleware\SecureHeaders::class
|
||||||
],
|
]
|
||||||
'saml' => [
|
|
||||||
\App\Http\Middleware\EncryptCookies::class,
|
|
||||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
|
||||||
\Illuminate\Session\Middleware\StartSession::class,
|
|
||||||
],
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ class Authenticate extends Middleware
|
||||||
}
|
}
|
||||||
return route('login');
|
return route('login');
|
||||||
}
|
}
|
||||||
|
abort(401);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ class SecureHeaders
|
||||||
View::share('nonce', $nonce = Vite::useCspNonce());
|
View::share('nonce', $nonce = Vite::useCspNonce());
|
||||||
// * For VueJS dev tool to execute
|
// * For VueJS dev tool to execute
|
||||||
$jsDev = config('app.debug') ? "'unsafe-eval' 'unsafe-inline'" : "'nonce-{$nonce}' 'strict-dynamic'";
|
$jsDev = config('app.debug') ? "'unsafe-eval' 'unsafe-inline'" : "'nonce-{$nonce}' 'strict-dynamic'";
|
||||||
|
$scheme = config('app.env') === 'local' ? 'http' : 'https';
|
||||||
$reportUri = Route::has('cspReportUri') ?
|
$reportUri = Route::has('cspReportUri') ?
|
||||||
\sprintf(' report-uri %s ;', \parse_url(route('cspReportUri'), \PHP_URL_PATH)) : '';
|
\sprintf(' report-uri %s ;', \parse_url(route('cspReportUri'), \PHP_URL_PATH)) : '';
|
||||||
$this->removeUnwantedHeaders($this->unwantedHeaderList);
|
$this->removeUnwantedHeaders($this->unwantedHeaderList);
|
||||||
|
|
@ -60,7 +61,6 @@ class SecureHeaders
|
||||||
]) . ';',
|
]) . ';',
|
||||||
"img-src 'self' data: blob: " . implode(' ', [
|
"img-src 'self' data: blob: " . implode(' ', [
|
||||||
'https://yl.s-web.fr',
|
'https://yl.s-web.fr',
|
||||||
'https://i3.ytimg.com/',
|
|
||||||
// * VITE DEV
|
// * VITE DEV
|
||||||
config('app.debug') ? "https://{$host}:4443" : '',
|
config('app.debug') ? "https://{$host}:4443" : '',
|
||||||
// * MESBR
|
// * MESBR
|
||||||
|
|
@ -99,6 +99,7 @@ class SecureHeaders
|
||||||
'https: blob:',
|
'https: blob:',
|
||||||
'https://www.googletagmanager.com',
|
'https://www.googletagmanager.com',
|
||||||
'https://cdnjs.cloudflare.com',
|
'https://cdnjs.cloudflare.com',
|
||||||
|
"$scheme://www.google-analytics.com",
|
||||||
// * VITE DEV
|
// * VITE DEV
|
||||||
config('app.debug') ? "https://{$host}:4443" : '',
|
config('app.debug') ? "https://{$host}:4443" : '',
|
||||||
]) . ';'
|
]) . ';'
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ namespace App\Http\Requests\Bo\Advice;
|
||||||
|
|
||||||
use App\Enums\Advices\AdviceDifficultyEnum;
|
use App\Enums\Advices\AdviceDifficultyEnum;
|
||||||
use App\Enums\Advices\AdviceTypeEnum;
|
use App\Enums\Advices\AdviceTypeEnum;
|
||||||
use App\Rules\WysiwygLength;
|
|
||||||
use App\Traits\Requests\HasPicture;
|
use App\Traits\Requests\HasPicture;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
@ -35,23 +34,23 @@ class StoreAdviceRequest extends FormRequest
|
||||||
{
|
{
|
||||||
//phpcs:enable
|
//phpcs:enable
|
||||||
$this->merge([
|
$this->merge([
|
||||||
'slug' => Str::slug(strip_tags($this->input('title'))),
|
'slug' => Str::slug(strip_tags($this->title)),
|
||||||
'published' => $this->boolean('published'),
|
'status' => $this->status ? true : false,
|
||||||
'tags' => $this->input('tags', []),
|
'tags' => $this->tags ?? [],
|
||||||
'products' => $this->input('products', []),
|
'products' => $this->products ?? [],
|
||||||
'associated_tips_list' => $this->input('associated_tips_list', []),
|
'associated_tips_list' => $this->associated_tips_list ?? [],
|
||||||
'associated_recipes_list' => $this->input('associated_recipes_list', []),
|
'associated_recipes_list' => $this->associated_recipes_list ?? [],
|
||||||
// * For sync relations
|
// * For sync relations
|
||||||
'tags_list' => \collect($this->input('tags'))->map(function ($value) {
|
'tags_list' => \collect($this->tags)->map(function ($value) {
|
||||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||||
})->filter()->all(),
|
})->filter()->all(),
|
||||||
'products_list' => \collect($this->input('products'))->map(function ($value) {
|
'products_list' => \collect($this->products)->map(function ($value) {
|
||||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||||
})->filter()->all(),
|
})->filter()->all(),
|
||||||
'tips_list' => \collect($this->input('tips'))->map(function ($value) {
|
'tips_list' => \collect($this->associated_tips_list)->map(function ($value) {
|
||||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||||
})->filter()->all(),
|
})->filter()->all(),
|
||||||
'recipes_list' => \collect($this->input('recipes'))->map(function ($value) {
|
'recipes_list' => \collect($this->associated_recipes_list)->map(function ($value) {
|
||||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||||
})->filter()->all(),
|
})->filter()->all(),
|
||||||
]);
|
]);
|
||||||
|
|
@ -80,28 +79,18 @@ class StoreAdviceRequest extends FormRequest
|
||||||
'sticker_title' => 'required_with:sticker|nullable|min:3|max:255',
|
'sticker_title' => 'required_with:sticker|nullable|min:3|max:255',
|
||||||
'sticker_sm_alt' => 'required_with:sticker_sm|nullable|min:3|max:255',
|
'sticker_sm_alt' => 'required_with:sticker_sm|nullable|min:3|max:255',
|
||||||
'sticker_sm_title' => 'required_with:sticker_sm|nullable|min:3|max:255',
|
'sticker_sm_title' => 'required_with:sticker_sm|nullable|min:3|max:255',
|
||||||
'preparation' => [
|
'preparation' => 'required|string|min:15',
|
||||||
'required',
|
'advice' => 'nullable|string|min:15',
|
||||||
'string',
|
|
||||||
new WysiwygLength(15, 2500)
|
|
||||||
],
|
|
||||||
'advice' => [
|
|
||||||
'nullable',
|
|
||||||
'string',
|
|
||||||
new WysiwygLength(15, 2500)
|
|
||||||
],
|
|
||||||
'ingredients' => [
|
'ingredients' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (count($value) < 1 || count($value) > 15) {
|
if (count($value) < 1 || count($value) > 15) {
|
||||||
$fail(\trans('Vous devez associer 1 à 15 lignes d\'ingrédients.'));
|
$fail(\trans('Vous devez associer 1 à 15 lignes d\'ingrédients.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'ingredients.*' => 'required|array',
|
'ingredients.*' => 'required|array',
|
||||||
'ingredients.*.value' => 'nullable|regex:/^\d*\.?\d{0,1}$/|between:0,65535',
|
'ingredients.*.value' => 'nullable|numeric|max:65535',
|
||||||
'ingredients.*.label' => [
|
'ingredients.*.label' => [
|
||||||
Rule::requiredIf(function () {
|
Rule::requiredIf(function () {
|
||||||
return $this->type === AdviceTypeEnum::recipes->value();
|
return $this->type === AdviceTypeEnum::recipes->value();
|
||||||
|
|
@ -129,22 +118,16 @@ class StoreAdviceRequest extends FormRequest
|
||||||
) {
|
) {
|
||||||
$fail(\trans('Le nombre de convives est obligatoire'));
|
$fail(\trans('Le nombre de convives est obligatoire'));
|
||||||
}
|
}
|
||||||
},
|
}, 'nullable', 'numeric', 'min:1', 'max:99'
|
||||||
'nullable',
|
|
||||||
'numeric',
|
|
||||||
'min:1',
|
|
||||||
'max:99'
|
|
||||||
],
|
],
|
||||||
'youtube_title' => 'required_with:youtube_video_id|nullable|min:3|max:255',
|
'youtube_title' => 'required_with:youtube_video_id|nullable|min:3|max:255',
|
||||||
'youtube_video_id' => 'required_with:youtube_title|nullable|min:3|max:50|regex:%([^"&?\/\s]{11})%i',
|
'youtube_video_id' => 'required_with:youtube_title|nullable|regex:%([^"&?\/\s]{11})%i',
|
||||||
'cooking_time' => 'nullable|numeric|min:0|max:65535',
|
'cooking_time' => 'nullable|numeric|min:0|max:65535',
|
||||||
'preparation_time' => [
|
'preparation_time' => [
|
||||||
Rule::requiredIf(function () {
|
Rule::requiredIf(function () {
|
||||||
return $this->type === AdviceTypeEnum::recipes->value();
|
return $this->type === AdviceTypeEnum::recipes->value();
|
||||||
}),
|
}),
|
||||||
'numeric',
|
'numeric', 'min:0', 'max:65535'
|
||||||
'min:0',
|
|
||||||
'max:65535'
|
|
||||||
],
|
],
|
||||||
'difficulty' => [
|
'difficulty' => [
|
||||||
Rule::requiredIf(function () {
|
Rule::requiredIf(function () {
|
||||||
|
|
@ -152,12 +135,10 @@ class StoreAdviceRequest extends FormRequest
|
||||||
}),
|
}),
|
||||||
new Enum(AdviceDifficultyEnum::class)
|
new Enum(AdviceDifficultyEnum::class)
|
||||||
],
|
],
|
||||||
'published' => 'required|boolean',
|
'status' => 'required|boolean',
|
||||||
'tags' => [
|
'tags' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (count($value) > 2) {
|
if (count($value) > 2) {
|
||||||
$fail(\trans('Vous devez associer au maximum 2 tags.'));
|
$fail(\trans('Vous devez associer au maximum 2 tags.'));
|
||||||
}
|
}
|
||||||
|
|
@ -167,10 +148,8 @@ class StoreAdviceRequest extends FormRequest
|
||||||
'tags.*.id' => 'required|numeric|exists:tags,id|distinct',
|
'tags.*.id' => 'required|numeric|exists:tags,id|distinct',
|
||||||
'tags.*.label' => 'required|string',
|
'tags.*.label' => 'required|string',
|
||||||
'products' => [
|
'products' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if ($this->type == AdviceTypeEnum::recipes->value()) {
|
if ($this->type == AdviceTypeEnum::recipes->value()) {
|
||||||
if (count($value) < 1 || count($value) > 3) {
|
if (count($value) < 1 || count($value) > 3) {
|
||||||
$fail(\trans('Vous devez associer 1 à 3 produits.'));
|
$fail(\trans('Vous devez associer 1 à 3 produits.'));
|
||||||
|
|
@ -186,10 +165,8 @@ class StoreAdviceRequest extends FormRequest
|
||||||
'products.*.value' => 'required|exists:products,id',
|
'products.*.value' => 'required|exists:products,id',
|
||||||
'products.*.label' => 'required|string',
|
'products.*.label' => 'required|string',
|
||||||
'associated_tips_list' => [
|
'associated_tips_list' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (count($value) > 3) {
|
if (count($value) > 3) {
|
||||||
$fail(\trans('Vous devez associer au maximum 3 astuces.'));
|
$fail(\trans('Vous devez associer au maximum 3 astuces.'));
|
||||||
}
|
}
|
||||||
|
|
@ -199,10 +176,8 @@ class StoreAdviceRequest extends FormRequest
|
||||||
'associated_tips_list.*.value' => 'required|exists:advice,id',
|
'associated_tips_list.*.value' => 'required|exists:advice,id',
|
||||||
'associated_tips_list.*.label' => 'required|string',
|
'associated_tips_list.*.label' => 'required|string',
|
||||||
'associated_recipes_list' => [
|
'associated_recipes_list' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (count($value) > 3) {
|
if (count($value) > 3) {
|
||||||
$fail(\trans('Vous devez associer au maximum 3 recettes.'));
|
$fail(\trans('Vous devez associer au maximum 3 recettes.'));
|
||||||
}
|
}
|
||||||
|
|
@ -214,9 +189,9 @@ class StoreAdviceRequest extends FormRequest
|
||||||
];
|
];
|
||||||
return \array_merge(
|
return \array_merge(
|
||||||
$rules,
|
$rules,
|
||||||
$this->pictureRules('picture', 650, 690, 650, 690, false),
|
$this->pictureRules('picture', true, 650, 690, 650, 690),
|
||||||
$this->pictureRules('sticker', 370, 300, 370, 300, false),
|
$this->pictureRules('sticker', true, 370, 300, 370, 300),
|
||||||
$this->pictureRules('sticker_sm', 270, 145, 270, 145, false),
|
$this->pictureRules('sticker_sm', true, 270, 145, 270, 145),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,84 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Bo\BrigadeSections;
|
|
||||||
|
|
||||||
use App\Rules\WysiwygLength;
|
|
||||||
use App\Traits\Requests\HasPicture;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class StoreBrigadeSectionsRequest extends FormRequest
|
|
||||||
{
|
|
||||||
use HasPicture;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the user is authorized to make this request.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return auth('backend')->check();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the data for validation.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function prepareForValidation(): void
|
|
||||||
{
|
|
||||||
$this->merge([
|
|
||||||
'published' => $this->boolean('published'),
|
|
||||||
'button_display' => $this->boolean('button_display'),
|
|
||||||
'button_newtab' => $this->boolean('button_newtab'),
|
|
||||||
]);
|
|
||||||
$this->mergePicture('picture');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the validation rules that apply to the request.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
$rules = [
|
|
||||||
'title' => 'required|string|min:3|max:500',
|
|
||||||
'content' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
new WysiwygLength(15, 1500)
|
|
||||||
],
|
|
||||||
'picture_alt' => 'required|string|min:3|max:255',
|
|
||||||
'picture_title' => 'required|string|min:3|max:255',
|
|
||||||
'button_display' => 'required|boolean',
|
|
||||||
'button_text' => 'required_if_accepted:button_display|nullable|string|min:3|max:255',
|
|
||||||
'button_url' => 'required_if_accepted:button_display|nullable|url:https|min:3|max:255',
|
|
||||||
'button_newtab' => 'required|boolean',
|
|
||||||
'published' => 'required|boolean',
|
|
||||||
];
|
|
||||||
return \array_merge(
|
|
||||||
$rules,
|
|
||||||
$this->pictureRules('picture', 800, 535, 800, 535, false),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get custom attributes for validator errors.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function attributes(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'title' => trans('Titre'),
|
|
||||||
'picture' => trans('Image'),
|
|
||||||
'picture_alt' => trans('Attribut alt de l\'image'),
|
|
||||||
'picture_title' => trans('Titre de l\'image'),
|
|
||||||
'content' => trans('Contenu'),
|
|
||||||
'button_text' => trans('Texte du CTA'),
|
|
||||||
'button_url' => trans('URL du CTA'),
|
|
||||||
'published' => trans('Statut'),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Bo\BrigadeSections;
|
|
||||||
|
|
||||||
class UpdateBrigadeSectionsRequest extends StoreBrigadeSectionsRequest
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Http\Requests\Bo\News;
|
namespace App\Http\Requests\Bo\News;
|
||||||
|
|
||||||
use App\Rules\WysiwygLength;
|
|
||||||
use App\Traits\Requests\HasPicture;
|
use App\Traits\Requests\HasPicture;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
@ -32,7 +31,7 @@ class StoreNewsRequest extends FormRequest
|
||||||
//phpcs:enable
|
//phpcs:enable
|
||||||
$this->merge([
|
$this->merge([
|
||||||
'slug' => Str::slug($this->title),
|
'slug' => Str::slug($this->title),
|
||||||
'published' => $this->published ? true : false,
|
'status' => $this->status ? true : false,
|
||||||
'categories' => $this->categories ?? [],
|
'categories' => $this->categories ?? [],
|
||||||
'products' => $this->products ?? [],
|
'products' => $this->products ?? [],
|
||||||
'associated_news_list' => $this->associated_news_list ?? [],
|
'associated_news_list' => $this->associated_news_list ?? [],
|
||||||
|
|
@ -67,18 +66,8 @@ class StoreNewsRequest extends FormRequest
|
||||||
'picture_title' => 'required_with:picture|nullable|min:3|max:255',
|
'picture_title' => 'required_with:picture|nullable|min:3|max:255',
|
||||||
'picture2_alt' => 'required_with:picture2|nullable|min:3|max:255',
|
'picture2_alt' => 'required_with:picture2|nullable|min:3|max:255',
|
||||||
'picture2_title' => 'required_with:picture2|nullable|min:3|max:255',
|
'picture2_title' => 'required_with:picture2|nullable|min:3|max:255',
|
||||||
'content' => [
|
'content' => 'required_with:picture|nullable|string|min:15',
|
||||||
'required_with:picture',
|
'content2' => 'required_with:picture2|nullable|string|min:15',
|
||||||
'nullable',
|
|
||||||
'string',
|
|
||||||
new WysiwygLength(15, 2500)
|
|
||||||
],
|
|
||||||
'content2' => [
|
|
||||||
'required_with:picture2',
|
|
||||||
'nullable',
|
|
||||||
'string',
|
|
||||||
new WysiwygLength(15, 2500)
|
|
||||||
],
|
|
||||||
'event_start' => 'nullable|date_format:Y-m-d',
|
'event_start' => 'nullable|date_format:Y-m-d',
|
||||||
'event_end' => [
|
'event_end' => [
|
||||||
'required_with:event_start',
|
'required_with:event_start',
|
||||||
|
|
@ -92,12 +81,10 @@ class StoreNewsRequest extends FormRequest
|
||||||
'min:3',
|
'min:3',
|
||||||
'max:255'
|
'max:255'
|
||||||
],
|
],
|
||||||
'published' => 'required|boolean',
|
'status' => 'required|boolean',
|
||||||
'categories' => [
|
'categories' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (count($value) < 1 || count($value) > 2) {
|
if (count($value) < 1 || count($value) > 2) {
|
||||||
$fail(\trans('Vous devez associer une actualité à 1 ou 2 catégories.'));
|
$fail(\trans('Vous devez associer une actualité à 1 ou 2 catégories.'));
|
||||||
}
|
}
|
||||||
|
|
@ -107,10 +94,8 @@ class StoreNewsRequest extends FormRequest
|
||||||
'categories.*.value' => 'required|exists:news_categories,id',
|
'categories.*.value' => 'required|exists:news_categories,id',
|
||||||
'categories.*.label' => 'required|string',
|
'categories.*.label' => 'required|string',
|
||||||
'products' => [
|
'products' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (count($value) > 3) {
|
if (count($value) > 3) {
|
||||||
$fail(\trans('Vous devez associer au maximum 3 produits.'));
|
$fail(\trans('Vous devez associer au maximum 3 produits.'));
|
||||||
}
|
}
|
||||||
|
|
@ -120,10 +105,8 @@ class StoreNewsRequest extends FormRequest
|
||||||
'products.*.value' => 'required|exists:products,id',
|
'products.*.value' => 'required|exists:products,id',
|
||||||
'products.*.label' => 'required|string',
|
'products.*.label' => 'required|string',
|
||||||
'associated_news_list' => [
|
'associated_news_list' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (count($value) > 3) {
|
if (count($value) > 3) {
|
||||||
$fail(\trans('Vous devez associer au maximum 3 actualités.'));
|
$fail(\trans('Vous devez associer au maximum 3 actualités.'));
|
||||||
}
|
}
|
||||||
|
|
@ -135,8 +118,8 @@ class StoreNewsRequest extends FormRequest
|
||||||
];
|
];
|
||||||
return \array_merge(
|
return \array_merge(
|
||||||
$rules,
|
$rules,
|
||||||
$this->pictureRules('picture', 590, 645, 590, 645, false),
|
$this->pictureRules('picture', true, 920, 1025, 920, 1025),
|
||||||
$this->pictureRules('picture2', 590, 645, 590, 645, true, requiredWith: 'content2')
|
$this->pictureRules('picture2', false, 920, 1025, 920, 1025)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -164,7 +147,7 @@ class StoreNewsRequest extends FormRequest
|
||||||
'event_start' => trans('Date de début de l\'évènement'),
|
'event_start' => trans('Date de début de l\'évènement'),
|
||||||
'event_end' => trans('Date de fin de l\'évènement'),
|
'event_end' => trans('Date de fin de l\'évènement'),
|
||||||
'event_text' => trans('Description de l\'évènement'),
|
'event_text' => trans('Description de l\'évènement'),
|
||||||
'published' => trans('Status'),
|
'status' => trans('Status'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ namespace App\Http\Requests\Bo\Products;
|
||||||
|
|
||||||
use App\Enums\NutriscoreEnum;
|
use App\Enums\NutriscoreEnum;
|
||||||
use App\Enums\Products\ProductSpeciesEnum;
|
use App\Enums\Products\ProductSpeciesEnum;
|
||||||
use App\Rules\WysiwygLength;
|
|
||||||
use App\Traits\Requests\HasPicture;
|
use App\Traits\Requests\HasPicture;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
@ -36,19 +35,9 @@ class StoreProductRequest extends FormRequest
|
||||||
'is_frenchpoultry' => $this->is_frenchpoultry ? true : false,
|
'is_frenchpoultry' => $this->is_frenchpoultry ? true : false,
|
||||||
'is_vip' => $this->is_vip ? true : false,
|
'is_vip' => $this->is_vip ? true : false,
|
||||||
'is_egalim' => $this->is_egalim ? true : false,
|
'is_egalim' => $this->is_egalim ? true : false,
|
||||||
'published' => $this->published ? true : false,
|
'status' => $this->status ? true : false
|
||||||
'tags' => $this->input('tags', []),
|
|
||||||
// * For sync relations
|
|
||||||
'tags_list' => \collect($this->input('tags'))->map(function ($value) {
|
|
||||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
|
||||||
})->filter()->all(),
|
|
||||||
]);
|
]);
|
||||||
$this->mergePicture('sticker_sm');
|
$this->mergePicture('sticker_sm');
|
||||||
($this->slider_pictures)
|
|
||||||
? $this->mergePictures('slider_pictures')
|
|
||||||
: $this->merge([
|
|
||||||
'slider_pictures' => [],
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -67,26 +56,12 @@ class StoreProductRequest extends FormRequest
|
||||||
'nutriscore' => ['required', new Enum(NutriscoreEnum::class)],
|
'nutriscore' => ['required', new Enum(NutriscoreEnum::class)],
|
||||||
'sticker_sm_alt' => 'required|min:3|max:255',
|
'sticker_sm_alt' => 'required|min:3|max:255',
|
||||||
'sticker_sm_title' => 'required|min:3|max:255',
|
'sticker_sm_title' => 'required|min:3|max:255',
|
||||||
'ingredients' => [
|
'ingredients' => 'required|string|min:15',
|
||||||
'required',
|
'advantage' => 'required|string|min:15',
|
||||||
'string',
|
'preparation' => 'required|string|min:15',
|
||||||
new WysiwygLength(15, 2500)
|
|
||||||
],
|
|
||||||
'advantage' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
new WysiwygLength(15, 2500)
|
|
||||||
],
|
|
||||||
'preparation' => [
|
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
new WysiwygLength(15, 2500)
|
|
||||||
],
|
|
||||||
'packaging' => [
|
'packaging' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (1 > count($value) || count($value) > 6) {
|
if (1 > count($value) || count($value) > 6) {
|
||||||
$fail(\trans('Vous devez remplir au moins 1 ligne et au plus 6 lignes de conditionnement.'));
|
$fail(\trans('Vous devez remplir au moins 1 ligne et au plus 6 lignes de conditionnement.'));
|
||||||
}
|
}
|
||||||
|
|
@ -95,10 +70,8 @@ class StoreProductRequest extends FormRequest
|
||||||
'packaging.*' => 'required|array',
|
'packaging.*' => 'required|array',
|
||||||
'packaging.*.value' => 'required|string|min:2|max:255',
|
'packaging.*.value' => 'required|string|min:2|max:255',
|
||||||
'caliber' => [
|
'caliber' => [
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (1 > count($value) || count($value) > 6) {
|
if (1 > count($value) || count($value) > 6) {
|
||||||
$fail(\trans('Vous devez remplir au moins 1 ligne et au plus 6 lignes de calibre.'));
|
$fail(\trans('Vous devez remplir au moins 1 ligne et au plus 6 lignes de calibre.'));
|
||||||
}
|
}
|
||||||
|
|
@ -106,30 +79,27 @@ class StoreProductRequest extends FormRequest
|
||||||
],
|
],
|
||||||
'caliber.*' => 'required|array',
|
'caliber.*' => 'required|array',
|
||||||
'caliber.*.value' => 'required|string|min:1|max:255',
|
'caliber.*.value' => 'required|string|min:1|max:255',
|
||||||
'is_frenchpoultry' => 'required|boolean',
|
'nutritionnal_values' => 'required|array',
|
||||||
'is_vip' => 'required|boolean',
|
'nutritionnal_values' => [
|
||||||
'is_egalim' => 'required|boolean',
|
|
||||||
'published' => 'required|boolean',
|
|
||||||
// * TAGS
|
|
||||||
'tags' => [
|
|
||||||
'present',
|
|
||||||
'array',
|
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, array $value, $fail) {
|
'present', 'array', function ($attribute, array $value, $fail) {
|
||||||
if (count($value) > 2) {
|
if (count($value) != 9) {
|
||||||
$fail(\trans('Vous devez associer au maximum 2 tags.'));
|
$fail(\trans('Vous devez remplir seulement 9 lignes de valeurs nutritionnelles.'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'tags.*' => 'required|array',
|
'nutritionnal_values.*' => 'nullable|array',
|
||||||
'tags.*.id' => 'required|numeric|exists:tags,id|distinct',
|
'nutritionnal_values.*.label' => 'nullable|string|min:3|max:255',
|
||||||
'tags.*.label' => 'required|string',
|
'nutritionnal_values.*.value' => 'nullable|numeric|min:0',
|
||||||
|
'is_frenchpoultry' => 'required|boolean',
|
||||||
|
'is_vip' => 'required|boolean',
|
||||||
|
'is_egalim' => 'required|boolean',
|
||||||
|
'status' => 'required|boolean'
|
||||||
];
|
];
|
||||||
return \array_merge(
|
return \array_merge(
|
||||||
$rules,
|
$rules,
|
||||||
$this->pictureRules('sticker_sm', 206, 159, 206, 159, false),
|
$this->pictureRules('sticker_sm', true, 206, 159, 206, 159),
|
||||||
$this->picturesRules('slider_pictures', 396, 286, 396, 286, 1, 5, true),
|
$this->picturesRules('slider_pictures', true, 396, 286, 396, 286, 1, 5),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,30 +111,29 @@ class StoreProductRequest extends FormRequest
|
||||||
public function attributes(): array
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'label' => trans('title'),
|
'label' => trans('title'),
|
||||||
'slug' => trans('slug'),
|
'slug' => trans('slug'),
|
||||||
'seo_title' => trans('title') . ' seo',
|
'seo_title' => trans('title') . ' seo',
|
||||||
'seo_description' => trans('description') . ' seo',
|
'seo_description' => trans('description') . ' seo',
|
||||||
'subrange_id' => trans('sous-gamme'),
|
'subrange_id' => trans('sous-gamme'),
|
||||||
'species' => trans('Espèce du produit'),
|
'species' => trans('Espèce du produit'),
|
||||||
'nutriscore' => trans('Label Nutriscore'),
|
'nutriscore' => trans('Label Nutriscore'),
|
||||||
'sticker_sm' => trans('miniature'),
|
'sticker_sm' => trans('miniature'),
|
||||||
'sticker_sm_alt' => trans('attribut alt de la miniature'),
|
'sticker_sm_alt' => trans('attribut alt de la miniature'),
|
||||||
'sticker_sm_title' => trans('titre de la miniature'),
|
'sticker_sm_title' => trans('titre de la miniature'),
|
||||||
'slider_pictures' => trans('images du slider'),
|
'slider_pictures' => trans('images du slider'),
|
||||||
'slider_pictures.*' => trans('image du slider'),
|
'slider_pictures.*' => trans('image du slider'),
|
||||||
'packaging' => trans('conditionnement'),
|
'packaging' => trans('conditionnement'),
|
||||||
'packaging.*.value' => trans('valeur du conditionnement'),
|
'packaging.*.value' => trans('valeur du conditionnement'),
|
||||||
'caliber' => trans('calibre'),
|
'caliber' => trans('calibre'),
|
||||||
'caliber.*.value' => trans('valeur du calibre'),
|
'caliber.*.value' => trans('valeur du calibre'),
|
||||||
'is_frenchpoultry' => trans('Label volaille française'),
|
'nutritionnal_values' => trans('valeurs nutritionnelles'),
|
||||||
'is_vip' => trans('Produit VIP'),
|
'nutritionnal_values.*.label' => trans('libellé de la valeur nutritionnelle'),
|
||||||
'is_egalim' => trans('Produit Égalim'),
|
'nutritionnal_values.*.value' => trans('valeur de la valeur nutritionnelle'),
|
||||||
'published' => trans('publish'),
|
'is_frenchpoultry' => trans('Label volaille française'),
|
||||||
'tags' => trans('tag'),
|
'is_vip' => trans('Produit VIP'),
|
||||||
'tags.*' => trans('tag'),
|
'is_egalim' => trans('Produit Égalim'),
|
||||||
'tags.*.id' => trans('id du tag'),
|
'status' => trans('publish')
|
||||||
'tags.*.label' => trans('label du tag'),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,8 @@ class UpdateRangeRequest extends FormRequest
|
||||||
];
|
];
|
||||||
return \array_merge(
|
return \array_merge(
|
||||||
$rules,
|
$rules,
|
||||||
$this->pictureRules('picture', 290, 232, 290, 232, true),
|
$this->pictureRules('picture', true, 290, 232, 290, 232),
|
||||||
$this->pictureRules('picture_banner', 1440, 300, 1440, 300, true),
|
$this->pictureRules('picture_banner', true, 1440, 300, 1440, 300),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Http\Requests\Bo\Slides;
|
namespace App\Http\Requests\Bo\Slides;
|
||||||
|
|
||||||
use App\Rules\WysiwygLength;
|
|
||||||
use App\Traits\Requests\HasPicture;
|
use App\Traits\Requests\HasPicture;
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
|
@ -28,9 +27,8 @@ class StoreSlideRequest extends FormRequest
|
||||||
protected function prepareForValidation(): void
|
protected function prepareForValidation(): void
|
||||||
{
|
{
|
||||||
$this->merge([
|
$this->merge([
|
||||||
'button_display' => $this->boolean('button_display'),
|
'button_display' => $this->button_display ? true : false,
|
||||||
'button_targetblank' => $this->boolean('button_targetblank'),
|
'button_targetblank' => $this->button_targetblank ? true : false,
|
||||||
'published' => $this->boolean('published'),
|
|
||||||
]);
|
]);
|
||||||
$this->mergePicture('picture');
|
$this->mergePicture('picture');
|
||||||
$this->mergePicture('picture_thumbnail');
|
$this->mergePicture('picture_thumbnail');
|
||||||
|
|
@ -45,11 +43,7 @@ class StoreSlideRequest extends FormRequest
|
||||||
{
|
{
|
||||||
$rules = [
|
$rules = [
|
||||||
'title' => 'required|min:3|max:255',
|
'title' => 'required|min:3|max:255',
|
||||||
'content' => [
|
'content' => 'required|string|min:15|max:540',
|
||||||
'required',
|
|
||||||
'string',
|
|
||||||
new WysiwygLength(15, 2500)
|
|
||||||
],
|
|
||||||
'button_display' => 'required|boolean',
|
'button_display' => 'required|boolean',
|
||||||
'button_text' => 'nullable|min:3|max:45',
|
'button_text' => 'nullable|min:3|max:45',
|
||||||
'button_url' => 'nullable|min:3|max:255|url',
|
'button_url' => 'nullable|min:3|max:255|url',
|
||||||
|
|
@ -57,13 +51,12 @@ class StoreSlideRequest extends FormRequest
|
||||||
'picture_alt' => 'required|min:3|max:255',
|
'picture_alt' => 'required|min:3|max:255',
|
||||||
'picture_title' => 'required|min:3|max:255',
|
'picture_title' => 'required|min:3|max:255',
|
||||||
'picture_thumbnail_alt' => 'required|min:3|max:255',
|
'picture_thumbnail_alt' => 'required|min:3|max:255',
|
||||||
'picture_thumbnail_title' => 'required|min:3|max:255',
|
'picture_thumbnail_title' => 'required|min:3|max:255'
|
||||||
'published' => 'required|boolean',
|
|
||||||
];
|
];
|
||||||
return \array_merge(
|
return \array_merge(
|
||||||
$rules,
|
$rules,
|
||||||
$this->pictureRules('picture', 950, 700, 950, 700, true),
|
$this->pictureRules('picture', true, 950, 700, 950, 700),
|
||||||
$this->pictureRules('picture_thumbnail', 167, 70, 167, 70, true)
|
$this->pictureRules('picture_thumbnail', true, 167, 70, 167, 70)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Bo\StaticPages;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class UpdateStaticPageRequest extends FormRequest
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Determine if the user is authorized to make this request.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return auth('backend')->check();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the data for validation.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function prepareForValidation(): void
|
|
||||||
{
|
|
||||||
$this->merge([
|
|
||||||
'content' => Str::of($this->post('content'))->value()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the validation rules that apply to the request.
|
|
||||||
*
|
|
||||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
|
||||||
*/
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'seo_title' => 'required|min:45|max:70',
|
|
||||||
'seo_description' => 'required|min:50|max:160',
|
|
||||||
'title' => 'required|min:3|max:255',
|
|
||||||
'content' => 'present',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,10 +2,8 @@
|
||||||
|
|
||||||
namespace App\Http\Requests\Bo\Tags;
|
namespace App\Http\Requests\Bo\Tags;
|
||||||
|
|
||||||
use App\Enums\TagTypeEnum;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Validation\Rule;
|
|
||||||
|
|
||||||
class StoreTagRequest extends FormRequest
|
class StoreTagRequest extends FormRequest
|
||||||
{
|
{
|
||||||
|
|
@ -40,10 +38,6 @@ class StoreTagRequest extends FormRequest
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'label' => 'required|min:2|max:30',
|
'label' => 'required|min:2|max:30',
|
||||||
'type' => [
|
|
||||||
'required',
|
|
||||||
Rule::enum(TagTypeEnum::class),
|
|
||||||
]
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +51,6 @@ class StoreTagRequest extends FormRequest
|
||||||
return [
|
return [
|
||||||
'label' => trans('libellé'),
|
'label' => trans('libellé'),
|
||||||
'slug' => trans('slug'),
|
'slug' => trans('slug'),
|
||||||
'type' => trans('type'),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Bo;
|
|
||||||
|
|
||||||
use App\Interfaces\OrderableInterface;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class UpdateOrderRequest extends FormRequest
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Attribute model needed.
|
|
||||||
*
|
|
||||||
* @var Model $orderable
|
|
||||||
*/
|
|
||||||
private Model $orderable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the user is authorized to make this request.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return auth('backend')->check();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the data for validation.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function prepareForValidation(): void
|
|
||||||
{
|
|
||||||
$this->orderable = collect($this->route()->parameters())
|
|
||||||
->first(fn($param) => $param instanceof Model);
|
|
||||||
|
|
||||||
$groupField = $this->orderable->getOrderGroupField();
|
|
||||||
|
|
||||||
if ($groupField) {
|
|
||||||
$this->orderable::query()->where($groupField, $this->orderable->{$groupField});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the validation rules that apply to the request.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'priority_order' => [
|
|
||||||
'required',
|
|
||||||
'integer',
|
|
||||||
'min:1',
|
|
||||||
sprintf('max:%s', $this->orderable->max('priority_order')),
|
|
||||||
function ($value, $fail) {
|
|
||||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
|
||||||
if ($this->orderable instanceof OrderableInterface && intval($value) === $this->orderable->getPriorityOrder()) {
|
|
||||||
$fail(trans('validation.custom.same_priority'));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -20,18 +20,6 @@ class ContactRequest extends FormRequest
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare the data for validation.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function prepareForValidation(): void
|
|
||||||
{
|
|
||||||
$this->merge([
|
|
||||||
'opt_in' => $this->boolean('opt_in'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the validation rules that apply to the request.
|
* Get the validation rules that apply to the request.
|
||||||
*
|
*
|
||||||
|
|
@ -48,12 +36,11 @@ class ContactRequest extends FormRequest
|
||||||
'phone' => 'required|max:255|phone:' . implode(',', $this->isoCodes()),
|
'phone' => 'required|max:255|phone:' . implode(',', $this->isoCodes()),
|
||||||
'activity' => ['required', new Enum(ContactActivityEnum::class)],
|
'activity' => ['required', new Enum(ContactActivityEnum::class)],
|
||||||
'society' => 'nullable|string|max:255',
|
'society' => 'nullable|string|max:255',
|
||||||
'postcode' => 'required|postal_code:' . implode(',', $this->isoCodes()),
|
'postcode' => 'nullable|postal_code:' . implode(',', $this->isoCodes()),
|
||||||
'city' => 'nullable|string|max:255',
|
'city' => 'nullable|string|max:255',
|
||||||
'message' => 'required|string|min:20|max:255',
|
'message' => 'required|string|min:20|max:255',
|
||||||
'callTime' => ['required', new Enum(ContactTimeEnum::class)],
|
'callTime' => ['required', new Enum(ContactTimeEnum::class)],
|
||||||
'brigade' => 'nullable|boolean',
|
'rgpd' => 'accepted'
|
||||||
'opt_in' => 'required|boolean',
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,8 +81,7 @@ class ContactRequest extends FormRequest
|
||||||
'city' => trans('ville'),
|
'city' => trans('ville'),
|
||||||
'message' => trans('message'),
|
'message' => trans('message'),
|
||||||
'callTime' => trans('préférence de rappel'),
|
'callTime' => trans('préférence de rappel'),
|
||||||
'brigade' => trans('La Brigade'),
|
'rgpd' => trans('condition d\'utilisation'),
|
||||||
'opt_in' => trans('newsletter'),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Fo\Newsletter;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class SingleOptinRequest extends FormRequest
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Determine if the user is authorized to make this request.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function authorize()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the validation rules that apply to the request.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function rules()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'email' => 'required|email:rfc,dns,spoof',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Requests\Fo\Newsletter;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
|
||||||
|
|
||||||
class UnsubscribeNewsletterRequest extends FormRequest
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Determine if the user is authorized to make this request.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public function authorize(): bool
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the validation rules that apply to the request.
|
|
||||||
*
|
|
||||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
|
||||||
*/
|
|
||||||
public function rules(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'hashcode' => 'required|uuid'
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -24,7 +24,7 @@ class AjaxAddProductBasket extends FormRequest
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'packaging' => 'array',
|
'packaging' => 'required|array|min:1',
|
||||||
'packaging.*' => [
|
'packaging.*' => [
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, $value, $fail) {
|
function ($attribute, $value, $fail) {
|
||||||
|
|
@ -37,7 +37,7 @@ class AjaxAddProductBasket extends FormRequest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'caliber' => 'array',
|
'caliber' => 'required|array|min:1',
|
||||||
'caliber.*' => [
|
'caliber.*' => [
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
function ($attribute, $value, $fail) {
|
function ($attribute, $value, $fail) {
|
||||||
|
|
@ -56,7 +56,7 @@ class AjaxAddProductBasket extends FormRequest
|
||||||
/**
|
/**
|
||||||
* Get custom attributes for validator errors.
|
* Get custom attributes for validator errors.
|
||||||
*
|
*
|
||||||
* @return array<string,string>
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function attributes(): array
|
public function attributes(): array
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,8 @@ class AjaxFilterProductsRequest extends FormRequest
|
||||||
{
|
{
|
||||||
$this->merge([
|
$this->merge([
|
||||||
'vip' => $this->vip ? true : false,
|
'vip' => $this->vip ? true : false,
|
||||||
'subranges' => isset($this->subranges) ?
|
'subranges' => isset($this->subranges) ? explode(',', $this->subranges) :
|
||||||
explode(',', $this->subranges) : (\is_array($this->subranges) ? $this->subranges : [])
|
(\is_array($this->subranges) ? $this->subranges : [])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ class AjaxFilterProductsRequest extends FormRequest
|
||||||
$rules['subranges'] = 'present|array';
|
$rules['subranges'] = 'present|array';
|
||||||
$rules['subranges.*'] = [
|
$rules['subranges.*'] = [
|
||||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||||
'exists:subranges,id', function (string $attribute, $value, callable $fail) {
|
'exists:subranges,id', function ($attribute, $value, $fail) {
|
||||||
if (empty($this->range) or !\is_object($this->range) or \get_class($this->range) !== Range::class) {
|
if (empty($this->range) or !\is_object($this->range) or \get_class($this->range) !== Range::class) {
|
||||||
$fail(trans('La gamme est obligatoire', ['attribute' => $attribute]));
|
$fail(trans('La gamme est obligatoire', ['attribute' => $attribute]));
|
||||||
return;
|
return;
|
||||||
|
|
@ -59,7 +59,7 @@ class AjaxFilterProductsRequest extends FormRequest
|
||||||
$hasSubrange = Range::query()->whereHas('subranges', function (Builder $q) use ($subrange) {
|
$hasSubrange = Range::query()->whereHas('subranges', function (Builder $q) use ($subrange) {
|
||||||
$q->where('id', $subrange->id);
|
$q->where('id', $subrange->id);
|
||||||
})->where('id', $this->range->id)->exists();
|
})->where('id', $this->range->id)->exists();
|
||||||
if (!$hasSubrange) {
|
if (empty($value) or !$hasSubrange) {
|
||||||
$fail(trans(':attribute doit appartenir à la bonne gamme', ['attribute' => $attribute]));
|
$fail(trans(':attribute doit appartenir à la bonne gamme', ['attribute' => $attribute]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ class ProductCommercialSheetResource extends JsonResource
|
||||||
'ingredients' => '',
|
'ingredients' => '',
|
||||||
'preparation' => '',
|
'preparation' => '',
|
||||||
'sticker_sm' => '',
|
'sticker_sm' => '',
|
||||||
|
'nutritionnal_values' => [],
|
||||||
'slider_pictures' => [],
|
'slider_pictures' => [],
|
||||||
'subrange' => null,
|
'subrange' => null,
|
||||||
];
|
];
|
||||||
|
|
@ -64,6 +65,7 @@ class ProductCommercialSheetResource extends JsonResource
|
||||||
'caliber' => $this->product->caliber,
|
'caliber' => $this->product->caliber,
|
||||||
'ingredients' => $this->product->ingredients,
|
'ingredients' => $this->product->ingredients,
|
||||||
'preparation' => $this->product->preparation,
|
'preparation' => $this->product->preparation,
|
||||||
|
'nutritionnal_values' => $this->product->nutritionnal_values,
|
||||||
'sticker_sm' => $this->product->sticker_sm,
|
'sticker_sm' => $this->product->sticker_sm,
|
||||||
'slider_pictures' => $this->product->slider_pictures,
|
'slider_pictures' => $this->product->slider_pictures,
|
||||||
'subrange' => (new SubrangeResource($this->product->subrange))->toArray($request),
|
'subrange' => (new SubrangeResource($this->product->subrange))->toArray($request),
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Interfaces;
|
|
||||||
|
|
||||||
interface OrderableInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Returns the priority order value.
|
|
||||||
*
|
|
||||||
* @return integer
|
|
||||||
*/
|
|
||||||
public function getPriorityOrder(): int;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the grouping field used for ordering.
|
|
||||||
* Returns null if the order is global.
|
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getOrderGroupField(): ?string;
|
|
||||||
}
|
|
||||||
37
app/Lib/CompleteSitemapWith.php
Normal file
37
app/Lib/CompleteSitemapWith.php
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Lib;
|
||||||
|
|
||||||
|
use App\Enums\Advices\AdviceTypeEnum;
|
||||||
|
use App\Models\Advice;
|
||||||
|
use App\Models\Product;
|
||||||
|
use LDC\SitemapGenerator\Lib\Sitemap;
|
||||||
|
|
||||||
|
class CompleteSitemapWith
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Use this method to append a list of links to the sitemap
|
||||||
|
*
|
||||||
|
* * Please call $sitemap->mergeUrls to append url for any specific route name.
|
||||||
|
*
|
||||||
|
* @param \LDC\SitemapGenerator\Lib\Sitemap $sitemap
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function append(Sitemap $sitemap): void
|
||||||
|
{
|
||||||
|
// * Ajouts des éléments qui sont affichés en random
|
||||||
|
$sitemap->mergeUrls(Product::query()->where('status', true)->pluck('slug')->transform(function (string $slug) {
|
||||||
|
return \route('fo.product.show', $slug);
|
||||||
|
}));
|
||||||
|
$sitemap->mergeUrls(Advice::query()
|
||||||
|
->where('status', true)->where('type', AdviceTypeEnum::recipes)
|
||||||
|
->pluck('slug')->transform(function (string $slug) {
|
||||||
|
return \route('fo.recipes.show', $slug);
|
||||||
|
}));
|
||||||
|
$sitemap->mergeUrls(Advice::query()
|
||||||
|
->where('status', true)->where('type', AdviceTypeEnum::tips)
|
||||||
|
->pluck('slug')->transform(function (string $slug) {
|
||||||
|
return \route('fo.tips.show', $slug);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -145,7 +145,7 @@ class ExceptionsHelper
|
||||||
$traceStr .= self::handleArgs($stack);
|
$traceStr .= self::handleArgs($stack);
|
||||||
}
|
}
|
||||||
$traceStr .= ")\n";
|
$traceStr .= ")\n";
|
||||||
} else {
|
} elseif (isset($stack['function'])) {
|
||||||
$traceStr .= "{$stack['function']}(";
|
$traceStr .= "{$stack['function']}(";
|
||||||
if (isset($stack['args'])) {
|
if (isset($stack['args'])) {
|
||||||
$traceStr .= self::handleArgs($stack);
|
$traceStr .= self::handleArgs($stack);
|
||||||
|
|
|
||||||
|
|
@ -30,20 +30,6 @@ use Illuminate\Support\Str;
|
||||||
*/
|
*/
|
||||||
class FileStorageHelper
|
class FileStorageHelper
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Remove all files from string attribute html that are stored in public
|
|
||||||
*
|
|
||||||
* @param string $publicStorageFilePath The file path from public directory.
|
|
||||||
* @return string The local storage path.
|
|
||||||
*/
|
|
||||||
public static function getFileFullPath(string $publicStorageFilePath): string
|
|
||||||
{
|
|
||||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
|
||||||
$disk = Storage::disk('uploads');
|
|
||||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
|
||||||
return $disk->path($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the file associate with the attribute.
|
* Destroy the file associate with the attribute.
|
||||||
*
|
*
|
||||||
|
|
@ -63,20 +49,6 @@ class FileStorageHelper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Destroy files associate with the attribute.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Database\Eloquent\Model $model
|
|
||||||
* @param array $array
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function removeFiles(Model $model, array $array): void
|
|
||||||
{
|
|
||||||
foreach ($array as $item) {
|
|
||||||
self::removeFile($model, $item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the file associate with the attribute old value (before updated to DB).
|
* Destroy the file associate with the attribute old value (before updated to DB).
|
||||||
*
|
*
|
||||||
|
|
@ -119,7 +91,7 @@ class FileStorageHelper
|
||||||
Model $model,
|
Model $model,
|
||||||
$file,
|
$file,
|
||||||
bool $slugify = false,
|
bool $slugify = false,
|
||||||
string|null $filename = null,
|
string $filename = null,
|
||||||
bool $private = false
|
bool $private = false
|
||||||
): string {
|
): string {
|
||||||
// phpcs:enable
|
// phpcs:enable
|
||||||
|
|
@ -180,7 +152,7 @@ class FileStorageHelper
|
||||||
public static function storeModelFilesFromHtml(
|
public static function storeModelFilesFromHtml(
|
||||||
Model $model,
|
Model $model,
|
||||||
string $htmlString,
|
string $htmlString,
|
||||||
string|null $oldHtmlString = null
|
string $oldHtmlString = null
|
||||||
): string {
|
): string {
|
||||||
\collect(self::onlyUploadedFilesWithFileManager(self::findFilesInHtml($htmlString)))
|
\collect(self::onlyUploadedFilesWithFileManager(self::findFilesInHtml($htmlString)))
|
||||||
->each(function (string $path) use ($model, &$htmlString) {
|
->each(function (string $path) use ($model, &$htmlString) {
|
||||||
|
|
@ -336,7 +308,8 @@ class FileStorageHelper
|
||||||
$folderPath = self::getStoragePath(
|
$folderPath = self::getStoragePath(
|
||||||
$private ? 'app/private/modelfiles' : 'app/public/modelfiles',
|
$private ? 'app/private/modelfiles' : 'app/public/modelfiles',
|
||||||
$tableName,
|
$tableName,
|
||||||
$filename
|
$filename,
|
||||||
|
$private
|
||||||
);
|
);
|
||||||
$filename = self::getFileUniqueName($folderPath, $filename);
|
$filename = self::getFileUniqueName($folderPath, $filename);
|
||||||
return "{$folderPath}/{$filename}";
|
return "{$folderPath}/{$filename}";
|
||||||
|
|
@ -431,7 +404,7 @@ class FileStorageHelper
|
||||||
$filename = Str::of($filename)->ltrim('.-');
|
$filename = Str::of($filename)->ltrim('.-');
|
||||||
// * Optional beautification
|
// * Optional beautification
|
||||||
if ($beautify) {
|
if ($beautify) {
|
||||||
$filename = self::beautifyFilename($filename);
|
$filename = static::beautifyFilename($filename);
|
||||||
}
|
}
|
||||||
// * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
// * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
||||||
/** @var string */
|
/** @var string */
|
||||||
|
|
|
||||||
|
|
@ -22,36 +22,6 @@ use Symfony\Component\Finder\SplFileInfo;
|
||||||
|
|
||||||
class ToolboxHelper
|
class ToolboxHelper
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Run a terminal command and gives the output
|
|
||||||
*
|
|
||||||
* @param array|string $command The command to execute on terminal.
|
|
||||||
* @param boolean $throw Wether to throw en esception on failure or not.
|
|
||||||
* @return string|false Return false on failure only if $throw is false.
|
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
|
|
||||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
|
||||||
* @throws \Illuminate\Process\Exceptions\ProcessTimedOutException
|
|
||||||
* @throws \Symfony\Component\Process\Exception\LogicException
|
|
||||||
* @throws \Symfony\Component\Process\Exception\InvalidArgumentException
|
|
||||||
* @throws \Symfony\Component\Process\Exception\RuntimeException
|
|
||||||
* @throws \LogicException
|
|
||||||
* @throws \RuntimeException If the command fails.
|
|
||||||
*/
|
|
||||||
public static function runConsoleCommand(array|string $command, bool $throw = true): string | false
|
|
||||||
{
|
|
||||||
// phpcs:enable
|
|
||||||
$process = \Illuminate\Support\Facades\Process::command($command)->run();
|
|
||||||
if ($process->failed()) {
|
|
||||||
$code = $process->exitCode();
|
|
||||||
$ouput = $process->errorOutput();
|
|
||||||
if ($throw) {
|
|
||||||
throw new \RuntimeException("Failed to run command exit code {$code} with output \n{$ouput}");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return $process->output();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int|string, mixed> $array1
|
* @param array<int|string, mixed> $array1
|
||||||
* @param array<int|string, mixed> $array2
|
* @param array<int|string, mixed> $array2
|
||||||
|
|
@ -106,7 +76,7 @@ class ToolboxHelper
|
||||||
throw new \RuntimeException();
|
throw new \RuntimeException();
|
||||||
}
|
}
|
||||||
if (\floatval($response->json('score')) < 0.8) {
|
if (\floatval($response->json('score')) < 0.8) {
|
||||||
$fail(trans('recaptcha.not_enough_score'));
|
$fail("Vous n'avez pas obtenu un score assez élevé lors de la validation du recaptcha");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -119,7 +89,7 @@ class ToolboxHelper
|
||||||
throw new \RuntimeException();
|
throw new \RuntimeException();
|
||||||
}
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$fail(trans('recaptcha.error'));
|
$fail('Erreur lors de la validation du formulaire veuillez réssayer');
|
||||||
} //end try
|
} //end try
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
@ -206,10 +176,11 @@ class ToolboxHelper
|
||||||
$url = $match;
|
$url = $match;
|
||||||
try {
|
try {
|
||||||
$request = Request::create($url);
|
$request = Request::create($url);
|
||||||
// Assert route matches existing routes.
|
// If a route is match then it do not throws exception.
|
||||||
$routes->match($request);
|
if (
|
||||||
// ? Is url internal ?
|
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||||
if (\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST)) {
|
$routes->match($request)
|
||||||
|
) {
|
||||||
// Removes the matched url.
|
// Removes the matched url.
|
||||||
throw ValidationException::withMessages([
|
throw ValidationException::withMessages([
|
||||||
$field => trans(
|
$field => trans(
|
||||||
|
|
@ -235,14 +206,14 @@ class ToolboxHelper
|
||||||
* @param array|string $replace
|
* @param array|string $replace
|
||||||
* @param array|string $subject
|
* @param array|string $subject
|
||||||
* @param integer $count
|
* @param integer $count
|
||||||
* @return array|string|false
|
* @return array|string
|
||||||
*/
|
*/
|
||||||
public static function mbReplace(
|
public static function mbReplace(
|
||||||
array|string $search,
|
array|string $search,
|
||||||
array|string $replace,
|
array|string $replace,
|
||||||
array|string $subject,
|
array|string $subject,
|
||||||
int &$count = 0
|
int &$count = 0
|
||||||
): array|string|false {
|
): array|string {
|
||||||
if (!is_array($search) && is_array($replace)) {
|
if (!is_array($search) && is_array($replace)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -318,17 +289,10 @@ class ToolboxHelper
|
||||||
*/
|
*/
|
||||||
public static function getOriginal(Model $model, string $attribute): mixed
|
public static function getOriginal(Model $model, string $attribute): mixed
|
||||||
{
|
{
|
||||||
if (
|
if (\in_array('Spatie\Translatable\HasTranslations', \class_uses_recursive($model))) {
|
||||||
\in_array('Spatie\Translatable\HasTranslations', \class_uses_recursive($model)) and
|
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
$model->isTranslatableAttribute($attribute)
|
|
||||||
) {
|
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
return $model->getTranslation(
|
return $model->getTranslation(
|
||||||
$attribute,
|
$attribute,
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
$model->getLocale(),
|
$model->getLocale(),
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
$model->useFallbackLocale()
|
$model->useFallbackLocale()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -398,45 +362,47 @@ class ToolboxHelper
|
||||||
/**
|
/**
|
||||||
* Convert deeply an object to array
|
* Convert deeply an object to array
|
||||||
*
|
*
|
||||||
* @param mixed $input
|
* @param array|object $input
|
||||||
* @return array
|
* @return array
|
||||||
* @throws \RuntimeException If $input var is a scalar value.
|
* @throws \RuntimeException If $input var is a scalar value.
|
||||||
*/
|
*/
|
||||||
public static function objectToArray(mixed $input): array
|
public static function objectToArray($input): array
|
||||||
{
|
{
|
||||||
// Only process if it's an object or array being passed to the function.
|
// Only process if it's an object or array being passed to the function.
|
||||||
if (!(is_object($input) or is_array($input))) {
|
if (is_object($input) or is_array($input)) {
|
||||||
|
$ret = (array)$input;
|
||||||
|
foreach ($ret as &$item) {
|
||||||
|
// Recursively process EACH element only if not scalar.
|
||||||
|
$item = (is_object($item) or is_array($item)) ?
|
||||||
|
self::objectToArray($item) : $item;
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
} else {
|
||||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||||
}
|
}
|
||||||
$ret = (array)$input;
|
|
||||||
foreach ($ret as &$item) {
|
|
||||||
// Recursively process EACH element only if not scalar.
|
|
||||||
$item = (is_object($item) or is_array($item)) ?
|
|
||||||
self::objectToArray($item) : $item;
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert deeply an array to object
|
* Convert deeply an array to object
|
||||||
*
|
*
|
||||||
* @param mixed $input
|
* @param array|object $input
|
||||||
* @return object
|
* @return object
|
||||||
* @throws \RuntimeException If $input var is a scalar value.
|
* @throws \RuntimeException If $input var is a scalar value.
|
||||||
*/
|
*/
|
||||||
public static function arrayToObject(mixed $input): object
|
public static function arrayToObject($input): object
|
||||||
{
|
{
|
||||||
// Only process if it's an object or array being passed to the function.
|
// Only process if it's an object or array being passed to the function.
|
||||||
if (!(is_object($input) or is_array($input))) {
|
if (is_object($input) or is_array($input)) {
|
||||||
|
$ret = (object)$input;
|
||||||
|
foreach ($ret as &$item) {
|
||||||
|
// Recursively process EACH element only if not scalar.
|
||||||
|
$item = (is_object($item) or is_array($item)) ?
|
||||||
|
self::arrayToObject($item) : $item;
|
||||||
|
}
|
||||||
|
return $ret;
|
||||||
|
} else {
|
||||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||||
}
|
}
|
||||||
$ret = (object)$input;
|
|
||||||
foreach ($ret as &$item) {
|
|
||||||
// Recursively process EACH element only if not scalar.
|
|
||||||
$item = (is_object($item) or is_array($item)) ?
|
|
||||||
self::arrayToObject($item) : $item;
|
|
||||||
}
|
|
||||||
return $ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -444,11 +410,11 @@ class ToolboxHelper
|
||||||
*
|
*
|
||||||
* @param string $attribute
|
* @param string $attribute
|
||||||
* @param string|null $value
|
* @param string|null $value
|
||||||
* @param callable $fail
|
* @param callback $fail
|
||||||
* @param object $sizes
|
* @param object $sizes
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes): void
|
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes)
|
||||||
{
|
{
|
||||||
if (!($useStorage = Storage::exists($value)) and !File::exists($value)) {
|
if (!($useStorage = Storage::exists($value)) and !File::exists($value)) {
|
||||||
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
||||||
|
|
@ -456,6 +422,7 @@ class ToolboxHelper
|
||||||
]));
|
]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/** @var string */
|
||||||
$fileFullPath = self::getUploadedFileFullPath($value, $useStorage);
|
$fileFullPath = self::getUploadedFileFullPath($value, $useStorage);
|
||||||
if (
|
if (
|
||||||
!\in_array(self::getUploadedFileMimeType($value, $useStorage), [
|
!\in_array(self::getUploadedFileMimeType($value, $useStorage), [
|
||||||
|
|
@ -466,7 +433,7 @@ class ToolboxHelper
|
||||||
'attribute' => $attribute
|
'attribute' => $attribute
|
||||||
]));
|
]));
|
||||||
}
|
}
|
||||||
if (!($dimensions = \getimagesize($fileFullPath))) {
|
if (!($dimensions = \getimagesize($fileFullPath)) or !isset($dimensions[0]) or !isset($dimensions[1])) {
|
||||||
$fail(trans(':attribute impossible de valider les dimensions', [
|
$fail(trans(':attribute impossible de valider les dimensions', [
|
||||||
'attribute' => $attribute
|
'attribute' => $attribute
|
||||||
]));
|
]));
|
||||||
|
|
@ -475,19 +442,19 @@ class ToolboxHelper
|
||||||
$height = intval($dimensions[1]);
|
$height = intval($dimensions[1]);
|
||||||
|
|
||||||
$xMessage = trans(
|
$xMessage = trans(
|
||||||
":attribute la largeur doit être comprise entre {$sizes->minWidth}px et {$sizes->maxWidth}px"
|
":attribute la largeur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px"
|
||||||
);
|
);
|
||||||
if ($sizes->minWidth === $sizes->maxWidth) {
|
if ($sizes->minWith === $sizes->maxWith) {
|
||||||
$xMessage = trans(":attribute la largeur doit être de {$sizes->minWidth}px");
|
$xMessage = trans(":attribute la largeur doit être de {$sizes->minWith}px");
|
||||||
}
|
}
|
||||||
$yMessage = trans(
|
$yMessage = trans(
|
||||||
":attribute la hauteur doit être comprise entre {$sizes->minWidth}px et {$sizes->maxWidth}px"
|
":attribute la hauteur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px"
|
||||||
);
|
);
|
||||||
if ($sizes->minHeight === $sizes->maxHeight) {
|
if ($sizes->minHeight === $sizes->maxHeight) {
|
||||||
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minHeight}px");
|
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minWith}px");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($width < $sizes->minWidth) or ($width > $sizes->maxWidth)) {
|
if (($width < $sizes->minWith) or ($width > $sizes->maxWith)) {
|
||||||
$fail($xMessage);
|
$fail($xMessage);
|
||||||
}
|
}
|
||||||
if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) {
|
if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) {
|
||||||
|
|
@ -552,26 +519,6 @@ class ToolboxHelper
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get validated pagination from request.
|
|
||||||
*
|
|
||||||
* @param integer $default
|
|
||||||
* @param string $field
|
|
||||||
* @param string $enumPath
|
|
||||||
* @return integer
|
|
||||||
*/
|
|
||||||
public static function getValidatedEnum(int $default, string $field, string $enumPath): int
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
return \intval(Validator::make(
|
|
||||||
[$field => \request()->get($field)],
|
|
||||||
[$field => new Enum($enumPath)]
|
|
||||||
)->validated()[$field]);
|
|
||||||
} catch (ValidationException $e) {
|
|
||||||
return $default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get validated pagination from request.
|
* Get validated pagination from request.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ class ContactFormMail extends Mailable
|
||||||
*/
|
*/
|
||||||
public function build()
|
public function build()
|
||||||
{
|
{
|
||||||
return $this->from(config('mail.from.address'))
|
return $this->from(config('mail.contactsList.contactform'))
|
||||||
->subject(sprintf("%s : %s", config('app.name'), trans("Nouveau contact")))
|
->subject(sprintf("%s : %s", config('app.name'), trans("Nouveau contact")))
|
||||||
->markdown('fo.emails.contact-form', $this->request->toArray());
|
->markdown('fo.emails.contact-form', $this->request->toArray());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,60 +2,48 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Interfaces\OrderableInterface;
|
|
||||||
use App\Enums\Advices\AdviceDifficultyEnum;
|
|
||||||
use App\Enums\Advices\AdviceTypeEnum;
|
use App\Enums\Advices\AdviceTypeEnum;
|
||||||
|
use App\Enums\Advices\AdviceDifficultyEnum;
|
||||||
use App\Lib\Helpers\FileStorageHelper;
|
use App\Lib\Helpers\FileStorageHelper;
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
use App\Traits\Models\Orderable;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Spatie\Sitemap\Contracts\Sitemapable;
|
|
||||||
use Spatie\Sitemap\Tags\Url;
|
|
||||||
use Uwil\Laravel\Redirections\Interfaces\RedirectableInterface;
|
|
||||||
use Uwil\Laravel\Redirections\Traits\IsRedirectable;
|
|
||||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
|
||||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||||
use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
use Uwil\Seo\Laravel\Objects\SeoItem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property integer $id Id.
|
* @property integer $id Id.
|
||||||
* @property string $title Title.
|
* @property string $title Title.
|
||||||
* @property string $slug Slug of the title.
|
* @property string $slug Slug of the title.
|
||||||
* @property string $seo_title SEO Title.
|
* @property string $seo_title SEO Title.
|
||||||
* @property string $seo_description SEO description.
|
* @property string $seo_description SEO description.
|
||||||
* @property \App\Enums\Advices\AdviceTypeEnum $type Type of the advice.
|
* @property \App\Enums\Advices\AdviceTypeEnum $type Type of the advice.
|
||||||
* @property string $picture Path of a picture.
|
* @property string $picture Path of a picture.
|
||||||
* @property string $picture_alt Picture's attribute alt.
|
* @property string $picture_alt Picture's attribute alt.
|
||||||
* @property string $picture_title Picture's attribute title.
|
* @property string $picture_title Picture's attribute title.
|
||||||
* @property string $sticker Path of a sticker.
|
* @property string $sticker Path of a sticker.
|
||||||
* @property string $sticker_alt Sticker's attribute alt.
|
* @property string $sticker_alt Sticker's attribute alt.
|
||||||
* @property string $sticker_title Sticker's attribute title.
|
* @property string $sticker_title Sticker's attribute title.
|
||||||
* @property string $sticker_sm Path of a small sticker.
|
* @property string $sticker_sm Path of a small sticker.
|
||||||
* @property string $sticker_sm_alt small sticker's attribute alt.
|
* @property string $sticker_sm_alt small sticker's attribute alt.
|
||||||
* @property string $sticker_sm_title Small sticker's attribute title.
|
* @property string $sticker_sm_title Small sticker's attribute title.
|
||||||
* @property string $preparation Preparation tips.
|
* @property string $preparation Preparation tips.
|
||||||
* @property string|null $advice Advice.
|
* @property string $advice Advice.
|
||||||
* @property array<array<string,string|integer>> $ingredients Ingredients.
|
* @property \Illuminate\Support\Carbon $ingredients Ingredients.
|
||||||
* @property integer|null $guests_nb Number of guests.
|
* @property \Illuminate\Support\Carbon $guests_nb Number of guests.
|
||||||
* @property string|null $youtube_title Youtube title.
|
* @property \Illuminate\Support\Carbon $youtube_title Youtube title.
|
||||||
* @property string|null $youtube_video_id Youtube video id.
|
* @property \Illuminate\Support\Carbon $youtube_video_id Youtube video id.
|
||||||
* @property integer|null $cooking_time Time of cooking.
|
* @property \Illuminate\Support\Carbon $cooking_time Time of cooking.
|
||||||
* @property integer|null $preparation_time Time of preparation.
|
* @property \Illuminate\Support\Carbon $preparation_time Time of preparation.
|
||||||
* @property \App\Enums\Advices\AdviceDifficultyEnum|null $difficulty Difficulty.
|
* @property \App\Enums\Advices\AdviceDifficultyEnum $difficulty Difficulty.
|
||||||
* @property boolean $published Status.
|
* @property boolean $status Status.
|
||||||
* @property integer $priority_order Priority Order.
|
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
|
||||||
*
|
*
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> $recipes
|
|
||||||
* HasMany Recipes.
|
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> $tips
|
|
||||||
* HasMany Tips.
|
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> $advices
|
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> $advices
|
||||||
* Advices Belongs-To-Many relationship.
|
* Advices Belongs-To-Many relationship.
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products
|
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products
|
||||||
|
|
@ -63,12 +51,10 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Tag> $tags
|
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Tag> $tags
|
||||||
* Tags Morph-To-Many relationship.
|
* Tags Morph-To-Many relationship.
|
||||||
*/
|
*/
|
||||||
class Advice extends Authenticatable implements SeoInterface, Sitemapable, RedirectableInterface, OrderableInterface
|
class Advice extends Authenticatable implements SeoInterface
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use SeoTrait;
|
use SeoTrait;
|
||||||
use IsRedirectable;
|
|
||||||
use Orderable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
|
|
@ -99,18 +85,17 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
'cooking_time',
|
'cooking_time',
|
||||||
'preparation_time',
|
'preparation_time',
|
||||||
'difficulty',
|
'difficulty',
|
||||||
'published',
|
'status'
|
||||||
'priority_order'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that should be cast.
|
* The attributes that should be cast.
|
||||||
*
|
*
|
||||||
* @var array<string,string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'ingredients' => 'array',
|
'ingredients' => 'array',
|
||||||
'published' => 'bool',
|
'status' => 'bool',
|
||||||
'type' => AdviceTypeEnum::class,
|
'type' => AdviceTypeEnum::class,
|
||||||
'difficulty' => AdviceDifficultyEnum::class,
|
'difficulty' => AdviceDifficultyEnum::class,
|
||||||
];
|
];
|
||||||
|
|
@ -124,7 +109,6 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
{
|
{
|
||||||
static::creating(function (self $model) {
|
static::creating(function (self $model) {
|
||||||
self::manageFields($model);
|
self::manageFields($model);
|
||||||
self::bootOrderable();
|
|
||||||
});
|
});
|
||||||
static::updating(function (self $model) {
|
static::updating(function (self $model) {
|
||||||
self::manageFields($model);
|
self::manageFields($model);
|
||||||
|
|
@ -139,7 +123,6 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
FileStorageHelper::removeFile($model, 'picture');
|
FileStorageHelper::removeFile($model, 'picture');
|
||||||
FileStorageHelper::removeFile($model, 'sticker');
|
FileStorageHelper::removeFile($model, 'sticker');
|
||||||
FileStorageHelper::removeFile($model, 'sticker_sm');
|
FileStorageHelper::removeFile($model, 'sticker_sm');
|
||||||
self::setOrder($model);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -148,10 +131,10 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
/**
|
/**
|
||||||
* Common methods function.
|
* Common methods function.
|
||||||
*
|
*
|
||||||
* @param self $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private static function manageFields(self $model): void
|
private static function manageFields(Model $model): void
|
||||||
{
|
{
|
||||||
self::assertTitleIsUnique($model->title, $model->id);
|
self::assertTitleIsUnique($model->title, $model->id);
|
||||||
$model->slug = Str::slug($model->title);
|
$model->slug = Str::slug($model->title);
|
||||||
|
|
@ -213,11 +196,11 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
/**
|
/**
|
||||||
* Limit products associated.
|
* Limit products associated.
|
||||||
*
|
*
|
||||||
* @param self $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||||
*/
|
*/
|
||||||
private static function assertLimitProducts(self $model): void
|
private static function assertLimitProducts(Model $model): void
|
||||||
{
|
{
|
||||||
$nbProductsInBdd = $model->products()->count();
|
$nbProductsInBdd = $model->products()->count();
|
||||||
if ($model->type->value == AdviceTypeEnum::recipes->value()) {
|
if ($model->type->value == AdviceTypeEnum::recipes->value()) {
|
||||||
|
|
@ -238,10 +221,10 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
/**
|
/**
|
||||||
* Asserts using validation that the title is unique.
|
* Asserts using validation that the title is unique.
|
||||||
*
|
*
|
||||||
* @param self $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private static function setCookingtimePreparationtimeValues(self $model): void
|
private static function setCookingtimePreparationtimeValues(Model $model): void
|
||||||
{
|
{
|
||||||
if ($model->type->value != AdviceTypeEnum::recipes->value()) {
|
if ($model->type->value != AdviceTypeEnum::recipes->value()) {
|
||||||
$model->cooking_time = null;
|
$model->cooking_time = null;
|
||||||
|
|
@ -268,59 +251,21 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
||||||
*/
|
*/
|
||||||
public function recipesQuery(): \Illuminate\Database\Eloquent\Collection
|
public function recipes(): \Illuminate\Database\Eloquent\Collection
|
||||||
{
|
{
|
||||||
return $this->advices()->where('type', AdviceTypeEnum::recipes)->get();
|
return $this->advices()->where('type', AdviceTypeEnum::recipes)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the advice recipes
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Casts\Attribute
|
|
||||||
*/
|
|
||||||
protected function recipes(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn() => $this->recipesQuery(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get associated tips
|
* Get associated tips
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
||||||
*/
|
*/
|
||||||
public function tipsQuery(): \Illuminate\Database\Eloquent\Collection
|
public function tips(): \Illuminate\Database\Eloquent\Collection
|
||||||
{
|
{
|
||||||
return $this->advices()->where('type', AdviceTypeEnum::tips)->get();
|
return $this->advices()->where('type', AdviceTypeEnum::tips)->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the advice tips
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Casts\Attribute
|
|
||||||
*/
|
|
||||||
protected function tips(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn() => $this->tipsQuery(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// * REDIRECTIONS.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the front url of this model.
|
|
||||||
* Should return the model.show route, with all binded elements if needed.
|
|
||||||
*
|
|
||||||
* @param string $modelKey
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getFrontUrl(string $modelKey): string
|
|
||||||
{
|
|
||||||
return route('fo.tips.show', $modelKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// * RELATIONSHIPS
|
// * RELATIONSHIPS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -356,7 +301,7 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
/**
|
/**
|
||||||
* Transfotrm to seoModel
|
* Transfotrm to seoModel
|
||||||
*
|
*
|
||||||
* @return \Uwil\Seo\Laravel\Objects\SeoItem
|
* @return \App\Objects\SeoItem
|
||||||
*/
|
*/
|
||||||
public function toSeoItem(): SeoItem
|
public function toSeoItem(): SeoItem
|
||||||
{
|
{
|
||||||
|
|
@ -364,33 +309,9 @@ class Advice extends Authenticatable implements SeoInterface, Sitemapable, Redir
|
||||||
\trans($this->getTable()),
|
\trans($this->getTable()),
|
||||||
$this->seo_title,
|
$this->seo_title,
|
||||||
$this->seo_description,
|
$this->seo_description,
|
||||||
$this->published ?? false,
|
$this->status ?? false,
|
||||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
||||||
$this->type === AdviceTypeEnum::recipes ? route('fo.recipes.show', $this) : route('fo.tips.show', $this)
|
$this->type === AdviceTypeEnum::recipes ? route('fo.recipes.show', $this) : route('fo.tips.show', $this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* toSitemapTag method
|
|
||||||
*
|
|
||||||
* @return Url|string|array
|
|
||||||
*/
|
|
||||||
public function toSitemapTag(): Url | string | array
|
|
||||||
{
|
|
||||||
$model = $this;
|
|
||||||
$route = $this->type === AdviceTypeEnum::tips ? 'fo.tips.show' : 'fo.recipes.show';
|
|
||||||
$params = ['publishedAdvice' => $model];
|
|
||||||
return SitemapHelper::generateUrl($route, $params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Group ordering by type.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getOrderGroupField(): string
|
|
||||||
{
|
|
||||||
return 'type';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,124 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Lib\Helpers\FileStorageHelper;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Validation\ValidationException;
|
|
||||||
use Uwil\Laravel\Common\Helpers\ToolboxHelper;
|
|
||||||
|
|
||||||
class BrigadeSection extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The attributes that are mass assignable.
|
|
||||||
*
|
|
||||||
* @var array<int, string>
|
|
||||||
*/
|
|
||||||
protected $fillable = [
|
|
||||||
'title',
|
|
||||||
'content',
|
|
||||||
'picture',
|
|
||||||
'picture_alt',
|
|
||||||
'picture_title',
|
|
||||||
'button_display',
|
|
||||||
'button_text',
|
|
||||||
'button_url',
|
|
||||||
'button_newtab',
|
|
||||||
'published',
|
|
||||||
'order'
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The attributes that should be cast.
|
|
||||||
*
|
|
||||||
* @var array<string,string>
|
|
||||||
*/
|
|
||||||
protected $casts = [
|
|
||||||
'button_display' => 'bool',
|
|
||||||
'button_newtab' => 'bool',
|
|
||||||
'published' => 'bool',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any actions required after the model boots.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected static function booted(): void
|
|
||||||
{
|
|
||||||
static::creating(function (self $model) {
|
|
||||||
self::setOrder($model);
|
|
||||||
self::manageFields($model);
|
|
||||||
});
|
|
||||||
static::updating(function (self $model) {
|
|
||||||
self::manageFields($model);
|
|
||||||
});
|
|
||||||
static::updated(function (self $model) {
|
|
||||||
FileStorageHelper::removeOldFile($model, 'picture');
|
|
||||||
});
|
|
||||||
static::updating(function (self $model) {
|
|
||||||
self::manageFields($model);
|
|
||||||
});
|
|
||||||
static::deleting(function (self $model) {
|
|
||||||
self::assertLimitPublishedSections($model, true);
|
|
||||||
});
|
|
||||||
static::deleted(function (self $model) {
|
|
||||||
FileStorageHelper::removeFile($model, 'picture');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// * METHODS
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common methods function.
|
|
||||||
*
|
|
||||||
* @param self $model
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private static function manageFields(self $model): void
|
|
||||||
{
|
|
||||||
self::assertLimitPublishedSections($model);
|
|
||||||
|
|
||||||
ToolboxHelper::assertNoInternalBoUrls('content', $model->content);
|
|
||||||
ToolboxHelper::assertNoInternalBoUrls('button_url', $model->content);
|
|
||||||
|
|
||||||
$model->content = clean($model->content);
|
|
||||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set order after the last element of the list.
|
|
||||||
*
|
|
||||||
* @param self $model
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
private static function setOrder(self $model): void
|
|
||||||
{
|
|
||||||
$model->order = \intval(self::query()->max('order')) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the limit of published element is reached.
|
|
||||||
*
|
|
||||||
* @param self $model
|
|
||||||
* @param boolean $isDeletion
|
|
||||||
* @return void
|
|
||||||
* @throws \Illuminate\Validation\ValidationException Returns if fails.
|
|
||||||
*/
|
|
||||||
private static function assertLimitPublishedSections(self $model, bool $isDeletion = false)
|
|
||||||
{
|
|
||||||
$count = self::query()->where('published', true)->count();
|
|
||||||
if (
|
|
||||||
(!$model->published && $count <= 1) ||
|
|
||||||
($model->published && $count >= 5) ||
|
|
||||||
($isDeletion && $count === 1)
|
|
||||||
) {
|
|
||||||
throw ValidationException::withMessages([
|
|
||||||
'Il doit y avoir entre 1 et 5 sections publiées simultanément.'
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -30,7 +30,7 @@ class ExpertiseProduct extends Model
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'page',
|
'page',
|
||||||
|
|
@ -46,7 +46,7 @@ class ExpertiseProduct extends Model
|
||||||
/**
|
/**
|
||||||
* The attributes that should be cast.
|
* The attributes that should be cast.
|
||||||
*
|
*
|
||||||
* @var array<string,string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'points' => 'array',
|
'points' => 'array',
|
||||||
|
|
@ -84,10 +84,10 @@ class ExpertiseProduct extends Model
|
||||||
/**
|
/**
|
||||||
* Common methods function.
|
* Common methods function.
|
||||||
*
|
*
|
||||||
* @param self $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private static function manageFields(self $model): void
|
private static function manageFields(Model $model): void
|
||||||
{
|
{
|
||||||
self::assertFieldIsUnique('label', $model->label, $model->id);
|
self::assertFieldIsUnique('label', $model->label, $model->id);
|
||||||
self::assertFieldIsUnique('title', $model->title, $model->id);
|
self::assertFieldIsUnique('title', $model->title, $model->id);
|
||||||
|
|
|
||||||
|
|
@ -2,22 +2,15 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Spatie\Sitemap\Tags\Url;
|
|
||||||
use Spatie\CalendarLinks\Link;
|
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
|
||||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
|
||||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
|
||||||
use App\Lib\Helpers\FileStorageHelper;
|
use App\Lib\Helpers\FileStorageHelper;
|
||||||
use Spatie\Sitemap\Contracts\Sitemapable;
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
|
||||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
|
||||||
use Illuminate\Validation\ValidationException;
|
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
||||||
use Uwil\Laravel\Redirections\Traits\IsRedirectable;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Uwil\Laravel\Redirections\Interfaces\RedirectableInterface;
|
use Illuminate\Support\Str;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||||
|
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
|
@ -31,21 +24,19 @@ use Uwil\Laravel\Redirections\Interfaces\RedirectableInterface;
|
||||||
* @property string $picture Path of a picture.
|
* @property string $picture Path of a picture.
|
||||||
* @property string $picture_alt Picture's attribute alt.
|
* @property string $picture_alt Picture's attribute alt.
|
||||||
* @property string $picture_title Picture's attribute title.
|
* @property string $picture_title Picture's attribute title.
|
||||||
* @property string|null $picture2 Path of a second picture.
|
* @property string $picture2 Path of a second picture.
|
||||||
* @property string|null $picture2_alt Second picture's attribute alt.
|
* @property string $picture2_alt Second picture's attribute alt.
|
||||||
* @property string|null $picture2_title Second picture's attribute title.
|
* @property string $picture2_title Second picture's attribute title.
|
||||||
* @property string $content First WYSWYG content.
|
* @property string $content First WYSWYG content.
|
||||||
* @property string|null $content2 Second WYSWYG content.
|
* @property string $content2 Second WYSWYG content.
|
||||||
* @property \Illuminate\Support\Carbon|null $event_start Start of the event.
|
* @property \Illuminate\Support\Carbon $event_start Start of the event.
|
||||||
* @property \Illuminate\Support\Carbon|null $event_end End of the event.
|
* @property \Illuminate\Support\Carbon $event_end End of the event.
|
||||||
* @property string|null $event_text Text of the event.
|
* @property string $event_text Text of the event.
|
||||||
* @property boolean $published Status.
|
* @property boolean $status Status.
|
||||||
* @property-read string $reading_time Time reading of a news' page
|
* @property-read string $reading_time Time reading of a news' page
|
||||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||||
*
|
*
|
||||||
* @property-read \Spatie\CalendarLinks\Link|null $cal_link
|
|
||||||
*
|
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\News> $news
|
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\News> $news
|
||||||
* News Belongs-To-Many relationship.
|
* News Belongs-To-Many relationship.
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products
|
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products
|
||||||
|
|
@ -53,16 +44,15 @@ use Uwil\Laravel\Redirections\Interfaces\RedirectableInterface;
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Tags> $categories
|
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Tags> $categories
|
||||||
* Categories Morph-To-Many relationship.
|
* Categories Morph-To-Many relationship.
|
||||||
*/
|
*/
|
||||||
class News extends Authenticatable implements SeoInterface, Sitemapable, RedirectableInterface
|
class News extends Authenticatable implements SeoInterface
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use SeoTrait;
|
use SeoTrait;
|
||||||
use IsRedirectable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int,string>
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'title',
|
'title',
|
||||||
|
|
@ -81,18 +71,18 @@ class News extends Authenticatable implements SeoInterface, Sitemapable, Redirec
|
||||||
'event_start',
|
'event_start',
|
||||||
'event_end',
|
'event_end',
|
||||||
'event_text',
|
'event_text',
|
||||||
'published',
|
'status',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that should be cast.
|
* The attributes that should be cast.
|
||||||
*
|
*
|
||||||
* @var array<string,string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'event_start' => 'datetime',
|
'event_start' => 'datetime',
|
||||||
'event_end' => 'datetime',
|
'event_end' => 'datetime',
|
||||||
'published' => 'bool',
|
'status' => 'bool',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -121,36 +111,15 @@ class News extends Authenticatable implements SeoInterface, Sitemapable, Redirec
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// * ATTRIBUTES
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get cal_link attribute
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Casts\Attribute
|
|
||||||
*/
|
|
||||||
public function calLink(): Attribute
|
|
||||||
{
|
|
||||||
return Attribute::make(
|
|
||||||
get: fn() => (
|
|
||||||
$this->exists() and
|
|
||||||
($this->event_start && $this->event_end && $this->event_text)
|
|
||||||
) ? Link::create(
|
|
||||||
$this->title,
|
|
||||||
$this->event_start,
|
|
||||||
$this->event_end
|
|
||||||
)->description($this->event_text)->ics() : null
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// * METHODS
|
// * METHODS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common methods function.
|
* Common methods function.
|
||||||
*
|
*
|
||||||
* @param self $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private static function manageFields(self $model): void
|
private static function manageFields(Model $model): void
|
||||||
{
|
{
|
||||||
self::assertTitleIsUnique($model->title, $model->id);
|
self::assertTitleIsUnique($model->title, $model->id);
|
||||||
$model->slug = Str::slug($model->title);
|
$model->slug = Str::slug($model->title);
|
||||||
|
|
@ -183,7 +152,6 @@ class News extends Authenticatable implements SeoInterface, Sitemapable, Redirec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limit news associated.
|
* Limit news associated.
|
||||||
*
|
|
||||||
* @param integer $nbNewsInBdd
|
* @param integer $nbNewsInBdd
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||||
|
|
@ -199,7 +167,6 @@ class News extends Authenticatable implements SeoInterface, Sitemapable, Redirec
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limit news categories associated.
|
* Limit news categories associated.
|
||||||
*
|
|
||||||
* @param integer $nbNewsCategoriesInBdd
|
* @param integer $nbNewsCategoriesInBdd
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||||
|
|
@ -249,31 +216,15 @@ class News extends Authenticatable implements SeoInterface, Sitemapable, Redirec
|
||||||
return ($time < 1) ? round(($allWords / 140) * 60, 0) . " seconde(s)" : $time . " minute(s)";
|
return ($time < 1) ? round(($allWords / 140) * 60, 0) . " seconde(s)" : $time . " minute(s)";
|
||||||
}
|
}
|
||||||
|
|
||||||
// * REDIRECTIONS.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the front url of this model.
|
|
||||||
* Should return the model.show route, with all binded elements if needed.
|
|
||||||
*
|
|
||||||
* @param string $modelKey
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getFrontUrl(string $modelKey): string
|
|
||||||
{
|
|
||||||
return route('fo.news.show', $modelKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// * RELATIONSHIPS
|
// * RELATIONSHIPS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* News Morph-To-Many relationship.
|
* News Morph-To-Many relationship.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||||
* @phpcs:disable Generic.NamingConventions.ConstructorName.OldStyle
|
|
||||||
*/
|
*/
|
||||||
public function news(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
public function news(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||||
{
|
{
|
||||||
// phpcs:enable
|
|
||||||
return $this->belongsToMany(News::class, 'news_news', 'news_id', 'news_related_id');
|
return $this->belongsToMany(News::class, 'news_news', 'news_id', 'news_related_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -296,34 +247,4 @@ class News extends Authenticatable implements SeoInterface, Sitemapable, Redirec
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(NewsCategory::class);
|
return $this->belongsToMany(NewsCategory::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* toSitemapTag method
|
|
||||||
*
|
|
||||||
* @return Url|string|array
|
|
||||||
*/
|
|
||||||
public function toSitemapTag(): Url | string | array
|
|
||||||
{
|
|
||||||
$model = $this;
|
|
||||||
$route = 'fo.news.show';
|
|
||||||
$params = ['actu' => $model];
|
|
||||||
return SitemapHelper::generateUrl($route, $params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform to seoModel
|
|
||||||
*
|
|
||||||
* @return \Uwil\Seo\Laravel\Objects\SeoItem
|
|
||||||
*/
|
|
||||||
public function toSeoItem(): SeoItem
|
|
||||||
{
|
|
||||||
return new SeoItem(
|
|
||||||
\trans($this->getTable()),
|
|
||||||
$this->seo_title,
|
|
||||||
$this->seo_description,
|
|
||||||
$this->published ?? false,
|
|
||||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
|
||||||
route('fo.news.show', $this)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ class NewsCategory extends Authenticatable
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int,string>
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'label',
|
'label',
|
||||||
|
|
|
||||||
|
|
@ -2,24 +2,16 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Interfaces\OrderableInterface;
|
|
||||||
use App\Enums\Advices\AdviceTypeEnum;
|
use App\Enums\Advices\AdviceTypeEnum;
|
||||||
use App\Enums\NutriscoreEnum;
|
use App\Enums\NutriscoreEnum;
|
||||||
use App\Enums\Products\ProductSpeciesEnum;
|
use App\Enums\Products\ProductSpeciesEnum;
|
||||||
use App\Lib\Helpers\FileStorageHelper;
|
use App\Lib\Helpers\FileStorageHelper;
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
use App\Traits\Models\Orderable;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Spatie\Sitemap\Contracts\Sitemapable;
|
|
||||||
use Spatie\Sitemap\Tags\Url;
|
|
||||||
use Uwil\Laravel\Redirections\Interfaces\RedirectableInterface;
|
|
||||||
use Uwil\Laravel\Redirections\Traits\IsRedirectable;
|
|
||||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
|
||||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||||
use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property integer $id Id.
|
* @property integer $id Id.
|
||||||
|
|
@ -33,18 +25,17 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
||||||
* @property string $sticker_sm Path of a small sticker.
|
* @property string $sticker_sm Path of a small sticker.
|
||||||
* @property string $sticker_sm_alt small sticker's attribute alt.
|
* @property string $sticker_sm_alt small sticker's attribute alt.
|
||||||
* @property string $sticker_sm_title Small sticker's attribute title.
|
* @property string $sticker_sm_title Small sticker's attribute title.
|
||||||
* @property array<string> $slider_pictures Array of paths of pictures.
|
* @property string $slider_pictures Array of paths of pictures.
|
||||||
* @property array<array<string,string>> $packaging Packaging.
|
* @property string $packaging Packaging.
|
||||||
* @property array<array<string,string>> $caliber Caliber.
|
* @property \Illuminate\Support\Carbon $caliber Caliber.
|
||||||
* @property string $ingredients Ingredients.
|
* @property \Illuminate\Support\Carbon $nutritionnal_values Nutritionnal values.
|
||||||
* @property string $advantage Advantage.
|
* @property \Illuminate\Support\Carbon $ingredients Ingredients.
|
||||||
* @property string $preparation Preparation.
|
* @property \Illuminate\Support\Carbon $advantage Advantage.
|
||||||
* @property boolean $is_frenchpoultry Is frenchpoultry or not.
|
* @property \Illuminate\Support\Carbon $preparation Preparation.
|
||||||
* @property boolean $is_vip Is vip or not.
|
* @property \Illuminate\Support\Carbon $is_frenchpoultry Is frenchpoultry or not.
|
||||||
* @property boolean $is_egalim Is egalim or not.
|
* @property \App\Enums\Advices\AdviceDifficultyEnum $is_vip Is vip or not.
|
||||||
* @property boolean $published Status.
|
* @property \App\Enums\Advices\AdviceDifficultyEnum $is_egalim Is egalim or not.
|
||||||
* @property integer $order Order.
|
* @property boolean $status Status.
|
||||||
* @property integer $priority_order Priority Order.
|
|
||||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||||
*
|
*
|
||||||
|
|
@ -54,17 +45,15 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\News> $news
|
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\News> $news
|
||||||
* News Belongs-To-Many relation.
|
* News Belongs-To-Many relation.
|
||||||
*/
|
*/
|
||||||
class Product extends Model implements SeoInterface, Sitemapable, RedirectableInterface, OrderableInterface
|
class Product extends Model implements SeoInterface
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use SeoTrait;
|
use SeoTrait;
|
||||||
use IsRedirectable;
|
|
||||||
use Orderable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'label',
|
'label',
|
||||||
|
|
@ -83,28 +72,29 @@ class Product extends Model implements SeoInterface, Sitemapable, RedirectableIn
|
||||||
'slider_pictures',
|
'slider_pictures',
|
||||||
'packaging',
|
'packaging',
|
||||||
'caliber',
|
'caliber',
|
||||||
|
'nutritionnal_values',
|
||||||
'is_frenchpoultry',
|
'is_frenchpoultry',
|
||||||
'is_vip',
|
'is_vip',
|
||||||
'is_egalim',
|
'is_egalim',
|
||||||
'published',
|
'status'
|
||||||
'priority_order',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that should be cast.
|
* The attributes that should be cast.
|
||||||
*
|
*
|
||||||
* @var array<string,string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'slider_pictures' => 'array',
|
'slider_pictures' => 'array',
|
||||||
'packaging' => 'array',
|
'packaging' => 'array',
|
||||||
'caliber' => 'array',
|
'caliber' => 'array',
|
||||||
'is_frenchpoultry' => 'bool',
|
'nutritionnal_values' => 'array',
|
||||||
'is_vip' => 'bool',
|
'is_frenchpoultry' => 'bool',
|
||||||
'is_egalim' => 'bool',
|
'is_vip' => 'bool',
|
||||||
'published' => 'bool',
|
'is_egalim' => 'bool',
|
||||||
'species' => ProductSpeciesEnum::class,
|
'status' => 'bool',
|
||||||
'nutriscore' => NutriscoreEnum::class
|
'species' => ProductSpeciesEnum::class,
|
||||||
|
'nutriscore' => NutriscoreEnum::class
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -117,25 +107,16 @@ class Product extends Model implements SeoInterface, Sitemapable, RedirectableIn
|
||||||
// * EVENT CLOSURES.
|
// * EVENT CLOSURES.
|
||||||
static::creating(function (self $model) {
|
static::creating(function (self $model) {
|
||||||
self::manageFields($model);
|
self::manageFields($model);
|
||||||
self::bootOrderable();
|
$model->order = \intval(self::query()->max('order')) + 1;
|
||||||
});
|
});
|
||||||
static::updating(function (self $model) {
|
static::updating(function (self $model) {
|
||||||
self::manageFields($model);
|
self::manageFields($model);
|
||||||
});
|
});
|
||||||
static::updated(function (self $model) {
|
static::updated(function (self $model) {
|
||||||
FileStorageHelper::removeOldFile($model, 'sticker_sm');
|
FileStorageHelper::removeOldFile($model, 'sticker_sm');
|
||||||
FileStorageHelper::removeOldFiles(
|
|
||||||
!is_array($model->getOriginal('slider_pictures')) ? [] : $model->getOriginal('slider_pictures'),
|
|
||||||
$model->slider_pictures
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
static::deleted(function (self $model) {
|
static::deleted(function (self $model) {
|
||||||
FileStorageHelper::removeFile($model, 'sticker_sm');
|
FileStorageHelper::removeFile($model, 'sticker_sm');
|
||||||
FileStorageHelper::removeFiles(
|
|
||||||
$model,
|
|
||||||
!is_array($model->getOriginal('slider_pictures')) ? [] : $model->getOriginal('slider_pictures'),
|
|
||||||
);
|
|
||||||
self::setOrder($model);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,13 +125,13 @@ class Product extends Model implements SeoInterface, Sitemapable, RedirectableIn
|
||||||
/**
|
/**
|
||||||
* Common methods function.
|
* Common methods function.
|
||||||
*
|
*
|
||||||
* @param self $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private static function manageFields(self $model): void
|
private static function manageFields(Model $model): void
|
||||||
{
|
{
|
||||||
// * ASSERTIONS
|
// * ASSERTIONS
|
||||||
self::assertLabelIsUnique($model->label, $model->id);
|
static::assertLabelIsUnique($model->label, $model->id);
|
||||||
ToolboxHelper::assertNoInternalBoUrls('ingredients', $model->ingredients);
|
ToolboxHelper::assertNoInternalBoUrls('ingredients', $model->ingredients);
|
||||||
ToolboxHelper::assertNoInternalBoUrls('advantage', $model->advantage);
|
ToolboxHelper::assertNoInternalBoUrls('advantage', $model->advantage);
|
||||||
ToolboxHelper::assertNoInternalBoUrls('preparation', $model->preparation);
|
ToolboxHelper::assertNoInternalBoUrls('preparation', $model->preparation);
|
||||||
|
|
@ -160,16 +141,22 @@ class Product extends Model implements SeoInterface, Sitemapable, RedirectableIn
|
||||||
foreach ($model->caliber as $calib) {
|
foreach ($model->caliber as $calib) {
|
||||||
ToolboxHelper::assertNoInternalBoUrls('caliber', $calib['value']);
|
ToolboxHelper::assertNoInternalBoUrls('caliber', $calib['value']);
|
||||||
}
|
}
|
||||||
|
foreach ($model->nutritionnal_values as $nutritionnal_value) {
|
||||||
|
if ($model->nutritionnal_value) {
|
||||||
|
ToolboxHelper::assertNoInternalBoUrls('nutritionnal_values', $nutritionnal_value['value']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// * TRANSFORMATIONS
|
// * TRANSFORMATIONS
|
||||||
$model->slug = Str::slug($model->label);
|
$model->slug = Str::slug($model->label);
|
||||||
$model->sticker_sm = FileStorageHelper::storeFile($model, $model->sticker_sm, true);
|
$model->sticker_sm = FileStorageHelper::storeFile($model, $model->sticker_sm, true);
|
||||||
$model->ingredients = clean($model->ingredients);
|
$model->ingredients = clean($model->ingredients);
|
||||||
$model->advantage = clean($model->advantage);
|
$model->advantage = clean($model->advantage);
|
||||||
$model->preparation = clean($model->preparation);
|
$model->preparation = clean($model->preparation);
|
||||||
$model->slider_pictures = clean($model->slider_pictures);
|
$model->slider_pictures = clean($model->slider_pictures);
|
||||||
$model->packaging = clean($model->packaging);
|
$model->packaging = clean($model->packaging);
|
||||||
$model->caliber = clean($model->caliber);
|
$model->caliber = clean($model->caliber);
|
||||||
|
$model->nutritionnal_values = clean($model->nutritionnal_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -209,47 +196,31 @@ class Product extends Model implements SeoInterface, Sitemapable, RedirectableIn
|
||||||
/**
|
/**
|
||||||
* Get associated tips.
|
* Get associated tips.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Collection<int,\App\Models\Advice>
|
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
||||||
*/
|
*/
|
||||||
public function tips(): \Illuminate\Database\Eloquent\Collection
|
public function tips(): \Illuminate\Database\Eloquent\Collection
|
||||||
{
|
{
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
return $this->tipsQuery()->get();
|
return $this->tipsQuery()->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get associated recipes.
|
* Get associated recipes.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Collection<int,\App\Models\Advice>
|
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
||||||
*/
|
*/
|
||||||
public function recipes(): \Illuminate\Database\Eloquent\Collection
|
public function recipes(): \Illuminate\Database\Eloquent\Collection
|
||||||
{
|
{
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
return $this->recipesQuery()->get();
|
return $this->recipesQuery()->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// * REDIRECTIONS.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the front url of this model.
|
|
||||||
* Should return the model.show route, with all binded elements if needed.
|
|
||||||
*
|
|
||||||
* @param string $modelKey
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getFrontUrl(string $modelKey): string
|
|
||||||
{
|
|
||||||
return route('fo.product.show', $modelKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// * RELATIONSHIPS
|
// * RELATIONSHIPS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subrange Has-One relation.
|
* Subrange Has-One relation.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
* @return \Illuminate\Database\Eloquent\Relations\belongsTo
|
||||||
*/
|
*/
|
||||||
public function subrange(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
public function subrange(): \Illuminate\Database\Eloquent\Relations\belongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Subrange::class);
|
return $this->belongsTo(Subrange::class);
|
||||||
}
|
}
|
||||||
|
|
@ -273,44 +244,4 @@ class Product extends Model implements SeoInterface, Sitemapable, RedirectableIn
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(News::class);
|
return $this->belongsToMany(News::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Tags Morph-To-Many relationship.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
|
|
||||||
*/
|
|
||||||
public function tags(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
|
||||||
{
|
|
||||||
return $this->morphToMany(Tag::class, 'taggable');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* toSitemapTag method
|
|
||||||
*
|
|
||||||
* @return Url|string|array
|
|
||||||
*/
|
|
||||||
public function toSitemapTag(): Url | string | array
|
|
||||||
{
|
|
||||||
$model = $this;
|
|
||||||
$route = 'fo.product.show';
|
|
||||||
$params = ['publishedProduct' => $model];
|
|
||||||
return SitemapHelper::generateUrl($route, $params, $model);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform to seoModel
|
|
||||||
*
|
|
||||||
* @return \Uwil\Seo\Laravel\Objects\SeoItem
|
|
||||||
*/
|
|
||||||
public function toSeoItem(): SeoItem
|
|
||||||
{
|
|
||||||
return new SeoItem(
|
|
||||||
\trans($this->getTable()),
|
|
||||||
$this->seo_title,
|
|
||||||
$this->seo_description,
|
|
||||||
$this->published ?? false,
|
|
||||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
|
||||||
route('fo.product.show', $this)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,6 @@ use Illuminate\Support\Str;
|
||||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
use Uwil\Seo\Laravel\Objects\SeoItem;
|
||||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||||
use Spatie\Sitemap\Contracts\Sitemapable;
|
|
||||||
use Spatie\Sitemap\Tags\Url;
|
|
||||||
use Uwil\Laravel\Redirections\Interfaces\RedirectableInterface;
|
|
||||||
use Uwil\Laravel\Redirections\Traits\IsRedirectable;
|
|
||||||
use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property integer $id Id.
|
* @property integer $id Id.
|
||||||
|
|
@ -37,16 +32,15 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
||||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Subrange> $subranges
|
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Subrange> $subranges
|
||||||
* Subranges Has-Many relationship.
|
* Subranges Has-Many relationship.
|
||||||
*/
|
*/
|
||||||
class Range extends Model implements SeoInterface, Sitemapable, RedirectableInterface
|
class Range extends Model implements SeoInterface
|
||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
use SeoTrait;
|
use SeoTrait;
|
||||||
use IsRedirectable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'label',
|
'label',
|
||||||
|
|
@ -66,7 +60,7 @@ class Range extends Model implements SeoInterface, Sitemapable, RedirectableInte
|
||||||
/**
|
/**
|
||||||
* The attributes that should be cast.
|
* The attributes that should be cast.
|
||||||
*
|
*
|
||||||
* @var array<string,string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'color' => RgbaColor::class,
|
'color' => RgbaColor::class,
|
||||||
|
|
@ -83,14 +77,14 @@ class Range extends Model implements SeoInterface, Sitemapable, RedirectableInte
|
||||||
throw new \RuntimeException('Impossible de créer un range');
|
throw new \RuntimeException('Impossible de créer un range');
|
||||||
});
|
});
|
||||||
static::updating(function (self $model) {
|
static::updating(function (self $model) {
|
||||||
self::assertLabelIsUnique($model->label, $model->id);
|
static::assertLabelIsUnique($model->label, $model->id);
|
||||||
$model->slug = Str::slug($model->label);
|
$model->slug = Str::slug($model->label);
|
||||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||||
$model->picture_banner = FileStorageHelper::storeFile($model, $model->picture_banner, true);
|
$model->picture_banner = FileStorageHelper::storeFile($model, $model->picture_banner, true);
|
||||||
});
|
});
|
||||||
static::updated(function (self $model) {
|
static::updated(function (self $model) {
|
||||||
FileStorageHelper::removeOldFile($model, 'picture');
|
$model->picture = FileStorageHelper::removeOldFile($model, 'picture');
|
||||||
FileStorageHelper::removeOldFile($model, 'picture_banner');
|
$model->picture_banner = FileStorageHelper::removeOldFile($model, 'picture_banner');
|
||||||
});
|
});
|
||||||
static::deleting(function () {
|
static::deleting(function () {
|
||||||
throw new \RuntimeException('Impossible de supprimer un range');
|
throw new \RuntimeException('Impossible de supprimer un range');
|
||||||
|
|
@ -114,38 +108,14 @@ class Range extends Model implements SeoInterface, Sitemapable, RedirectableInte
|
||||||
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($label), $id);
|
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($label), $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// * REDIRECTIONS.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* All models that belongs to it.
|
|
||||||
*
|
|
||||||
* @return array<string>
|
|
||||||
*/
|
|
||||||
protected function getRouteChildrenModels(): array
|
|
||||||
{
|
|
||||||
return ['App\Models\Subrange'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the front url of this model.
|
|
||||||
* Should return the model.show route, with all binded elements if needed.
|
|
||||||
*
|
|
||||||
* @param string $modelKey
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getFrontUrl(string $modelKey): string
|
|
||||||
{
|
|
||||||
return route('fo.products.range-products', $modelKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// * RELATIONSHIPS
|
// * RELATIONSHIPS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subranges Has-Many relationship.
|
* Subranges Has-Many relationship.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
* @return \Illuminate\Database\Eloquent\Relations\hasMany
|
||||||
*/
|
*/
|
||||||
public function subranges(): \Illuminate\Database\Eloquent\Relations\HasMany
|
public function subranges(): \Illuminate\Database\Eloquent\Relations\hasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Subrange::class);
|
return $this->hasMany(Subrange::class);
|
||||||
}
|
}
|
||||||
|
|
@ -153,9 +123,9 @@ class Range extends Model implements SeoInterface, Sitemapable, RedirectableInte
|
||||||
// * SEO
|
// * SEO
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform to seoModel
|
* Transfotrm to seoModel
|
||||||
*
|
*
|
||||||
* @return \Uwil\Seo\Laravel\Objects\SeoItem
|
* @return \App\Objects\SeoItem
|
||||||
*/
|
*/
|
||||||
public function toSeoItem(): SeoItem
|
public function toSeoItem(): SeoItem
|
||||||
{
|
{
|
||||||
|
|
@ -168,17 +138,4 @@ class Range extends Model implements SeoInterface, Sitemapable, RedirectableInte
|
||||||
\route('fo.products.range-products', $this)
|
\route('fo.products.range-products', $this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* toSitemapTag method
|
|
||||||
*
|
|
||||||
* @return Url|string|array
|
|
||||||
*/
|
|
||||||
public function toSitemapTag(): Url | string | array
|
|
||||||
{
|
|
||||||
$model = $this;
|
|
||||||
$route = 'fo.products.range-products';
|
|
||||||
$params = ['range' => $model];
|
|
||||||
return SitemapHelper::generateUrl($route, $params, $model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@ use Illuminate\Validation\ValidationException;
|
||||||
/**
|
/**
|
||||||
* @property integer $id Id.
|
* @property integer $id Id.
|
||||||
* @property string $title Title.
|
* @property string $title Title.
|
||||||
* @property string $content WYSWYG content.
|
* @property integer $content WYSWYG content.
|
||||||
* @property boolean $button_display Display the button.
|
* @property boolean $button_display Display the button.
|
||||||
* @property string|null $button_text Title of the button.
|
* @property string $button_text Title of the button.
|
||||||
* @property string|null $button_url Link of the button.
|
* @property string $button_url Link of the button.
|
||||||
* @property boolean|null $button_targetblank Open in new window.
|
* @property boolean $button_targetblank Open in new window.
|
||||||
* @property string $picture Path of a picture.
|
* @property string $picture Path of a picture.
|
||||||
* @property string $picture_alt Picture's attribute alt.
|
* @property string $picture_alt Picture's attribute alt.
|
||||||
* @property string $picture_title Picture's attribute title.
|
* @property string $picture_title Picture's attribute title.
|
||||||
|
|
@ -23,7 +23,6 @@ use Illuminate\Validation\ValidationException;
|
||||||
* @property string $picture_thumbnail_alt Thumbnail picture's attribute alt.
|
* @property string $picture_thumbnail_alt Thumbnail picture's attribute alt.
|
||||||
* @property string $picture_thumbnail_title Thumbnail picture's attribute title.
|
* @property string $picture_thumbnail_title Thumbnail picture's attribute title.
|
||||||
* @property integer $order Order.
|
* @property integer $order Order.
|
||||||
* @property boolean $published Is the slide published ?
|
|
||||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||||
*/
|
*/
|
||||||
|
|
@ -34,7 +33,7 @@ class Slide extends Model
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'title',
|
'title',
|
||||||
|
|
@ -49,19 +48,17 @@ class Slide extends Model
|
||||||
'picture_thumbnail',
|
'picture_thumbnail',
|
||||||
'picture_thumbnail_alt',
|
'picture_thumbnail_alt',
|
||||||
'picture_thumbnail_title',
|
'picture_thumbnail_title',
|
||||||
'order',
|
'order'
|
||||||
'published'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that should be cast.
|
* The attributes that should be cast.
|
||||||
*
|
*
|
||||||
* @var array<string,string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'button_display' => 'bool',
|
'button_display' => 'bool',
|
||||||
'button_targetblank' => 'bool',
|
'button_targetblank' => 'bool'
|
||||||
'published' => 'bool'
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -72,6 +69,9 @@ class Slide extends Model
|
||||||
protected static function booted(): void
|
protected static function booted(): void
|
||||||
{
|
{
|
||||||
static::creating(function (self $model) {
|
static::creating(function (self $model) {
|
||||||
|
if (count(self::get()) >= 4) {
|
||||||
|
self::assertNumberOfSlides();
|
||||||
|
}
|
||||||
self::manageFields($model);
|
self::manageFields($model);
|
||||||
$model->order = \intval(self::query()->max('order')) + 1;
|
$model->order = \intval(self::query()->max('order')) + 1;
|
||||||
});
|
});
|
||||||
|
|
@ -82,8 +82,10 @@ class Slide extends Model
|
||||||
FileStorageHelper::removeOldFile($model, 'picture');
|
FileStorageHelper::removeOldFile($model, 'picture');
|
||||||
FileStorageHelper::removeOldFile($model, 'picture_thumbnail');
|
FileStorageHelper::removeOldFile($model, 'picture_thumbnail');
|
||||||
});
|
});
|
||||||
static::deleting(function (self $model) {
|
static::deleting(function () {
|
||||||
self::assertNumberOfSlides($model, true);
|
if (1 >= count(self::get())) {
|
||||||
|
self::assertNumberOfSlides();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
static::deleted(function (self $model) {
|
static::deleted(function (self $model) {
|
||||||
FileStorageHelper::removeFile($model, 'picture');
|
FileStorageHelper::removeFile($model, 'picture');
|
||||||
|
|
@ -96,13 +98,12 @@ class Slide extends Model
|
||||||
/**
|
/**
|
||||||
* Common methods function.
|
* Common methods function.
|
||||||
*
|
*
|
||||||
* @param self $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private static function manageFields(self $model): void
|
private static function manageFields(Model $model): void
|
||||||
{
|
{
|
||||||
self::assertTitleIsUnique($model->title, $model->id);
|
self::assertTitleIsUnique($model->title, $model->id);
|
||||||
self::assertNumberOfSlides($model);
|
|
||||||
ToolboxHelper::assertNoInternalBoUrls($model->content, 'content');
|
ToolboxHelper::assertNoInternalBoUrls($model->content, 'content');
|
||||||
$model->content = clean($model->content);
|
$model->content = clean($model->content);
|
||||||
if ($model->button_url) {
|
if ($model->button_url) {
|
||||||
|
|
@ -116,31 +117,14 @@ class Slide extends Model
|
||||||
/**
|
/**
|
||||||
* Asserts the number of slides in the slider.
|
* Asserts the number of slides in the slider.
|
||||||
*
|
*
|
||||||
* @param self $model
|
|
||||||
* @param boolean $isDeleting
|
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Illuminate\Validation\ValidationException If there is less 1 or more than 4 slides.
|
* @throws \Illuminate\Validation\ValidationException If there is less 1 or more than 4 slides.
|
||||||
*/
|
*/
|
||||||
private static function assertNumberOfSlides(self $model, bool $isDeleting = false): void
|
private static function assertNumberOfSlides(): void
|
||||||
{
|
{
|
||||||
if (
|
throw ValidationException::withMessages([
|
||||||
$isDeleting &&
|
'Opération impossible, minimum un et maximum quatre slides doivent être présentes.'
|
||||||
$model->published &&
|
]);
|
||||||
self::query()->where('published', true)->count() <= 1
|
|
||||||
) {
|
|
||||||
throw ValidationException::withMessages(
|
|
||||||
[trans('Minimum 1 slide doit être publiée, la slide n\'a pas été supprimée.')]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if ($model->published !== $model->getOriginal('published')) {
|
|
||||||
if (self::query()->where('published', true)->count() + 1 > 4 && $model->published) {
|
|
||||||
$model->published = false;
|
|
||||||
\session()->flash('info', \trans('Maximum 4 slides peuvent être publiées, la slide a été dépubliée.'));
|
|
||||||
} elseif (self::query()->where('published', true)->count() <= 1 && !$model->published) {
|
|
||||||
$model->published = true;
|
|
||||||
\session()->flash('info', \trans('Minimum 1 slide doit être publiée, la slide a été publiée.'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Models;
|
|
||||||
|
|
||||||
use App\Enums\StaticPageType;
|
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @property \App\Enums\StaticPageType $type Page type (StaticPageEnum).
|
|
||||||
* @property string $seo_title Seo title about 70 chars as recommended.
|
|
||||||
* @property string $seo_description Seo description about 160 chars as recommended.
|
|
||||||
* @property string $title Title for the page.
|
|
||||||
* @property string $slug Slug of the title for the page.
|
|
||||||
* @property string $content WYSIWYG text content using ckeditor.
|
|
||||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
|
||||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
|
||||||
*/
|
|
||||||
class StaticPage extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The attributes that are mass assignable.
|
|
||||||
*
|
|
||||||
* @var array<int, string>
|
|
||||||
*/
|
|
||||||
protected $fillable = [
|
|
||||||
'seo_title',
|
|
||||||
'seo_description',
|
|
||||||
'title',
|
|
||||||
'content',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The attributes that should be cast.
|
|
||||||
*
|
|
||||||
* @var array<string, string>
|
|
||||||
*/
|
|
||||||
protected $casts = [
|
|
||||||
'type' => StaticPageType::class,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform any actions required after the model boots.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected static function booted(): void
|
|
||||||
{
|
|
||||||
static::creating(function (self $model) {
|
|
||||||
// * ASSERTIONS
|
|
||||||
self::assertTitleIsUnique($model->title);
|
|
||||||
|
|
||||||
// * CHANGES
|
|
||||||
$model->slug = Str::slug($model->title);
|
|
||||||
});
|
|
||||||
static::updating(function (self $model) {
|
|
||||||
// * ASSERTIONS
|
|
||||||
self::assertTitleIsUnique($model->title, $model->id);
|
|
||||||
|
|
||||||
// * CHANGES
|
|
||||||
$model->slug = Str::slug($model->title);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// * METHODS
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Asserts using validation that the title is unique
|
|
||||||
*
|
|
||||||
* @param string|null $title
|
|
||||||
* @param integer|null $id
|
|
||||||
* @return void
|
|
||||||
* @throws \Illuminate\Validation\ValidationException If an actu title already exists.
|
|
||||||
*/
|
|
||||||
private static function assertTitleIsUnique(string|null $title, ?int $id = null)
|
|
||||||
{
|
|
||||||
$table = (new self())->getTable();
|
|
||||||
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
|
|
||||||
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -26,7 +26,7 @@ class Subrange extends Model
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'label',
|
'label',
|
||||||
|
|
@ -55,12 +55,12 @@ class Subrange extends Model
|
||||||
/**
|
/**
|
||||||
* Common methods function.
|
* Common methods function.
|
||||||
*
|
*
|
||||||
* @param self $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
private static function manageFields(self $model): void
|
private static function manageFields(Model $model): void
|
||||||
{
|
{
|
||||||
self::assertLabelIsUnique($model->label, $model->id);
|
static::assertLabelIsUnique($model->label, $model->id);
|
||||||
$model->slug = Str::slug($model->label);
|
$model->slug = Str::slug($model->label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,9 +83,9 @@ class Subrange extends Model
|
||||||
/**
|
/**
|
||||||
* Products Belongs-To-Many relationship.
|
* Products Belongs-To-Many relationship.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
* @return \Illuminate\Database\Eloquent\Relations\hasMany
|
||||||
*/
|
*/
|
||||||
public function products(): \Illuminate\Database\Eloquent\Relations\HasMany
|
public function products()
|
||||||
{
|
{
|
||||||
return $this->hasMany(Product::class);
|
return $this->hasMany(Product::class);
|
||||||
}
|
}
|
||||||
|
|
@ -93,9 +93,9 @@ class Subrange extends Model
|
||||||
/**
|
/**
|
||||||
* Range Belongs-To relationship.
|
* Range Belongs-To relationship.
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
* @return \Illuminate\Database\Eloquent\Relations\belongsTo
|
||||||
*/
|
*/
|
||||||
public function range(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
public function range()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Range::class);
|
return $this->belongsTo(Range::class);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Enums\TagTypeEnum;
|
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
use App\Lib\Helpers\ToolboxHelper;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
@ -10,9 +9,30 @@ use Illuminate\Support\Str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property integer $id Id.
|
* @property integer $id Id.
|
||||||
* @property string $slug Slug.
|
* @property string $title Title.
|
||||||
* @property string $label Label.
|
* @property string $slug Slug of the title.
|
||||||
* @property \App\Enums\TagTypeEnum $type Type (ENUM).
|
* @property string $seo_title SEO Title.
|
||||||
|
* @property string $seo_description SEO description.
|
||||||
|
* @property \App\Enums\Advices\AdviceTypeEnum $type Type of the advice.
|
||||||
|
* @property string $picture Path of a picture.
|
||||||
|
* @property string $picture_alt Picture's attribute alt.
|
||||||
|
* @property string $picture_title Picture's attribute title.
|
||||||
|
* @property string $sticker Path of a sticker.
|
||||||
|
* @property string $sticker_alt Sticker's attribute alt.
|
||||||
|
* @property string $sticker_title Sticker's attribute title.
|
||||||
|
* @property string $sticker_sm Path of a small sticker.
|
||||||
|
* @property string $sticker_sm_alt small sticker's attribute alt.
|
||||||
|
* @property string $sticker_sm_title Small sticker's attribute title.
|
||||||
|
* @property string $preparation Preparation tips.
|
||||||
|
* @property string $advice Advice.
|
||||||
|
* @property \Illuminate\Support\Carbon $ingredients Ingredients.
|
||||||
|
* @property \Illuminate\Support\Carbon $guests_nb Number of guests.
|
||||||
|
* @property \Illuminate\Support\Carbon $youtube_title Youtube title.
|
||||||
|
* @property \Illuminate\Support\Carbon $youtube_video_id Youtube video id.
|
||||||
|
* @property \Illuminate\Support\Carbon $cooking_time Time of cooking.
|
||||||
|
* @property \Illuminate\Support\Carbon $preparation_time Time of preparation.
|
||||||
|
* @property \App\Enums\Advices\AdviceDifficultyEnum $difficulty Difficulty.
|
||||||
|
* @property boolean $status Status.
|
||||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||||
*
|
*
|
||||||
|
|
@ -26,20 +46,10 @@ class Tag extends Model
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
*
|
*
|
||||||
* @var array<int, string>
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'label',
|
'label'
|
||||||
'type',
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The attributes that should be cast.
|
|
||||||
*
|
|
||||||
* @var array<string,string>
|
|
||||||
*/
|
|
||||||
protected $casts = [
|
|
||||||
'type' => TagTypeEnum::class,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -49,16 +59,16 @@ class Tag extends Model
|
||||||
*/
|
*/
|
||||||
protected static function booted(): void
|
protected static function booted(): void
|
||||||
{
|
{
|
||||||
static::creating(function (self $model) {
|
static::creating(function (Tag $tag) {
|
||||||
static::assertLabelIsUnique($model->label);
|
static::assertLabelIsUnique($tag->label);
|
||||||
$model->slug = Str::slug($model->label);
|
$tag->slug = Str::slug($tag->label);
|
||||||
});
|
});
|
||||||
static::updating(function (self $model) {
|
static::updating(function (Tag $tag) {
|
||||||
static::assertLabelIsUnique($model->label, $model->id);
|
static::assertLabelIsUnique($tag->label, $tag->id);
|
||||||
$model->slug = Str::slug($model->label);
|
$tag->slug = Str::slug($tag->label);
|
||||||
});
|
});
|
||||||
static::deleting(function (self $model) {
|
static::deleting(function (Tag $tag) {
|
||||||
$model->advice()->detach();
|
$tag->advice()->detach();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,7 +82,7 @@ class Tag extends Model
|
||||||
* @return void
|
* @return void
|
||||||
* @throws \Illuminate\Validation\ValidationException If a tag label already exists.
|
* @throws \Illuminate\Validation\ValidationException If a tag label already exists.
|
||||||
*/
|
*/
|
||||||
public static function assertLabelIsUnique(string $label, ?int $id = null): void
|
private static function assertLabelIsUnique(string $label, ?int $id = null): void
|
||||||
{
|
{
|
||||||
$table = (new self())->getTable();
|
$table = (new self())->getTable();
|
||||||
ToolboxHelper::assertFieldIsUnique($table, 'label', $label, $id);
|
ToolboxHelper::assertFieldIsUnique($table, 'label', $label, $id);
|
||||||
|
|
@ -90,14 +100,4 @@ class Tag extends Model
|
||||||
{
|
{
|
||||||
return $this->morphedByMany(Advice::class, 'taggable');
|
return $this->morphedByMany(Advice::class, 'taggable');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Product Morphed-By-Many relation.
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
|
|
||||||
*/
|
|
||||||
public function products(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
|
||||||
{
|
|
||||||
return $this->morphedByMany(Product::class, 'taggable');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,16 @@ use App\Lib\Helpers\ToolboxHelper;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property integer $id Id.
|
* @property integer $id Id.
|
||||||
* @property string $firstname Firstname.
|
* @property string $firstname Firstname.
|
||||||
* @property string $lastname Lastname.
|
* @property string $lastname Lastname.
|
||||||
* @property string $email Email.
|
* @property string $email Email.
|
||||||
|
* @property \Illuminate\Support\Carbon $email_verified_at Email_verified_at.
|
||||||
|
* @property string $password Password.
|
||||||
* @property string $remember_token Remember_token.
|
* @property string $remember_token Remember_token.
|
||||||
* @property \Carbon\Carbon $last_connection Last_connection.
|
* @property \Carbon\Carbon $last_connection Last_connection.
|
||||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||||
|
|
@ -30,7 +34,8 @@ class User extends Authenticatable
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'firstname',
|
'firstname',
|
||||||
'lastname',
|
'lastname',
|
||||||
'email'
|
'email',
|
||||||
|
'password',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -39,7 +44,8 @@ class User extends Authenticatable
|
||||||
* @var array<int, string>
|
* @var array<int, string>
|
||||||
*/
|
*/
|
||||||
protected $hidden = [
|
protected $hidden = [
|
||||||
'remember_token'
|
'password',
|
||||||
|
'remember_token',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,7 +54,8 @@ class User extends Authenticatable
|
||||||
* @var array<string, string>
|
* @var array<string, string>
|
||||||
*/
|
*/
|
||||||
protected $casts = [
|
protected $casts = [
|
||||||
'last_connection' => 'date',
|
'email_verified_at' => 'datetime',
|
||||||
|
'last_connection' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -60,10 +67,18 @@ class User extends Authenticatable
|
||||||
{
|
{
|
||||||
// * EVENT CLOSURES.
|
// * EVENT CLOSURES.
|
||||||
static::creating(function (self $user) {
|
static::creating(function (self $user) {
|
||||||
self::assertEmailIsUnique($user->email);
|
static::assertEmailIsUnique($user->email);
|
||||||
|
if (Hash::needsRehash($user->password)) {
|
||||||
|
$user->password = Hash::make($user->password);
|
||||||
|
}
|
||||||
|
$user->remember_token = Str::random(10);
|
||||||
});
|
});
|
||||||
static::updating(function (self $user) {
|
static::updating(function (self $user) {
|
||||||
self::assertEmailIsUnique($user->email, $user->id);
|
static::assertEmailIsUnique($user->email, $user->id);
|
||||||
|
if (Hash::needsRehash($user->password)) {
|
||||||
|
$user->password = Hash::make($user->password);
|
||||||
|
}
|
||||||
|
$user->remember_token = Str::random(10);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Policies\Rules;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Userlevel Policiy Static Rules
|
|
||||||
*
|
|
||||||
* @codeCoverageIgnore
|
|
||||||
*/
|
|
||||||
abstract class UserStaticRules
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Allow everyone.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static function everyOne(): bool
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allow no one.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static function noOne(): bool
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,36 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Policies;
|
|
||||||
|
|
||||||
use App\Models\StaticPage;
|
|
||||||
use App\Models\User;
|
|
||||||
|
|
||||||
class StaticPagePolicy
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Determine whether the user can view any models.
|
|
||||||
*
|
|
||||||
* @param \App\Models\User $authUser
|
|
||||||
* @return boolean
|
|
||||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
|
||||||
*/
|
|
||||||
public function viewAny(User $authUser): bool
|
|
||||||
{
|
|
||||||
// phpcs:enable
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine whether the user can update the model.
|
|
||||||
*
|
|
||||||
* @param \App\Models\User $authUser
|
|
||||||
* @param \App\Models\StaticPage $static_page
|
|
||||||
* @return boolean
|
|
||||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
|
|
||||||
*/
|
|
||||||
public function update(User $authUser, StaticPage $static_page): bool
|
|
||||||
{
|
|
||||||
// phpcs:enable
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\App;
|
use Illuminate\Support\Facades\App;
|
||||||
use Illuminate\Support\Facades\URL;
|
use Illuminate\Support\Facades\URL;
|
||||||
|
|
@ -17,8 +16,6 @@ class AppServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot()
|
||||||
{
|
{
|
||||||
Model::shouldBeStrict(!$this->app->environment('production'));
|
|
||||||
|
|
||||||
// * HTTPS FIX
|
// * HTTPS FIX
|
||||||
URL::forceScheme('https');
|
URL::forceScheme('https');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class AuthServiceProvider extends ServiceProvider
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function boot(): void
|
public function boot()
|
||||||
{
|
{
|
||||||
$this->registerPolicies();
|
$this->registerPolicies();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Providers;
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\App;
|
|
||||||
use Illuminate\Support\ServiceProvider;
|
|
||||||
use LDC\LDCCRM\CrmApiV4;
|
|
||||||
|
|
||||||
class CrmApiServiceProvider extends ServiceProvider
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Bootstrap the application services.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function boot(): void
|
|
||||||
{
|
|
||||||
App::singleton('crmAPI', function () {
|
|
||||||
return new CrmApiV4(
|
|
||||||
config('crm.endpoint'),
|
|
||||||
config('crm.token'),
|
|
||||||
config('crm.password')
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,13 +3,6 @@
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||||
use Illuminate\Support\Facades\Event;
|
|
||||||
use App\Models\User;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
|
||||||
use Illuminate\Support\Facades\Session;
|
|
||||||
use Slides\Saml2\Events\SignedIn;
|
|
||||||
use Slides\Saml2\Events\SignedOut;
|
|
||||||
|
|
||||||
class EventServiceProvider extends ServiceProvider
|
class EventServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
|
|
@ -27,41 +20,5 @@ class EventServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot()
|
||||||
{
|
{
|
||||||
Event::listen('Slides\Saml2\Events\SignedIn', function (SignedIn $event) {
|
|
||||||
|
|
||||||
$messageId = $event->getAuth()->getLastMessageId();
|
|
||||||
|
|
||||||
$fromCache = Cache::get(config('cache.prefix') . "_saml_message_id_" . $messageId);
|
|
||||||
if ($fromCache) {
|
|
||||||
logger()->error(
|
|
||||||
'SAML MESSAGE ID HANDLER',
|
|
||||||
['error' => 'Message ID : ' . $messageId . " replayed !"]
|
|
||||||
);
|
|
||||||
abort(403);
|
|
||||||
} else {
|
|
||||||
Cache::put(config('cache.prefix') . "_saml_message_id_" . $messageId, $messageId, 28800);
|
|
||||||
// Cache for 8h.
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = $event->getSaml2User();
|
|
||||||
$email = $user->getNameId();
|
|
||||||
|
|
||||||
$lUser = User::where('email', '=', $email)->first();
|
|
||||||
|
|
||||||
if (!$lUser) {
|
|
||||||
abort(403);
|
|
||||||
}
|
|
||||||
|
|
||||||
Auth::guard('backend')->login($lUser);
|
|
||||||
session(['sessionIndex' => $user->getSessionIndex()]);
|
|
||||||
$lUser->last_connection = now();
|
|
||||||
$lUser->saveQuietly();
|
|
||||||
});
|
|
||||||
|
|
||||||
//phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
|
||||||
Event::listen('Slides\Saml2\Events\SignedOut', function (SignedOut $event) {
|
|
||||||
Auth::guard('backend')->logout();
|
|
||||||
Session::save();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Models\Advice;
|
use App\Models\Advice;
|
||||||
use App\Models\BrigadeSection;
|
|
||||||
use App\Models\ExpertiseProduct;
|
use App\Models\ExpertiseProduct;
|
||||||
use App\Models\News;
|
use App\Models\News;
|
||||||
use App\Models\NewsCategory;
|
use App\Models\NewsCategory;
|
||||||
|
|
@ -58,7 +57,6 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
Route::model('range', Range::class);
|
Route::model('range', Range::class);
|
||||||
Route::model('product', Product::class);
|
Route::model('product', Product::class);
|
||||||
Route::model('advice', Advice::class);
|
Route::model('advice', Advice::class);
|
||||||
Route::model('brigade_section', BrigadeSection::class);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Route::bind('actu', function ($value) {
|
Route::bind('actu', function ($value) {
|
||||||
|
|
@ -67,7 +65,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
// * Front binded Models
|
// * Front binded Models
|
||||||
Route::bind('publishedAdvice', function ($value) {
|
Route::bind('publishedAdvice', function ($value) {
|
||||||
return Advice::where('slug', $value)->where('published', true)->firstOrFail();
|
return Advice::where('slug', $value)->where('status', true)->firstOrFail();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,11 +110,8 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
})->all();
|
})->all();
|
||||||
// * Filter array keys
|
// * Filter array keys
|
||||||
$cspReport = collect(array_intersect_key($cspReport, [
|
$cspReport = collect(array_intersect_key($cspReport, [
|
||||||
'blocked-uri' => '',
|
'blocked-uri' => '', 'document-uri' => '', 'original-policy' => '',
|
||||||
'document-uri' => '',
|
'referrer' => '', 'violated-directive' => ''
|
||||||
'original-policy' => '',
|
|
||||||
'referrer' => '',
|
|
||||||
'violated-directive' => ''
|
|
||||||
]));
|
]));
|
||||||
\Illuminate\Support\Facades\Log::warning(sprintf(
|
\Illuminate\Support\Facades\Log::warning(sprintf(
|
||||||
"CSP REPORT for %s : \n %s",
|
"CSP REPORT for %s : \n %s",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\File;
|
use Illuminate\Support\Facades\File;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
@ -21,19 +20,9 @@ class TranslationServiceProvider extends ServiceProvider
|
||||||
foreach ($this->collectLocalesStrings() as $locale) {
|
foreach ($this->collectLocalesStrings() as $locale) {
|
||||||
// * Suported locales
|
// * Suported locales
|
||||||
Cache::rememberForever(sprintf('translations.%s', $locale), function () use ($locale) {
|
Cache::rememberForever(sprintf('translations.%s', $locale), function () use ($locale) {
|
||||||
$phpTransFallback = $this->phpTranslations(config('app.fallback_locale'));
|
$translations = [
|
||||||
$phpTransLocale = $this->phpTranslations($locale);
|
'php' => $this->phpTranslations($locale),
|
||||||
$jsonTransFallback = $this->jsonTranslations(config('app.fallback_locale'));
|
'json' => $this->jsonTranslations($locale),
|
||||||
$jsonTransLocale = $this->jsonTranslations($locale);
|
|
||||||
$translations = [
|
|
||||||
'php' => ToolboxHelper::arrayMergeRecursiveDistinct(
|
|
||||||
$phpTransLocale,
|
|
||||||
$phpTransFallback,
|
|
||||||
),
|
|
||||||
'json' => ToolboxHelper::arrayMergeRecursiveDistinct(
|
|
||||||
$jsonTransLocale,
|
|
||||||
$jsonTransFallback,
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
return $translations;
|
return $translations;
|
||||||
});
|
});
|
||||||
|
|
@ -47,13 +36,11 @@ class TranslationServiceProvider extends ServiceProvider
|
||||||
*/
|
*/
|
||||||
private function collectLocalesStrings(): Collection
|
private function collectLocalesStrings(): Collection
|
||||||
{
|
{
|
||||||
// * En dur dans ->keys array<int,string>.
|
|
||||||
// @phpstan-ignore-next-line
|
|
||||||
return collect(File::allFiles(resource_path('lang/')))->flatMap(function (SplFileInfo $file) {
|
return collect(File::allFiles(resource_path('lang/')))->flatMap(function (SplFileInfo $file) {
|
||||||
if ($file->getRelativePath() and \strpos($file->getRelativePath(), 'vendor') !== 0) {
|
if ($file->getRelativePath() and \strpos($file->getRelativePath(), 'vendor') !== 0) {
|
||||||
return [$file->getRelativePath() => ''];
|
return [$file->getRelativePath() => ''];
|
||||||
}
|
}
|
||||||
})->keys()->merge(config('app.locales', []));
|
})->keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -66,10 +53,6 @@ class TranslationServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
$path = resource_path("lang/$locale");
|
$path = resource_path("lang/$locale");
|
||||||
|
|
||||||
if (!File::exists($path) or !File::isReadable($path)) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return collect(File::allFiles($path))->flatMap(function ($file) use ($locale) {
|
return collect(File::allFiles($path))->flatMap(function ($file) use ($locale) {
|
||||||
$translation = $file->getBasename('.php');
|
$translation = $file->getBasename('.php');
|
||||||
return [$translation => trans($translation, [], $locale)];
|
return [$translation => trans($translation, [], $locale)];
|
||||||
|
|
@ -86,10 +69,10 @@ class TranslationServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
$path = resource_path("lang/$locale.json");
|
$path = resource_path("lang/$locale.json");
|
||||||
|
|
||||||
if (!File::exists($path) or !File::isReadable($path)) {
|
if (is_string($path) && is_readable($path)) {
|
||||||
return [];
|
return json_decode(file_get_contents($path), true) ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
return json_decode(File::get($path), true) ?? [];
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class ViewServiceProvider extends ServiceProvider
|
||||||
if (collect(explode('/', \request()->getPathInfo()))->get(1) === 'bo') {
|
if (collect(explode('/', \request()->getPathInfo()))->get(1) === 'bo') {
|
||||||
Paginator::defaultView('bo.modules.pagination');
|
Paginator::defaultView('bo.modules.pagination');
|
||||||
} else {
|
} else {
|
||||||
Paginator::useBootstrapFive();
|
Paginator::useBootstrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Rules;
|
|
||||||
|
|
||||||
use Illuminate\Contracts\Validation\ValidationRule;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check the length of a Wysiwyg field, excluding tags and end spaces.
|
|
||||||
*
|
|
||||||
* @package App\Rules
|
|
||||||
*/
|
|
||||||
class WysiwygLength implements ValidationRule
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Construct method.
|
|
||||||
*
|
|
||||||
* @param integer $min The minimum length of the content (excluding tags). Default is 15.
|
|
||||||
* @param integer|null $max The maximum length of the content (excluding tags).
|
|
||||||
* Default is null (max will be defined by the type of the column in DB).
|
|
||||||
* @return void
|
|
||||||
* @throws \InvalidArgumentException If $max < $min.
|
|
||||||
*/
|
|
||||||
public function __construct(private int $min = 15, private int|null $max = null)
|
|
||||||
{
|
|
||||||
if ($max !== null && $max < $min && $min < 0) {
|
|
||||||
throw new \InvalidArgumentException(sprintf(
|
|
||||||
'$max should be higher than $min. $max = %d. $min = %d.',
|
|
||||||
$max,
|
|
||||||
$min
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the validation rule.
|
|
||||||
*
|
|
||||||
* @param string $attribute
|
|
||||||
* @param mixed $value
|
|
||||||
* @param \Closure $fail
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
|
||||||
{
|
|
||||||
$length = Str::length(\strip_tags($value));
|
|
||||||
|
|
||||||
$translatedAttribute = self::getTranslatedAttribute($attribute);
|
|
||||||
if (!\is_null($this->max) and !($length >= $this->min && $length <= $this->max)) {
|
|
||||||
$fail(trans('validation.between.string', [
|
|
||||||
'attribute' => $translatedAttribute,
|
|
||||||
'min' => $this->min,
|
|
||||||
'max' => $this->max
|
|
||||||
]));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($length < $this->min) {
|
|
||||||
$fail(trans('validation.min.string', [
|
|
||||||
'attribute' => $translatedAttribute,
|
|
||||||
'min' => $this->min
|
|
||||||
]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the correct translation for the given attrribute.
|
|
||||||
*
|
|
||||||
* @param string $attribute
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private static function getTranslatedAttribute(string $attribute): string
|
|
||||||
{
|
|
||||||
/** @var \Illuminate\Translation\Translator $trans */
|
|
||||||
$trans = trans();
|
|
||||||
if ($trans->has('validation.attributes.' . $attribute)) {
|
|
||||||
return trans('validation.attributes.' . $attribute);
|
|
||||||
}
|
|
||||||
if ($trans->has('validation.custom.' . $attribute)) {
|
|
||||||
return trans('validation.custom.' . $attribute);
|
|
||||||
}
|
|
||||||
return $attribute;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Traits\Controllers;
|
namespace App\Traits\Controllers;
|
||||||
|
|
||||||
use App\Http\Requests\Bo\UpdateChangeOrderRequest;
|
use App\Http\Requests\Bo\UpdateChangeOrderRequest;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Session;
|
use Illuminate\Support\Facades\Session;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
@ -14,43 +14,44 @@ trait ChangesModelOrder
|
||||||
* Change order.
|
* Change order.
|
||||||
*
|
*
|
||||||
* @param \App\Http\Requests\Bo\UpdateChangeOrderRequest $request
|
* @param \App\Http\Requests\Bo\UpdateChangeOrderRequest $request
|
||||||
* @param mixed ...$params
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
* @throws \RuntimeException Si le nom du parametre de la route ne correspond pas au model utilisé.
|
* @throws \RuntimeException Si le nom du parametre de la route ne correspond pas au model utilisé.
|
||||||
*/
|
*/
|
||||||
public function changeOrder(UpdateChangeOrderRequest $request, mixed ...$params): \Illuminate\Http\RedirectResponse
|
public function changeOrder(UpdateChangeOrderRequest $request, Model $model): \Illuminate\Http\RedirectResponse
|
||||||
{
|
{
|
||||||
$paramNames = collect(request()->route()->parameterNames);
|
$params = collect(request()->route()->parameterNames);
|
||||||
$className = Str::of($paramNames->get($paramNames->count() - 2))->lower()->studly();
|
$className = Str::ucfirst(Str::lower($params->get($params->count() - 2)));
|
||||||
$className = "\\App\\Models\\$className";
|
$className = "\\App\\Models\\$className";
|
||||||
$model = Arr::get($params, $paramNames->count() - 2);
|
|
||||||
|
|
||||||
if (!class_exists($className)) {
|
if (!class_exists($className)) {
|
||||||
throw new \RuntimeException("The $className class doesn't exist.");
|
throw new \RuntimeException("The $className class doesn't exist.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||||
$model = $className::where($model->getRouteKeyName(), $model->getRouteKey())->first();
|
$model = $className::where('id', $model->id)->first();
|
||||||
|
|
||||||
if (!$model) {
|
if (!$model) {
|
||||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
return redirect()->back()->with('error', trans('crud.messages.order_not_changed'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return DB::transaction(function () use ($request, $className, $model) {
|
return DB::transaction(function () use ($request, $className, $model) {
|
||||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||||
$tmp = $className::where('order', $request->direction ? '<' : '>', $model->getOriginal('order'))
|
$tmp = $className::where('order', $request->direction ? '<' : '>', $model->order)
|
||||||
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
|
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
|
||||||
|
|
||||||
if (!$tmp) {
|
if (!$tmp) {
|
||||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
return redirect()->back()->with('error', trans('crud.messages.order_not_changed'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$newOrder = $tmp->getOriginal('order');
|
$newOrder = $tmp->order;
|
||||||
$tmp->update(['order' => $model->getOriginal('order')]);
|
$tmp->order = $model->order;
|
||||||
$model->update(['order' => $newOrder]);
|
$model->order = $newOrder;
|
||||||
|
$tmp->saveOrFail();
|
||||||
|
$model->saveOrFail();
|
||||||
Session::flash('success', trans('crud.messages.order_changed'));
|
Session::flash('success', trans('crud.messages.order_changed'));
|
||||||
|
|
||||||
return back();
|
return redirect()->back();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
31
app/Traits/Controllers/HasPicture.php
Normal file
31
app/Traits/Controllers/HasPicture.php
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Traits\Controllers;
|
||||||
|
|
||||||
|
use App\Lib\Helpers\FileStorageHelper;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
trait HasPicture
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Save Model Images
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @phpcs:disable Generic.Commenting.Fixme.TaskFound
|
||||||
|
* FIXME: Rename trait as IT Handled "Slider pictures" not only static "picture".
|
||||||
|
*/
|
||||||
|
private function storePictures(Request $request, Model $model)
|
||||||
|
{
|
||||||
|
if (is_array($request->slider_pictures)) {
|
||||||
|
$model->slider_pictures = [];
|
||||||
|
$model->slider_pictures = collect($request->slider_pictures)
|
||||||
|
->map(function ($picture) use ($model) {
|
||||||
|
return FileStorageHelper::storeFile($model, $picture, true);
|
||||||
|
})->all();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Traits\Controllers;
|
|
||||||
|
|
||||||
use App\Http\Requests\Bo\UpdateOrderRequest;
|
|
||||||
use App\Interfaces\OrderableInterface;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
|
|
||||||
trait ManagesOrder
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Updates the order of a model and reorders all impacted elements.
|
|
||||||
*
|
|
||||||
* Shifts by +1 or -1 all elements located between the old
|
|
||||||
* and new position of the model, then assigns the new position
|
|
||||||
* to the target model. The whole operation runs inside a
|
|
||||||
* database transaction to ensure data consistency.
|
|
||||||
*
|
|
||||||
* @param UpdateOrderRequest $request The validated request containing the 'priority' field.
|
|
||||||
* @param Model&OrderableInterface $model The model to reorder (must use the Orderable trait).
|
|
||||||
* @return RedirectResponse
|
|
||||||
*
|
|
||||||
* @throws \Throwable Returns if save fail.
|
|
||||||
*/
|
|
||||||
public function changeOrderPriority(UpdateOrderRequest $request, Model&OrderableInterface $model): RedirectResponse
|
|
||||||
{
|
|
||||||
$newPriority = (int) $request->validated('priority_order');
|
|
||||||
|
|
||||||
return DB::transaction(function () use ($model, $newPriority): RedirectResponse {
|
|
||||||
|
|
||||||
$query = $model::query()
|
|
||||||
->whereKeyNot($model)
|
|
||||||
->whereBetween('priority_order', [
|
|
||||||
min($model->getPriorityOrder(), $newPriority),
|
|
||||||
max($model->getPriorityOrder(), $newPriority),
|
|
||||||
]);
|
|
||||||
|
|
||||||
$groupField = $model->getOrderGroupField();
|
|
||||||
if ($groupField) {
|
|
||||||
$query->where($groupField, $model->{$groupField});
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->getPriorityOrder() < $newPriority
|
|
||||||
? $query->decrement('priority_order', 1)
|
|
||||||
: $query->increment('priority_order', 1);
|
|
||||||
|
|
||||||
$model->setAttribute('priority_order', $newPriority);
|
|
||||||
$model->saveOrFail();
|
|
||||||
|
|
||||||
return redirect()->back()->with('success', trans('crud.messages.order_changed'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,17 +9,18 @@ use Illuminate\Database\Eloquent\Model;
|
||||||
* to resolve the model and the DB row
|
* to resolve the model and the DB row
|
||||||
* It does not work with binder Service
|
* It does not work with binder Service
|
||||||
*/
|
*/
|
||||||
trait UpdateModelPublished
|
trait UpdateModelStatus
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Change model published.
|
* Change model published
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Database\Eloquent\Model $model
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
* @return \Illuminate\Http\RedirectResponse
|
* @return \Illuminate\Http\RedirectResponse
|
||||||
*/
|
*/
|
||||||
public function changePublished(Model $model)
|
public function changePublished(Model $model)
|
||||||
{
|
{
|
||||||
$model->update(['published' => !$model->getOriginal('published')]);
|
$model->status = !$model->status;
|
||||||
return redirect()->back()->with('success', trans('crud.messages.publish_status_saved'));
|
$model->saveOrFail();
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -89,7 +89,7 @@ trait BaseEnum
|
||||||
/**
|
/**
|
||||||
* Get enums.
|
* Get enums.
|
||||||
*
|
*
|
||||||
* @return array<self>
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function toArray(): array
|
public static function toArray(): array
|
||||||
{
|
{
|
||||||
|
|
@ -118,9 +118,9 @@ trait BaseEnum
|
||||||
/**
|
/**
|
||||||
* Fetch enum using value.
|
* Fetch enum using value.
|
||||||
*
|
*
|
||||||
* @param self|integer|string $value
|
* @param \App\Traits\Enums\BaseEnum|integer|string $value
|
||||||
* @param string $field
|
* @param string $field
|
||||||
* @return self|null
|
* @return \App\Traits\Enums\BaseEnum|null
|
||||||
*/
|
*/
|
||||||
public static function make(self|int|string $value, string $field = 'value'): self|null
|
public static function make(self|int|string $value, string $field = 'value'): self|null
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,78 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Traits\Models;
|
|
||||||
|
|
||||||
use App\Interfaces\OrderableInterface;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
trait Orderable
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @property int $priority_order
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the grouping field used for ordering.
|
|
||||||
* Returns null if the order is global
|
|
||||||
*
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getOrderGroupField(): ?string
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the priority order value of the model.
|
|
||||||
*
|
|
||||||
* @return integer
|
|
||||||
*/
|
|
||||||
public function getPriorityOrder(): int
|
|
||||||
{
|
|
||||||
return $this->priority_order ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* shifts down by 1 all elements positioned after the delete.
|
|
||||||
*
|
|
||||||
* @param Model&OrderableInterface $model
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function setOrder(OrderableInterface $model): void
|
|
||||||
{
|
|
||||||
$groupField = $model->getOrderGroupField();
|
|
||||||
$query = $model::query()->where('priority_order', '>', $model->getPriorityOrder());
|
|
||||||
|
|
||||||
if ($groupField) {
|
|
||||||
$query->where($groupField, $model->{$groupField});
|
|
||||||
}
|
|
||||||
|
|
||||||
$query->each(function (Model $item): void {
|
|
||||||
/** @var Model&OrderableInterface $item */
|
|
||||||
$item->setAttribute('priority_order', $item->getPriorityOrder() - 1);
|
|
||||||
$item->saveOrFail();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assigns the next order value on creation.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public static function bootOrderable(): void
|
|
||||||
{
|
|
||||||
static::creating(function (Model $model): void {
|
|
||||||
/** @var Model&OrderableInterface $model */
|
|
||||||
if (!$model->getPriorityOrder()) {
|
|
||||||
$groupField = $model->getOrderGroupField();
|
|
||||||
$query = static::query();
|
|
||||||
|
|
||||||
if ($groupField) {
|
|
||||||
$query->where($groupField, $model->{$groupField});
|
|
||||||
}
|
|
||||||
|
|
||||||
$model->setAttribute('priority_order', ($query->max('priority_order') ?? 0) + 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,11 +2,8 @@
|
||||||
|
|
||||||
namespace App\Traits\Requests;
|
namespace App\Traits\Requests;
|
||||||
|
|
||||||
use App\Lib\Helpers\ToolboxHelper;
|
use Illuminate\Support\Facades\File;
|
||||||
|
|
||||||
/**
|
|
||||||
* ! This assumes file system is using local storage
|
|
||||||
*/
|
|
||||||
trait HasPicture
|
trait HasPicture
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|
@ -14,14 +11,14 @@ trait HasPicture
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
private $minWidth = 400;
|
private $minWith = 400;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximum width
|
* Maximum width
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
*/
|
*/
|
||||||
private $maxWidth = 1800;
|
private $maxWith = 1800;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimum height
|
* Minimum height
|
||||||
|
|
@ -41,41 +38,32 @@ trait HasPicture
|
||||||
* Image rules
|
* Image rules
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param integer|null $minWidth
|
* @param boolean $required
|
||||||
|
* @param integer|null $minWith
|
||||||
* @param integer|null $minHeight
|
* @param integer|null $minHeight
|
||||||
* @param integer|null $maxWidth
|
* @param integer|null $maxWith
|
||||||
* @param integer|null $maxHeight
|
* @param integer|null $maxHeight
|
||||||
* @param boolean $nullable
|
|
||||||
* @param integer|null $size
|
|
||||||
* @param string|null $requiredWith
|
|
||||||
* @param string|null $requiredWithout
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function pictureRules(
|
public function pictureRules(
|
||||||
string $name = 'picture',
|
string $name = 'picture',
|
||||||
?int $minWidth = null,
|
bool $required = true,
|
||||||
|
?int $minWith = null,
|
||||||
?int $minHeight = null,
|
?int $minHeight = null,
|
||||||
?int $maxWidth = null,
|
?int $maxWith = null,
|
||||||
?int $maxHeight = null,
|
?int $maxHeight = null
|
||||||
bool $nullable = false,
|
|
||||||
?int $size = null,
|
|
||||||
?string $requiredWith = null,
|
|
||||||
?string $requiredWithout = null,
|
|
||||||
): array {
|
): array {
|
||||||
$dimensions = (object)[
|
$sizes = (object)[
|
||||||
'minWidth' => $minWidth ?? $this->minWidth,
|
'minWith' => $minWith ?? $this->minWith,
|
||||||
'minHeight' => $minHeight ?? $this->minHeight,
|
'minHeight' => $minHeight ?? $this->minHeight,
|
||||||
'maxWidth' => $maxWidth ?? $this->maxWidth,
|
'maxWith' => $maxWith ?? $this->maxWith,
|
||||||
'maxHeight' => $maxHeight ?? $this->maxHeight
|
'maxHeight' => $maxHeight ?? $this->maxHeight
|
||||||
];
|
];
|
||||||
return [
|
return [
|
||||||
$name => [
|
$name => [
|
||||||
!$nullable ? 'required' : 'nullable',
|
$required ? 'required' : 'nullable',
|
||||||
(strlen($requiredWith)) ? 'required_with:' . $requiredWith : '',
|
function (string $attribute, $value, callable $fail) use ($sizes) {
|
||||||
(strlen($requiredWithout)) ? 'required_without:' . $requiredWithout : '',
|
return $this->validatePicture($attribute, $value, $fail, $sizes);
|
||||||
($size) ? 'max:' . $size : '',
|
|
||||||
function (string $attribute, $value, callable $fail) use ($dimensions) {
|
|
||||||
ToolboxHelper::validatePicture($attribute, $value, $fail, $dimensions);
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
@ -85,42 +73,92 @@ trait HasPicture
|
||||||
* Images rules
|
* Images rules
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string $name
|
||||||
* @param integer|null $minWidth
|
* @param boolean $required
|
||||||
|
* @param integer|null $minWith
|
||||||
* @param integer|null $minHeight
|
* @param integer|null $minHeight
|
||||||
* @param integer|null $maxWidth
|
* @param integer|null $maxWith
|
||||||
* @param integer|null $maxHeight
|
* @param integer|null $maxHeight
|
||||||
* @param integer $limitMin
|
* @param integer|null $limitMin
|
||||||
* @param integer $limitMax
|
* @param integer|null $limitMax
|
||||||
* @param boolean $nullable
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function picturesRules(
|
public function picturesRules(
|
||||||
string $name = 'pictures',
|
string $name = 'pictures',
|
||||||
?int $minWidth = null,
|
bool $required = true,
|
||||||
|
?int $minWith = null,
|
||||||
?int $minHeight = null,
|
?int $minHeight = null,
|
||||||
?int $maxWidth = null,
|
?int $maxWith = null,
|
||||||
?int $maxHeight = null,
|
?int $maxHeight = null,
|
||||||
int $limitMin = 1,
|
?int $limitMin = null,
|
||||||
int $limitMax = 5,
|
?int $limitMax = null
|
||||||
bool $nullable = false
|
|
||||||
): array {
|
): array {
|
||||||
$sizes = (object)[
|
$sizes = (object)[
|
||||||
'minWidth' => $minWidth ?? $this->minWidth,
|
'required' => $required ?? $this->required,
|
||||||
|
'minWith' => $minWith ?? $this->minWith,
|
||||||
'minHeight' => $minHeight ?? $this->minHeight,
|
'minHeight' => $minHeight ?? $this->minHeight,
|
||||||
'maxWidth' => $maxWidth ?? $this->maxWidth,
|
'maxWith' => $maxWith ?? $this->maxWith,
|
||||||
'maxHeight' => $maxHeight ?? $this->maxHeight,
|
'maxHeight' => $maxHeight ?? $this->maxHeight,
|
||||||
|
'limitMin' => $limitMin ?? $this->limitMin,
|
||||||
|
'limitMax' => $limitMax ?? $this->limitMax
|
||||||
];
|
];
|
||||||
return [
|
return [
|
||||||
$name => [!$nullable ? 'required' : 'nullable', 'array', "between:{$limitMin},{$limitMax}"],
|
"{$name}" => ($required ? 'required' : 'nullable') . "|array|between:$limitMin,$limitMax",
|
||||||
"{$name}.*" => [
|
"{$name}.*" => [
|
||||||
'required',
|
'required',
|
||||||
function (string $attribute, $value, callable $fail) use ($sizes) {
|
function (string $attribute, $value, callable $fail) use ($sizes) {
|
||||||
ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
|
return $this->validatePicture($attribute, $value, $fail, $sizes);
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate picture
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @param callback $fail
|
||||||
|
* @param object $sizes
|
||||||
|
* @return void
|
||||||
|
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||||
|
*/
|
||||||
|
private function validatePicture(string $attribute, mixed $value, callable $fail, object $sizes)
|
||||||
|
{
|
||||||
|
if (!File::exists($value)) {
|
||||||
|
$fail(trans(":attribute n'existe pas dans le système de fichier"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!\in_array(File::mimeType($value), ['image/jpeg', 'image/jpg', 'image/png', 'image/gif'])) {
|
||||||
|
$fail(trans(":attribute doit être une image de type 'image/jpeg,image/jpg,image/png,image/gif'"));
|
||||||
|
}
|
||||||
|
if (!($dimensions = \getimagesize($value)) or !isset($dimensions[0]) or !isset($dimensions[1])) {
|
||||||
|
$fail(trans(":attribute impossible de valider les dimensions"));
|
||||||
|
} else {
|
||||||
|
$width = intval($dimensions[0]);
|
||||||
|
$height = intval($dimensions[1]);
|
||||||
|
|
||||||
|
$xMessage = trans(
|
||||||
|
":attribute la largeur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px"
|
||||||
|
);
|
||||||
|
if ($sizes->minWith === $sizes->maxWith) {
|
||||||
|
$xMessage = trans(":attribute la largeur doit être de {$sizes->minWith}px");
|
||||||
|
}
|
||||||
|
$yMessage = trans(
|
||||||
|
":attribute la hauteur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px"
|
||||||
|
);
|
||||||
|
if ($sizes->minHeight === $sizes->maxHeight) {
|
||||||
|
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minWith}px");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($width < $sizes->minWith) or ($width > $sizes->maxWith)) {
|
||||||
|
$fail($xMessage);
|
||||||
|
}
|
||||||
|
if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) {
|
||||||
|
$fail($yMessage);
|
||||||
|
}
|
||||||
|
} //end if
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges products pictures fields with request data
|
* Merges products pictures fields with request data
|
||||||
*
|
*
|
||||||
|
|
@ -151,38 +189,4 @@ trait HasPicture
|
||||||
]);
|
]);
|
||||||
} //end if
|
} //end if
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Merges products pictures fields with request data
|
|
||||||
*
|
|
||||||
* @param string $name
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected function mergePictures(string $name = 'pictures'): void
|
|
||||||
{
|
|
||||||
$pictures = $this->{$name};
|
|
||||||
if (is_array($pictures)) {
|
|
||||||
$this->merge(["{$name}Validate" => []]);
|
|
||||||
foreach ($pictures as $key => $picturePath) {
|
|
||||||
// ! Empty picture.
|
|
||||||
if ($picturePath === 'false') {
|
|
||||||
// * Empty picture and exit
|
|
||||||
$this->merge([$name => []]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$decodedPath = \urldecode($picturePath);
|
|
||||||
$this->merge([
|
|
||||||
"{$name}Validate" => array_merge(
|
|
||||||
$this->{"{$name}Validate"},
|
|
||||||
[\public_path(ltrim($decodedPath, '/'))]
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
$changedPicture = $this->{$name};
|
|
||||||
$changedPicture[$key] = ltrim($decodedPath, '/');
|
|
||||||
$this->merge([
|
|
||||||
$name => $changedPicture
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
} //end if
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,38 +12,33 @@
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": "^8.5",
|
"php": "^8.2",
|
||||||
"24slides/laravel-saml2": "^2.4",
|
|
||||||
"axlon/laravel-postal-code-validation": "^3.4",
|
"axlon/laravel-postal-code-validation": "^3.4",
|
||||||
"carlos-meneses/laravel-mpdf": "^2.1.13",
|
"carlos-meneses/laravel-mpdf": "^2.1.13",
|
||||||
"diglactic/laravel-breadcrumbs": "^9.0",
|
"diglactic/laravel-breadcrumbs": "^8.1.1",
|
||||||
"guzzlehttp/guzzle": "^7.2",
|
"guzzlehttp/guzzle": "^7.2",
|
||||||
"kaishiyoku/laravel-color-validation": "*",
|
"kaishiyoku/laravel-color-validation": "^2.1.1",
|
||||||
"laravel/framework": "^11.0",
|
"kwaadpepper/image-resizer": "^2.1.0",
|
||||||
|
"laravel/framework": "^10.0",
|
||||||
"laravel/tinker": "^2.8",
|
"laravel/tinker": "^2.8",
|
||||||
"laravel/ui": "^4.2",
|
"laravel/ui": "^4.2",
|
||||||
"ldc/ldccrmv4client": "^4.0",
|
"ldc/sitemap-generator": "^2.0",
|
||||||
|
"ldc/web-admin-secure-laravel": "^2.0.0",
|
||||||
"mews/purifier": "^3.4",
|
"mews/purifier": "^3.4",
|
||||||
"propaganistas/laravel-phone": "^5.0.3",
|
"propaganistas/laravel-phone": "^5.0.3",
|
||||||
"sentry/sentry-laravel": "^4.9",
|
"sentry/sentry-laravel": "^3.8",
|
||||||
"spatie/calendar-links": "^1.8.5",
|
"spatie/calendar-links": "^1.8.5",
|
||||||
"uwil/admin-secure-laravel": "^5.0",
|
|
||||||
"uwil/k8s-laravel": "^1.2",
|
"uwil/k8s-laravel": "^1.2",
|
||||||
"uwil/laravel-common": "^2.0",
|
"uwil/seo-laravel": "^1.0"
|
||||||
"uwil/laravel-redirections": "^2.0",
|
|
||||||
"uwil/seo-laravel": "^3.0",
|
|
||||||
"uwil/sitemap-generator": "^3.0",
|
|
||||||
"verschuur/laravel-robotstxt": "^5.1"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"doctrine/dbal": "^3.3",
|
"doctrine/dbal": "^3.3",
|
||||||
"fakerphp/faker": "^1.9.1",
|
"fakerphp/faker": "^1.9.1",
|
||||||
"larastan/larastan": "^2.8",
|
|
||||||
"laravel-lang/lang": "10.0",
|
"laravel-lang/lang": "10.0",
|
||||||
"laravel/pint": "^1.0",
|
"laravel/pint": "^1.0",
|
||||||
"laravel/sail": "^1.18",
|
"laravel/sail": "^1.18",
|
||||||
"mockery/mockery": "^1.4.4",
|
"mockery/mockery": "^1.4.4",
|
||||||
"nunomaduro/collision": "^8.1",
|
"nunomaduro/collision": "^7.0",
|
||||||
"phpunit/phpunit": "^10.0",
|
"phpunit/phpunit": "^10.0",
|
||||||
"slevomat/coding-standard": "^8.10",
|
"slevomat/coding-standard": "^8.10",
|
||||||
"spatie/laravel-ignition": "^2.3"
|
"spatie/laravel-ignition": "^2.3"
|
||||||
|
|
@ -94,10 +89,7 @@
|
||||||
"pestphp/pest-plugin": true,
|
"pestphp/pest-plugin": true,
|
||||||
"php-http/discovery": true,
|
"php-http/discovery": true,
|
||||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||||
},
|
}
|
||||||
"gitlab-domains": [
|
|
||||||
"lab.s-web.fr"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"minimum-stability": "stable",
|
"minimum-stability": "stable",
|
||||||
"prefer-stable": true
|
"prefer-stable": true
|
||||||
|
|
|
||||||
6090
composer.lock
generated
6090
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -179,7 +179,6 @@ return [
|
||||||
App\Providers\EventServiceProvider::class,
|
App\Providers\EventServiceProvider::class,
|
||||||
App\Providers\RouteServiceProvider::class,
|
App\Providers\RouteServiceProvider::class,
|
||||||
App\Providers\ViewServiceProvider::class,
|
App\Providers\ViewServiceProvider::class,
|
||||||
App\Providers\CrmApiServiceProvider::class,
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
'endpoint' => env('CRM_ENDPOINT'),
|
|
||||||
'token' => env('CRM_TOKEN'),
|
|
||||||
'password' => env('CRM_PASSWORD')
|
|
||||||
];
|
|
||||||
|
|
@ -5,7 +5,7 @@ return [
|
||||||
* The php image driver to use
|
* The php image driver to use
|
||||||
* this can be 'imagick' or 'gd'
|
* this can be 'imagick' or 'gd'
|
||||||
*/
|
*/
|
||||||
'driver' => 'imagick',
|
'driver' => 'gd',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cache driver to use as defined
|
* The cache driver to use as defined
|
||||||
|
|
@ -57,9 +57,6 @@ return [
|
||||||
* ]
|
* ]
|
||||||
*/
|
*/
|
||||||
'templates' => [
|
'templates' => [
|
||||||
'toWebp' => [
|
|
||||||
'format' => 'webp'
|
|
||||||
],
|
|
||||||
'tipsBigCard' => [
|
'tipsBigCard' => [
|
||||||
'height' => 300,
|
'height' => 300,
|
||||||
'width' => 370,
|
'width' => 370,
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'contactsList' => [
|
'contactsList' => [
|
||||||
'contactform' => array_filter(explode(',', env('MAIL_LIST_CONTACTFORM', '') ?? '')),
|
'contactform' => env('MAIL_LIST_CONTACTFORM')
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
return [
|
|
||||||
'environments' => [
|
|
||||||
'production' => [
|
|
||||||
'paths' => [
|
|
||||||
'*' => [
|
|
||||||
'disallow' => [
|
|
||||||
'/bo',
|
|
||||||
'*.pdf$'
|
|
||||||
],
|
|
||||||
'allow' => []
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'sitemaps' => [
|
|
||||||
'sitemap.xml'
|
|
||||||
]
|
|
||||||
]
|
|
||||||
]
|
|
||||||
];
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue