Merge branch 'trunk'
This commit is contained in:
commit
d9c4c1b791
361 changed files with 22600 additions and 29170 deletions
5
.browserslistrc
Normal file
5
.browserslistrc
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Browsers that we support
|
||||
|
||||
last 3 version
|
||||
> 0.3%
|
||||
not dead # no browsers without security updates
|
||||
|
|
@ -3,9 +3,9 @@ root = true
|
|||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
|
|
@ -14,8 +14,8 @@ trim_trailing_whitespace = false
|
|||
[*.{yml,yaml}]
|
||||
indent_size = 2
|
||||
|
||||
[*.vue]
|
||||
indent_size = 2
|
||||
|
||||
[docker-compose.yml]
|
||||
indent_size = 4
|
||||
|
||||
[*.vue]
|
||||
indent_size = 2
|
||||
|
|
|
|||
|
|
@ -10,16 +10,16 @@
|
|||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.vue"],
|
||||
"rules": {
|
||||
"no-undef": "off"
|
||||
}
|
||||
"files": ["*.ts", "*.vue"],
|
||||
"rules": {
|
||||
"no-undef": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["*.vue"],
|
||||
"rules": {
|
||||
"indent": "off"
|
||||
}
|
||||
"files": ["*.vue"],
|
||||
"rules": {
|
||||
"indent": "off"
|
||||
}
|
||||
}
|
||||
],
|
||||
"parser": "vue-eslint-parser",
|
||||
|
|
@ -37,5 +37,19 @@
|
|||
"semi": ["error", "always"],
|
||||
"vue/script-indent": ["error", 2, { "baseIndent": 0, "switchCase": 1 }],
|
||||
"vue/one-component-per-file": "off"
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"node": {
|
||||
"extensions": [".js", ".vue", ".ts", ".d.ts"]
|
||||
},
|
||||
"alias": {
|
||||
"extensions": [".vue", ".js", ".ts", ".scss", ".d.ts"],
|
||||
"map": [
|
||||
["~", "./resources/assets"],
|
||||
["@", "./node_modules"]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
.gitattributes
vendored
3
.gitattributes
vendored
|
|
@ -1,4 +1,4 @@
|
|||
* text=auto
|
||||
* text=auto eol=lf
|
||||
|
||||
*.blade.php diff=html
|
||||
*.css diff=css
|
||||
|
|
@ -8,3 +8,4 @@
|
|||
|
||||
/.github export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
.styleci.yml export-ignore
|
||||
|
|
|
|||
29
.gitignore
vendored
29
.gitignore
vendored
|
|
@ -1,21 +1,24 @@
|
|||
/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
/public/build
|
||||
/public/medias
|
||||
/public/uploads
|
||||
/public/cache
|
||||
/public/sitemap.xml
|
||||
/storage/*.key
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpunit.result.cache
|
||||
.stylelintcache
|
||||
/.fleet
|
||||
/.idea
|
||||
/.phpunit.cache
|
||||
/.vscode
|
||||
/node_modules
|
||||
/public/build
|
||||
/public/cache
|
||||
/public/hot
|
||||
/public/sitemap.xml
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/vendor
|
||||
auth.json
|
||||
docker-compose.override.yml
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
/.idea
|
||||
/.vscode
|
||||
auth.json
|
||||
.npmrc
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
include:
|
||||
- project: 'ldc-web/shared-ci'
|
||||
ref: 'main'
|
||||
file: 'lint/lint7.3.yml'
|
||||
file: 'lint/lint.yml'
|
||||
- project: 'ldc-web/shared-ci'
|
||||
ref: 'main'
|
||||
file: 'security/security7.3.yml'
|
||||
file: 'security/security.yml'
|
||||
- project: 'ldc-web/shared-ci'
|
||||
ref: 'main'
|
||||
file: 'build/build7.3.yml'
|
||||
file: 'build/build.yml'
|
||||
- project: 'ldc-web/shared-ci'
|
||||
ref: 'main'
|
||||
file: 'test/test.yml'
|
||||
|
|
@ -21,4 +21,4 @@ stages:
|
|||
- security
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
- deploy
|
||||
|
|
|
|||
|
|
@ -4,8 +4,13 @@
|
|||
"stylelint-config-sass-guidelines",
|
||||
"stylelint-config-idiomatic-order"
|
||||
],
|
||||
"plugins": ["stylelint-scss"],
|
||||
"files": ["**/*.css", "**/*.scss"],
|
||||
"plugins": [
|
||||
"stylelint-scss"
|
||||
],
|
||||
"files": [
|
||||
"**/*.css",
|
||||
"**/*.scss"
|
||||
],
|
||||
"ignoreFiles": [
|
||||
"**/vendor/*.css",
|
||||
"**/vendor/**/*.css",
|
||||
|
|
@ -25,6 +30,10 @@
|
|||
"order/properties-alphabetical-order": null,
|
||||
"max-nesting-depth": 5,
|
||||
"selector-max-compound-selectors": 5,
|
||||
"declaration-colon-space-after": "always-single-line",
|
||||
"function-parentheses-space-inside": "never-single-line",
|
||||
"declaration-colon-newline-after": null,
|
||||
"value-list-comma-newline-after": null,
|
||||
"scss/double-slash-comment-empty-line-before": [
|
||||
"always",
|
||||
{
|
||||
|
|
|
|||
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
|
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
"peacock.remoteColor": "#006ea3",
|
||||
"workbench.colorCustomizations": {
|
||||
"activityBar.activeBackground": "#0090d6",
|
||||
"activityBar.background": "#0090d6",
|
||||
|
|
@ -18,5 +17,9 @@
|
|||
"titleBar.activeForeground": "#e7e7e7",
|
||||
"titleBar.inactiveBackground": "#006ea399",
|
||||
"titleBar.inactiveForeground": "#e7e7e799"
|
||||
}
|
||||
},
|
||||
"peacock.remoteColor": "#006ea3",
|
||||
"intelephense.environment.phpVersion": "8.2.0",
|
||||
"intelephense.completion.fullyQualifyGlobalConstantsAndFunctions": true,
|
||||
"intelephense.phpdoc.useFullyQualifiedNames": true
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
# 18/09/2023
|
||||
bump laravel 10 + update with base project
|
||||
|
||||
# 01/08/2022
|
||||
init
|
||||
with packages :
|
||||
|
|
@ -7,4 +10,4 @@ with packages :
|
|||
- ldc/web-status-checker-laravel
|
||||
|
||||
with Google Services keys
|
||||
with gitlab-ci config file
|
||||
with gitlab-ci config file
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/ldcweb-production-7.3:latest
|
||||
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/ldcweb-production-8.2:latest
|
||||
COPY --chown=www-data:www-data . /app/srcs
|
||||
USER root
|
||||
RUN chmod -R 755 /app/srcs/storage
|
||||
|
|
|
|||
|
|
@ -1,90 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* Creates a new user
|
||||
*/
|
||||
class CreateAdmin extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'user:create';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a backend admin user';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$email = null;
|
||||
while (is_null($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();
|
||||
$email = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid email %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
$name = null;
|
||||
while (is_null($name)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user name', 'Admin');
|
||||
$validator = Validator::make(['name' => $tmp], [
|
||||
'name' => 'required|min:5,max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$name = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$password = null;
|
||||
while (
|
||||
($password = $this->secret(
|
||||
(!\is_null($password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||
)) !== $this->secret('Confirm the password')
|
||||
) {
|
||||
continue;
|
||||
};
|
||||
|
||||
$admin = new User([
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
'password' => $password
|
||||
]);
|
||||
$admin->saveOrFail();
|
||||
|
||||
$this->info('User created.');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
35
app/Console/Commands/TestMail.php
Normal file
35
app/Console/Commands/TestMail.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
|
||||
class TestMail extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'mail:test';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Send test email to equipe.web@ldc.fr';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
Mail::raw(sprintf('UWIL mail-test from %s %s', \config('app.name'), \config('app.url')), function ($msg) {
|
||||
$msg->to('equipe.web@ldc.fr')->subject('Test Email');
|
||||
});
|
||||
}
|
||||
}
|
||||
178
app/Console/Commands/UserCreate.php
Normal file
178
app/Console/Commands/UserCreate.php
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class UserCreate extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'user:create';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a backend admin user';
|
||||
|
||||
/**
|
||||
* The firstname of the new user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $firstname;
|
||||
|
||||
/**
|
||||
* The lastname of the new user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $lastname;
|
||||
|
||||
/**
|
||||
* The email of the new user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->firstname = null;
|
||||
$this->addFirstname();
|
||||
|
||||
$this->lastname = null;
|
||||
$this->addLastname();
|
||||
|
||||
$this->email = null;
|
||||
$this->addEmail();
|
||||
|
||||
$this->password = null;
|
||||
$this->addPassword();
|
||||
|
||||
$user = new User([
|
||||
'firstname' => $this->firstname,
|
||||
'lastname' => $this->lastname,
|
||||
'email' => $this->email,
|
||||
'password' => $this->password,
|
||||
'last_connection' => Carbon::now(),
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
||||
$this->info('User created 👌');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a firstname to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addFirstname(): void
|
||||
{
|
||||
while (is_null($this->firstname)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user firstname', 'Admin');
|
||||
$validator = Validator::make(['firstname' => $tmp], [
|
||||
'firstname' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->firstname = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid firstname %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a lastname to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addLastname(): void
|
||||
{
|
||||
while (is_null($this->lastname)) {
|
||||
try {
|
||||
$tmp = $this->ask('Type the wanted user lastname', 'Saïtama');
|
||||
$validator = Validator::make(['lastname' => $tmp], [
|
||||
'lastname' => 'required|min:3|max:255'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->lastname = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please provide a valid lastname %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
|
||||
}
|
||||
}
|
||||
|
|
@ -2,40 +2,22 @@
|
|||
|
||||
namespace App\Enums\Advices;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self easy()
|
||||
* @method static self medium()
|
||||
* @method static self hard()
|
||||
*/
|
||||
final class AdviceDifficultyEnum extends BaseEnum
|
||||
enum AdviceDifficultyEnum: int
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'easy' => 0,
|
||||
'medium' => 1,
|
||||
'hard' => 2
|
||||
];
|
||||
}
|
||||
use BaseEnum;
|
||||
|
||||
case easy = 0;
|
||||
case medium = 1;
|
||||
case hard = 2;
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'easy' => trans('Facile'),
|
||||
'medium' => trans('Moyen'),
|
||||
'hard' => trans('Difficile')
|
||||
];
|
||||
}
|
||||
private const LABELS = [
|
||||
self::easy->name => 'Facile',
|
||||
self::medium->name => 'Moyen',
|
||||
self::hard->name => 'Difficile',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,70 +2,44 @@
|
|||
|
||||
namespace App\Enums\Advices;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self first()
|
||||
* @method static self second()
|
||||
* @method static self third()
|
||||
* @method static self fourth()
|
||||
*/
|
||||
final class AdviceTimeEnum extends BaseEnum
|
||||
enum AdviceTimeEnum: int
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'first' => 1,
|
||||
'second' => 2,
|
||||
'third' => 3,
|
||||
'fourth' => 4,
|
||||
];
|
||||
}
|
||||
use BaseEnum;
|
||||
|
||||
case first = 1;
|
||||
case second = 2;
|
||||
case third = 3;
|
||||
case fourth = 4;
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'first' => trans('0 - 30min'),
|
||||
'second' => trans('31min - 2h'),
|
||||
'third' => trans('2h - 4h'),
|
||||
'fourth' => trans('> 4h'),
|
||||
];
|
||||
}
|
||||
private const LABELS = [
|
||||
self::first->name => '0 - 30min',
|
||||
self::second->name => '31min - 2h',
|
||||
self::third->name => '2h - 4h',
|
||||
self::fourth->name => '> 4h',
|
||||
];
|
||||
|
||||
/**
|
||||
* Enum times
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
protected static function times(): array
|
||||
{
|
||||
return [
|
||||
'first' => [0, 30],
|
||||
'second' => [31, 120],
|
||||
'third' => [120, 240],
|
||||
'fourth' => [240, 1440]
|
||||
];
|
||||
}
|
||||
private const TIMES = [
|
||||
'first' => [0, 30],
|
||||
'second' => [31, 120],
|
||||
'third' => [120, 240],
|
||||
'fourth' => [240, 1440]
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $attribute
|
||||
* @return integer|string
|
||||
* Get time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __get(string $attribute)
|
||||
public function times(): string
|
||||
{
|
||||
if ($attribute === 'times') {
|
||||
return $this->times()[$this->getDefinition()] ?? null;
|
||||
}
|
||||
return parent::__get($attribute);
|
||||
return self::TIMES[$this->name];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,40 +2,22 @@
|
|||
|
||||
namespace App\Enums\Advices;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self all()
|
||||
* @method static self recipes()
|
||||
* @method static self tips()
|
||||
*/
|
||||
final class AdviceTypeEnum extends BaseEnum
|
||||
enum AdviceTypeEnum: int
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'all' => 0,
|
||||
'recipes' => 1,
|
||||
'tips' => 2,
|
||||
];
|
||||
}
|
||||
use BaseEnum;
|
||||
|
||||
case all = 0;
|
||||
case recipes = 1;
|
||||
case tips = 2;
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'all' => trans('Recettes / Astuces'),
|
||||
'recipes' => trans('Recettes'),
|
||||
'tips' => trans('Astuces'),
|
||||
];
|
||||
}
|
||||
private const LABELS = [
|
||||
self::all->name => 'Recettes / Astuces',
|
||||
self::recipes->name => 'Recettes',
|
||||
self::tips->name => 'Astuces',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,49 +2,28 @@
|
|||
|
||||
namespace App\Enums\Contact;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self distributeur()
|
||||
* @method static self restaurationSociale()
|
||||
* @method static self restaurationCommerciale()
|
||||
* @method static self boulangeriePatisserie()
|
||||
* @method static self journaliste()
|
||||
* @method static self autre()
|
||||
*/
|
||||
final class ContactActivityEnum extends BaseEnum
|
||||
enum ContactActivityEnum: int
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'distributeur' => 1,
|
||||
'restaurationSociale' => 2,
|
||||
'restaurationCommerciale' => 3,
|
||||
'boulangeriePatisserie' => 4,
|
||||
'journaliste' => 5,
|
||||
'autre' => 6
|
||||
];
|
||||
}
|
||||
use BaseEnum;
|
||||
|
||||
case distributeur = 1;
|
||||
case restaurationSociale = 2;
|
||||
case restaurationCommerciale = 3;
|
||||
case boulangeriePatisserie = 4;
|
||||
case journaliste = 5;
|
||||
case autre = 6;
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'distributeur' => trans('Distributeur'),
|
||||
'restaurationSociale' => trans('Restauration sociale'),
|
||||
'restaurationCommerciale' => trans('Restauration commerciale'),
|
||||
'boulangeriePatisserie' => trans('Boulangerie-pâtisserie'),
|
||||
'journaliste' => trans('Journaliste'),
|
||||
'autre' => trans('Autre'),
|
||||
];
|
||||
}
|
||||
private const LABELS = [
|
||||
self::distributeur->name => 'Distributeur',
|
||||
self::restaurationSociale->name => 'Restauration sociale',
|
||||
self::restaurationCommerciale->name => 'Restauration commerciale',
|
||||
self::boulangeriePatisserie->name => 'Boulangerie-pâtisserie',
|
||||
self::journaliste->name => 'Journaliste',
|
||||
self::autre->name => 'Autre',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,40 +2,22 @@
|
|||
|
||||
namespace App\Enums\Contact;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self morning()
|
||||
* @method static self afternoon()
|
||||
* @method static self anytime()
|
||||
*/
|
||||
final class ContactTimeEnum extends BaseEnum
|
||||
enum ContactTimeEnum: int
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'morning' => 1,
|
||||
'afternoon' => 2,
|
||||
'anytime' => 3,
|
||||
];
|
||||
}
|
||||
use BaseEnum;
|
||||
|
||||
case morning = 1;
|
||||
case afternoon = 2;
|
||||
case anytime = 3;
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'morning' => trans('Le matin'),
|
||||
'afternoon' => trans('L\'après-midi'),
|
||||
'anytime' => trans('À tout moment'),
|
||||
];
|
||||
}
|
||||
private const LABELS = [
|
||||
self::morning->name => 'Le matin',
|
||||
self::afternoon->name => 'L\'après-midi',
|
||||
self::anytime->name => 'À tout moment',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,46 +2,26 @@
|
|||
|
||||
namespace App\Enums\ExpertiseProducts;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self duck()
|
||||
* @method static self turkey()
|
||||
* @method static self rabbit()
|
||||
* @method static self guineafowl()
|
||||
* @method static self chicken()
|
||||
*/
|
||||
final class ExpertiseProductPageEnum extends BaseEnum
|
||||
enum ExpertiseProductPageEnum: int
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'duck' => 0,
|
||||
'turkey' => 1,
|
||||
'rabbit' => 2,
|
||||
'guineafowl' => 3,
|
||||
'chicken' => 4,
|
||||
];
|
||||
}
|
||||
use BaseEnum;
|
||||
|
||||
case duck = 0;
|
||||
case turkey = 1;
|
||||
case rabbit = 2;
|
||||
case guineafowl = 3;
|
||||
case chicken = 4;
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'duck' => trans('Canard'),
|
||||
'turkey' => trans('Dinde'),
|
||||
'rabbit' => trans('Lapin'),
|
||||
'guineafowl' => trans('Pintade'),
|
||||
'chicken' => trans('Poulet'),
|
||||
];
|
||||
}
|
||||
private const LABELS = [
|
||||
self::duck->name => 'Canard',
|
||||
self::turkey->name => 'Dinde',
|
||||
self::rabbit->name => 'Lapin',
|
||||
self::guineafowl->name => 'Pintade',
|
||||
self::chicken->name => 'Poulet',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,52 +2,28 @@
|
|||
|
||||
namespace App\Enums;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self noLetter()
|
||||
* @method static self aLetter()
|
||||
* @method static self bLetter()
|
||||
* @method static self cLetter()
|
||||
* @method static self dLetter()
|
||||
* @method static self eLetter()
|
||||
*/
|
||||
final class NutriscoreEnum extends BaseEnum
|
||||
enum NutriscoreEnum: int
|
||||
{
|
||||
// @phpcs:ignore Generic.Commenting.Fixme.TaskFound
|
||||
// FIXME: faire en sorte de ne pas afficher le nutriscore en front si sa valeur est de 0.
|
||||
use BaseEnum;
|
||||
|
||||
case noLetter = 0;
|
||||
case aLetter = 1;
|
||||
case bLetter = 2;
|
||||
case cLetter = 3;
|
||||
case dLetter = 4;
|
||||
case eLetter = 5;
|
||||
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'noLetter' => 0,
|
||||
'aLetter' => 1,
|
||||
'bLetter' => 2,
|
||||
'cLetter' => 3,
|
||||
'dLetter' => 4,
|
||||
'eLetter' => 5
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'noLetter' => 'Ø',
|
||||
'aLetter' => 'A',
|
||||
'bLetter' => 'B',
|
||||
'cLetter' => 'C',
|
||||
'dLetter' => 'D',
|
||||
'eLetter' => 'E'
|
||||
];
|
||||
}
|
||||
private const LABELS = [
|
||||
self::noLetter->name => 'Ø',
|
||||
self::aLetter->name => 'A',
|
||||
self::bLetter->name => 'B',
|
||||
self::cLetter->name => 'C',
|
||||
self::dLetter->name => 'D',
|
||||
self::eLetter->name => 'E'
|
||||
];
|
||||
}
|
||||
|
|
|
|||
16
app/Enums/Pagination/ItemsPerPaginationEnum.php
Normal file
16
app/Enums/Pagination/ItemsPerPaginationEnum.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace App\Enums\Pagination;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
enum ItemsPerPaginationEnum: int
|
||||
{
|
||||
use BaseEnum;
|
||||
|
||||
case five = 5;
|
||||
case twelve = 12;
|
||||
case twentyfive = 25;
|
||||
case fifty = 50;
|
||||
case onehundred = 100;
|
||||
}
|
||||
|
|
@ -2,64 +2,38 @@
|
|||
|
||||
namespace App\Enums\Products;
|
||||
|
||||
use Kwaadpepper\Enum\BaseEnum;
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
||||
/**
|
||||
* @method static self caille()
|
||||
* @method static self canard()
|
||||
* @method static self canette()
|
||||
* @method static self coq()
|
||||
* @method static self coquelet()
|
||||
* @method static self dinde()
|
||||
* @method static self lapin()
|
||||
* @method static self pigeonneau()
|
||||
* @method static self pintade()
|
||||
* @method static self poule()
|
||||
* @method static self poulet()
|
||||
*/
|
||||
final class ProductSpeciesEnum extends BaseEnum
|
||||
enum ProductSpeciesEnum: int
|
||||
{
|
||||
/**
|
||||
* Enum values
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'caille' => 0,
|
||||
'canard' => 1,
|
||||
'canette' => 2,
|
||||
'coq' => 3,
|
||||
'coquelet' => 4,
|
||||
'dinde' => 5,
|
||||
'lapin' => 6,
|
||||
'pigeonneau' => 7,
|
||||
'pintade' => 8,
|
||||
'poule' => 9,
|
||||
'poulet' => 10,
|
||||
];
|
||||
}
|
||||
use BaseEnum;
|
||||
|
||||
case caille = 0;
|
||||
case canard = 1;
|
||||
case canette = 2;
|
||||
case coq = 3;
|
||||
case coquelet = 4;
|
||||
case dinde = 5;
|
||||
case lapin = 6;
|
||||
case pigeonneau = 7;
|
||||
case pintade = 8;
|
||||
case poule = 9;
|
||||
case poulet = 10;
|
||||
|
||||
/**
|
||||
* Enum labels
|
||||
*
|
||||
* @return array
|
||||
* Optionnal labels definition.
|
||||
*/
|
||||
protected static function labels(): array
|
||||
{
|
||||
return [
|
||||
'caille' => trans('Caille'),
|
||||
'canard' => trans('Canard'),
|
||||
'canette' => trans('Canette'),
|
||||
'coq' => trans('Coq'),
|
||||
'coquelet' => trans('Coquelet'),
|
||||
'dinde' => trans('Dinde'),
|
||||
'lapin' => trans('Lapin'),
|
||||
'pigeonneau' => trans('Pigeonneau'),
|
||||
'pintade' => trans('Pintade'),
|
||||
'poule' => trans('Poule'),
|
||||
'poulet' => trans('Poulet')
|
||||
];
|
||||
}
|
||||
private const LABELS = [
|
||||
self::caille->name => 'Caille',
|
||||
self::canard->name => 'Canard',
|
||||
self::canette->name => 'Canette',
|
||||
self::coq->name => 'Coq',
|
||||
self::coquelet->name => 'Coquelet',
|
||||
self::dinde->name => 'Dinde',
|
||||
self::lapin->name => 'Lapin',
|
||||
self::pigeonneau->name => 'Pigeonneau',
|
||||
self::pintade->name => 'Pintade',
|
||||
self::poule->name => 'Poule',
|
||||
self::poulet->name => 'Poulet'
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,18 +3,26 @@
|
|||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
protected $levels = [];
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<Throwable>>
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
*/
|
||||
protected $dontReport = [];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
* A list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
|
|
@ -31,7 +39,7 @@ class Handler extends ExceptionHandler
|
|||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (\Throwable $e) {
|
||||
$this->reportable(function (Throwable $e) {
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,91 +21,96 @@ class AdviceController extends Controller
|
|||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $advice */
|
||||
$advice = Advice::query();
|
||||
$type = $request->type;
|
||||
$currentType = AdviceTypeEnum::make(\intval($type));
|
||||
|
||||
$advice->when(isset($type), function ($advice) use ($currentType) {
|
||||
$advice->where('type', '=', $currentType->value);
|
||||
$adviceModels = Advice::query();
|
||||
$type = $request->type;
|
||||
$currentType = AdviceTypeEnum::make(\intval($type));
|
||||
$adviceModels->when(isset($type), function ($adviceModels) use ($currentType) {
|
||||
if ($currentType->value() !== AdviceTypeEnum::all->value()) {
|
||||
$adviceModels->where('type', '=', $currentType->value());
|
||||
}
|
||||
});
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$advice,
|
||||
$request->search,
|
||||
$adviceModels,
|
||||
$search,
|
||||
null,
|
||||
'title'
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($advice);
|
||||
$searchFields = trans('Titre');
|
||||
|
||||
$advice = $advice->paginate(10);
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($adviceModels);
|
||||
|
||||
return view('bo.pages.advice.index', compact('advice', 'currentType', 'searchFields'));
|
||||
/** Custom pagination */
|
||||
$adviceModels = $this->paginate($adviceModels);
|
||||
|
||||
return view('bo.pages.advice.index', compact('adviceModels', 'currentType', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Request $request)
|
||||
public function create(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$advice = new Advice();
|
||||
$type = $request->type;
|
||||
$currentType = AdviceTypeEnum::make(\intval($type));
|
||||
$adviceTags = Tag::query()->select(['id', 'label', 'slug'])->get();
|
||||
$adviceProducts = Product::all();
|
||||
$recipeList = Advice::where('type', '=', AdviceTypeEnum::recipes())->get();
|
||||
$tipList = Advice::where('type', '=', AdviceTypeEnum::tips())->get();
|
||||
$recipeList = Advice::where('type', '=', AdviceTypeEnum::recipes)->get();
|
||||
$tipList = Advice::where('type', '=', AdviceTypeEnum::tips)->get();
|
||||
|
||||
$recipeList = collect($recipeList)->each(function (\App\Models\Advice &$value) {
|
||||
$recipeList = collect($recipeList)->each(function (Advice &$value) {
|
||||
$value->label = $value->title;
|
||||
});
|
||||
$tipList = collect($tipList)->each(function (\App\Models\Advice &$value) {
|
||||
$tipList = collect($tipList)->each(function (Advice &$value) {
|
||||
$value->label = $value->title;
|
||||
});
|
||||
|
||||
$recipesSelected = collect([]);
|
||||
$tipsSelected = collect([]);
|
||||
collect($advice->advices)->each(function ($eltAdvice) use (&$recipesSelected, &$tipsSelected) {
|
||||
if ($eltAdvice->type->value == AdviceTypeEnum::recipes()->value) {
|
||||
if ($eltAdvice->type->value == AdviceTypeEnum::recipes->value()) {
|
||||
$eltAdvice->label = $eltAdvice->title;
|
||||
$recipesSelected = $recipesSelected->concat([$eltAdvice]);
|
||||
} elseif ($eltAdvice->type->value == AdviceTypeEnum::tips()->value) {
|
||||
} elseif ($eltAdvice->type->value == AdviceTypeEnum::tips->value()) {
|
||||
$eltAdvice->label = $eltAdvice->title;
|
||||
$tipsSelected = $tipsSelected->concat([$eltAdvice]);
|
||||
}
|
||||
});
|
||||
|
||||
return view('bo.pages.advice.create', [
|
||||
'advice' => $advice,
|
||||
'currentType' => $currentType,
|
||||
'adviceTags' => $adviceTags,
|
||||
'adviceProducts' => $adviceProducts,
|
||||
'recipeList' => $recipeList,
|
||||
'tipList' => $tipList,
|
||||
'adviceModel' => $advice,
|
||||
'currentType' => $currentType,
|
||||
'adviceTags' => $adviceTags,
|
||||
'adviceProducts' => $adviceProducts,
|
||||
'recipeList' => $recipeList,
|
||||
'tipList' => $tipList,
|
||||
'recipesSelected' => $recipesSelected,
|
||||
'tipsSelected' => $tipsSelected,
|
||||
'tipsSelected' => $tipsSelected,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Advice\StoreAdviceRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\Advice\StoreAdviceRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreAdviceRequest $request)
|
||||
public function store(StoreAdviceRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$advice = new Advice();
|
||||
|
|
@ -120,17 +125,16 @@ class AdviceController extends Controller
|
|||
|
||||
return redirect()
|
||||
->route('bo.advice.edit', $advice)
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular($currentType->label)]
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular($currentType->label())]
|
||||
));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular($currentType->label)]
|
||||
->with('error', __(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular($currentType->label())]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -139,27 +143,27 @@ class AdviceController extends Controller
|
|||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Advice $advice
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Advice $advice)
|
||||
public function edit(Advice $advice): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$currentType = $advice->type;
|
||||
$adviceTags = Tag::whereNotIn('id', $advice->tags()->pluck('id'))
|
||||
->select(['id', 'label', 'slug'])->get();
|
||||
$adviceProducts = Product::all();
|
||||
$recipeList = Advice::where([
|
||||
['type', '=', AdviceTypeEnum::recipes()],
|
||||
['type', '=', AdviceTypeEnum::recipes],
|
||||
['id', '!=', $advice->id],
|
||||
])->get();
|
||||
$tipList = Advice::where([
|
||||
['type', '=', AdviceTypeEnum::tips()],
|
||||
['type', '=', AdviceTypeEnum::tips],
|
||||
['id', '!=', $advice->id],
|
||||
])->get();
|
||||
|
||||
$recipeList = collect($recipeList)->each(function (\App\Models\Advice &$value) {
|
||||
$recipeList = collect($recipeList)->each(function (Advice &$value) {
|
||||
$value->label = $value->title;
|
||||
});
|
||||
$tipList = collect($tipList)->each(function (\App\Models\Advice &$value) {
|
||||
$tipList = collect($tipList)->each(function (Advice &$value) {
|
||||
$value->label = $value->title;
|
||||
});
|
||||
|
||||
|
|
@ -176,25 +180,25 @@ class AdviceController extends Controller
|
|||
});
|
||||
|
||||
return view('bo.pages.advice.edit', [
|
||||
'advice' => $advice,
|
||||
'currentType' => $currentType,
|
||||
'adviceTags' => $adviceTags,
|
||||
'adviceProducts' => $adviceProducts,
|
||||
'recipeList' => $recipeList,
|
||||
'tipList' => $tipList,
|
||||
'adviceModel' => $advice,
|
||||
'currentType' => $currentType,
|
||||
'adviceTags' => $adviceTags,
|
||||
'adviceProducts' => $adviceProducts,
|
||||
'recipeList' => $recipeList,
|
||||
'tipList' => $tipList,
|
||||
'recipesSelected' => $recipesSelected,
|
||||
'tipsSelected' => $tipsSelected,
|
||||
'tipsSelected' => $tipsSelected,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Advice\UpdateAdviceRequest $request
|
||||
* @param \App\Models\Advice $advice
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\Advice\UpdateAdviceRequest $request
|
||||
* @param \App\Models\Advice $advice
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateAdviceRequest $request, Advice $advice)
|
||||
public function update(UpdateAdviceRequest $request, Advice $advice): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $advice) {
|
||||
$advice->tags()->sync(collect($request->tags)->pluck('id'));
|
||||
|
|
@ -209,16 +213,16 @@ class AdviceController extends Controller
|
|||
return redirect()
|
||||
->route('bo.advice.edit', $advice)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular($currentType->label)]
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular($currentType->label())]
|
||||
));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular($currentType->label)]
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular($currentType->label())]
|
||||
));
|
||||
});
|
||||
}
|
||||
|
|
@ -226,32 +230,32 @@ class AdviceController extends Controller
|
|||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Advice $advice
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Models\Advice $advice
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Advice $advice)
|
||||
public function destroy(Advice $advice): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
DB::table('advice_advice')->where($advice->advices()->getRelatedPivotKeyName(), $advice->id)->delete();
|
||||
$advice->tags()->sync([]);
|
||||
$advice->products()->sync([]);
|
||||
$advice->advices()->sync([]);
|
||||
|
||||
$currentType = AdviceTypeEnum::make(\intval($advice->type->value));
|
||||
$currentType = AdviceTypeEnum::make(\intval($advice->type->value()));
|
||||
|
||||
if ($advice->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.advice.index', ['type' => $currentType])
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular($currentType->label)]
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular($currentType->label())]
|
||||
));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular($currentType->label)]
|
||||
'crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular($currentType->label())]
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,24 +3,14 @@
|
|||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Foundation\Auth\ThrottlesLogins;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
use AuthenticatesUsers;
|
||||
use ThrottlesLogins;
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
|
@ -32,68 +22,33 @@ class LoginController extends Controller
|
|||
$this->middleware('guest:backend')->except('logout');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
return Auth::guard('backend');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showLoginForm()
|
||||
public function showLoginForm(): View
|
||||
{
|
||||
return view('bo.auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to log the user into the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return boolean
|
||||
*/
|
||||
protected function attemptLogin(Request $request)
|
||||
{
|
||||
return Auth::guard('backend')->attempt(
|
||||
$this->credentials($request),
|
||||
$request->filled('remember')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has been authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param null $user
|
||||
* @return mixed
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing, Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
*/
|
||||
protected function authenticated(Request $request, $user)
|
||||
{
|
||||
/** @var \App\Models\User|null */
|
||||
$user = Auth::guard('backend')->user();
|
||||
if ($user) {
|
||||
$user->last_connection = now();
|
||||
$user->saveOrFail();
|
||||
Session::flash('info', trans('Vous êtes à présent connecté'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The user has logged out of the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
protected function loggedOut(Request $request)
|
||||
{
|
||||
Session::flash('info', trans('Vous êtes à présent déconnecté'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath()
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
return response()->redirectToRoute('bo.dashboard')->getTargetUrl();
|
||||
return response()->redirectToIntended()->getTargetUrl();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,62 +16,68 @@ class ExpertiseProductController extends Controller
|
|||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $vips */
|
||||
$vips = ExpertiseProduct::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $vipModels */
|
||||
$vipModels = ExpertiseProduct::query();
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$vips,
|
||||
$request->search,
|
||||
$vipModels,
|
||||
$search,
|
||||
null,
|
||||
'label',
|
||||
'title'
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($vips);
|
||||
$searchFields = trans('Libellé, Titre');
|
||||
|
||||
$vips = $vips->paginate(10);
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($vipModels);
|
||||
|
||||
return view('bo.pages.vips.index', compact('vips', 'searchFields'));
|
||||
/** Custom pagination */
|
||||
$vipModels = $this->paginate($vipModels);
|
||||
|
||||
return view('bo.pages.vips.index', compact('vipModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param App\Models\ExpertiseProduct $vip
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create()
|
||||
public function create(ExpertiseProduct $vip): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.vips.create');
|
||||
return view('bo.pages.vips.create', ['vipModel' => $vip]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\ExpertiseProducts\StoreExpertiseProductRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\ExpertiseProducts\StoreExpertiseProductRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreExpertiseProductRequest $request)
|
||||
public function store(StoreExpertiseProductRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$vip = new ExpertiseProduct();
|
||||
$vip->fill($request->validated());
|
||||
|
||||
if ($vip->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.vips.edit', $vip)
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.vips'))]
|
||||
));
|
||||
return redirect()->route('bo.vips.edit', $vip->id)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::singular(trans_choice('models.classes.vips', 2))
|
||||
]));
|
||||
}
|
||||
return back();
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::singular(trans_choice('models.classes.vips', 2))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -79,13 +85,11 @@ class ExpertiseProductController extends Controller
|
|||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\ExpertiseProduct $vip
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(ExpertiseProduct $vip)
|
||||
public function edit(ExpertiseProduct $vip): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.vips.edit', [
|
||||
'vip' => $vip
|
||||
]);
|
||||
return view('bo.pages.vips.edit', ['vipModel' => $vip]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,41 +97,45 @@ class ExpertiseProductController extends Controller
|
|||
*
|
||||
* @param \App\Http\Requests\Bo\ExpertiseProduct\UpdateExpertiseProductRequest $request
|
||||
* @param \App\Models\ExpertiseProduct $vip
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateExpertiseProductRequest $request, ExpertiseProduct $vip)
|
||||
{
|
||||
public function update(
|
||||
UpdateExpertiseProductRequest $request,
|
||||
ExpertiseProduct $vip
|
||||
): \Illuminate\Http\RedirectResponse {
|
||||
return DB::transaction(function () use ($request, $vip) {
|
||||
$vip->fill($request->validated());
|
||||
|
||||
if ($vip->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.vips.edit', $vip)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.vips'))]
|
||||
));
|
||||
return redirect()->route('bo.vips.edit', $vip->id)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::singular(trans_choice('models.classes.vips', 2))
|
||||
]));
|
||||
}
|
||||
return back();
|
||||
return redirect()->route('bo.vips.edit', $vip->id)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::singular(trans_choice('models.classes.vips', 2))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\ExpertiseProduct $vip
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Models\ExpertiseProduct $vip
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(ExpertiseProduct $vip)
|
||||
public function destroy(ExpertiseProduct $vip): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if ($vip->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.vips.index')
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.vips'))]
|
||||
));
|
||||
return redirect()->route('bo.vips.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::singular(trans_choice('models.classes.vips', 2))
|
||||
]));
|
||||
}
|
||||
return back();
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::singular(trans_choice('models.classes.vips', 2))
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,12 @@ use App\Http\Controllers\Controller;
|
|||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Dashboard view
|
||||
* Dashboard view.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function dashboard()
|
||||
public function dashboard(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.home');
|
||||
return view('bo.pages.homepage');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace App\Http\Controllers\Bo;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\NewsCategories\UpdateNewsCategoryRequest;
|
||||
use App\Models\NewsCategory;
|
||||
use App\Traits\Models\ChangesModelOrder;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -18,40 +18,44 @@ class NewsCategoryController extends Controller
|
|||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $newscategories */
|
||||
$newscategories = NewsCategory::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $newscategoryModels */
|
||||
$newscategoryModels = NewsCategory::query();
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$newscategories,
|
||||
$request->search,
|
||||
$newscategoryModels,
|
||||
$search,
|
||||
null,
|
||||
'label'
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($newscategories);
|
||||
$searchFields = trans('Libellé');
|
||||
|
||||
$newscategories = $newscategories->get();
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($newscategoryModels);
|
||||
|
||||
return view('bo.pages.newscategories.index', compact('newscategories', 'searchFields'));
|
||||
/** Custom pagination */
|
||||
$newscategoryModels = $this->paginate($newscategoryModels);
|
||||
|
||||
return view('bo.pages.newscategories.index', compact('newscategoryModels', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\NewsCategory $newscategory
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(NewsCategory $newscategory)
|
||||
public function edit(NewsCategory $newscategory): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.newscategories.edit', [
|
||||
'newscategory' => $newscategory
|
||||
'newscategoryModel' => $newscategory
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -60,22 +64,25 @@ class NewsCategoryController extends Controller
|
|||
*
|
||||
* @param \App\Http\Requests\Bo\NewsCategories\UpdateNewsCategoryRequest $request
|
||||
* @param \App\Models\NewsCategory $newscategory
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateNewsCategoryRequest $request, NewsCategory $newscategory)
|
||||
{
|
||||
public function update(
|
||||
UpdateNewsCategoryRequest $request,
|
||||
NewsCategory $newscategory
|
||||
): \Illuminate\Http\RedirectResponse {
|
||||
return DB::transaction(function () use ($request, $newscategory) {
|
||||
$newscategory->fill($request->validated());
|
||||
|
||||
if ($newscategory->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.newscategories.edit', $newscategory)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.newscategories'))]
|
||||
));
|
||||
return redirect()->route('bo.newscategories.edit', $newscategory->id)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::singular(__('models.classes.newscategories'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back();
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::singular(__('models.classes.newscategories'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,17 +21,19 @@ class NewsController extends Controller
|
|||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $news */
|
||||
$news = News::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $newsModels */
|
||||
$newsModels = News::query();
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$news,
|
||||
$request->search,
|
||||
$newsModels,
|
||||
$search,
|
||||
null,
|
||||
'title',
|
||||
'subtitle',
|
||||
|
|
@ -39,47 +41,55 @@ class NewsController extends Controller
|
|||
'content2'
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($news);
|
||||
$searchFields = trans('Titre, Sous-titre, Contenus');
|
||||
|
||||
$news = $news->paginate(10);
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($newsModels);
|
||||
|
||||
return view('bo.pages.news.index', compact('news', 'searchFields'));
|
||||
/** Custom pagination */
|
||||
$newsModels = $this->paginate($newsModels);
|
||||
|
||||
return view('bo.pages.news.index', compact('newsModels', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Models\News $news
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create()
|
||||
public function create(News $news): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$news = new News();
|
||||
$news = $news ?? new News();
|
||||
$newsCategories = NewsCategory::all();
|
||||
$newsProducts = Product::all();
|
||||
$newsList = News::all();
|
||||
|
||||
$newsList = collect($newsList)->each(function (\App\Models\News &$value) {
|
||||
$newsList = collect($newsList)->each(function (News &$value) {
|
||||
$value->label = $value->title;
|
||||
});
|
||||
|
||||
$newsSelected = collect([]);
|
||||
collect($news->news ?? [])->each(function (\App\Models\News &$value) use (&$newsSelected) {
|
||||
collect($news->news ?? [])->each(function (News &$value) use (&$newsSelected) {
|
||||
$value->label = $value->title;
|
||||
$newsSelected = $newsSelected->concat([$value]);
|
||||
});
|
||||
|
||||
return view('bo.pages.news.create', compact('newsCategories', 'newsProducts', 'newsList'));
|
||||
return view('bo.pages.news.create', [
|
||||
'newsModel' => $news,
|
||||
'newsCategories' => $newsCategories,
|
||||
'newsProducts' => $newsProducts,
|
||||
'newsList' => $newsList,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\News\StoreNewsRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\News\StoreNewsRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreNewsRequest $request)
|
||||
public function store(StoreNewsRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$news = new News();
|
||||
|
|
@ -90,20 +100,15 @@ class NewsController extends Controller
|
|||
$news->products()->sync($request->products_list);
|
||||
$news->news()->sync($request->news_list);
|
||||
|
||||
return redirect()
|
||||
->route('bo.news.edit', $news)
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.news'))]
|
||||
));
|
||||
return redirect()->route('bo.news.edit', $news->id)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::singular(__('models.classes.news'))
|
||||
]));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.news'))]
|
||||
));
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::singular(__('models.classes.news'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -111,9 +116,9 @@ class NewsController extends Controller
|
|||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\News $news
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(News $news)
|
||||
public function edit(News $news): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$newsCategories = NewsCategory::all();
|
||||
$newsProducts = Product::all();
|
||||
|
|
@ -130,21 +135,21 @@ class NewsController extends Controller
|
|||
});
|
||||
|
||||
return view('bo.pages.news.edit', [
|
||||
'news' => $news,
|
||||
'newsModel' => $news,
|
||||
'newsCategories' => $newsCategories,
|
||||
'newsProducts' => $newsProducts,
|
||||
'newsList' => $newsList,
|
||||
'newsProducts' => $newsProducts,
|
||||
'newsList' => $newsList,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\News\UpdateNewsRequest $request
|
||||
* @param \App\Models\News $news
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\News\UpdateNewsRequest $request
|
||||
* @param \App\Models\News $news
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateNewsRequest $request, News $news)
|
||||
public function update(UpdateNewsRequest $request, News $news): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $news) {
|
||||
$news->categories()->sync($request->categories_list);
|
||||
|
|
@ -154,30 +159,25 @@ class NewsController extends Controller
|
|||
$news->fill($request->validated());
|
||||
|
||||
if ($news->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.news.edit', $news)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.news'))]
|
||||
));
|
||||
return redirect()->route('bo.news.edit', $news->id)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::singular(__('models.classes.news'))
|
||||
]));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.news'))]
|
||||
));
|
||||
return redirect()->route('bo.news.edit', $news->id)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::singular(__('models.classes.news'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\News $news
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Models\News $news
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(News $news)
|
||||
public function destroy(News $news): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
DB::table('news_news')->where($news->news()->getRelatedPivotKeyName(), $news->id)->delete();
|
||||
$news->categories()->sync([]);
|
||||
|
|
@ -185,19 +185,14 @@ class NewsController extends Controller
|
|||
$news->news()->sync([]);
|
||||
|
||||
if ($news->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.news.index')
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.news'))]
|
||||
));
|
||||
return redirect()->route('bo.news.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::singular(__('models.classes.news'))
|
||||
]));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.news'))]
|
||||
));
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::singular(__('models.classes.news'))
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use App\Models\Product;
|
|||
use App\Models\Subrange;
|
||||
use App\Traits\Controllers\HasPicture;
|
||||
use App\Traits\Controllers\UpdateModelStatus;
|
||||
use App\Traits\Models\ChangesModelOrder;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -24,50 +24,58 @@ class ProductController extends Controller
|
|||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $products */
|
||||
$products = Product::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $productModels */
|
||||
$productModels = Product::query();
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$products,
|
||||
$request->search,
|
||||
$productModels,
|
||||
$search,
|
||||
null,
|
||||
'label'
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($products);
|
||||
$searchFields = trans('Label');
|
||||
|
||||
$products = $products->paginate(10);
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($productModels);
|
||||
|
||||
return view('bo.pages.products.index', compact('products', 'searchFields'));
|
||||
/** Custom pagination */
|
||||
$productModels = $this->paginate($productModels);
|
||||
|
||||
return view('bo.pages.products.index', compact('productModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create()
|
||||
public function create(Product $product): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $subranges */
|
||||
$subranges = Subrange::get();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $subrangeModels */
|
||||
$subrangeModels = Subrange::get();
|
||||
|
||||
return view('bo.pages.products.create', compact('subranges'));
|
||||
return view('bo.pages.products.create', [
|
||||
'productModel' => $product,
|
||||
'subrangeModels' => $subrangeModels
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Products\StoreProductRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\Products\StoreProductRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreProductRequest $request)
|
||||
public function store(StoreProductRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$product = new Product();
|
||||
|
|
@ -75,19 +83,15 @@ class ProductController extends Controller
|
|||
$this->storePictures($request, $product);
|
||||
|
||||
if ($product->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.edit', $product)
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.products'))]
|
||||
));
|
||||
return redirect()->route('bo.products.edit', $product->id)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::singular(__('models.classes.products'))
|
||||
]));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.products'))]
|
||||
));
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::singular(__('models.classes.products'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -95,14 +99,17 @@ class ProductController extends Controller
|
|||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Product $product)
|
||||
public function edit(Product $product): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $subranges */
|
||||
$subranges = Subrange::get();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $subrangeModels */
|
||||
$subrangeModels = Subrange::get();
|
||||
|
||||
return view('bo.pages.products.edit', ['product' => $product], compact('subranges'));
|
||||
return view('bo.pages.products.edit', [
|
||||
'productModel' => $product,
|
||||
'subrangeModels' => $subrangeModels,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -110,55 +117,47 @@ class ProductController extends Controller
|
|||
*
|
||||
* @param \App\Http\Requests\Bo\Products\UpdateProductRequest $request
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateProductRequest $request, Product $product)
|
||||
public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $product) {
|
||||
$product->fill($request->validated());
|
||||
$this->storePictures($request, $product);
|
||||
|
||||
if ($product->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.edit', $product)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.products'))]
|
||||
));
|
||||
return redirect()->route('bo.products.edit', $product->id)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::singular(__('models.classes.products'))
|
||||
]));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.products'))]
|
||||
));
|
||||
return redirect()->route('bo.products.edit', $product->id)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::singular(__('models.classes.products'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Product $product)
|
||||
public function destroy(Product $product): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$product->advices()->sync([]);
|
||||
$product->news()->sync([]);
|
||||
|
||||
if ($product->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.index')
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.products'))]
|
||||
));
|
||||
return redirect()->route('bo.products.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::singular(__('models.classes.products'))
|
||||
]));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.products'))]
|
||||
));
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::singular(__('models.classes.products'))
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace App\Http\Controllers\Bo;
|
|||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Ranges\UpdateRangeRequest;
|
||||
use App\Models\Range;
|
||||
use App\Traits\Models\ChangesModelOrder;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -18,41 +18,43 @@ class RangeController extends Controller
|
|||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $ranges */
|
||||
$ranges = Range::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $rangeModels */
|
||||
$rangeModels = Range::query();
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$ranges,
|
||||
$request->search,
|
||||
$rangeModels,
|
||||
$search,
|
||||
null,
|
||||
'label'
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($ranges);
|
||||
$searchFields = trans('Libellé');
|
||||
|
||||
$ranges = $ranges->paginate(10);
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($rangeModels);
|
||||
|
||||
return view('bo.pages.ranges.index', compact('ranges', 'searchFields'));
|
||||
/** Custom pagination */
|
||||
$rangeModels = $this->paginate($rangeModels);
|
||||
|
||||
return view('bo.pages.ranges.index', compact('rangeModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Range $range)
|
||||
public function edit(Range $range): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.ranges.edit', [
|
||||
'range' => $range
|
||||
]);
|
||||
return view('bo.pages.ranges.edit', ['rangeModel' => $range]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -60,22 +62,23 @@ class RangeController extends Controller
|
|||
*
|
||||
* @param \App\Http\Requests\Bo\Ranges\UpdateRangeRequest $request
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateRangeRequest $request, Range $range)
|
||||
public function update(UpdateRangeRequest $request, Range $range): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $range) {
|
||||
$range->fill($request->validated());
|
||||
|
||||
if ($range->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.ranges.edit', $range)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.ranges'))]
|
||||
));
|
||||
return redirect()->route('bo.ranges.edit', $range->id)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::singular(__('models.classes.ranges'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back();
|
||||
return redirect()->route('bo.ranges.edit', $range->id)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::singular(__('models.classes.ranges'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use App\Http\Controllers\Controller;
|
|||
use App\Http\Requests\Bo\Slides\StoreSlideRequest;
|
||||
use App\Http\Requests\Bo\Slides\UpdateSlideRequest;
|
||||
use App\Models\Slide;
|
||||
use App\Traits\Models\ChangesModelOrder;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -19,62 +19,68 @@ class SlideController extends Controller
|
|||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $slides */
|
||||
$slides = Slide::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $slideModels */
|
||||
$slideModels = Slide::query();
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$slides,
|
||||
$request->search,
|
||||
$slideModels,
|
||||
$search,
|
||||
null,
|
||||
'title',
|
||||
'content',
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($slides);
|
||||
$searchFields = trans('Titre, Contenu');
|
||||
|
||||
$slides = $slides->paginate(10);
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($slideModels);
|
||||
|
||||
return view('bo.pages.slides.index', compact('slides', 'searchFields'));
|
||||
/** Custom pagination */
|
||||
$slideModels = $this->paginate($slideModels);
|
||||
|
||||
return view('bo.pages.slides.index', compact('slideModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param App\Models\Slide $slide
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create()
|
||||
public function create(Slide $slide): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.slides.create');
|
||||
return view('bo.pages.slides.create', ['slideModel' => $slide]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Slides\StoreSlideRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreSlideRequest $request)
|
||||
public function store(StoreSlideRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$slide = new Slide();
|
||||
$slide->fill($request->validated());
|
||||
|
||||
if ($slide->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.slides.edit', $slide)
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.slides'))]
|
||||
));
|
||||
return redirect()->route('bo.slides.edit', $slide->id)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::singular(__('models.classes.slides'))
|
||||
]));
|
||||
}
|
||||
return back();
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::singular(__('models.classes.slides'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -82,13 +88,11 @@ class SlideController extends Controller
|
|||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Slide $slide
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Slide $slide)
|
||||
public function edit(Slide $slide): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.slides.edit', [
|
||||
'slide' => $slide
|
||||
]);
|
||||
return view('bo.pages.slides.edit', ['slideModel' => $slide]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -96,22 +100,23 @@ class SlideController extends Controller
|
|||
*
|
||||
* @param \App\Http\Requests\Bo\Slides\UpdateSlideRequest $request
|
||||
* @param \App\Models\Slide $slide
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateSlideRequest $request, Slide $slide)
|
||||
public function update(UpdateSlideRequest $request, Slide $slide): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $slide) {
|
||||
$slide->fill($request->validated());
|
||||
|
||||
if ($slide->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.slides.edit', $slide)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.slides'))]
|
||||
));
|
||||
return redirect()->route('bo.slides.edit', $slide->id)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::singular(__('models.classes.slides'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back();
|
||||
return redirect()->route('bo.slides.edit', $slide->id)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::singular(__('models.classes.slides'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -119,18 +124,19 @@ class SlideController extends Controller
|
|||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Slide $slide
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Slide $slide)
|
||||
public function destroy(Slide $slide): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if ($slide->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.slides.index')
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.slides'))]
|
||||
));
|
||||
return redirect()->route('bo.slides.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::singular(__('models.classes.slides'))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()->with('error', trans('Suppression impossible'));
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::singular(__('models.classes.slides'))
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,67 +16,67 @@ class TagController extends Controller
|
|||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $tags */
|
||||
$tags = Tag::query();
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $tagModels */
|
||||
$tagModels = Tag::query();
|
||||
|
||||
if ($request->search) {
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$tags,
|
||||
$request->search,
|
||||
$tagModels,
|
||||
$search,
|
||||
null,
|
||||
'label'
|
||||
);
|
||||
}
|
||||
|
||||
$this->sortQuery($tags);
|
||||
$searchFields = trans('Nom');
|
||||
|
||||
$tags = $tags->paginate(10);
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($tagModels);
|
||||
|
||||
return view('bo.pages.tags.index', compact('tags', 'searchFields'));
|
||||
/** Custom pagination */
|
||||
$tagModels = $this->paginate($tagModels);
|
||||
|
||||
return view('bo.pages.tags.index', compact('tagModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Models\Tag $tag
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create()
|
||||
public function create(Tag $tag): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.tags.create');
|
||||
return view('bo.pages.tags.create', ['tagModel' => $tag]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Tags\StoreTagRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\Tags\StoreTagRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreTagRequest $request)
|
||||
public function store(StoreTagRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$tag = new Tag();
|
||||
$tag->fill($request->validated());
|
||||
|
||||
if ($tag->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.tags.edit', $tag)
|
||||
->with('success', trans(
|
||||
':model a été créé',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
));
|
||||
return redirect()->route('bo.tags.edit', $tag->id)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::singular(__('models.classes.tags'))
|
||||
]));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été créé',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
));
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::singular(__('models.classes.tags'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -84,9 +84,9 @@ class TagController extends Controller
|
|||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Tags\StoreTagRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function jsonStore(StoreTagRequest $request)
|
||||
public function jsonStore(StoreTagRequest $request): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
/** @var \App\Models\Tag */
|
||||
|
|
@ -101,66 +101,57 @@ class TagController extends Controller
|
|||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Tag $tag
|
||||
* @return \Illuminate\Http\Response
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Tag $tag)
|
||||
public function edit(Tag $tag): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('bo.pages.tags.edit', [
|
||||
'tag' => $tag,
|
||||
'tagModel' => $tag,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Tags\UpdateTagRequest $request
|
||||
* @param \App\Models\Tag $tag
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Http\Requests\Bo\Tags\UpdateTagRequest $request
|
||||
* @param \App\Models\Tag $tag
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateTagRequest $request, Tag $tag)
|
||||
public function update(UpdateTagRequest $request, Tag $tag): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $tag) {
|
||||
$tag->fill($request->validated());
|
||||
|
||||
if ($tag->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.tags.edit', $tag)
|
||||
->with('success', trans(
|
||||
':model a été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
));
|
||||
return redirect()->route('bo.tags.edit', $tag->id)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::singular(__('models.classes.tags'))
|
||||
]));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été mis à jour',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
));
|
||||
return redirect()->route('bo.tags.edit', $tag->id)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::singular(__('models.classes.tags'))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Tag $tag
|
||||
* @return \Illuminate\Http\Response
|
||||
* @param \App\Models\Tag $tag
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Tag $tag)
|
||||
public function destroy(Tag $tag): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if ($tag->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.tags.index')
|
||||
->with('warning', trans(
|
||||
':model a bien été supprimé',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
));
|
||||
return redirect()->route('bo.tags.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::singular(__('models.classes.tags'))
|
||||
]));
|
||||
}
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
':model n\'a pas été supprimée',
|
||||
['model' => Str::singular(trans('models.classes.tags'))]
|
||||
));
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::singular(__('models.classes.tags'))
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,18 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\Advices\AdviceTypeEnum;
|
||||
use App\Enums\Pagination\ItemsPerPaginationEnum;
|
||||
use App\Enums\Products\ProductSpeciesEnum;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use App\Models\Advice;
|
||||
use App\Models\News;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -19,21 +22,19 @@ use Illuminate\Support\Str;
|
|||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
use DispatchesJobs;
|
||||
use ValidatesRequests;
|
||||
|
||||
// Back search methods.
|
||||
|
||||
/**
|
||||
* Build Search query on specified fields
|
||||
* splitting search into words or using whole sentence
|
||||
*
|
||||
* @param 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 Builder
|
||||
* @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,
|
||||
|
|
@ -64,10 +65,10 @@ class Controller extends BaseController
|
|||
/**
|
||||
* Build query search on all fields
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param string $search
|
||||
* @param array $fields
|
||||
* @return Builder
|
||||
* @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): Builder
|
||||
{
|
||||
|
|
@ -94,9 +95,9 @@ class Controller extends BaseController
|
|||
/**
|
||||
* Sort columns with a query
|
||||
*
|
||||
* @param Builder $query
|
||||
* @param array $ignore
|
||||
* @return Builder
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param array $ignore
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function sortQuery(Builder $query, array $ignore = []): Builder
|
||||
{
|
||||
|
|
@ -104,11 +105,14 @@ class Controller extends BaseController
|
|||
$table = $query->getModel()->getTable();
|
||||
if (request()->sort_col) {
|
||||
Session::put("$rName.sort_col", request()->sort_col);
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->sort_way) {
|
||||
Session::put("$rName.sort_way", request()->sort_way);
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->rst) {
|
||||
Session::remove("$rName.sorted");
|
||||
Session::remove("$rName.sort_col");
|
||||
Session::remove("$rName.sort_way");
|
||||
}
|
||||
|
|
@ -127,6 +131,28 @@ class Controller extends BaseController
|
|||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize pagination with cache or config (default).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \App\Enums\Pagination\ItemsPerPaginationEnum|null $pagination
|
||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
protected function paginate(Builder $query, ItemsPerPaginationEnum $pagination = null): LengthAwarePaginator
|
||||
{
|
||||
$currentRoutePath = Str::slug(request()->route()->getName());
|
||||
$cacheKey = "pagination.{$currentRoutePath}";
|
||||
$pagination = $pagination ?? ItemsPerPaginationEnum::twelve;
|
||||
$pagination = ToolboxHelper::getValidatedPaginate(
|
||||
Cache::get($cacheKey, $pagination->value)
|
||||
);
|
||||
if (Cache::get($cacheKey) !== $pagination) {
|
||||
Cache::put($cacheKey, $pagination);
|
||||
}
|
||||
$query = $query->paginate($pagination);
|
||||
return $query;
|
||||
}
|
||||
|
||||
// Front Search methods.
|
||||
|
||||
/**
|
||||
|
|
@ -165,11 +191,11 @@ class Controller extends BaseController
|
|||
if (\strlen($search)) {
|
||||
/** @var \App\Enums\Products\ProductSpeciesEnum|null $specie */
|
||||
$specie = \collect(ProductSpeciesEnum::toArray())
|
||||
->filter(function (ProductSpeciesEnum $specie) use ($search) {
|
||||
->filter(function (mixed $specie) use ($search) {
|
||||
return \strpos(Str::lower($specie->label), Str::lower($search)) !== false;
|
||||
})->first();
|
||||
if ($specie) {
|
||||
$query->orWhere('species', $specie);
|
||||
$query->orWhere('species', $specie->value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -206,7 +232,7 @@ class Controller extends BaseController
|
|||
protected function getRecipeQuery(string $search): Builder
|
||||
{
|
||||
return Advice::query()->where('status', true)
|
||||
->where('type', '=', AdviceTypeEnum::recipes()->value)
|
||||
->where('type', '=', AdviceTypeEnum::recipes->value)
|
||||
->where(function ($query) use ($search) {
|
||||
$query->where('title', 'like', "%{$search}%");
|
||||
$query->orWhere('preparation', 'like', "%{$search}%");
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ class ActivitiesController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function sociale()
|
||||
public function sociale(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// phpcs:disable
|
||||
$activity_title = "Restauration sociale";
|
||||
|
|
@ -43,7 +43,7 @@ class ActivitiesController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function commerciale()
|
||||
public function commerciale(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// phpcs:disable
|
||||
$activity_title = "Restauration commerciale";
|
||||
|
|
@ -55,7 +55,7 @@ class ActivitiesController extends Controller
|
|||
La pintade et le canard pour des repas gourmands. <br><br>
|
||||
Des produits cuits pour plus de praticité et des services rapides. <br><br>
|
||||
Une large gamme de pané pour la création de burger.<br><br>
|
||||
Ou encore de nombreux produits pour la réalisation des menu enfants.";
|
||||
Ou encore de nombreux produits pour la réalisation des menu enfants.";
|
||||
// phpcs:enable
|
||||
$activity_image = "restau-commerciale.jpg";
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ class ActivitiesController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function distributeur()
|
||||
public function distributeur(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// phpcs:disable
|
||||
$activity_title = "Distributeur";
|
||||
|
|
@ -108,7 +108,7 @@ class ActivitiesController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function boulangerie()
|
||||
public function boulangerie(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// phpcs:disable
|
||||
$activity_title = "Boul Pat";
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class AdnController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.adn.adn');
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ class AdnController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function story()
|
||||
public function story(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.adn.story');
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ class AdnController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function btob()
|
||||
public function btob(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.adn.btob');
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ class AdnController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function breeder()
|
||||
public function breeder(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.adn.breeder');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class BreederController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.breeder');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class BusinessController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.btob');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class ContactController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.contact');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class EngagmentsController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function francais()
|
||||
public function francais(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.engagments.francais');
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ class EngagmentsController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function eleverdurablement()
|
||||
public function eleverdurablement(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.engagments.eleverdurablement');
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ class EngagmentsController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function biennourrir()
|
||||
public function biennourrir(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.engagments.biennourrir');
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ class EngagmentsController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function respecterlaterre()
|
||||
public function respecterlaterre(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.engagments.respecterlaterre');
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ class EngagmentsController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function vivreensemble()
|
||||
public function vivreensemble(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.engagments.vivreensemble');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,19 +18,19 @@ class ExpertiseController extends Controller
|
|||
* @return \Illuminate\Contracts\View\View
|
||||
*
|
||||
*/
|
||||
public function canard()
|
||||
public function canard(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Get VIP Products for this page.
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::duck()->value)->get();
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::duck->value())->get();
|
||||
$products = Product::query()->where('status', true)
|
||||
->where('species', ProductSpeciesEnum::canard()->value)
|
||||
->where('species', ProductSpeciesEnum::canard->value())
|
||||
->inRandomOrder()
|
||||
->limit(3)
|
||||
->with('subrange.range')
|
||||
->get();
|
||||
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||
return $query->where('species', ProductSpeciesEnum::canard()->value);
|
||||
})->where('type', AdviceTypeEnum::recipes())->limit(3)->get();
|
||||
return $query->where('species', ProductSpeciesEnum::canard->value());
|
||||
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||
|
||||
return view('fo.pages.expertise.canard', compact('vip', 'products', 'recipes'));
|
||||
}
|
||||
|
|
@ -40,19 +40,19 @@ class ExpertiseController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function dinde()
|
||||
public function dinde(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Get VIP Products for this page.
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::turkey()->value)->get();
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::turkey->value())->get();
|
||||
$products = Product::query()->where('status', true)
|
||||
->where('species', ProductSpeciesEnum::dinde()->value)
|
||||
->where('species', ProductSpeciesEnum::dinde->value())
|
||||
->inRandomOrder()
|
||||
->limit(3)
|
||||
->with('subrange.range')
|
||||
->get();
|
||||
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||
return $query->where('species', ProductSpeciesEnum::dinde()->value);
|
||||
})->where('type', AdviceTypeEnum::recipes())->limit(3)->get();
|
||||
return $query->where('species', ProductSpeciesEnum::dinde->value());
|
||||
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||
|
||||
return view('fo.pages.expertise.dinde', compact('vip', 'products', 'recipes'));
|
||||
}
|
||||
|
|
@ -62,19 +62,19 @@ class ExpertiseController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function lapin()
|
||||
public function lapin(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Get VIP Products for this page.
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::rabbit()->value)->get();
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::rabbit->value())->get();
|
||||
$products = Product::query()->where('status', true)
|
||||
->where('species', ProductSpeciesEnum::lapin()->value)
|
||||
->where('species', ProductSpeciesEnum::lapin->value())
|
||||
->inRandomOrder()
|
||||
->limit(3)
|
||||
->with('subrange.range')
|
||||
->get();
|
||||
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||
return $query->where('species', ProductSpeciesEnum::lapin()->value);
|
||||
})->where('type', AdviceTypeEnum::recipes())->limit(3)->get();
|
||||
return $query->where('species', ProductSpeciesEnum::lapin->value());
|
||||
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||
|
||||
return view('fo.pages.expertise.lapin', compact('vip', 'products', 'recipes'));
|
||||
}
|
||||
|
|
@ -84,19 +84,19 @@ class ExpertiseController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function pintade()
|
||||
public function pintade(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Get VIP Products for this page.
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::guineafowl()->value)->get();
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::guineafowl->value())->get();
|
||||
$products = Product::query()->where('status', true)
|
||||
->where('species', ProductSpeciesEnum::pintade()->value)
|
||||
->where('species', ProductSpeciesEnum::pintade->value())
|
||||
->inRandomOrder()
|
||||
->limit(3)
|
||||
->with('subrange.range')
|
||||
->get();
|
||||
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||
return $query->where('species', ProductSpeciesEnum::pintade()->value);
|
||||
})->where('type', AdviceTypeEnum::recipes())->limit(3)->get();
|
||||
return $query->where('species', ProductSpeciesEnum::pintade->value());
|
||||
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||
|
||||
return view('fo.pages.expertise.pintade', compact('vip', 'products', 'recipes'));
|
||||
}
|
||||
|
|
@ -106,19 +106,19 @@ class ExpertiseController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function poulet()
|
||||
public function poulet(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Get VIP Products for this page.
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::chicken()->value)->get();
|
||||
$vip = ExpertiseProduct::query()->where('page', ExpertiseProductPageEnum::chicken->value())->get();
|
||||
$products = Product::query()->where('status', true)
|
||||
->where('species', ProductSpeciesEnum::poulet()->value)
|
||||
->where('species', ProductSpeciesEnum::poulet->value())
|
||||
->inRandomOrder()
|
||||
->limit(3)
|
||||
->with('subrange.range')
|
||||
->get();
|
||||
$recipes = Advice::query()->whereHas('products', function ($query) {
|
||||
return $query->where('species', ProductSpeciesEnum::poulet()->value);
|
||||
})->where('type', AdviceTypeEnum::recipes())->limit(3)->get();
|
||||
return $query->where('species', ProductSpeciesEnum::poulet->value());
|
||||
})->where('type', AdviceTypeEnum::recipes)->limit(3)->get();
|
||||
|
||||
return view('fo.pages.expertise.poulet', compact('vip', 'products', 'recipes'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,14 +17,13 @@ class HomeController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
|
||||
// Get Slides.
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $slides */
|
||||
$slides = Slide::query();
|
||||
$this->sortQuery($slides);
|
||||
$slides->orderBy('order', 'DESC');
|
||||
$slides = $slides->get();
|
||||
|
||||
|
|
@ -33,25 +32,25 @@ class HomeController extends Controller
|
|||
|
||||
// VIP Products.
|
||||
$threeproducts = Product::where('status', true)
|
||||
->where('is_vip', true)
|
||||
->where('is_vip', true)
|
||||
->take(3)
|
||||
->orderBy('order', 'DESC')
|
||||
->with('subrange.range')
|
||||
->get();
|
||||
->get();
|
||||
|
||||
// Get Agenda.
|
||||
// Events starting in the future.
|
||||
$events = News::where('status', true)
|
||||
->where('event_start', '>', Carbon::now())
|
||||
->orderBy('event_start', 'desc')
|
||||
->take(2)->get();
|
||||
->where('event_start', '>', Carbon::now())
|
||||
->orderBy('event_start', 'desc')
|
||||
->take(2)->get();
|
||||
|
||||
$events = $events->reverse();
|
||||
|
||||
foreach ($events as $event) {
|
||||
$event->cal_link = Link::create($event->title, $event->event_start, $event->event_end)
|
||||
->description($event->event_text)
|
||||
->ics();
|
||||
->description($event->event_text)
|
||||
->ics();
|
||||
}
|
||||
|
||||
// Get last 3 News.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class IdeasController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.ideas.ideas');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class NewsController extends Controller
|
|||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request)
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Get NewsCategories.
|
||||
$categories = NewsCategory::orderBy('label', 'ASC')->get();
|
||||
|
|
@ -27,16 +27,16 @@ class NewsController extends Controller
|
|||
isset($filters_activated) and $filters_activated[0] != 'all',
|
||||
function ($query) use ($filters_activated) {
|
||||
$query->with('categories')
|
||||
->whereRelation('categories', function ($query) use ($filters_activated) {
|
||||
foreach ($filters_activated as $value) {
|
||||
$query->orWhere('id', 'like', $value);
|
||||
}
|
||||
});
|
||||
->whereRelation('categories', function ($query) use ($filters_activated) {
|
||||
foreach ($filters_activated as $value) {
|
||||
$query->orWhere('id', 'like', $value);
|
||||
}
|
||||
});
|
||||
}
|
||||
)
|
||||
->where('status', true)
|
||||
->orderBy('created_at')
|
||||
->paginate(6);
|
||||
->paginate(6);
|
||||
|
||||
return view('fo.pages.news.index', compact('categories', 'news', 'filters_activated'));
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ class NewsController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(News $news)
|
||||
public function show(News $news): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$news->load('categories', 'news.categories', 'products');
|
||||
$readingTime = $news->getReadingTime();
|
||||
|
|
|
|||
|
|
@ -11,11 +11,9 @@ use App\Http\Resources\Fo\Products\ProductResource;
|
|||
use App\Models\Product;
|
||||
use App\Models\Range;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use Mccarlosen\LaravelMpdf\LaravelMpdf;
|
||||
|
||||
class ProductsController extends Controller
|
||||
{
|
||||
|
|
@ -24,7 +22,7 @@ class ProductsController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// Gammes.
|
||||
$ranges = Range::all();
|
||||
|
|
@ -36,9 +34,9 @@ class ProductsController extends Controller
|
|||
* View a specific range products
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function products(Range $range)
|
||||
public function products(Range $range): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$ranges = Range::query()->with('subranges')->get();
|
||||
$range->load('subranges');
|
||||
|
|
@ -54,9 +52,9 @@ class ProductsController extends Controller
|
|||
*
|
||||
* @param \App\Http\Requests\Fo\Products\AjaxFilterProductsRequest $request
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function productsAjax(AjaxFilterProductsRequest $request, Range $range)
|
||||
public function productsAjax(AjaxFilterProductsRequest $request, Range $range): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
// * Init product query with search and status.
|
||||
$search = htmlspecialchars($request->query('search') ?? '');
|
||||
|
|
@ -93,9 +91,9 @@ class ProductsController extends Controller
|
|||
* View a specific range products
|
||||
*
|
||||
* @param \App\Models\Product $publishedProduct
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Product $publishedProduct)
|
||||
public function show(Product $publishedProduct): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> */
|
||||
$recipes = $publishedProduct->recipesQuery()->where('status', true)->get();
|
||||
|
|
@ -129,9 +127,9 @@ class ProductsController extends Controller
|
|||
* Print product commercial sheet
|
||||
*
|
||||
* @param \App\Models\Product $publishedProduct
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function printCommericalSheet(Product $publishedProduct)
|
||||
public function printCommericalSheet(Product $publishedProduct): \Symfony\Component\HttpFoundation\Response
|
||||
{
|
||||
$title = trans('Fiche commerciale du produit : :label - :appname', [
|
||||
'label' => $publishedProduct->label,
|
||||
|
|
@ -152,8 +150,10 @@ class ProductsController extends Controller
|
|||
* @param \App\Models\Product $publishedProduct
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function addProductToBasket(AjaxAddProductBasket $request, Product $publishedProduct): JsonResponse
|
||||
{
|
||||
public function addProductToBasket(
|
||||
AjaxAddProductBasket $request,
|
||||
Product $publishedProduct
|
||||
): \Illuminate\Http\JsonResponse {
|
||||
$sessionProducts = $this->getBasketProducts();
|
||||
$sessionProducts->put(
|
||||
$publishedProduct->id,
|
||||
|
|
@ -175,7 +175,7 @@ class ProductsController extends Controller
|
|||
* @param string $slug
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function removeProductFromBasket(string $slug): JsonResponse
|
||||
public function removeProductFromBasket(string $slug): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$sessionProducts = $this->getBasketProducts()->filter(function (array $basketElement) use ($slug) {
|
||||
return $basketElement['product']->slug !== $slug and !empty($slug);
|
||||
|
|
@ -209,13 +209,13 @@ class ProductsController extends Controller
|
|||
* @param string $title
|
||||
* @return \Mccarlosen\LaravelMpdf\LaravelMpdf
|
||||
*/
|
||||
private function generateProductCommercialPdf(Product $product, string $title): LaravelMpdf
|
||||
private function generateProductCommercialPdf(Product $product, string $title): \Mccarlosen\LaravelMpdf\LaravelMpdf
|
||||
{
|
||||
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */
|
||||
$mpdf = app('laravel-mpdf');
|
||||
/** @var \Mccarlosen\LaravelMpdf\LaravelMpdf */
|
||||
$pdf = $mpdf->loadView(
|
||||
'documents.product-commercial-sheet',
|
||||
'fo.documents.product-commercial-sheet',
|
||||
// * Dirty convert to object.
|
||||
[
|
||||
'title' => $title,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class RecipesController extends Controller
|
|||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function indexRecipes(Request $request)
|
||||
public function indexRecipes(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$search_range = $request->search_range;
|
||||
$search_cooking_time = $request->search_cooking_time;
|
||||
|
|
@ -64,11 +64,11 @@ class RecipesController extends Controller
|
|||
* @param \App\Models\Advice $publishedAdvice
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Advice $publishedAdvice)
|
||||
public function show(Advice $publishedAdvice): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$recipe = $publishedAdvice;
|
||||
$relatedRecipes = $publishedAdvice->advices()->where('type', '=', AdviceTypeEnum::recipes()->value)->get();
|
||||
$relatedTips = $publishedAdvice->advices()->where('type', '=', AdviceTypeEnum::tips()->value)->get();
|
||||
$relatedRecipes = $publishedAdvice->advices()->where('type', '=', AdviceTypeEnum::recipes->value())->get();
|
||||
$relatedTips = $publishedAdvice->advices()->where('type', '=', AdviceTypeEnum::tips->value())->get();
|
||||
|
||||
return view('fo.pages.ideas.recipe', compact('recipe', 'relatedRecipes', 'relatedTips'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ class SearchController extends Controller
|
|||
/**
|
||||
* Search input txt in products, news and recipes
|
||||
*
|
||||
* @param Request $request
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function search(Request $request)
|
||||
public function search(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$search = htmlspecialchars($request->query('search') ?? '');
|
||||
$model = $request->query('model');
|
||||
|
|
@ -65,7 +65,7 @@ class SearchController extends Controller
|
|||
* @param string $search
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function searchModel(string $modelName, string $search)
|
||||
public function searchModel(string $modelName, string $search): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$models = [];
|
||||
$modelList = [
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class StoryController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index()
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return view('fo.pages.story');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ class TipsController extends Controller
|
|||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function indexTips()
|
||||
public function indexTips(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$advices = Advice::query()->with('tags')
|
||||
->where('type', AdviceTypeEnum::tips())
|
||||
->where('type', AdviceTypeEnum::tips)
|
||||
->where('status', true)
|
||||
->paginate(9);
|
||||
return view('fo.pages.ideas.tips', \compact('advices'));
|
||||
|
|
@ -26,9 +26,9 @@ class TipsController extends Controller
|
|||
* Display an advice
|
||||
*
|
||||
* @param \App\Models\Advice $publishedAdvice
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Advice $publishedAdvice)
|
||||
public function show(Advice $publishedAdvice): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$publishedAdvice->load([
|
||||
'advices', 'products.subrange', 'tags'
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ class Kernel extends HttpKernel
|
|||
protected $middleware = [
|
||||
\App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
|
|
@ -12,9 +13,8 @@ class Authenticate extends Middleware
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
protected function redirectTo(Request $request): ?string
|
||||
{
|
||||
$logins = [
|
||||
'backend' => route('bo.login')
|
||||
|
|
@ -31,8 +31,10 @@ class Authenticate extends Middleware
|
|||
}
|
||||
}
|
||||
}
|
||||
return collect($logins)->first() ?? '/';
|
||||
return route('login');
|
||||
}
|
||||
abort(401);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,5 @@ class EncryptCookies extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Http\Middleware;
|
|||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class HtmlSanitizer
|
||||
{
|
||||
|
|
@ -12,21 +13,34 @@ class HtmlSanitizer
|
|||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param mixed ...$params
|
||||
* @return mixed
|
||||
* @param string|array ...$params
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next, ...$params)
|
||||
public function handle(Request $request, \Closure $next, string|array ...$params): Response
|
||||
{
|
||||
$inputs = $request->all();
|
||||
array_walk_recursive($inputs, function (&$input, $name) use ($params) {
|
||||
/** @var callable|null */
|
||||
$cleanInput = null;
|
||||
$cleanInput = function (
|
||||
null|string|array &$input,
|
||||
string $name,
|
||||
?string $rootName = null
|
||||
) use (
|
||||
$params,
|
||||
&$cleanInput
|
||||
): void {
|
||||
// * Nested element array
|
||||
if (is_array($input)) {
|
||||
array_walk_recursive($input, $cleanInput, $name);
|
||||
}
|
||||
if (!is_string($input)) {
|
||||
return;
|
||||
}
|
||||
if (in_array($name, $params)) {
|
||||
if (in_array($name, $params) or in_array($rootName ?? $name, $params)) {
|
||||
// ? Is a json input ?
|
||||
if ($isJson = \json_decode($input, true) and is_array($isJson)) {
|
||||
// ! Decode each json field recursive.
|
||||
\array_walk_recursive($isJson, function (&$item) {
|
||||
\array_walk_recursive($isJson, function (string|array &$item) {
|
||||
if (\is_string($item)) {
|
||||
$item = clean($item);
|
||||
$item = ToolboxHelper::stripCkEditorSchemesOnMediaInputs($item);
|
||||
|
|
@ -39,7 +53,8 @@ class HtmlSanitizer
|
|||
} else {
|
||||
$input = strip_tags($input);
|
||||
}
|
||||
});
|
||||
};
|
||||
\array_walk($inputs, $cleanInput);
|
||||
$request->merge($inputs);
|
||||
return $next($request);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,5 @@ class PreventRequestsDuringMaintenance extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,27 +4,38 @@ namespace App\Http\Middleware;
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \RuntimeException If guard is unhandled.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next, ...$guards)
|
||||
public function handle(Request $request, \Closure $next, ...$guards): Response
|
||||
{
|
||||
$logins = [
|
||||
'backend' => route('bo.dashboard')
|
||||
];
|
||||
// phpcs:enable phpcs:disable
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return \redirect()->to($logins[$guard]);
|
||||
switch ($guard) {
|
||||
case 'frontend':
|
||||
return \redirect()->route('fo.home');
|
||||
case 'backend':
|
||||
if (!$request->routeIs('bo.*')) {
|
||||
continue;
|
||||
}
|
||||
return \redirect()->route('bo.dashboard');
|
||||
default:
|
||||
throw new \RuntimeException("Unhandled guard `{$guard}` .");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Closure;
|
|||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\Facades\Vite;
|
||||
|
||||
class SecureHeaders
|
||||
{
|
||||
|
|
@ -24,13 +25,14 @@ class SecureHeaders
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
public function handle(Request $request, Closure $next): \Symfony\Component\HttpFoundation\Response
|
||||
{
|
||||
View::share('nonce', $nonce = \uniqid());
|
||||
View::share('nonce', $nonce = Vite::useCspNonce());
|
||||
// * For VueJS dev tool to execute
|
||||
$jsDev = config('app.debug') ? "'unsafe-eval' 'unsafe-inline'" : "'nonce-$nonce'";
|
||||
$reportUri = Route::has('cspReportUri') ?
|
||||
|
|
@ -83,7 +85,7 @@ class SecureHeaders
|
|||
* @param array $headerList
|
||||
* @return void
|
||||
*/
|
||||
private function removeUnwantedHeaders(array $headerList)
|
||||
private function removeUnwantedHeaders(array $headerList): void
|
||||
{
|
||||
foreach ($headerList as $header) {
|
||||
header_remove($header);
|
||||
|
|
|
|||
15
app/Http/Middleware/ValidateSignature.php
Normal file
15
app/Http/Middleware/ValidateSignature.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
||||
class ValidateSignature extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the query string parameters that should be ignored.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
@ -12,5 +12,6 @@ class VerifyCsrfToken extends Middleware
|
|||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
];
|
||||
'/csp-report'
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use App\Traits\Requests\HasPicture;
|
|||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreAdviceRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -19,7 +19,7 @@ class StoreAdviceRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -28,28 +28,29 @@ class StoreAdviceRequest extends FormRequest
|
|||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
|
||||
*/
|
||||
// phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
//phpcs:enable
|
||||
$this->merge([
|
||||
'slug' => Str::slug(strip_tags($this->title)),
|
||||
'status' => $this->status ? true : false,
|
||||
'tags' => $this->tags ?? [],
|
||||
'products' => $this->products ?? [],
|
||||
'associated_tips_list' => $this->associated_tips_list ?? [],
|
||||
'slug' => Str::slug(strip_tags($this->title)),
|
||||
'status' => $this->status ? true : false,
|
||||
'tags' => $this->tags ?? [],
|
||||
'products' => $this->products ?? [],
|
||||
'associated_tips_list' => $this->associated_tips_list ?? [],
|
||||
'associated_recipes_list' => $this->associated_recipes_list ?? [],
|
||||
// * For sync relations
|
||||
'tags_list' => \collect($this->tags)->map(function ($value) {
|
||||
'tags_list' => \collect($this->tags)->map(function ($value) {
|
||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||
})->filter()->all(),
|
||||
'products_list' => \collect($this->products)->map(function ($value) {
|
||||
'products_list' => \collect($this->products)->map(function ($value) {
|
||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||
})->filter()->all(),
|
||||
'tips_list' => \collect($this->associated_tips_list)->map(function ($value) {
|
||||
'tips_list' => \collect($this->associated_tips_list)->map(function ($value) {
|
||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||
})->filter()->all(),
|
||||
'recipes_list' => \collect($this->associated_recipes_list)->map(function ($value) {
|
||||
'recipes_list' => \collect($this->associated_recipes_list)->map(function ($value) {
|
||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||
})->filter()->all(),
|
||||
]);
|
||||
|
|
@ -62,24 +63,25 @@ class StoreAdviceRequest extends FormRequest
|
|||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
|
||||
*/
|
||||
// phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
//phpcs:enable
|
||||
$rules = [
|
||||
'title' => 'required|min:3|max:255',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'type' => ['required', new EnumIsValidRule(AdviceTypeEnum::class)],
|
||||
'picture_alt' => 'required_with:picture|nullable|min:3|max:255',
|
||||
'picture_title' => 'required_with:picture|nullable|min:3|max:255',
|
||||
'sticker_alt' => 'required_with:sticker|nullable|min:3|max:255',
|
||||
'sticker_title' => 'required_with:sticker|nullable|min:3|max:255',
|
||||
'sticker_sm_alt' => 'required_with:sticker_sm|nullable|min:3|max:255',
|
||||
'sticker_sm_title' => 'required_with:sticker_sm|nullable|min:3|max:255',
|
||||
'preparation' => 'required|string|min:15',
|
||||
'advice' => 'nullable|string|min:15',
|
||||
'ingredients' => [
|
||||
'title' => 'required|min:3|max:255',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'type' => ['required', new Enum(AdviceTypeEnum::class)],
|
||||
'picture_alt' => 'required_with:picture|nullable|min:3|max:255',
|
||||
'picture_title' => 'required_with:picture|nullable|min:3|max:255',
|
||||
'sticker_alt' => 'required_with:sticker|nullable|min:3|max:255',
|
||||
'sticker_title' => 'required_with:sticker|nullable|min:3|max:255',
|
||||
'sticker_sm_alt' => 'required_with:sticker_sm|nullable|min:3|max:255',
|
||||
'sticker_sm_title' => 'required_with:sticker_sm|nullable|min:3|max:255',
|
||||
'preparation' => 'required|string|min:15',
|
||||
'advice' => 'nullable|string|min:15',
|
||||
'ingredients' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (count($value) < 1 || count($value) > 15) {
|
||||
|
|
@ -87,15 +89,15 @@ class StoreAdviceRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'ingredients.*' => 'required|array',
|
||||
'ingredients.*.value' => 'nullable|numeric|max:65535',
|
||||
'ingredients.*.label' => [
|
||||
'ingredients.*' => 'required|array',
|
||||
'ingredients.*.value' => 'nullable|numeric|max:65535',
|
||||
'ingredients.*.label' => [
|
||||
Rule::requiredIf(function () {
|
||||
return $this->type === AdviceTypeEnum::recipes()->value;
|
||||
return $this->type === AdviceTypeEnum::recipes->value();
|
||||
}),
|
||||
//phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->type == AdviceTypeEnum::recipes()->value) {
|
||||
if ($this->type == AdviceTypeEnum::recipes->value()) {
|
||||
if (!$value) {
|
||||
$fail(\trans('Le champ description de l\'ingrédient doit être une chaîne de caractères.'));
|
||||
}
|
||||
|
|
@ -106,7 +108,7 @@ class StoreAdviceRequest extends FormRequest
|
|||
},
|
||||
'max:255'
|
||||
],
|
||||
'guests_nb' => [
|
||||
'guests_nb' => [
|
||||
//phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if (
|
||||
|
|
@ -118,23 +120,23 @@ class StoreAdviceRequest extends FormRequest
|
|||
}
|
||||
}, 'nullable', 'numeric', 'min:1', 'max:99'
|
||||
],
|
||||
'youtube_title' => 'required_with:youtube_video_id|nullable|min:3|max:255',
|
||||
'youtube_video_id' => 'required_with:youtube_title|nullable|regex:%([^"&?\/\s]{11})%i',
|
||||
'cooking_time' => 'nullable|numeric|min:0|max:65535',
|
||||
'preparation_time' => [
|
||||
'youtube_title' => 'required_with:youtube_video_id|nullable|min:3|max:255',
|
||||
'youtube_video_id' => 'required_with:youtube_title|nullable|regex:%([^"&?\/\s]{11})%i',
|
||||
'cooking_time' => 'nullable|numeric|min:0|max:65535',
|
||||
'preparation_time' => [
|
||||
Rule::requiredIf(function () {
|
||||
return $this->type === AdviceTypeEnum::recipes()->value;
|
||||
return $this->type === AdviceTypeEnum::recipes->value();
|
||||
}),
|
||||
'numeric', 'min:0', 'max:65535'
|
||||
],
|
||||
'difficulty' => [
|
||||
'difficulty' => [
|
||||
Rule::requiredIf(function () {
|
||||
return $this->type === AdviceTypeEnum::recipes()->value;
|
||||
return $this->type === AdviceTypeEnum::recipes->value();
|
||||
}),
|
||||
new EnumIsValidRule(AdviceDifficultyEnum::class)
|
||||
new Enum(AdviceDifficultyEnum::class)
|
||||
],
|
||||
'status' => 'required|boolean',
|
||||
'tags' => [
|
||||
'status' => 'required|boolean',
|
||||
'tags' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (count($value) > 2) {
|
||||
|
|
@ -142,13 +144,13 @@ class StoreAdviceRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'tags.*' => 'required|array',
|
||||
'tags.*.id' => 'required|numeric|exists:tags,id|distinct',
|
||||
'tags.*.label' => 'required|string',
|
||||
'products' => [
|
||||
'tags.*' => 'required|array',
|
||||
'tags.*.id' => 'required|numeric|exists:tags,id|distinct',
|
||||
'tags.*.label' => 'required|string',
|
||||
'products' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if ($this->type == AdviceTypeEnum::recipes()->value) {
|
||||
if ($this->type == AdviceTypeEnum::recipes->value()) {
|
||||
if (count($value) < 1 || count($value) > 3) {
|
||||
$fail(\trans('Vous devez associer 1 à 3 produits.'));
|
||||
}
|
||||
|
|
@ -159,10 +161,10 @@ class StoreAdviceRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'products.*' => 'required|array',
|
||||
'products.*.value' => 'required|exists:products,id',
|
||||
'products.*.label' => 'required|string',
|
||||
'associated_tips_list' => [
|
||||
'products.*' => 'required|array',
|
||||
'products.*.value' => 'required|exists:products,id',
|
||||
'products.*.label' => 'required|string',
|
||||
'associated_tips_list' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (count($value) > 3) {
|
||||
|
|
@ -170,10 +172,10 @@ class StoreAdviceRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'associated_tips_list.*' => 'required|array',
|
||||
'associated_tips_list.*.value' => 'required|exists:advice,id',
|
||||
'associated_tips_list.*.label' => 'required|string',
|
||||
'associated_recipes_list' => [
|
||||
'associated_tips_list.*' => 'required|array',
|
||||
'associated_tips_list.*.value' => 'required|exists:advice,id',
|
||||
'associated_tips_list.*.label' => 'required|string',
|
||||
'associated_recipes_list' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (count($value) > 3) {
|
||||
|
|
@ -181,7 +183,7 @@ class StoreAdviceRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'associated_recipes_list.*' => 'required|array',
|
||||
'associated_recipes_list.*' => 'required|array',
|
||||
'associated_recipes_list.*.value' => 'required|exists:advice,id',
|
||||
'associated_recipes_list.*.label' => 'required|string',
|
||||
];
|
||||
|
|
@ -201,30 +203,30 @@ class StoreAdviceRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'title' => trans('Titre'),
|
||||
'slug' => trans('Slug'),
|
||||
'seo_title' => trans('title') . ' seo',
|
||||
'seo_description' => trans('description') . ' seo',
|
||||
'tags' => trans('tag'),
|
||||
'tags.*' => trans('tag'),
|
||||
'tags.*.id' => trans('id du tag'),
|
||||
'tags.*.label' => trans('label du tag'),
|
||||
'difficulty' => trans('Difficulté'),
|
||||
'picture' => trans('Visuel'),
|
||||
'picture_alt' => trans('Attribut alt du visuel'),
|
||||
'picture_title' => trans('Titre du visuel'),
|
||||
'sticker' => trans('Vignette'),
|
||||
'sticker_alt' => trans('Attribut alt de la vignette'),
|
||||
'sticker_title' => trans('Titre de la vignette'),
|
||||
'sticker_sm' => trans('Petite vignette'),
|
||||
'sticker_sm_alt' => trans('Attribut alt de la petite vignette'),
|
||||
'sticker_sm_title' => trans('Titre de la petite vignette'),
|
||||
'title' => trans('Titre'),
|
||||
'slug' => trans('Slug'),
|
||||
'seo_title' => trans('title') . ' seo',
|
||||
'seo_description' => trans('description') . ' seo',
|
||||
'tags' => trans('tag'),
|
||||
'tags.*' => trans('tag'),
|
||||
'tags.*.id' => trans('id du tag'),
|
||||
'tags.*.label' => trans('label du tag'),
|
||||
'difficulty' => trans('Difficulté'),
|
||||
'picture' => trans('Visuel'),
|
||||
'picture_alt' => trans('Attribut alt du visuel'),
|
||||
'picture_title' => trans('Titre du visuel'),
|
||||
'sticker' => trans('Vignette'),
|
||||
'sticker_alt' => trans('Attribut alt de la vignette'),
|
||||
'sticker_title' => trans('Titre de la vignette'),
|
||||
'sticker_sm' => trans('Petite vignette'),
|
||||
'sticker_sm_alt' => trans('Attribut alt de la petite vignette'),
|
||||
'sticker_sm_title' => trans('Titre de la petite vignette'),
|
||||
'ingredients.*.value' => trans('quantité de l\'ingrédient'),
|
||||
'ingredients.*.label' => trans('description de l\'ingrédient'),
|
||||
'guests_nb' => trans('Nombre de convives'),
|
||||
'youtube_title' => trans('Titre de la vidéo Youtube'),
|
||||
'youtube_video_id' => trans('ID de la vidéo Youtube'),
|
||||
'advice' => trans('Conseil LGP'),
|
||||
'guests_nb' => trans('Nombre de convives'),
|
||||
'youtube_title' => trans('Titre de la vidéo Youtube'),
|
||||
'youtube_video_id' => trans('ID de la vidéo Youtube'),
|
||||
'advice' => trans('Conseil LGP'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ namespace App\Http\Requests\Bo\ExpertiseProducts;
|
|||
use App\Enums\ExpertiseProducts\ExpertiseProductPageEnum;
|
||||
use App\Enums\NutriscoreEnum;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreExpertiseProductRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -14,7 +14,7 @@ class StoreExpertiseProductRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -24,12 +24,12 @@ class StoreExpertiseProductRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'is_frenchpoultry' => $this->is_frenchpoultry ? true : false,
|
||||
'is_frenchpoultry' => $this->is_frenchpoultry ? true : false,
|
||||
'is_natureeleveurs' => $this->is_natureeleveurs ? true : false,
|
||||
'points' => $this->points ?? []
|
||||
'points' => $this->points ?? []
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -38,19 +38,19 @@ class StoreExpertiseProductRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'page' => ['required', new EnumIsValidRule(ExpertiseProductPageEnum::class)],
|
||||
'label' => 'required|min:3|max:255',
|
||||
'title' => 'required|min:3|max:255',
|
||||
'subtitle' => 'required|min:3|max:255',
|
||||
'points' => 'required|array',
|
||||
'points.*' => 'required|array',
|
||||
'points.*.value' => 'required|min:3|max:255',
|
||||
'is_frenchpoultry' => 'required|boolean',
|
||||
'page' => ['required', new Enum(ExpertiseProductPageEnum::class)],
|
||||
'label' => 'required|min:3|max:255',
|
||||
'title' => 'required|min:3|max:255',
|
||||
'subtitle' => 'required|min:3|max:255',
|
||||
'points' => 'required|array',
|
||||
'points.*' => 'required|array',
|
||||
'points.*.value' => 'required|min:3|max:255',
|
||||
'is_frenchpoultry' => 'required|boolean',
|
||||
'is_natureeleveurs' => 'required|boolean',
|
||||
'nutriscore' => ['required', new EnumIsValidRule(NutriscoreEnum::class)]
|
||||
'nutriscore' => ['required', new Enum(NutriscoreEnum::class)]
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -62,16 +62,16 @@ class StoreExpertiseProductRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'page' => trans('Espèce'),
|
||||
'label' => trans('Libellé du bloc'),
|
||||
'title' => trans('Titre dans le bloc'),
|
||||
'subtitle' => trans('Sous-titre'),
|
||||
'points' => trans('Bloc des points forts'),
|
||||
'points.*' => trans('Point fort'),
|
||||
'points.*.value' => trans('Valeur Point fort'),
|
||||
'is_frenchpoultry' => trans('Label volaille française'),
|
||||
'page' => trans('Espèce'),
|
||||
'label' => trans('Libellé du bloc'),
|
||||
'title' => trans('Titre dans le bloc'),
|
||||
'subtitle' => trans('Sous-titre'),
|
||||
'points' => trans('Bloc des points forts'),
|
||||
'points.*' => trans('Point fort'),
|
||||
'points.*.value' => trans('Valeur Point fort'),
|
||||
'is_frenchpoultry' => trans('Label volaille française'),
|
||||
'is_natureeleveurs' => trans('Label nature d\'éleveur'),
|
||||
'nutriscore' => trans('Label Nutriscore')
|
||||
'nutriscore' => trans('Label Nutriscore')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class StoreNewsRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -24,28 +24,28 @@ class StoreNewsRequest extends FormRequest
|
|||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
|
||||
*/
|
||||
// phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh, Squiz.Commenting.FunctionComment.Missing
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
//phpcs:enable
|
||||
$this->merge([
|
||||
'slug' => Str::slug($this->title),
|
||||
'status' => $this->status ? true : false,
|
||||
'categories' => $this->categories ?? [],
|
||||
'products' => $this->products ?? [],
|
||||
'slug' => Str::slug($this->title),
|
||||
'status' => $this->status ? true : false,
|
||||
'categories' => $this->categories ?? [],
|
||||
'products' => $this->products ?? [],
|
||||
'associated_news_list' => $this->associated_news_list ?? [],
|
||||
// * For sync relations
|
||||
'news_list' => \collect($this->associated_news_list)->map(function ($value) {
|
||||
'news_list' => \collect($this->associated_news_list)->map(function ($value) {
|
||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||
})->filter()->all(),
|
||||
'products_list' => \collect($this->products)->map(function ($value) {
|
||||
'products_list' => \collect($this->products)->map(function ($value) {
|
||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||
})->filter()->all(),
|
||||
'categories_list' => \collect($this->categories)->map(function ($value) {
|
||||
'categories_list' => \collect($this->categories)->map(function ($value) {
|
||||
return \is_array($value) ? ($value['value'] ?? null) : null;
|
||||
})->filter()->all()
|
||||
]);
|
||||
|
||||
$this->mergePicture('picture');
|
||||
$this->mergePicture('picture2');
|
||||
}
|
||||
|
|
@ -55,34 +55,34 @@ class StoreNewsRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'title' => 'required|min:3|max:255',
|
||||
'subtitle' => 'required|min:3|max:255',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'picture_alt' => 'required_with:picture|nullable|min:3|max:255',
|
||||
'picture_title' => 'required_with:picture|nullable|min:3|max:255',
|
||||
'picture2_alt' => 'required_with:picture2|nullable|min:3|max:255',
|
||||
'picture2_title' => 'required_with:picture2|nullable|min:3|max:255',
|
||||
'content' => 'required_with:picture|nullable|string|min:15',
|
||||
'content2' => 'required_with:picture2|nullable|string|min:15',
|
||||
'event_start' => 'nullable|date_format:Y-m-d',
|
||||
'event_end' => [
|
||||
'title' => 'required|min:3|max:255',
|
||||
'subtitle' => 'required|min:3|max:255',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'picture_alt' => 'required_with:picture|nullable|min:3|max:255',
|
||||
'picture_title' => 'required_with:picture|nullable|min:3|max:255',
|
||||
'picture2_alt' => 'required_with:picture2|nullable|min:3|max:255',
|
||||
'picture2_title' => 'required_with:picture2|nullable|min:3|max:255',
|
||||
'content' => 'required_with:picture|nullable|string|min:15',
|
||||
'content2' => 'required_with:picture2|nullable|string|min:15',
|
||||
'event_start' => 'nullable|date_format:Y-m-d',
|
||||
'event_end' => [
|
||||
'required_with:event_start',
|
||||
'after_or_equal:event_start',
|
||||
'nullable',
|
||||
'date_format:Y-m-d'
|
||||
],
|
||||
'event_text' => [
|
||||
'event_text' => [
|
||||
'required_with:event_start',
|
||||
'nullable',
|
||||
'min:3',
|
||||
'max:255'
|
||||
],
|
||||
'status' => 'required|boolean',
|
||||
'categories' => [
|
||||
'categories' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (count($value) < 1 || count($value) > 2) {
|
||||
|
|
@ -90,10 +90,10 @@ class StoreNewsRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'categories.*' => 'required|array',
|
||||
'categories.*.value' => 'required|exists:news_categories,id',
|
||||
'categories.*.label' => 'required|string',
|
||||
'products' => [
|
||||
'categories.*' => 'required|array',
|
||||
'categories.*.value' => 'required|exists:news_categories,id',
|
||||
'categories.*.label' => 'required|string',
|
||||
'products' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (count($value) > 3) {
|
||||
|
|
@ -101,10 +101,10 @@ class StoreNewsRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'products.*' => 'required|array',
|
||||
'products.*.value' => 'required|exists:products,id',
|
||||
'products.*.label' => 'required|string',
|
||||
'associated_news_list' => [
|
||||
'products.*' => 'required|array',
|
||||
'products.*.value' => 'required|exists:products,id',
|
||||
'products.*.label' => 'required|string',
|
||||
'associated_news_list' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (count($value) > 3) {
|
||||
|
|
@ -112,7 +112,7 @@ class StoreNewsRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'associated_news_list.*' => 'required|array',
|
||||
'associated_news_list.*' => 'required|array',
|
||||
'associated_news_list.*.value' => 'required|exists:news,id',
|
||||
'associated_news_list.*.label' => 'required|string',
|
||||
];
|
||||
|
|
@ -131,23 +131,23 @@ class StoreNewsRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'title' => trans('Titre'),
|
||||
'slug' => trans('Slug'),
|
||||
'seo_title' => trans('title') . ' seo',
|
||||
'title' => trans('Titre'),
|
||||
'slug' => trans('Slug'),
|
||||
'seo_title' => trans('title') . ' seo',
|
||||
'seo_description' => trans('description') . ' seo',
|
||||
'subtitle' => trans('Sous-titre'),
|
||||
'picture' => trans('Image'),
|
||||
'picture_alt' => trans('Attribut alt de l\'image'),
|
||||
'picture_title' => trans('Titre de l\'image'),
|
||||
'picture2' => trans('Image 2'),
|
||||
'picture2_alt' => trans('Attribut alt de l\'image 2'),
|
||||
'picture2_title' => trans('Titre de l\'image 2'),
|
||||
'content' => trans('Contenu'),
|
||||
'content2' => trans('Contenu 2'),
|
||||
'event_start' => trans('Date de début de l\'évènement'),
|
||||
'event_end' => trans('Date de fin de l\'évènement'),
|
||||
'event_text' => trans('Description de l\'évènement'),
|
||||
'status' => trans('Status'),
|
||||
'subtitle' => trans('Sous-titre'),
|
||||
'picture' => trans('Image'),
|
||||
'picture_alt' => trans('Attribut alt de l\'image'),
|
||||
'picture_title' => trans('Titre de l\'image'),
|
||||
'picture2' => trans('Image 2'),
|
||||
'picture2_alt' => trans('Attribut alt de l\'image 2'),
|
||||
'picture2_title' => trans('Titre de l\'image 2'),
|
||||
'content' => trans('Contenu'),
|
||||
'content2' => trans('Contenu 2'),
|
||||
'event_start' => trans('Date de début de l\'évènement'),
|
||||
'event_end' => trans('Date de fin de l\'évènement'),
|
||||
'event_text' => trans('Description de l\'évènement'),
|
||||
'status' => trans('Status'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class UpdateNewsCategoryRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ class UpdateNewsCategoryRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'slug' => Str::slug(strip_tags($this->label))
|
||||
|
|
@ -34,7 +34,7 @@ class UpdateNewsCategoryRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'label' => 'required|min:3|max:30',
|
||||
|
|
@ -50,7 +50,7 @@ class UpdateNewsCategoryRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'label' => trans('label'),
|
||||
'slug' => trans('slug'),
|
||||
'slug' => trans('slug'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use App\Enums\Products\ProductSpeciesEnum;
|
|||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class StoreProductRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -18,7 +18,7 @@ class StoreProductRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -28,14 +28,14 @@ class StoreProductRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'slug' => Str::slug(strip_tags($this->name)),
|
||||
'slug' => Str::slug(strip_tags($this->name)),
|
||||
'is_frenchpoultry' => $this->is_frenchpoultry ? true : false,
|
||||
'is_vip' => $this->is_vip ? true : false,
|
||||
'is_egalim' => $this->is_egalim ? true : false,
|
||||
'status' => $this->status ? true : false
|
||||
'is_vip' => $this->is_vip ? true : false,
|
||||
'is_egalim' => $this->is_egalim ? true : false,
|
||||
'status' => $this->status ? true : false
|
||||
]);
|
||||
$this->mergePicture('sticker_sm');
|
||||
}
|
||||
|
|
@ -45,21 +45,21 @@ class StoreProductRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'label' => 'required|min:3|max:255',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'subrange_id' => 'required',
|
||||
'species' => ['required', new EnumIsValidRule(ProductSpeciesEnum::class)],
|
||||
'nutriscore' => ['required', new EnumIsValidRule(NutriscoreEnum::class)],
|
||||
'sticker_sm_alt' => 'required|min:3|max:255',
|
||||
'sticker_sm_title' => 'required|min:3|max:255',
|
||||
'ingredients' => 'required|string|min:15',
|
||||
'advantage' => 'required|string|min:15',
|
||||
'preparation' => 'required|string|min:15',
|
||||
'packaging' => [
|
||||
'label' => 'required|min:3|max:255',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'subrange_id' => 'required',
|
||||
'species' => ['required', new Enum(ProductSpeciesEnum::class)],
|
||||
'nutriscore' => ['required', new Enum(NutriscoreEnum::class)],
|
||||
'sticker_sm_alt' => 'required|min:3|max:255',
|
||||
'sticker_sm_title' => 'required|min:3|max:255',
|
||||
'ingredients' => 'required|string|min:15',
|
||||
'advantage' => 'required|string|min:15',
|
||||
'preparation' => 'required|string|min:15',
|
||||
'packaging' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (1 > count($value) || count($value) > 6) {
|
||||
|
|
@ -67,9 +67,9 @@ class StoreProductRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'packaging.*' => 'required|array',
|
||||
'packaging.*.value' => 'required|string|min:2|max:255',
|
||||
'caliber' => [
|
||||
'packaging.*' => 'required|array',
|
||||
'packaging.*.value' => 'required|string|min:2|max:255',
|
||||
'caliber' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (1 > count($value) || count($value) > 6) {
|
||||
|
|
@ -77,10 +77,10 @@ class StoreProductRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'caliber.*' => 'required|array',
|
||||
'caliber.*.value' => 'required|string|min:1|max:255',
|
||||
'nutritionnal_values' => 'required|array',
|
||||
'nutritionnal_values' => [
|
||||
'caliber.*' => 'required|array',
|
||||
'caliber.*.value' => 'required|string|min:1|max:255',
|
||||
'nutritionnal_values' => 'required|array',
|
||||
'nutritionnal_values' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
'present', 'array', function ($attribute, array $value, $fail) {
|
||||
if (count($value) != 9) {
|
||||
|
|
@ -88,13 +88,13 @@ class StoreProductRequest extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'nutritionnal_values.*' => 'nullable|array',
|
||||
'nutritionnal_values.*' => 'nullable|array',
|
||||
'nutritionnal_values.*.label' => 'nullable|string|min:3|max:255',
|
||||
'nutritionnal_values.*.value' => 'nullable|numeric|min:0',
|
||||
'is_frenchpoultry' => 'required|boolean',
|
||||
'is_vip' => 'required|boolean',
|
||||
'is_egalim' => 'required|boolean',
|
||||
'status' => 'required|boolean'
|
||||
'is_frenchpoultry' => 'required|boolean',
|
||||
'is_vip' => 'required|boolean',
|
||||
'is_egalim' => 'required|boolean',
|
||||
'status' => 'required|boolean'
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
|
|
@ -111,29 +111,29 @@ class StoreProductRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'label' => trans('title'),
|
||||
'slug' => trans('slug'),
|
||||
'seo_title' => trans('title') . ' seo',
|
||||
'seo_description' => trans('description') . ' seo',
|
||||
'subrange_id' => trans('sous-gamme'),
|
||||
'species' => trans('Espèce du produit'),
|
||||
'nutriscore' => trans('Label Nutriscore'),
|
||||
'sticker_sm' => trans('miniature'),
|
||||
'sticker_sm_alt' => trans('attribut alt de la miniature'),
|
||||
'sticker_sm_title' => trans('titre de la miniature'),
|
||||
'slider_pictures' => trans('images du slider'),
|
||||
'slider_pictures.*' => trans('image du slider'),
|
||||
'packaging' => trans('conditionnement'),
|
||||
'packaging.*.value' => trans('valeur du conditionnement'),
|
||||
'caliber' => trans('calibre'),
|
||||
'caliber.*.value' => trans('valeur du calibre'),
|
||||
'nutritionnal_values' => trans('valeurs nutritionnelles'),
|
||||
'label' => trans('title'),
|
||||
'slug' => trans('slug'),
|
||||
'seo_title' => trans('title') . ' seo',
|
||||
'seo_description' => trans('description') . ' seo',
|
||||
'subrange_id' => trans('sous-gamme'),
|
||||
'species' => trans('Espèce du produit'),
|
||||
'nutriscore' => trans('Label Nutriscore'),
|
||||
'sticker_sm' => trans('miniature'),
|
||||
'sticker_sm_alt' => trans('attribut alt de la miniature'),
|
||||
'sticker_sm_title' => trans('titre de la miniature'),
|
||||
'slider_pictures' => trans('images du slider'),
|
||||
'slider_pictures.*' => trans('image du slider'),
|
||||
'packaging' => trans('conditionnement'),
|
||||
'packaging.*.value' => trans('valeur du conditionnement'),
|
||||
'caliber' => trans('calibre'),
|
||||
'caliber.*.value' => trans('valeur du calibre'),
|
||||
'nutritionnal_values' => trans('valeurs nutritionnelles'),
|
||||
'nutritionnal_values.*.label' => trans('libellé de la valeur nutritionnelle'),
|
||||
'nutritionnal_values.*.value' => trans('valeur de la valeur nutritionnelle'),
|
||||
'is_frenchpoultry' => trans('Label volaille française'),
|
||||
'is_vip' => trans('Produit VIP'),
|
||||
'is_egalim' => trans('Produit Égalim'),
|
||||
'status' => trans('publish')
|
||||
'is_frenchpoultry' => trans('Label volaille française'),
|
||||
'is_vip' => trans('Produit VIP'),
|
||||
'is_egalim' => trans('Produit Égalim'),
|
||||
'status' => trans('publish')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class UpdateRangeRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ class UpdateRangeRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'slug' => Str::slug(strip_tags($this->label))
|
||||
|
|
@ -39,16 +39,16 @@ class UpdateRangeRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'label' => 'required|min:3|max:255',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'color' => 'required|color_rgba',
|
||||
'picture_alt' => 'required|min:3|max:255',
|
||||
'picture_title' => 'required|min:3|max:255',
|
||||
'picture_banner_alt' => 'required|min:3|max:255',
|
||||
'label' => 'required|min:3|max:255',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'color' => 'required|color_rgba',
|
||||
'picture_alt' => 'required|min:3|max:255',
|
||||
'picture_title' => 'required|min:3|max:255',
|
||||
'picture_banner_alt' => 'required|min:3|max:255',
|
||||
'picture_banner_title' => 'required|min:3|max:255',
|
||||
];
|
||||
return \array_merge(
|
||||
|
|
@ -66,16 +66,16 @@ class UpdateRangeRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'label' => trans('label'),
|
||||
'slug' => trans('slug'),
|
||||
'seo_title' => trans('title') . ' seo',
|
||||
'seo_description' => trans('description') . ' seo',
|
||||
'color' => trans('couleur'),
|
||||
'picture' => trans('Illustration'),
|
||||
'picture_alt' => trans('attribut alt de l\'image'),
|
||||
'picture_title' => trans('titre de l\'image'),
|
||||
'picture_banner' => trans('bannière'),
|
||||
'picture_banner_alt' => trans('attribut alt de la bannière'),
|
||||
'label' => trans('label'),
|
||||
'slug' => trans('slug'),
|
||||
'seo_title' => trans('title') . ' seo',
|
||||
'seo_description' => trans('description') . ' seo',
|
||||
'color' => trans('couleur'),
|
||||
'picture' => trans('Illustration'),
|
||||
'picture_alt' => trans('attribut alt de l\'image'),
|
||||
'picture_title' => trans('titre de l\'image'),
|
||||
'picture_banner' => trans('bannière'),
|
||||
'picture_banner_alt' => trans('attribut alt de la bannière'),
|
||||
'picture_banner_title' => trans('titre de la bannière'),
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class StoreSlideRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -24,10 +24,10 @@ class StoreSlideRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'button_display' => $this->button_display ? true : false,
|
||||
'button_display' => $this->button_display ? true : false,
|
||||
'button_targetblank' => $this->button_targetblank ? true : false,
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
|
|
@ -39,18 +39,18 @@ class StoreSlideRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'title' => 'required|min:3|max:255',
|
||||
'content' => 'required|string|min:15|max:540',
|
||||
'button_display' => 'required|boolean',
|
||||
'button_text' => 'nullable|min:3|max:45',
|
||||
'button_url' => 'nullable|min:3|max:255|url',
|
||||
'button_targetblank' => 'required|boolean',
|
||||
'picture_alt' => 'required|min:3|max:255',
|
||||
'picture_title' => 'required|min:3|max:255',
|
||||
'picture_thumbnail_alt' => 'required|min:3|max:255',
|
||||
'title' => 'required|min:3|max:255',
|
||||
'content' => 'required|string|min:15|max:540',
|
||||
'button_display' => 'required|boolean',
|
||||
'button_text' => 'nullable|min:3|max:45',
|
||||
'button_url' => 'nullable|min:3|max:255|url',
|
||||
'button_targetblank' => 'required|boolean',
|
||||
'picture_alt' => 'required|min:3|max:255',
|
||||
'picture_title' => 'required|min:3|max:255',
|
||||
'picture_thumbnail_alt' => 'required|min:3|max:255',
|
||||
'picture_thumbnail_title' => 'required|min:3|max:255'
|
||||
];
|
||||
return \array_merge(
|
||||
|
|
@ -68,17 +68,17 @@ class StoreSlideRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'title' => trans('title'),
|
||||
'content' => trans('contenu de la slide'),
|
||||
'button_display' => trans('afficher le bouton'),
|
||||
'button_text' => trans('texte du bouton'),
|
||||
'button_url' => trans('url du bouton'),
|
||||
'button_targetblank' => trans('ouvrir dans un nouvel onglet'),
|
||||
'picture' => trans('Illustration'),
|
||||
'picture_alt' => trans('attribut alt de l\'image'),
|
||||
'picture_title' => trans('titre de l\'image'),
|
||||
'picture_thumbnail' => trans('vignette'),
|
||||
'picture_thumbnail_alt' => trans('attribut alt de la vignette'),
|
||||
'title' => trans('title'),
|
||||
'content' => trans('contenu de la slide'),
|
||||
'button_display' => trans('afficher le bouton'),
|
||||
'button_text' => trans('texte du bouton'),
|
||||
'button_url' => trans('url du bouton'),
|
||||
'button_targetblank' => trans('ouvrir dans un nouvel onglet'),
|
||||
'picture' => trans('Illustration'),
|
||||
'picture_alt' => trans('attribut alt de l\'image'),
|
||||
'picture_title' => trans('titre de l\'image'),
|
||||
'picture_thumbnail' => trans('vignette'),
|
||||
'picture_thumbnail_alt' => trans('attribut alt de la vignette'),
|
||||
'picture_thumbnail_title' => trans('titre de la vignette')
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ class StoreTagRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ class StoreTagRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepareForValidation()
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'slug' => Str::slug($this->label),
|
||||
|
|
@ -34,7 +34,7 @@ class StoreTagRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'label' => 'required|min:2|max:30',
|
||||
|
|
@ -50,7 +50,7 @@ class StoreTagRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'label' => trans('libellé'),
|
||||
'slug' => trans('slug'),
|
||||
'slug' => trans('slug'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,14 @@ namespace App\Http\Requests\Bo;
|
|||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ChangeOrderRequest extends FormRequest
|
||||
class UpdateChangeOrderRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
|
@ -21,10 +21,10 @@ class ChangeOrderRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'direction' => $this->action === 'up' ? true : false
|
||||
'direction' => $this->direction === 'up' ? true : false
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -33,10 +33,9 @@ class ChangeOrderRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'action' => 'required|string|in:up,down',
|
||||
'direction' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ use App\Enums\Contact\ContactActivityEnum;
|
|||
use App\Enums\Contact\ContactTimeEnum;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class ContactRequest extends FormRequest
|
||||
{
|
||||
|
|
@ -15,7 +15,7 @@ class ContactRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -25,22 +25,22 @@ class ContactRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
ToolboxHelper::validateRecaptcha($this, \config('services.google.recaptcha.version'));
|
||||
|
||||
return [
|
||||
'firstname' => 'nullable|min:2|max:255',
|
||||
'lastname' => 'required|min:2|max:255',
|
||||
'email' => 'required|email:rfc,dns,spoof|max:255',
|
||||
'phone' => 'required|max:255|phone:' . implode(',', $this->isoCodes()),
|
||||
'activity' => ['required', new EnumIsValidRule(ContactActivityEnum::class)],
|
||||
'society' => 'nullable|string|max:255',
|
||||
'postcode' => 'nullable|postal_code:' . implode(',', $this->isoCodes()),
|
||||
'city' => 'nullable|string|max:255',
|
||||
'message' => 'required|string|min:20|max:255',
|
||||
'callTime' => ['required', new EnumIsValidRule(ContactTimeEnum::class)],
|
||||
'rgpd' => 'accepted'
|
||||
'lastname' => 'required|min:2|max:255',
|
||||
'email' => 'required|email:rfc,dns,spoof|max:255',
|
||||
'phone' => 'required|max:255|phone:' . implode(',', $this->isoCodes()),
|
||||
'activity' => ['required', new Enum(ContactActivityEnum::class)],
|
||||
'society' => 'nullable|string|max:255',
|
||||
'postcode' => 'nullable|postal_code:' . implode(',', $this->isoCodes()),
|
||||
'city' => 'nullable|string|max:255',
|
||||
'message' => 'required|string|min:20|max:255',
|
||||
'callTime' => ['required', new Enum(ContactTimeEnum::class)],
|
||||
'rgpd' => 'accepted'
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -49,17 +49,17 @@ class ContactRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages()
|
||||
public function messages(): array
|
||||
{
|
||||
return [
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'phone.phone' => trans('Le champ :attribute est invalide, il accepte les numéros des pays suivants :countries.', [
|
||||
'countries' => implode(', ', array_keys($this->isoCodes()))
|
||||
]),
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'postcode.postal_code' => trans('Le champ :attribute est invalide, il accepte les codes postaux des pays suivants :countries.', [
|
||||
'countries' => implode(', ', array_keys($this->isoCodes()))
|
||||
]),
|
||||
'phone.phone' => trans(
|
||||
'Le champ :attribute est invalide, il accepte les numéros des pays suivants :countries.',
|
||||
['countries' => implode(', ', array_keys($this->isoCodes()))]
|
||||
),
|
||||
'postcode.postal_code' => trans(
|
||||
'Le champ :attribute est invalide, il accepte les codes postaux des pays suivants :countries.',
|
||||
['countries' => implode(', ', array_keys($this->isoCodes()))]
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -72,16 +72,16 @@ class ContactRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'firstname' => trans('prénom'),
|
||||
'lastname' => trans('nom'),
|
||||
'email' => trans('email'),
|
||||
'phone' => trans('téléphone'),
|
||||
'activity' => trans('activité'),
|
||||
'society' => trans('société'),
|
||||
'postcode' => trans('code postal'),
|
||||
'city' => trans('ville'),
|
||||
'message' => trans('message'),
|
||||
'callTime' => trans('préférence de rappel'),
|
||||
'rgpd' => trans('condition d\'utilisation'),
|
||||
'lastname' => trans('nom'),
|
||||
'email' => trans('email'),
|
||||
'phone' => trans('téléphone'),
|
||||
'activity' => trans('activité'),
|
||||
'society' => trans('société'),
|
||||
'postcode' => trans('code postal'),
|
||||
'city' => trans('ville'),
|
||||
'message' => trans('message'),
|
||||
'callTime' => trans('préférence de rappel'),
|
||||
'rgpd' => trans('condition d\'utilisation'),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -93,20 +93,20 @@ class ContactRequest extends FormRequest
|
|||
private function isoCodes(): array
|
||||
{
|
||||
return [
|
||||
'france' => 'FR',
|
||||
'belgium' => 'BE',
|
||||
'luxembourg' => 'LU',
|
||||
'guadeloupe' => 'GP',
|
||||
'martinique' => 'MQ',
|
||||
'frenchGuiana' => 'GF',
|
||||
'reunion' => 'RE',
|
||||
'france' => 'FR',
|
||||
'belgium' => 'BE',
|
||||
'luxembourg' => 'LU',
|
||||
'guadeloupe' => 'GP',
|
||||
'martinique' => 'MQ',
|
||||
'frenchGuiana' => 'GF',
|
||||
'reunion' => 'RE',
|
||||
'saintPierreAndMiquelon' => 'PM',
|
||||
'mayotte' => 'YT',
|
||||
'saintBarthelemy' => 'BL',
|
||||
'saintMartinFrenchPart' => 'MF',
|
||||
'wallisAndFutuna' => 'WF',
|
||||
'frenchPolynesia' => 'PF',
|
||||
'newCaledonia' => 'NC',
|
||||
'mayotte' => 'YT',
|
||||
'saintBarthelemy' => 'BL',
|
||||
'saintMartinFrenchPart' => 'MF',
|
||||
'wallisAndFutuna' => 'WF',
|
||||
'frenchPolynesia' => 'PF',
|
||||
'newCaledonia' => 'NC',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class AjaxAddProductBasket extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -21,10 +21,10 @@ class AjaxAddProductBasket extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'packaging' => 'required|array|min:1',
|
||||
'packaging' => 'required|array|min:1',
|
||||
'packaging.*' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
|
|
@ -37,8 +37,8 @@ class AjaxAddProductBasket extends FormRequest
|
|||
}
|
||||
}
|
||||
],
|
||||
'caliber' => 'required|array|min:1',
|
||||
'caliber.*' => [
|
||||
'caliber' => 'required|array|min:1',
|
||||
'caliber.*' => [
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
$containsAttribute = (bool)collect($this->publishedProduct->caliber)
|
||||
|
|
@ -62,7 +62,7 @@ class AjaxAddProductBasket extends FormRequest
|
|||
{
|
||||
return [
|
||||
'packaging' => trans('conditionnement'),
|
||||
'caliber' => trans('calibre'),
|
||||
'caliber' => trans('calibre'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class AjaxFilterProductsRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -24,10 +24,10 @@ class AjaxFilterProductsRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepareForValidation()
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'vip' => $this->vip ? true : false,
|
||||
'vip' => $this->vip ? true : false,
|
||||
'subranges' => \is_array($this->subranges) ? $this->subranges : []
|
||||
]);
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ class AjaxFilterProductsRequest extends FormRequest
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [];
|
||||
if ($this->ajax()) {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Resources\Fo\Products;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ProductCommercialSheetResource extends JsonResource
|
||||
|
|
@ -12,24 +13,24 @@ class ProductCommercialSheetResource extends JsonResource
|
|||
|
||||
/** @var array */
|
||||
private static $skeleton = [
|
||||
'id' => '',
|
||||
'label' => '',
|
||||
'slug' => '',
|
||||
'species' => null,
|
||||
'is_frenchpoultry' => false,
|
||||
'nutriscore' => [
|
||||
'id' => '',
|
||||
'label' => '',
|
||||
'slug' => '',
|
||||
'species' => null,
|
||||
'is_frenchpoultry' => false,
|
||||
'nutriscore' => [
|
||||
'label' => 'none',
|
||||
'value' => 0
|
||||
],
|
||||
'advantage' => '',
|
||||
'packaging' => [],
|
||||
'caliber' => [],
|
||||
'ingredients' => '',
|
||||
'preparation' => '',
|
||||
'sticker_sm' => '',
|
||||
'advantage' => '',
|
||||
'packaging' => [],
|
||||
'caliber' => [],
|
||||
'ingredients' => '',
|
||||
'preparation' => '',
|
||||
'sticker_sm' => '',
|
||||
'nutritionnal_values' => [],
|
||||
'slider_pictures' => [],
|
||||
'subrange' => null,
|
||||
'slider_pictures' => [],
|
||||
'subrange' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -48,27 +49,26 @@ class ProductCommercialSheetResource extends JsonResource
|
|||
*
|
||||
* @param \Illuminate\Http\Request|null $request
|
||||
* @return array
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
public function toArray($request = null)
|
||||
public function toArray(?Request $request = null): array
|
||||
{
|
||||
return array_intersect_key(
|
||||
[
|
||||
'id' => $this->product->id,
|
||||
'label' => $this->product->label,
|
||||
'slug' => $this->product->slug,
|
||||
'species' => $this->product->species,
|
||||
'is_frenchpoultry' => $this->product->is_frenchpoultry,
|
||||
'nutriscore' => $this->product->nutriscore,
|
||||
'advantage' => $this->product->advantage,
|
||||
'packaging' => $this->product->packaging,
|
||||
'caliber' => $this->product->caliber,
|
||||
'ingredients' => $this->product->ingredients,
|
||||
'preparation' => $this->product->preparation,
|
||||
'id' => $this->product->id,
|
||||
'label' => $this->product->label,
|
||||
'slug' => $this->product->slug,
|
||||
'species' => $this->product->species,
|
||||
'is_frenchpoultry' => $this->product->is_frenchpoultry,
|
||||
'nutriscore' => $this->product->nutriscore,
|
||||
'advantage' => $this->product->advantage,
|
||||
'packaging' => $this->product->packaging,
|
||||
'caliber' => $this->product->caliber,
|
||||
'ingredients' => $this->product->ingredients,
|
||||
'preparation' => $this->product->preparation,
|
||||
'nutritionnal_values' => $this->product->nutritionnal_values,
|
||||
'sticker_sm' => $this->product->sticker_sm,
|
||||
'slider_pictures' => $this->product->slider_pictures,
|
||||
'subrange' => (new SubrangeResource($this->product->subrange))->toArray($request),
|
||||
'sticker_sm' => $this->product->sticker_sm,
|
||||
'slider_pictures' => $this->product->slider_pictures,
|
||||
'subrange' => (new SubrangeResource($this->product->subrange))->toArray($request),
|
||||
],
|
||||
$this->getSkeleton()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Resources\Fo\Products;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class ProductPaginatedCollectionResource extends ResourceCollection
|
||||
|
|
@ -13,27 +14,26 @@ class ProductPaginatedCollectionResource extends ResourceCollection
|
|||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*/
|
||||
public function toArray($request)
|
||||
public function toArray(Request $request): array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
{
|
||||
// phpcs:enable
|
||||
//phpcs:enable
|
||||
/** @var \Illuminate\Pagination\LengthAwarePaginator */
|
||||
$paginator = $this->resource;
|
||||
return [
|
||||
'first_page_url' => $paginator->url(0),
|
||||
'current_page' => $paginator->currentPage(),
|
||||
'next_page_url' => $paginator->nextPageUrl(),
|
||||
'links' => $paginator->linkCollection(),
|
||||
'prev_page_url' => $paginator->previousPageUrl(),
|
||||
'last_page_url' => $paginator->url($paginator->lastPage()),
|
||||
'last_page' => $paginator->lastPage(),
|
||||
'per_page' => $paginator->perPage(),
|
||||
'total' => $paginator->total(),
|
||||
'path' => $paginator->path(),
|
||||
'from' => $paginator->firstItem(),
|
||||
'to' => $paginator->lastItem(),
|
||||
'data' => $this->collection->map(function (Product $product) {
|
||||
'current_page' => $paginator->currentPage(),
|
||||
'next_page_url' => $paginator->nextPageUrl(),
|
||||
'links' => $paginator->linkCollection(),
|
||||
'prev_page_url' => $paginator->previousPageUrl(),
|
||||
'last_page_url' => $paginator->url($paginator->lastPage()),
|
||||
'last_page' => $paginator->lastPage(),
|
||||
'per_page' => $paginator->perPage(),
|
||||
'total' => $paginator->total(),
|
||||
'path' => $paginator->path(),
|
||||
'from' => $paginator->firstItem(),
|
||||
'to' => $paginator->lastItem(),
|
||||
'data' => $this->collection->map(function (Product $product) {
|
||||
return new ProductResource($product);
|
||||
})
|
||||
];
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Resources\Fo\Products;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ProductResource extends JsonResource
|
||||
|
|
@ -12,14 +13,14 @@ class ProductResource extends JsonResource
|
|||
|
||||
/** @var array */
|
||||
private static $skeleton = [
|
||||
'id' => '',
|
||||
'label' => '',
|
||||
'slug' => '',
|
||||
'species' => null,
|
||||
'sticker_sm' => '',
|
||||
'sticker_sm_alt' => '',
|
||||
'id' => '',
|
||||
'label' => '',
|
||||
'slug' => '',
|
||||
'species' => null,
|
||||
'sticker_sm' => '',
|
||||
'sticker_sm_alt' => '',
|
||||
'sticker_sm_title' => '',
|
||||
'subrange' => null,
|
||||
'subrange' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -38,20 +39,19 @@ class ProductResource extends JsonResource
|
|||
*
|
||||
* @param \Illuminate\Http\Request|null $request
|
||||
* @return array
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
public function toArray($request = null)
|
||||
public function toArray(?Request $request = null): array
|
||||
{
|
||||
return array_intersect_key(
|
||||
[
|
||||
'id' => $this->product->id,
|
||||
'label' => $this->product->label,
|
||||
'slug' => $this->product->slug,
|
||||
'species' => $this->product->species,
|
||||
'sticker_sm' => $this->product->sticker_sm,
|
||||
'sticker_sm_alt' => $this->product->sticker_sm_alt,
|
||||
'id' => $this->product->id,
|
||||
'label' => $this->product->label,
|
||||
'slug' => $this->product->slug,
|
||||
'species' => $this->product->species,
|
||||
'sticker_sm' => $this->product->sticker_sm,
|
||||
'sticker_sm_alt' => $this->product->sticker_sm_alt,
|
||||
'sticker_sm_title' => $this->product->sticker_sm_title,
|
||||
'subrange' => (new SubrangeResource($this->product->subrange))->toArray($request),
|
||||
'subrange' => (new SubrangeResource($this->product->subrange))->toArray($request),
|
||||
],
|
||||
$this->getSkeleton()
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Resources\Fo\Products;
|
||||
|
||||
use App\Models\Range;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class RangeResource extends JsonResource
|
||||
|
|
@ -12,9 +13,9 @@ class RangeResource extends JsonResource
|
|||
|
||||
/** @var array */
|
||||
private static $skeleton = [
|
||||
'id' => '',
|
||||
'id' => '',
|
||||
'label' => '',
|
||||
'slug' => '',
|
||||
'slug' => '',
|
||||
'color' => ''
|
||||
];
|
||||
|
||||
|
|
@ -36,13 +37,14 @@ class RangeResource extends JsonResource
|
|||
* @return array
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
public function toArray($request = null)
|
||||
public function toArray(?Request $request = null): array
|
||||
{
|
||||
//phpcs:enable
|
||||
return array_intersect_key(
|
||||
[
|
||||
'id' => $this->range->id,
|
||||
'id' => $this->range->id,
|
||||
'label' => $this->range->label,
|
||||
'slug' => $this->range->slug,
|
||||
'slug' => $this->range->slug,
|
||||
'color' => $this->range->color
|
||||
],
|
||||
$this->getSkeleton()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Resources\Fo\Products;
|
||||
|
||||
use App\Models\Subrange;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class SubrangeResource extends JsonResource
|
||||
|
|
@ -12,9 +13,9 @@ class SubrangeResource extends JsonResource
|
|||
|
||||
/** @var array */
|
||||
private static $skeleton = [
|
||||
'id' => '',
|
||||
'id' => '',
|
||||
'label' => '',
|
||||
'slug' => '',
|
||||
'slug' => '',
|
||||
'range' => null
|
||||
];
|
||||
|
||||
|
|
@ -34,9 +35,8 @@ class SubrangeResource extends JsonResource
|
|||
*
|
||||
* @param \Illuminate\Http\Request|null $request
|
||||
* @return array
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
public function toArray($request = null)
|
||||
public function toArray(?Request $request = null): array
|
||||
{
|
||||
return array_intersect_key(
|
||||
[
|
||||
|
|
@ -50,7 +50,7 @@ class SubrangeResource extends JsonResource
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns the resource skeletton
|
||||
* Returns the resource skeletton.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
|
|
|||
37
app/Lib/CompleteSitemapWith.php
Normal file
37
app/Lib/CompleteSitemapWith.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib;
|
||||
|
||||
use App\Enums\Advices\AdviceTypeEnum;
|
||||
use App\Models\Advice;
|
||||
use App\Models\Product;
|
||||
use LDC\SitemapGenerator\Lib\Sitemap;
|
||||
|
||||
class CompleteSitemapWith
|
||||
{
|
||||
/**
|
||||
* Use this method to append a list of links to the sitemap
|
||||
*
|
||||
* * Please call $sitemap->mergeUrls to append url for any specific route name.
|
||||
*
|
||||
* @param \LDC\SitemapGenerator\Lib\Sitemap $sitemap
|
||||
* @return void
|
||||
*/
|
||||
public static function append(Sitemap $sitemap): void
|
||||
{
|
||||
// * Ajouts des éléments qui sont affichés en random
|
||||
$sitemap->mergeUrls(Product::query()->where('status', true)->pluck('slug')->transform(function (string $slug) {
|
||||
return \route('fo.product.show', $slug);
|
||||
}));
|
||||
$sitemap->mergeUrls(Advice::query()
|
||||
->where('status', true)->where('type', AdviceTypeEnum::recipes)
|
||||
->pluck('slug')->transform(function (string $slug) {
|
||||
return \route('fo.recipes.show', $slug);
|
||||
}));
|
||||
$sitemap->mergeUrls(Advice::query()
|
||||
->where('status', true)->where('type', AdviceTypeEnum::tips)
|
||||
->pluck('slug')->transform(function (string $slug) {
|
||||
return \route('fo.tips.show', $slug);
|
||||
}));
|
||||
}
|
||||
}
|
||||
64
app/Lib/Helpers/CollectionHelper.php
Normal file
64
app/Lib/Helpers/CollectionHelper.php
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class CollectionHelper
|
||||
{
|
||||
/**
|
||||
* Paginate a collection
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $results
|
||||
* @param integer $pageSize
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public static function paginate(Collection $results, int $pageSize): LengthAwarePaginator
|
||||
{
|
||||
$page = Paginator::resolveCurrentPage('page');
|
||||
|
||||
return self::paginateManually($results, $pageSize, $page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate a collection
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $results
|
||||
* @param integer $pageSize
|
||||
* @param integer $page
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public static function paginateManually(Collection $results, int $pageSize, int $page = 1): LengthAwarePaginator
|
||||
{
|
||||
$total = $results->count();
|
||||
|
||||
return self::paginator($results->forPage($page, $pageSize), $total, $pageSize, $page, [
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'pageName' => 'page',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new length-aware paginator instance.
|
||||
*
|
||||
* @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, int $total, int $perPage, int $currentPage, array $options)
|
||||
{
|
||||
return Container::getInstance()->makeWith(LengthAwarePaginator::class, [
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'perPage' => $perPage,
|
||||
'currentPage' => $currentPage,
|
||||
'options' => $options
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -80,13 +80,13 @@ class ExceptionsHelper
|
|||
foreach ($params as &$param) {
|
||||
$type = \strtolower(\gettype($param));
|
||||
if (\is_string($param)) {
|
||||
$type = \explode(' ', \trim($param))[0] ?? null;
|
||||
$type = \explode(' ', \trim(strtolower($param)))[0] ?? null;
|
||||
}
|
||||
switch ($type) {
|
||||
case 'Lambda':
|
||||
case 'Object':
|
||||
switch (true) {
|
||||
case $type === 'lambda':
|
||||
case $type === 'object':
|
||||
continue 2;
|
||||
case 'array':
|
||||
case $type === 'array' and \is_array($param):
|
||||
$param = sprintf('Array(%d)', \count($param));
|
||||
continue 2;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -60,10 +60,10 @@ class FileStorageHelper
|
|||
public static function removeOldFile(Model $model, string $attribute, bool $onlyIfUpdated = true): void
|
||||
{
|
||||
// * Ignore If removal has to be done only if the field has changed and it actually hasnt.
|
||||
if ($onlyIfUpdated and $model->{$attribute} === $model->getOriginal($attribute)) {
|
||||
if ($onlyIfUpdated and $model->{$attribute} === ToolboxHelper::getOriginal($model, $attribute)) {
|
||||
return;
|
||||
}
|
||||
$originalPath = \ltrim(\urldecode($model->getOriginal($attribute)), '/');
|
||||
$originalPath = \ltrim(\urldecode(ToolboxHelper::getOriginal($model, $attribute)), '/');
|
||||
if (\strpos($originalPath, 'storage') !== 0) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -82,29 +82,48 @@ class FileStorageHelper
|
|||
* @param \Illuminate\Http\UploadedFile|\SplFileInfo|string $file The file, will just return itself is string.
|
||||
* @param boolean $slugify Force filename slugification.
|
||||
* @param string|null $filename This string may be used to store the file.
|
||||
* @param boolean $private To store the file in a private space.
|
||||
* @return string
|
||||
* @throws \RuntimeException If file copy fails.
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
public static function storeFile(Model $model, $file, bool $slugify = false, string $filename = null): string
|
||||
{
|
||||
public static function storeFile(
|
||||
Model $model,
|
||||
$file,
|
||||
bool $slugify = false,
|
||||
string $filename = null,
|
||||
bool $private = false
|
||||
): string {
|
||||
// phpcs:enable
|
||||
$tableName = $model->getTable();
|
||||
if (\is_object($file) and $file instanceof \Illuminate\Http\UploadedFile) {
|
||||
/** @var \Illuminate\Http\UploadedFile $file */
|
||||
$filename = $filename ?: $file->getClientOriginalName();
|
||||
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
|
||||
$newPath = self::prepareMoveFile($tableName, $filename);
|
||||
$newPath = self::prepareMoveFile($tableName, $filename, $private);
|
||||
$newPath = str_replace(storage_path('app'), '', $newPath);
|
||||
$file->storePubliclyAs(
|
||||
|
||||
if (!$private) {
|
||||
// * Store public file.
|
||||
$file->storePubliclyAs(
|
||||
pathinfo($newPath, \PATHINFO_DIRNAME),
|
||||
pathinfo($newPath, \PATHINFO_BASENAME)
|
||||
);
|
||||
return 'storage' . str_replace('/public', '', $newPath);
|
||||
}
|
||||
|
||||
$file->storeAs(
|
||||
pathinfo($newPath, \PATHINFO_DIRNAME),
|
||||
pathinfo($newPath, \PATHINFO_BASENAME)
|
||||
);
|
||||
return 'storage' . str_replace('/public', '', $newPath);
|
||||
}
|
||||
|
||||
return str_replace('/private/', '', $newPath);
|
||||
} //end if
|
||||
if (\is_object($file) and $file instanceof \SplFileInfo) {
|
||||
/** @var \SplFileInfo $file */
|
||||
$filename = $filename ?: $file->getBaseName();
|
||||
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
|
||||
$newPath = self::prepareMoveFile($tableName, $filename);
|
||||
$newPath = self::prepareMoveFile($tableName, $filename, $private);
|
||||
if (!File::copy($file->getRealPath(), $newPath)) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
'Failed to copy file %s to %s',
|
||||
|
|
@ -112,7 +131,9 @@ class FileStorageHelper
|
|||
$newPath
|
||||
));
|
||||
}
|
||||
return \ltrim(str_replace(\storage_path('app/public'), '/storage', $newPath), '/');
|
||||
return $private ?
|
||||
\ltrim(str_replace(\storage_path('app/private'), '/storage/app/private', $newPath), '/') :
|
||||
\ltrim(str_replace(\storage_path('app/public'), '/storage', $newPath), '/');
|
||||
}
|
||||
return strval($file);
|
||||
}
|
||||
|
|
@ -122,7 +143,6 @@ class FileStorageHelper
|
|||
* If oldHtmlString is passed, a diff is done with new and old files
|
||||
* to keep only files that are present in the new html string.
|
||||
*
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model The model that will hold the picture.
|
||||
* @param string $htmlString The html string to parse and modify files.
|
||||
* @param string|null $oldHtmlString The old html string with alreadyParsed
|
||||
|
|
@ -208,6 +228,7 @@ class FileStorageHelper
|
|||
|
||||
/**
|
||||
* Find all occurence of files in html
|
||||
*
|
||||
* @param string $html
|
||||
* @return array
|
||||
*/
|
||||
|
|
@ -268,22 +289,28 @@ class FileStorageHelper
|
|||
* Prepare storage path and return
|
||||
* the file full path
|
||||
*
|
||||
* @param string $tableName Model table name.
|
||||
* @param string $filename The basename for the file.
|
||||
* @param string $tableName Model table name.
|
||||
* @param string $filename The basename for the file.
|
||||
* @param boolean $private May the file be stored in a private dir.
|
||||
* @return string
|
||||
*/
|
||||
private static function prepareMoveFile(string $tableName, string $filename): string
|
||||
private static function prepareMoveFile(string $tableName, string $filename, bool $private = false): string
|
||||
{
|
||||
// * Security filter
|
||||
$filename = \htmlspecialchars($filename);
|
||||
// * Security filter + beautifier
|
||||
$filename = self::sanitizeFileName($filename);
|
||||
// * Security filter
|
||||
$filename = \filter_var($filename, \FILTER_SANITIZE_STRING);
|
||||
// * Slugify filename
|
||||
$ext = \pathinfo($filename, \PATHINFO_EXTENSION);
|
||||
$filename = Str::slug(\pathinfo($filename, \PATHINFO_FILENAME)) .
|
||||
(\strlen($ext) ? ".{$ext}" : '');
|
||||
|
||||
$folderPath = self::getStoragePath($tableName, $filename);
|
||||
$folderPath = self::getStoragePath(
|
||||
$private ? 'app/private/modelfiles' : 'app/public/modelfiles',
|
||||
$tableName,
|
||||
$filename,
|
||||
$private
|
||||
);
|
||||
$filename = self::getFileUniqueName($folderPath, $filename);
|
||||
return "{$folderPath}/{$filename}";
|
||||
}
|
||||
|
|
@ -293,15 +320,17 @@ class FileStorageHelper
|
|||
* storage/modelfiles/posts/10/04/19/5f
|
||||
* year/month/day/md5 first 2 letters
|
||||
*
|
||||
* @param string $storage_dir
|
||||
* @param string $table
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
private static function getStoragePath(string $table, string $filename): string
|
||||
private static function getStoragePath(string $storage_dir, string $table, string $filename): string
|
||||
{
|
||||
$filenameHash = \md5($filename);
|
||||
$pathFolder = \storage_path(sprintf(
|
||||
'app/public/modelfiles/%s/%s/%s/%s/%s',
|
||||
'%s/%s/%s/%s/%s/%s',
|
||||
$storage_dir,
|
||||
$table,
|
||||
gmdate('y'),
|
||||
gmdate('m'),
|
||||
|
|
@ -328,7 +357,7 @@ class FileStorageHelper
|
|||
$maxAttempts = 20;
|
||||
while (File::exists("{$folderPath}/{$filename}")) {
|
||||
if ($attempts++ >= $maxAttempts) {
|
||||
throw new \RuntimeException("Failed to has a unique filename for {$folderPath}/{$filename}");
|
||||
throw new \RuntimeException("Failed to have a unique filename for {$folderPath}/{$filename}");
|
||||
}
|
||||
$filename = pathinfo($filename, \PATHINFO_FILENAME) .
|
||||
\uniqid('-') . '.' .
|
||||
|
|
@ -422,39 +451,4 @@ class FileStorageHelper
|
|||
$filename = trim($filename, '.-');
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store picture array
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param array $files
|
||||
* @return array Containing stored Files using storage strategy.
|
||||
*/
|
||||
public static function storePictureArray(Model $model, array $files): array
|
||||
{
|
||||
return \collect($files)->map(function ($file) use ($model) {
|
||||
if (!\is_string($file) and !(\is_object($file) and $file instanceof \SplFileInfo)) {
|
||||
throw new \RuntimeException('picture array does not support anything else than string or SplfFileInfo');
|
||||
}
|
||||
return FileStorageHelper::storeFile($model, $file, true);
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove picture array
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param array $files
|
||||
* @return void
|
||||
*/
|
||||
public static function removePictureArray(Model $model, array $files): void
|
||||
{
|
||||
\collect($files)->map(function ($file) use ($model) {
|
||||
if (!\is_string($file)) {
|
||||
throw new \RuntimeException('picture array does not support anything else than string');
|
||||
}
|
||||
// * Use temp prop te remove file.
|
||||
$model->tempPicture = $file;
|
||||
FileStorageHelper::removeFile($model, 'tempPicture');
|
||||
$model->tempPicture = null;
|
||||
})->all();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,319 +2,51 @@
|
|||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use App\Enums\Pagination\ItemsPerPaginationEnum;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
class ToolboxHelper
|
||||
{
|
||||
/**
|
||||
* Cut string words
|
||||
* @param array<int|string, mixed> $array1
|
||||
* @param array<int|string, mixed> $array2
|
||||
*
|
||||
* @param string $string
|
||||
* @param integer $max
|
||||
* @param string $hyphen
|
||||
* @return string
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public static function cutWords(string $string, int $max = 20, string $hyphen = '[.]')
|
||||
public static function arrayMergeRecursiveDistinct(array &$array1, array &$array2): array
|
||||
{
|
||||
$originalString = $string;
|
||||
$tok = strtok($string, ' ');
|
||||
$string = '';
|
||||
while ($tok !== false && mb_strlen($string) < $max) {
|
||||
if (
|
||||
mb_strlen($string) + mb_strlen($tok) <= $max
|
||||
) {
|
||||
$string .= $tok . ' ';
|
||||
$merged = $array1;
|
||||
foreach ($array2 as $key => &$value) {
|
||||
if (is_array($value) && isset($merged[$key]) && is_array($merged[$key])) {
|
||||
$merged[$key] = self::arrayMergeRecursiveDistinct($merged[$key], $value);
|
||||
} else {
|
||||
break;
|
||||
$merged[$key] = $value;
|
||||
}
|
||||
$tok = strtok(' ');
|
||||
}
|
||||
return trim($string) . (strlen(trim($string)) !== strlen(trim($originalString)) ? $hyphen : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip scheme (https) on oembed urls
|
||||
* Only embed allowed are for MP4 self hosted videos right now
|
||||
*
|
||||
* https is force by ckeditor MediaElements which natively supports
|
||||
* only cloud hosted medias (youtube, spotify etc..)
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public static function stripCkEditorSchemesOnMediaInputs(string $input): string
|
||||
{
|
||||
$input = \preg_replace('/(?<=<oembed url=")(https:\/\/)(?=.*?">)/m', '', $input);
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That no Back Office url is present on txt
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalBoUrls(string $field, string $text): string
|
||||
{
|
||||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'/(?P<url>(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))/',
|
||||
function ($matches) use ($routes, $field) {
|
||||
$match = collect($matches)->first() ?? '';
|
||||
$url = $match;
|
||||
try {
|
||||
$request = Request::create($url);
|
||||
// If a route is match then it do not throws exception.
|
||||
if (
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||
trim($routes->match($request)->getPrefix() ?? '', '/') === 'bo'
|
||||
) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => ':attribute : Il est interdit de coller une url du back office dans ce champ'
|
||||
]);
|
||||
}
|
||||
return $match;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That only external url is present on txt
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalUrls(string $field, string $text): string
|
||||
{
|
||||
self::assertNoInternalBoUrls($field, $text);
|
||||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'/(?P<url>(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))/',
|
||||
function ($matches) use ($routes, $field) {
|
||||
$match = collect($matches)->first() ?? '';
|
||||
$url = $match;
|
||||
try {
|
||||
$request = Request::create($url);
|
||||
// If a route is match then it do not throws exception.
|
||||
if (
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||
$routes->match($request)
|
||||
) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => sprintf(
|
||||
':attribute : Il est interdit de coller une url de %s dans ce champ',
|
||||
config('app.name')
|
||||
)
|
||||
]);
|
||||
}
|
||||
return $match;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate url using laravel route passing our group query if present
|
||||
* This is used to keep ou group tracking
|
||||
* Curd-policies is only used for root users as it cannot keep track of our group
|
||||
* and validate things
|
||||
*
|
||||
* @param array|string $name
|
||||
* @param mixed $parameters
|
||||
* @param boolean $absolute
|
||||
* @return string
|
||||
* @throws \ErrorException If an object given as parameter is not a Model.
|
||||
*/
|
||||
public static function routeWithGroup($name, $parameters = [], bool $absolute = true): string
|
||||
{
|
||||
// * Handle if parameter if is an object.
|
||||
if (\is_object($parameters)) {
|
||||
$parents = \class_parents($parameters);
|
||||
if ($parents === false or !\in_array(Model::class, $parents)) {
|
||||
throw new \ErrorException(\sprintf(
|
||||
'%s only support object of type %s',
|
||||
__FUNCTION__,
|
||||
Model::class
|
||||
));
|
||||
}
|
||||
/** @var \Illuminate\Database\Eloquent\Model $model */
|
||||
$model = $parameters;
|
||||
$parameters = [Str::singular($model->getTable()) => $model];
|
||||
}
|
||||
// * Handle if parameter isnt and array like slug or else.
|
||||
if (!is_array($parameters)) {
|
||||
// * Best effort, result is not garantee.
|
||||
$parameters = [$parameters];
|
||||
}
|
||||
// * Pass our group.
|
||||
if ($group = Session::get('activeGroup', request()->group)) {
|
||||
$parameters = array_merge($parameters, ['group' => $group]);
|
||||
}
|
||||
// * Call laravel route helper.
|
||||
return route($name, $parameters, $absolute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutltibyte string replace
|
||||
* @param mixed $search
|
||||
* @param mixed $replace
|
||||
* @param mixed $subject
|
||||
* @param integer $count
|
||||
* @return mixed
|
||||
*/
|
||||
public static function mbReplace($search, $replace, $subject, int &$count = 0)
|
||||
{
|
||||
if (!is_array($search) && is_array($replace)) {
|
||||
return false;
|
||||
}
|
||||
if (is_array($subject)) {
|
||||
// Call mb_replace for each single string in $subject .
|
||||
foreach ($subject as &$string) {
|
||||
$string = &self::mbReplace($search, $replace, $string, $count);
|
||||
}
|
||||
} elseif (is_array($search)) {
|
||||
if (!is_array($replace)) {
|
||||
foreach ($search as &$string) {
|
||||
$subject = self::mbReplace($string, $replace, $subject, $count);
|
||||
}
|
||||
} else {
|
||||
$n = max(count($search), count($replace));
|
||||
while ($n--) {
|
||||
$subject = self::mbReplace(current($search), current($replace), $subject, $count);
|
||||
next($search);
|
||||
next($replace);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$parts = mb_split(preg_quote($search), $subject);
|
||||
$count = count($parts) - 1;
|
||||
$subject = implode($replace, $parts);
|
||||
} //end if
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the field is unique
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $field
|
||||
* @param mixed $value
|
||||
* @param integer|null $id
|
||||
* @param callable|null $query
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If the field is not unique.
|
||||
*/
|
||||
public static function assertFieldIsUnique(
|
||||
string $table,
|
||||
string $field,
|
||||
$value,
|
||||
?int $id = null,
|
||||
?callable $query = null
|
||||
) {
|
||||
if (!$query) {
|
||||
Validator::make([$field => $value], [
|
||||
$field => Rule::unique($table, $field)->ignore($id),
|
||||
], [
|
||||
$field . '.unique' => trans('La valeur :value pour le champ :attribute est déjà utilisé', [
|
||||
'attribute' => $field,
|
||||
'value' => $value
|
||||
])
|
||||
])->validate();
|
||||
return;
|
||||
}
|
||||
Validator::make([$field => $value], [
|
||||
$field => Rule::unique($table)->where($query)->ignore($id),
|
||||
], [
|
||||
$field . '.unique' => trans('La valeur pour le champ :attribute est déjà utilisé', [
|
||||
'attribute' => $field
|
||||
])
|
||||
])->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that two arrays have the same content (1 level only)
|
||||
*
|
||||
* @param array $array1
|
||||
* @param array $array2
|
||||
* @return boolean
|
||||
*/
|
||||
public static function arrayHaveSameContent(array $array1, array $array2): bool
|
||||
{
|
||||
return (array_diff($array1, $array2) == [] && array_diff($array2, $array1) == []);
|
||||
}
|
||||
|
||||
/**
|
||||
* * Register CSP report URI
|
||||
*
|
||||
* Put this function inside RouteServiceProvider,
|
||||
* and call it in RouteServiceProvider::boot
|
||||
*
|
||||
* ! Use this in conjonction with kwaadpepper/exception-handler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function cspReportRoute()
|
||||
{
|
||||
// * CSP REPORT URI, Please add /csp-report to VerifyCsrfToken $except middleware
|
||||
\Illuminate\Support\Facades\Route::post('/csp-report', function () {
|
||||
$isCspRequest = request()->header('Content-Type') === 'application/csp-report';
|
||||
if (!$isCspRequest or !request()->json('csp-report') or !is_array(request()->json('csp-report'))) {
|
||||
abort(401);
|
||||
}
|
||||
// * Flatten if needed
|
||||
$cspReport = collect(request()->json('csp-report'))
|
||||
->flatMap(function ($v, $k) {
|
||||
return [$k => is_array($v) ? collect($v)->flatten()->implode(', ') : $v];
|
||||
})->all();
|
||||
// * Filter array keys
|
||||
$cspReport = collect(array_intersect_key($cspReport, [
|
||||
'blocked-uri' => '', 'document-uri' => '', 'original-policy' => '',
|
||||
'referrer' => '', 'violated-directive' => ''
|
||||
]));
|
||||
report(new \Illuminate\Http\Client\HttpClientException(sprintf(
|
||||
"CSP REPORT for %s : \n %s",
|
||||
$cspReport->get('document-uri'),
|
||||
$cspReport->implode("\n")
|
||||
)));
|
||||
})->middleware('throttle:5,2')
|
||||
->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class)
|
||||
->name('cspReportUri');
|
||||
return $merged;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate recaptcha
|
||||
*
|
||||
* @param Request $request
|
||||
* @param boolean $isV3
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param boolean $isV3
|
||||
* @return void
|
||||
*/
|
||||
public static function validateRecaptcha(Request $request, bool $isV3 = true)
|
||||
|
|
@ -363,4 +95,445 @@ class ToolboxHelper
|
|||
]
|
||||
], [], ['g-recaptcha-response' => 'reCaptcha']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip scheme (https) on oembed urls
|
||||
* Only embed allowed are for MP4 self hosted videos right now
|
||||
*
|
||||
* https is force by ckeditor MediaElements which natively supports
|
||||
* only cloud hosted medias (youtube, spotify etc..)
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public static function stripCkEditorSchemesOnMediaInputs(string $input): string
|
||||
{
|
||||
$input = \preg_replace('/(?<=<oembed url=")(https:\/\/)(?=.*?">)/m', '', $input);
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That no Back Office url is present on txt
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalBoUrls(string $field, string $text): string
|
||||
{
|
||||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'/(?P<url>(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))/',
|
||||
function ($matches) use ($routes, $field) {
|
||||
$match = collect($matches)->first() ?? '';
|
||||
$url = $match;
|
||||
try {
|
||||
$request = Request::create($url);
|
||||
// If a route is match then it do not throws exception.
|
||||
if (
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||
trim($routes->match($request)->getPrefix() ?? '', '/') === 'bo'
|
||||
) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => trans(
|
||||
'crud.libs.toolbox.assertNoInternalBoUrls',
|
||||
['attribute' => $field]
|
||||
)
|
||||
]);
|
||||
}
|
||||
return $match;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That only external url is present on txt
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalUrls(string $field, string $text): string
|
||||
{
|
||||
self::assertNoInternalBoUrls($field, $text);
|
||||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'/(?P<url>(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))/',
|
||||
function ($matches) use ($routes, $field) {
|
||||
$match = collect($matches)->first() ?? '';
|
||||
$url = $match;
|
||||
try {
|
||||
$request = Request::create($url);
|
||||
// If a route is match then it do not throws exception.
|
||||
if (
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||
$routes->match($request)
|
||||
) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => trans(
|
||||
'crud.libs.toolbox.assertNoInternalUrls',
|
||||
['attribute' => $field, 'appname' => config('app.name')]
|
||||
)
|
||||
]);
|
||||
}
|
||||
return $match;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutltibyte string replace
|
||||
*
|
||||
* @param array|string $search
|
||||
* @param array|string $replace
|
||||
* @param array|string $subject
|
||||
* @param integer $count
|
||||
* @return array|string
|
||||
*/
|
||||
public static function mbReplace(
|
||||
array|string $search,
|
||||
array|string $replace,
|
||||
array|string $subject,
|
||||
int &$count = 0
|
||||
): array|string {
|
||||
if (!is_array($search) && is_array($replace)) {
|
||||
return false;
|
||||
}
|
||||
if (is_array($subject)) {
|
||||
// Call mb_replace for each single string in $subject .
|
||||
foreach ($subject as &$string) {
|
||||
$string = &self::mbReplace($search, $replace, $string, $count);
|
||||
}
|
||||
} elseif (is_array($search)) {
|
||||
if (!is_array($replace)) {
|
||||
foreach ($search as &$string) {
|
||||
$subject = self::mbReplace($string, $replace, $subject, $count);
|
||||
}
|
||||
} else {
|
||||
$n = max(count($search), count($replace));
|
||||
while ($n--) {
|
||||
$subject = self::mbReplace(current($search), current($replace), $subject, $count);
|
||||
next($search);
|
||||
next($replace);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$parts = mb_split(preg_quote($search), $subject);
|
||||
$count = count($parts) - 1;
|
||||
$subject = implode($replace, $parts);
|
||||
} //end if
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the field is unique
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
public static function assertFieldIsUnique(
|
||||
string $table,
|
||||
string $field,
|
||||
string|int|float|bool|null|array $value,
|
||||
?int $id = null,
|
||||
?callable $query = null
|
||||
) {
|
||||
if (!$query) {
|
||||
Validator::make([$field => $value], [
|
||||
self::mbReplace('.', '\.', $field) => Rule::unique($table, $field)->ignore($id),
|
||||
], [
|
||||
self::mbReplace('.', '\.', "{$field}.unique")
|
||||
=> trans('crud.libs.toolbox.assertFieldIsUnique', ['attribute' => $field, 'value' => $value])
|
||||
])->validate();
|
||||
return;
|
||||
}
|
||||
Validator::make([$field => $value], [
|
||||
$field => Rule::unique($table)->where($query)->ignore($id),
|
||||
], [
|
||||
$field . '.unique' => trans(
|
||||
'crud.libs.toolbox.assertFieldIsUnique',
|
||||
['attribute' => $field, 'value' => $value]
|
||||
)
|
||||
])->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get original polyfill with autotranslate behavior
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $attribute
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getOriginal(Model $model, string $attribute): mixed
|
||||
{
|
||||
if (\in_array('Spatie\Translatable\HasTranslations', \class_uses_recursive($model))) {
|
||||
return $model->getTranslation(
|
||||
$attribute,
|
||||
$model->getLocale(),
|
||||
$model->useFallbackLocale()
|
||||
);
|
||||
}
|
||||
return $model->getOriginal($attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public static function queryColumnWithLocales(
|
||||
string $defaultLocale,
|
||||
Builder $q,
|
||||
string $column,
|
||||
string $value
|
||||
): Builder {
|
||||
$currentLocale = app()->currentLocale();
|
||||
$locales = collect(config('app.locales'))
|
||||
->mapWithKeys(fn (string $locale) => [$locale => $locale]);
|
||||
if (!$locales->has($defaultLocale)) {
|
||||
// * Remove default locale.
|
||||
$locales->pull($defaultLocale);
|
||||
}
|
||||
if (!$locales->has($currentLocale)) {
|
||||
// * Remove current locale.
|
||||
$locales->pull($currentLocale);
|
||||
}
|
||||
|
||||
return $q->where(function (Builder $q) use ($defaultLocale, $currentLocale, $locales, $column, $value) {
|
||||
// * Query default locale
|
||||
$q->whereRaw("JSON_EXTRACT({$column}, '$.{$defaultLocale}') = '{$value}'");
|
||||
if ($defaultLocale !== $currentLocale) {
|
||||
// * Query current locale
|
||||
$q->whereRaw("JSON_EXTRACT({$column}, '$.{$currentLocale}') = '{$value}'");
|
||||
}
|
||||
// * Query any other locale
|
||||
$locales->each(fn ($locale) => $q->orWhereRaw(
|
||||
"JSON_EXTRACT({$column}, '$.{$locale}') = '{$value}'"
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array from a dot separated string
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $value
|
||||
* @param string $separator
|
||||
* @return array
|
||||
*/
|
||||
public static function dotStringToNestedArray(string $path, mixed $value, string $separator = '.'): array
|
||||
{
|
||||
$arr = $value;
|
||||
$keys = array_reverse(explode($separator, $path));
|
||||
|
||||
foreach ($keys as $key) {
|
||||
$arr = [$key => $arr];
|
||||
}
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an object to array
|
||||
*
|
||||
* @param array|object $input
|
||||
* @return array
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function objectToArray($input): array
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (is_object($input) or is_array($input)) {
|
||||
$ret = (array)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::objectToArray($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an array to object
|
||||
*
|
||||
* @param array|object $input
|
||||
* @return object
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function arrayToObject($input): object
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (is_object($input) or is_array($input)) {
|
||||
$ret = (object)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::arrayToObject($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate picture
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|null $value
|
||||
* @param callback $fail
|
||||
* @param object $sizes
|
||||
* @return void
|
||||
*/
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes)
|
||||
{
|
||||
if (!($useStorage = Storage::exists($value)) and !File::exists($value)) {
|
||||
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
||||
'attribute' => $attribute
|
||||
]));
|
||||
return;
|
||||
}
|
||||
/** @var string */
|
||||
$fileFullPath = self::getUploadedFileFullPath($value, $useStorage);
|
||||
if (
|
||||
!\in_array(self::getUploadedFileMimeType($value, $useStorage), [
|
||||
'image/jpeg', 'image/jpg', 'image/png', 'image/gif'
|
||||
])
|
||||
) {
|
||||
$fail(trans(':attribute doit être une image de type \'image/jpeg,image/jpg,image/png,image/gif\'', [
|
||||
'attribute' => $attribute
|
||||
]));
|
||||
}
|
||||
if (!($dimensions = \getimagesize($fileFullPath)) or !isset($dimensions[0]) or !isset($dimensions[1])) {
|
||||
$fail(trans(':attribute impossible de valider les dimensions', [
|
||||
'attribute' => $attribute
|
||||
]));
|
||||
} else {
|
||||
$width = intval($dimensions[0]);
|
||||
$height = intval($dimensions[1]);
|
||||
|
||||
$xMessage = trans(
|
||||
":attribute la largeur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px"
|
||||
);
|
||||
if ($sizes->minWith === $sizes->maxWith) {
|
||||
$xMessage = trans(":attribute la largeur doit être de {$sizes->minWith}px");
|
||||
}
|
||||
$yMessage = trans(
|
||||
":attribute la hauteur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px"
|
||||
);
|
||||
if ($sizes->minHeight === $sizes->maxHeight) {
|
||||
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minWith}px");
|
||||
}
|
||||
|
||||
if (($width < $sizes->minWith) or ($width > $sizes->maxWith)) {
|
||||
$fail($xMessage);
|
||||
}
|
||||
if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) {
|
||||
$fail($yMessage);
|
||||
}
|
||||
} //end if
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file full path
|
||||
*
|
||||
* @param string $value
|
||||
* @param boolean $useStorage
|
||||
* @return string
|
||||
*/
|
||||
private static function getUploadedFileFullPath(string $value, bool $useStorage): string
|
||||
{
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
$disk = Storage::disk();
|
||||
return !$useStorage ? (realpath($value) ?: $value) : $disk->path($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file mimetype
|
||||
*
|
||||
* @param string $value
|
||||
* @param boolean $useStorage
|
||||
* @return string|false
|
||||
*/
|
||||
private static function getUploadedFileMimeType(string $value, bool $useStorage)
|
||||
{
|
||||
return !$useStorage ? File::mimeType($value) : Storage::mimeType($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch class list from a specific namespace
|
||||
*
|
||||
* @param string $namespace
|
||||
* @return array<string> An array of classe namespaces
|
||||
*/
|
||||
public static function getClassesUsingNamespace(string $namespace): array
|
||||
{
|
||||
return collect(File::files(\app_path(Str::of($namespace)->replaceFirst('\App', ''))))
|
||||
->filter(fn (SplFileInfo $splFileInfo) => $splFileInfo->getExtension() === 'php')
|
||||
->map(fn (SplFileInfo $splFileInfo) => Str::of($splFileInfo->getBasename())
|
||||
->replace('.' . $splFileInfo->getExtension(), '')->prepend("{$namespace}\\"))->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all classes from a specific namespace that implement a specific interface
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $interface
|
||||
* @return array<string> An array of classe namespaces
|
||||
*/
|
||||
public static function getClassesUsingInterface(string $namespace, string $interface): array
|
||||
{
|
||||
return Arr::where(
|
||||
static::getClassesUsingNamespace($namespace),
|
||||
fn (string $class_namespace) => \collect(class_implements($class_namespace, true))->filter()
|
||||
->contains(fn (string $class_interface) => $class_interface === $interface)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get validated pagination from request.
|
||||
*
|
||||
* @param integer $default
|
||||
* @return integer
|
||||
*/
|
||||
public static function getValidatedPaginate(int $default): int
|
||||
{
|
||||
try {
|
||||
return \intval(Validator::make(
|
||||
['pagination' => \request()->get('pagination')],
|
||||
['pagination' => new Enum(ItemsPerPaginationEnum::class)]
|
||||
)->validated()['pagination']);
|
||||
} catch (ValidationException $e) {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,18 +6,55 @@ use App\Enums\Advices\AdviceTypeEnum;
|
|||
use App\Enums\Advices\AdviceDifficultyEnum;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Kwaadpepper\Enum\Traits\CastsEnums;
|
||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
||||
|
||||
class Advice extends Authenticatable
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $title Title.
|
||||
* @property string $slug Slug of the title.
|
||||
* @property string $seo_title SEO Title.
|
||||
* @property string $seo_description SEO description.
|
||||
* @property \App\Enums\Advices\AdviceTypeEnum $type Type of the advice.
|
||||
* @property string $picture Path of a picture.
|
||||
* @property string $picture_alt Picture's attribute alt.
|
||||
* @property string $picture_title Picture's attribute title.
|
||||
* @property string $sticker Path of a sticker.
|
||||
* @property string $sticker_alt Sticker's attribute alt.
|
||||
* @property string $sticker_title Sticker's attribute title.
|
||||
* @property string $sticker_sm Path of a small sticker.
|
||||
* @property string $sticker_sm_alt small sticker's attribute alt.
|
||||
* @property string $sticker_sm_title Small sticker's attribute title.
|
||||
* @property string $preparation Preparation tips.
|
||||
* @property string $advice Advice.
|
||||
* @property \Illuminate\Support\Carbon $ingredients Ingredients.
|
||||
* @property \Illuminate\Support\Carbon $guests_nb Number of guests.
|
||||
* @property \Illuminate\Support\Carbon $youtube_title Youtube title.
|
||||
* @property \Illuminate\Support\Carbon $youtube_video_id Youtube video id.
|
||||
* @property \Illuminate\Support\Carbon $cooking_time Time of cooking.
|
||||
* @property \Illuminate\Support\Carbon $preparation_time Time of preparation.
|
||||
* @property \App\Enums\Advices\AdviceDifficultyEnum $difficulty Difficulty.
|
||||
* @property boolean $status Status.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> $advices
|
||||
* Advices Belongs-To-Many relationship.
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products
|
||||
* Products Belongs-To-Many relationship.
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Tag> $tags
|
||||
* Tags Morph-To-Many relationship.
|
||||
*/
|
||||
class Advice extends Authenticatable implements SeoInterface
|
||||
{
|
||||
use CastsEnums;
|
||||
use HasFactory;
|
||||
use SeoTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -51,16 +88,6 @@ class Advice extends Authenticatable
|
|||
'status'
|
||||
];
|
||||
|
||||
/**
|
||||
* Map attribute names to enum classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $enumCasts = [
|
||||
'type' => AdviceTypeEnum::class,
|
||||
'difficulty' => AdviceDifficultyEnum::class
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
|
|
@ -68,7 +95,9 @@ class Advice extends Authenticatable
|
|||
*/
|
||||
protected $casts = [
|
||||
'ingredients' => 'array',
|
||||
'status' => 'bool'
|
||||
'status' => 'bool',
|
||||
'type' => AdviceTypeEnum::class,
|
||||
'difficulty' => AdviceDifficultyEnum::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -76,7 +105,7 @@ class Advice extends Authenticatable
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
|
|
@ -100,12 +129,12 @@ class Advice extends Authenticatable
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage fields on this model event.
|
||||
* Common methods function.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(Model $model)
|
||||
private static function manageFields(Model $model): void
|
||||
{
|
||||
self::assertTitleIsUnique($model->title, $model->id);
|
||||
$model->slug = Str::slug($model->title);
|
||||
|
|
@ -139,7 +168,7 @@ class Advice extends Authenticatable
|
|||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||
*/
|
||||
private static function assertLimitTags(int $nbTagsInBdd)
|
||||
private static function assertLimitTags(int $nbTagsInBdd): void
|
||||
{
|
||||
if ($nbTagsInBdd > 2) {
|
||||
throw ValidationException::withMessages([
|
||||
|
|
@ -155,7 +184,7 @@ class Advice extends Authenticatable
|
|||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||
*/
|
||||
private static function assertLimitAdvices(int $nbAdvicesInBdd)
|
||||
private static function assertLimitAdvices(int $nbAdvicesInBdd): void
|
||||
{
|
||||
if ($nbAdvicesInBdd > 6) {
|
||||
throw ValidationException::withMessages([
|
||||
|
|
@ -171,16 +200,16 @@ class Advice extends Authenticatable
|
|||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||
*/
|
||||
private static function assertLimitProducts(Model $model)
|
||||
private static function assertLimitProducts(Model $model): void
|
||||
{
|
||||
$nbProductsInBdd = $model->products()->count();
|
||||
if ($model->type->value == AdviceTypeEnum::recipes()->value) {
|
||||
if ($model->type->value == AdviceTypeEnum::recipes->value()) {
|
||||
if ($nbProductsInBdd < 1 || $nbProductsInBdd > 3) {
|
||||
throw ValidationException::withMessages([
|
||||
'Vous devez associer 1 à 3 produits.'
|
||||
]);
|
||||
}
|
||||
} elseif ($model->type->value == AdviceTypeEnum::tips()->value) {
|
||||
} elseif ($model->type->value == AdviceTypeEnum::tips->value()) {
|
||||
if ($nbProductsInBdd > 3) {
|
||||
throw ValidationException::withMessages([
|
||||
'Vous devez associer au maximum 3 produits.'
|
||||
|
|
@ -195,9 +224,9 @@ class Advice extends Authenticatable
|
|||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function setCookingtimePreparationtimeValues(Model $model)
|
||||
private static function setCookingtimePreparationtimeValues(Model $model): void
|
||||
{
|
||||
if ($model->type->value != AdviceTypeEnum::recipes()->value) {
|
||||
if ($model->type->value != AdviceTypeEnum::recipes->value()) {
|
||||
$model->cooking_time = null;
|
||||
$model->preparation_time = null;
|
||||
}
|
||||
|
|
@ -206,11 +235,11 @@ class Advice extends Authenticatable
|
|||
/**
|
||||
* Asserts using validation that the title is unique.
|
||||
*
|
||||
* @param mixed $title
|
||||
* @param string $title
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
*/
|
||||
private static function assertTitleIsUnique($title, ?int $id = null)
|
||||
private static function assertTitleIsUnique(string $title, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
|
||||
|
|
@ -222,9 +251,9 @@ class Advice extends Authenticatable
|
|||
*
|
||||
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
||||
*/
|
||||
public function recipes(): Collection
|
||||
public function recipes(): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
return $this->advices()->where('type', AdviceTypeEnum::recipes())->get();
|
||||
return $this->advices()->where('type', AdviceTypeEnum::recipes)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -232,40 +261,57 @@ class Advice extends Authenticatable
|
|||
*
|
||||
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
||||
*/
|
||||
public function tips(): Collection
|
||||
public function tips(): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
return $this->advices()->where('type', AdviceTypeEnum::tips())->get();
|
||||
return $this->advices()->where('type', AdviceTypeEnum::tips)->get();
|
||||
}
|
||||
|
||||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* BelongsToMany advices
|
||||
* Advices Belongs-To-Many relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function advices()
|
||||
public function advices(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Advice::class, 'advice_advice', 'advice_id', 'advice_related_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsToMany products
|
||||
* Products Belongs-To-Many relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function products()
|
||||
public function products(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Product::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* MorphToMany Tags
|
||||
* Tags Morph-To-Many relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||
*/
|
||||
public function tags()
|
||||
public function tags(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||
{
|
||||
return $this->morphToMany(Tag::class, 'taggable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfotrm to seoModel
|
||||
*
|
||||
* @return \App\Objects\SeoItem
|
||||
*/
|
||||
public function toSeoItem(): SeoItem
|
||||
{
|
||||
return new SeoItem(
|
||||
\trans($this->getTable()),
|
||||
$this->seo_title,
|
||||
$this->seo_description,
|
||||
$this->status ?? false,
|
||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
||||
$this->type === AdviceTypeEnum::recipes ? route('fo.recipes.show', $this) : route('fo.tips.show', $this)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,22 @@ use App\Lib\Helpers\ToolboxHelper;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Kwaadpepper\Enum\Traits\CastsEnums;
|
||||
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property \App\Enums\ExpertiseProducts\ExpertiseProductPageEnum $page Title.
|
||||
* @property string $label Label of the title.
|
||||
* @property string $title Title.
|
||||
* @property string $subtitle Subtitle.
|
||||
* @property array $points Type of the advice.
|
||||
* @property boolean $is_frenchpoultry Is frenchpoultry or not.
|
||||
* @property boolean $is_natureeleveurs Is natureeleveurs or not.
|
||||
* @property \App\Enums\NutriscoreEnum $nutriscore Nutriscore.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class ExpertiseProduct extends Model
|
||||
{
|
||||
use CastsEnums;
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
|
|
@ -29,17 +40,7 @@ class ExpertiseProduct extends Model
|
|||
'points',
|
||||
'is_frenchpoultry',
|
||||
'is_natureeleveurs',
|
||||
'nutriscore'
|
||||
];
|
||||
|
||||
/**
|
||||
* Map attribute names to enum classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $enumCasts = [
|
||||
'page' => ExpertiseProductPageEnum::class,
|
||||
'nutriscore' => NutriscoreEnum::class
|
||||
'nutriscore',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -48,9 +49,11 @@ class ExpertiseProduct extends Model
|
|||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'points' => 'array',
|
||||
'is_frenchpoultry' => 'bool',
|
||||
'is_natureeleveurs' => 'bool'
|
||||
'points' => 'array',
|
||||
'is_frenchpoultry' => 'bool',
|
||||
'is_natureeleveurs' => 'bool',
|
||||
'page' => ExpertiseProductPageEnum::class,
|
||||
'nutriscore' => NutriscoreEnum::class
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -58,7 +61,7 @@ class ExpertiseProduct extends Model
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
|
|
@ -79,28 +82,27 @@ class ExpertiseProduct extends Model
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
* Common methods function.
|
||||
*
|
||||
* @param Model $model
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(Model $model)
|
||||
private static function manageFields(Model $model): void
|
||||
{
|
||||
static::assertFieldIsUnique('label', $model->label, $model->id);
|
||||
static::assertFieldIsUnique('title', $model->title, $model->id);
|
||||
|
||||
self::assertFieldIsUnique('label', $model->label, $model->id);
|
||||
self::assertFieldIsUnique('title', $model->title, $model->id);
|
||||
self::assertNumberOfProductsVip($model->page->value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts using validation that the label is unique
|
||||
* Asserts using validation that the label is unique.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $field
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
*/
|
||||
private static function assertFieldIsUnique(string $name, $field, ?int $id = null)
|
||||
private static function assertFieldIsUnique(string $name, mixed $field, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, $name, $field, $id);
|
||||
|
|
@ -113,7 +115,7 @@ class ExpertiseProduct extends Model
|
|||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If there are more than 3 products.
|
||||
*/
|
||||
private static function assertNumberOfProductsVip(int $specie)
|
||||
private static function assertNumberOfProductsVip(int $specie): void
|
||||
{
|
||||
if (count(self::where('page', '=', $specie)->get()) >= 3) {
|
||||
throw ValidationException::withMessages([
|
||||
|
|
|
|||
|
|
@ -9,13 +9,45 @@ use Illuminate\Database\Eloquent\Model;
|
|||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||
|
||||
/**
|
||||
* @property-read string $reading_time Time reading of a news' page
|
||||
*/
|
||||
class News extends Authenticatable
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $title Title.
|
||||
* @property string $subtitle Type of the advice.
|
||||
* @property string $slug Slug of the title.
|
||||
* @property string $seo_title SEO Title.
|
||||
* @property string $seo_description SEO description.
|
||||
* @property string $picture Path of a picture.
|
||||
* @property string $picture_alt Picture's attribute alt.
|
||||
* @property string $picture_title Picture's attribute title.
|
||||
* @property string $picture2 Path of a second picture.
|
||||
* @property string $picture2_alt Second picture's attribute alt.
|
||||
* @property string $picture2_title Second picture's attribute title.
|
||||
* @property string $content First WYSWYG content.
|
||||
* @property string $content2 Second WYSWYG content.
|
||||
* @property \Illuminate\Support\Carbon $event_start Start of the event.
|
||||
* @property \Illuminate\Support\Carbon $event_end End of the event.
|
||||
* @property string $event_text Text of the event.
|
||||
* @property boolean $status Status.
|
||||
* @property-read string $reading_time Time reading of a news' page
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\News> $news
|
||||
* News Belongs-To-Many relationship.
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products
|
||||
* Products Belongs-To-Many relationship.
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Tags> $categories
|
||||
* Categories Morph-To-Many relationship.
|
||||
*/
|
||||
class News extends Authenticatable implements SeoInterface
|
||||
{
|
||||
use HasFactory;
|
||||
use SeoTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -39,7 +71,7 @@ class News extends Authenticatable
|
|||
'event_start',
|
||||
'event_end',
|
||||
'event_text',
|
||||
'status'
|
||||
'status',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -49,8 +81,8 @@ class News extends Authenticatable
|
|||
*/
|
||||
protected $casts = [
|
||||
'event_start' => 'datetime',
|
||||
'event_end' => 'datetime',
|
||||
'status' => 'bool'
|
||||
'event_end' => 'datetime',
|
||||
'status' => 'bool',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -58,7 +90,7 @@ class News extends Authenticatable
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::manageFields($model);
|
||||
|
|
@ -82,12 +114,12 @@ class News extends Authenticatable
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage fields on this model event.
|
||||
* Common methods function.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(Model $model)
|
||||
private static function manageFields(Model $model): void
|
||||
{
|
||||
self::assertTitleIsUnique($model->title, $model->id);
|
||||
$model->slug = Str::slug($model->title);
|
||||
|
|
@ -104,11 +136,12 @@ class News extends Authenticatable
|
|||
|
||||
/**
|
||||
* Limit products associated.
|
||||
*
|
||||
* @param integer $nbProductsInBdd
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||
*/
|
||||
private static function assertLimitProducts(int $nbProductsInBdd)
|
||||
private static function assertLimitProducts(int $nbProductsInBdd): void
|
||||
{
|
||||
if ($nbProductsInBdd > 3) {
|
||||
throw ValidationException::withMessages([
|
||||
|
|
@ -123,7 +156,7 @@ class News extends Authenticatable
|
|||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||
*/
|
||||
private static function assertLimitNews(int $nbNewsInBdd)
|
||||
private static function assertLimitNews(int $nbNewsInBdd): void
|
||||
{
|
||||
if ($nbNewsInBdd > 3) {
|
||||
throw ValidationException::withMessages([
|
||||
|
|
@ -138,7 +171,7 @@ class News extends Authenticatable
|
|||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException Error exception.
|
||||
*/
|
||||
private static function assertLimitNewsCategory(int $nbNewsCategoriesInBdd)
|
||||
private static function assertLimitNewsCategory(int $nbNewsCategoriesInBdd): void
|
||||
{
|
||||
if ($nbNewsCategoriesInBdd < 1 or $nbNewsCategoriesInBdd > 2) {
|
||||
throw ValidationException::withMessages([
|
||||
|
|
@ -150,11 +183,11 @@ class News extends Authenticatable
|
|||
/**
|
||||
* Asserts using validation that the title is unique.
|
||||
*
|
||||
* @param mixed $title
|
||||
* @param string $title
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
*/
|
||||
private static function assertTitleIsUnique($title, ?int $id = null)
|
||||
private static function assertTitleIsUnique(string $title, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
|
||||
|
|
@ -165,11 +198,9 @@ class News extends Authenticatable
|
|||
/**
|
||||
* Getter reading_time.
|
||||
*
|
||||
* * USED
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReadingTime()
|
||||
public function getReadingTime(): string
|
||||
{
|
||||
$allWords = count(explode(
|
||||
" ",
|
||||
|
|
@ -188,31 +219,31 @@ class News extends Authenticatable
|
|||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* BelongsToMany news
|
||||
* News Morph-To-Many relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function news()
|
||||
public function news(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(News::class, 'news_news', 'news_id', 'news_related_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsToMany products
|
||||
* Products Morph-To-Many relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function products()
|
||||
public function products(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Product::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsToMany categories
|
||||
* Categories Morph-To-Many relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function categories()
|
||||
public function categories(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(NewsCategory::class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,16 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $label Label.
|
||||
* @property string $slug Slug of the title.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\News> $news
|
||||
* News Belongs-To-Many relationship.
|
||||
*/
|
||||
class NewsCategory extends Authenticatable
|
||||
{
|
||||
use HasFactory;
|
||||
|
|
@ -39,12 +49,12 @@ class NewsCategory extends Authenticatable
|
|||
/**
|
||||
* Asserts using validation that the label is unique.
|
||||
*
|
||||
* @param mixed $label
|
||||
* @param string $label
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If an actu label already exists.
|
||||
*/
|
||||
private static function assertLabelIsUnique($label, ?int $id = null)
|
||||
private static function assertLabelIsUnique(string $label, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'label', $label, $id);
|
||||
|
|
@ -58,7 +68,7 @@ class NewsCategory extends Authenticatable
|
|||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function news()
|
||||
public function news(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(News::class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,17 +7,48 @@ use App\Enums\NutriscoreEnum;
|
|||
use App\Enums\Products\ProductSpeciesEnum;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Support\Str;
|
||||
use Kwaadpepper\Enum\Traits\CastsEnums;
|
||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||
|
||||
class Product extends Model
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $label Title.
|
||||
* @property string $slug Slug of the title.
|
||||
* @property integer $subrange_id Foreign key Subrange.
|
||||
* @property string $seo_title SEO Title.
|
||||
* @property string $seo_description SEO description.
|
||||
* @property \App\Enums\Products\ProductSpeciesEnum $species Species of products.
|
||||
* @property \App\Enums\NutriscoreEnum $nutriscore Nutriscore.
|
||||
* @property string $sticker_sm Path of a small sticker.
|
||||
* @property string $sticker_sm_alt small sticker's attribute alt.
|
||||
* @property string $sticker_sm_title Small sticker's attribute title.
|
||||
* @property string $slider_pictures Array of paths of pictures.
|
||||
* @property string $packaging Packaging.
|
||||
* @property \Illuminate\Support\Carbon $caliber Caliber.
|
||||
* @property \Illuminate\Support\Carbon $nutritionnal_values Nutritionnal values.
|
||||
* @property \Illuminate\Support\Carbon $ingredients Ingredients.
|
||||
* @property \Illuminate\Support\Carbon $advantage Advantage.
|
||||
* @property \Illuminate\Support\Carbon $preparation Preparation.
|
||||
* @property \Illuminate\Support\Carbon $is_frenchpoultry Is frenchpoultry or not.
|
||||
* @property \App\Enums\Advices\AdviceDifficultyEnum $is_vip Is vip or not.
|
||||
* @property \App\Enums\Advices\AdviceDifficultyEnum $is_egalim Is egalim or not.
|
||||
* @property boolean $status Status.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\Subrange $subrange Subrange Has-One relation.
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> $advices
|
||||
* Advices Belongs-To-Many relation.
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\News> $news
|
||||
* News Belongs-To-Many relation.
|
||||
*/
|
||||
class Product extends Model implements SeoInterface
|
||||
{
|
||||
use CastsEnums;
|
||||
use HasFactory;
|
||||
use SeoTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -48,30 +79,22 @@ class Product extends Model
|
|||
'status'
|
||||
];
|
||||
|
||||
/**
|
||||
* Map attribute names to enum classes.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $enumCasts = [
|
||||
'species' => ProductSpeciesEnum::class,
|
||||
'nutriscore' => NutriscoreEnum::class
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'slider_pictures' => 'array',
|
||||
'packaging' => 'array',
|
||||
'caliber' => 'array',
|
||||
'slider_pictures' => 'array',
|
||||
'packaging' => 'array',
|
||||
'caliber' => 'array',
|
||||
'nutritionnal_values' => 'array',
|
||||
'is_frenchpoultry' => 'bool',
|
||||
'is_vip' => 'bool',
|
||||
'is_egalim' => 'bool',
|
||||
'status' => 'bool'
|
||||
'is_frenchpoultry' => 'bool',
|
||||
'is_vip' => 'bool',
|
||||
'is_egalim' => 'bool',
|
||||
'status' => 'bool',
|
||||
'species' => ProductSpeciesEnum::class,
|
||||
'nutriscore' => NutriscoreEnum::class
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -79,7 +102,7 @@ class Product extends Model
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
// * EVENT CLOSURES.
|
||||
static::creating(function (self $model) {
|
||||
|
|
@ -100,12 +123,12 @@ class Product extends Model
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
* Common methods function.
|
||||
*
|
||||
* @param Model $model
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(Model $model)
|
||||
private static function manageFields(Model $model): void
|
||||
{
|
||||
// * ASSERTIONS
|
||||
static::assertLabelIsUnique($model->label, $model->id);
|
||||
|
|
@ -137,13 +160,13 @@ class Product extends Model
|
|||
}
|
||||
|
||||
/**
|
||||
* Asserts using validation that the label is unique
|
||||
* Asserts using validation that the label is unique.
|
||||
*
|
||||
* @param mixed $label
|
||||
* @param string $label
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
*/
|
||||
private static function assertLabelIsUnique($label, ?int $id = null)
|
||||
private static function assertLabelIsUnique(string $label, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'label', $label, $id);
|
||||
|
|
@ -151,42 +174,41 @@ class Product extends Model
|
|||
}
|
||||
|
||||
/**
|
||||
* Get associated tips
|
||||
* Get associated tips.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function tipsQuery(): BelongsToMany
|
||||
public function tipsQuery(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->advices()->where('type', AdviceTypeEnum::tips());
|
||||
return $this->advices()->where('type', AdviceTypeEnum::tips);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get associated recipes
|
||||
* Get associated recipes.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function recipesQuery(): BelongsToMany
|
||||
public function recipesQuery(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->advices()->where('type', AdviceTypeEnum::tips());
|
||||
return $this->advices()->where('type', AdviceTypeEnum::recipes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get associated tips
|
||||
* Get associated tips.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
||||
*/
|
||||
public function tips(): Collection
|
||||
public function tips(): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
return $this->tipsQuery()->get();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get associated recipes
|
||||
* Get associated recipes.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Collection<\App\Models\Advice>
|
||||
*/
|
||||
public function recipes(): Collection
|
||||
public function recipes(): \Illuminate\Database\Eloquent\Collection
|
||||
{
|
||||
return $this->recipesQuery()->get();
|
||||
}
|
||||
|
|
@ -194,31 +216,31 @@ class Product extends Model
|
|||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* HasOne Subrange relation
|
||||
* Subrange Has-One relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\belongsTo
|
||||
*/
|
||||
public function subrange()
|
||||
public function subrange(): \Illuminate\Database\Eloquent\Relations\belongsTo
|
||||
{
|
||||
return $this->belongsTo(Subrange::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsToMany advices relation
|
||||
* Advices Belongs-To-Many relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function advices()
|
||||
public function advices(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(Advice::class, 'advice_product');
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsToMany advice relation
|
||||
* News Belongs-To-Many relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function news()
|
||||
public function news(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
{
|
||||
return $this->belongsToMany(News::class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,34 @@ use App\Lib\Helpers\ToolboxHelper;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||
|
||||
class Range extends Model
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $label Label.
|
||||
* @property string $slug Slug of the title.
|
||||
* @property string $seo_title SEO Title.
|
||||
* @property string $seo_description SEO description.
|
||||
* @property integer $color Color of the range.
|
||||
* @property string $picture Path of a picture.
|
||||
* @property string $picture_alt Picture's attribute alt.
|
||||
* @property string $picture_title Picture's attribute title.
|
||||
* @property string $banner Path of a banner.
|
||||
* @property string $banner_alt Banner's attribute alt.
|
||||
* @property string $banner_title Banner's attribute title.
|
||||
* @property integer $order Order.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Subrange> $subranges
|
||||
* Subranges Has-Many relationship.
|
||||
*/
|
||||
class Range extends Model implements SeoInterface
|
||||
{
|
||||
use HasFactory;
|
||||
use SeoTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -30,7 +54,7 @@ class Range extends Model
|
|||
'picture_banner',
|
||||
'picture_banner_alt',
|
||||
'picture_banner_title',
|
||||
'order'
|
||||
'order',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -39,7 +63,7 @@ class Range extends Model
|
|||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'color' => RgbaColor::class
|
||||
'color' => RgbaColor::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -47,7 +71,7 @@ class Range extends Model
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function () {
|
||||
throw new \RuntimeException('Impossible de créer un range');
|
||||
|
|
@ -70,14 +94,14 @@ class Range extends Model
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Asserts using validation that the label is unique
|
||||
* Asserts using validation that the label is unique.
|
||||
*
|
||||
* @param mixed $label
|
||||
* @param string $label
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If an actu label already exists.
|
||||
*/
|
||||
private static function assertLabelIsUnique($label, ?int $id = null)
|
||||
private static function assertLabelIsUnique(string $label, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'label', $label, $id);
|
||||
|
|
@ -87,12 +111,31 @@ class Range extends Model
|
|||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* Get subranges for the Range.
|
||||
* Subranges Has-Many relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\hasMany
|
||||
*/
|
||||
public function subranges()
|
||||
public function subranges(): \Illuminate\Database\Eloquent\Relations\hasMany
|
||||
{
|
||||
return $this->hasMany(Subrange::class);
|
||||
}
|
||||
|
||||
// * SEO
|
||||
|
||||
/**
|
||||
* Transfotrm to seoModel
|
||||
*
|
||||
* @return \App\Objects\SeoItem
|
||||
*/
|
||||
public function toSeoItem(): SeoItem
|
||||
{
|
||||
return new SeoItem(
|
||||
\trans($this->getTable()),
|
||||
$this->seo_title,
|
||||
$this->seo_description,
|
||||
true,
|
||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
||||
\route('fo.products.range-products', $this)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,24 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $title Title.
|
||||
* @property integer $content WYSWYG content.
|
||||
* @property boolean $button_display Display the button.
|
||||
* @property string $button_text Title of the button.
|
||||
* @property string $button_url Link of the button.
|
||||
* @property boolean $button_targetblank Open in new window.
|
||||
* @property string $picture Path of a picture.
|
||||
* @property string $picture_alt Picture's attribute alt.
|
||||
* @property string $picture_title Picture's attribute title.
|
||||
* @property string $picture_thumbnail Path of a thumbnail picture.
|
||||
* @property string $picture_thumbnail_alt Thumbnail picture's attribute alt.
|
||||
* @property string $picture_thumbnail_title Thumbnail picture's attribute title.
|
||||
* @property integer $order Order.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class Slide extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
|
@ -48,7 +66,7 @@ class Slide extends Model
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
if (count(self::get()) >= 4) {
|
||||
|
|
@ -78,12 +96,12 @@ class Slide extends Model
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
* Common methods function.
|
||||
*
|
||||
* @param Model $model
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(Model $model)
|
||||
private static function manageFields(Model $model): void
|
||||
{
|
||||
self::assertTitleIsUnique($model->title, $model->id);
|
||||
ToolboxHelper::assertNoInternalBoUrls($model->content, 'content');
|
||||
|
|
@ -102,7 +120,7 @@ class Slide extends Model
|
|||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If there is less 1 or more than 4 slides.
|
||||
*/
|
||||
private static function assertNumberOfSlides()
|
||||
private static function assertNumberOfSlides(): void
|
||||
{
|
||||
throw ValidationException::withMessages([
|
||||
'Opération impossible, minimum un et maximum quatre slides doivent être présentes.'
|
||||
|
|
@ -112,11 +130,11 @@ class Slide extends Model
|
|||
/**
|
||||
* Asserts using validation that the title is unique.
|
||||
*
|
||||
* @param mixed $title
|
||||
* @param string $title
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
*/
|
||||
private static function assertTitleIsUnique($title, ?int $id = null)
|
||||
private static function assertTitleIsUnique(string $title, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,18 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $label Label.
|
||||
* @property string $slug Slug of the label.
|
||||
* @property integer $range_id Foreign key Range.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Product> $products
|
||||
* Products Belongs-To-Many relationship.
|
||||
* @property-read \App\Models\Range $range Range Belongs-To relationship.
|
||||
*/
|
||||
class Subrange extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
|
@ -26,7 +38,7 @@ class Subrange extends Model
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
// * EVENT CLOSURES.
|
||||
static::creating(function (self $model) {
|
||||
|
|
@ -41,28 +53,25 @@ class Subrange extends Model
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
* Common methods function.
|
||||
*
|
||||
* @param Model $model
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(Model $model)
|
||||
private static function manageFields(Model $model): void
|
||||
{
|
||||
// * ASSERTIONS
|
||||
static::assertLabelIsUnique($model->label, $model->id);
|
||||
|
||||
// * TRANSFORMATIONS
|
||||
$model->slug = Str::slug($model->label);
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts using validation that the label is unique
|
||||
*
|
||||
* @param mixed $label
|
||||
* @param string $label
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
*/
|
||||
private static function assertLabelIsUnique($label, ?int $id = null)
|
||||
private static function assertLabelIsUnique(string $label, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'label', $label, $id);
|
||||
|
|
@ -72,7 +81,7 @@ class Subrange extends Model
|
|||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* Get products for the Subrange.
|
||||
* Products Belongs-To-Many relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\hasMany
|
||||
*/
|
||||
|
|
@ -82,7 +91,7 @@ class Subrange extends Model
|
|||
}
|
||||
|
||||
/**
|
||||
* Get range for the Subrange.
|
||||
* Range Belongs-To relationship.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\belongsTo
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -7,6 +7,38 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $title Title.
|
||||
* @property string $slug Slug of the title.
|
||||
* @property string $seo_title SEO Title.
|
||||
* @property string $seo_description SEO description.
|
||||
* @property \App\Enums\Advices\AdviceTypeEnum $type Type of the advice.
|
||||
* @property string $picture Path of a picture.
|
||||
* @property string $picture_alt Picture's attribute alt.
|
||||
* @property string $picture_title Picture's attribute title.
|
||||
* @property string $sticker Path of a sticker.
|
||||
* @property string $sticker_alt Sticker's attribute alt.
|
||||
* @property string $sticker_title Sticker's attribute title.
|
||||
* @property string $sticker_sm Path of a small sticker.
|
||||
* @property string $sticker_sm_alt small sticker's attribute alt.
|
||||
* @property string $sticker_sm_title Small sticker's attribute title.
|
||||
* @property string $preparation Preparation tips.
|
||||
* @property string $advice Advice.
|
||||
* @property \Illuminate\Support\Carbon $ingredients Ingredients.
|
||||
* @property \Illuminate\Support\Carbon $guests_nb Number of guests.
|
||||
* @property \Illuminate\Support\Carbon $youtube_title Youtube title.
|
||||
* @property \Illuminate\Support\Carbon $youtube_video_id Youtube video id.
|
||||
* @property \Illuminate\Support\Carbon $cooking_time Time of cooking.
|
||||
* @property \Illuminate\Support\Carbon $preparation_time Time of preparation.
|
||||
* @property \App\Enums\Advices\AdviceDifficultyEnum $difficulty Difficulty.
|
||||
* @property boolean $status Status.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \Illuminate\Database\Eloquent\Collection<\App\Models\Advice> $advice
|
||||
* Advice Morph-To-Many relationship.
|
||||
*/
|
||||
class Tag extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
|
@ -25,7 +57,7 @@ class Tag extends Model
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (Tag $tag) {
|
||||
static::assertLabelIsUnique($tag->label);
|
||||
|
|
@ -43,14 +75,14 @@ class Tag extends Model
|
|||
// * METHODS
|
||||
|
||||
/**
|
||||
* Asserts using validation that the label is unique
|
||||
* Asserts using validation that the label is unique.
|
||||
*
|
||||
* @param mixed $label
|
||||
* @param string $label
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If a tag label already exists.
|
||||
*/
|
||||
private static function assertLabelIsUnique($label, ?int $id = null)
|
||||
private static function assertLabelIsUnique(string $label, ?int $id = null): void
|
||||
{
|
||||
$table = (new self())->getTable();
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'label', $label, $id);
|
||||
|
|
@ -60,11 +92,11 @@ class Tag extends Model
|
|||
// * RELATIONSHIPS
|
||||
|
||||
/**
|
||||
* MorphedByMany advice relation
|
||||
* Advice Morphed-By-Many relation.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphedByMany
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||
*/
|
||||
public function advice()
|
||||
public function advice(): \Illuminate\Database\Eloquent\Relations\MorphToMany
|
||||
{
|
||||
return $this->morphedByMany(Advice::class, 'taggable');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,18 @@ use Illuminate\Notifications\Notifiable;
|
|||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property integer $id Id.
|
||||
* @property string $firstname Firstname.
|
||||
* @property string $lastname Lastname.
|
||||
* @property string $email Email.
|
||||
* @property \Illuminate\Support\Carbon $email_verified_at Email_verified_at.
|
||||
* @property string $password Password.
|
||||
* @property string $remember_token Remember_token.
|
||||
* @property \Carbon\Carbon $last_connection Last_connection.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasFactory;
|
||||
|
|
@ -20,7 +32,8 @@ class User extends Authenticatable
|
|||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'firstname',
|
||||
'lastname',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
|
@ -42,7 +55,7 @@ class User extends Authenticatable
|
|||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
'last_connection' => 'datetime',
|
||||
'last_connection' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -50,7 +63,7 @@ class User extends Authenticatable
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function booted()
|
||||
protected static function booted(): void
|
||||
{
|
||||
// * EVENT CLOSURES.
|
||||
static::creating(function (self $user) {
|
||||
|
|
@ -74,12 +87,12 @@ class User extends Authenticatable
|
|||
/**
|
||||
* Asserts using validation that the email is unique
|
||||
*
|
||||
* @param mixed $email
|
||||
* @param string $email
|
||||
* @param integer|null $id
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If user email as already used.
|
||||
*/
|
||||
private static function assertEmailIsUnique($email, ?int $id = null)
|
||||
private static function assertEmailIsUnique(string $email, ?int $id = null): void
|
||||
{
|
||||
ToolboxHelper::assertFieldIsUnique((new self())->getTable(), 'email', $email, $id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,22 +2,13 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
|
|
@ -25,32 +16,25 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot()
|
||||
{
|
||||
// * HTTPS FIX
|
||||
URL::forceScheme('https');
|
||||
|
||||
// * LOCAL FORCE eg: for Carbon
|
||||
// * Remove numeric to prevent float seperator to breaking numeric transactions
|
||||
\collect([\LC_TIME, \LC_MESSAGES, \LC_COLLATE, \LC_CTYPE, \LC_MONETARY])
|
||||
->map(function ($contant) {
|
||||
setlocale(
|
||||
$contant,
|
||||
\sprintf(
|
||||
'%s_%s.UTF-8',
|
||||
config('app.locale'),
|
||||
\strtoupper(config('app.locale'))
|
||||
)
|
||||
);
|
||||
});
|
||||
Carbon::setLocale(config('app.locale'));
|
||||
|
||||
// * Force bootstrap paginator with tooltips.
|
||||
Paginator::defaultView('bo.modules.pagination');
|
||||
|
||||
// * HA PROXY FIX
|
||||
app()->singleton('clientIp', function () {
|
||||
App::singleton('clientIp', function () {
|
||||
if (config('app.env') === 'local') {
|
||||
return request()->getClientIp();
|
||||
} else {
|
||||
return request()->server('HTTP_X_FORWARDED_FOR') ??
|
||||
request()->getClientIp();
|
||||
}
|
||||
return request()->server('HTTP_X_FORWARDED_FOR') ?? request()->getClientIp();
|
||||
});
|
||||
|
||||
// * LOCAL FORCE eg: for Carbon
|
||||
setlocale(LC_ALL, \sprintf(
|
||||
'%s_%s.UTF-8',
|
||||
config('app.locale'),
|
||||
\strtoupper(config('app.locale'))
|
||||
));
|
||||
Carbon::setLocale(config('app.locale'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use App\Models\Advice;
|
||||
use App\Models\ExpertiseProduct;
|
||||
use App\Models\News;
|
||||
use App\Models\NewsCategory;
|
||||
use App\Models\Product;
|
||||
use App\Models\Range;
|
||||
use App\Models\Slide;
|
||||
use App\Models\Tag;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
|
|
@ -15,7 +15,6 @@ use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvi
|
|||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -26,7 +25,7 @@ class RouteServiceProvider extends ServiceProvider
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/home';
|
||||
public const HOME = '/';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
|
|
@ -37,7 +36,7 @@ class RouteServiceProvider extends ServiceProvider
|
|||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
ToolboxHelper::cspReportRoute();
|
||||
$this->cspReportRoute();
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('web')
|
||||
|
|
@ -49,13 +48,16 @@ class RouteServiceProvider extends ServiceProvider
|
|||
->group(base_path('routes/web-bo.php'));
|
||||
});
|
||||
|
||||
Route::model('slide', Slide::class);
|
||||
Route::model('expertiseproduct', ExpertiseProduct::class);
|
||||
Route::model('news', News::class);
|
||||
Route::model('newscategory', NewsCategory::class);
|
||||
Route::model('tag', Tag::class);
|
||||
Route::model('product', Product::class);
|
||||
Route::model('advice', Advice::class);
|
||||
if (collect(explode('/', \request()->getPathInfo()))->get(1) === 'bo') {
|
||||
Route::model('slide', Slide::class);
|
||||
Route::model('expertiseproduct', ExpertiseProduct::class);
|
||||
Route::model('news', News::class);
|
||||
Route::model('newscategory', NewsCategory::class);
|
||||
Route::model('tag', Tag::class);
|
||||
Route::model('range', Range::class);
|
||||
Route::model('product', Product::class);
|
||||
Route::model('advice', Advice::class);
|
||||
}
|
||||
|
||||
Route::bind('actu', function ($value) {
|
||||
return News::where('id', $value)->orWhere('slug', $value)->firstOrFail();
|
||||
|
|
@ -72,13 +74,16 @@ class RouteServiceProvider extends ServiceProvider
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureRateLimiting()
|
||||
protected function configureRateLimiting(): void
|
||||
{
|
||||
RateLimiter::for('credentials', function (Request $request) {
|
||||
return Limit::perMinute(25)->by(optional($request->user())->id ?: app('clientIp'));
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(150)->by($request->user()?->id ?: app('clientIp'));
|
||||
});
|
||||
RateLimiter::for('web', function (Request $request) {
|
||||
return Limit::perMinute(150)->by(optional($request->user())->id ?: app('clientIp'));
|
||||
return Limit::perMinute(150)->by($request->user()?->id ?: app('clientIp'));
|
||||
});
|
||||
RateLimiter::for('credentials', function (Request $request) {
|
||||
return Limit::perMinute(30)->by($request->user()?->id ?: app('clientIp'));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -88,8 +93,6 @@ class RouteServiceProvider extends ServiceProvider
|
|||
* Put this function inside RouteServiceProvider,
|
||||
* and call it in RouteServiceProvider::boot
|
||||
*
|
||||
* ! Use this in conjonction with kwaadpepper/exception-handler
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function cspReportRoute()
|
||||
|
|
@ -110,7 +113,7 @@ class RouteServiceProvider extends ServiceProvider
|
|||
'blocked-uri' => '', 'document-uri' => '', 'original-policy' => '',
|
||||
'referrer' => '', 'violated-directive' => ''
|
||||
]));
|
||||
Log::warning(sprintf(
|
||||
\Illuminate\Support\Facades\Log::warning(sprintf(
|
||||
"CSP REPORT for %s : \n %s",
|
||||
$cspReport->get('document-uri'),
|
||||
$cspReport->implode("\n")
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Illuminate\Support\Collection;
|
|||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
class TranslationServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -14,7 +15,7 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
public function boot(): void
|
||||
{
|
||||
foreach ($this->collectLocalesStrings() as $locale) {
|
||||
// * Suported locales
|
||||
|
|
@ -31,12 +32,12 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
/**
|
||||
* Gather provided langs checking from files
|
||||
*
|
||||
* @return Collection
|
||||
* @return \Illuminate\Support\Collection<string, string>
|
||||
*/
|
||||
private function collectLocalesStrings(): Collection
|
||||
{
|
||||
return collect(File::allFiles(resource_path('lang/')))->flatMap(function ($file) {
|
||||
if ($file->getRelativePath()) {
|
||||
return collect(File::allFiles(resource_path('lang/')))->flatMap(function (SplFileInfo $file) {
|
||||
if ($file->getRelativePath() and \strpos($file->getRelativePath(), 'vendor') !== 0) {
|
||||
return [$file->getRelativePath() => ''];
|
||||
}
|
||||
})->keys();
|
||||
|
|
@ -46,7 +47,7 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
* Gather all php translations
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function phpTranslations(string $locale): array
|
||||
{
|
||||
|
|
@ -62,7 +63,7 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
* Gather json translations
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function jsonTranslations(string $locale): array
|
||||
{
|
||||
|
|
|
|||
39
app/Providers/ViewServiceProvider.php
Normal file
39
app/Providers/ViewServiceProvider.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class ViewServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$appInfos = Cache::remember('composer', 360, function () {
|
||||
return json_decode(File::get(\app_path('../composer.json')));
|
||||
});
|
||||
// Share composer.json infos.
|
||||
if (isset($appInfos->name) and isset($appInfos->version)) {
|
||||
View::share('cpsr_name', $appInfos->name);
|
||||
View::share('cpsr_version', $appInfos->version);
|
||||
}
|
||||
|
||||
if (!app()->runningInConsole()) {
|
||||
// * FORCE BOOTSTRAP PAGINATOR (or custom if in front)
|
||||
// Early boot, request wont be filled as expected.
|
||||
if (collect(explode('/', \request()->getPathInfo()))->get(1) === 'bo') {
|
||||
Paginator::defaultView('bo.modules.pagination');
|
||||
} else {
|
||||
Paginator::useBootstrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
app/Traits/Controllers/ChangesModelOrder.php
Normal file
57
app/Traits/Controllers/ChangesModelOrder.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Traits\Controllers;
|
||||
|
||||
use App\Http\Requests\Bo\UpdateChangeOrderRequest;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait ChangesModelOrder
|
||||
{
|
||||
/**
|
||||
* Change order.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\UpdateChangeOrderRequest $request
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \RuntimeException Si le nom du parametre de la route ne correspond pas au model utilisé.
|
||||
*/
|
||||
public function changeOrder(UpdateChangeOrderRequest $request, Model $model): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$params = collect(request()->route()->parameterNames);
|
||||
$className = Str::ucfirst(Str::lower($params->get($params->count() - 2)));
|
||||
$className = "\\App\\Models\\$className";
|
||||
|
||||
if (!class_exists($className)) {
|
||||
throw new \RuntimeException("The $className class doesn't exist.");
|
||||
}
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$model = $className::where('id', $model->id)->first();
|
||||
|
||||
if (!$model) {
|
||||
return redirect()->back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
}
|
||||
|
||||
return DB::transaction(function () use ($request, $className, $model) {
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$tmp = $className::where('order', $request->direction ? '<' : '>', $model->order)
|
||||
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
|
||||
|
||||
if (!$tmp) {
|
||||
return redirect()->back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
}
|
||||
|
||||
$newOrder = $tmp->order;
|
||||
$tmp->order = $model->order;
|
||||
$model->order = $newOrder;
|
||||
$tmp->saveOrFail();
|
||||
$model->saveOrFail();
|
||||
Session::flash('success', trans('crud.messages.order_changed'));
|
||||
|
||||
return redirect()->back();
|
||||
});
|
||||
}
|
||||
}
|
||||
256
app/Traits/Enums/BaseEnum.php
Normal file
256
app/Traits/Enums/BaseEnum.php
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
<?php
|
||||
|
||||
namespace App\Traits\Enums;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait BaseEnum
|
||||
{
|
||||
// * GENERIC METHODS
|
||||
/**
|
||||
* Get enum value
|
||||
*
|
||||
* @return string|integer
|
||||
*/
|
||||
public function value(): string|int
|
||||
{
|
||||
return self::toValues()[$this->name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enum label
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function label(): string
|
||||
{
|
||||
return self::toLabels()[$this->name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enum name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
// * STATIC FETCH METHODS
|
||||
|
||||
/**
|
||||
* Get enum labels
|
||||
*
|
||||
* @return array<string>
|
||||
*/
|
||||
public static function toLabels(): array
|
||||
{
|
||||
if (empty(self::getCache('labels'))) {
|
||||
$labels = self::getLabelsConstant();
|
||||
self::setCache('labels', \collect(self::cases())
|
||||
->mapWithKeys(function ($enum) use ($labels) {
|
||||
if (!\is_null($labels) and !isset($labels[$enum->name])) {
|
||||
throw new \Error('Missing definition label ' . self::class . " for {$enum->name}");
|
||||
}
|
||||
return [$enum->name => \trans(
|
||||
!\is_null($labels) ? $labels[$enum->name] : Str::ucfirst($enum->name)
|
||||
)];
|
||||
})->all());
|
||||
}
|
||||
return self::getCache('labels');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enum values
|
||||
*
|
||||
* @return array<integer|string>
|
||||
*/
|
||||
public static function toValues(): array
|
||||
{
|
||||
if (empty(self::getCache('values'))) {
|
||||
self::setCache('values', \collect(self::cases())
|
||||
->mapWithKeys(fn ($enum) => [$enum->name => $enum->value])->all());
|
||||
}
|
||||
return self::getCache('values');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enums
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function all(): array
|
||||
{
|
||||
return self::cases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enums
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function toArray(): array
|
||||
{
|
||||
if (empty(self::getCache('enums'))) {
|
||||
$definitions = self::getCustomDefinitions();
|
||||
self::setCache('enums', \collect(self::cases())
|
||||
->mapWithKeys(function ($enum) use ($definitions) {
|
||||
$baseArray = [
|
||||
'name' => $enum->name,
|
||||
'label' => $enum->label(),
|
||||
'value' => $enum->value,
|
||||
];
|
||||
foreach ($definitions as $index => $elements) {
|
||||
$index = Str::lower(Str::singular($index));
|
||||
if (!isset($elements[$enum->name])) {
|
||||
throw new \Error("Missing definition {$index} " . self::class . " for {$enum->name}");
|
||||
}
|
||||
$baseArray[$index] = $elements[$enum->name];
|
||||
}
|
||||
return [$enum->name => (object)$baseArray];
|
||||
})->all());
|
||||
}
|
||||
return self::getCache('enums');
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch enum using value
|
||||
*
|
||||
* @param \App\Traits\Enums\BaseEnum|integer|string $value
|
||||
* @return \App\Traits\Enums\BaseEnum|null
|
||||
*/
|
||||
public static function make(self|int|string $value): self|null
|
||||
{
|
||||
return !\is_object($value) ?
|
||||
\collect(self::cases())->keyBy('value')->get($value) : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if 2 enum are equals
|
||||
*
|
||||
* @param object ...$others
|
||||
* @return boolean
|
||||
* @throws \Error If provided element are not enums taht extends BaseEnum.
|
||||
*/
|
||||
public function equals(object ...$others): bool
|
||||
{
|
||||
foreach ($others as $other) {
|
||||
if (!\in_array(BaseEnum::class, \class_uses_recursive($other))) {
|
||||
throw new \Error(__METHOD__ .
|
||||
' requires $enum to use ' . BaseEnum::class);
|
||||
}
|
||||
if (
|
||||
get_class($this) === get_class($other)
|
||||
&& $this->value === $other->value
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize to json
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
|
||||
// * CACHE
|
||||
|
||||
/**
|
||||
* Get cache array
|
||||
*
|
||||
* @param string $index
|
||||
* @return array
|
||||
*/
|
||||
private static function getCache(string $index): array
|
||||
{
|
||||
self::initCache();
|
||||
if (!isset($GLOBALS[self::class]['props'][$index])) {
|
||||
$GLOBALS[self::class]['props'][$index] = [];
|
||||
}
|
||||
return $GLOBALS[self::class]['props'][$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cache array
|
||||
*
|
||||
* @param string $index
|
||||
* @param array $items
|
||||
* @return void
|
||||
*/
|
||||
private static function setCache(string $index, array $items): void
|
||||
{
|
||||
self::initCache();
|
||||
if (!isset($GLOBALS[self::class]['props'][$index])) {
|
||||
$GLOBALS[self::class]['props'][$index] = [];
|
||||
}
|
||||
$GLOBALS[self::class]['props'][$index] = $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init cache if needed
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function initCache(): void
|
||||
{
|
||||
if (!isset($GLOBALS[self::class])) {
|
||||
$GLOBALS[self::class] = [
|
||||
'props' => [
|
||||
'enums' => [],
|
||||
'values' => [],
|
||||
'labels' => []
|
||||
],
|
||||
'customProps' => null
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
// * PRIVATE
|
||||
|
||||
/**
|
||||
* Fetch the LABELS constant if exists
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private static function getLabelsConstant(): array|null
|
||||
{
|
||||
$class_name = self::class;
|
||||
try {
|
||||
$constant_reflex = new \ReflectionClassConstant($class_name, 'LABELS');
|
||||
return $constant_reflex->getValue();
|
||||
} catch (\ReflectionException $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom constants
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private static function getCustomDefinitions(): array
|
||||
{
|
||||
// ? Has custom props in cache ?
|
||||
if (!isset($GLOBALS[self::class]) or \is_null($GLOBALS[self::class]['customProps'])) {
|
||||
$names = \collect(self::cases())->keyBy('name');
|
||||
|
||||
$GLOBALS[self::class]['customProps'] = \collect((new \ReflectionClass(self::class))->getConstants())
|
||||
->filter(function (mixed $constant, string $key) use ($names) {
|
||||
if ($key === 'LABELS' or !\is_array($constant)) {
|
||||
return false;
|
||||
}
|
||||
return \collect($constant)->keys()
|
||||
->filter(fn (string $name) => $names->has($name))->count();
|
||||
})->all();
|
||||
}
|
||||
return $GLOBALS[self::class]['customProps'];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Traits\Models;
|
||||
|
||||
use App\Http\Requests\Bo\ChangeOrderRequest;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
|
||||
trait ChangesModelOrder
|
||||
{
|
||||
/**
|
||||
* Change order
|
||||
*
|
||||
* @param \App\Traits\Models\ChangeOrderRequest $request
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \RuntimeException Si le nom du parametre de la route ne correspond pas au model utilisé.
|
||||
*/
|
||||
public function changeOrder(ChangeOrderRequest $request, Model $model): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $model) {
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$tmp = (\get_class($model))::where('order', $request->direction ? '<' : '>', $model->order)
|
||||
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
|
||||
if (!$tmp) {
|
||||
return back()->with('error', trans('L\'ordre n\'a pas pu être modifié'));
|
||||
}
|
||||
$newOrder = $tmp->order;
|
||||
$tmp->order = $model->order;
|
||||
$model->order = $newOrder;
|
||||
$tmp->saveOrFail();
|
||||
$model->saveOrFail();
|
||||
Session::flash('success', trans('L\'ordre à été modifié'));
|
||||
return back();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ trait HasPicture
|
|||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
*/
|
||||
private function validatePicture(string $attribute, $value, callable $fail, object $sizes)
|
||||
private function validatePicture(string $attribute, mixed $value, callable $fail, object $sizes)
|
||||
{
|
||||
if (!File::exists($value)) {
|
||||
$fail(trans(":attribute n'existe pas dans le système de fichier"));
|
||||
|
|
|
|||
|
|
@ -1,37 +1,47 @@
|
|||
{
|
||||
"name": "uwil/le-gaulois-pro",
|
||||
"version": "2.0.0",
|
||||
"type": "project",
|
||||
"description": "Le Gaulois Pro website.",
|
||||
"support": {
|
||||
"email": "equipe.web@ldc.fr"
|
||||
},
|
||||
"keywords": [
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"axlon/laravel-postal-code-validation": "^3.3",
|
||||
"carlos-meneses/laravel-mpdf": "^2.1",
|
||||
"diglactic/laravel-breadcrumbs": "^8.0",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"kaishiyoku/laravel-color-validation": "^1.6",
|
||||
"kwaadpepper/image-resizer": "^0.1.2",
|
||||
"kwaadpepper/refresh-sitemap": "^1.0",
|
||||
"laravel/framework": "^8.83",
|
||||
"laravel/tinker": "^2.5",
|
||||
"laravel/ui": "^3.4",
|
||||
"ldc/web-admin-secure-laravel": "^1.0",
|
||||
"mews/purifier": "^3.3",
|
||||
"propaganistas/laravel-phone": "^4.4",
|
||||
"sentry/sentry-laravel": "^3.1",
|
||||
"spatie/calendar-links": "^1.5",
|
||||
"spatie/laravel-mix-preload": "^1.3",
|
||||
"uwil/k8s-laravel": "^1.2"
|
||||
"php": "^8.2",
|
||||
"axlon/laravel-postal-code-validation": "^3.4",
|
||||
"carlos-meneses/laravel-mpdf": "^2.1.13",
|
||||
"diglactic/laravel-breadcrumbs": "^8.1.1",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"kaishiyoku/laravel-color-validation": "^2.1.1",
|
||||
"kwaadpepper/image-resizer": "^2.1.0",
|
||||
"laravel/framework": "^10.0",
|
||||
"laravel/tinker": "^2.8",
|
||||
"laravel/ui": "^4.2",
|
||||
"ldc/sitemap-generator": "^2.0",
|
||||
"ldc/web-admin-secure-laravel": "^2.0.0",
|
||||
"mews/purifier": "^3.4",
|
||||
"propaganistas/laravel-phone": "^5.0.3",
|
||||
"sentry/sentry-laravel": "^3.8",
|
||||
"spatie/calendar-links": "^1.8.5",
|
||||
"uwil/k8s-laravel": "^1.2",
|
||||
"uwil/seo-laravel": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/dbal": "^3.3",
|
||||
"facade/ignition": "^2.5",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"laravel-lang/lang": "10.0",
|
||||
"laravel/sail": "^1.0.1",
|
||||
"laravel/pint": "^1.0",
|
||||
"laravel/sail": "^1.18",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^5.10",
|
||||
"phpunit/phpunit": "^9.5.10",
|
||||
"slevomat/coding-standard": "^8.3"
|
||||
"nunomaduro/collision": "^7.0",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"slevomat/coding-standard": "^8.10",
|
||||
"spatie/laravel-ignition": "^2.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
@ -45,6 +55,12 @@
|
|||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://lab.s-web.fr/api/v4/group/23/-/packages/composer/packages.json"
|
||||
}
|
||||
],
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
|
|
@ -70,19 +86,11 @@
|
|||
"preferred-install": "dist",
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true,
|
||||
"php-http/discovery": true
|
||||
},
|
||||
"gitlab-domains": [
|
||||
"lab.s-web.fr"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true,
|
||||
"repositories": {
|
||||
"lab.s-web.fr": {
|
||||
"type": "composer",
|
||||
"url": "https://lab.s-web.fr/api/v4/group/23/-/packages/composer/packages.json"
|
||||
"pestphp/pest-plugin": true,
|
||||
"php-http/discovery": true,
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
}
|
||||
|
|
|
|||
5962
composer.lock
generated
5962
composer.lock
generated
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue