Compare commits
No commits in common. "main" and "clean" have entirely different histories.
332 changed files with 6051 additions and 19645 deletions
21
.env.example
21
.env.example
|
|
@ -61,29 +61,8 @@ VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
|||
# Sentry
|
||||
SENTRY_LARAVEL_DSN=
|
||||
|
||||
# Matomo
|
||||
MATOMO_SITE_ID=id
|
||||
|
||||
# MAILS
|
||||
MAIL_CONTACT_REMARK="equipe.web@ldc.fr"
|
||||
MAIL_CONTACT_SPONSORING="equipe.web@ldc.fr"
|
||||
MAIL_CONTACT_SERVICE="equipe.web@ldc.fr"
|
||||
MAIL_CONTACT_OTHER="equipe.web@ldc.fr"
|
||||
|
||||
# GOOGLE
|
||||
# - RECAPTCHA
|
||||
GOOGLE_RECAPTCHA_PUBLIC=
|
||||
GOOGLE_RECAPTCHA_PRIVATE=
|
||||
GOOGLE_RECAPTCHA_VERSION=
|
||||
|
||||
|
||||
SAML2_DEFAULT_TENANT_UUID=
|
||||
SAML2_SP_CERT_x509=
|
||||
SAML2_SP_CERT_PRIVATEKEY=
|
||||
SAML2_CONTACT_TECHNICAL_EMAIL=
|
||||
|
||||
# UWIL ADMIN SECURE
|
||||
# - LIST SEPARATED WITH ',' (Required)
|
||||
UWIL_ADMIN_SECURE_CIDR_LIST=""
|
||||
# - LIST SEPARATED WITH ',' (Optional)
|
||||
UWIL_ADMIN_SECURE_CIDR_PROJECT_ALLOWED_LIST=""
|
||||
|
|
|
|||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -23,9 +23,6 @@ Homestead.yaml
|
|||
npm-debug.log
|
||||
yarn-error.log
|
||||
.npmrc
|
||||
.zshrc
|
||||
.npm/
|
||||
.composer/
|
||||
|
||||
# Ignore public favicon
|
||||
/public/android-chrome-192x192.png
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
include:
|
||||
- project: "ldc-web/shared-ci"
|
||||
ref: "main"
|
||||
file: "lint/lint.yml"
|
||||
file: "lint/lint8.3.yml"
|
||||
- project: "ldc-web/shared-ci"
|
||||
ref: "main"
|
||||
file: "security/security.yml"
|
||||
file: "security/security8.3.yml"
|
||||
- project: "ldc-web/shared-ci"
|
||||
ref: "main"
|
||||
file: "build/docker-multistage.yml"
|
||||
file: "build/build8.3.yml"
|
||||
- project: "ldc-web/shared-ci"
|
||||
ref: "main"
|
||||
file: "test/test.yml"
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/sh
|
||||
npx commitlint --config node_modules/@uwil/husky-config/commitlint.config.js --edit $1
|
||||
47
Dockerfile
47
Dockerfile
|
|
@ -1,46 +1,5 @@
|
|||
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 config set @uwil:registry https://lab.s-web.fr/api/v4/groups/ldc-web/-/packages/npm/
|
||||
RUN npm config set -- '//lab.s-web.fr/api/v4/groups/ldc-web/-/packages/npm/:_authToken' "${GITLAB_PASSWORD}"
|
||||
RUN npm ci --no-audit --no-fund --loglevel=error && npm run prod
|
||||
|
||||
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 --from=vendor --chown=${USER}:${USER} /app/vendor/ /app/srcs/vendor/
|
||||
COPY --from=frontend --chown=${USER}:${USER} /app/public/build/ /app/srcs/public/build/
|
||||
COPY --chown=${USER}:${USER} ./resources/favicon /app/srcs/public
|
||||
|
||||
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
|
||||
USER root
|
||||
RUN chmod -R 755 /app/srcs/storage
|
||||
USER ${USER}
|
||||
USER www-data
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Jobs\CleanOldActivities as CleanOldActivitiesJob;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CleanOldActivities extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'uwil:activity-logs:clean {--force : Delete all activity logs regardless of date.}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Clean all logs older than one year. Use --force to delete all logs.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$messageTitle = "<comment>activity logs</comment>";
|
||||
$this->components->info("Cleaning {$messageTitle}...");
|
||||
|
||||
$force = $this->option('force');
|
||||
|
||||
if ($force && !$this->confirm('Are you sure you want to delete all activity logs ? This cannot be undone.')) {
|
||||
$this->components->error("Clean of {$messageTitle} aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
(new CleanOldActivitiesJob(force: $force))->handle();
|
||||
|
||||
$messageContent = $force ? "All {$messageTitle} deleted" : "Old {$messageTitle} cleaned";
|
||||
$this->components->success($messageContent);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Artisan command to create a backend admin user.
|
||||
*/
|
||||
class MakeUser extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'uwil:make:user';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a new backend admin user.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$this->components->info("Creating a new <comment>backend user</comment>...");
|
||||
|
||||
$firstName = $this->askValid(
|
||||
'first_name',
|
||||
'First name',
|
||||
'Admin',
|
||||
['required', 'min:3', 'max:255']
|
||||
);
|
||||
$lastName = $this->askValid(
|
||||
'last_name',
|
||||
'Last name',
|
||||
'Saïtama',
|
||||
['required', 'min:3', 'max:255']
|
||||
);
|
||||
$email = $this->askValid(
|
||||
'email',
|
||||
'Email',
|
||||
'equipe.web@ldc.fr',
|
||||
['required', 'unique:users,email', 'email:rfc,strict,dns,spoof,filter']
|
||||
);
|
||||
$role = $this->askRole();
|
||||
|
||||
$user = new User([
|
||||
'first_name' => $firstName,
|
||||
'last_name' => $lastName,
|
||||
'email' => $email,
|
||||
'role' => $role,
|
||||
'published' => true,
|
||||
'published_at' => Carbon::now(),
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
||||
$this->components->success("User <comment>{$firstName} {$lastName}</comment> created successfully.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask for a value and validate it, re-prompting on failure.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $label
|
||||
* @param string $default
|
||||
* @param array<int, string> $rules
|
||||
* @return string
|
||||
*/
|
||||
private function askValid(string $field, string $label, string $default, array $rules): string
|
||||
{
|
||||
try {
|
||||
$value = $this->ask(sprintf("Type the wanted user %s", $label), $default);
|
||||
$validator = Validator::make([$field => $value], [$field => $rules]);
|
||||
$validator->validate();
|
||||
return $value;
|
||||
} catch (ValidationException $e) {
|
||||
$this->components->error(
|
||||
collect($e->errors())->flatten()->first()
|
||||
);
|
||||
return $this->askValid($field, $label, $default, $rules);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask for a role and return the corresponding RoleEnum.
|
||||
*
|
||||
* @return \App\Enums\Users\RoleEnum
|
||||
*/
|
||||
private function askRole(): \App\Enums\Users\RoleEnum
|
||||
{
|
||||
$options = collect([
|
||||
RoleEnum::conceptor,
|
||||
RoleEnum::admin,
|
||||
RoleEnum::visitor,
|
||||
])->mapWithKeys(fn(RoleEnum $role) => [
|
||||
Str::ucFirst($role->label()) => $role
|
||||
]);
|
||||
|
||||
/** @var string $choice */
|
||||
$choice = $this->choice('Role', $options->keys()->all(), Str::ucFirst(RoleEnum::visitor->label()));
|
||||
return $options->get($choice);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Jobs\UpdatePlanificatedStatus as UpdatePlanificatedStatusJob;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class UpdatePlanificatedStatus extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'uwil:update-planificated-status';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Update models planificated status.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
(new UpdatePlanificatedStatusJob())->handle();
|
||||
$this->info('Models\' planificated status updated 👌');
|
||||
}
|
||||
}
|
||||
236
app/Console/Commands/UserCreate.php
Normal file
236
app/Console/Commands/UserCreate.php
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserCreate extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'uwil:user:create';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a backend admin user';
|
||||
|
||||
/**
|
||||
* The first name of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $first_name;
|
||||
|
||||
/**
|
||||
* The last name of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $last_name;
|
||||
|
||||
/**
|
||||
* The email of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* The role of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $role;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->first_name = null;
|
||||
$this->addFirstName();
|
||||
|
||||
$this->last_name = null;
|
||||
$this->addLastName();
|
||||
|
||||
$this->email = null;
|
||||
$this->addEmail();
|
||||
|
||||
$this->password = null;
|
||||
$this->addPassword();
|
||||
|
||||
$this->role = null;
|
||||
$this->addRole();
|
||||
|
||||
$user = new User([
|
||||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'password' => $this->password,
|
||||
'role' => $this->role,
|
||||
'published' => true,
|
||||
'published_at' => Carbon::now(),
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
||||
$this->info('User created 👌');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a first name to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addFirstName(): void
|
||||
{
|
||||
while (is_null($this->first_name)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user first name', 'Admin');
|
||||
$validator = Validator::make(['first_name' => $tmp], [
|
||||
'first_name' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->first_name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid first name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a last name to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addLastName(): void
|
||||
{
|
||||
while (is_null($this->last_name)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user last name', 'Saïtama');
|
||||
$validator = Validator::make(['last_name' => $tmp], [
|
||||
'last_name' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->last_name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid last_name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an email to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addEmail(): void
|
||||
{
|
||||
while (is_null($this->email)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user email', 'equipe.web@ldc.fr');
|
||||
$validator = Validator::make(['email' => $tmp], [
|
||||
'email' => 'required|unique:users,email|email:rfc,dns'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->email = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid email %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //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
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a role to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addRole(): void
|
||||
{
|
||||
while (is_null($this->role)) {
|
||||
try {
|
||||
$tmp = $this->choice(
|
||||
'Select his role',
|
||||
[
|
||||
Str::ucFirst(RoleEnum::conceptor->label()),
|
||||
Str::ucFirst(RoleEnum::admin->label()),
|
||||
Str::ucFirst(RoleEnum::visitor->label())
|
||||
],
|
||||
Str::ucFirst(RoleEnum::visitor->label()),
|
||||
$maxAttempts = null,
|
||||
$allowMultipleSelections = false
|
||||
);
|
||||
if ($tmp === Str::ucFirst(RoleEnum::conceptor->label())) {
|
||||
$tmp = RoleEnum::conceptor;
|
||||
}
|
||||
if ($tmp === Str::ucFirst(RoleEnum::admin->label())) {
|
||||
$tmp = RoleEnum::admin;
|
||||
}
|
||||
if ($tmp === Str::ucFirst(RoleEnum::visitor->label())) {
|
||||
$tmp = RoleEnum::visitor;
|
||||
}
|
||||
$validator = Validator::make(['role' => $tmp], [
|
||||
'role' => 'required'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->role = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please choose from the selection %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Jobs\CleanOldActivities;
|
||||
use App\Jobs\UpdatePlanificatedStatus;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
|
|
@ -15,10 +13,8 @@ class Kernel extends ConsoleKernel
|
|||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
$schedule->job(CleanOldActivities::class)->daily();
|
||||
$schedule->job(UpdatePlanificatedStatus::class)->everyFiveMinutes();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -26,7 +22,7 @@ class Kernel extends ConsoleKernel
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands(): void
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__ . '/Commands');
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ enum ActivityLogsEventEnum: int
|
|||
case deleted = 4;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
|
|
@ -27,7 +27,7 @@ enum ActivityLogsEventEnum: int
|
|||
|
||||
|
||||
/**
|
||||
* Custom added classes definition.
|
||||
* Custom added classes definition
|
||||
*/
|
||||
private const BOOTSTRAPCLASS = [
|
||||
self::created->name => 'success',
|
||||
|
|
@ -37,7 +37,7 @@ enum ActivityLogsEventEnum: int
|
|||
];
|
||||
|
||||
/**
|
||||
* Get Class.
|
||||
* Get Class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -9,10 +9,9 @@ enum CkEditorConfigName: int
|
|||
use BaseEnum;
|
||||
|
||||
case minimal = 1;
|
||||
case basic = 2;
|
||||
case base = 2;
|
||||
case advanced = 3;
|
||||
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
|
|
@ -20,8 +19,7 @@ enum CkEditorConfigName: int
|
|||
*/
|
||||
private const LABELS = [
|
||||
self::minimal->name => 'minimal',
|
||||
self::basic->name => 'basic',
|
||||
self::base->name => 'base',
|
||||
self::advanced->name => 'advanced',
|
||||
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -518,7 +518,7 @@ enum Country: int
|
|||
/**
|
||||
* Get Valid Shipping Countries
|
||||
*
|
||||
* @return array<int, self>
|
||||
* @return array
|
||||
*/
|
||||
public static function validShippingCountries(): array
|
||||
{
|
||||
|
|
@ -544,7 +544,7 @@ enum Country: int
|
|||
/**
|
||||
* Get Valid Shipping Countries
|
||||
*
|
||||
* @return array<int, self>
|
||||
* @return array
|
||||
*/
|
||||
public static function validBillingCountries(): array
|
||||
{
|
||||
|
|
@ -568,7 +568,7 @@ enum Country: int
|
|||
/**
|
||||
* Get Alpha 2 ISO code of valid shipping countries
|
||||
*
|
||||
* @return array<int, string>
|
||||
* @return array
|
||||
*/
|
||||
public static function getValidShippingCountriesIsoAplha2Codes(): array
|
||||
{
|
||||
|
|
@ -578,7 +578,7 @@ enum Country: int
|
|||
/**
|
||||
* Get Alpha 2 ISO code of valid billing countries
|
||||
*
|
||||
* @return array<int, string>
|
||||
* @return array
|
||||
*/
|
||||
public static function getValidBillingCountriesIsoAplha2Codes(): array
|
||||
{
|
||||
|
|
@ -586,7 +586,7 @@ enum Country: int
|
|||
}
|
||||
|
||||
/**
|
||||
* Custom added ISOCODES definition.
|
||||
* Custom added ISOCODES definition
|
||||
*/
|
||||
private const ISOCODES = [
|
||||
self::afghanistan->name => 'AFG',
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ enum PageSectionEnum: int
|
|||
case produce_quality = 28;
|
||||
case produce_linking = 29;
|
||||
case listening_study = 30;
|
||||
case produce_networks = 31;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
|
|
@ -76,7 +75,6 @@ enum PageSectionEnum: int
|
|||
self::produce_quality->name => 'Qualité',
|
||||
self::produce_linking->name => 'Liens',
|
||||
self::listening_study->name => 'On étudie',
|
||||
self::produce_networks->name => 'Nos réseaux',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -116,8 +114,7 @@ enum PageSectionEnum: int
|
|||
self::produce_rhd,
|
||||
self::produce_export,
|
||||
self::produce_quality,
|
||||
self::listening_study,
|
||||
self::produce_networks => false,
|
||||
self::listening_study => false,
|
||||
}; //end match
|
||||
}
|
||||
|
||||
|
|
@ -135,7 +132,7 @@ enum PageSectionEnum: int
|
|||
self::home_life,
|
||||
self::unveil_sites,
|
||||
self::unveil_history,
|
||||
self::unveil_commitments => \App\Enums\CkEditorConfigName::basic->label(),
|
||||
self::unveil_commitments => \App\Enums\CkEditorConfigName::base->label(),
|
||||
self::unveil_pole,
|
||||
self::unveil_missions,
|
||||
self::unveil_local,
|
||||
|
|
@ -158,8 +155,7 @@ enum PageSectionEnum: int
|
|||
self::produce_quality,
|
||||
self::listening_study => \App\Enums\CkEditorConfigName::advanced->label(),
|
||||
self::produce_linking,
|
||||
self::hire_grow,
|
||||
self::produce_networks => null,
|
||||
self::hire_grow, => null,
|
||||
}; //end match
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,73 +30,4 @@ enum SpeciesEnum: int
|
|||
self::guinea_fowl->name => 'Pintade',
|
||||
self::rooster->name => 'Coq',
|
||||
];
|
||||
|
||||
/**
|
||||
* Pictures paths.
|
||||
*/
|
||||
private const PICTURES = [
|
||||
self::chicken->name => 'resources/assets/images/pictos/chicken.jpg',
|
||||
self::turkey->name => 'resources/assets/images/pictos/turkey.jpg',
|
||||
self::hen->name => 'resources/assets/images/pictos/hen_and_rooster.jpg',
|
||||
self::duck->name => 'resources/assets/images/pictos/duck.jpg',
|
||||
self::rabbit->name => 'resources/assets/images/pictos/rabbit.jpg',
|
||||
self::guinea_fowl->name => 'resources/assets/images/pictos/guinea_fowl.jpg',
|
||||
self::rooster->name => 'resources/assets/images/pictos/hen_and_rooster.jpg',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get picture path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function picture(): string
|
||||
{
|
||||
return self::PICTURES[$this->name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Alt attributes for pictures.
|
||||
*/
|
||||
private const ALTS = [
|
||||
self::chicken->name => 'Pictogramme pour la catégorie \'poulet\'',
|
||||
self::turkey->name => 'Pictogramme pour la catégorie \'dinde\'',
|
||||
self::hen->name => 'Pictogramme pour la catégorie \'poule\'',
|
||||
self::duck->name => 'Pictogramme pour la catégorie \'canard\'',
|
||||
self::rabbit->name => 'Pictogramme pour la catégorie \'lapin\'',
|
||||
self::guinea_fowl->name => 'Pictogramme pour la catégorie \'pintade\'',
|
||||
self::rooster->name => 'Pictogramme pour la catégorie \'coq\'',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get picture alt attribute.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function alt(): string
|
||||
{
|
||||
return self::ALTS[$this->name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Alt attributes for pictures.
|
||||
*/
|
||||
private const TITLES = [
|
||||
self::chicken->name => 'Pictogramme pour la catégorie \'poulet\'',
|
||||
self::turkey->name => 'Pictogramme pour la catégorie \'dinde\'',
|
||||
self::hen->name => 'Pictogramme pour la catégorie \'poule\'',
|
||||
self::duck->name => 'Pictogramme pour la catégorie \'canard\'',
|
||||
self::rabbit->name => 'Pictogramme pour la catégorie \'lapin\'',
|
||||
self::guinea_fowl->name => 'Pictogramme pour la catégorie \'pintade\'',
|
||||
self::rooster->name => 'Pictogramme pour la catégorie \'coq\'',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get picture alt attribute.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function title(): string
|
||||
{
|
||||
return self::TITLES[$this->name];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ enum SliderTypeEnum: int
|
|||
case home = 1;
|
||||
case better_life = 2;
|
||||
case respect_earth = 3;
|
||||
case team = 4;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
|
|
@ -22,6 +21,5 @@ enum SliderTypeEnum: int
|
|||
self::home->name => 'Accueil',
|
||||
self::better_life->name => 'Mieux vivre',
|
||||
self::respect_earth->name => 'Respecter la terre',
|
||||
self::team->name => 'Nous rejoindre',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ enum StaticPageType: int
|
|||
/**
|
||||
* Get the enums for the page which contains sections.
|
||||
*
|
||||
* @return array<int, self>
|
||||
* @return array
|
||||
*/
|
||||
public static function containsSection(): array
|
||||
{
|
||||
|
|
@ -66,7 +66,7 @@ enum StaticPageType: int
|
|||
// @phpcs:enable
|
||||
return match ($this) {
|
||||
self::contact => false,
|
||||
self::legals => true,
|
||||
self::legals => false,
|
||||
self::confidentiality => true,
|
||||
self::home => false,
|
||||
self::unveil => false,
|
||||
|
|
@ -74,25 +74,7 @@ enum StaticPageType: int
|
|||
self::we_commit => false,
|
||||
self::we_move => false,
|
||||
self::we_produce => false,
|
||||
self::we_listen => false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the static page need to fill its 'picture' column ?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function containsBanner(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::unveil,
|
||||
self::we_hire,
|
||||
self::we_commit,
|
||||
self::we_move,
|
||||
self::we_produce,
|
||||
self::we_listen => true,
|
||||
default => false,
|
||||
self::we_listen => true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum StickiesColorEnum: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case primary = 1;
|
||||
case secondary = 2;
|
||||
case tertiary = 3;
|
||||
case quad = 4;
|
||||
case quint = 5;
|
||||
case sixt = 6;
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::primary->name => 'Primary',
|
||||
self::secondary->name => 'Secondary',
|
||||
self::tertiary->name => 'Tertiary',
|
||||
self::quad->name => 'Quad',
|
||||
self::quint->name => 'Quint',
|
||||
self::sixt->name => 'Sixt',
|
||||
];
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ enum PictoEnum: int
|
|||
* Pictures paths.
|
||||
*/
|
||||
private const PICTURES = [
|
||||
self::none->name => 'resources/assets/images/pictos/none.jpg',
|
||||
self::none->name => '',
|
||||
self::danger->name => 'resources/assets/images/pictos/danger.png',
|
||||
self::respect_earth->name => 'resources/assets/images/pictos/respect_earth.png',
|
||||
self::breeding->name => 'resources/assets/images/pictos/breeding.png',
|
||||
|
|
@ -42,7 +42,7 @@ enum PictoEnum: int
|
|||
];
|
||||
|
||||
/**
|
||||
* Get picture path.
|
||||
* Get picture path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
@ -55,7 +55,7 @@ enum PictoEnum: int
|
|||
* Alt attributes for pictures.
|
||||
*/
|
||||
private const ALTS = [
|
||||
self::none->name => 'Logo Volena',
|
||||
self::none->name => '',
|
||||
self::danger->name => 'Pictogramme pour la catégorie \'Danger\'',
|
||||
self::respect_earth->name => 'Pictogramme pour la catégorie \'Respecter la terre\'',
|
||||
self::breeding->name => 'Pictogramme pour la catégorie \'Elever durablement\'',
|
||||
|
|
@ -64,7 +64,7 @@ enum PictoEnum: int
|
|||
];
|
||||
|
||||
/**
|
||||
* Get picture alt attribute.
|
||||
* Get picture alt attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
@ -78,7 +78,7 @@ enum PictoEnum: int
|
|||
* Alt attributes for pictures.
|
||||
*/
|
||||
private const TITLES = [
|
||||
self::none->name => 'Logo Volena',
|
||||
self::none->name => '',
|
||||
self::danger->name => 'Pictogramme pour la catégorie \'Danger\'',
|
||||
self::respect_earth->name => 'Pictogramme pour la catégorie \'Respecter la terre\'',
|
||||
self::breeding->name => 'Pictogramme pour la catégorie \'Elever durablement\'',
|
||||
|
|
@ -87,7 +87,7 @@ enum PictoEnum: int
|
|||
];
|
||||
|
||||
/**
|
||||
* Get picture alt attribute.
|
||||
* Get picture alt attribute
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -29,9 +29,6 @@ enum TypeEnum: int
|
|||
self::hire->name => 'On Embauche',
|
||||
];
|
||||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
private const COLORS = [
|
||||
self::breeding->name => 'tertiary',
|
||||
self::better_life->name => 'quad',
|
||||
|
|
@ -42,7 +39,7 @@ enum TypeEnum: int
|
|||
];
|
||||
|
||||
/**
|
||||
* Get color name.
|
||||
* Get color name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class ActivityLogController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\ActivityLog> $query */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
$query = ActivityLog::query()->with('user');
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -55,7 +55,6 @@ class ActivityLogController extends Controller
|
|||
*/
|
||||
public function show(ActivityLog $activity_log): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Model $targetModelClass */
|
||||
$targetModelClass = $activity_log->model_class;
|
||||
$targetModel = $activity_log->model_class::where(
|
||||
(new $targetModelClass())->getRouteKeyName(),
|
||||
|
|
|
|||
|
|
@ -1,194 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Aisles\StoreAisleRequest;
|
||||
use App\Http\Requests\Bo\Aisles\UpdateAisleRequest;
|
||||
use App\Models\Aisle;
|
||||
use App\Models\Network;
|
||||
use App\Traits\Controllers\UpdateModelOrder;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class AisleController extends Controller
|
||||
{
|
||||
use UpdateModelOrder;
|
||||
use UpdateModelPublished;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Aisle::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<\App\Models\Aisle> $aisleModels */
|
||||
$aisleModels = Aisle::query()->with('network');
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\Network> $networkModels */
|
||||
$networkModels = Network::query()->where('published', true)->get();
|
||||
|
||||
$selectedNetwork = intval($request->network);
|
||||
|
||||
$aisleModels = $aisleModels->when($selectedNetwork, function ($query) use ($selectedNetwork) {
|
||||
$query->where('network_id', $selectedNetwork);
|
||||
});
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$aisleModels,
|
||||
$search,
|
||||
null,
|
||||
'name',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
Str::ucfirst(trans('validation.attributes.name')),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($aisleModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$aisleModels = $this->paginate($aisleModels);
|
||||
|
||||
return view(
|
||||
'bo.pages.aisles.index',
|
||||
compact(
|
||||
'aisleModels',
|
||||
'networkModels',
|
||||
'selectedNetwork',
|
||||
'search',
|
||||
'searchFields'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Aisle $aisle
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Aisle $aisle): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$networkModels = Network::all();
|
||||
|
||||
return view('bo.pages.aisles.create', [
|
||||
'aisleModel' => $aisle,
|
||||
'networkModels' => $networkModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Aisles\StoreAisleRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreAisleRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$aisle = new Aisle();
|
||||
$aisle->fill($request->validated());
|
||||
|
||||
if ($aisle->saveOrFail()) {
|
||||
return redirect()->route('bo.aisles.edit', $aisle)
|
||||
->with('success', trans('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans('models.classes.aisle'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(trans('models.classes.aisle'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Aisle $aisle
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Aisle $aisle): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$networkModels = Network::all();
|
||||
|
||||
return view('bo.pages.aisles.edit', [
|
||||
'aisleModel' => $aisle,
|
||||
'networkModels' => $networkModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Aisles\UpdateAisleRequest $request
|
||||
* @param \App\Models\Aisle $aisle
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateAisleRequest $request, Aisle $aisle): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $aisle) {
|
||||
$aisle->fill($request->validated());
|
||||
|
||||
if ($aisle->saveOrFail()) {
|
||||
return redirect()->route('bo.aisles.edit', $aisle)
|
||||
->with('success', trans('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(trans('models.classes.aisle'))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.aisles.edit', $aisle)
|
||||
->with('error', trans('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans('models.classes.aisle'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Aisle $aisle
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Aisle $aisle): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($aisle) {
|
||||
if ($aisle->deleteOrFail()) {
|
||||
return redirect()->route('bo.aisles.index')
|
||||
->with('success', trans('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(trans('models.classes.aisle'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(trans('models.classes.aisle'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Aisle $aisle
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Aisle $aisle): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($aisle->replicate());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,176 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Brands\StoreBrandRequest;
|
||||
use App\Http\Requests\Bo\Brands\UpdateBrandRequest;
|
||||
use App\Models\Aisle;
|
||||
use App\Models\Brand;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class BrandController extends Controller
|
||||
{
|
||||
use UpdateModelPublished;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Brand::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<\App\Models\Brand> $brandModels */
|
||||
$brandModels = Brand::query()->with('aisle');
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$brandModels,
|
||||
$search,
|
||||
null,
|
||||
'name',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
Str::ucfirst(trans('validation.attributes.name')),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($brandModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$brandModels = $this->paginate($brandModels);
|
||||
|
||||
return view('bo.pages.brands.index', compact('brandModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Brand $brand
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Brand $brand): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$aisleModels = Aisle::all();
|
||||
|
||||
return view('bo.pages.brands.create', [
|
||||
'brandModel' => $brand,
|
||||
'aisleModels' => $aisleModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Brands\StoreBrandRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreBrandRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$brand = new Brand();
|
||||
$brand->fill($request->validated());
|
||||
|
||||
if ($brand->saveOrFail()) {
|
||||
return redirect()->route('bo.brands.edit', $brand)
|
||||
->with('success', trans('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans('models.classes.brand'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(trans('models.classes.brand'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Brand $brand
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Brand $brand): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$aisleModels = Aisle::all();
|
||||
|
||||
return view('bo.pages.brands.edit', [
|
||||
'brandModel' => $brand,
|
||||
'aisleModels' => $aisleModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Brands\UpdateBrandRequest $request
|
||||
* @param \App\Models\Brand $brand
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateBrandRequest $request, Brand $brand): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $brand) {
|
||||
$brand->fill($request->validated());
|
||||
|
||||
if ($brand->saveOrFail()) {
|
||||
return redirect()->route('bo.brands.edit', $brand)
|
||||
->with('success', trans('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(trans('models.classes.brand'))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.brands.edit', $brand)
|
||||
->with('error', trans('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans('models.classes.brand'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Brand $brand
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Brand $brand): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($brand) {
|
||||
if ($brand->deleteOrFail()) {
|
||||
return redirect()->route('bo.brands.index')
|
||||
->with('success', trans('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(trans('models.classes.brand'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(trans('models.classes.brand'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Brand $brand
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Brand $brand): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($brand->replicate());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,228 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Carousels\StoreCarouselRequest;
|
||||
use App\Http\Requests\Bo\Carousels\UpdateCarouselRequest;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Carousel;
|
||||
use App\Models\Section;
|
||||
use App\Traits\Controllers\UpdateModelOrder;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CarouselController extends Controller
|
||||
{
|
||||
use UpdateModelOrder;
|
||||
use UpdateModelPublished;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Carousel::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<\App\Models\Carousel> $carouselModels */
|
||||
$carouselModels = Carousel::query()->with('section');
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\Section> $sectionModels */
|
||||
$sectionModels = Section::query()->whereHas('carousels')->get();
|
||||
|
||||
$selectedSection = intval($request->section);
|
||||
|
||||
$carouselModels = $carouselModels->when($selectedSection, function ($query) use ($selectedSection) {
|
||||
$query->where('section_id', $selectedSection);
|
||||
});
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$carouselModels,
|
||||
$search,
|
||||
null,
|
||||
'title',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
Str::ucFirst(trans('validation.attributes.title')),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($carouselModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$carouselModels = $this->paginate($carouselModels);
|
||||
|
||||
return view('bo.pages.carousels.index', compact(
|
||||
'carouselModels',
|
||||
'sectionModels',
|
||||
'selectedSection',
|
||||
'search',
|
||||
'searchFields'
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Carousel $carousel
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Carousel $carousel): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$sectionModels = Section::all();
|
||||
|
||||
return view('bo.pages.carousels.create', [
|
||||
'carouselModel' => $carousel,
|
||||
'sectionModels' => $sectionModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Carousels\StoreCarouselRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreCarouselRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$carousel = new Carousel();
|
||||
$carousel->fill($request->validated());
|
||||
|
||||
if (!Arr::exists($request->validated(), 'media')) {
|
||||
$carousel->media = [];
|
||||
}
|
||||
|
||||
// Set the new pictures files in the pictures array.
|
||||
collect($request->only(['media.pictures.*.path']))
|
||||
->each(
|
||||
function (mixed $value, string $attribute) use ($carousel) {
|
||||
foreach ($value['pictures']['*']['path'] as $index => $file) {
|
||||
if ($file instanceof \Illuminate\Http\UploadedFile) {
|
||||
$carousel->setAttribute(
|
||||
"{$attribute}->pictures->{$index}->path",
|
||||
FileStorageHelper::storeFile($carousel, $file, true)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if ($carousel->saveOrFail()) {
|
||||
return redirect()->route('bo.carousels.edit', $carousel)
|
||||
->with('success', trans('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.carousel', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.carousel', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Carousel $carousel
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Carousel $carousel): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$sectionModels = Section::all();
|
||||
|
||||
return view('bo.pages.carousels.edit', [
|
||||
'carouselModel' => $carousel,
|
||||
'sectionModels' => $sectionModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Carousels\UpdateCarouselRequest $request
|
||||
* @param \App\Models\Carousel $carousel
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateCarouselRequest $request, Carousel $carousel): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $carousel) {
|
||||
$carousel->fill($request->validated());
|
||||
if (!Arr::exists($request->validated(), 'media')) {
|
||||
$carousel->media = [];
|
||||
}
|
||||
|
||||
// Set the new pictures files in the pictures array.
|
||||
collect($request->only(['media.pictures.*.path']))
|
||||
->each(
|
||||
function (mixed $value, string $attribute) use ($carousel) {
|
||||
foreach ($value['pictures']['*']['path'] as $index => $file) {
|
||||
if ($file instanceof \Illuminate\Http\UploadedFile) {
|
||||
$carousel->setAttribute(
|
||||
"{$attribute}->pictures->{$index}->path",
|
||||
FileStorageHelper::storeFile($carousel, $file, true)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
if ($carousel->saveOrFail()) {
|
||||
return redirect()->route('bo.carousels.edit', $carousel)
|
||||
->with('success', trans('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.carousel', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.carousels.edit', $carousel)
|
||||
->with('error', trans('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.carousel', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Carousel $carousel
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Carousel $carousel): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if ($carousel->deleteOrFail()) {
|
||||
return redirect()->route('bo.carousels.index')
|
||||
->with('success', trans('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.carousel', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.carousel', 1))
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Carousel $carousel
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Carousel $carousel): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($carousel->replicate());
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ use App\Http\Controllers\Controller;
|
|||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* Dashboard Page.
|
||||
* Dashboard Page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class HistoricalMilestoneController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\HistoricalMilestone> $historicalMilestoneModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $historicalMilestoneModels */
|
||||
$historicalMilestoneModels = HistoricalMilestone::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class JobVideoController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\JobVideo> $jobVideoModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $jobVideoModels */
|
||||
$jobVideoModels = JobVideo::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ class LogoController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\Logo> $logoModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $logoModels */
|
||||
$logoModels = Logo::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$logoModels,
|
||||
|
|
|
|||
|
|
@ -1,171 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Networks\StoreNetworkRequest;
|
||||
use App\Http\Requests\Bo\Networks\UpdateNetworkRequest;
|
||||
use App\Models\Network;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class NetworkController extends Controller
|
||||
{
|
||||
use ChangesModelOrder;
|
||||
use UpdateModelPublished;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Network::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<\App\Models\Network> $networkModels */
|
||||
$networkModels = Network::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$networkModels,
|
||||
$search,
|
||||
null,
|
||||
'name',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
Str::ucfirst(trans('validation.attributes.name')),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($networkModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$networkModels = $this->paginate($networkModels);
|
||||
|
||||
return view('bo.pages.networks.index', compact('networkModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Network $network
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Network $network): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.networks.create', [
|
||||
'networkModel' => $network,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Networks\StoreNetworkRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreNetworkRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$network = new Network();
|
||||
$network->fill($request->validated());
|
||||
|
||||
if ($network->saveOrFail()) {
|
||||
return redirect()->route('bo.networks.edit', $network)
|
||||
->with('success', trans('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.network', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.network', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Network $network
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Network $network): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.networks.edit', [
|
||||
'networkModel' => $network,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Networks\UpdateNetworkRequest $request
|
||||
* @param \App\Models\Network $network
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateNetworkRequest $request, Network $network): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $network) {
|
||||
$network->fill($request->validated());
|
||||
|
||||
if ($network->saveOrFail()) {
|
||||
return redirect()->route('bo.networks.edit', $network)
|
||||
->with('success', trans('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.network', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.networks.edit', $network)
|
||||
->with('error', trans('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.network', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Network $network
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Network $network): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($network) {
|
||||
if ($network->deleteOrFail()) {
|
||||
return redirect()->route('bo.networks.index')
|
||||
->with('success', trans('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.network', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.network', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Network $network
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Network $network): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($network->replicate());
|
||||
}
|
||||
}
|
||||
|
|
@ -33,11 +33,11 @@ class NewsController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\News> $newsModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $newsModels */
|
||||
$newsModels = News::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$newsModels,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use App\Http\Controllers\Controller;
|
|||
use App\Http\Requests\Bo\Sections\UpdateSectionRequest;
|
||||
use App\Models\Section;
|
||||
use App\Models\StaticPage;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -30,7 +29,7 @@ class SectionController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\Section> $query */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
$query = Section::query()->with('page');
|
||||
|
||||
// Filter by related page if requested.
|
||||
|
|
@ -49,7 +48,7 @@ class SectionController extends Controller
|
|||
}
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$query,
|
||||
|
|
@ -89,18 +88,14 @@ class SectionController extends Controller
|
|||
* @param \App\Models\Section $section
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateSectionRequest $request, Section $section): RedirectResponse
|
||||
public function update(UpdateSectionRequest $request, Section $section): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $section) {
|
||||
$encoded = json_encode($section->toArray());
|
||||
if ($encoded === false) {
|
||||
return redirect()->back()->with('error', trans('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans('models.classes.section'))
|
||||
]));
|
||||
}
|
||||
/** @var array<string, mixed> $data */
|
||||
$data = json_decode($encoded, true);
|
||||
$section->fill(array_replace_recursive($data, $request->validated()));
|
||||
$section->fill(array_replace_recursive(
|
||||
\json_decode(\json_encode($section->toArray()), true),
|
||||
$request->validated()
|
||||
));
|
||||
|
||||
|
||||
if ($section->saveOrFail()) {
|
||||
return redirect()->route('bo.sections.edit', $section)
|
||||
|
|
@ -114,38 +109,4 @@ class SectionController extends Controller
|
|||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Section add PartPiece
|
||||
*
|
||||
* @param \App\Models\Section $section
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function addPartPiece(Section $section): RedirectResponse
|
||||
{
|
||||
$section->addPartPiece();
|
||||
$section->saveOrFail();
|
||||
return response()->redirectToRoute('bo.sections.edit', $section)
|
||||
->with('success', trans('Partie ajouté'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Section remove PartPiece
|
||||
*
|
||||
* @param \App\Models\Section $section
|
||||
* @param integer $index
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function removePartPiece(Section $section, int $index): RedirectResponse
|
||||
{
|
||||
$count = $section->removePartPiece($index);
|
||||
$section->saveOrFail();
|
||||
$response = response()->redirectToRoute('bo.sections.edit', $section);
|
||||
if ($count) {
|
||||
$response->with('error', trans('Partie enlevé'));
|
||||
} else {
|
||||
$response->with('info', trans('Aucune partie enlevé'));
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,23 +32,25 @@ class SiteController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\Site> $siteModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $siteModels */
|
||||
$siteModels = Site::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$siteModels,
|
||||
$search,
|
||||
null,
|
||||
'name',
|
||||
'description',
|
||||
'title',
|
||||
'introduction',
|
||||
'content',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
Str::ucfirst(trans('validation.attributes.name')),
|
||||
trans('validation.attributes.description'),
|
||||
Str::ucfirst(trans('validation.attributes.title')),
|
||||
trans('validation.custom.introduction'),
|
||||
trans('validation.attributes.content'),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
|
|
@ -90,9 +92,7 @@ class SiteController extends Controller
|
|||
$site->fill($request->safe()->except(['logos']));
|
||||
|
||||
if ($site->saveOrFail()) {
|
||||
/** @var array<int, array<string, mixed>> $logos */
|
||||
$logos = $request->validated('logos') ?? [];
|
||||
$site->logos()->attach(collect($logos)->pluck('id'));
|
||||
$site->logos()->attach(collect($request->validated('logos'))->pluck('id'));
|
||||
return redirect()->route('bo.sites.edit', $site)
|
||||
->with('success', trans('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans('models.classes.site'))
|
||||
|
|
@ -131,10 +131,8 @@ class SiteController extends Controller
|
|||
public function update(UpdateSiteRequest $request, Site $site): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $site) {
|
||||
/** @var array<int, array<string, mixed>> $logos */
|
||||
$logos = $request->validated('logos') ?? [];
|
||||
$site->logos()->sync(collect($logos)->pluck('id'));
|
||||
$site->fill($request->safe()->except(['logos']));
|
||||
$site->logos()->sync(collect($request->validated('logos'))->pluck('id'));
|
||||
|
||||
if ($site->saveOrFail()) {
|
||||
return redirect()->route('bo.sites.edit', $site)
|
||||
|
|
|
|||
|
|
@ -28,17 +28,17 @@ class SlideController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\Slide> $slideModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $slideModels */
|
||||
$slideModels = Slide::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$slideModels,
|
||||
$search,
|
||||
null,
|
||||
'type',
|
||||
'slider',
|
||||
'title',
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ class StaticPageController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\StaticPage> $query */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
$query = StaticPage::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$query,
|
||||
|
|
|
|||
|
|
@ -1,157 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Stickies\StoreStickyRequest;
|
||||
use App\Http\Requests\Bo\Stickies\UpdateStickyRequest;
|
||||
use App\Models\Sticky;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class StickyController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->authorizeResource(Sticky::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<\App\Models\Sticky> $stickyModels */
|
||||
$stickyModels = Sticky::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$stickyModels,
|
||||
$search,
|
||||
null,
|
||||
'title',
|
||||
);
|
||||
}
|
||||
$searchFields = \implode(', ', [
|
||||
Str::ucfirst(trans('validation.attributes.title')),
|
||||
]);
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($stickyModels);
|
||||
|
||||
/** Custom pagination */
|
||||
$stickyModels = $this->paginate($stickyModels);
|
||||
|
||||
return view('bo.pages.stickies.index', compact('stickyModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Sticky $sticky): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.stickies.create', ['stickyModel' => $sticky]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Stickies\StoreStickyRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreStickyRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$sticky = new Sticky();
|
||||
|
||||
if ($sticky->fill($request->validated())->saveOrFail()) {
|
||||
return redirect()->route('bo.stickies.edit', $sticky)
|
||||
->with('success', trans('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Sticky $sticky): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.stickies.edit', ['stickyModel' => $sticky]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Stickies\UpdateStickyRequest $request
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateStickyRequest $request, Sticky $sticky): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $sticky) {
|
||||
if ($sticky->fill($request->validated())->saveOrFail()) {
|
||||
return redirect()->route('bo.stickies.edit', $sticky)
|
||||
->with('success', trans('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.stickies.edit', $sticky)
|
||||
->with('error', trans('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Sticky $sticky): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if ($sticky->deleteOrFail()) {
|
||||
return redirect()->route('bo.stickies.index')
|
||||
->with('success', trans('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', trans('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.sticky', 0))
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\Sticky $sticky
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(Sticky $sticky): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($sticky->replicate());
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,6 @@ use App\Models\News;
|
|||
use App\Models\Strip;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
|
|
@ -33,11 +32,11 @@ class StripController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\Strip> $stripModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $stripModels */
|
||||
$stripModels = Strip::query()->with('news');
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$stripModels,
|
||||
|
|
@ -132,15 +131,6 @@ class StripController extends Controller
|
|||
if ($request->news_id === null) {
|
||||
$strip->news()->dissociate();
|
||||
}
|
||||
|
||||
if (!Arr::exists($request->validated(), 'picture')) {
|
||||
$strip->picture = null;
|
||||
$strip->picture_alt = null;
|
||||
$strip->picture_title = null;
|
||||
} elseif (!Arr::exists($request->validated(), 'picto')) {
|
||||
$strip->picto = null;
|
||||
}
|
||||
|
||||
if ($strip->saveOrFail()) {
|
||||
return redirect()->route('bo.strips.edit', $strip)
|
||||
->with('success', trans('crud.messages.has_been_updated', [
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ class TestimonialController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\Testimonial> $testimonialModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $testimonialModels */
|
||||
$testimonialModels = Testimonial::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$testimonialModels,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace App\Http\Controllers\Bo;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\UploadFileRequest;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Models\Section;
|
||||
|
||||
class UploadController extends Controller
|
||||
{
|
||||
|
|
@ -18,19 +18,10 @@ class UploadController extends Controller
|
|||
*/
|
||||
public function uploadFile(UploadFileRequest $request)
|
||||
{
|
||||
$modelClass = "App\\Models\\$request->folder";
|
||||
|
||||
if (!class_exists($modelClass) && !is_subclass_of($modelClass, Model::class)) {
|
||||
return response()->json(['error' => 'Invalid model class'], 404);
|
||||
}
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Model $model */
|
||||
$model = new $modelClass();
|
||||
|
||||
/** @var \Illuminate\Http\UploadedFile $image */
|
||||
$image = $request->file('upload');
|
||||
$image = $request->upload;
|
||||
|
||||
$path = FileStorageHelper::storeFile($model, $image, true);
|
||||
$path = FileStorageHelper::storeFile(new Section(), $image, true);
|
||||
|
||||
return response()->json([
|
||||
'url' => "/{$path}"
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ class UserController extends Controller
|
|||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder<\App\Models\User> $userModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $userModels */
|
||||
$userModels = User::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->input('search');
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$userModels,
|
||||
|
|
@ -145,7 +145,7 @@ class UserController extends Controller
|
|||
{
|
||||
/** @var array<string,string> */
|
||||
$previousQueries = [];
|
||||
\parse_str((string) \parse_url(url()->previous(), \PHP_URL_QUERY), $previousQueries);
|
||||
\parse_str(\parse_url(url()->previous(), \PHP_URL_QUERY), $previousQueries);
|
||||
if ($user->deleteOrFail()) {
|
||||
return redirect()->route('bo.users.index', $previousQueries)
|
||||
->with('success', trans('crud.messages.has_been_deleted', [
|
||||
|
|
|
|||
|
|
@ -24,19 +24,18 @@ class Controller extends BaseController
|
|||
* Build Search query on specified fields
|
||||
* splitting search into words or using whole sentence
|
||||
*
|
||||
* @template TModel of \Illuminate\Database\Eloquent\Model
|
||||
* @param \Illuminate\Database\Eloquent\Builder<TModel> $query The eloquent query builder.
|
||||
* @param string $search The searched string.
|
||||
* @param callable|null $searchQuery The query string.
|
||||
* @param string ...$fields Either a simple array or a string
|
||||
* in case of a string the two fields
|
||||
* would be concatenate to make the search.
|
||||
* @return \Illuminate\Database\Eloquent\Builder<TModel>
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query The eloquent query builder.
|
||||
* @param string $search The query string.
|
||||
* @param callable $searchQuery The query string.
|
||||
* @param string ...$fields Either a simple array or a string
|
||||
* in case of a string the two fields
|
||||
* would be concatenate to make the search.
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function searchQuery(
|
||||
Builder $query,
|
||||
string $search,
|
||||
callable|null $searchQuery = null,
|
||||
callable $searchQuery = null,
|
||||
string ...$fields
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
if (count($fields)) {
|
||||
|
|
@ -62,16 +61,15 @@ class Controller extends BaseController
|
|||
/**
|
||||
* Build query search on all fields
|
||||
*
|
||||
* @template TModel of \Illuminate\Database\Eloquent\Model
|
||||
* @param \Illuminate\Database\Eloquent\Builder<TModel> $query
|
||||
* @param string $search
|
||||
* @param array<int|string, string|array<int, string>> $fields
|
||||
* @return \Illuminate\Database\Eloquent\Builder<TModel>
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $search
|
||||
* @param array $fields
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
private function searchOnFields(
|
||||
Builder $query,
|
||||
string $search,
|
||||
array $fields,
|
||||
array $fields
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
$table = $query->getModel()->getTable();
|
||||
foreach ($fields as $field) {
|
||||
|
|
@ -117,17 +115,13 @@ class Controller extends BaseController
|
|||
/**
|
||||
* Get the search value (on string or Enum).
|
||||
*
|
||||
* @template TModel of \Illuminate\Database\Eloquent\Model
|
||||
* @param \Illuminate\Database\Eloquent\Builder<TModel> $query
|
||||
* @param string $search
|
||||
* @param string $field
|
||||
* @return string|array<int, mixed>
|
||||
* @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 {
|
||||
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.
|
||||
|
|
@ -137,8 +131,8 @@ class Controller extends BaseController
|
|||
/** @var \App\Traits\Enums $cast */
|
||||
// @phpstan-ignore-next-line
|
||||
$cases = collect($cast::toArray());
|
||||
$enum = $cases->filter(function ($item) use ($search): bool {
|
||||
return preg_match('/' . Str::lower($search) . '/', Str::lower($item->label)) === 1;
|
||||
$enum = $cases->filter(function ($item) use ($search) {
|
||||
return preg_match('/' . Str::lower($search) . '/', Str::lower($item->label));
|
||||
});
|
||||
return $enum->toArray();
|
||||
} else {
|
||||
|
|
@ -149,15 +143,12 @@ class Controller extends BaseController
|
|||
/**
|
||||
* Sort columns with a query.
|
||||
*
|
||||
* @template TModel of \Illuminate\Database\Eloquent\Model
|
||||
* @param \Illuminate\Database\Eloquent\Builder<TModel> $query
|
||||
* @param array<int, string> $ignore
|
||||
* @return \Illuminate\Database\Eloquent\Builder<TModel>
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param array $ignore
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function sortQuery(
|
||||
Builder $query,
|
||||
array $ignore = [],
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
protected function sortQuery(Builder $query, array $ignore = []): \Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
$rName = request()->route()->getName();
|
||||
$table = $query->getModel()->getTable();
|
||||
if (request()->input('sort_col')) {
|
||||
|
|
@ -203,14 +194,13 @@ class Controller extends BaseController
|
|||
/**
|
||||
* Customize pagination with cache or config (default).
|
||||
*
|
||||
* @template TModel of \Illuminate\Database\Eloquent\Model
|
||||
* @param \Illuminate\Database\Eloquent\Builder<TModel> $query
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \App\Enums\Pagination\ItemsPerPaginationEnum|null $pagination
|
||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator<TModel>
|
||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
protected function paginate(
|
||||
Builder $query,
|
||||
ItemsPerPaginationEnum|null $pagination = null
|
||||
ItemsPerPaginationEnum $pagination = null
|
||||
): \Illuminate\Contracts\Pagination\LengthAwarePaginator {
|
||||
$currentRoutePath = Str::slug(request()->route()->getName());
|
||||
$cacheKey = "pagination.{$currentRoutePath}";
|
||||
|
|
@ -218,7 +208,7 @@ class Controller extends BaseController
|
|||
$pagination = ToolboxHelper::getValidatedEnum(
|
||||
Cache::get($cacheKey, $pagination->value()),
|
||||
'pagination',
|
||||
ItemsPerPaginationEnum::class,
|
||||
'\App\Enums\Pagination\ItemsPerPaginationEnum',
|
||||
);
|
||||
if (Cache::get($cacheKey) !== $pagination) {
|
||||
Cache::put($cacheKey, $pagination);
|
||||
|
|
@ -238,7 +228,7 @@ class Controller extends BaseController
|
|||
$theme = ToolboxHelper::getValidatedEnum(
|
||||
$request->theme ?: Cache::get('theme', BootstrapThemeEnum::light->value()),
|
||||
'theme',
|
||||
BootstrapThemeEnum::class,
|
||||
'\App\Http\Controllers\BootstrapThemeEnum',
|
||||
);
|
||||
if (Cache::get("theme") !== $theme) {
|
||||
Cache::put("theme", $theme);
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Network;
|
||||
|
||||
class NetworkController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Network $network
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Network $network): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$network->load(['aisles', 'aisles.brands']);
|
||||
$networkModels = Network::query()
|
||||
->whereNot('id', $network->id)
|
||||
->where('published', true)
|
||||
->orderBy('order')
|
||||
->get();
|
||||
|
||||
return view('fo.pages.networks.show', [
|
||||
'networkModel' => $network,
|
||||
'networkModels' => $networkModels,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -20,13 +20,10 @@ class NewsController extends Controller
|
|||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::we_move)->first();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get();
|
||||
$newsModels = News::query()
|
||||
->where('published', true)
|
||||
->orderBy('displayed_date', 'DESC')
|
||||
->simplePaginate(4)
|
||||
->fragment('corpo');
|
||||
$newsModels = News::query()->where('published', true)->orderBy('publish_at', 'DESC')->simplePaginate(4);
|
||||
$lifeSection = $sectionModels->where('section', PageSectionEnum::move_life)->first();
|
||||
$commitmentSection = $sectionModels->where('section', PageSectionEnum::move_commitments)->first();
|
||||
|
||||
return view('fo.pages.news.index', \compact(
|
||||
'staticPageModel',
|
||||
'sectionModels',
|
||||
|
|
@ -45,7 +42,10 @@ class NewsController extends Controller
|
|||
public function show(News $news): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Get only id from published news.
|
||||
// @phpcs:disabled
|
||||
// @phpstan-ignore-next-line
|
||||
$publishedNews = News::query()->where('published', true)->orderBy('publish_at', 'DESC')->get()->pluck('id');
|
||||
// @phpcs:enable
|
||||
// Search the position of the current news id.
|
||||
$positionId = \array_search($news->id, $publishedNews->toArray());
|
||||
// Check if it's the last position.
|
||||
|
|
@ -57,10 +57,6 @@ class NewsController extends Controller
|
|||
// Find the next news from the id.
|
||||
$prevNews = News::query()->where('id', $publishedNews[$prevPositionId])->firstOrFail();
|
||||
|
||||
return view('fo.pages.news.show', [
|
||||
'news' => $news,
|
||||
'nextNews' => $nextNews,
|
||||
'prevNews' => $prevNews,
|
||||
]);
|
||||
return view('fo.pages.news.show', \compact('news', 'nextNews', 'prevNews'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,27 +6,21 @@ use App\Enums\Listen\ObjectEnum;
|
|||
use App\Enums\Sections\PageSectionEnum;
|
||||
use App\Enums\Slides\SliderTypeEnum;
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Enums\StickiesColorEnum;
|
||||
use App\Enums\Testimonials\TypeEnum;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\ListenFormRequest;
|
||||
use App\Mail\SendConfirmationMail;
|
||||
use App\Mail\SendContactMail;
|
||||
use App\Models\Carousel;
|
||||
use App\Models\HistoricalMilestone;
|
||||
use App\Models\JobVideo;
|
||||
use App\Models\Network;
|
||||
use App\Models\News;
|
||||
use App\Models\Section;
|
||||
use App\Models\Site;
|
||||
use App\Models\Slide;
|
||||
use App\Models\StaticPage;
|
||||
use App\Models\Sticky;
|
||||
use App\Models\Strip;
|
||||
use App\Models\Testimonial;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class StaticPageController extends Controller
|
||||
{
|
||||
|
|
@ -39,18 +33,13 @@ class StaticPageController extends Controller
|
|||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::home)->first();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get();
|
||||
$stripModels = Strip::query()
|
||||
->where('published', true)
|
||||
$stripModels = Strip::query()->where('published', true)
|
||||
->orderBy('publish_at', 'DESC')
|
||||
->limit(6)
|
||||
->with('news')
|
||||
->whereHas('news', function (Builder $query) {
|
||||
$query->where('published', true);
|
||||
})
|
||||
->get();
|
||||
$newsModels = News::query()
|
||||
->where('published', true)
|
||||
->orderBy('displayed_date', 'DESC')
|
||||
$newsModels = News::query()->where('published', true)
|
||||
->orderBy('publish_at', 'DESC')
|
||||
->limit(4)
|
||||
->get();
|
||||
$slideModels = Slide::query()->where('type', SliderTypeEnum::home)->get();
|
||||
|
|
@ -58,7 +47,6 @@ class StaticPageController extends Controller
|
|||
$ambitionSection = $sectionModels->where('section', PageSectionEnum::home_ambition)->first();
|
||||
$teamSection = $sectionModels->where('section', PageSectionEnum::home_team)->first();
|
||||
$lifeSection = $sectionModels->where('section', PageSectionEnum::home_life)->first();
|
||||
$slideTeams = Slide::query()->where('type', SliderTypeEnum::team)->get();
|
||||
|
||||
return view('fo.pages.home', compact(
|
||||
'staticPageModel',
|
||||
|
|
@ -70,7 +58,6 @@ class StaticPageController extends Controller
|
|||
'ambitionSection',
|
||||
'teamSection',
|
||||
'lifeSection',
|
||||
'slideTeams',
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -82,46 +69,27 @@ class StaticPageController extends Controller
|
|||
public function unveil(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::unveil)->first();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->getKey())->get();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get();
|
||||
$historicalMilestoneModels = HistoricalMilestone::query()->orderBy('year', 'ASC')->get();
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<array-key,\App\Models\Site> */
|
||||
$siteModelList = Site::query()->orderBy('order')->get();
|
||||
$keySection = $sectionModels->where('section', PageSectionEnum::unveil_pole)->first();
|
||||
$missionsSection = $sectionModels->where('section', PageSectionEnum::unveil_missions)->first();
|
||||
$localSection = $sectionModels->where('section', PageSectionEnum::unveil_local)->first();
|
||||
$siteSection = $sectionModels->where('section', PageSectionEnum::unveil_sites)->first();
|
||||
$historySection = $sectionModels->where('section', PageSectionEnum::unveil_history)->first();
|
||||
$commitmentSection = $sectionModels->where('section', PageSectionEnum::unveil_commitments)->first();
|
||||
$navLinks = Sticky::query()->where('type', StaticPageType::unveil)->get();
|
||||
|
||||
$viewBox = null;
|
||||
$initialZoom = null;
|
||||
// * Calcul Viewbox leaflet map ().
|
||||
// Carte page “on se dévoile” : Point central = Laval + rayon = 100 km
|
||||
/** @var \App\Models\Site|null $lavalSite */
|
||||
$lavalSite = $siteModelList->first(fn(Site $site) => Str::contains($site->name, 'Laval'));
|
||||
if ($lavalSite) {
|
||||
$viewBox = (object) [
|
||||
'lat' => $lavalSite->latitude,
|
||||
'lng' => $lavalSite->longitude
|
||||
];
|
||||
$initialZoom = 9;
|
||||
}
|
||||
$siteModel = Site::query()->first();
|
||||
$keySection = $sectionModels->where('section', PageSectionEnum::unveil_pole)->first();
|
||||
$missionsSection = $sectionModels->where('section', PageSectionEnum::unveil_missions)->first();
|
||||
$localSection = $sectionModels->where('section', PageSectionEnum::unveil_local)->first();
|
||||
$siteSection = $sectionModels->where('section', PageSectionEnum::unveil_sites)->first();
|
||||
$historySection = $sectionModels->where('section', PageSectionEnum::unveil_history)->first();
|
||||
$commitmentSection = $sectionModels->where('section', PageSectionEnum::unveil_commitments)->first();
|
||||
|
||||
return view('fo.pages.unveil', compact(
|
||||
'viewBox',
|
||||
'initialZoom',
|
||||
'staticPageModel',
|
||||
'sectionModels',
|
||||
'historicalMilestoneModels',
|
||||
'siteModelList',
|
||||
'siteModel',
|
||||
'keySection',
|
||||
'missionsSection',
|
||||
'localSection',
|
||||
'siteSection',
|
||||
'historySection',
|
||||
'commitmentSection',
|
||||
'navLinks'
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -134,8 +102,8 @@ class StaticPageController extends Controller
|
|||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::we_commit)->first();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get();
|
||||
$slideLifeModels = Slide::query()->where('type', SliderTypeEnum::better_life)->latest()->get();
|
||||
$slideEarthModels = Slide::query()->where('type', SliderTypeEnum::respect_earth)->latest()->get();
|
||||
$slideLifeModels = Slide::query()->where('type', SliderTypeEnum::better_life)->get();
|
||||
$slideEarthModels = Slide::query()->where('type', SliderTypeEnum::respect_earth)->get();
|
||||
$testimonialModels = Testimonial::query()
|
||||
->whereIn('type', [
|
||||
TypeEnum::breeding->value,
|
||||
|
|
@ -151,8 +119,6 @@ class StaticPageController extends Controller
|
|||
$feedSection = $sectionModels->where('section', PageSectionEnum::commit_feed)->first();
|
||||
$testimonialsSection = $sectionModels->where('section', PageSectionEnum::commit_commitments)->first();
|
||||
|
||||
$navLinks = Sticky::query()->where('type', StaticPageType::we_commit)->get();
|
||||
|
||||
return view('fo.pages.commitments', compact(
|
||||
'staticPageModel',
|
||||
'sectionModels',
|
||||
|
|
@ -165,7 +131,6 @@ class StaticPageController extends Controller
|
|||
'earthSection',
|
||||
'feedSection',
|
||||
'testimonialsSection',
|
||||
'navLinks',
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -204,45 +169,35 @@ class StaticPageController extends Controller
|
|||
*/
|
||||
public function produce(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// MODELS.
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::we_produce)->first();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get();
|
||||
$networkModels = Network::query()->where('published', true)->orderBy('order')->get();
|
||||
|
||||
// SECTIONS.
|
||||
$localSection = $sectionModels->where('section', PageSectionEnum::produce_local)->first();
|
||||
$gmsSection = $sectionModels->where('section', PageSectionEnum::produce_gms)->first();
|
||||
$rhdSection = $sectionModels->where('section', PageSectionEnum::produce_rhd)->first();
|
||||
$exportSection = $sectionModels->where('section', PageSectionEnum::produce_export)->first();
|
||||
$qualitySection = $sectionModels->where('section', PageSectionEnum::produce_quality)->first();
|
||||
$networkSection = $sectionModels->where('section', PageSectionEnum::produce_networks)->first();
|
||||
$localSection = $sectionModels->where('section', PageSectionEnum::produce_local)->first();
|
||||
$gmsSection = $sectionModels->where('section', PageSectionEnum::produce_gms)->first();
|
||||
$rhdSection = $sectionModels->where('section', PageSectionEnum::produce_rhd)->first();
|
||||
$exportSection = $sectionModels->where('section', PageSectionEnum::produce_export)->first();
|
||||
$qualitySection = $sectionModels->where('section', PageSectionEnum::produce_quality)->first();
|
||||
|
||||
return view('fo.pages.produce.show', compact(
|
||||
'staticPageModel',
|
||||
'networkModels',
|
||||
'localSection',
|
||||
'gmsSection',
|
||||
'rhdSection',
|
||||
'exportSection',
|
||||
'qualitySection',
|
||||
'networkSection',
|
||||
'qualitySection'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the 'we_listen' page.
|
||||
* This page is used to send a contact form.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function listen(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::we_listen)->first();
|
||||
$sectionModel = Section::query()->where('page_id', $staticPageModel->id)->first();
|
||||
|
||||
return view('fo.pages.listen', compact(
|
||||
'staticPageModel',
|
||||
'sectionModel',
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -255,8 +210,8 @@ class StaticPageController extends Controller
|
|||
public function listenForm(ListenFormRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
Mail::to(config('mail.contact.' . ObjectEnum::make(intval($request->validated()['object']))->name()))
|
||||
->send(new SendContactMail((object) $request->validated()));
|
||||
Mail::to($request->validated()['email'])->send(new SendConfirmationMail((object) $request->validated()));
|
||||
->send(new SendContactMail((object)$request->validated()));
|
||||
Mail::to($request->validated()['email'])->send(new SendConfirmationMail((object)$request->validated()));
|
||||
|
||||
return redirect()->route('fo.listen.show')
|
||||
->with('success', trans(
|
||||
|
|
@ -272,21 +227,15 @@ class StaticPageController extends Controller
|
|||
*/
|
||||
public function hire(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::we_hire)->first();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get();
|
||||
$videoModels = JobVideo::query()->inRandomOrder()->simplePaginate(4);
|
||||
$testimonialModels = Testimonial::query()->where('type', TypeEnum::hire)->get();
|
||||
$compagnyLifeSection = $sectionModels->where('section', PageSectionEnum::hire_life)->first();
|
||||
$formationSection = $sectionModels->where('section', PageSectionEnum::hire_formation)->first();
|
||||
$testimonialSection = $sectionModels->where('section', PageSectionEnum::hire_grow)->first();
|
||||
$paritySection = $sectionModels->where('section', PageSectionEnum::hire_parity)->first();
|
||||
$findSection = $sectionModels->where('section', PageSectionEnum::hire_find)->first();
|
||||
$carouselSectionParity = Carousel::query()
|
||||
->where('section_id', PageSectionEnum::hire_parity)
|
||||
->where('published', true)
|
||||
->orderBy('order')
|
||||
->get();
|
||||
$navLinks = Sticky::query()->where('type', StaticPageType::we_hire)->get();
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::we_hire)->first();
|
||||
$sectionModels = Section::query()->where('page_id', $staticPageModel->id)->get();
|
||||
$videoModels = JobVideo::query()->inRandomOrder()->simplePaginate(4);
|
||||
$testimonialModels = Testimonial::query()->where('type', TypeEnum::hire)->get();
|
||||
$compagnyLifeSection = $sectionModels->where('section', PageSectionEnum::hire_life)->first();
|
||||
$formationSection = $sectionModels->where('section', PageSectionEnum::hire_formation)->first();
|
||||
$testimonialSection = $sectionModels->where('section', PageSectionEnum::hire_grow)->first();
|
||||
$paritySection = $sectionModels->where('section', PageSectionEnum::hire_parity)->first();
|
||||
$findSection = $sectionModels->where('section', PageSectionEnum::hire_find)->first();
|
||||
|
||||
return view('fo.pages.hire', \compact(
|
||||
'staticPageModel',
|
||||
|
|
@ -297,9 +246,7 @@ class StaticPageController extends Controller
|
|||
'formationSection',
|
||||
'testimonialSection',
|
||||
'paritySection',
|
||||
'findSection',
|
||||
'carouselSectionParity',
|
||||
'navLinks'
|
||||
'findSection'
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -311,41 +258,15 @@ class StaticPageController extends Controller
|
|||
*/
|
||||
public function site(Site $site): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<array-key,\App\Models\Site> */
|
||||
$siteModels = Site::query()->orderBy('order')->get();
|
||||
$siteModelList = $siteModels->keyBy('order');
|
||||
|
||||
$nextSiteModel = $siteModelList->where(
|
||||
'order',
|
||||
'>',
|
||||
$site->order
|
||||
)->first();
|
||||
if ($siteModelList->last()->is($site)) {
|
||||
$nextSiteModel = $siteModelList->first();
|
||||
if ($site->order === Site::query()->max('order')) {
|
||||
$nextSiteModel = Site::query()->orderBy('order')->first();
|
||||
} else {
|
||||
$nextSiteModel = Site::query()->orderBy('order')->where('order', '>', $site->order)->first();
|
||||
}
|
||||
|
||||
$viewBox = (object) [
|
||||
'lat' => $site->latitude,
|
||||
'lng' => $site->longitude
|
||||
];
|
||||
$initialZoom = 10;
|
||||
|
||||
// Create datas similar to Sticky model.
|
||||
$navLinks = collect([
|
||||
(object) [
|
||||
'title' => $site->sticky_title,
|
||||
'anchor' => $site->sticky_link,
|
||||
'color' => StickiesColorEnum::quad,
|
||||
],
|
||||
]);
|
||||
|
||||
return view('fo.pages.site', [
|
||||
'siteModelList' => $siteModelList,
|
||||
'siteModel' => $site,
|
||||
'nextSiteModel' => $nextSiteModel,
|
||||
'viewBox' => $viewBox,
|
||||
'initialZoom' => $initialZoom,
|
||||
'navLinks' => $navLinks,
|
||||
'nextSiteModel' => $nextSiteModel
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,11 +39,7 @@ class Kernel extends HttpKernel
|
|||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\SecureHeaders::class
|
||||
],
|
||||
'saml' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class HtmlSanitizer
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|array<int, mixed> ...$params
|
||||
* @param string|array ...$params
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function handle(
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class RedirectIfAuthenticated
|
|||
return \redirect()->route('fo.home.show');
|
||||
case 'backend':
|
||||
if (!$request->routeIs('bo.*')) {
|
||||
continue 2;
|
||||
continue;
|
||||
}
|
||||
return \redirect()->route('bo.dashboard');
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class SecureHeaders
|
|||
* Great starting point would be to go check out @Scott_Helme's:
|
||||
* https://securityheaders.com/
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array
|
||||
*/
|
||||
private $unwantedHeaderList = [
|
||||
'X-Powered-By',
|
||||
|
|
@ -59,10 +59,6 @@ class SecureHeaders
|
|||
'https://yl.s-web.fr'
|
||||
]) . ';',
|
||||
"img-src 'self' data: blob: " . implode(' ', [
|
||||
// * Leaftlet With OpenStreetmaps
|
||||
'https://tile.openstreetmap.org',
|
||||
// * Youtube thumbnails
|
||||
'https://img.youtube.com/vi/',
|
||||
// * VITE DEV
|
||||
config('app.debug') ? "https://{$host}:4443" : '',
|
||||
]) . ';',
|
||||
|
|
@ -70,8 +66,8 @@ class SecureHeaders
|
|||
"frame-src 'self' " . implode(' ', [
|
||||
'https://www.google.com/recaptcha/',
|
||||
'https://recaptcha.google.com/recaptcha/',
|
||||
'https://www.google.com/maps/',
|
||||
'https://www.youtube.com',
|
||||
'https://www.youtube-nocookie.com/embed/',
|
||||
]) . ';',
|
||||
"font-src 'self' data: " . \implode(' ', [
|
||||
// * VITE DEV
|
||||
|
|
@ -112,9 +108,9 @@ class SecureHeaders
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove unwanted headers.
|
||||
* Remove unwanted headers
|
||||
*
|
||||
* @param list<string> $headerList
|
||||
* @param array $headerList
|
||||
* @return void
|
||||
*/
|
||||
private function removeUnwantedHeaders(array $headerList): void
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Aisles;
|
||||
|
||||
use App\Rules\WysiwygLength;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreAisleRequest 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')
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|string|between:3,255',
|
||||
'title' => 'required|string|between:3,255',
|
||||
'text' => [
|
||||
'required',
|
||||
'string',
|
||||
new WysiwygLength(3, 500),
|
||||
],
|
||||
'picture_alt' => 'required|string|between:3,255',
|
||||
'picture_title' => 'required|string|between:3,255',
|
||||
'network_id' => 'required|exists:networks,id',
|
||||
'published' => 'required|boolean',
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 1400, 450, 1400, 450, false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Aisles;
|
||||
|
||||
class UpdateAisleRequest extends StoreAisleRequest
|
||||
{
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Brands;
|
||||
|
||||
use App\Rules\WysiwygLength;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreBrandRequest 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')
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|string|between:3,255',
|
||||
'text' => [
|
||||
'required',
|
||||
'string',
|
||||
new WysiwygLength(3, 500),
|
||||
],
|
||||
'picture_alt' => 'required|string|between:3,255',
|
||||
'picture_title' => 'required|string|between:3,255',
|
||||
'link' => 'nullable|url:https',
|
||||
'aisle_id' => 'required|exists:aisles,id',
|
||||
'published' => 'required|boolean',
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 250, 250, 250, 250, false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Brands;
|
||||
|
||||
class UpdateBrandRequest extends StoreBrandRequest
|
||||
{
|
||||
}
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Carousels;
|
||||
|
||||
use App\Models\Section;
|
||||
use App\Rules\IsMaxChildrenReached;
|
||||
use App\Rules\WysiwygLength;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class StoreCarouselRequest 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
|
||||
{
|
||||
if ($this->input('media.pictures')) {
|
||||
foreach ($this->input('media.pictures') as $index => $pictureArray) {
|
||||
$this->mergePicture("media.pictures.$index.path");
|
||||
}
|
||||
}
|
||||
|
||||
$this->merge([
|
||||
'published' => $this->boolean('published'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'title' => 'required|string|between:3,255',
|
||||
'section_id' => [
|
||||
'required',
|
||||
Rule::exists('sections', 'id'),
|
||||
new IsMaxChildrenReached(new Section(), 'carousels', 5)
|
||||
],
|
||||
'media' => 'required|array',
|
||||
'media.pictures.*.alt' => 'sometimes|string|between:3,255',
|
||||
'media.pictures.*.title' => 'sometimes|string|between:3,255',
|
||||
'media.pictures.*.legend' => [
|
||||
'sometimes',
|
||||
'string',
|
||||
new WysiwygLength(3, 255),
|
||||
],
|
||||
'published' => 'required|boolean',
|
||||
];
|
||||
if ($this->input('media')) {
|
||||
if (Arr::exists($this->input('media'), 'pictures')) {
|
||||
foreach ($this->input('media')['pictures'] as $pictureIndex => $pictureArray) {
|
||||
$rules = array_merge(
|
||||
$rules,
|
||||
[
|
||||
"media.pictures.$pictureIndex.alt" => 'required|string|between:3,255',
|
||||
"media.pictures.$pictureIndex.title" => 'required|string|between:3,255',
|
||||
"media.pictures.$pictureIndex.legend" => [
|
||||
'sometimes',
|
||||
'string',
|
||||
new WysiwygLength(3, 255),
|
||||
],
|
||||
],
|
||||
$this->pictureRules("media.pictures.$pictureIndex.path", 500, 500, 500, 500, false),
|
||||
);
|
||||
}
|
||||
} //end if
|
||||
} //end if
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
$attributes = [
|
||||
'title' => trans('validation.attributes.title'),
|
||||
];
|
||||
if ($this->input('media') && array_key_exists('pictures', $this->input('media'))) {
|
||||
foreach ($this->input('media.pictures') as $index => $pictureArray) {
|
||||
$attributes = array_merge(
|
||||
$attributes,
|
||||
[
|
||||
"media.pictures.$index.alt" => trans(':field :inter:model', [
|
||||
'field' => trans('validation.custom.alt_attribute'),
|
||||
'inter' => trans('validation.custom.of_the.vowel'),
|
||||
'model' => sprintf('%s n°%d', trans('validation.custom.picture'), $index + 1),
|
||||
]),
|
||||
"media.pictures.$index.title" => trans(':field :inter:model', [
|
||||
'field' => trans('validation.custom.title_attribute'),
|
||||
'inter' => trans('validation.custom.of_the.vowel'),
|
||||
'model' => sprintf('%s n°%d', trans('validation.custom.picture'), $index + 1),
|
||||
]),
|
||||
"media.pictures.$index.legend" => trans(':field :inter:model', [
|
||||
'field' => trans('validation.custom.legend'),
|
||||
'inter' => trans('validation.custom.of_the.vowel'),
|
||||
'model' => sprintf('%s n°%d', trans('validation.custom.picture'), $index + 1),
|
||||
]),
|
||||
],
|
||||
);
|
||||
} //end foreach
|
||||
} //end if
|
||||
return $attributes;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Carousels;
|
||||
|
||||
class UpdateCarouselRequest extends StoreCarouselRequest
|
||||
{
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ class StoreHistoricalMilestoneRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -61,7 +61,7 @@ class StoreHistoricalMilestoneRequest extends FormRequest
|
|||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class StoreJobVideoRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -36,7 +36,7 @@ class StoreJobVideoRequest extends FormRequest
|
|||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class StoreLogoRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -51,7 +51,7 @@ class StoreLogoRequest extends FormRequest
|
|||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Networks;
|
||||
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class StoreNetworkRequest 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')
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'seo_title' => 'required|string|between:45,70',
|
||||
'seo_description' => 'required|string|between:50,160',
|
||||
'name' => 'required|string|between:3,255',
|
||||
'title' => 'required|string|between:3,255',
|
||||
'subtitle' => 'required|string|between:3,255',
|
||||
'picture_alt' => 'required|string|between:3,255',
|
||||
'picture_title' => 'required|string|between:3,255',
|
||||
'button_text' => 'required|string|between:3,255',
|
||||
'published' => 'required|boolean',
|
||||
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 1920, 1080, 1920, 1080, false),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Networks;
|
||||
|
||||
class UpdateNetworkRequest extends StoreNetworkRequest
|
||||
{
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ class StoreNewsRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -53,21 +53,20 @@ class StoreNewsRequest extends FormRequest
|
|||
'linkedin_url' => 'nullable|url',
|
||||
'published' => 'required|boolean',
|
||||
'publish_at' => 'nullable|date',
|
||||
'displayed_date' => 'required|date',
|
||||
'unpublish_at' => 'nullable|date|after:publish_at',
|
||||
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 500, 390, 500, 390, true),
|
||||
$this->pictureRules('thumbnail', 660, 440, 660, 440, true),
|
||||
$this->pictureRules('picture', 500, 450, 500, 450, true),
|
||||
$this->pictureRules('thumbnail', 300, 200, 300, 200, true),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
@ -85,7 +84,6 @@ class StoreNewsRequest extends FormRequest
|
|||
'published' => trans('validation.custom.activated'),
|
||||
'publish_at' => trans('validation.custom.publish_at'),
|
||||
'unpublish_at' => trans('validation.custom.unpublish_at'),
|
||||
'displayed_date' => trans('validation.custom.displayed_date'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,9 +36,7 @@ class UpdateSectionRequest extends UpdateMiniCrudRequest
|
|||
/** @var \App\Models\Section|null $section */
|
||||
$section = $this->route('section');
|
||||
if ($section) {
|
||||
if (
|
||||
$section->section !== \App\Enums\Sections\PageSectionEnum::hire_grow
|
||||
) {
|
||||
if ($section->section !== \App\Enums\Sections\PageSectionEnum::hire_grow) {
|
||||
$rules = \array_merge($rules, [
|
||||
'text' => 'present',
|
||||
]);
|
||||
|
|
@ -56,7 +54,7 @@ class UpdateSectionRequest extends UpdateMiniCrudRequest
|
|||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,12 +27,9 @@ class StoreSiteRequest extends FormRequest
|
|||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
/** @var array<int, mixed> $pictos */
|
||||
$pictos = $this->input('pictos') ?? [];
|
||||
$this->merge([
|
||||
'published' => $this->boolean('published'),
|
||||
'invert_director_block' => $this->boolean('invert_director_block'),
|
||||
'pictos' => \collect($pictos)->all(),
|
||||
'published' => $this->boolean('published'),
|
||||
'pictos' => \collect($this->input('pictos'))->all(),
|
||||
]);
|
||||
$this->mergePicture('logo');
|
||||
$this->mergePicture('picture_1');
|
||||
|
|
@ -43,49 +40,47 @@ class StoreSiteRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'seo_title' => 'required|between:45,70',
|
||||
'seo_description' => 'required|between:50,160',
|
||||
'name' => 'required|string|between:3,100',
|
||||
'description' => 'required|string|between:3,255',
|
||||
'description_2' => 'nullable|string|between:3,255',
|
||||
'employees' => 'required|numeric|min:0',
|
||||
'pictos' => 'present|array',
|
||||
'pictos.*' => 'required|integer',
|
||||
'address' => 'required|string|between:3,255',
|
||||
'phone_number' => 'required|string|between:10,20',
|
||||
'access_line' => 'present|array',
|
||||
'access_line.*' => 'nullable|string|between:3,255',
|
||||
'director_name' => 'required|string|between:3,255',
|
||||
'director_function' => 'required|string|between:3,255',
|
||||
'director_speach' => 'required|string|min:15',
|
||||
'invert_director_block' => 'required|boolean',
|
||||
'employee_name' => 'nullable|string|between:3,255',
|
||||
'employee_function' => 'nullable|string|between:3,255',
|
||||
'employee_speach' => 'nullable|string|min:15',
|
||||
'highlights' => 'nullable|string|min:15',
|
||||
'latitude' => 'required|numeric|between:-90,90',
|
||||
'longitude' => 'required|numeric|between:-180,180',
|
||||
'sticky_title' => 'required_with:sticky_link|nullable|string|between:3,255',
|
||||
'sticky_link' => 'required_with:sticky_title|nullable|string|between:3,255',
|
||||
'logo_alt' => 'required|string|between:3,255',
|
||||
'logo_title' => 'required|string|between:3,255',
|
||||
'picture_1_alt' => 'required|string|between:3,255',
|
||||
'picture_1_title' => 'required|string|between:3,255',
|
||||
'picture_2_alt' => 'required_with:picture_2|nullable|string|between:3,255',
|
||||
'picture_2_title' => 'required_with:picture_2|nullable|string|between:3,255',
|
||||
'picture_3_alt' => 'required_with:picture_3|nullable|string|between:3,255',
|
||||
'picture_3_title' => 'required_with:picture_3|nullable|string|between:3,255',
|
||||
'logos' => 'nullable|array',
|
||||
'logos.*.id' => 'required|exists:logos,id',
|
||||
'seo_title' => 'required|between:45,70',
|
||||
'seo_description' => 'required|between:50,160',
|
||||
'name' => 'required|string|between:3,100',
|
||||
'description' => 'required|string|between:3,255',
|
||||
'description_2' => 'nullable|string|between:3,255',
|
||||
'employees' => 'required|numeric|min:0',
|
||||
'pictos' => 'present|array',
|
||||
'pictos.*' => 'required|integer',
|
||||
'address' => 'required|string|between:3,255',
|
||||
'phone_number' => 'required|string|between:10,20',
|
||||
'access_line' => 'present|array',
|
||||
'access_line.*' => 'nullable|string|between:3,255',
|
||||
'director_name' => 'nullable|string|between:3,255',
|
||||
'director_speach' => 'required|string|min:15',
|
||||
'employee_name' => 'nullable|string|between:3,255',
|
||||
'employee_function' => 'nullable|string|between:3,255',
|
||||
'employee_speach' => 'nullable|string|min:15',
|
||||
'highlights' => 'nullable|string|min:15',
|
||||
'latitude' => 'required|numeric|between:-90,90',
|
||||
'longitude' => 'required|numeric|between:-180,180',
|
||||
'logo_alt' => 'required|string|between:3,255',
|
||||
'logo_title' => 'required|string|between:3,255',
|
||||
'picture_1_alt' => 'required|string|between:3,255',
|
||||
'picture_1_title' => 'required|string|between:3,255',
|
||||
'picture_2_alt' => 'required_with:picture_2|nullable|string|between:3,255',
|
||||
'picture_2_title' => 'required_with:picture_2|nullable|string|between:3,255',
|
||||
'picture_3_alt' => 'required_with:picture_3|nullable|string|between:3,255',
|
||||
'picture_3_title' => 'required_with:picture_3|nullable|string|between:3,255',
|
||||
'logos' => 'nullable|array',
|
||||
'logos.*.id' => 'required|exists:logos,id',
|
||||
|
||||
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('logo', 1000, 727, 1000, 727, false),
|
||||
$this->pictureRules('logo', 300, 300, 300, 300, false),
|
||||
$this->pictureRules('picture_1', 1000, 562, 1000, 562, false),
|
||||
$this->pictureRules('picture_2', 1000, 562, 1000, 562, true),
|
||||
$this->pictureRules('picture_3', 1000, 562, 1000, 562, true),
|
||||
|
|
@ -95,38 +90,34 @@ class StoreSiteRequest extends FormRequest
|
|||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'seo_title' => trans('validation.custom.seo_title'),
|
||||
'seo_description' => trans('validation.custom.seo_description'),
|
||||
'name' => trans('validation.attributes.name'),
|
||||
'description' => trans('validation.custom.description'),
|
||||
'description_2' => trans('validation.custom.description_2'),
|
||||
'employees' => trans('validation.custom.employees_count'),
|
||||
'pictos' => Str::plural(trans('validation.custom.picto')),
|
||||
'pictos.*' => trans('validation.custom.picto'),
|
||||
'address' => trans('validation.attributes.address'),
|
||||
'phone_number' => trans('validation.attributes.phone'),
|
||||
'access_line' => trans('validation.custom.access_line'),
|
||||
'access_line.*' => trans('ligne d\'accès au site'),
|
||||
'director_name' => trans('validation.custom.director_name'),
|
||||
'director_function' => trans('validation.custom.director_function'),
|
||||
'director_speach' => trans('validation.custom.director_speach'),
|
||||
'invert_director_block' => trans('validation.custom.invert_block'),
|
||||
'employee_name' => trans('validation.custom.employee_name'),
|
||||
'employee_function' => trans('validation.custom.employee_function'),
|
||||
'employee_speach' => trans('validation.custom.employee_speach'),
|
||||
'highlights' => Str::plural(trans('validation.custom.highlight')),
|
||||
'latitude' => trans('validation.custom.latitude'),
|
||||
'longitude' => trans('validation.custom.longitude'),
|
||||
'sticky_title' => trans('validation.custom.sticky_item.title'),
|
||||
'sticky_link' => trans('validation.custom.sticky_item.link'),
|
||||
'logos' => Str::plural(trans('models.classes.logo')),
|
||||
'logos.*' => trans('models.classes.logo'),
|
||||
'logo_alt' => trans(':field :inter:model', [
|
||||
'seo_title' => trans('validation.custom.seo_title'),
|
||||
'seo_description' => trans('validation.custom.seo_description'),
|
||||
'name' => trans('validation.attributes.name'),
|
||||
'description' => trans('validation.custom.description'),
|
||||
'description_2' => trans('validation.custom.description_2'),
|
||||
'employees' => trans('validation.custom.employees_count'),
|
||||
'pictos' => Str::plural(trans('validation.custom.picto')),
|
||||
'pictos.*' => trans('validation.custom.picto'),
|
||||
'address' => trans('validation.attributes.address'),
|
||||
'phone_number' => trans('validation.attributes.phone'),
|
||||
'access_line' => trans('validation.custom.access_line'),
|
||||
'access_line.*' => trans('ligne d\'accès au site'),
|
||||
'director_name' => trans('validation.custom.director_name'),
|
||||
'director_speach' => trans('validation.custom.director_speach'),
|
||||
'employee_name' => trans('validation.custom.employee_name'),
|
||||
'employee_function' => trans('validation.custom.employee_function'),
|
||||
'employee_speach' => trans('validation.custom.employee_speach'),
|
||||
'highlights' => Str::plural(trans('validation.custom.highlight')),
|
||||
'latitude' => trans('validation.custom.latitude'),
|
||||
'longitude' => trans('validation.custom.longitude'),
|
||||
'logos' => Str::plural(trans('models.classes.logo')),
|
||||
'logos.*' => trans('models.classes.logo'),
|
||||
'logo_alt' => trans(':field :inter:model', [
|
||||
'field' => trans('validation.custom.alt_attribute'),
|
||||
'inter' => trans('validation.custom.of_the.male'),
|
||||
'model' => trans('validation.custom.logo'),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Http\Requests\Bo\Slides;
|
||||
|
||||
use App\Enums\Slides\SliderTypeEnum;
|
||||
use App\Rules\WysiwygLength;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
|
@ -31,7 +30,7 @@ class StoreSlideRequest extends FormRequest
|
|||
{
|
||||
$this->merge([
|
||||
'button_status' => $this->boolean('button_status'),
|
||||
'button_new_tab' => $this->boolean('button_new_tab'),
|
||||
'button_new_tab' => $this->boolean('button_new_tab')
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
|
|
@ -39,7 +38,7 @@ class StoreSlideRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -55,31 +54,19 @@ class StoreSlideRequest extends FormRequest
|
|||
'between:3,255'
|
||||
],
|
||||
'content' => [
|
||||
'required_if:type,' . SliderTypeEnum::home->value() . ', ' . SliderTypeEnum::team->value(),
|
||||
'required_if:type,' . SliderTypeEnum::home->value(),
|
||||
'nullable',
|
||||
'string',
|
||||
new WysiwygLength(3, 275),
|
||||
'max:500'
|
||||
'between:3,255'
|
||||
],
|
||||
'video_id' => 'nullable|string|regex:%([^"&?\/\s]{11})%i',
|
||||
'picture_alt' => [
|
||||
'required_unless:type,' . SliderTypeEnum::team->value(),
|
||||
'nullable',
|
||||
'string',
|
||||
'between:3,255'
|
||||
],
|
||||
'picture_title' => [
|
||||
'required_unless:type,' . SliderTypeEnum::team->value(),
|
||||
'nullable',
|
||||
'string',
|
||||
'between:3,255'
|
||||
],
|
||||
'picture_alt' => 'required|string|between:3,255',
|
||||
'picture_title' => 'required|string|between:3,255',
|
||||
'button_label' => 'required_if:button_status,true|nullable|string|between:3,35',
|
||||
'button_url' => 'required_if:button_status,true|nullable|string|between:3,255',
|
||||
'button_status' => [
|
||||
'required_unless:type,' . SliderTypeEnum::home->value() . ', ' . SliderTypeEnum::team->value(),
|
||||
'nullable',
|
||||
'boolean'
|
||||
'required_unless:type,' . SliderTypeEnum::home->value(),
|
||||
'nullable', 'boolean'
|
||||
],
|
||||
'button_new_tab' => 'required|boolean',
|
||||
];
|
||||
|
|
@ -92,7 +79,7 @@ class StoreSlideRequest extends FormRequest
|
|||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
@ -114,27 +101,23 @@ class StoreSlideRequest extends FormRequest
|
|||
/**
|
||||
* Custom validaton messages.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
'title.required_unless' => __('Le champ :attribute est obligatoire si le slider n\'est pas :name.', [
|
||||
'attribute' => trans('validation.attributes.title'),
|
||||
'name' => SliderTypeEnum::home->label()
|
||||
]),
|
||||
'content.required_if' => __('Le champ :attribute est obligatoire si le slider est :name1 ou :name2.', [
|
||||
'attribute' => trans('validation.attributes.content'),
|
||||
'name1' => SliderTypeEnum::home->label(),
|
||||
'name2' => SliderTypeEnum::team->label()
|
||||
]),
|
||||
'content.max' => __(
|
||||
'Le champ :attribute ne peut pas contenir plus de :max caractères (balises incluses).',
|
||||
[
|
||||
'title' => [
|
||||
'required_unless' => __('Le champ :attribute est obligatoire si le slider n\'est pas :name.', [
|
||||
'attribute' => trans('validation.attributes.title'),
|
||||
'name' => SliderTypeEnum::home->label()
|
||||
]),
|
||||
],
|
||||
'content' => [
|
||||
'required_unless' => __('Le champ :attribute est obligatoire si le slider n\'est pas :name.', [
|
||||
'attribute' => trans('validation.attributes.content'),
|
||||
'max' => '500',
|
||||
]
|
||||
),
|
||||
'name' => SliderTypeEnum::home->label()
|
||||
]),
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,12 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\StaticPages;
|
||||
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UpdateStaticPageRequest extends FormRequest
|
||||
{
|
||||
use HasPicture;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
|
|
@ -33,7 +30,6 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
null :
|
||||
Str::of($this->input('content'))->value()
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,23 +48,13 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
if (request()->route()->parameters()['static_page']->type->containsContent()) {
|
||||
$rules = array_merge($rules, ['content' => 'required|string|min:15']);
|
||||
}
|
||||
if (request()->route()->parameters()['static_page']->type->containsBanner()) {
|
||||
$rules = array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 1920, 1080, 1920, 1080, false),
|
||||
[
|
||||
'picture_alt' => 'required|string|between:3,255',
|
||||
'picture_title' => 'required|string|between:3,255',
|
||||
]
|
||||
);
|
||||
}
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
@ -77,9 +63,6 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
'seo_description' => trans('validation.custom.seo_description'),
|
||||
'title' => trans('validation.attributes.title'),
|
||||
'content' => trans('validation.attributes.content'),
|
||||
'picture' => trans('validation.custom.banner'),
|
||||
'picture_alt' => trans('validation.custom.attribute_alt'),
|
||||
'picture_title' => trans('validation.custom.attribute_title'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Stickies;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Enums\StickiesColorEnum;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreStickyRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'type' => [
|
||||
Rule::requiredIf($this->user()->can('create', $this->sticky)),
|
||||
new Enum(StaticPageType::class)
|
||||
],
|
||||
'title' => 'required|string|between:3,255',
|
||||
'anchor' => [
|
||||
Rule::requiredIf($this->user()->can('create', $this->sticky)),
|
||||
'string',
|
||||
'between:3,255'
|
||||
],
|
||||
'color' => [
|
||||
Rule::requiredIf($this->user()->can('create', $this->sticky)),
|
||||
new Enum(StickiesColorEnum::class)
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'type' => trans('validation.custom.type'),
|
||||
'title' => trans('validation.attributes.title'),
|
||||
'anchor' => trans('validation.custom.anchor'),
|
||||
'color' => trans('validation.custom.color'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo\Stickies;
|
||||
|
||||
class UpdateStickyRequest extends StoreStickyRequest
|
||||
{
|
||||
}
|
||||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Strips;
|
||||
|
||||
use App\Rules\WysiwygLength;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreStripRequest extends FormRequest
|
||||
|
|
@ -31,71 +31,55 @@ class StoreStripRequest extends FormRequest
|
|||
$this->merge([
|
||||
'published' => $this->boolean('published'),
|
||||
]);
|
||||
if ($this->input('picture')) {
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
return [
|
||||
'picto' => [
|
||||
'required',
|
||||
new Enum(\App\Enums\Strips\PictoEnum::class)
|
||||
],
|
||||
'text' => [
|
||||
'required',
|
||||
'string',
|
||||
new WysiwygLength(3, 90),
|
||||
'min:3',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function (string $attribute, mixed $value, \Closure $fail) {
|
||||
if (Str::wordCount(\strip_tags($value)) > 255) {
|
||||
$fail(trans('validation.max_words', [
|
||||
'attribute' => trans('validation.attributes.text'),
|
||||
'count' => '255'
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'news_id' => 'nullable|exists:news,id',
|
||||
'published' => 'required|boolean',
|
||||
'publish_at' => 'nullable|date',
|
||||
'unpublish_at' => 'nullable|date|after:publish_at',
|
||||
];
|
||||
|
||||
if ($this->input('picture')) {
|
||||
$rules = array_merge(
|
||||
$rules,
|
||||
[
|
||||
'picture_alt' => 'required_with|string|between:3,255',
|
||||
'picture_title' => 'required_with|string|between:3,255',
|
||||
],
|
||||
$this->pictureRules('picture', 100, 65, 100, 65, true),
|
||||
);
|
||||
} else {
|
||||
$rules = array_merge(
|
||||
$rules,
|
||||
[
|
||||
'picto' => [
|
||||
'required',
|
||||
new Enum(\App\Enums\Strips\PictoEnum::class)
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'picto' => trans('validation.custom.picto'),
|
||||
'picture' => trans('validation.custom.picture'),
|
||||
'picture_alt' => trans('validation.custom.alt_attribute'),
|
||||
'picture_title' => trans('validation.custom.title_attribute'),
|
||||
'text' => trans('validation.attributes.content'),
|
||||
'news_id' => trans('models.classes.news'),
|
||||
'published' => trans('validation.custom.activated'),
|
||||
'publish_at' => trans('validation.custom.publish_at'),
|
||||
'unpublish_at' => trans('validation.custom.unpublish_at'),
|
||||
'picto' => trans('validation.custom.picto'),
|
||||
'text' => trans('validation.attributes.content'),
|
||||
'news_id' => trans('models.classes.news'),
|
||||
'published' => trans('validation.custom.activated'),
|
||||
'publish_at' => trans('validation.custom.publish_at'),
|
||||
'unpublish_at' => trans('validation.custom.unpublish_at'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class StoreTestimonialRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -50,14 +50,14 @@ class StoreTestimonialRequest extends FormRequest
|
|||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 150, 150, 150, 150, false),
|
||||
$this->pictureRules('picture', 100, 100, 100, 100, false),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class UpdateChangeOrderRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29,8 +29,8 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
|
||||
* @return array
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
* @phpcs:disable Generic.Metrics.NestingLevel.TooHigh
|
||||
*/
|
||||
public function rules(): array
|
||||
|
|
@ -38,8 +38,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
// phpcs:enable
|
||||
$rules = [];
|
||||
foreach ($this->{$this->modelName}->data as $iptName => $input) {
|
||||
$encoded = \json_encode($input);
|
||||
$input = \json_decode($encoded !== false ? $encoded : '[]', true);
|
||||
$input = \json_decode(\json_encode($input), true);
|
||||
switch ($input['inputType']) {
|
||||
case InputType::number->value:
|
||||
$rules = array_merge($rules, [
|
||||
|
|
@ -72,7 +71,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
$mergeRules = $this->compileValidate('required|string|min:15', $input);
|
||||
$mergeRules = collect($mergeRules)
|
||||
->map(function ($rule) {
|
||||
if (\is_string($rule) && \strpos($rule, 'max:') !== false) {
|
||||
if (\strpos($rule, 'max:') !== false) {
|
||||
$max = \intval(str_replace('max:', '', $rule));
|
||||
return function ($attribute, $value, $fail) use ($max) {
|
||||
if (\strlen(\strip_tags($value)) > $max) {
|
||||
|
|
@ -81,13 +80,13 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
};
|
||||
}
|
||||
return $rule;
|
||||
})->all();
|
||||
});
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $mergeRules
|
||||
]);
|
||||
break;
|
||||
case InputType::image->value:
|
||||
$required = $this->isUpdate() ? 'sometimes' : ($input['required'] ? 'required' : 'nullable');
|
||||
$required = $this->isUpdate() ? 'sometimes' : 'required';
|
||||
$ipt = $this->data[$iptName];
|
||||
$max = isset($ipt['dimensionsMax']);
|
||||
$dim = \is_string($input['dimensions']) ? collect(explode(
|
||||
|
|
@ -100,11 +99,11 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
}) : $input['dimensions'];
|
||||
|
||||
// * Adapt dimensions
|
||||
$sizes = [
|
||||
$sizes = (object)[
|
||||
'minHeight' => $dim['height'],
|
||||
'maxHeight' => $dim['height'],
|
||||
'minWidth' => $dim['width'],
|
||||
'maxWidth' => $dim['width'],
|
||||
'minWidth' => $dim['width'],
|
||||
'maxWidth' => $dim['width'],
|
||||
];
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => [
|
||||
|
|
@ -134,10 +133,15 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
case InputType::url->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => [
|
||||
$this->compileValidate('url', $input),
|
||||
'required', 'url',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
$this->validateUrl($attribute, $value, $fail);
|
||||
try {
|
||||
ToolboxHelper::assertNoInternalUrls($attribute, $value);
|
||||
ToolboxHelper::assertNoInternalBoUrls($attribute, $value);
|
||||
} catch (ValidationException $e) {
|
||||
$fail(collect($e->errors())->first()[0]);
|
||||
}
|
||||
}
|
||||
]
|
||||
]);
|
||||
|
|
@ -156,23 +160,22 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
break;
|
||||
} //end switch
|
||||
} //end foreach
|
||||
// @phpstan-ignore-next-line
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function.
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string|array<int, string> $inputTypeValidate
|
||||
* @param array<string, mixed> $input
|
||||
* @return array<int, mixed>
|
||||
* @param string|array $inputTypeValidate
|
||||
* @param array $input
|
||||
* @return array
|
||||
*/
|
||||
public function compileValidate(string|array $inputTypeValidate, array $input): array
|
||||
{
|
||||
if (\is_string($inputTypeValidate)) {
|
||||
$inputTypeValidate = explode('|', $inputTypeValidate);
|
||||
}
|
||||
/** @var array<int|string, mixed>|string $inputValidate */
|
||||
/** @var array|string */
|
||||
$inputValidate = \collect($input)->get('validate', $input);
|
||||
$inputValidate = \is_string($inputValidate) ? explode('|', $inputValidate) : $inputValidate;
|
||||
foreach ($inputValidate as $validate) {
|
||||
|
|
@ -181,32 +184,18 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
|
||||
$test = \collect($inputTypeValidate)->all();
|
||||
$test = \collect($inputTypeValidate)->sort(function ($valueA, $valueB) {
|
||||
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
|
||||
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
|
||||
return $valueA - $valueB;
|
||||
})->unique()->all();
|
||||
|
||||
return \collect($inputTypeValidate)->unique()->sort(function ($valueA, $valueB) {
|
||||
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
|
||||
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
|
||||
return $valueA - $valueB;
|
||||
})->values()->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate URl
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $url
|
||||
* @param \Closure $fail
|
||||
* @return void
|
||||
*/
|
||||
private function validateUrl(string $attribute, mixed $url, \Closure $fail): void
|
||||
{
|
||||
try {
|
||||
if (!is_null($url)) {
|
||||
$url = is_string($url) ? $url : '';
|
||||
ToolboxHelper::assertNoInternalUrls($attribute, $url);
|
||||
ToolboxHelper::assertNoInternalBoUrls($attribute, $url);
|
||||
}
|
||||
} catch (ValidationException $e) {
|
||||
$fail(collect($e->errors())->first()[0]);
|
||||
}
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,60 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateOrderRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Attribute model needed.
|
||||
*
|
||||
* @var Model $orderable
|
||||
*/
|
||||
private Model $orderableModel;
|
||||
|
||||
/**
|
||||
* 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->orderableModel = collect($this->route()->parameters())
|
||||
->first(fn($param) => $param instanceof Model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'order' => [
|
||||
'required',
|
||||
'integer',
|
||||
'min:1',
|
||||
sprintf('max:%s', $this->orderableModel->max('order')),
|
||||
function ($attribute, $value, $fail) {
|
||||
/** @phpstan-ignore-next-line */
|
||||
if ($this->orderableModel && intval($value) === $this->orderableModel->order) {
|
||||
$fail("La valeur de {$attribute} doit être différente de la valeur actuelle.");
|
||||
}
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ class UploadFileRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use App\Models\User;
|
|||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class StoreUserRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -35,7 +36,7 @@ class StoreUserRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -43,6 +44,14 @@ class StoreUserRequest extends FormRequest
|
|||
'first_name' => 'required|string|min:3|max:255',
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
],
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'published' => 'required|boolean',
|
||||
];
|
||||
|
|
@ -51,7 +60,7 @@ class StoreUserRequest extends FormRequest
|
|||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
@ -59,6 +68,7 @@ class StoreUserRequest extends FormRequest
|
|||
'first_name' => trans('validation.attributes.first_name'),
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'password' => trans('validation.attributes.password'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication')
|
||||
];
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Http\Requests\Bo\Users;
|
|||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UpdateUserRequest extends StoreUserRequest
|
||||
{
|
||||
|
|
@ -25,14 +26,18 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->boolean('published'),
|
||||
'published' => $this->boolean('published'),
|
||||
'password' => $this->input('password') ??
|
||||
\optional($this->route('user'))->password,
|
||||
'password_confirmation' => $this->input('password_confirmation') ??
|
||||
\optional($this->route('user'))->password
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -41,7 +46,15 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
'required',
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
Rule::unique('users', 'email')->ignore(\optional($this->route('user'))->getRouteKey())
|
||||
]
|
||||
],
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class ListenFormRequest extends FormRequest
|
|||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'country' => $this->post('country') ?? null,
|
||||
'country' => $this->post('country') == null ? $this->post('country') : null,
|
||||
'accept_rules' => $this->boolean('accept_rules'),
|
||||
'send_data' => $this->boolean('send_data'),
|
||||
]);
|
||||
|
|
@ -30,7 +30,7 @@ class ListenFormRequest extends FormRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -40,27 +40,21 @@ class ListenFormRequest extends FormRequest
|
|||
'last_name' => 'required|string|between:3,100',
|
||||
'society' => 'present|nullable|string|between:3,255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|max:255',
|
||||
'phone' => array_merge(
|
||||
['present', 'nullable'],
|
||||
!is_null(request()->input('country'))
|
||||
? (Country::make(request()->input('country'))->value === Country::france->value
|
||||
? ['phone:FR', 'max:25']
|
||||
: ['numeric', 'max:50'])
|
||||
: ['numeric', 'max:50']
|
||||
),
|
||||
'postal_code' => array_merge(
|
||||
['present', 'nullable'],
|
||||
!is_null(request()->input('country'))
|
||||
? (Country::make(request()->input('country'))->value === Country::france->value
|
||||
? ['postal_code:FR', 'max:25']
|
||||
: ['numeric', 'max:50'])
|
||||
: ['numeric', 'max:50']
|
||||
),
|
||||
// @phpstan-ignore-next-line
|
||||
'phone' => 'present|nullable|' . (
|
||||
Country::make(request()->country)->value === Country::france->value
|
||||
) ? 'phone:FR|max:25' : 'number|max:50',
|
||||
// @phpstan-ignore-next-line
|
||||
'postal_code' => 'present|nullable|' . (
|
||||
Country::make(request()->country)->value === Country::france->value
|
||||
) ? 'postal_code:FR|max:25' : 'number|max:50',
|
||||
'city' => 'present|nullable|string|between:3,20',
|
||||
'country' => ['present', 'nullable', new Enum(Country::class)],
|
||||
'address' => 'present|nullable|string|between:3,255',
|
||||
'object' => ['required', new Enum(ObjectEnum::class)],
|
||||
'message' => 'required|min:20|max:35656',
|
||||
'accept_rules' => 'required|boolean',
|
||||
'send_data' => 'required|boolean',
|
||||
];
|
||||
if (
|
||||
isset(request()->file) and
|
||||
|
|
@ -101,7 +95,7 @@ class ListenFormRequest extends FormRequest
|
|||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\ActivityLog;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Permanently deletes entries that have been stored for more than one year.
|
||||
*/
|
||||
class CleanOldActivities implements ShouldQueue, ShouldBeUnique
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* Create the controller instance.
|
||||
*
|
||||
* @param boolean $force
|
||||
*/
|
||||
public function __construct(public readonly bool $force = false)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete entries if it has been stored for more than one year.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
$query = ActivityLog::query();
|
||||
|
||||
if (!$this->force) {
|
||||
$query->where('created_at', '<', Carbon::now()->subYear());
|
||||
}
|
||||
|
||||
$query->cursor()->each(fn($model) => $model->delete());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\News;
|
||||
use App\Models\Strip;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
/**
|
||||
* Update published attribute reading its
|
||||
* publish_at and unpublish_at attributes.
|
||||
*/
|
||||
class UpdatePlanificatedStatus
|
||||
{
|
||||
/**
|
||||
* Called when the job will be executed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
collect([News::class, Strip::class])
|
||||
->each(function (string $model) {
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<array-key,\App\Models\News|\App\Models\Strip> */
|
||||
$modelListToPublish = $model::query()
|
||||
->whereNotNull('publish_at')
|
||||
->where('publish_at', '<=', Carbon::now())
|
||||
->where(function ($query) {
|
||||
$query->whereNull('unpublish_at')
|
||||
->orWhere('unpublish_at', '>', Carbon::now());
|
||||
})
|
||||
->where('published', false)
|
||||
->get();
|
||||
Log::debug(__CLASS__ . " models to publish " . $modelListToPublish->count());
|
||||
$modelListToPublish->each(function ($currentModel) {
|
||||
$currentModel->published = true;
|
||||
$currentModel->saveOrFail();
|
||||
});
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<array-key,\App\Models\News|\App\Models\Strip> */
|
||||
$modelListToUnpublish = $model::query()
|
||||
->whereNotNull('unpublish_at')
|
||||
->where('unpublish_at', '<=', Carbon::now())
|
||||
->where('published', true)
|
||||
->get();
|
||||
Log::debug(__CLASS__ . " models to unpublish " . $modelListToUnpublish->count());
|
||||
$modelListToUnpublish->each(function ($currentModel) {
|
||||
$currentModel->published = false;
|
||||
$currentModel->saveOrFail();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -10,27 +10,26 @@ use Illuminate\Support\Collection;
|
|||
class CollectionHelper
|
||||
{
|
||||
/**
|
||||
* Paginate a collection.
|
||||
* Paginate a collection
|
||||
*
|
||||
* @template TModel of \Illuminate\Database\Eloquent\Model
|
||||
* @param \Illuminate\Support\Collection<int, TModel> $results
|
||||
* @param integer $pageSize
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator<TModel>
|
||||
* @param \Illuminate\Support\Collection $results
|
||||
* @param integer $pageSize
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public static function paginate(Collection $results, int $pageSize): \Illuminate\Pagination\LengthAwarePaginator
|
||||
{
|
||||
$page = Paginator::resolveCurrentPage('page');
|
||||
|
||||
return self::paginateManually($results, $pageSize, $page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate a collection.
|
||||
* Paginate a collection
|
||||
*
|
||||
* @template TModel of \Illuminate\Database\Eloquent\Model
|
||||
* @param \Illuminate\Support\Collection<int, TModel> $results
|
||||
* @param integer $pageSize
|
||||
* @param integer $page
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator<TModel>
|
||||
* @param \Illuminate\Support\Collection $results
|
||||
* @param integer $pageSize
|
||||
* @param integer $page
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public static function paginateManually(
|
||||
Collection $results,
|
||||
|
|
@ -40,7 +39,7 @@ class CollectionHelper
|
|||
$total = $results->count();
|
||||
|
||||
return self::paginator($results->forPage($page, $pageSize), $total, $pageSize, $page, [
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'pageName' => 'page',
|
||||
]);
|
||||
}
|
||||
|
|
@ -48,13 +47,12 @@ class CollectionHelper
|
|||
/**
|
||||
* Create a new length-aware paginator instance.
|
||||
*
|
||||
* @template TModel of \Illuminate\Database\Eloquent\Model
|
||||
* @param \Illuminate\Support\Collection<int, TModel> $items
|
||||
* @param integer $total
|
||||
* @param integer $perPage
|
||||
* @param integer $currentPage
|
||||
* @param array<mixed> $options
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator<TModel>
|
||||
* @param \Illuminate\Support\Collection $items
|
||||
* @param integer $total
|
||||
* @param integer $perPage
|
||||
* @param integer $currentPage
|
||||
* @param array $options
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
protected static function paginator(
|
||||
Collection $items,
|
||||
|
|
@ -64,11 +62,11 @@ class CollectionHelper
|
|||
array $options
|
||||
): \Illuminate\Pagination\LengthAwarePaginator {
|
||||
return Container::getInstance()->makeWith(LengthAwarePaginator::class, [
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'perPage' => $perPage,
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'perPage' => $perPage,
|
||||
'currentPage' => $currentPage,
|
||||
'options' => $options
|
||||
'options' => $options
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace App\Lib\Helpers;
|
|||
class ExceptionsHelper
|
||||
{
|
||||
/**
|
||||
* Handle sentry event.
|
||||
* Handle sentry event
|
||||
*
|
||||
* @param \Sentry\Event $event
|
||||
* @return null|\Sentry\Event
|
||||
|
|
@ -26,7 +26,7 @@ class ExceptionsHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Anonimize Sentry Exception bag.
|
||||
* Anonimize Sentry Exception bag
|
||||
*
|
||||
* @param \Sentry\ExceptionDataBag $exceptionDataBag
|
||||
* @return \Sentry\ExceptionDataBag
|
||||
|
|
@ -42,7 +42,7 @@ class ExceptionsHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Anonymise sentry stacktrace.
|
||||
* Anonymise sentry stacktrace
|
||||
*
|
||||
* @param \Sentry\Stacktrace $stackTrace
|
||||
* @return \Sentry\Stacktrace
|
||||
|
|
@ -70,7 +70,7 @@ class ExceptionsHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Get anonymized sentry params.
|
||||
* Get anonymized sentry params
|
||||
*
|
||||
* @param mixed[] $params
|
||||
* @return string[]
|
||||
|
|
@ -80,7 +80,7 @@ class ExceptionsHelper
|
|||
foreach ($params as &$param) {
|
||||
$type = \strtolower(\gettype($param));
|
||||
if (\is_string($param)) {
|
||||
$type = \explode(' ', \trim(strtolower($param)))[0];
|
||||
$type = \explode(' ', \trim(strtolower($param)))[0] ?? null;
|
||||
}
|
||||
switch (true) {
|
||||
case $type === 'lambda':
|
||||
|
|
@ -104,7 +104,7 @@ class ExceptionsHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Anonymize at least Sql queries.
|
||||
* Anonymize at least Sql queries
|
||||
*
|
||||
* @param string $message
|
||||
* @return string
|
||||
|
|
@ -119,14 +119,14 @@ class ExceptionsHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Anonymize stack trace.
|
||||
* Anonymize stack trace
|
||||
*
|
||||
* @param \Throwable $e
|
||||
* @return string
|
||||
*/
|
||||
public static function getAnonymizedStackTrace(\Throwable $e): string
|
||||
{
|
||||
$projectPath = \realpath(\sprintf('%s/../', \app_path())) ?: '';
|
||||
$projectPath = \realpath(\sprintf('%s/../', \app_path()));
|
||||
$traceStack = $e->getTrace();
|
||||
$traceStr = '';
|
||||
$maxStackStage = 0;
|
||||
|
|
@ -158,9 +158,9 @@ class ExceptionsHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Handle Args.
|
||||
* Handle Args
|
||||
*
|
||||
* @param array<string, mixed> $stack
|
||||
* @param array $stack
|
||||
* @return string
|
||||
*/
|
||||
public static function handleArgs(array $stack): string
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ use Illuminate\Support\Str;
|
|||
* The final path will be storage/modelfiles/posts/10/04/19/5f/black-cat-under-red-car-286071690833400.png
|
||||
*
|
||||
* ! No limits of file per folder will be handled.
|
||||
*
|
||||
* @author Munsch Jérémy <jeremy.munsch@ldc.fr>
|
||||
*/
|
||||
class FileStorageHelper
|
||||
{
|
||||
|
|
@ -38,7 +40,7 @@ class FileStorageHelper
|
|||
{
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
$disk = Storage::disk('uploads');
|
||||
$path = ToolboxHelper::mbReplaceString('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
return $disk->path($path);
|
||||
}
|
||||
|
||||
|
|
@ -55,7 +57,7 @@ class FileStorageHelper
|
|||
if (\strpos($path, 'storage') !== 0) {
|
||||
return;
|
||||
}
|
||||
$path = ToolboxHelper::mbReplaceString('storage/', '', $path);
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', $path);
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
}
|
||||
|
|
@ -79,7 +81,7 @@ class FileStorageHelper
|
|||
if (\strpos($originalPath, 'storage') !== 0) {
|
||||
return;
|
||||
}
|
||||
$originalPath = ToolboxHelper::mbReplaceString('storage/', '', $originalPath);
|
||||
$originalPath = ToolboxHelper::mbReplace('storage/', '', $originalPath);
|
||||
if (Storage::disk('public')->exists($originalPath)) {
|
||||
Storage::disk('public')->delete($originalPath);
|
||||
}
|
||||
|
|
@ -103,8 +105,8 @@ class FileStorageHelper
|
|||
Model $model,
|
||||
$file,
|
||||
bool $slugify = false,
|
||||
string|null $filename = null,
|
||||
bool $private = false,
|
||||
string $filename = null,
|
||||
bool $private = false
|
||||
): string {
|
||||
// phpcs:enable
|
||||
$tableName = $model->getTable();
|
||||
|
|
@ -164,16 +166,16 @@ class FileStorageHelper
|
|||
public static function storeModelFilesFromHtml(
|
||||
Model $model,
|
||||
string $htmlString,
|
||||
string|null $oldHtmlString = null
|
||||
string $oldHtmlString = null
|
||||
): string {
|
||||
\collect(self::onlyUploadedFilesWithFileManager(self::findFilesInHtml($htmlString)))
|
||||
->each(function (string $path) use ($model, &$htmlString) {
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
$disk = Storage::disk('uploads');
|
||||
$fileInfo = new \SplFileInfo($disk->path(
|
||||
ToolboxHelper::mbReplaceString('/uploads/', '', \urldecode($path))
|
||||
ToolboxHelper::mbReplace('/uploads/', '', \urldecode($path))
|
||||
));
|
||||
$htmlString = ToolboxHelper::mbReplaceString(
|
||||
$htmlString = ToolboxHelper::mbReplace(
|
||||
$path,
|
||||
'/' . self::storeFile($model, $fileInfo, true),
|
||||
$htmlString
|
||||
|
|
@ -214,7 +216,7 @@ class FileStorageHelper
|
|||
$filesToKeep = \collect(self::onlyUploadedFilesWithFileStorageHelper($newFiles));
|
||||
$filesToRemove = $oldFiles->diff($filesToKeep);
|
||||
$filesToRemove->each(function (string $publicStorageFilePath) {
|
||||
$path = ToolboxHelper::mbReplaceString('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
}
|
||||
|
|
@ -231,7 +233,7 @@ class FileStorageHelper
|
|||
{
|
||||
$filesToRemove = \collect(self::onlyUploadedFilesWithFileStorageHelper(self::findFilesInHtml($htmlString)));
|
||||
$filesToRemove->each(function (string $publicStorageFilePath) {
|
||||
$path = ToolboxHelper::mbReplaceString('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
}
|
||||
|
|
@ -242,7 +244,7 @@ class FileStorageHelper
|
|||
* Find all occurence of files in html
|
||||
*
|
||||
* @param string $html
|
||||
* @return array<mixed>
|
||||
* @return array
|
||||
*/
|
||||
public static function findFilesInHtml(string $html): array
|
||||
{
|
||||
|
|
@ -257,20 +259,20 @@ class FileStorageHelper
|
|||
* Filter array to get only uploaded files that exists
|
||||
* on disk 'public' (using helper storage strategy)
|
||||
*
|
||||
* @param array<int, string> $urls
|
||||
* @return array<mixed>
|
||||
* @param array $urls
|
||||
* @return array
|
||||
*/
|
||||
public static function onlyUploadedFilesWithFileStorageHelper(array $urls): array
|
||||
{
|
||||
return \collect($urls)->unique()
|
||||
// * Filter to get only /uploads and using app url or empty
|
||||
->filter(function (string $url) {
|
||||
$path = (string) \parse_url($url, \PHP_URL_PATH);
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return \strpos(\ltrim($path, '/'), 'storage/modelfiles') === 0;
|
||||
})->filter(function (string $url) {
|
||||
$path = (string) \parse_url($url, \PHP_URL_PATH);
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return Storage::disk('public')
|
||||
->exists(ToolboxHelper::mbReplaceString('storage/', '', \ltrim(\urldecode($path), '/')));
|
||||
->exists(ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($path), '/')));
|
||||
})->all();
|
||||
}
|
||||
|
||||
|
|
@ -278,22 +280,22 @@ class FileStorageHelper
|
|||
* Filter array to get only uploaded files that exists
|
||||
* on disk 'uploads'
|
||||
*
|
||||
* @param array<int, string> $urls
|
||||
* @return array<mixed>
|
||||
* @param array $urls
|
||||
* @return array
|
||||
*/
|
||||
private static function onlyUploadedFilesWithFileManager(array $urls): array
|
||||
{
|
||||
return \collect($urls)->unique()
|
||||
// * Filter to get only /uploads and using app url or empty
|
||||
->filter(function (string $url) {
|
||||
$host = (string) \parse_url($url, \PHP_URL_HOST);
|
||||
$path = (string) \parse_url($url, \PHP_URL_PATH);
|
||||
return ($host === (string) \parse_url(config('app.url'), PHP_URL_HOST) or $host === '') and
|
||||
$host = \parse_url($url, \PHP_URL_HOST);
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return ($host === \parse_url(config('app.url'), PHP_URL_HOST) or \is_null($host)) and
|
||||
\strpos(\ltrim($path, '/'), 'uploads') === 0;
|
||||
})->filter(function (string $url) {
|
||||
$path = (string) \parse_url($url, \PHP_URL_PATH);
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return Storage::disk('uploads')
|
||||
->exists(ToolboxHelper::mbReplaceString('uploads/', '', \ltrim(\urldecode($path), '/')));
|
||||
->exists(ToolboxHelper::mbReplace('uploads/', '', \ltrim(\urldecode($path), '/')));
|
||||
})->all();
|
||||
}
|
||||
|
||||
|
|
@ -457,7 +459,7 @@ class FileStorageHelper
|
|||
'/\.{2,}/'
|
||||
], '.', $filename);
|
||||
// Lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625 .
|
||||
$filename = mb_strtolower($filename, mb_detect_encoding($filename) ?: null);
|
||||
$filename = mb_strtolower($filename, mb_detect_encoding($filename));
|
||||
// * ".file-name.-" becomes "file-name"
|
||||
$filename = trim($filename, '.-');
|
||||
return $filename;
|
||||
|
|
@ -466,7 +468,7 @@ class FileStorageHelper
|
|||
/**
|
||||
* Remove all model files for the given Model.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param Model $model
|
||||
* @return void
|
||||
*/
|
||||
public static function removeModelFiles(Model $model): void
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
namespace App\Lib\Helpers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -24,8 +24,8 @@ class ToolboxHelper
|
|||
/**
|
||||
* Run a terminal command and gives the output.
|
||||
*
|
||||
* @param array<string>|string $command The command to execute on terminal.
|
||||
* @param boolean $throw Wether to throw en esception on failure or not.
|
||||
* @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
|
||||
|
|
@ -36,7 +36,7 @@ class ToolboxHelper
|
|||
* @throws \LogicException
|
||||
* @throws \RuntimeException If the command fails.
|
||||
*/
|
||||
public static function runConsoleCommand(array|string $command, bool $throw = true): string|false
|
||||
public static function runConsoleCommand(array|string $command, bool $throw = true): string | false
|
||||
{
|
||||
// phpcs:enable
|
||||
$process = \Illuminate\Support\Facades\Process::command($command)->run();
|
||||
|
|
@ -54,6 +54,7 @@ class ToolboxHelper
|
|||
/**
|
||||
* @param array<int|string, mixed> $array1
|
||||
* @param array<int|string, mixed> $array2
|
||||
*
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public static function arrayMergeRecursiveDistinct(array &$array1, array &$array2): array
|
||||
|
|
@ -66,6 +67,7 @@ class ToolboxHelper
|
|||
$merged[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $merged;
|
||||
}
|
||||
|
||||
|
|
@ -228,12 +230,11 @@ class ToolboxHelper
|
|||
/**
|
||||
* Mutltibyte string replace.
|
||||
*
|
||||
* @param array<string>|string $search
|
||||
* @param array<string>|string $replace
|
||||
* @param array<string>|string $subject
|
||||
* @param integer $count
|
||||
* @return array<string>|string|false
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
* @param array|string $search
|
||||
* @param array|string $replace
|
||||
* @param array|string $subject
|
||||
* @param integer $count
|
||||
* @return array|string|false
|
||||
*/
|
||||
public static function mbReplace(
|
||||
array|string $search,
|
||||
|
|
@ -247,58 +248,37 @@ class ToolboxHelper
|
|||
if (is_array($subject)) {
|
||||
// Call mb_replace for each single string in $subject .
|
||||
foreach ($subject as &$string) {
|
||||
$string = &self::mbReplace($search, $replace, $string, $count) ?: '';
|
||||
$string = &self::mbReplace($search, $replace, $string, $count);
|
||||
}
|
||||
return $subject;
|
||||
} elseif (is_array($search)) {
|
||||
if (!is_array($replace)) {
|
||||
foreach ($search as &$string) {
|
||||
$subject = self::mbReplace($string, $replace, $subject, $count) ?: '';
|
||||
$subject = self::mbReplace($string, $replace, $subject, $count);
|
||||
}
|
||||
} else {
|
||||
$n = max(count($search), count($replace));
|
||||
while ($n--) {
|
||||
$currentSearch = current($search);
|
||||
$currentReplace = current($replace);
|
||||
if ($currentSearch === false || $currentReplace === false) {
|
||||
break;
|
||||
}
|
||||
$result = self::mbReplace($currentSearch, $currentReplace, $subject, $count);
|
||||
$subject = is_string($result) ? $result : '';
|
||||
$subject = self::mbReplace(current($search), current($replace), $subject, $count);
|
||||
next($search);
|
||||
next($replace);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$parts = mb_split(preg_quote($search), $subject) ?: [];
|
||||
$count = (int) count($parts) - 1;
|
||||
$subject = implode(is_array($replace) ? '' : $replace, $parts);
|
||||
$parts = mb_split(preg_quote($search), $subject);
|
||||
$count = count($parts) - 1;
|
||||
$subject = implode($replace, $parts);
|
||||
} //end if
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Multibyte string replace (string only version).
|
||||
* Asserts that the field is unique.
|
||||
*
|
||||
* @param string $search
|
||||
* @param string $replace
|
||||
* @param string $subject
|
||||
* @return string
|
||||
*/
|
||||
public static function mbReplaceString(string $search, string $replace, string $subject): string
|
||||
{
|
||||
$parts = mb_split(preg_quote($search), $subject) ?: [];
|
||||
return implode($replace, $parts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the field is unique
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $field
|
||||
* @param string|integer|float|boolean|null|array<mixed> $value
|
||||
* @param integer|null $id
|
||||
* @param callable|null $query
|
||||
* @param string $table
|
||||
* @param string $field
|
||||
* @param string|integer|float|boolean|null|array $value
|
||||
* @param integer|null $id
|
||||
* @param callable|null $query
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If the field is not unique.
|
||||
*/
|
||||
|
|
@ -311,24 +291,20 @@ class ToolboxHelper
|
|||
): void {
|
||||
if (!$query) {
|
||||
Validator::make([$field => $value], [
|
||||
/** @phpstan-ignore-next-line */
|
||||
self::mbReplace('.', '\.', $field) => Rule::unique($table, $field)->ignore($id),
|
||||
], [
|
||||
/** @phpstan-ignore-next-line */
|
||||
self::mbReplace('.', '\.', "{$field}.unique") => trans('crud.libs.toolbox.assertFieldIsUnique', [
|
||||
'attribute' => $field,
|
||||
'value' => is_array($value) ? implode(', ', array_map('strval', $value)) : (string) $value,
|
||||
])
|
||||
self::mbReplace('.', '\.', "{$field}.unique")
|
||||
=> trans('crud.libs.toolbox.assertFieldIsUnique', ['attribute' => $field, 'value' => $value])
|
||||
])->validate();
|
||||
return;
|
||||
}
|
||||
Validator::make([$field => $value], [
|
||||
$field => Rule::unique($table)->where(\Closure::fromCallable($query))->ignore($id),
|
||||
$field => Rule::unique($table)->where($query)->ignore($id),
|
||||
], [
|
||||
$field . '.unique' => trans('crud.libs.toolbox.assertFieldIsUnique', [
|
||||
'attribute' => $field,
|
||||
'value' => is_array($value) ? implode(', ', array_map('strval', $value)) : (string) $value,
|
||||
])
|
||||
$field . '.unique' => trans(
|
||||
'crud.libs.toolbox.assertFieldIsUnique',
|
||||
['attribute' => $field, 'value' => $value]
|
||||
)
|
||||
])->validate();
|
||||
}
|
||||
|
||||
|
|
@ -361,20 +337,20 @@ class ToolboxHelper
|
|||
/**
|
||||
* Dynamic model query.
|
||||
*
|
||||
* @param string $defaultLocale
|
||||
* @param \Illuminate\Contracts\Database\Eloquent\Builder $q
|
||||
* @param string $column
|
||||
* @param string $value
|
||||
* @return \Illuminate\Contracts\Database\Eloquent\Builder
|
||||
* @param string $defaultLocale
|
||||
* @param \Illuminate\Database\Eloquent\Builder $q
|
||||
* @param string $column
|
||||
* @param string $value
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public static function queryColumnWithLocales(
|
||||
string $defaultLocale,
|
||||
Builder $q,
|
||||
string $column,
|
||||
string $value
|
||||
): \Illuminate\Contracts\Database\Eloquent\Builder {
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
$currentLocale = app()->currentLocale();
|
||||
$locales = collect((array) config('app.locales', []))
|
||||
$locales = collect(config('app.locales'))
|
||||
->mapWithKeys(fn (string $locale) => [$locale => $locale]);
|
||||
if (!$locales->has($defaultLocale)) {
|
||||
// * Remove default locale.
|
||||
|
|
@ -402,16 +378,15 @@ class ToolboxHelper
|
|||
/**
|
||||
* Generates an array from a dot separated string.
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $value
|
||||
* @param string|null $separator
|
||||
* @return array<mixed>
|
||||
* @param string $path
|
||||
* @param mixed $value
|
||||
* @param string $separator
|
||||
* @return array
|
||||
*/
|
||||
public static function dotStringToNestedArray(string $path, mixed $value, string|null $separator = null): array
|
||||
public static function dotStringToNestedArray(string $path, mixed $value, string $separator = '.'): array
|
||||
{
|
||||
$arr = $value;
|
||||
$separator = $separator ?: '.';
|
||||
$keys = array_reverse(explode($separator, $path));
|
||||
$arr = $value;
|
||||
$keys = array_reverse(explode($separator, $path));
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$arr = [$key => $arr];
|
||||
|
|
@ -423,7 +398,7 @@ class ToolboxHelper
|
|||
* Convert deeply an object to array.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return array<mixed>
|
||||
* @return array
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function objectToArray(mixed $input): array
|
||||
|
|
@ -432,7 +407,7 @@ class ToolboxHelper
|
|||
if (!(is_object($input) or is_array($input))) {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$ret = (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)) ?
|
||||
|
|
@ -454,25 +429,25 @@ class ToolboxHelper
|
|||
if (!(is_object($input) or is_array($input))) {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$ret = (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 (object) $ret;
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate picture.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|null $value
|
||||
* @param callable $fail
|
||||
* @param array{minWidth: int, maxWidth: int, minHeight: int, maxHeight: int} $sizes
|
||||
* @param string $attribute
|
||||
* @param string|null $value
|
||||
* @param callable $fail
|
||||
* @param object $sizes
|
||||
* @return void
|
||||
*/
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, array $sizes): void
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes): void
|
||||
{
|
||||
if (!($useStorage = Storage::exists($value)) and !File::exists($value)) {
|
||||
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
||||
|
|
@ -499,22 +474,22 @@ class ToolboxHelper
|
|||
$height = intval($dimensions[1]);
|
||||
|
||||
$xMessage = trans(
|
||||
":attribute la largeur doit être comprise entre {$sizes['minWidth']}px et {$sizes['maxWidth']}px"
|
||||
":attribute la largeur doit être comprise entre {$sizes->minWidth}px et {$sizes->maxWidth}px"
|
||||
);
|
||||
if ($sizes['minWidth'] === $sizes['maxWidth']) {
|
||||
$xMessage = trans(":attribute la largeur doit être de {$sizes['minWidth']}px");
|
||||
if ($sizes->minWidth === $sizes->maxWidth) {
|
||||
$xMessage = trans(":attribute la largeur doit être de {$sizes->minWidth}px");
|
||||
}
|
||||
$yMessage = trans(
|
||||
":attribute la hauteur doit être comprise entre {$sizes['minHeight']}px et {$sizes['maxHeight']}px"
|
||||
":attribute la hauteur doit être comprise entre {$sizes->minHeight}px et {$sizes->maxHeight}px"
|
||||
);
|
||||
if ($sizes['minHeight'] === $sizes['maxHeight']) {
|
||||
$yMessage = trans(":attribute la hauteur doit être de {$sizes['minHeight']}px");
|
||||
if ($sizes->minHeight === $sizes->maxHeight) {
|
||||
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minHeight}px");
|
||||
}
|
||||
|
||||
if (($width < $sizes['minWidth']) or ($width > $sizes['maxWidth'])) {
|
||||
if (($width < $sizes->minWidth) or ($width > $sizes->maxWidth)) {
|
||||
$fail($xMessage);
|
||||
}
|
||||
if (($height < $sizes['minHeight']) or ($height > $sizes['maxHeight'])) {
|
||||
if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) {
|
||||
$fail($yMessage);
|
||||
}
|
||||
} //end if
|
||||
|
|
@ -571,7 +546,7 @@ class ToolboxHelper
|
|||
{
|
||||
return Arr::where(
|
||||
static::getClassesUsingNamespace($namespace),
|
||||
fn (string $class_namespace) => \collect(class_implements($class_namespace, true) ?: [])->filter()
|
||||
fn (string $class_namespace) => \collect(class_implements($class_namespace, true))->filter()
|
||||
->contains(fn (string $class_interface) => $class_interface === $interface)
|
||||
);
|
||||
}
|
||||
|
|
@ -579,9 +554,9 @@ class ToolboxHelper
|
|||
/**
|
||||
* Get validated pagination from request.
|
||||
*
|
||||
* @param integer $default
|
||||
* @param string $field
|
||||
* @param class-string<\UnitEnum> $enumPath
|
||||
* @param integer $default
|
||||
* @param string $field
|
||||
* @param string $enumPath
|
||||
* @return integer
|
||||
*/
|
||||
public static function getValidatedEnum(int $default, string $field, string $enumPath): int
|
||||
|
|
|
|||
|
|
@ -46,10 +46,10 @@ class SendConfirmationMail extends Mailable
|
|||
*/
|
||||
private function sanitizeStringInputs(): void
|
||||
{
|
||||
$this->data = (object) Arr::map((array) $this->data, function ($el) {
|
||||
$this->data = (object)Arr::map((array)$this->data, function ($el) {
|
||||
if (is_string($el)) {
|
||||
$el = \htmlspecialchars(\strip_tags(Blade::render(
|
||||
(string) Markdown::parse($el)
|
||||
(string)Markdown::parse($el)
|
||||
)));
|
||||
$el = Str::of($el)->replaceMatches(
|
||||
'/[^\p{L}0-9\n\s\@\.\:\-\_\?\!\;\(\)\+\-\/\\\=]+/us',
|
||||
|
|
|
|||
|
|
@ -49,10 +49,10 @@ class SendContactMail extends Mailable
|
|||
*/
|
||||
private function sanitizeStringInputs(): void
|
||||
{
|
||||
$this->data = (object) Arr::map((array) $this->data, function ($el) {
|
||||
$this->data = (object)Arr::map((array)$this->data, function ($el) {
|
||||
if (is_string($el)) {
|
||||
$el = \htmlspecialchars(\strip_tags(Blade::render(
|
||||
(string) Markdown::parse($el)
|
||||
(string)Markdown::parse($el)
|
||||
)));
|
||||
$el = Str::of($el)->replaceMatches(
|
||||
'/[^\p{L}0-9\n\s\@\.\:\-\_\?\!\;\(\)\+\-\/\\\=]+/us',
|
||||
|
|
|
|||
|
|
@ -3,20 +3,25 @@
|
|||
namespace App\Models;
|
||||
|
||||
use App\Enums\ActivityLogs\ActivityLogsEventEnum;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property string $model Target model.
|
||||
* @property string $model_id Id of the target model.
|
||||
* @property \App\Enums\ActivityLogs\ActivityLogsEventEnum $event Event of this activity (ActivityLogsEventEnum).
|
||||
* @property array<string, mixed> $data Changes.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property array $data Changes.
|
||||
* @property \Illuminate\Support\Carbon $created_at Created date.
|
||||
*
|
||||
* @property-read \App\Models\User $user User BelongsTo relation.
|
||||
*/
|
||||
class ActivityLog extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use Notifiable;
|
||||
|
||||
/**
|
||||
* Indicates if the model should be timestamped.
|
||||
*
|
||||
|
|
@ -27,7 +32,7 @@ class ActivityLog extends Model
|
|||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'is_anonymous',
|
||||
|
|
@ -76,8 +81,7 @@ class ActivityLog extends Model
|
|||
$activity->model_id = $model->getKey();
|
||||
$activity->event = $eventEnum;
|
||||
$activity->data = static::getChangedColumns($activity, $model, $eventEnum);
|
||||
// @phpstan-ignore-next-line
|
||||
$activity->created_at = now();
|
||||
$activity->created_at = now();
|
||||
$activity->saveOrFail();
|
||||
}
|
||||
|
||||
|
|
@ -87,19 +91,17 @@ class ActivityLog extends Model
|
|||
* @param self $activity
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param \App\Enums\ActivityLogs\ActivityLogsEventEnum $eventEnum
|
||||
* @return array<string, string>
|
||||
* @return array
|
||||
*/
|
||||
public static function getChangedColumns(self $activity, Model $model, ActivityLogsEventEnum $eventEnum): array
|
||||
{
|
||||
$modelClassName = $activity->model_class;
|
||||
$modelTarget = new $modelClassName();
|
||||
|
||||
/** Get type of each fields of the target model */
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null $targetModel */
|
||||
$targetModel = ($modelTarget instanceof \Illuminate\Database\Eloquent\Model) ? $activity->model_class::where(
|
||||
$modelTarget->getRouteKeyName(),
|
||||
$targetModel = $activity->model_class::where(
|
||||
(new $modelClassName())->getRouteKeyName(),
|
||||
$activity->model_id
|
||||
)->first() : null;
|
||||
)->first();
|
||||
|
||||
if (\is_null($targetModel)) {
|
||||
return [];
|
||||
|
|
@ -131,7 +133,6 @@ class ActivityLog extends Model
|
|||
// phpcs:enable
|
||||
$type = \gettype($value);
|
||||
switch ($type) {
|
||||
// phpcs:ignore PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
|
||||
case 'string':
|
||||
return match (true) {
|
||||
Str::length(\strip_tags($value)) !== Str::length($value) => 'html',
|
||||
|
|
@ -162,12 +163,12 @@ class ActivityLog extends Model
|
|||
} //end switch
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
* User BelongsTo relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\User,$this>
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,142 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use App\Traits\Models\Orderable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class Aisle extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use Orderable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'title',
|
||||
'text',
|
||||
'picture',
|
||||
'picture_alt',
|
||||
'picture_title',
|
||||
'published',
|
||||
'network_id',
|
||||
'order',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'published' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* 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::deleting(function (self $model) {
|
||||
self::assertLimitPublishedModels($model, true);
|
||||
});
|
||||
static::deleted(function (self $model) {
|
||||
FileStorageHelper::removeFile($model, 'picture');
|
||||
self::setOrder($model, true);
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(self $model): void
|
||||
{
|
||||
// * ASSERTIONS
|
||||
self::assertLimitPublishedModels($model);
|
||||
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the limit of published models is reached.
|
||||
*
|
||||
* @param self $model
|
||||
* @param boolean $isDeletion
|
||||
* @throws \Illuminate\Validation\ValidationException If the limit of published models is reached.
|
||||
* @return void
|
||||
*/
|
||||
private static function assertLimitPublishedModels(self $model, bool $isDeletion = false)
|
||||
{
|
||||
$count = self::query()
|
||||
->where('published', true)
|
||||
->where('network_id', $model->network_id)
|
||||
->count();
|
||||
$updatePublished = !$isDeletion && $model->published && !$model->getOriginal('published');
|
||||
|
||||
if (
|
||||
(!$model->published && $count <= 1) ||
|
||||
($updatePublished && $count >= 4) ||
|
||||
($isDeletion && $count === 1)
|
||||
) {
|
||||
throw ValidationException::withMessages([
|
||||
'Il doit y avoir entre 1 et 4 éléments attachés à chaque réseau.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Group ordering by network_id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOrderGroupField(): string
|
||||
{
|
||||
return 'network_id';
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
|
||||
/**
|
||||
* The network that belongs to the logo.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Network,$this>
|
||||
*/
|
||||
public function network(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Network::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associated brands.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Brand,$this>
|
||||
*/
|
||||
public function brands(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Brand::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class Brand extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'text',
|
||||
'picture',
|
||||
'picture_alt',
|
||||
'picture_title',
|
||||
'link',
|
||||
'published',
|
||||
'aisle_id'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'published' => 'bool',
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
});
|
||||
static::updated(function (self $model) {
|
||||
FileStorageHelper::removeOldFile($model, 'picture');
|
||||
});
|
||||
static::deleting(function (self $model) {
|
||||
self::assertLimitPublishedModels($model, true);
|
||||
});
|
||||
static::deleted(function (self $model) {
|
||||
FileStorageHelper::removeFile($model, 'picture');
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(self $model): void
|
||||
{
|
||||
// * ASSERTIONS.
|
||||
self::assertLimitPublishedModels($model);
|
||||
|
||||
// * TRANSFORMATIONS.
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the limit of published models is reached.
|
||||
*
|
||||
* @param self $model
|
||||
* @param boolean $isDeletion
|
||||
* @throws \Illuminate\Validation\ValidationException If the limit of published models is reached.
|
||||
* @return void
|
||||
*/
|
||||
private static function assertLimitPublishedModels(self $model, bool $isDeletion = false)
|
||||
{
|
||||
$count = self::query()
|
||||
->where('published', true)
|
||||
->where('aisle_id', $model->aisle_id)
|
||||
->count();
|
||||
$updatePublished = !$isDeletion && $model->published && !$model->getOriginal('published');
|
||||
|
||||
if (
|
||||
$count !== 0 &&
|
||||
((!$model->published && $count <= 1) ||
|
||||
($updatePublished && $count >= 5) ||
|
||||
($isDeletion && $count === 1))
|
||||
) {
|
||||
throw ValidationException::withMessages([
|
||||
'Il doit y avoir entre 1 et 5 éléments publiés simultanément.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
|
||||
/**
|
||||
* Associated aisle.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Aisle,$this>
|
||||
*/
|
||||
public function aisle(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Aisle::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,102 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use App\Traits\Models\Orderable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property-read int $id Id.
|
||||
* @property string $title Title.
|
||||
* @property array $media Medias of the carousel.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship.
|
||||
*/
|
||||
class Carousel extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use Orderable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'section_id',
|
||||
'title',
|
||||
'media',
|
||||
'order',
|
||||
'published',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'media' => 'array',
|
||||
'published' => 'boolean',
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
$otherCarousels = self::query()
|
||||
->whereRelation('section', 'id', $model->section->id)
|
||||
->count();
|
||||
if ($otherCarousels > 4) {
|
||||
throw new \RuntimeException('Creating more than 5 carousels is not allowed');
|
||||
}
|
||||
self::setOrder($model);
|
||||
});
|
||||
static::updated(function (self $model) {
|
||||
FileStorageHelper::removeOldFiles(
|
||||
data_get(ToolboxHelper::getOriginal($model, 'media'), 'pictures.*.path', ['']),
|
||||
data_get($model->media, 'pictures.*.path', [''])
|
||||
);
|
||||
});
|
||||
static::deleted(function (self $model) {
|
||||
FileStorageHelper::removeOldFiles(
|
||||
data_get($model->media, 'pictures.*.path', ['']),
|
||||
['']
|
||||
);
|
||||
self::setOrder($model, true);
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
|
||||
/**
|
||||
* Group ordering by section_id.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getOrderGroupField(): string
|
||||
{
|
||||
return 'section_id';
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS.
|
||||
|
||||
/**
|
||||
* Get the sections that owns the Carousel
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\Section,$this>
|
||||
*/
|
||||
public function section(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Section::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,13 +26,12 @@ use Illuminate\Database\Eloquent\Model;
|
|||
class HistoricalMilestone extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\HistoricalMilestoneFactory> */
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'title',
|
||||
|
|
@ -79,7 +78,7 @@ class HistoricalMilestone extends Model
|
|||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
|
|
|
|||
|
|
@ -18,13 +18,12 @@ use Illuminate\Database\Eloquent\Model;
|
|||
class JobVideo extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\JobVideoFactory> */
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'title',
|
||||
|
|
|
|||
|
|
@ -21,13 +21,12 @@ use Illuminate\Database\Eloquent\Model;
|
|||
class Logo extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\LogoFactory> */
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'label',
|
||||
|
|
@ -58,7 +57,7 @@ class Logo extends Model
|
|||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
|
|
@ -71,12 +70,12 @@ class Logo extends Model
|
|||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
* The sites that belong to the logo.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany<\App\Models\Site,$this>
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function sites(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,163 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class Network extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'seo_title',
|
||||
'seo_description',
|
||||
'name',
|
||||
'slug',
|
||||
'title',
|
||||
'subtitle',
|
||||
'picture',
|
||||
'picture_alt',
|
||||
'picture_title',
|
||||
'button_text',
|
||||
'order',
|
||||
'published',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'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::deleting(function (self $model) {
|
||||
self::assertLimitPublishedModels($model, true);
|
||||
});
|
||||
static::deleted(function (self $model) {
|
||||
FileStorageHelper::removeFile($model, 'picture');
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(self $model): void
|
||||
{
|
||||
// * ASSERTIONS.
|
||||
self::assertLimitPublishedModels($model);
|
||||
self::assertFieldIsUnique('name', $model->name, $model->id);
|
||||
self::assertFieldIsUnique('slug', Str::slug($model->name), $model->id);
|
||||
|
||||
// * TRANSFORMATIONS.
|
||||
self::setSlug($model, $model->name);
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the slug.
|
||||
*
|
||||
* @param self $model
|
||||
* @param string $original
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function setSlug(self $model, string $original): void
|
||||
{
|
||||
$model->slug = Str::slug($original);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts using validation that the field is unique.
|
||||
*
|
||||
* @param string $nameField
|
||||
* @param string $valueField
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
*/
|
||||
private static function assertFieldIsUnique(string $nameField, string $valueField, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the limit of published models is reached.
|
||||
*
|
||||
* @param self $model
|
||||
* @param boolean $isDeletion
|
||||
* @throws \Illuminate\Validation\ValidationException If the limit of published models is reached.
|
||||
* @return void
|
||||
*/
|
||||
private static function assertLimitPublishedModels(self $model, bool $isDeletion = false)
|
||||
{
|
||||
$count = self::query()->where('published', true)->count();
|
||||
$updatePublished = !$isDeletion && $model->published && !$model->getOriginal('published');
|
||||
|
||||
if (
|
||||
(!$model->published && $count <= 1) ||
|
||||
($updatePublished && $count >= 5) ||
|
||||
($isDeletion && $count === 1)
|
||||
) {
|
||||
throw ValidationException::withMessages([
|
||||
'Il doit y avoir entre 1 et 5 éléments publiés simultanément.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
|
||||
/**
|
||||
* The aisles that belong to the logo.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Aisle,$this>
|
||||
*/
|
||||
public function aisles(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Aisle::class);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,14 +5,11 @@ namespace App\Models;
|
|||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use App\Traits\Models\PlanificatedStatus;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Spatie\Sitemap\Contracts\Sitemapable;
|
||||
use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $seo_title SEO title.
|
||||
* @property string $seo_description SEO description.
|
||||
* @property string $title Title.
|
||||
|
|
@ -30,21 +27,20 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
|||
* @property boolean $published Publication status.
|
||||
* @property \Carbon\Carbon|null $publish_at Publication date.
|
||||
* @property \Carbon\Carbon|null $unpublish_at Unpublication status update date.
|
||||
* @property \Carbon\Carbon $displayed_date News dipslayed date.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship.
|
||||
*/
|
||||
class News extends Model implements Sitemapable
|
||||
class News extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use PlanificatedStatus;
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'seo_title',
|
||||
|
|
@ -64,7 +60,6 @@ class News extends Model implements Sitemapable
|
|||
'published',
|
||||
'publish_at',
|
||||
'unpublish_at',
|
||||
'displayed_date',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -73,10 +68,9 @@ class News extends Model implements Sitemapable
|
|||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'published' => 'bool',
|
||||
'publish_at' => 'datetime',
|
||||
'unpublish_at' => 'datetime',
|
||||
'displayed_date' => 'datetime',
|
||||
'published' => 'bool',
|
||||
'publish_at' => 'datetime',
|
||||
'unpublish_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -102,7 +96,7 @@ class News extends Model implements Sitemapable
|
|||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
|
|
@ -169,15 +163,50 @@ class News extends Model implements Sitemapable
|
|||
}
|
||||
|
||||
/**
|
||||
* To sitemap tag method.
|
||||
* Adjusts model status using current status and publish dates.
|
||||
*
|
||||
* @return \Spatie\Sitemap\Tags\Url|string|array<int|string, mixed>
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
public function toSitemapTag(): \Spatie\Sitemap\Tags\Url | string | array
|
||||
private static function makeStatusSense(self $model): void
|
||||
{
|
||||
$model = $this;
|
||||
$route = 'fo.news.show';
|
||||
$params = ['publishedNews' => $model];
|
||||
return SitemapHelper::generateUrl($route, $params, $model);
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$publish_at = $model->publish_at;
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$unpublish_at = $model->unpublish_at;
|
||||
$wantedStatus = $model->published;
|
||||
if ($publish_at or $unpublish_at) {
|
||||
$model->published = $model->planificated_status;
|
||||
}
|
||||
if ($wantedStatus !== $model->published) {
|
||||
$previousMessage = session()->get('bo.info', '');
|
||||
session()->flash('bo.info', \trans(
|
||||
'La publication est modifiée en concordance avec les dates enregistrées.
|
||||
Pour modifier l\'état de publication, veuillez modifier ou enlever les dates correspondantes.'
|
||||
) . " \n{$previousMessage}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter the current status following planification dates planificated_status.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getPlanificatedStatusAttribute(): bool
|
||||
{
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$publish_at = $this->publish_at;
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$unpublish_at = $this->unpublish_at;
|
||||
if ($publish_at and $unpublish_at) {
|
||||
return $unpublish_at->greaterThanOrEqualTo(now()) and $publish_at->lessThan(now());
|
||||
}
|
||||
if ($publish_at) {
|
||||
return $publish_at->lessThan(now());
|
||||
}
|
||||
if ($unpublish_at) {
|
||||
return $unpublish_at->greaterThanOrEqualTo(now());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,14 +12,12 @@ use App\Traits\Models\MiniCrudModel;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\StaticPage;
|
||||
use App\Enums\StaticPageType;
|
||||
|
||||
/**
|
||||
* @property \App\Enums\Sections\PageSectionEnum $section Slider that contains the slide.
|
||||
* @property string $h2_title Title.
|
||||
* @property string $text WYSIWYG - Content.
|
||||
* @property array $data Minicrud content.
|
||||
* @property string $data Minicrud content.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*
|
||||
|
|
@ -29,14 +27,13 @@ use App\Enums\StaticPageType;
|
|||
class Section extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\SectionFactory> */
|
||||
use HasFactory;
|
||||
use MiniCrudModel;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'section',
|
||||
|
|
@ -56,7 +53,7 @@ class Section extends Model
|
|||
*/
|
||||
protected $casts = [
|
||||
'section' => PageSectionEnum::class,
|
||||
'data' => 'array',
|
||||
'data' => 'object',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -77,7 +74,6 @@ class Section extends Model
|
|||
$model->text = FileStorageHelper::storeModelFilesFromHtml($model, $model->text);
|
||||
});
|
||||
static::updated(function (self $model) {
|
||||
$model->minicrudUpdated();
|
||||
FileStorageHelper::removeOldModelFilesFromHtml(
|
||||
$model->text,
|
||||
ToolboxHelper::getOriginal($model, 'text')
|
||||
|
|
@ -89,19 +85,20 @@ class Section extends Model
|
|||
}
|
||||
|
||||
// * METHODS.
|
||||
// * EMPTY BLOCS.
|
||||
|
||||
/**
|
||||
* Empty bloc for picture.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param string $img
|
||||
* @param string $imgAlt
|
||||
* @param string $imgTitle
|
||||
* @param integer $width
|
||||
* @param integer $height
|
||||
* @param boolean $required
|
||||
* @param string $name
|
||||
* @return array<string, mixed>
|
||||
* @param array $data
|
||||
* @param string $img
|
||||
* @param string $imgAlt
|
||||
* @param string $imgTitle
|
||||
* @param integer $width
|
||||
* @param integer $height
|
||||
* @param boolean $required
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public static function emptyPictureBloc(
|
||||
array $data,
|
||||
|
|
@ -129,11 +126,11 @@ class Section extends Model
|
|||
/**
|
||||
* Empty bloc for link.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param string $url
|
||||
* @param boolean $required
|
||||
* @param string $name
|
||||
* @return array<string, mixed>
|
||||
* @param array $data
|
||||
* @param string $url
|
||||
* @param boolean $required
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public static function emptyLinkBloc(
|
||||
array $data,
|
||||
|
|
@ -141,7 +138,7 @@ class Section extends Model
|
|||
bool $required = false,
|
||||
string $name = "URL à ouvrir",
|
||||
): array {
|
||||
$data[sprintf('bloc_%s', Str::of($name)->snake()->ascii()->remove(['\'', '-']))] = [
|
||||
$data["bloc_link"] = [
|
||||
'label' => $name,
|
||||
'inputType' => InputType::url->value,
|
||||
'value' => $url,
|
||||
|
|
@ -154,9 +151,9 @@ class Section extends Model
|
|||
/**
|
||||
* Empty bloc for boolean new tab link.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param string $name
|
||||
* @return array<string, mixed>
|
||||
* @param array $data
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public static function emptyLinkNewTabBloc(
|
||||
array $data,
|
||||
|
|
@ -173,11 +170,12 @@ class Section extends Model
|
|||
/**
|
||||
* Empty bloc for key numbers.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param string $name
|
||||
* @param integer $value
|
||||
* @param boolean $required
|
||||
* @return array<string, mixed>
|
||||
* @param array $data
|
||||
* @param string $name
|
||||
* @param integer $value
|
||||
* @param boolean $required
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function emptyKeyNumberBloc(
|
||||
array $data,
|
||||
|
|
@ -198,41 +196,18 @@ class Section extends Model
|
|||
/**
|
||||
* Empty bloc for the button boolean.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param string $name
|
||||
* @param boolean $value
|
||||
* @return array<string, mixed>
|
||||
* @param array $data
|
||||
* @param string $name
|
||||
* @return array
|
||||
*/
|
||||
public static function emptyButtonBooleanBloc(
|
||||
array $data,
|
||||
string $name,
|
||||
bool $value = false
|
||||
string $name
|
||||
): array {
|
||||
$data['bloc_button_' . Str::of($name)->snake()->ascii()->remove(['\'', '-'])] = [
|
||||
'label' => "Afficher le bouton '{$name}' ?",
|
||||
'inputType' => InputType::boolean->value,
|
||||
'value' => $value
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty bloc for a boolean.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param string $name
|
||||
* @param boolean $value
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public static function emptyBooleanBloc(
|
||||
array $data,
|
||||
string $name,
|
||||
bool $value = false
|
||||
): array {
|
||||
$data['bloc_boolean_' . Str::of($name)->snake()->ascii()->remove(['\'', '-'])] = [
|
||||
'label' => "{$name} ?",
|
||||
'inputType' => InputType::boolean->value,
|
||||
'value' => $value
|
||||
'value' => false
|
||||
];
|
||||
return $data;
|
||||
}
|
||||
|
|
@ -240,11 +215,11 @@ class Section extends Model
|
|||
/**
|
||||
* Empty bloc for the h3 title.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param boolean $required
|
||||
* @return array<string, mixed>
|
||||
* @param array $data
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param boolean $required
|
||||
* @return array
|
||||
*/
|
||||
public static function emptyStringBloc(
|
||||
array $data,
|
||||
|
|
@ -265,18 +240,18 @@ class Section extends Model
|
|||
/**
|
||||
* Empty bloc for the WYSIWYG content.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @param array $data
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @param \App\Enums\CkEditorConfigName $config
|
||||
* @param boolean $required
|
||||
* @return array<string, mixed>
|
||||
* @return array
|
||||
*/
|
||||
public static function emptyWysiwygBloc(
|
||||
array $data,
|
||||
string $name,
|
||||
string $value = '',
|
||||
CkEditorConfigName $config = CkEditorConfigName::basic,
|
||||
CkEditorConfigName $config = CkEditorConfigName::base,
|
||||
bool $required = false
|
||||
): array {
|
||||
$data['bloc_' . Str::of($name)->snake()->ascii()->remove(['\'', '-']) . '_content'] = [
|
||||
|
|
@ -290,221 +265,15 @@ class Section extends Model
|
|||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add part piece.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPartPiece(): void
|
||||
{
|
||||
$pieceTemplateLinesCount = self::countPartPieces();
|
||||
|
||||
$pieceToAdd = self::getAddablePartPieceBlock(
|
||||
$this->section,
|
||||
$this->countPartPieces() + 1
|
||||
);
|
||||
|
||||
/** @var array<string, mixed> $rawData */
|
||||
$rawData = $this->data;
|
||||
$data = collect($rawData);
|
||||
$linesToSkip = 1;
|
||||
|
||||
$groupedPieces = $data->skip($linesToSkip)->splitIn($data->count() / ($pieceTemplateLinesCount ?: 1))
|
||||
->concat([$pieceToAdd])
|
||||
->sort(function ($aCollect, $bCollect) {
|
||||
if ($this->section->equals(PageSectionEnum::produce_rhd)) {
|
||||
/** @var array<string, mixed> $aFirst */
|
||||
$aFirst = collect($aCollect)->first();
|
||||
/** @var array<string, mixed> $bFirst */
|
||||
$bFirst = collect($bCollect)->first();
|
||||
return strcmp(
|
||||
strrev((string) collect($aFirst)->first()),
|
||||
strrev((string) collect($bFirst)->first())
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
$groupedPieces->prepend([$data->keys()->first() => $data->first()]);
|
||||
$this->data = $groupedPieces->collapse()->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove part piece.
|
||||
*
|
||||
* @param integer $index
|
||||
* @return integer Elements count removed.
|
||||
*/
|
||||
public function removePartPiece(int $index): int
|
||||
{
|
||||
$pieceTemplate = self::getPartPieces();
|
||||
$pieceTemplateLinesCount = self::countPartPieces();
|
||||
if (!$pieceTemplateLinesCount) {
|
||||
return 0;
|
||||
}
|
||||
$linesToSkip = 1;
|
||||
$data = collect($this->data);
|
||||
$groupedPieces = $data->skip($linesToSkip)->splitIn($data->count() / count($pieceTemplate));
|
||||
$removedGroup = $groupedPieces->splice($index - 1, 1);
|
||||
$this->data = $groupedPieces->collapse()
|
||||
->prepend($data->first(), $data->keys()->first())
|
||||
->all();
|
||||
return $removedGroup->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count part pieces.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function countPartPieces(): int
|
||||
{
|
||||
$pieceTemplate = self::getPartPieces();
|
||||
$data = collect($this->data);
|
||||
$templateKeys = collect($pieceTemplate)->keys();
|
||||
$dataCount = $data->count();
|
||||
$repetitionCount = 0;
|
||||
for ($i = 1; $i <= $dataCount; $i++) {
|
||||
$indexKeys = $templateKeys->map(fn($key) => str_replace('__index', strval($i), $key));
|
||||
if ($indexKeys->every(fn($key) => $data->has($key))) {
|
||||
$repetitionCount++;
|
||||
}
|
||||
}
|
||||
return $repetitionCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get part pieces.
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function getPartPieces(): array
|
||||
{
|
||||
$pieceTemplate = self::getAddablePartPieceBlockTemplate($this->section);
|
||||
return is_null($pieceTemplate) ? [] : $pieceTemplate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Addable part piece block.
|
||||
*
|
||||
* @param \App\Enums\Sections\PageSectionEnum $sectionEnum
|
||||
* @param integer $index
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
public static function getAddablePartPieceBlock(PageSectionEnum $sectionEnum, int $index = 1): array|null
|
||||
{
|
||||
$data = null;
|
||||
$pieceTemplate = self::getAddablePartPieceBlockTemplate($sectionEnum);
|
||||
if (!is_null($pieceTemplate)) {
|
||||
$encoded = json_encode($pieceTemplate);
|
||||
if ($encoded !== false) {
|
||||
/** @var array<string, mixed> $data */
|
||||
$data = json_decode(Str::of($encoded)->replace('__index', strval($index)), true);
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Addable part piece block.
|
||||
*
|
||||
* @param \App\Enums\Sections\PageSectionEnum $sectionEnum
|
||||
* @return array<int, string>|null
|
||||
*/
|
||||
public static function getAddablePartPieceBlockIndexes(PageSectionEnum $sectionEnum): array|null
|
||||
{
|
||||
$data = self::getAddablePartPieceBlockTemplate($sectionEnum);
|
||||
if (!is_null($data)) {
|
||||
return array_keys($data);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Addable part piece block template.
|
||||
*
|
||||
* @param \App\Enums\Sections\PageSectionEnum $sectionEnum
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private static function getAddablePartPieceBlockTemplate(PageSectionEnum $sectionEnum): array|null
|
||||
{
|
||||
$data = null;
|
||||
switch ($sectionEnum) {
|
||||
case PageSectionEnum::produce_export:
|
||||
$data = array_merge(
|
||||
self::emptyWysiwygBloc(
|
||||
[],
|
||||
"accompagnant l'image __index de la partie",
|
||||
''
|
||||
),
|
||||
self::emptyPictureBloc([], '', '', '', 100, 100, true, "Image __index de la partie"),
|
||||
self::emptyLinkBloc([], '', false, "Lien de l'image__index de la partie")
|
||||
);
|
||||
break;
|
||||
case PageSectionEnum::produce_rhd:
|
||||
$data = array_merge(
|
||||
self::emptyWysiwygBloc(
|
||||
[],
|
||||
"accompagnant l'image __index de la partie 1",
|
||||
''
|
||||
),
|
||||
self::emptyPictureBloc([], '', '', '', 100, 100, true, "Image __index de la partie 1"),
|
||||
self::emptyLinkBloc([], '', false, "Lien de l'image__index de la partie 1")
|
||||
);
|
||||
break;
|
||||
default:
|
||||
} //end switch
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of sections for a page type.
|
||||
*
|
||||
* @param \App\Enums\StaticPageType $type
|
||||
* @return \Illuminate\Database\Eloquent\Collection<int, self>
|
||||
*/
|
||||
public static function getSections(StaticPageType $type): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', $type)->first();
|
||||
$sectionModels = self::where('page_id', $staticPageModel->id)->get();
|
||||
|
||||
return $sectionModels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active section for a type page.
|
||||
*
|
||||
* @param \App\Enums\StaticPageType $type
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isActive(StaticPageType $type)
|
||||
{
|
||||
$staticPage = StaticPage::getStaticPage($type);
|
||||
return $staticPage->sections->contains(
|
||||
function ($section) {
|
||||
return request()->is("bo/sections/$section->id/edit");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
* Get the page that owns the section.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\StaticPage,$this>
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function page(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(StaticPage::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the sections that own the carousel.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Carousel,$this>
|
||||
*/
|
||||
public function carousels(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Carousel::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@ use App\Traits\Models\ActivityLog;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Spatie\Sitemap\Contracts\Sitemapable;
|
||||
use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
||||
|
||||
/**
|
||||
* @property string $seo_title SEO title.
|
||||
|
|
@ -31,8 +29,6 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
|||
* @property string $highlights WYSIWYG - Highlights part content.
|
||||
* @property double $latitude Latitude in degrees.
|
||||
* @property double $longitude Longitude in degrees.
|
||||
* @property string $sticky_title Sticky item title.
|
||||
* @property string $sticky_link Sticky item link.
|
||||
* @property string $logo Path of the logo.
|
||||
* @property string $logo_alt Logo alt attribute.
|
||||
* @property string $logo_title Logo title attribute.
|
||||
|
|
@ -52,16 +48,15 @@ use Uwil\SitemapGenerator\Lib\SitemapHelper;
|
|||
* @property-read \App\Models\Logo $logos Logos Many-to-many relationship.
|
||||
* @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship.
|
||||
*/
|
||||
class Site extends Model implements Sitemapable
|
||||
class Site extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\SiteFactory> */
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'seo_title',
|
||||
|
|
@ -76,17 +71,13 @@ class Site extends Model implements Sitemapable
|
|||
'phone_number',
|
||||
'access_line',
|
||||
'director_name',
|
||||
'director_function',
|
||||
'director_speach',
|
||||
'invert_director_block',
|
||||
'employee_name',
|
||||
'employee_function',
|
||||
'employee_speach',
|
||||
'highlights',
|
||||
'latitude',
|
||||
'longitude',
|
||||
'sticky_title',
|
||||
'sticky_link',
|
||||
'logo',
|
||||
'logo_alt',
|
||||
'logo_title',
|
||||
|
|
@ -108,9 +99,8 @@ class Site extends Model implements Sitemapable
|
|||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'pictos' => 'array',
|
||||
'access_line' => 'array',
|
||||
'invert_director_block' => 'boolean'
|
||||
'pictos' => 'array',
|
||||
'access_line' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -142,7 +132,7 @@ class Site extends Model implements Sitemapable
|
|||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
|
|
@ -202,25 +192,12 @@ class Site extends Model implements Sitemapable
|
|||
ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* To sitemap tag method.
|
||||
*
|
||||
* @return \Spatie\Sitemap\Tags\Url|string|array<int|string, mixed>
|
||||
*/
|
||||
public function toSitemapTag(): \Spatie\Sitemap\Tags\Url | string | array
|
||||
{
|
||||
$model = $this;
|
||||
$route = 'fo.sites.show';
|
||||
$params = ['site' => $model];
|
||||
return SitemapHelper::generateUrl($route, $params, $model);
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
* The logos that belong to the site.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany<\App\Models\Logo,$this>
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function logos(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ use App\Lib\Helpers\FileStorageHelper;
|
|||
use App\Traits\Models\ActivityLog;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* @property \App\Enums\Slides\SliderTypeEnum $type Slide type.
|
||||
|
|
@ -29,19 +28,12 @@ use Illuminate\Validation\ValidationException;
|
|||
class Slide extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\SlideFactory> */
|
||||
use HasFactory;
|
||||
|
||||
/** @var integer Minimum number of published slides */
|
||||
private static int $min = 1;
|
||||
|
||||
/** @var integer Maximum number of published slides */
|
||||
private static int $max = 3;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'type',
|
||||
|
|
@ -76,14 +68,6 @@ class Slide extends Model
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
if (
|
||||
$model->type === SliderTypeEnum::team &&
|
||||
self::query()->where('type', SliderTypeEnum::team)->count() + 1 > $model::getMaxPublished()
|
||||
) {
|
||||
throw ValidationException::withMessages([
|
||||
'slide' => 'Il ne peut y avoir que 3 slides en même temps.'
|
||||
]);
|
||||
}
|
||||
self::manageFields($model);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
|
|
@ -92,22 +76,12 @@ class Slide extends Model
|
|||
static::updated(function (self $model) {
|
||||
FileStorageHelper::removeOldFile($model, 'picture');
|
||||
});
|
||||
static::deleting(function (self $model) {
|
||||
if (
|
||||
$model->type === SliderTypeEnum::team &&
|
||||
self::query()->where('type', SliderTypeEnum::team)->count() - 1 < $model::getMinPublished()
|
||||
) {
|
||||
throw ValidationException::withMessages([
|
||||
'slide' => 'Il doit y avoir au mininmum 1 slide d\'active.'
|
||||
]);
|
||||
}
|
||||
});
|
||||
static::deleted(function (self $model) {
|
||||
FileStorageHelper::removeFile($model, 'picture');
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
|
|
@ -119,24 +93,4 @@ class Slide extends Model
|
|||
{
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the $min property.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function getMinPublished(): int
|
||||
{
|
||||
return self::$min;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for the $max property.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public static function getMaxPublished(): int
|
||||
{
|
||||
return self::$max;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,23 +3,19 @@
|
|||
namespace App\Models;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @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 string $picture Slide picture path.
|
||||
* @property string $picture_alt Slide picture alt attribute.
|
||||
* @property string $picture_title Slide picture title attribute.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
|
|
@ -28,20 +24,18 @@ use Illuminate\Support\Str;
|
|||
class StaticPage extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'seo_title',
|
||||
'seo_description',
|
||||
'title',
|
||||
'content',
|
||||
'picture',
|
||||
'picture_alt',
|
||||
'picture_title',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -61,17 +55,20 @@ class StaticPage extends Model
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
// * ASSERTIONS
|
||||
self::assertTitleIsUnique($model->title);
|
||||
// * CHANGES
|
||||
$model->slug = Str::slug($model->title);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
});
|
||||
static::updated(function (self $model) {
|
||||
FileStorageHelper::removeOldFile($model, 'picture');
|
||||
// * ASSERTIONS
|
||||
self::assertTitleIsUnique($model->title, $model->id);
|
||||
// * CHANGES
|
||||
$model->slug = Str::slug($model->title);
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
// * ROUTABLE
|
||||
|
||||
/**
|
||||
* Get the value of the model's route key.
|
||||
|
|
@ -97,39 +94,7 @@ class StaticPage extends Model
|
|||
return 'type';
|
||||
}
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(self $model): void
|
||||
{
|
||||
// * ASSERTIONS
|
||||
self::assertTitleIsUnique($model->title, $model->id);
|
||||
if ($model->content) {
|
||||
ToolboxHelper::assertNoInternalBoUrls('content', $model->content);
|
||||
$model->content = clean($model->content);
|
||||
}
|
||||
if ($model->picture) {
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
// * TRANSFORMATIONS
|
||||
self::setSlug($model, $model->title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the slug.
|
||||
*
|
||||
* @param self $model
|
||||
* @param string $original
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function setSlug(self $model, string $original): void
|
||||
{
|
||||
$model->slug = Str::slug($original);
|
||||
}
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Asserts using validation that the title is unique
|
||||
|
|
@ -145,28 +110,4 @@ class StaticPage extends Model
|
|||
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the static page for a page type.
|
||||
*
|
||||
* @param \App\Enums\StaticPageType $type
|
||||
* @return \App\Models\StaticPage
|
||||
*/
|
||||
public static function getStaticPage(StaticPageType $type): \App\Models\StaticPage
|
||||
{
|
||||
$query = (new self())->where('type', $type)->first();
|
||||
return $query;
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany<\App\Models\Section,$this>
|
||||
*/
|
||||
public function sections(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Section::class, 'page_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Enums\StickiesColorEnum;
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property \App\Enums\StaticPageType $type Page type (StaticPageEnum).
|
||||
* @property string $title Title for the sticky.
|
||||
* @property string $anchor Anchor for the sticky.
|
||||
* @property \App\Enums\StickiesColorEnum $color Color of the button (StickiesColorEnum).
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship.
|
||||
*/
|
||||
class Sticky extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'type',
|
||||
'title',
|
||||
'anchor',
|
||||
'color',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'type' => StaticPageType::class,
|
||||
'color' => StickiesColorEnum::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function () {
|
||||
// * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() < RoleEnum::conceptor->value(),
|
||||
AuthorizationException::class
|
||||
);
|
||||
});
|
||||
static::deleting(function () {
|
||||
// // * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() < RoleEnum::conceptor->value(),
|
||||
AuthorizationException::class
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -3,43 +3,34 @@
|
|||
namespace App\Models;
|
||||
|
||||
use App\Enums\Strips\PictoEnum;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use App\Traits\Models\PlanificatedStatus;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property App\Enums\Strips\PictoEnum|null $picto Picto.
|
||||
* @property string|null $picture Strip picture path.
|
||||
* @property string|null $picture_alt Strip picture alt attribute.
|
||||
* @property string|null $picture_title Strip picture title attribute.
|
||||
* @property string $text WYSIWYG restrained (blod and underline only). Text.
|
||||
* @property boolean $published Publication status.
|
||||
* @property \Carbon\Carbon|null $publish_at Publication date.
|
||||
* @property \Carbon\Carbon|null $unpublish_at Unpublication status update date.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
* @property-read \App\Models\News $news News Belongs to relationship.
|
||||
* @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship.
|
||||
* @property App\Enums\Strips\PictoEnum $picto Picto.
|
||||
* @property string $text WYSIWYG restrained (blod and underline only). Text.
|
||||
* @property boolean $published Publication status.
|
||||
* @property \Carbon\Carbon|null $publish_at Publication date.
|
||||
* @property \Carbon\Carbon|null $unpublish_at Unpublication status update date.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\News $news News Belongs to relationship.
|
||||
* @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship.
|
||||
*/
|
||||
class Strip extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\StripFactory> */
|
||||
use HasFactory;
|
||||
use PlanificatedStatus;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'picto',
|
||||
'picture',
|
||||
'picture_alt',
|
||||
'picture_title',
|
||||
'text',
|
||||
'published',
|
||||
'publish_at',
|
||||
|
|
@ -72,15 +63,9 @@ class Strip extends Model
|
|||
static::updating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
});
|
||||
static::updated(function (self $model) {
|
||||
FileStorageHelper::removeOldFile($model, 'picture');
|
||||
});
|
||||
static::deleted(function (self $model) {
|
||||
FileStorageHelper::removeFile($model, 'picture');
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
|
|
@ -91,17 +76,62 @@ class Strip extends Model
|
|||
private static function manageFields(self $model): void
|
||||
{
|
||||
self::makeStatusSense($model);
|
||||
if ($model->picture) {
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts model status using current status and publish dates
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function makeStatusSense(self $model): void
|
||||
{
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$publish_at = $model->publish_at;
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$unpublish_at = $model->unpublish_at;
|
||||
$wantedStatus = $model->published;
|
||||
if ($publish_at or $unpublish_at) {
|
||||
$model->published = $model->planificated_status;
|
||||
}
|
||||
if ($wantedStatus !== $model->published) {
|
||||
$previousMessage = session()->get('bo.info', '');
|
||||
session()->flash('bo.info', \trans(
|
||||
'La publication est modifiée en concordance avec les dates enregistrées.
|
||||
Pour modifier l\'état de publication, veuillez modifier ou enlever les dates correspondantes.'
|
||||
) . " \n{$previousMessage}");
|
||||
}
|
||||
}
|
||||
|
||||
// * RELATIONS.
|
||||
/**
|
||||
* Getter the current status following planification dates planificated_status.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getPlanificatedStatusAttribute(): bool
|
||||
{
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$publish_at = $this->publish_at;
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$unpublish_at = $this->unpublish_at;
|
||||
if ($publish_at and $unpublish_at) {
|
||||
return $unpublish_at->greaterThanOrEqualTo(now()) and $publish_at->lessThan(now());
|
||||
}
|
||||
if ($publish_at) {
|
||||
return $publish_at->lessThan(now());
|
||||
}
|
||||
if ($unpublish_at) {
|
||||
return $unpublish_at->greaterThanOrEqualTo(now());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
* Get the news that owns the strip.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<\App\Models\News,$this>
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function news(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,13 +24,12 @@ use Illuminate\Database\Eloquent\Model;
|
|||
class Testimonial extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\TestimonialFactory> */
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
|
|
@ -72,7 +71,7 @@ class Testimonial extends Model
|
|||
});
|
||||
}
|
||||
|
||||
// * METHODS.
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
|
|
|
|||
|
|
@ -8,11 +8,13 @@ use Illuminate\Auth\Access\AuthorizationException;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
/**
|
||||
* @property string $first_name Firstname.
|
||||
* @property string $last_name Lastname.
|
||||
* @property string $email Email.
|
||||
* @property string $password Password.
|
||||
* @property \App\Enums\Users\RoleEnum $role Role.
|
||||
* @property \Illuminate\Support\Carbon $published Published status.
|
||||
* @property \Illuminate\Support\Carbon $published_at Publication status update date.
|
||||
|
|
@ -24,14 +26,13 @@ use Illuminate\Notifications\Notifiable;
|
|||
class User extends Authenticatable
|
||||
{
|
||||
use ActivityLog;
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory;
|
||||
use Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'first_name',
|
||||
|
|
@ -46,9 +47,10 @@ class User extends Authenticatable
|
|||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
|
|
@ -58,10 +60,10 @@ class User extends Authenticatable
|
|||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'role' => RoleEnum::class,
|
||||
'last_connection' => 'date',
|
||||
'published' => 'boolean',
|
||||
'published_at' => 'datetime',
|
||||
'role' => RoleEnum::class,
|
||||
'email_verified_at' => 'datetime',
|
||||
'published' => 'boolean',
|
||||
'published_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -72,6 +74,7 @@ class User extends Authenticatable
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
// * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() > $model->role->value(),
|
||||
|
|
@ -79,6 +82,7 @@ class User extends Authenticatable
|
|||
);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
if (optional(auth('backend')->user())->getKey() === $model->getKey()) {
|
||||
\validator(
|
||||
['published' => $model->published],
|
||||
|
|
@ -93,4 +97,19 @@ class User extends Authenticatable
|
|||
);
|
||||
});
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Update password.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function updatePassword(self $model): void
|
||||
{
|
||||
if (Hash::needsRehash($model->password)) {
|
||||
$model->password = Hash::make($model->password);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,120 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Models\User;
|
||||
use App\Policies\Rules\UserStaticRules;
|
||||
|
||||
class AislePolicy
|
||||
{
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function viewAny(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function view(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function create(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function update(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function restore(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function forceDelete(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can duplicate the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function duplicate(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can publish/unpublish the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changePublished(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can change the order of the model.
|
||||
*
|
||||
* @param \App\Models\User $authUser
|
||||
* @return boolean
|
||||
*/
|
||||
public function changeOrder(User $authUser): bool
|
||||
{
|
||||
return UserStaticRules::atLeastRole($authUser, RoleEnum::admin);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue