Bump with laravel base controller phpstan and phpcs
Still TODO picture sizes for seeders
|
|
@ -45,9 +45,6 @@
|
|||
"vue/script-indent": ["error", 2, { "baseIndent": 0, "switchCase": 1 }],
|
||||
"vue/one-component-per-file": "off"
|
||||
},
|
||||
"globals": {
|
||||
"require": true
|
||||
},
|
||||
"settings": {
|
||||
"import/resolver": {
|
||||
"node": {
|
||||
|
|
|
|||
14
.gitignore
vendored
|
|
@ -8,6 +8,7 @@
|
|||
/.phpunit.cache
|
||||
/.vscode
|
||||
/node_modules
|
||||
/bootstrap
|
||||
/public/build
|
||||
/public/cache
|
||||
/public/hot
|
||||
|
|
@ -22,3 +23,16 @@ Homestead.yaml
|
|||
npm-debug.log
|
||||
yarn-error.log
|
||||
.npmrc
|
||||
|
||||
# Ignore public favicon
|
||||
/public/android-chrome-192x192.png
|
||||
/public/android-chrome-512x512.png
|
||||
/public/apple-touch-icon.png
|
||||
/public/browserconfig.xml
|
||||
/public/browserconfig.xml
|
||||
/public/favicon-16x16.png
|
||||
/public/favicon-32x32.png
|
||||
/public/favicon.ico
|
||||
/public/mstile-150x150.png
|
||||
/public/safari-pinned-tab.svg
|
||||
/public/site.webmanifest
|
||||
|
|
|
|||
1
.vscode/extensions.json
vendored
|
|
@ -8,7 +8,6 @@
|
|||
"neilbrayfield.php-docblocker",
|
||||
"bmewburn.vscode-intelephense-client",
|
||||
"valeryanm.vscode-phpsab",
|
||||
"shevaua.phpcs",
|
||||
"syler.sass-indented",
|
||||
"sibiraj-s.vscode-scss-formatter",
|
||||
"mrmlnc.vscode-scss",
|
||||
|
|
|
|||
5
Dockerfile
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
FROM registry.s-web.fr/ldc-web/projets/ldc-web-images-docker/ldcweb-production-8.2:latest
|
||||
COPY --chown=www-data:www-data . /app/srcs
|
||||
USER root
|
||||
RUN chmod -R 755 /app/srcs/storage
|
||||
USER www-data
|
||||
|
|
@ -8,6 +8,7 @@ use Carbon\Carbon;
|
|||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserCreate extends Command
|
||||
{
|
||||
|
|
@ -28,35 +29,35 @@ class UserCreate extends Command
|
|||
/**
|
||||
* The first name of the new user.
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
protected $first_name;
|
||||
|
||||
/**
|
||||
* The last name of the new user.
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
protected $last_name;
|
||||
|
||||
/**
|
||||
* The email of the new user.
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* The role of the new user.
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
protected $role;
|
||||
|
||||
|
|
@ -200,18 +201,22 @@ class UserCreate extends Command
|
|||
try {
|
||||
$tmp = $this->choice(
|
||||
'Select his role',
|
||||
[RoleEnum::conceptor->name, RoleEnum::admin->name, RoleEnum::visitor->name],
|
||||
RoleEnum::visitor->name,
|
||||
[
|
||||
Str::ucFirst(RoleEnum::conceptor->label()),
|
||||
Str::ucFirst(RoleEnum::admin->label()),
|
||||
Str::ucFirst(RoleEnum::visitor->label())
|
||||
],
|
||||
Str::ucFirst(RoleEnum::visitor->label()),
|
||||
$maxAttempts = null,
|
||||
$allowMultipleSelections = false
|
||||
);
|
||||
if ($tmp === RoleEnum::conceptor->name) {
|
||||
if ($tmp === Str::ucFirst(RoleEnum::conceptor->label())) {
|
||||
$tmp = RoleEnum::conceptor;
|
||||
}
|
||||
if ($tmp === RoleEnum::admin->name) {
|
||||
if ($tmp === Str::ucFirst(RoleEnum::admin->label())) {
|
||||
$tmp = RoleEnum::admin;
|
||||
}
|
||||
if ($tmp === RoleEnum::visitor->name) {
|
||||
if ($tmp === Str::ucFirst(RoleEnum::visitor->label())) {
|
||||
$tmp = RoleEnum::visitor;
|
||||
}
|
||||
$validator = Validator::make(['role' => $tmp], [
|
||||
|
|
@ -221,7 +226,7 @@ class UserCreate extends Command
|
|||
$this->role = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please choose from the selection',
|
||||
'Please choose from the selection %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ enum ActivityLogsEventEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::created->name => 'Création',
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ enum CkEditorConfigName: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::minimal->name => 'minimal',
|
||||
|
|
|
|||
|
|
@ -260,6 +260,8 @@ enum Country: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::afghanistan->name => 'Afghanistan',
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ enum PageSectionEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::home_missions->name => 'Nos Missions',
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ enum SpeciesEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::chicken->name => 'Poulet',
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ enum SliderTypeEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::home->name => 'Accueil',
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ enum StaticPageType: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::contact->name => 'Contact',
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ enum PictoEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::danger->name => 'Danger',
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ enum TypeEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::breeding->name => 'Elever Durablement',
|
||||
|
|
|
|||
|
|
@ -13,9 +13,11 @@ enum BootstrapThemeEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::light->name => 'Light',
|
||||
self::dark->name => 'Dark',
|
||||
self::light->name => 'enums.bootstrap-theme.light',
|
||||
self::dark->name => 'enums.bootstrap-theme.dark',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@ enum RoleEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::conceptor->name => 'Concepteur',
|
||||
self::admin->name => 'Administrateur',
|
||||
self::visitor->name => 'Visiteur',
|
||||
self::conceptor->name => 'enums.user-role.conceptor',
|
||||
self::admin->name => 'enums.user-role.admin',
|
||||
self::visitor->name => 'enums.user-role.visitor',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class ActivityLogController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\ActivityLog $activity_log
|
||||
* @param \App\Models\ActivityLog $activity_log
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(ActivityLog $activity_log): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class HistoricalMilestoneController extends Controller
|
|||
$historicalMilestoneModels = HistoricalMilestone::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$historicalMilestoneModels,
|
||||
|
|
@ -74,7 +74,7 @@ class HistoricalMilestoneController extends Controller
|
|||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\HistoricalMilestone\StoreHistoricalMilestoneRequest $request
|
||||
* @param \App\Http\Requests\Bo\HistoricalMilestones\StoreHistoricalMilestoneRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreHistoricalMilestoneRequest $request): \Illuminate\Http\RedirectResponse
|
||||
|
|
@ -86,12 +86,12 @@ class HistoricalMilestoneController extends Controller
|
|||
if ($historicalMilestone->saveOrFail()) {
|
||||
return redirect()->route('bo.historicalmilestones.edit', $historicalMilestone)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ class HistoricalMilestoneController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\HistoricalMilestone $historicalMilestone
|
||||
* @param \App\Models\HistoricalMilestone $historicalMilestone
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(HistoricalMilestone $historicalMilestone): \Illuminate\Contracts\View\View
|
||||
|
|
@ -110,8 +110,8 @@ class HistoricalMilestoneController extends Controller
|
|||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\HistoricalMilestone\UpdateHistoricalMilestoneRequest $request
|
||||
* @param \App\Models\HistoricalMilestone $historicalMilestone
|
||||
* @param \App\Http\Requests\Bo\HistoricalMilestones\UpdateHistoricalMilestoneRequest $request
|
||||
* @param \App\Models\HistoricalMilestone $historicalMilestone
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(
|
||||
|
|
@ -124,12 +124,12 @@ class HistoricalMilestoneController extends Controller
|
|||
if ($historicalMilestone->saveOrFail()) {
|
||||
return redirect()->route('bo.historicalmilestones.edit', $historicalMilestone)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.historicalmilestones.edit', $historicalMilestone)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
|
@ -145,12 +145,12 @@ class HistoricalMilestoneController extends Controller
|
|||
if ($historicalMilestone->deleteOrFail()) {
|
||||
return redirect()->route('bo.historicalmilestones.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.historicalMilestone', 1))
|
||||
]));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class JobVideoController extends Controller
|
|||
$jobVideoModels = JobVideo::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
$search = $request->search;
|
||||
$search = $request->input('search');
|
||||
if ($search) {
|
||||
$this->searchQuery(
|
||||
$jobVideoModels,
|
||||
|
|
@ -86,12 +86,12 @@ class JobVideoController extends Controller
|
|||
if ($jobVideo->saveOrFail()) {
|
||||
return redirect()->route('bo.jobvideos.edit', $jobVideo)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ class JobVideoController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\JobVideo $jobVideo
|
||||
* @param \App\Models\JobVideo $jobVideo
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(JobVideo $jobVideo): \Illuminate\Contracts\View\View
|
||||
|
|
@ -124,12 +124,12 @@ class JobVideoController extends Controller
|
|||
if ($jobVideo->saveOrFail()) {
|
||||
return redirect()->route('bo.jobvideos.edit', $jobVideo)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.jobvideos.edit', $jobVideo)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', 1))
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
|
@ -145,12 +145,12 @@ class JobVideoController extends Controller
|
|||
if ($jobVideo->deleteOrFail()) {
|
||||
return redirect()->route('bo.jobvideos.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', 1))
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', '1'))
|
||||
'model' => Str::ucfirst(trans_choice('models.classes.job_video', 1))
|
||||
]));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class LogoController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\Logo $logo
|
||||
* @param \App\Models\Logo $logo
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Logo $logo): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class NewsController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\News $news
|
||||
* @param \App\Models\News $news
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(News $news): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class SectionController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\Section $section
|
||||
* @param \App\Models\Section $section
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Section $section): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ class SiteController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\Site $site
|
||||
* @param \App\Models\Site $site
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Site $site): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ class SlideController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\Slide $slide
|
||||
* @param \App\Models\Slide $slide
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Slide $slide): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ class StaticPageController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\StaticPage $static_page
|
||||
* @param \App\Models\StaticPage $static_page
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(StaticPage $static_page): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ class StripController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\Strip $strip
|
||||
* @param \App\Models\Strip $strip
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Strip $strip): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ class TestimonialController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\Testimonial $testimonial
|
||||
* @param \App\Models\Testimonial $testimonial
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Testimonial $testimonial): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@ class UserController extends Controller
|
|||
return view('bo.pages.users.index', compact('userModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
|
|
@ -103,7 +102,7 @@ class UserController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param App\Models\User $user
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(User $user): \Illuminate\Contracts\View\View
|
||||
|
|
@ -144,8 +143,11 @@ class UserController extends Controller
|
|||
*/
|
||||
public function destroy(User $user): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var array<string,string> */
|
||||
$previousQueries = [];
|
||||
\parse_str(\parse_url(url()->previous(), \PHP_URL_QUERY), $previousQueries);
|
||||
if ($user->deleteOrFail()) {
|
||||
return redirect()->route('bo.users.index')
|
||||
return redirect()->route('bo.users.index', $previousQueries)
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class Controller extends BaseController
|
|||
return $query;
|
||||
}
|
||||
// Get models with relation's name/label.
|
||||
if (Str::endsWith($field, '_id') && $query->getModel()->has(Str::remove('_id', $field))) {
|
||||
if (Str::endsWith($field, '_id')) {
|
||||
$query->orWhereHas(Str::remove('_id', $field), function ($queryRelation) use ($field, $search) {
|
||||
if (Schema::hasColumn(Str::remove('_id', $field) . 's', 'name')) {
|
||||
$queryRelation->where('name', 'like', '%' . $search . '%');
|
||||
|
|
@ -122,12 +122,15 @@ class Controller extends BaseController
|
|||
*/
|
||||
protected function getSearchValue(Builder $query, string $search, string $field): string|array
|
||||
{
|
||||
$cast = $query->getModel()->getCasts()[$field] ?? null;
|
||||
if (
|
||||
count($query->getModel()->getCasts()) and // Check if the model has casts.
|
||||
isset($query->getModel()->getCasts()[$field]) and // Check if there is cast about specific field.
|
||||
enum_exists($query->getModel()->getCasts()[$field]) // Check if the cast is an enum.
|
||||
$cast and // Check if there is cast about specific field.
|
||||
enum_exists($cast) // Check if the cast is an enum.
|
||||
) {
|
||||
$cases = collect($query->getModel()->getCasts()[$field]::toArray());
|
||||
/** @var \App\Traits\Enums $cast */
|
||||
// @phpstan-ignore-next-line
|
||||
$cases = collect($cast::toArray());
|
||||
$enum = $cases->filter(function ($item) use ($search) {
|
||||
return preg_match('/' . Str::lower($search) . '/', Str::lower($item->label));
|
||||
});
|
||||
|
|
@ -148,12 +151,12 @@ class Controller extends BaseController
|
|||
{
|
||||
$rName = request()->route()->getName();
|
||||
$table = $query->getModel()->getTable();
|
||||
if (request()->sort_col) {
|
||||
Session::put("$rName.sort_col", request()->sort_col);
|
||||
if (request()->input('sort_col')) {
|
||||
Session::put("$rName.sort_col", request()->input('sort_col'));
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->sort_way) {
|
||||
Session::put("$rName.sort_way", request()->sort_way);
|
||||
if (request()->input('sort_way')) {
|
||||
Session::put("$rName.sort_way", request()->input('sort_way'));
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->rst) {
|
||||
|
|
@ -161,12 +164,16 @@ class Controller extends BaseController
|
|||
Session::remove("$rName.sort_col");
|
||||
Session::remove("$rName.sort_way");
|
||||
}
|
||||
if (request()->sort_col and request()->sort_way and Schema::hasColumn($table, request()->sort_col)) {
|
||||
if (
|
||||
!isset($ignore) or
|
||||
(isset($ignore) and !in_array(request()->sort_col, $ignore))
|
||||
) {
|
||||
$query = $query->orderBy(\sprintf("$table.%s", request()->sort_col), request()->sort_way);
|
||||
if (
|
||||
request()->input('sort_col') and
|
||||
request()->input('sort_way') and
|
||||
Schema::hasColumn($table, request()->input('sort_col'))
|
||||
) {
|
||||
if (!in_array(request()->input('sort_col'), $ignore)) {
|
||||
$query = $query->orderBy(
|
||||
\sprintf("$table.%s", request()->input('sort_col')),
|
||||
request()->input('sort_way')
|
||||
);
|
||||
}
|
||||
} elseif (Schema::hasColumn($table, 'order')) {
|
||||
$query = $query->orderBy('order', 'ASC');
|
||||
|
|
|
|||
|
|
@ -54,16 +54,16 @@ class Kernel extends HttpKernel
|
|||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,18 +53,21 @@ class SecureHeaders
|
|||
"default-src 'none';",
|
||||
"manifest-src 'self';",
|
||||
// * CKEDITOR Specific https://ckeditor.com/docs/ckeditor5/latest/installation/advanced/csp.html
|
||||
"connect-src 'self' " . implode(' ', [
|
||||
"connect-src 'self' blob: " . implode(' ', [
|
||||
// * VITE DEV
|
||||
config('app.debug') ? "wss://{$host}:4443" : '',
|
||||
config('app.debug') ? "https://{$host}:4443" : '',
|
||||
'https://yl.s-web.fr'
|
||||
]) . ';',
|
||||
"img-src * data: blob:;",
|
||||
'frame-src ' . implode(' ', [
|
||||
'\'self\'',
|
||||
"img-src 'self' data: blob: " . implode(' ', [
|
||||
// * VITE DEV
|
||||
config('app.debug') ? "https://{$host}:4443" : '',
|
||||
]) . ';',
|
||||
"object-src 'self' " . implode(' ', []) . ';',
|
||||
"frame-src 'self' " . implode(' ', [
|
||||
'https://www.google.com/recaptcha/',
|
||||
'https://recaptcha.google.com/recaptcha/',
|
||||
'https://www.google.com/maps/',
|
||||
'https://www.youtube.com',
|
||||
'https://www.google.com/maps/'
|
||||
]) . ';',
|
||||
"font-src 'self' data: " . \implode(' ', [
|
||||
// * VITE DEV
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ class TrustProxies extends Middleware
|
|||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* ! Added * as tmp Fix for #13
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
protected $proxies = '*';
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
|
|
@ -20,7 +22,7 @@ class TrustProxies extends Middleware
|
|||
* @var integer
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ class StoreHistoricalMilestoneRequest extends FormRequest
|
|||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'button_status' => $this->button_status ? true : false,
|
||||
'button_new_tab' => $this->button_new_tab ? true : false
|
||||
'button_status' => $this->boolean('button_status'),
|
||||
'button_new_tab' => $this->boolean('button_new_tab')
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
|
|
@ -54,8 +54,7 @@ class StoreHistoricalMilestoneRequest extends FormRequest
|
|||
|
||||
return \array_merge(
|
||||
$rules,
|
||||
// FIXME: Mettre à jour les tailles.
|
||||
$this->pictureRules('picture', 100, 100, 100, 100, null, false),
|
||||
$this->pictureRules('picture', 606, 800, 606, 800, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,8 +44,7 @@ class StoreLogoRequest extends FormRequest
|
|||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
// FIXME: Mettre à jour les tailles.
|
||||
$this->pictureRules('picture', 100, 100, 100, 100, null, false),
|
||||
$this->pictureRules('picture', 331, 240, 331, 100, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ class StoreNewsRequest extends FormRequest
|
|||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->published ? true : false
|
||||
'published' => $this->boolean('published')
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
$this->mergePicture('thumbnail');
|
||||
|
|
|
|||
|
|
@ -33,16 +33,20 @@ class UpdateSectionRequest extends UpdateMiniCrudRequest
|
|||
$rules = [
|
||||
'h2_title' => 'required|between:3,255',
|
||||
];
|
||||
if ($this->route('section')->section !== \app\Enums\Sections\PageSectionEnum::hire_grow) {
|
||||
$rules = \array_merge($rules, [
|
||||
'text' => 'present',
|
||||
]);
|
||||
}
|
||||
if ($this->route('section')->section->containsData()) {
|
||||
$rules = \array_merge($rules, [
|
||||
'data' => 'present|array',
|
||||
'data.*' => 'required|array',
|
||||
]);
|
||||
/** @var \App\Models\Section|null $section */
|
||||
$section = $this->route('section');
|
||||
if ($section) {
|
||||
if ($section->section !== \App\Enums\Sections\PageSectionEnum::hire_grow) {
|
||||
$rules = \array_merge($rules, [
|
||||
'text' => 'present',
|
||||
]);
|
||||
}
|
||||
if ($section->section->containsData()) {
|
||||
$rules = \array_merge($rules, [
|
||||
'data' => 'present|array',
|
||||
'data.*' => 'required|array',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return \array_merge(
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ class StoreSiteRequest extends FormRequest
|
|||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->published ? true : false,
|
||||
'pictos' => \collect($this->pictos)->all(),
|
||||
'published' => $this->boolean('published'),
|
||||
'pictos' => \collect($this->input('pictos'))->all(),
|
||||
]);
|
||||
$this->mergePicture('logo');
|
||||
$this->mergePicture('picture_1');
|
||||
|
|
@ -84,11 +84,11 @@ class StoreSiteRequest extends FormRequest
|
|||
return \array_merge(
|
||||
$rules,
|
||||
// FIXME: Mettre à jour les tailles.
|
||||
$this->pictureRules('logo', 100, 100, 100, 100, null, false),
|
||||
$this->pictureRules('picture_1', 100, 100, 100, 100, null, false),
|
||||
$this->pictureRules('picture_2', 100, 100, 100, 100, null, true),
|
||||
$this->pictureRules('picture_3', 100, 100, 100, 100, null, true),
|
||||
$this->pictureRules('map_picture', 100, 100, 100, 100, null, false),
|
||||
$this->pictureRules('logo', 100, 100, 100, 100, false),
|
||||
$this->pictureRules('picture_1', 100, 100, 100, 100, false),
|
||||
$this->pictureRules('picture_2', 100, 100, 100, 100, true),
|
||||
$this->pictureRules('picture_3', 100, 100, 100, 100, true),
|
||||
$this->pictureRules('map_picture', 100, 100, 100, 100, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ class StoreSlideRequest extends FormRequest
|
|||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'button_status' => $this->button_status ? true : false,
|
||||
'button_new_tab' => $this->button_new_tab ? true : false
|
||||
'button_status' => $this->boolean('button_status'),
|
||||
'button_new_tab' => $this->boolean('button_new_tab')
|
||||
]);
|
||||
if (intval($this->slider) !== \App\Enums\Slides\SliderTypeEnum::home->value()) {
|
||||
$this->merge([
|
||||
|
|
@ -69,7 +69,7 @@ class StoreSlideRequest extends FormRequest
|
|||
return \array_merge(
|
||||
$rules,
|
||||
// FIXME: Mettre à jour les tailles.
|
||||
$this->pictureRules('picture', 100, 100, 100, 100, null, false),
|
||||
$this->pictureRules('picture', 100, 100, 100, 100, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
namespace App\Http\Requests\Bo\StaticPages;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UpdateStaticPageRequest extends FormRequest
|
||||
|
|
@ -14,7 +15,7 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
return Gate::check('update', $this->route('static_page'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -25,7 +26,7 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'content' => (string)Str::of($this->post('content'))
|
||||
'content' => Str::of($this->input('content'))->value()
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -37,10 +38,25 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_title' => 'required|min:45|max:70',
|
||||
'seo_description' => 'required|min:50|max:160',
|
||||
'title' => 'required|min:3|max:255',
|
||||
'content' => 'present',
|
||||
'title' => 'required|min:3|max:255',
|
||||
'content' => 'present',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'seo_title' => trans('validation.custom.seo_title'),
|
||||
'seo_description' => trans('validation.custom.seo_description'),
|
||||
'title' => trans('validation.attributes.title'),
|
||||
'content' => trans('validation.attributes.content'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class StoreStripRequest extends FormRequest
|
|||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->published ? true : false,
|
||||
'published' => $this->boolean('published'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -49,9 +49,8 @@ class StoreStripRequest extends FormRequest
|
|||
'required',
|
||||
'string',
|
||||
'min:3',
|
||||
// phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function (string $attribute, mixed $value, \Closure $fail) {
|
||||
// phpcs:enable
|
||||
if (Str::wordCount(\strip_tags($value)) > 255) {
|
||||
$fail(trans('validation.max_words', [
|
||||
'attribute' => trans('validation.attributes.text'),
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class StoreTestimonialRequest extends FormRequest
|
|||
return \array_merge(
|
||||
$rules,
|
||||
// FIXME: Mettre à jour les tailles.
|
||||
$this->pictureRules('picture', 100, 100, 100, 100, null, false),
|
||||
$this->pictureRules('picture', 100, 100, 100, 100, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ class UpdateChangeOrderRequest extends FormRequest
|
|||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'direction' => $this->direction === 'up' ? true : false
|
||||
'direction' => $this->route('direction') === 'up' ? true : false
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,40 +21,19 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
foreach ($this->{$this->modelName}->data as $iptName => $input) {
|
||||
$input = \json_decode(\json_encode($input), true);
|
||||
switch ($input['inputType']) {
|
||||
case InputType::text->value:
|
||||
if (is_null($this->data[$iptName]['value']) && !$input['required']) {
|
||||
$this->merge([
|
||||
$this->data[$iptName]['value'] => ''
|
||||
]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
* @phpcs:disable Generic.Metrics.NestingLevel.TooHigh
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
// phpcs:enable
|
||||
$rules = [];
|
||||
|
|
@ -89,8 +68,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
]);
|
||||
break;
|
||||
case InputType::text->value:
|
||||
$required = $input['required'] ? 'required' : 'nullable';
|
||||
$mergeRules = $this->compileValidate($required . '|string|min:15', $input);
|
||||
$mergeRules = $this->compileValidate('required|string|min:15', $input);
|
||||
$mergeRules = collect($mergeRules)
|
||||
->map(function ($rule) {
|
||||
if (\strpos($rule, 'max:') !== false) {
|
||||
|
|
@ -109,10 +87,9 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
break;
|
||||
case InputType::image->value:
|
||||
$required = $this->isUpdate() ? 'sometimes' : 'required';
|
||||
|
||||
$ipt = $this->data[$iptName];
|
||||
$max = isset($ipt['dimensionsMax']);
|
||||
$dim = \is_string($input['dimensions']) ? collect(explode(
|
||||
$ipt = $this->data[$iptName];
|
||||
$max = isset($ipt['dimensionsMax']);
|
||||
$dim = \is_string($input['dimensions']) ? collect(explode(
|
||||
',',
|
||||
(isset($ipt['dimensionsMax']) and is_string($ipt['dimensionsMax'])) ?
|
||||
$ipt['dimensionsMax'] : $input['dimensions']
|
||||
|
|
@ -125,17 +102,13 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
$sizes = (object)[
|
||||
'minHeight' => $dim['height'],
|
||||
'maxHeight' => $dim['height'],
|
||||
'minWith' => $dim['width'],
|
||||
'maxWith' => $dim['width'],
|
||||
'minWidth' => $dim['width'],
|
||||
'maxWidth' => $dim['width'],
|
||||
];
|
||||
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => [
|
||||
function (string $attribute, $value, callable $fail) use ($sizes, $input) {
|
||||
// Picture can be null.
|
||||
if ($input['required'] || $value !== null) {
|
||||
return ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
|
||||
}
|
||||
function (string $attribute, $value, callable $fail) use ($sizes) {
|
||||
ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
|
||||
}
|
||||
],
|
||||
$this->compileValidate(
|
||||
|
|
@ -153,13 +126,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
|
|||
]),
|
||||
$input
|
||||
),
|
||||
]);
|
||||
|
||||
// Attributes are required if a picture is set.
|
||||
$required = $this->data['bloc_image']['value'] ? 'required' : 'nullable';
|
||||
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.alt" => $this->compileValidate("$required|string|min:5", $input),
|
||||
"data.$iptName.alt" => $this->compileValidate("$required|string|min:5", $input),
|
||||
"data.$iptName.title" => $this->compileValidate("$required|string|min:5", $input)
|
||||
]);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
namespace App\Http\Requests\Bo\Users;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
|
|
@ -16,7 +18,7 @@ class StoreUserRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('backend')->check();
|
||||
return Gate::check('create', User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -24,10 +26,10 @@ class StoreUserRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->published ? true : false
|
||||
'published' => $this->boolean('published')
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -40,9 +42,9 @@ class StoreUserRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'first_name' => 'required|string|min:3|max:255',
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'password' => [
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
|
|
@ -50,8 +52,8 @@ class StoreUserRequest extends FormRequest
|
|||
->symbols()
|
||||
->uncompromised()
|
||||
],
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'published' => 'required|boolean',
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'published' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -64,11 +66,11 @@ class StoreUserRequest extends FormRequest
|
|||
{
|
||||
return [
|
||||
'first_name' => trans('validation.attributes.first_name'),
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'password' => trans('validation.attributes.password'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication')
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'password' => trans('validation.attributes.password'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,23 +2,35 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Users;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
class UpdateUserRequest extends StoreUserRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('update', $this->route('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation()
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->published ? true : false,
|
||||
'password' => $this->password ? $this->password : $this->route('user')->password,
|
||||
'password_confirmation' => $this->password_confirmation ?
|
||||
$this->password_confirmation :
|
||||
$this->route('user')->password
|
||||
'published' => $this->boolean('published'),
|
||||
'password' => $this->input('password') ??
|
||||
\optional($this->route('user'))->password,
|
||||
'password_confirmation' => $this->input('password_confirmation') ??
|
||||
\optional($this->route('user'))->password
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -30,10 +42,10 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return array_merge(parent::rules(), [
|
||||
'email' => [
|
||||
'email' => [
|
||||
'required',
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
'unique:users,email,' . $this->route('user')->id . ',id',
|
||||
Rule::unique('users', 'email')->ignore(\optional($this->route('user'))->getRouteKey())
|
||||
],
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ class ExceptionsHelper
|
|||
$traceStr .= self::handleArgs($stack);
|
||||
}
|
||||
$traceStr .= ")\n";
|
||||
} elseif (isset($stack['function'])) {
|
||||
} else {
|
||||
$traceStr .= "{$stack['function']}(";
|
||||
if (isset($stack['args'])) {
|
||||
$traceStr .= self::handleArgs($stack);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,20 @@ use Illuminate\Support\Str;
|
|||
*/
|
||||
class FileStorageHelper
|
||||
{
|
||||
/**
|
||||
* Remove all files from string attribute html that are stored in public
|
||||
*
|
||||
* @param string $publicStorageFilePath The file path from public directory.
|
||||
* @return string The local storage path.
|
||||
*/
|
||||
public static function getFileFullPath(string $publicStorageFilePath): string
|
||||
{
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
$disk = Storage::disk('uploads');
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
return $disk->path($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the file associate with the attribute.
|
||||
*
|
||||
|
|
@ -308,8 +322,7 @@ class FileStorageHelper
|
|||
$folderPath = self::getStoragePath(
|
||||
$private ? 'app/private/modelfiles' : 'app/public/modelfiles',
|
||||
$tableName,
|
||||
$filename,
|
||||
$private
|
||||
$filename
|
||||
);
|
||||
$filename = self::getFileUniqueName($folderPath, $filename);
|
||||
return "{$folderPath}/{$filename}";
|
||||
|
|
@ -404,7 +417,7 @@ class FileStorageHelper
|
|||
$filename = Str::of($filename)->ltrim('.-');
|
||||
// * Optional beautification
|
||||
if ($beautify) {
|
||||
$filename = static::beautifyFilename($filename);
|
||||
$filename = self::beautifyFilename($filename);
|
||||
}
|
||||
// * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
||||
/** @var string */
|
||||
|
|
|
|||
|
|
@ -21,6 +21,36 @@ use Symfony\Component\Finder\SplFileInfo;
|
|||
|
||||
class ToolboxHelper
|
||||
{
|
||||
/**
|
||||
* Run a terminal command and gives the output
|
||||
*
|
||||
* @param array|string $command The command to execute on terminal.
|
||||
* @param boolean $throw Wether to throw en esception on failure or not.
|
||||
* @return string|false Return false on failure only if $throw is false.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
* @throws \Illuminate\Process\Exceptions\ProcessTimedOutException
|
||||
* @throws \Symfony\Component\Process\Exception\LogicException
|
||||
* @throws \Symfony\Component\Process\Exception\InvalidArgumentException
|
||||
* @throws \Symfony\Component\Process\Exception\RuntimeException
|
||||
* @throws \LogicException
|
||||
* @throws \RuntimeException If the command fails.
|
||||
*/
|
||||
public static function runConsoleCommand(array|string $command, bool $throw = true): string | false
|
||||
{
|
||||
// phpcs:enable
|
||||
$process = \Illuminate\Support\Facades\Process::command($command)->run();
|
||||
if ($process->failed()) {
|
||||
$code = $process->exitCode();
|
||||
$ouput = $process->errorOutput();
|
||||
if ($throw) {
|
||||
throw new \RuntimeException("Failed to run command exit code {$code} with output \n{$ouput}");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return $process->output();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int|string, mixed> $array1
|
||||
* @param array<int|string, mixed> $array2
|
||||
|
|
@ -175,11 +205,10 @@ class ToolboxHelper
|
|||
$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)
|
||||
) {
|
||||
// Assert route matches existing routes.
|
||||
$routes->match($request);
|
||||
// ? Is url internal ?
|
||||
if (\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST)) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => trans(
|
||||
|
|
@ -205,14 +234,14 @@ class ToolboxHelper
|
|||
* @param array|string $replace
|
||||
* @param array|string $subject
|
||||
* @param integer $count
|
||||
* @return array|string
|
||||
* @return array|string|false
|
||||
*/
|
||||
public static function mbReplace(
|
||||
array|string $search,
|
||||
array|string $replace,
|
||||
array|string $subject,
|
||||
int &$count = 0
|
||||
): array|string {
|
||||
): array|string|false {
|
||||
if (!is_array($search) && is_array($replace)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -288,10 +317,17 @@ class ToolboxHelper
|
|||
*/
|
||||
public static function getOriginal(Model $model, string $attribute): mixed
|
||||
{
|
||||
if (\in_array('Spatie\Translatable\HasTranslations', \class_uses_recursive($model))) {
|
||||
if (
|
||||
\in_array('Spatie\Translatable\HasTranslations', \class_uses_recursive($model)) and
|
||||
// @phpstan-ignore-next-line
|
||||
$model->isTranslatableAttribute($attribute)
|
||||
) {
|
||||
// @phpstan-ignore-next-line
|
||||
return $model->getTranslation(
|
||||
$attribute,
|
||||
// @phpstan-ignore-next-line
|
||||
$model->getLocale(),
|
||||
// @phpstan-ignore-next-line
|
||||
$model->useFallbackLocale()
|
||||
);
|
||||
}
|
||||
|
|
@ -361,47 +397,45 @@ class ToolboxHelper
|
|||
/**
|
||||
* Convert deeply an object to array
|
||||
*
|
||||
* @param array|object $input
|
||||
* @param mixed $input
|
||||
* @return array
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function objectToArray($input): array
|
||||
public static function objectToArray(mixed $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 {
|
||||
if (!(is_object($input) or is_array($input))) {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$ret = (array)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::objectToArray($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an array to object
|
||||
*
|
||||
* @param array|object $input
|
||||
* @param mixed $input
|
||||
* @return object
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function arrayToObject($input): object
|
||||
public static function arrayToObject(mixed $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 {
|
||||
if (!(is_object($input) or is_array($input))) {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$ret = (object)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::arrayToObject($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -409,11 +443,11 @@ class ToolboxHelper
|
|||
*
|
||||
* @param string $attribute
|
||||
* @param string|null $value
|
||||
* @param callback $fail
|
||||
* @param callable $fail
|
||||
* @param object $sizes
|
||||
* @return void
|
||||
*/
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes)
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes): void
|
||||
{
|
||||
if (!($useStorage = Storage::exists($value)) and !File::exists($value)) {
|
||||
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
||||
|
|
@ -421,7 +455,6 @@ class ToolboxHelper
|
|||
]));
|
||||
return;
|
||||
}
|
||||
/** @var string */
|
||||
$fileFullPath = self::getUploadedFileFullPath($value, $useStorage);
|
||||
if (
|
||||
!\in_array(self::getUploadedFileMimeType($value, $useStorage), [
|
||||
|
|
@ -432,7 +465,7 @@ class ToolboxHelper
|
|||
'attribute' => $attribute
|
||||
]));
|
||||
}
|
||||
if (!($dimensions = \getimagesize($fileFullPath)) or !isset($dimensions[0]) or !isset($dimensions[1])) {
|
||||
if (!($dimensions = \getimagesize($fileFullPath))) {
|
||||
$fail(trans(':attribute impossible de valider les dimensions', [
|
||||
'attribute' => $attribute
|
||||
]));
|
||||
|
|
@ -441,19 +474,19 @@ class ToolboxHelper
|
|||
$height = intval($dimensions[1]);
|
||||
|
||||
$xMessage = trans(
|
||||
":attribute la largeur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px"
|
||||
":attribute la largeur doit être comprise entre {$sizes->minWidth}px et {$sizes->maxWidth}px"
|
||||
);
|
||||
if ($sizes->minWith === $sizes->maxWith) {
|
||||
$xMessage = trans(":attribute la largeur doit être de {$sizes->minWith}px");
|
||||
if ($sizes->minWidth === $sizes->maxWidth) {
|
||||
$xMessage = trans(":attribute la largeur doit être de {$sizes->minWidth}px");
|
||||
}
|
||||
$yMessage = trans(
|
||||
":attribute la hauteur doit être comprise entre {$sizes->minWith}px et {$sizes->maxWith}px"
|
||||
":attribute la hauteur doit être comprise entre {$sizes->minHeight}px et {$sizes->maxHeight}px"
|
||||
);
|
||||
if ($sizes->minHeight === $sizes->maxHeight) {
|
||||
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minWith}px");
|
||||
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minHeight}px");
|
||||
}
|
||||
|
||||
if (($width < $sizes->minWith) or ($width > $sizes->maxWith)) {
|
||||
if (($width < $sizes->minWidth) or ($width > $sizes->maxWidth)) {
|
||||
$fail($xMessage);
|
||||
}
|
||||
if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) {
|
||||
|
|
|
|||
|
|
@ -3,18 +3,17 @@
|
|||
namespace App\Models;
|
||||
|
||||
use App\Enums\ActivityLogs\ActivityLogsEventEnum;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property string $model Target model.
|
||||
* @property string $model_id Id of the target model.
|
||||
* @property string $event Event of this activity (ActivityLogsEventEnum).
|
||||
* @property string $data Changes.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property string $model Target model.
|
||||
* @property string $model_id Id of the target model.
|
||||
* @property \App\Enums\ActivityLogs\ActivityLogsEventEnum $event Event of this activity (ActivityLogsEventEnum).
|
||||
* @property array $data Changes.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
*
|
||||
* @property-read \App\Models\User $user User BelongsTo relation.
|
||||
*/
|
||||
|
|
@ -82,37 +81,88 @@ class ActivityLog extends Model
|
|||
$activity->model_id = $model->getKey();
|
||||
$activity->event = $eventEnum;
|
||||
$activity->data = static::getChangedColumns($activity, $model, $eventEnum);
|
||||
$activity->created_at = Carbon::now();
|
||||
// @phpstan-ignore-next-line
|
||||
$activity->created_at = now();
|
||||
$activity->saveOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get old, new columns that has changed.
|
||||
*
|
||||
* @param \self $activity
|
||||
* @param self $activity
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param \App\Enums\ActivityLogs\ActivityLogsEventEnum $eventEnum
|
||||
* @return array|null
|
||||
* @return array
|
||||
*/
|
||||
public static function getChangedColumns(self $activity, Model $model, ActivityLogsEventEnum $eventEnum): array|null
|
||||
public static function getChangedColumns(self $activity, Model $model, ActivityLogsEventEnum $eventEnum): array
|
||||
{
|
||||
$modelClassName = $activity->model_class;
|
||||
/** Get type of each fields of the target model */
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null $targetModel */
|
||||
$targetModel = $activity->model_class::where(
|
||||
(new $modelClassName())->getRouteKeyName(),
|
||||
$activity->model_id
|
||||
)->first();
|
||||
if ($targetModel != null) {
|
||||
// phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
$targetModelTypes = collect($targetModel->toArray())
|
||||
->map(function ($field, $fieldIndex) use ($targetModel) {
|
||||
return Schema::getColumnType($targetModel->getTable(), $fieldIndex);
|
||||
})->toArray();
|
||||
// phpcs:enable
|
||||
|
||||
if (\is_null($targetModel)) {
|
||||
return [];
|
||||
}
|
||||
$targetModelTypes = collect($targetModel->toArray())
|
||||
->map(fn ($value) => self::getValueType($value))
|
||||
->toArray();
|
||||
/** Return old, new and type of values changed */
|
||||
return ($eventEnum === ActivityLogsEventEnum::updated) ?
|
||||
array_intersect_key($targetModelTypes, $model->getChanges()) : null;
|
||||
return match ($eventEnum) {
|
||||
ActivityLogsEventEnum::created => array_intersect_key($targetModelTypes, $model->toArray()),
|
||||
ActivityLogsEventEnum::duplicated => array_intersect_key($targetModelTypes, $model->toArray()),
|
||||
ActivityLogsEventEnum::updated => array_intersect_key($targetModelTypes, $model->getChanges()),
|
||||
default => []
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a value type as a string
|
||||
* ! Use this for display purpose only
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
* @throws \RuntimeException If type is unhlanded.
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
|
||||
*/
|
||||
private static function getValueType(mixed $value): string
|
||||
{
|
||||
// phpcs:enable
|
||||
$type = \gettype($value);
|
||||
switch ($type) {
|
||||
// phpcs:ignore PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
|
||||
case 'string':
|
||||
return match (true) {
|
||||
Str::length(\strip_tags($value)) !== Str::length($value) => 'html',
|
||||
Str::startsWith($value, 'storage/modelfiles') => 'file',
|
||||
Str::isUuid($value) => 'uuid',
|
||||
Str::isUlid($value) => 'ulid',
|
||||
Str::isUrl($value) => 'url',
|
||||
Str::isMatch('/^[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]$/', $value) => 'youtube_video_id',
|
||||
\is_numeric($value) => 'numeric',
|
||||
Str::isJson($value) and
|
||||
(Str::startsWith($value, '[') or Str::startsWith($value, '{')) => 'json',
|
||||
default => 'string'
|
||||
};
|
||||
case 'NULL':
|
||||
case 'object':
|
||||
case 'array':
|
||||
case 'integer':
|
||||
case 'boolean':
|
||||
return $type;
|
||||
case 'double':
|
||||
return is_float($value) ? 'float' : 'double';
|
||||
case 'resource (closed)':
|
||||
case 'resource':
|
||||
throw new \RuntimeException('Laravel model properties should not contain resources !');
|
||||
case 'unknown type':
|
||||
default:
|
||||
throw new \RuntimeException('Unhandled Type ' . \gettype($value));
|
||||
} //end switch
|
||||
}
|
||||
|
||||
// * RELATIONS
|
||||
|
|
@ -122,7 +172,7 @@ class ActivityLog extends Model
|
|||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user()
|
||||
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,12 +12,12 @@ use Illuminate\Database\Eloquent\Model;
|
|||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* @property App\Enums\Sections\PageSectionEnum $section Slider that contains the slide.
|
||||
* @property string $h2_title Title.
|
||||
* @property string $text WYSIWYG - Content.
|
||||
* @property string $data Minicrud content.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
* @property \App\Enums\Sections\PageSectionEnum $section Slider that contains the slide.
|
||||
* @property string $h2_title Title.
|
||||
* @property string $text WYSIWYG - Content.
|
||||
* @property string $data Minicrud content.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\StaticPage $page StaticPage Belongs to relationship.
|
||||
|
||||
|
|
@ -83,17 +83,6 @@ class Section extends Model
|
|||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Manage model fields.
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function manageFields(self $model): void
|
||||
{
|
||||
$model->picture = FileStorageHelper::storeFile($model, $model->picture, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get MiniCrud bloc for home_missions section.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class Site extends Model
|
|||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'pictos' => 'array',
|
||||
|
|
@ -200,54 +200,6 @@ class Site extends Model
|
|||
ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts model status using current status and publish dates
|
||||
*
|
||||
* @param self $model
|
||||
* @return void
|
||||
*/
|
||||
private static function makeStatusSense(self $model): void
|
||||
{
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$publish_at = $model->publish_at;
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$unpublish_at = $model->unpublish_at;
|
||||
$wantedStatus = $model->published;
|
||||
if ($publish_at or $unpublish_at) {
|
||||
$model->published = $model->planificated_status;
|
||||
}
|
||||
if ($wantedStatus !== $model->published) {
|
||||
$previousMessage = session()->get('bo.info', '');
|
||||
session()->flash('bo.info', \trans(
|
||||
'La publication est modifiée en concordance avec les dates enregistrées.
|
||||
Pour modifier l\'état de publication, veuillez modifier ou enlever les dates correspondantes.'
|
||||
) . " \n{$previousMessage}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter the current status following planification dates planificated_status
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function getPlanificatedStatusAttribute(): bool
|
||||
{
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$publish_at = $this->publish_at;
|
||||
/** @var \Carbon\Carbon|null */
|
||||
$unpublish_at = $this->unpublish_at;
|
||||
if ($publish_at and $unpublish_at) {
|
||||
return $unpublish_at->greaterThanOrEqualTo(now()) and $publish_at->lessThan(now());
|
||||
}
|
||||
if ($publish_at) {
|
||||
return $publish_at->lessThan(now());
|
||||
}
|
||||
if ($unpublish_at) {
|
||||
return $unpublish_at->greaterThanOrEqualTo(now());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,20 +7,20 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property App\Enums\Slides\SliderTypeEnum $slider Slider that contains the slide.
|
||||
* @property string $title Title.
|
||||
* @property string $content WYSIWYG - Content.
|
||||
* @property string $video_id Id of the Youtube video.
|
||||
* @property boolean $button_status Is the button visible ?.
|
||||
* @property string $button_label Button label, max 35 chars.
|
||||
* Required if button_status == true.
|
||||
* @property string $button_url Button URL. equired if the button is visible.
|
||||
* @property boolean $button_new_tab Does the link need to be opened in a new tab ?
|
||||
* @property string $picture Path of the image.
|
||||
* @property string $picture_alt Alt attribute of the image.
|
||||
* @property string $picture_title Title attribute of the image.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
* @property \App\Enums\Slides\SliderTypeEnum $slider Slider that contains the slide.
|
||||
* @property string $title Title.
|
||||
* @property string $content WYSIWYG - Content.
|
||||
* @property string $video_id Id of the Youtube video.
|
||||
* @property boolean $button_status Is the button visible ?.
|
||||
* @property string $button_label Button label, max 35 chars.
|
||||
* Required if button_status == true.
|
||||
* @property string $button_url Button URL. equired if the button is visible.
|
||||
* @property boolean $button_new_tab Does the link need to be opened in a new tab ?
|
||||
* @property string $picture Path of the image.
|
||||
* @property string $picture_alt Alt attribute of the image.
|
||||
* @property string $picture_title Title attribute of the image.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class Slide extends Model
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@ use Illuminate\Support\Str;
|
|||
* @property string $title Title for the page.
|
||||
* @property string $slug Slug of the title for the page.
|
||||
* @property string $content WYSIWYG text content using ckeditor.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\Section $sections Sections Has Many relationship.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class StaticPage extends Model
|
||||
{
|
||||
|
|
@ -54,21 +52,48 @@ class StaticPage extends Model
|
|||
*/
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function () {
|
||||
throw new \RuntimeException("Creating a new page is not authorized");
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
static::creating(function (self $model) {
|
||||
// * ASSERTIONS
|
||||
static::assertTitleIsUnique($model->title, $model->id);
|
||||
self::assertTitleIsUnique($model->title);
|
||||
|
||||
// * CHANGES
|
||||
$model->slug = Str::slug($model->title);
|
||||
});
|
||||
static::deleting(function () {
|
||||
throw new \RuntimeException('Deleting a page is not authorized');
|
||||
static::updating(function (self $model) {
|
||||
// * ASSERTIONS
|
||||
self::assertTitleIsUnique($model->title, $model->id);
|
||||
|
||||
// * CHANGES
|
||||
$model->slug = Str::slug($model->title);
|
||||
});
|
||||
}
|
||||
|
||||
// * ROUTABLE
|
||||
|
||||
/**
|
||||
* Get the value of the model's route key.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRouteKey()
|
||||
{
|
||||
/** @var \App\Enums\StaticPageType */
|
||||
$enum = $this->getAttribute($this->getRouteKeyName());
|
||||
return $enum->value();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the route key for the model.
|
||||
*
|
||||
* ! Type is the routable parameter
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName(): string
|
||||
{
|
||||
return 'type';
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
|
|
@ -85,16 +110,4 @@ class StaticPage extends Model
|
|||
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id);
|
||||
}
|
||||
|
||||
// * RELATIONS
|
||||
|
||||
/**
|
||||
* Get the sections of the page.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function sections(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->hasMany(Section::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,15 +7,15 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property string $name Name of the person.
|
||||
* @property string $job Function of the person.
|
||||
* @property string $content WYSIWYG - Content.
|
||||
* @property App\Enums\Testimonial\TypeEnum $type Type of the testimonial.
|
||||
* @property string $picture Path of the image.
|
||||
* @property string $picture_alt Alt attribute of the image.
|
||||
* @property string $picture_title Title attribute of the image.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
* @property string $name Name of the person.
|
||||
* @property string $job Function of the person.
|
||||
* @property string $content WYSIWYG - Content.
|
||||
* @property \App\Enums\Testimonials\TypeEnum $type Type of the testimonial.
|
||||
* @property string $picture Path of the image.
|
||||
* @property string $picture_alt Alt attribute of the image.
|
||||
* @property string $picture_title Title attribute of the image.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class Testimonial extends Model
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,21 +4,22 @@ namespace App\Models;
|
|||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Traits\Models\ActivityLog;
|
||||
use Illuminate\Auth\Access\AuthorizationException;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
/**
|
||||
* @property string $first_name Prénom.
|
||||
* @property string $last_name Nom.
|
||||
* @property string $first_name Firstname.
|
||||
* @property string $last_name Lastname.
|
||||
* @property string $email Email.
|
||||
* @property string $password Mot de passe.
|
||||
* @property \App\Enums\Users\RoleEnum $role Rôle.
|
||||
* @property \Illuminate\Support\Carbon $published État de publication.
|
||||
* @property \Illuminate\Support\Carbon $published_at Date de mise à jour de l'état de publication.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
* @property string $password Password.
|
||||
* @property \App\Enums\Users\RoleEnum $role Role.
|
||||
* @property \Illuminate\Support\Carbon $published Published status.
|
||||
* @property \Illuminate\Support\Carbon $published_at Publication status update date.
|
||||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*
|
||||
* @property-read \App\Models\ActivityLog $activityLogs Activities logs One-to-many relationship.
|
||||
*/
|
||||
|
|
@ -62,6 +63,7 @@ class User extends Authenticatable
|
|||
'role' => RoleEnum::class,
|
||||
'email_verified_at' => 'datetime',
|
||||
'published' => 'boolean',
|
||||
'published_at' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -72,7 +74,7 @@ class User extends Authenticatable
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
static::updatePassword($model);
|
||||
self::updatePassword($model);
|
||||
// * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() > $model->role->value(),
|
||||
|
|
@ -80,12 +82,12 @@ class User extends Authenticatable
|
|||
);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
static::updatePassword($model);
|
||||
self::updatePassword($model);
|
||||
if (optional(auth('backend')->user())->getKey() === $model->getKey()) {
|
||||
\validator(
|
||||
['published' => $model->published],
|
||||
['published' => 'required|boolean|accepted'],
|
||||
['published.accepted' => trans('Vous ne pouvez pas déactiver votre propre compte')],
|
||||
['published.accepted' => trans('crud.messages.user_unpublished')],
|
||||
)->validate();
|
||||
}
|
||||
// * Prevent user elevation privileges
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\News;
|
||||
use App\Models\Strip;
|
||||
use App\Models\User;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
|
|
@ -44,8 +42,6 @@ class RouteServiceProvider extends ServiceProvider
|
|||
});
|
||||
|
||||
Route::model('user', User::class);
|
||||
Route::model('news', News::class);
|
||||
Route::model('strip', Strip::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
|
@ -18,33 +18,45 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
public function boot(): void
|
||||
{
|
||||
foreach ($this->collectLocalesStrings() as $locale) {
|
||||
// * Suported locales
|
||||
// * Suported locales.
|
||||
Cache::rememberForever(sprintf('translations.%s', $locale), function () use ($locale) {
|
||||
$translations = [
|
||||
'php' => $this->phpTranslations($locale),
|
||||
'json' => $this->jsonTranslations($locale),
|
||||
$phpTransFallback = $this->phpTranslations(config('app.fallback_locale'));
|
||||
$phpTransLocale = $this->phpTranslations($locale);
|
||||
$jsonTransFallback = $this->jsonTranslations(config('app.fallback_locale'));
|
||||
$jsonTransLocale = $this->jsonTranslations($locale);
|
||||
$translations = [
|
||||
'php' => ToolboxHelper::arrayMergeRecursiveDistinct(
|
||||
$phpTransFallback,
|
||||
$phpTransLocale,
|
||||
),
|
||||
'json' => ToolboxHelper::arrayMergeRecursiveDistinct(
|
||||
$jsonTransFallback,
|
||||
$jsonTransLocale,
|
||||
),
|
||||
];
|
||||
return $translations;
|
||||
});
|
||||
}
|
||||
} //end foreach
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather provided langs checking from files
|
||||
* Gather provided langs checking from files.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection<string, string>
|
||||
*/
|
||||
private function collectLocalesStrings(): Collection
|
||||
private function collectLocalesStrings(): \Illuminate\Support\Collection
|
||||
{
|
||||
// * En dur dans ->keys array<int,string>.
|
||||
// @phpstan-ignore-next-line
|
||||
return collect(File::allFiles(resource_path('lang/')))->flatMap(function (SplFileInfo $file) {
|
||||
if ($file->getRelativePath() and \strpos($file->getRelativePath(), 'vendor') !== 0) {
|
||||
return [$file->getRelativePath() => ''];
|
||||
}
|
||||
})->keys();
|
||||
})->keys()->merge(config('app.locales', []));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gather all php translations
|
||||
* Gather all php translations.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array<string, string>
|
||||
|
|
@ -53,6 +65,10 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
{
|
||||
$path = resource_path("lang/$locale");
|
||||
|
||||
if (!File::exists($path) or !File::isReadable($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return collect(File::allFiles($path))->flatMap(function ($file) use ($locale) {
|
||||
$translation = $file->getBasename('.php');
|
||||
return [$translation => trans($translation, [], $locale)];
|
||||
|
|
@ -60,7 +76,7 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
}
|
||||
|
||||
/**
|
||||
* Gather json translations
|
||||
* Gather json translations.
|
||||
*
|
||||
* @param string $locale
|
||||
* @return array<string, string>
|
||||
|
|
@ -69,10 +85,10 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
{
|
||||
$path = resource_path("lang/$locale.json");
|
||||
|
||||
if (is_string($path) && is_readable($path)) {
|
||||
return json_decode(file_get_contents($path), true) ?? [];
|
||||
if (!File::exists($path) or !File::isReadable($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
return json_decode(File::get($path), true) ?? [];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
43
app/Rules/IsValidVimeoId.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Validate a vimeo ID regex
|
||||
*
|
||||
* @package App\Rules
|
||||
*/
|
||||
class IsValidVimeoId implements ValidationRule
|
||||
{
|
||||
/**
|
||||
* Run the validation rule.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param \Closure(string):\Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||
{
|
||||
// phpcs:enable
|
||||
if (!self::validates($value)) {
|
||||
$fail(trans('validation.vimeo_id'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public static function validates(mixed $value): bool
|
||||
{
|
||||
return Str::of($value)->isMatch('/^[0-9]{8,10}$/');
|
||||
}
|
||||
}
|
||||
44
app/Rules/IsValidYoutubeId.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Validate a youtube ID regex
|
||||
*
|
||||
* @url https://webapps.stackexchange.com/questions/54443/format-for-id-of-youtube-video
|
||||
* @package App\Rules
|
||||
*/
|
||||
class IsValidYoutubeId implements ValidationRule
|
||||
{
|
||||
/**
|
||||
* Run the validation rule.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
* @param \Closure(string):\Illuminate\Translation\PotentiallyTranslatedString $fail
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function validate(string $attribute, mixed $value, \Closure $fail): void
|
||||
{
|
||||
// phpcs:enable
|
||||
if (!self::validates($value)) {
|
||||
$fail(trans('validation.youtube_id'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a value
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return boolean
|
||||
*/
|
||||
public static function validates(mixed $value): bool
|
||||
{
|
||||
return Str::of($value)->isMatch('/^[0-9A-Za-z_-]{10}[048AEIMQUYcgkosw]$/');
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
namespace App\Traits\Controllers;
|
||||
|
||||
use App\Http\Requests\Bo\UpdateChangeOrderRequest;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -14,22 +14,31 @@ trait ChangesModelOrder
|
|||
* Change order.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\UpdateChangeOrderRequest $request
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param mixed ...$params
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws \RuntimeException Si le nom du parametre de la route ne correspond pas au model utilisé.
|
||||
* @throws \RuntimeException Si le nom du parametre de la route ne correspond pas au params utilisé.
|
||||
*/
|
||||
public function changeOrder(UpdateChangeOrderRequest $request, Model $model): \Illuminate\Http\RedirectResponse
|
||||
public function changeOrder(UpdateChangeOrderRequest $request, mixed ...$params): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$params = collect(request()->route()->parameterNames);
|
||||
$className = Str::ucfirst(Str::lower($params->get($params->count() - 2)));
|
||||
$className = "\\App\\Models\\$className";
|
||||
$paramNames = collect(request()->route()->parameterNames);
|
||||
$className = Str::of($paramNames->get($paramNames->count() - 2))->lower()->studly();
|
||||
$className = "\\App\\Models\\{$className}";
|
||||
$model = Arr::get($params, $paramNames->count() - 2);
|
||||
|
||||
if (!class_exists($className)) {
|
||||
throw new \RuntimeException("The $className class doesn't exist.");
|
||||
throw new \RuntimeException("The {$className} class doesn't exist.");
|
||||
}
|
||||
|
||||
if (!\is_object($model)) {
|
||||
throw new \RuntimeException("The second last param isn't an object.");
|
||||
}
|
||||
|
||||
if (get_class($model) !== (string)Str::of($className)->replaceStart('\\', '')) {
|
||||
throw new \RuntimeException("The {$className} doesn't match second last binded param.");
|
||||
}
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$model = $className::where($model->getRouteKeyName(), $model->getRouteKey())->first();
|
||||
$model = $className::query()->where($model->getRouteKeyName(), $model->getRouteKey())->first();
|
||||
|
||||
if (!$model) {
|
||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
|
|
@ -37,18 +46,16 @@ trait ChangesModelOrder
|
|||
|
||||
return DB::transaction(function () use ($request, $className, $model) {
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$tmp = $className::where('order', $request->direction ? '<' : '>', $model->order)
|
||||
$tmp = $className::where('order', $request->direction ? '<' : '>', $model->getOriginal('order'))
|
||||
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
|
||||
|
||||
if (!$tmp) {
|
||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
}
|
||||
|
||||
$newOrder = $tmp->order;
|
||||
$tmp->order = $model->order;
|
||||
$model->order = $newOrder;
|
||||
$tmp->saveOrFail();
|
||||
$model->saveOrFail();
|
||||
$newOrder = $tmp->getOriginal('order');
|
||||
$tmp->update(['order' => $model->getOriginal('order')]);
|
||||
$model->update(['order' => $newOrder]);
|
||||
Session::flash('success', trans('crud.messages.order_changed'));
|
||||
|
||||
return back();
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ trait UpdateModelPublished
|
|||
*/
|
||||
public function changePublished(Model $model)
|
||||
{
|
||||
$model->published = !$model->published;
|
||||
$model->saveOrFail();
|
||||
$model->update(['published' => !$model->getOriginal('published')]);
|
||||
return redirect()->back()->with('success', trans(__('crud.messages.publish_status_saved')));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ trait BaseEnum
|
|||
/**
|
||||
* Get enums.
|
||||
*
|
||||
* @return array
|
||||
* @return array<self>
|
||||
*/
|
||||
public static function toArray(): array
|
||||
{
|
||||
|
|
@ -118,9 +118,9 @@ trait BaseEnum
|
|||
/**
|
||||
* Fetch enum using value.
|
||||
*
|
||||
* @param \App\Traits\Enums\BaseEnum|integer|string $value
|
||||
* @param string $field
|
||||
* @return \App\Traits\Enums\BaseEnum|null
|
||||
* @param self|integer|string $value
|
||||
* @param string $field
|
||||
* @return self|null
|
||||
*/
|
||||
public static function make(self|int|string $value, string $field = 'value'): self|null
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ use Illuminate\Support\Facades\Cache;
|
|||
/**
|
||||
* ! Use this only on limited elements, (not on tags, or products, or posts for ex.)
|
||||
*
|
||||
* @property private static array $cacheConditions Eloquent condition to cache elements (to be used in where statement).
|
||||
* @property array<string,string|integer|float|boolean> $cacheConditions
|
||||
* Eloquent condition to cache elements (to be used in where statement).
|
||||
*/
|
||||
trait IsCachedAsCollection
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,8 +11,9 @@ trait MiniCrudModel
|
|||
/**
|
||||
* Fill the model with an array of attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*
|
||||
* @throws \Illuminate\Database\Eloquent\MassAssignmentException If fill prop is not allowed.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
|
||||
*/
|
||||
|
|
@ -23,6 +24,7 @@ trait MiniCrudModel
|
|||
if (isset($attributes['data'])) {
|
||||
$this->setData($attributes['data']);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -62,7 +64,7 @@ trait MiniCrudModel
|
|||
*/
|
||||
public function minicrudUpdated()
|
||||
{
|
||||
/** @var array */
|
||||
/** @var array $input */
|
||||
foreach ($this->data as $index => $input) {
|
||||
switch ($input['inputType']) {
|
||||
case InputType::text->value:
|
||||
|
|
@ -166,7 +168,7 @@ trait MiniCrudModel
|
|||
case InputType::string->value:
|
||||
case InputType::text->value:
|
||||
case InputType::url->value:
|
||||
ToolboxHelper::assertNoInternalBoUrls('content', $input['value'] ?? '');
|
||||
ToolboxHelper::assertNoInternalBoUrls('content', $input['value']);
|
||||
break;
|
||||
default:
|
||||
throw new \ErrorException(sprintf(
|
||||
|
|
|
|||
|
|
@ -14,14 +14,14 @@ trait HasPicture
|
|||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $minWith = 400;
|
||||
private $minWidth = 400;
|
||||
|
||||
/**
|
||||
* Maximum width
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $maxWith = 1800;
|
||||
private $maxWidth = 1800;
|
||||
|
||||
/**
|
||||
* Minimum height
|
||||
|
|
@ -41,38 +41,41 @@ trait HasPicture
|
|||
* Image rules
|
||||
*
|
||||
* @param string $name
|
||||
* @param integer|null $minWith
|
||||
* @param integer|null $minWidth
|
||||
* @param integer|null $minHeight
|
||||
* @param integer|null $maxWith
|
||||
* @param integer|null $maxWidth
|
||||
* @param integer|null $maxHeight
|
||||
* @param integer|null $size
|
||||
* @param boolean $nullable
|
||||
* @param integer|null $size
|
||||
* @param string|null $requiredWith
|
||||
* @param string|null $requiredWithout
|
||||
* @return array
|
||||
*/
|
||||
public function pictureRules(
|
||||
string $name = 'picture',
|
||||
?int $minWith = null,
|
||||
?int $minWidth = null,
|
||||
?int $minHeight = null,
|
||||
?int $maxWith = null,
|
||||
?int $maxWidth = null,
|
||||
?int $maxHeight = null,
|
||||
?int $size = null,
|
||||
bool $nullable = false,
|
||||
?int $size = null,
|
||||
?string $requiredWith = null,
|
||||
?string $requiredWithout = null,
|
||||
): array {
|
||||
$dimensions = (object)[
|
||||
'minWith' => $minWith ?? $this->minWith,
|
||||
'minWidth' => $minWidth ?? $this->minWidth,
|
||||
'minHeight' => $minHeight ?? $this->minHeight,
|
||||
'maxWith' => $maxWith ?? $this->maxWith,
|
||||
'maxWidth' => $maxWidth ?? $this->maxWidth,
|
||||
'maxHeight' => $maxHeight ?? $this->maxHeight
|
||||
];
|
||||
return [
|
||||
$name => [
|
||||
!$nullable ? 'required' : 'nullable',
|
||||
(strlen($requiredWith)) ? 'required_with:' . $requiredWith : '',
|
||||
(strlen($requiredWithout)) ? 'required_without:' . $requiredWithout : '',
|
||||
($size) ? 'max:' . $size : '',
|
||||
function (string $attribute, $value, callable $fail) use ($dimensions) {
|
||||
return ToolboxHelper::validatePicture($attribute, $value, $fail, $dimensions);
|
||||
ToolboxHelper::validatePicture($attribute, $value, $fail, $dimensions);
|
||||
}
|
||||
]
|
||||
];
|
||||
|
|
@ -82,32 +85,38 @@ trait HasPicture
|
|||
* Images rules
|
||||
*
|
||||
* @param string $name
|
||||
* @param integer|null $minWith
|
||||
* @param integer|null $minWidth
|
||||
* @param integer|null $minHeight
|
||||
* @param integer|null $maxWith
|
||||
* @param integer|null $maxWidth
|
||||
* @param integer|null $maxHeight
|
||||
* @param integer $limitMin
|
||||
* @param integer $limitMax
|
||||
* @param boolean $nullable
|
||||
* @return array
|
||||
*/
|
||||
public function picturesRules(
|
||||
string $name = 'pictures',
|
||||
?int $minWith = null,
|
||||
?int $minWidth = null,
|
||||
?int $minHeight = null,
|
||||
?int $maxWith = null,
|
||||
?int $maxHeight = null
|
||||
?int $maxWidth = null,
|
||||
?int $maxHeight = null,
|
||||
int $limitMin = 1,
|
||||
int $limitMax = 5,
|
||||
bool $nullable = false
|
||||
): array {
|
||||
$sizes = (object)[
|
||||
'minWith' => $minWith ?? $this->minWith,
|
||||
'minWidth' => $minWidth ?? $this->minWidth,
|
||||
'minHeight' => $minHeight ?? $this->minHeight,
|
||||
'maxWith' => $maxWith ?? $this->maxWith,
|
||||
'maxHeight' => $maxHeight ?? $this->maxHeight
|
||||
'maxWidth' => $maxWidth ?? $this->maxWidth,
|
||||
'maxHeight' => $maxHeight ?? $this->maxHeight,
|
||||
];
|
||||
return [
|
||||
$name => 'sometimes|array',
|
||||
$name => [!$nullable ? 'required' : 'nullable', 'array', "between:{$limitMin},{$limitMax}"],
|
||||
"{$name}Validate" => "required_with:{$name}|array",
|
||||
"{$name}Validate.*" => [
|
||||
'required',
|
||||
function (string $attribute, $value, callable $fail) use ($sizes) {
|
||||
return $this->validatePicture($attribute, $value, $fail, $sizes);
|
||||
ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
|
||||
}
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,8 +1,16 @@
|
|||
{
|
||||
"name": "uwil/volena",
|
||||
"version": "2.0.0",
|
||||
"name": "uwil/laravel-base-project",
|
||||
"version": "1.0.0",
|
||||
"type": "project",
|
||||
"description": "Volena website.",
|
||||
"description": "Laravel base project reference.",
|
||||
"support": {
|
||||
"email": "equipe.web@ldc.fr"
|
||||
},
|
||||
"keywords": [
|
||||
"framework",
|
||||
"laravel"
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"diglactic/laravel-breadcrumbs": "^8.0",
|
||||
|
|
@ -11,12 +19,14 @@
|
|||
"laravel/tinker": "^2.8",
|
||||
"laravel/ui": "^4.2",
|
||||
"mews/purifier": "^3.4",
|
||||
"sentry/sentry-laravel": "*"
|
||||
"sentry/sentry-laravel": "*",
|
||||
"uwil/k8s-laravel": "^1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"kitloong/laravel-migrations-generator": "^6.11",
|
||||
"kitloong/laravel-migrations-generator": "^6.8",
|
||||
"krlove/eloquent-model-generator": "dev-l10-compatibility",
|
||||
"larastan/larastan": "^2.6",
|
||||
"laravel-lang/common": "^4.0",
|
||||
"laravel/pint": "^1.0",
|
||||
"laravel/sail": "^1.18",
|
||||
|
|
@ -38,6 +48,10 @@
|
|||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/laravel-shift/eloquent-model-generator.git"
|
||||
},
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://lab.s-web.fr/api/v4/group/23/-/packages/composer/packages.json"
|
||||
}
|
||||
],
|
||||
"autoload-dev": {
|
||||
|
|
@ -73,7 +87,10 @@
|
|||
"pestphp/pest-plugin": true,
|
||||
"php-http/discovery": true,
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
}
|
||||
},
|
||||
"gitlab-domains": [
|
||||
"lab.s-web.fr"
|
||||
]
|
||||
},
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true
|
||||
|
|
|
|||
3031
composer.lock
generated
|
|
@ -111,7 +111,10 @@ return [
|
|||
'theme' => 'default',
|
||||
|
||||
'paths' => [
|
||||
resource_path('views/vendor/mail'),
|
||||
// * For custom compiled css.
|
||||
public_path('build/vendor/mail'),
|
||||
// * For generic customized blade (moteur seulement)
|
||||
resource_path('views/vendor/mail')
|
||||
],
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -30,13 +30,13 @@ return [
|
|||
'URI.SafeIframeRegexp' => "%^(http://|https://|//)(www.youtube.com/embed/|player.vimeo.com/video/|vimeo.com/|www.dailymotion.com/video/)%",
|
||||
'HTML.Doctype' => 'HTML 4.01 Transitional',
|
||||
// * Legacy filter en full avec safe legacy.
|
||||
'HTML.Allowed' => 'h1[style|id],h2[style|id],h3[style|id],h4[style|id],h5[style|id],h6[style|id],figure[class|style],oembed[url],div[style],b,strong,i,em,u,s,pre,code[class],a[href|title|target|rel|id],ul[style],ol[style],dl[style],li,p[style],br,span[style|class],img[width|height|alt|src|style|class|title],iframe[src|width|height|class|frameborder|style],table[style|align|border|cellspacing|cellpadding|width],thead,tbody,th[colspan|align|valign|style],tr[align|valign|style],td[style|colspan|rowspan|scope|align|valign],hr,dl,dt,mark[class]',
|
||||
// 'HTML.Allowed' => 'h1[style|id],h2[style|id],h3[style|id],h4[style|id],h5[style|id],h6[style|id],figure[class|style],oembed[url],div[style],b,strong,i,em,u,s,pre,code[class],a[href|title|target|rel|id],ul[style],ol[style],dl[style],li,p[style],br,span[style|class],img[width|height|alt|src|style|class|title],iframe[src|width|height|class|frameborder|style],table[style|align|border|cellspacing|cellpadding|width],thead,tbody,th[colspan|align|valign|style],tr[align|valign|style],td[style|colspan|rowspan|scope|align|valign],hr,dl,dt,mark[class]',
|
||||
// * Restricted basics.
|
||||
// 'HTML.Allowed' => 'br,p[style],b[style],u[style],i[style],a[href|title|target|rel],strong[style],span[class],ul[style],ol[style],li[style],h2[style],h3[style],h4[style],hr,blockquote[style]',
|
||||
'HTML.Allowed' => 'br,p[style],b[style],u[style],i[style],a[href|title|target|rel],strong[style],span[class],ul[style],ol[style],li[style],h2[style],h3[style],h4[style],hr,blockquote[style]',
|
||||
// * Legacy filter en full avec safe legacy.
|
||||
'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align,list-style-type,float,width,height,vertical-align,border,border-color,margin-left',
|
||||
// 'CSS.AllowedProperties' => 'font,font-size,font-weight,font-style,font-family,text-decoration,padding-left,color,background-color,text-align,list-style-type,float,width,height,vertical-align,border,border-color,margin-left',
|
||||
// * Restricted basics.
|
||||
// 'CSS.AllowedProperties' => 'text-align,margin-left',
|
||||
'CSS.AllowedProperties' => 'text-align,margin-left',
|
||||
'AutoFormat.AutoParagraph' => false,
|
||||
'AutoFormat.RemoveEmpty' => false,
|
||||
'AutoFormat.RemoveEmpty.RemoveNbsp' => false,
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ class UserFactory extends Factory
|
|||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function definition()
|
||||
public function definition(): array
|
||||
{
|
||||
$published = $this->faker->boolean(75);
|
||||
return [
|
||||
'first_name' => fake()->firstname(),
|
||||
'last_name' => fake()->lastname(),
|
||||
'first_name' => fake()->firstname(),
|
||||
'last_name' => fake()->lastname(),
|
||||
'email' => fake()->unique()->safeEmail(),
|
||||
'email_verified_at' => now(),
|
||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
|
||||
|
|
@ -36,7 +36,7 @@ class UserFactory extends Factory
|
|||
*/
|
||||
public function unverified(): static
|
||||
{
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'email_verified_at' => null,
|
||||
]);
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 581 B |
|
After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 581 B |
BIN
database/factories/assets/logos/default-picture-331x240.jpg
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
database/factories/assets/news/default-picture-511x400.jpg
Normal file
|
After Width: | Height: | Size: 5 KiB |
BIN
database/factories/assets/sections/home-missions-430x430.jpg
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
database/factories/assets/sections/home-team-465x525.jpg
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
database/factories/assets/sites/default-picture-813x450.jpg
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
|
|
@ -23,7 +23,7 @@ return new class extends Migration
|
|||
$table->rememberToken();
|
||||
$table->unsignedTinyInteger('role')->comment('Role of the user who defines the rights/access.');
|
||||
$table->boolean('published')->comment('The user is acivated or not.');
|
||||
$table->timestamp('published_at')->nullable()->comment('The date on which the user was acivated.');
|
||||
$table->timestamp('published_at')->nullable()->comment('The date on which the user was activated.');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ return new class extends Migration
|
|||
{
|
||||
Schema::create('activity_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('user_id')->nullable()->constrained('users')
|
||||
$table->foreignId('user_id')->nullable()->constrained('users')->nullOnDelete()
|
||||
->comment('Id of the user associated, or nullable for a deleted user.');
|
||||
$table->boolean('is_anonymous')->comment('If there is no user connected when action was realised.');
|
||||
$table->boolean('is_console')->comment('If the action was realised in console.');
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
|
|
@ -16,22 +15,14 @@ return new class extends Migration
|
|||
{
|
||||
Schema::create('static_pages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->unsignedTinyInteger('type')->unique()->comment('Page type (StaticPageEnum)');
|
||||
|
||||
$table->string('seo_title')->comment('Seo title about 70 chars as recommended');
|
||||
$table->string('seo_description')->comment('Seo description about 160 chars as recommended');
|
||||
|
||||
$table->string('title')->comment('Title for the page');
|
||||
$table->string('slug')->unique()->comment('Unique title slug');
|
||||
|
||||
$table->text('content')->comment('WYSIWYG text content using ckeditor');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
Artisan::call('db:seed', [
|
||||
'class' => 'StaticPageSeeder'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
30
database/migrations/2030_01_01_000001_mandatory_seeds.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
use Database\Seeders\MandatorySeeder;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Artisan::call('db:seed', [
|
||||
'class' => MandatorySeeder::class
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
};
|
||||
|
|
@ -14,16 +14,8 @@ class DatabaseSeeder extends Seeder
|
|||
public function run()
|
||||
{
|
||||
$this->call([
|
||||
UserSeeder::class,
|
||||
HistoricalMilestoneSeeder::class,
|
||||
JobVideoSeeder::class,
|
||||
LogoSeeder::class,
|
||||
NewsSeeder::class,
|
||||
SectionSeeder::class,
|
||||
SiteSeeder::class,
|
||||
SlideSeeder::class,
|
||||
StripSeeder::class,
|
||||
TestimonialSeeder::class
|
||||
MandatorySeeder::class,
|
||||
DevelopmentSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\HistoricalMilestone;
|
||||
|
|
@ -16,11 +16,12 @@ class HistoricalMilestoneSeeder extends Seeder
|
|||
public function run()
|
||||
{
|
||||
FileStorageHelper::removeModelFiles(new HistoricalMilestone());
|
||||
// @phpstan-ignore-next-line
|
||||
HistoricalMilestone::factory(10)->make()->each(function (HistoricalMilestone $historicalMilestone) {
|
||||
$historicalMilestone->picture = FileStorageHelper::storeFile(
|
||||
new HistoricalMilestone(),
|
||||
new \SplFileInfo(\resource_path(
|
||||
'../database/factories/assets/historical_milestones/default-picture-100x100.png'
|
||||
'../database/factories/assets/historical_milestones/default-picture-606x800.jpg'
|
||||
))
|
||||
);
|
||||
$historicalMilestone->save();
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Models\JobVideo;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Logo;
|
||||
|
|
@ -16,11 +16,12 @@ class LogoSeeder extends Seeder
|
|||
public function run()
|
||||
{
|
||||
FileStorageHelper::removeModelFiles(new Logo());
|
||||
// @phpstan-ignore-next-line
|
||||
Logo::factory(10)->make()->each(function (Logo $logo) {
|
||||
$logo->picture = FileStorageHelper::storeFile(
|
||||
new Logo(),
|
||||
new \SplFileInfo(\resource_path(
|
||||
'../database/factories/assets/logos/default-picture-100x100.png'
|
||||
'../database/factories/assets/logos/default-picture-331x240.jpg'
|
||||
))
|
||||
);
|
||||
$logo->save();
|
||||
|
|
@ -1,11 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\News;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* FIXME: Definir les tailes d'images pour les news
|
||||
*
|
||||
* @package Database\Seeders\Development
|
||||
*/
|
||||
class NewsSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
|
|
@ -16,6 +21,7 @@ class NewsSeeder extends Seeder
|
|||
public function run()
|
||||
{
|
||||
FileStorageHelper::removeModelFiles(new News());
|
||||
// @phpstan-ignore-next-line
|
||||
News::factory(10)->make()->each(function (News $news) {
|
||||
$news->thumbnail = FileStorageHelper::storeFile(
|
||||
new News(),
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Enums\Sections\PageSectionEnum;
|
||||
use App\Enums\StaticPageType;
|
||||
|
|
@ -10,6 +10,11 @@ use App\Models\StaticPage;
|
|||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* FIXME: Definir les tailes d'images pour les sections
|
||||
*
|
||||
* @package Database\Seeders\Development
|
||||
*/
|
||||
class SectionSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
|
|
@ -22,8 +27,9 @@ class SectionSeeder extends Seeder
|
|||
FileStorageHelper::removeModelFiles(new Section());
|
||||
|
||||
foreach (PageSectionEnum::cases() as $sectionEnum) {
|
||||
// @phpstan-ignore-next-line
|
||||
Section::factory(1)->make()->each(function (Section $section) use ($sectionEnum) {
|
||||
$section->section = $sectionEnum->value;
|
||||
$section->section = $sectionEnum;
|
||||
$section->page_id = $this->getPageId($sectionEnum);
|
||||
if ($sectionEnum === PageSectionEnum::hire_grow) {
|
||||
$section->text = '';
|
||||
|
|
@ -113,13 +119,13 @@ class SectionSeeder extends Seeder
|
|||
FileStorageHelper::storeFile(
|
||||
new Section(),
|
||||
new \SplFileInfo(\resource_path(
|
||||
'../database/factories/assets/sections/default-picture-100x100.png'
|
||||
'../database/factories/assets/sections/home-missions-430x430.jpg'
|
||||
))
|
||||
),
|
||||
fake()->sentence(),
|
||||
fake()->sentence(),
|
||||
100,
|
||||
100,
|
||||
430,
|
||||
430,
|
||||
fake()->url(),
|
||||
fake()->randomNumber(),
|
||||
fake()->randomNumber()
|
||||
|
|
@ -139,13 +145,13 @@ class SectionSeeder extends Seeder
|
|||
FileStorageHelper::storeFile(
|
||||
new Section(),
|
||||
new \SplFileInfo(\resource_path(
|
||||
'../database/factories/assets/sections/default-picture-100x100.png'
|
||||
'../database/factories/assets/sections/home-team-465x525.jpg'
|
||||
))
|
||||
),
|
||||
fake()->sentence(),
|
||||
fake()->sentence(),
|
||||
100,
|
||||
100,
|
||||
465,
|
||||
525,
|
||||
fake()->url(),
|
||||
);
|
||||
}
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Logo;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* FIXME: Definir les tailes d'images pour les sites
|
||||
*
|
||||
* @package Database\Seeders\Development
|
||||
*/
|
||||
class SiteSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
|
|
@ -17,6 +22,7 @@ class SiteSeeder extends Seeder
|
|||
public function run()
|
||||
{
|
||||
FileStorageHelper::removeModelFiles(new Site());
|
||||
// @phpstan-ignore-next-line
|
||||
Site::factory(10)->make()->each(function (Site $site) {
|
||||
$site->logo = FileStorageHelper::storeFile(
|
||||
new Site(),
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Enums\Slides\SliderTypeEnum;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Slide;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* FIXME: Definir les tailes d'images pour les slides
|
||||
*
|
||||
* @package Database\Seeders\Development
|
||||
*/
|
||||
class SlideSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
|
|
@ -18,8 +23,9 @@ class SlideSeeder extends Seeder
|
|||
{
|
||||
FileStorageHelper::removeModelFiles(new Slide());
|
||||
foreach (SliderTypeEnum::cases() as $slider) {
|
||||
// @phpstan-ignore-next-line
|
||||
Slide::factory(3)->make()->each(function (Slide $slide) use ($slider) {
|
||||
$slide->slider = $slider->value;
|
||||
$slide->slider = $slider;
|
||||
$slide->video_id = $slider === SliderTypeEnum::home ? '6B4O-_1CQoI' : '';
|
||||
$slide->picture = FileStorageHelper::storeFile(
|
||||
new Slide(),
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Strip;
|
||||
|
|
@ -1,12 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Enums\Testimonials\TypeEnum;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Testimonial;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* FIXME: Definir les tailes d'images pour les testimonials
|
||||
*
|
||||
* @package Database\Seeders\Development
|
||||
*/
|
||||
class TestimonialSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
|
|
@ -18,8 +23,9 @@ class TestimonialSeeder extends Seeder
|
|||
{
|
||||
FileStorageHelper::removeModelFiles(new Testimonial());
|
||||
foreach (TypeEnum::cases() as $type) {
|
||||
// @phpstan-ignore-next-line
|
||||
Testimonial::factory(3)->make()->each(function (Testimonial $testimonial) use ($type) {
|
||||
$testimonial->type = $type->value;
|
||||
$testimonial->type = $type;
|
||||
$testimonial->picture = FileStorageHelper::storeFile(
|
||||
new Testimonial(),
|
||||
new \SplFileInfo(\resource_path(
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Development;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
39
database/seeders/DevelopmentSeeder.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Database\Seeders\Development\HistoricalMilestoneSeeder;
|
||||
use Database\Seeders\Development\JobVideoSeeder;
|
||||
use Database\Seeders\Development\LogoSeeder;
|
||||
use Database\Seeders\Development\NewsSeeder;
|
||||
use Database\Seeders\Development\SectionSeeder;
|
||||
use Database\Seeders\Development\SiteSeeder;
|
||||
use Database\Seeders\Development\SlideSeeder;
|
||||
use Database\Seeders\Development\StripSeeder;
|
||||
use Database\Seeders\Development\TestimonialSeeder;
|
||||
use Database\Seeders\Development\UserSeeder;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DevelopmentSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
UserSeeder::class,
|
||||
HistoricalMilestoneSeeder::class,
|
||||
JobVideoSeeder::class,
|
||||
LogoSeeder::class,
|
||||
NewsSeeder::class,
|
||||
SectionSeeder::class,
|
||||
SiteSeeder::class,
|
||||
SlideSeeder::class,
|
||||
StripSeeder::class,
|
||||
TestimonialSeeder::class
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
namespace Database\Seeders\Mandatory;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Models\StaticPage;
|
||||
21
database/seeders/MandatorySeeder.php
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Database\Seeders\Mandatory\StaticPageSeeder;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class MandatorySeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->call([
|
||||
StaticPageSeeder::class
|
||||
]);
|
||||
}
|
||||
}
|
||||
3273
package-lock.json
generated
37
package.json
|
|
@ -16,11 +16,10 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.22.11",
|
||||
"@babel/types": "^7.21.2",
|
||||
"@fortawesome/fontawesome-svg-core": "latest",
|
||||
"@fortawesome/free-brands-svg-icons": "latest",
|
||||
"@fortawesome/free-regular-svg-icons": "latest",
|
||||
"@fortawesome/free-solid-svg-icons": "latest",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.3",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
||||
"@fortawesome/vue-fontawesome": "^3.0.5",
|
||||
"@sipec/vue3-tags-input": "^3.0.4",
|
||||
"@types/bootstrap": "^5.2.7",
|
||||
"@types/node": "^20.8.2",
|
||||
|
|
@ -28,44 +27,44 @@
|
|||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.36.2",
|
||||
"@vitejs/plugin-basic-ssl": "^1.0.1",
|
||||
"@vitejs/plugin-legacy": "latest",
|
||||
"@vitejs/plugin-vue": "latest",
|
||||
"@vitejs/plugin-vue": "^4.6.2",
|
||||
"@vue/compiler-sfc": "latest",
|
||||
"@vue/eslint-config-typescript": "latest",
|
||||
"@vue/tsconfig": "latest",
|
||||
"@vue/tsconfig": "^0.4.0",
|
||||
"axios": "^1.5.1",
|
||||
"bootstrap": "^5.3.2",
|
||||
"chart.js": "^4.4.0",
|
||||
"cropperjs": "^1.6.1",
|
||||
"eslint": "latest",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-plugin-vue": "latest",
|
||||
"eslint": "latest",
|
||||
"laravel-vite-plugin": "latest",
|
||||
"laravel-vite-plugin": "^0.8.1",
|
||||
"postcss-discard-comments": "^6.0.0",
|
||||
"prettier": "latest",
|
||||
"print-js": "^1.6.0",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"rollup-plugin-copy": "^3.5.0",
|
||||
"sass": "latest",
|
||||
"slugify": "^1.6.6",
|
||||
"stylelint": "^15.11.0",
|
||||
"stylelint-config-idiomatic-order": "github:ream88/stylelint-config-idiomatic-order",
|
||||
"stylelint-config-sass-guidelines": "latest",
|
||||
"stylelint-config-standard-scss": "latest",
|
||||
"stylelint-scss": "latest",
|
||||
"stylelint": "latest",
|
||||
"stylelint-config-sass-guidelines": "^10.0.0",
|
||||
"stylelint-config-standard-scss": "^11.1.0",
|
||||
"stylelint-scss": "^5.3.2",
|
||||
"sweetalert2": "^11.7.31",
|
||||
"terser": "latest",
|
||||
"toastify-js": "^1.12.0",
|
||||
"ts-loader": "^9.3.1",
|
||||
"typescript": ">=3.3.1 <5.2.0",
|
||||
"typescript-eslint": "latest",
|
||||
"typescript": "latest",
|
||||
"vite": "^4.5.1",
|
||||
"vite-plugin-babel": "latest",
|
||||
"vite-plugin-checker": "latest",
|
||||
"vite-plugin-eslint": "latest",
|
||||
"vite-plugin-stylelint": "latest",
|
||||
"vite": "^4.0.0",
|
||||
"vue-eslint-parser": "^9.1.0",
|
||||
"vue-loader": "^16.8.3",
|
||||
"vue": "latest",
|
||||
"vue-tsc": "1.6.0"
|
||||
"vue-eslint-parser": "^9.3.2",
|
||||
"vue-loader": "^17.3.1",
|
||||
"vue-tsc": "1.8.11"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
phpstan.neon
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
includes:
|
||||
- vendor/larastan/larastan/extension.neon
|
||||
|
||||
parameters:
|
||||
|
||||
paths:
|
||||
- app/
|
||||
|
||||
# Level 9 is the highest level
|
||||
level: 5
|
||||