Compare commits
91 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
314ef2dff7 | ||
|
|
f80f43a0a0 | ||
|
|
6dc813e366 | ||
|
|
fc7dad207e | ||
|
|
bdbbb9ff9a | ||
|
|
705aa7c522 | ||
|
|
3c63d85bd9 | ||
|
|
2648256177 | ||
|
|
5f90384be4 | ||
|
|
35f6d98dbc | ||
|
|
480482f5b2 | ||
|
|
7bf122def5 | ||
|
|
f374271268 | ||
|
|
7e9292e27e | ||
|
|
54b3d22d40 | ||
|
|
480d6394b4 | ||
|
|
f693e2a195 | ||
|
|
58518d0238 | ||
|
|
acd7e13c81 | ||
|
|
404b022a17 | ||
|
|
a65d855acc | ||
|
|
aba83a5c91 | ||
|
|
9481b4ca70 | ||
|
|
45ff265caf | ||
|
|
87b2ca2368 | ||
|
|
50c743f728 | ||
|
|
91094d9120 | ||
|
|
3d959fd37c | ||
|
|
0f4fe5eaac | ||
|
|
58111ca5dd | ||
|
|
97817caaaa | ||
|
|
066fd0c8b3 | ||
|
|
97dc1acf2a | ||
|
|
608803bd0c | ||
|
|
bd5be3fce1 | ||
|
|
8668c6a38c | ||
|
|
6e01470b5c | ||
|
|
f9a7728375 | ||
|
|
4d5dc72b11 | ||
|
|
b01c6cc577 | ||
|
|
d97071b740 | ||
|
|
a17953deb1 | ||
|
|
6e433628b5 | ||
|
|
3f15d48355 | ||
|
|
d61f05640d | ||
|
|
3e64820fb8 | ||
|
|
21d0ec429f | ||
|
|
ca54e892b5 | ||
|
|
608852e80a | ||
|
|
425a7b223d | ||
|
|
6ceb64a50c | ||
|
|
6d6729285b | ||
|
|
4cc8134e96 | ||
|
|
e1994588e1 | ||
|
|
5220fc130f | ||
|
|
70e05dd6fa | ||
|
|
3ceaceacb6 | ||
|
|
abc6dd8484 | ||
|
|
b63450f905 | ||
|
|
34235baa16 | ||
|
|
1242d4893f | ||
|
|
e7ce6aef02 | ||
|
|
7d689d30fb | ||
|
|
219eba96ec | ||
|
|
0d7bdd5901 | ||
|
|
3712af4419 | ||
|
|
fe494a24cf | ||
|
|
f3a7994154 | ||
|
|
ff10196da7 | ||
|
|
3343e18a11 | ||
|
|
ed92ed2d94 | ||
|
|
f581a25ba7 | ||
|
|
c2b5daa67c | ||
|
|
2a46a25165 | ||
|
|
e346e65d7d | ||
|
|
a807c9656c | ||
|
|
ba73f40554 | ||
|
|
037b859066 | ||
|
|
0e4d84cc6f | ||
|
|
57e84ab247 | ||
|
|
656562afe5 | ||
|
|
76114a0d59 | ||
|
|
5f16a9e77f | ||
|
|
78931c7a46 | ||
|
|
96ed23b5c9 | ||
|
|
f8eb6f481e | ||
|
|
1564eb8bc3 | ||
|
|
f47d3f6fd1 | ||
|
|
338715d9eb | ||
|
|
b25444263a | ||
|
|
dc41c9aa82 |
31
.env.example
|
|
@ -3,6 +3,7 @@ APP_ENV=local
|
|||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
ASSET_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
|
|
@ -22,6 +23,12 @@ QUEUE_CONNECTION=sync
|
|||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailpit
|
||||
MAIL_PORT=1025
|
||||
|
|
@ -30,7 +37,26 @@ MAIL_PASSWORD=null
|
|||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
MAIL_CONTACTFORM_RECEIVER=
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_HOST=
|
||||
PUSHER_PORT=443
|
||||
PUSHER_SCHEME=https
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
|
||||
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||
VITE_PUSHER_HOST="${PUSHER_HOST}"
|
||||
VITE_PUSHER_PORT="${PUSHER_PORT}"
|
||||
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
|
||||
# Sentry
|
||||
SENTRY_LARAVEL_DSN=
|
||||
|
|
@ -43,6 +69,3 @@ MATOMO_SITE_ID=
|
|||
GOOGLE_RECAPTCHA_PUBLIC=
|
||||
GOOGLE_RECAPTCHA_PRIVATE=
|
||||
GOOGLE_RECAPTCHA_VERSION=
|
||||
|
||||
# Admin secure
|
||||
LDC_WEB_API_KEY=
|
||||
13
.gitignore
vendored
|
|
@ -23,16 +23,3 @@ 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,5 +0,0 @@
|
|||
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
|
||||
|
|
@ -1,7 +1 @@
|
|||
# Agis
|
||||
|
||||
## CRON
|
||||
Put every min in PROD :
|
||||
```
|
||||
php artisan schedule:run
|
||||
```
|
||||
|
|
@ -28,35 +28,35 @@ class UserCreate extends Command
|
|||
/**
|
||||
* The first name of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
* @var string
|
||||
*/
|
||||
protected $first_name;
|
||||
|
||||
/**
|
||||
* The last name of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
* @var string
|
||||
*/
|
||||
protected $last_name;
|
||||
|
||||
/**
|
||||
* The email of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
* @var string
|
||||
*/
|
||||
protected $email;
|
||||
|
||||
/**
|
||||
* The password of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
* @var string
|
||||
*/
|
||||
protected $password;
|
||||
|
||||
/**
|
||||
* The role of the new user.
|
||||
*
|
||||
* @var string|null
|
||||
* @var string
|
||||
*/
|
||||
protected $role;
|
||||
|
||||
|
|
@ -219,7 +219,7 @@ class UserCreate extends Command
|
|||
$this->role = $tmp;
|
||||
} catch (ValidationException $e) {
|
||||
$this->error(sprintf(
|
||||
'Please choose from the selection %s',
|
||||
'Please choose from the selection',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ enum ActivityLogsEventEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::created->name => 'Création',
|
||||
|
|
|
|||
|
|
@ -13,11 +13,9 @@ enum CivilityEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::man->name => 'Monsieur',
|
||||
self::woman->name => 'Madame',
|
||||
self::man->name => 'Homme',
|
||||
self::woman->name => 'Femme',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,8 +15,6 @@ enum ObjectEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::customerService->name => 'Service consommateurs',
|
||||
|
|
|
|||
|
|
@ -260,8 +260,6 @@ enum Country: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::afghanistan->name => 'Afghanistan',
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ enum CategoryEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::enterprise->name => 'La vie d\'Entreprise',
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@ enum CookingModeEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::microwave->name => 'Micro-ondes',
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ enum BackgroundEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::candlemas->name => 'Chandeleur',
|
||||
|
|
|
|||
|
|
@ -21,8 +21,6 @@ enum StaticPageType: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::contact->name => 'Contact',
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ enum BootstrapThemeEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::light->name => 'Light',
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@ enum RoleEnum: int
|
|||
|
||||
/**
|
||||
* Optionnal labels definition.
|
||||
*
|
||||
* @phpstan-ignore-next-line
|
||||
*/
|
||||
private const LABELS = [
|
||||
self::conceptor->name => 'Concepteur',
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class ActivityLogsController 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
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class CommitmentController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Commitment $commitment
|
||||
* @param App\Models\Commitment $commitment
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Commitment $commitment): \Illuminate\Contracts\View\View
|
||||
|
|
@ -139,7 +139,7 @@ class CommitmentController extends Controller
|
|||
{
|
||||
$commitment->products()->detach();
|
||||
|
||||
if ($commitment->explorerpage()->count() === 0) {
|
||||
if ($commitment->explorerpage()->count() > 3) {
|
||||
if ($commitment->deleteOrFail()) {
|
||||
return redirect()->route('bo.commitments.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class JoinuspageController extends Controller
|
|||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Joinuspage\UpdateJoinuspageRequest $request
|
||||
* @param \App\Http\Requests\Bo\Joinuspages\UpdateJoinuspageRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateJoinuspageRequest $request): \Illuminate\Http\RedirectResponse
|
||||
|
|
|
|||
|
|
@ -104,7 +104,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
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ class ProductController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @param App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Product $product): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ class RangeController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @param App\Models\Range $range
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Range $range): \Illuminate\Contracts\View\View
|
||||
|
|
@ -143,9 +143,7 @@ class RangeController extends Controller
|
|||
*/
|
||||
public function destroy(Range $range): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Collection $products*/
|
||||
$products = $range->products;
|
||||
if (!$products->isEmpty()) {
|
||||
if (!$range->products->isEmpty()) {
|
||||
return redirect()->back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted_relation', [
|
||||
'model' => Str::ucfirst(__('models.classes.range')),
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class SeasonalSectionController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\SeasonalSection $seasonalSection
|
||||
* @param App\Models\SeasonalSection $seasonalSection
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(SeasonalSection $seasonalSection): \Illuminate\Contracts\View\View
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class StampController extends Controller
|
|||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Stamp $stamp
|
||||
* @param App\Models\Stamp $stamp
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Stamp $stamp): \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
|
||||
|
|
|
|||
|
|
@ -100,7 +100,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
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ class UsersController 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
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class Controller extends BaseController
|
|||
return $query;
|
||||
}
|
||||
// Get models with relation's name/label.
|
||||
if (Str::endsWith($field, '_id')) {
|
||||
if (Str::endsWith($field, '_id') && $query->getModel()->has(Str::remove('_id', $field))) {
|
||||
$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,15 +122,12 @@ 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.
|
||||
$cast and // Check if there is cast about specific field.
|
||||
enum_exists($cast) // Check if the cast is an enum.
|
||||
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.
|
||||
) {
|
||||
/** @var \App\Traits\Enums $cast */
|
||||
// @phpstan-ignore-next-line
|
||||
$cases = collect($cast::toArray());
|
||||
$cases = collect($query->getModel()->getCasts()[$field]::toArray());
|
||||
$enum = $cases->filter(function ($item) use ($search) {
|
||||
return preg_match('/' . Str::lower($search) . '/', Str::lower($item->label));
|
||||
});
|
||||
|
|
@ -151,12 +148,12 @@ class Controller extends BaseController
|
|||
{
|
||||
$rName = request()->route()->getName();
|
||||
$table = $query->getModel()->getTable();
|
||||
if (request()->input('sort_col')) {
|
||||
Session::put("$rName.sort_col", request()->input('sort_col'));
|
||||
if (request()->sort_col) {
|
||||
Session::put("$rName.sort_col", request()->sort_col);
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->input('sort_way')) {
|
||||
Session::put("$rName.sort_way", request()->input('sort_way'));
|
||||
if (request()->sort_way) {
|
||||
Session::put("$rName.sort_way", request()->sort_way);
|
||||
Session::put("$rName.sorted", true);
|
||||
}
|
||||
if (request()->rst) {
|
||||
|
|
@ -164,16 +161,12 @@ class Controller extends BaseController
|
|||
Session::remove("$rName.sort_col");
|
||||
Session::remove("$rName.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')
|
||||
);
|
||||
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);
|
||||
}
|
||||
} elseif (Schema::hasColumn($table, 'order')) {
|
||||
$query = $query->orderBy('order', 'ASC');
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ class NewsController extends Controller
|
|||
|
||||
/** @var \App\Models\News $newsModels */
|
||||
$newsModels = News::query()->where('published', true)->orderBy('publish_at', 'desc')->paginate(12);
|
||||
|
||||
return view('fo.pages.news.index', \compact('staticPageModel', 'newsModels'));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Lib\Helpers\CollectionHelper;
|
||||
use App\Models\Product;
|
||||
|
||||
class ProductController extends Controller
|
||||
|
|
@ -11,35 +10,16 @@ class ProductController extends Controller
|
|||
/**
|
||||
* Display the product page.
|
||||
*
|
||||
* @param string $slug
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(string $slug): \Illuminate\Contracts\View\View
|
||||
public function show(Product $product): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$productModel = Product::query()->where('slug', $slug)->firstOrFail();
|
||||
|
||||
$otherProductModels = $productModel->range->products()
|
||||
->where('id', '!=', $productModel->id)
|
||||
$otherProductModels = $product->range->products()
|
||||
->where('id', '!=', $product->id)
|
||||
->where('published', true)
|
||||
->inRandomOrder()
|
||||
->get();
|
||||
|
||||
return view('fo.pages.products.show', compact('productModel', 'otherProductModels'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filtered products.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function productsFiltered(): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$productModels = Product::query()
|
||||
->where('published', true)
|
||||
->where('range_id', request()->range_id)
|
||||
->orderBy('order', 'asc')
|
||||
->get();
|
||||
$productModels = CollectionHelper::paginateManually($productModels, 12, request()->page);
|
||||
return response()->json($productModels);
|
||||
return view('fo.pages.products.show', compact('product', 'otherProductModels'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace App\Http\Controllers\Fo;
|
|||
|
||||
use App\Enums\StaticPageType;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Lib\Helpers\CollectionHelper;
|
||||
use App\Models\Product;
|
||||
use App\Models\Range;
|
||||
use App\Models\StaticPage;
|
||||
|
|
@ -18,12 +17,12 @@ class RangeController extends Controller
|
|||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var \App\Models\Range $rangeModels */
|
||||
$rangeModels = Range::query()->where('published', true)->orderBy('order')->get();
|
||||
|
||||
/** @var \App\Models\StaticPage $staticPageModel */
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::ranges)->firstOrFail();
|
||||
|
||||
/** @var \App\Models\Range $rangeModels */
|
||||
$rangeModels = Range::query()->where('published', true)->orderBy('order')->paginate(12);
|
||||
|
||||
return view('fo.pages.ranges.index', compact('rangeModels', 'staticPageModel'));
|
||||
}
|
||||
|
||||
|
|
@ -39,27 +38,8 @@ class RangeController extends Controller
|
|||
$rangeModel = Range::query()->where('published', true)->where('slug', $slug)->firstOrFail();
|
||||
|
||||
/** @var \App\Models\Product $productModels */
|
||||
$productModels = Product::query()
|
||||
->where('range_id', $rangeModel->id)
|
||||
->where('published', true)
|
||||
->orderBy('order')
|
||||
->paginate(12);
|
||||
$productModels = Product::query()->where('range_id', $rangeModel->id)->where('published', true)->get();
|
||||
|
||||
return view('fo.pages.ranges.show', compact('rangeModel', 'productModels'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filtered ranges.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function rangesFiltered(): \Illuminate\Http\JsonResponse
|
||||
{
|
||||
$productModels = Range::query()
|
||||
->where('published', true)
|
||||
->orderBy('order', 'asc')
|
||||
->get();
|
||||
$productModels = CollectionHelper::paginateManually($productModels, 12, request()->page);
|
||||
return response()->json($productModels);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,10 +110,7 @@ class StaticPageController extends Controller
|
|||
*/
|
||||
public function contactForm(ContactRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$receivers = \config('mail.contactform.receiver');
|
||||
foreach ($receivers as $email) {
|
||||
Mail::to($email)->send(new SendContactMail((object)$request->validated()));
|
||||
}
|
||||
Mail::to(\config('mail.from.address'))->send(new SendContactMail((object)$request->validated()));
|
||||
|
||||
return redirect()->route('fo.contact.show')
|
||||
->with(
|
||||
|
|
@ -187,10 +184,7 @@ class StaticPageController extends Controller
|
|||
*/
|
||||
public function joinusForm(JoinusRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$receivers = \config('mail.contactform.receiver');
|
||||
foreach ($receivers as $email) {
|
||||
Mail::to($email)->send(new SendJoinusMail((object)$request->validated()));
|
||||
}
|
||||
Mail::to(\config('mail.from.address'))->send(new SendJoinusMail((object)$request->validated()));
|
||||
|
||||
return redirect()->route('fo.joinus.show')
|
||||
->with(
|
||||
|
|
|
|||
|
|
@ -65,6 +65,5 @@ class Kernel extends HttpKernel
|
|||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
||||
'local-development' => \App\Http\Middleware\LocalDevelopment::class,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LocalDevelopment
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (app()->environment() != 'local') {
|
||||
return abort(403, 'You are not authorized to access this');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
@ -59,16 +59,12 @@ class SecureHeaders
|
|||
config('app.debug') ? "https://{$host}:4443" : '',
|
||||
'https://yl.s-web.fr',
|
||||
]) . ';',
|
||||
"img-src 'self' data: blob: " . implode(' ', [
|
||||
// * VITE DEV
|
||||
config('app.debug') ? "https://{$host}:4443" : ''
|
||||
]) . ';',
|
||||
"img-src * https://yl.s-web.fr data: blob:;",
|
||||
'frame-src ' . implode(' ', [
|
||||
'https://www.google.com/recaptcha/',
|
||||
'https://recaptcha.google.com/recaptcha/',
|
||||
'https://www.google.com/maps/',
|
||||
'https://www.youtube.com',
|
||||
'https://player.vimeo.com',
|
||||
]) . ';',
|
||||
"font-src 'self' data: " . \implode(' ', [
|
||||
// * VITE DEV
|
||||
|
|
|
|||
|
|
@ -27,14 +27,14 @@ class UpdateConvictionpageRequest extends FormRequest
|
|||
public function rules()
|
||||
{
|
||||
return [
|
||||
'key_feed' => 'required|numeric|max:2147483647',
|
||||
'key_earth_1' => 'required|numeric|max:2147483647',
|
||||
'key_earth_2' => 'required|numeric|max:2147483647',
|
||||
'key_together_1' => 'required|numeric|max:2147483647',
|
||||
'key_together_2' => 'required|numeric|max:2147483647',
|
||||
'key_together_3' => 'required|numeric|max:2147483647',
|
||||
'key_together_4' => 'required|numeric|max:2147483647',
|
||||
'key_territory' => 'required|numeric|max:2147483647',
|
||||
'key_feed' => 'required|numeric',
|
||||
'key_earth_1' => 'required|numeric',
|
||||
'key_earth_2' => 'required|numeric',
|
||||
'key_together_1' => 'required|numeric',
|
||||
'key_together_2' => 'required|numeric',
|
||||
'key_together_3' => 'required|numeric',
|
||||
'key_together_4' => 'required|numeric',
|
||||
'key_territory' => 'required|numeric',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Homepage;
|
||||
|
||||
use App\Rules\IsValidVimeoId;
|
||||
use App\Rules\IsValidYoutubeId;
|
||||
use App\Traits\Requests\HasPicture;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
|
|
@ -28,9 +26,6 @@ class UpdateHomepageRequest extends FormRequest
|
|||
*/
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'display_video' => $this->boolean('display_video')
|
||||
]);
|
||||
$this->mergePicture('picture');
|
||||
}
|
||||
|
||||
|
|
@ -49,20 +44,10 @@ class UpdateHomepageRequest extends FormRequest
|
|||
'picture_title' => 'required|string|between:3,255',
|
||||
'presentation_title' => 'required|string|between:3,255',
|
||||
'presentation_content' => 'required|string',
|
||||
'display_video' => 'present|boolean',
|
||||
'video_id' => [
|
||||
'nullable', 'required_if:display_video,true',
|
||||
function (string $attribute, mixed $value, \Closure $fail) {
|
||||
if (!IsValidYoutubeId::validates($value) and !IsValidVimeoId::validates($value)) {
|
||||
(new IsValidYoutubeId())->validate($attribute, $value, $fail);
|
||||
(new IsValidVimeoId())->validate($attribute, $value, $fail);
|
||||
}
|
||||
}
|
||||
],
|
||||
];
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 640, 390, 640, 390, true, requiredIf: 'display_video,false'),
|
||||
$this->pictureRules('picture', 640, 390, 640, 390, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +59,6 @@ class UpdateHomepageRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'video_id' => trans('validation.custom.video_id'),
|
||||
'title_part1' => trans('validation.custom.title_part1'),
|
||||
'title_part2' => trans('validation.custom.title_part2'),
|
||||
'title_part3' => trans('validation.custom.title_part3'),
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Http\Requests\Bo\Joinuspage;
|
||||
|
||||
use App\Rules\IsValidVimeoId;
|
||||
use App\Rules\IsValidYoutubeId;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UpdateJoinuspageRequest extends FormRequest
|
||||
|
|
@ -26,15 +24,7 @@ class UpdateJoinuspageRequest extends FormRequest
|
|||
public function rules()
|
||||
{
|
||||
return [
|
||||
'video_id' => [
|
||||
'required', 'string',
|
||||
function (string $attribute, mixed $value, \Closure $fail) {
|
||||
if (!IsValidYoutubeId::validates($value) and !IsValidVimeoId::validates($value)) {
|
||||
(new IsValidYoutubeId())->validate($attribute, $value, $fail);
|
||||
(new IsValidVimeoId())->validate($attribute, $value, $fail);
|
||||
}
|
||||
}
|
||||
],
|
||||
'video_id' => 'required|string|regex:%([^"&?\/\s]{11})%i',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class StoreNewsRequest extends FormRequest
|
|||
'subtitle' => 'required|string|between:3,255',
|
||||
'content' => 'required|string|min:15',
|
||||
'published' => 'required|boolean',
|
||||
'publish_at' => 'required|date',
|
||||
'publish_at' => 'nullable|date',
|
||||
'unpublish_at' => 'nullable|date|after:publish_at',
|
||||
|
||||
];
|
||||
|
|
|
|||
|
|
@ -68,8 +68,8 @@ class StoreProductRequest extends FormRequest
|
|||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture_thumbnail', 332, 252, 332, 252, false),
|
||||
$this->pictureRules('picture_ambiance', 1115, 790, 1115, 790, false),
|
||||
$this->pictureRules('picture_packshot', 560, 480, 560, 480, false),
|
||||
$this->pictureRules('picture_ambiance', 774, 515, 774, 515, false),
|
||||
$this->pictureRules('picture_packshot', 327, 252, 327, 252, false),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -89,35 +89,35 @@ class StoreProductRequest extends FormRequest
|
|||
// phpcs:enable
|
||||
$nutritionnal_values = json_encode([
|
||||
"energyKj" => [
|
||||
"label" => "ÉNERGIE (kj)",
|
||||
"label" => "Energie en Kj",
|
||||
"value" => $this->nutritionnal_values['energy_kj'],
|
||||
],
|
||||
"energyKcal" => [
|
||||
"label" => "ÉNERGIE (kcal)",
|
||||
"label" => "Energie en kcal",
|
||||
"value" => $this->nutritionnal_values['energy_kcal'],
|
||||
],
|
||||
"fat" => [
|
||||
"label" => "MATIÈRES GRASSES (g)",
|
||||
"label" => "Matières grasses",
|
||||
"value" => $this->nutritionnal_values['fat'],
|
||||
],
|
||||
"saturated-fat" => [
|
||||
"label" => "ACIDES GRAS SATURÉS (g)",
|
||||
"label" => "dont acides gras saturés",
|
||||
"value" => $this->nutritionnal_values['saturated_fat'],
|
||||
],
|
||||
"carbohydrate" => [
|
||||
"label" => "GLUCIDES (g)",
|
||||
"label" => "Glucides",
|
||||
"value" => $this->nutritionnal_values['carbohydrate'],
|
||||
],
|
||||
"sugar" => [
|
||||
"label" => "SUCRES (g)",
|
||||
"label" => "dont sucres",
|
||||
"value" => $this->nutritionnal_values['sugar'],
|
||||
],
|
||||
"proteins" => [
|
||||
"label" => "PROTÉINES (g)",
|
||||
"label" => "Protéines",
|
||||
"value" => $this->nutritionnal_values['proteins'],
|
||||
],
|
||||
"salt" => [
|
||||
"label" => "SEL (g)",
|
||||
"label" => "Sel",
|
||||
"value" => $this->nutritionnal_values['salt'],
|
||||
]
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ class StoreRangeRequest extends FormRequest
|
|||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', 466, 440, 466, 440, false),
|
||||
$this->pictureRules('picture_productsheet', 680, 300, 680, 300, false),
|
||||
$this->pictureRules('picture_productsheet', 332, 442, 332, 442, false),
|
||||
$this->pictureRules('picture_thumbnail', 246, 337, 246, 337, false),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
*/
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
/** @var \App\Models\StaticPage $staticPageModel */
|
||||
$staticPageModel = $this->route('static_page');
|
||||
if (
|
||||
\in_array($staticPageModel->type, [
|
||||
\in_array($this->route('static_page')->type, [
|
||||
\App\Enums\StaticPageType::confidentiality,
|
||||
\App\Enums\StaticPageType::legals
|
||||
])
|
||||
|
|
|
|||
229
app/Http/Requests/Bo/UpdateMiniCrudRequest.php
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Bo;
|
||||
|
||||
use App\Enums\InputType;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
abstract class UpdateMiniCrudRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* The model parameter name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $modelName = null;
|
||||
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
* @phpcs:disable Generic.Metrics.NestingLevel.TooHigh
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
// phpcs:enable
|
||||
$rules = [];
|
||||
foreach ($this->{$this->modelName}->data as $iptName => $input) {
|
||||
$input = \json_decode(\json_encode($input), true);
|
||||
switch ($input['inputType']) {
|
||||
case InputType::number->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $this->compileValidate('required|numeric', $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::videoYoutube->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $this->compileValidate('regex:%([^"&?\/\s]{11})%i', $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::videoVimeo->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $this->compileValidate('regex:%([0-9]{8,10})%i', $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::video->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $this->compileValidate([
|
||||
'regex:%([0-9]{8,10}|[^"&?\/\s]{11})%i'
|
||||
], $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::string->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $this->compileValidate('required|string|min:3', $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::text->value:
|
||||
$mergeRules = $this->compileValidate('required|string|min:15', $input);
|
||||
$mergeRules = collect($mergeRules)
|
||||
->map(function ($rule) {
|
||||
if (\strpos($rule, 'max:') !== false) {
|
||||
$max = \intval(str_replace('max:', '', $rule));
|
||||
return function ($attribute, $value, $fail) use ($max) {
|
||||
if (\strlen(\strip_tags($value)) > $max) {
|
||||
$fail("$attribute ne doit pas excéder $max caractères");
|
||||
}
|
||||
};
|
||||
}
|
||||
return $rule;
|
||||
});
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => $mergeRules
|
||||
]);
|
||||
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(
|
||||
',',
|
||||
(isset($ipt['dimensionsMax']) and is_string($ipt['dimensionsMax'])) ?
|
||||
$ipt['dimensionsMax'] : $input['dimensions']
|
||||
))->mapWithKeys(function ($v) {
|
||||
$v = explode(' ', $v);
|
||||
return [$v[0] => $v[1]];
|
||||
}) : $input['dimensions'];
|
||||
|
||||
// * Adapt dimensions
|
||||
$sizes = (object)[
|
||||
'minHeight' => $dim['height'],
|
||||
'maxHeight' => $dim['height'],
|
||||
'minWith' => $dim['width'],
|
||||
'maxWith' => $dim['width'],
|
||||
];
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => [
|
||||
function (string $attribute, $value, callable $fail) use ($sizes) {
|
||||
return ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
|
||||
}
|
||||
],
|
||||
$this->compileValidate(
|
||||
implode('|', [
|
||||
$required,
|
||||
'image',
|
||||
'mimes:png,jpg,jpeg',
|
||||
sprintf(
|
||||
'dimensions:%s=%d,%s=%d',
|
||||
$max ? 'max_height' : 'height',
|
||||
$dim['height'],
|
||||
$max ? 'max_width' : 'width',
|
||||
$dim['width']
|
||||
)
|
||||
]),
|
||||
$input
|
||||
),
|
||||
"data.$iptName.alt" => $this->compileValidate("$required|string|min:5", $input),
|
||||
"data.$iptName.title" => $this->compileValidate("$required|string|min:5", $input)
|
||||
]);
|
||||
break;
|
||||
case InputType::url->value:
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => [
|
||||
'required', 'url',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
try {
|
||||
ToolboxHelper::assertNoInternalUrls($attribute, $value);
|
||||
ToolboxHelper::assertNoInternalBoUrls($attribute, $value);
|
||||
} catch (ValidationException $e) {
|
||||
$fail(collect($e->errors())->first()[0]);
|
||||
}
|
||||
}
|
||||
]
|
||||
]);
|
||||
break;
|
||||
case InputType::boolean->value:
|
||||
$all = $this->all();
|
||||
$nested = ToolboxHelper::dotStringToNestedArray(
|
||||
"data.$iptName.value",
|
||||
$this->input("data.$iptName.value") ? true : false
|
||||
);
|
||||
$all = ToolboxHelper::arrayMergeRecursiveDistinct($all, $nested);
|
||||
$this->merge($all);
|
||||
$rules = array_merge($rules, [
|
||||
"data.$iptName.value" => 'boolean'
|
||||
]);
|
||||
break;
|
||||
} //end switch
|
||||
} //end foreach
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Undocumented function
|
||||
*
|
||||
* @param string|array $inputTypeValidate
|
||||
* @param array $input
|
||||
* @return array
|
||||
*/
|
||||
public function compileValidate(string|array $inputTypeValidate, array $input): array
|
||||
{
|
||||
if (\is_string($inputTypeValidate)) {
|
||||
$inputTypeValidate = explode('|', $inputTypeValidate);
|
||||
}
|
||||
/** @var array|string */
|
||||
$inputValidate = \collect($input)->get('validate', $input);
|
||||
$inputValidate = \is_string($inputValidate) ? explode('|', $inputValidate) : $inputValidate;
|
||||
foreach ($inputValidate as $validate) {
|
||||
if (!\in_array($validate, $inputTypeValidate)) {
|
||||
$inputTypeValidate[] = $validate;
|
||||
}
|
||||
}
|
||||
|
||||
$test = \collect($inputTypeValidate)->all();
|
||||
$test = \collect($inputTypeValidate)->sort(function ($valueA, $valueB) {
|
||||
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
|
||||
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
|
||||
return $valueA - $valueB;
|
||||
})->unique()->all();
|
||||
|
||||
return \collect($inputTypeValidate)->unique()->sort(function ($valueA, $valueB) {
|
||||
$valueA = $this->ruleHasToComeFirst($valueA) ? 0 : 2;
|
||||
$valueB = $this->ruleHasToComeFirst($valueB) ? 1 : 2;
|
||||
return $valueA - $valueB;
|
||||
})->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the rulle need to come first ?
|
||||
*
|
||||
* @param string $rule
|
||||
* @return boolean
|
||||
*/
|
||||
private function ruleHasToComeFirst(string $rule): bool
|
||||
{
|
||||
$rule = \collect(\explode(':', $rule, 1))->filter()->first(null, '');
|
||||
return \collect([
|
||||
'nullable', 'present', 'required', 'required_if',
|
||||
'required_unless', 'required_with', 'required_with_all',
|
||||
'required_without', 'required_without_all', 'required_with_all',
|
||||
'missing', 'missing_if', 'missing_unless',
|
||||
'missing_with', 'missing_with_all',
|
||||
])->first(fn (string $firstRule) => \strpos($rule, $firstRule) === 0) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this request an update request ?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function isUpdate(): bool
|
||||
{
|
||||
return $this->isMethod('PUT');
|
||||
}
|
||||
}
|
||||
|
|
@ -3,9 +3,7 @@
|
|||
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;
|
||||
|
||||
|
|
@ -18,7 +16,7 @@ class StoreUserRequest extends FormRequest
|
|||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('create', User::class);
|
||||
return auth('backend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -26,10 +24,10 @@ class StoreUserRequest extends FormRequest
|
|||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->boolean('published')
|
||||
'published' => $this->published ? true : false
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,35 +2,23 @@
|
|||
|
||||
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(): void
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->boolean('published'),
|
||||
'password' => $this->input('password') ??
|
||||
\optional($this->route('user'))->password,
|
||||
'password_confirmation' => $this->input('password_confirmation') ??
|
||||
\optional($this->route('user'))->password
|
||||
'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
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -42,10 +30,10 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return array_merge(parent::rules(), [
|
||||
'email' => [
|
||||
'email' => [
|
||||
'required',
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
Rule::unique('users', 'email')->ignore(\optional($this->route('user'))->getRouteKey())
|
||||
'unique:users,email,' . $this->route('user')->getKey() . ',id',
|
||||
],
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ class ContactRequest extends FormRequest
|
|||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'accept_rules' => $this->boolean('accept_rules'),
|
||||
'send_data' => $this->boolean('send_data'),
|
||||
'accept_rules' => $this->accept_rules ? true : false,
|
||||
'send_data' => $this->send_data ? true : false,
|
||||
]);
|
||||
$this->mergePicture('file');
|
||||
}
|
||||
|
|
@ -31,11 +31,9 @@ class ContactRequest extends FormRequest
|
|||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
// phpcs:enable
|
||||
ToolboxHelper::validateRecaptcha($this, \config('services.google.recaptcha.version'));
|
||||
|
||||
$rules = [
|
||||
|
|
@ -45,96 +43,104 @@ class ContactRequest extends FormRequest
|
|||
'society' => 'sometimes|nullable|string|between:3,255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|max:255',
|
||||
'phone' => 'sometimes|nullable|numeric|min:0',
|
||||
'address' => 'required|string|between:3,255',
|
||||
'postal_code' => 'required|numeric|min:0',
|
||||
'city' => 'required|string|between:3,255',
|
||||
'address' => 'sometimes|nullable|string|between:3,255',
|
||||
'postal_code' => 'sometimes|nullable|numeric|min:0',
|
||||
'city' => 'sometimes|nullable|string|between:3,255',
|
||||
'object' => ['required', new Enum(ObjectEnum::class)],
|
||||
'message' => 'required|string|between:3,500',
|
||||
'product_name' => [
|
||||
'nullable', 'string', 'between:3,255',
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'required_with:product_date_limit,product_barcode,product_lot,product_date_consumption,product_location',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_name'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_date_limit' => [
|
||||
'sometimes', 'nullable', 'string', 'between:3,255',
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'required_with:product_name,product_barcode,product_lot,product_date_consumption,product_location',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_date_limit'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_barcode' => [
|
||||
'sometimes', 'nullable', 'numeric', 'min:0',
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'required_with:product_name,product_date_limit,product_lot,product_date_consumption,product_location',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_barcode'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_lot' => [
|
||||
'sometimes', 'nullable', 'numeric', 'min:0',
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'required_with:product_name,product_date_limit,product_barcode,product_date_consumption,product_location',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_lot'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_date_consumption' => [
|
||||
'sometimes', 'nullable', 'string', 'between:3,255',
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'required_with:product_name,product_date_limit,product_barcode,product_lot,product_location',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_date_consumption'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_location' => [
|
||||
'sometimes', 'nullable', 'string', 'between:3,255',
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'required_with:product_name,product_date_limit,product_barcode,product_lot,product_date_consumption',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_location'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'message' => 'required|string|between:3,255',
|
||||
'accept_rules' => 'required|boolean',
|
||||
'send_data' => 'required|boolean',
|
||||
];
|
||||
if ($this->object === strval(ObjectEnum::customerService->value())) {
|
||||
$rules = \array_merge($rules, [
|
||||
'product_name' => [
|
||||
'string', 'between:3,255', 'required',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_name'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_date_limit' => [
|
||||
'required', 'date',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_date_limit'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_barcode' => [
|
||||
'numeric', 'min:0', 'required',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_barcode'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_lot' => [
|
||||
'numeric', 'min:0', 'required',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_lot'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_date_consumption' => [
|
||||
'required', 'date',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_date_consumption'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
'product_location' => [
|
||||
'string', 'between:3,255', 'required',
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
if ($this->get("object") != ObjectEnum::customerService->value()) {
|
||||
$fail(\trans('le Champs :field doit être vide lorsque le champs objet
|
||||
n\'est pas égale à :enumValue.', [
|
||||
'field' => trans('validation.custom.product_location'),
|
||||
'enumValue' => ObjectEnum::customerService->label(),
|
||||
]));
|
||||
}
|
||||
}
|
||||
],
|
||||
]);
|
||||
} //end if
|
||||
if (
|
||||
isset(request()->file) and
|
||||
(request()->file->getClientMimeType() === "image/jpeg" ||
|
||||
|
|
@ -146,8 +152,8 @@ class ContactRequest extends FormRequest
|
|||
0,
|
||||
1920,
|
||||
1080,
|
||||
true,
|
||||
3000,
|
||||
true,
|
||||
'product_name,product_date_limit,product_barcode,product_lot,product_date_consumption,product_location'
|
||||
));
|
||||
} elseif (isset(request()->file) and (request()->file->getClientMimeType() === "application/pdf")) {
|
||||
|
|
@ -155,20 +161,6 @@ class ContactRequest extends FormRequest
|
|||
//phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'file' => 'sometimes|nullable|mimes:pdf|required_with:product_name,product_date_limit,product_barcode,product_lot,product_date_consumption,product_location'
|
||||
]);
|
||||
} elseif (
|
||||
isset(request()->file) and
|
||||
(request()->file->getClientMimeType() !== "application/pdf") and
|
||||
(request()->file->getClientMimeType() !== "image/jpeg") and
|
||||
(request()->file->getClientMimeType() !== "image/png")
|
||||
) {
|
||||
$rules = \array_merge($rules, [
|
||||
'file' => [
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
$fail(\trans('Le format du fichier doit être .jpg, .png ou .pdf'));
|
||||
}
|
||||
],
|
||||
]);
|
||||
} //end if
|
||||
return $rules;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class JoinusRequest extends FormRequest
|
|||
'first_name' => 'required|string|between:3,255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|max:255',
|
||||
'phone' => 'required|numeric|min:0',
|
||||
'message' => 'required|string|between:3,500',
|
||||
'message' => 'required|string|between:3,255',
|
||||
"file" => "sometimes|nullable|mimes:pdf|max:10000"
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class SeasonalSectionStatusUpdate
|
|||
*/
|
||||
public function handle()
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\SeasonalSection> */
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\SeasonalSections> */
|
||||
$seasonalsectionsListToPublish = SeasonalSection::query()
|
||||
->where('publish_at', '<=', Carbon::now()->toDateTime())
|
||||
->whereNotNull('publish_at')
|
||||
|
|
@ -30,7 +30,7 @@ class SeasonalSectionStatusUpdate
|
|||
$seasonalsections->published = true;
|
||||
$seasonalsections->saveOrFail();
|
||||
}
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\SeasonalSection> */
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<array-key, \App\Models\SeasonalSections> */
|
||||
$seasonalsectionsListToUnPublish = SeasonalSection::query()
|
||||
->where('unpublish_at', '<=', Carbon::now()->toDateTime())
|
||||
->whereNotNull('unpublish_at')
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ class ExceptionsHelper
|
|||
$traceStr .= self::handleArgs($stack);
|
||||
}
|
||||
$traceStr .= ")\n";
|
||||
} else {
|
||||
} elseif (isset($stack['function'])) {
|
||||
$traceStr .= "{$stack['function']}(";
|
||||
if (isset($stack['args'])) {
|
||||
$traceStr .= self::handleArgs($stack);
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ class FileStorageHelper
|
|||
);
|
||||
|
||||
return str_replace('/private/', '', $newPath);
|
||||
} //end if
|
||||
}//end if
|
||||
if (\is_object($file) and $file instanceof \SplFileInfo) {
|
||||
/** @var \SplFileInfo $file */
|
||||
$filename = $filename ?: $file->getBaseName();
|
||||
|
|
@ -309,6 +309,7 @@ class FileStorageHelper
|
|||
$private ? 'app/private/modelfiles' : 'app/public/modelfiles',
|
||||
$tableName,
|
||||
$filename,
|
||||
$private
|
||||
);
|
||||
$filename = self::getFileUniqueName($folderPath, $filename);
|
||||
return "{$folderPath}/{$filename}";
|
||||
|
|
@ -403,7 +404,7 @@ class FileStorageHelper
|
|||
$filename = Str::of($filename)->ltrim('.-');
|
||||
// * Optional beautification
|
||||
if ($beautify) {
|
||||
$filename = self::beautifyFilename($filename);
|
||||
$filename = static::beautifyFilename($filename);
|
||||
}
|
||||
// * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
||||
/** @var string */
|
||||
|
|
|
|||
|
|
@ -175,10 +175,11 @@ class ToolboxHelper
|
|||
$url = $match;
|
||||
try {
|
||||
$request = Request::create($url);
|
||||
// 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)) {
|
||||
// If a route is match then it do not throws exception.
|
||||
if (
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||
$routes->match($request)
|
||||
) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => trans(
|
||||
|
|
@ -204,14 +205,14 @@ class ToolboxHelper
|
|||
* @param array|string $replace
|
||||
* @param array|string $subject
|
||||
* @param integer $count
|
||||
* @return array|string|false
|
||||
* @return array|string
|
||||
*/
|
||||
public static function mbReplace(
|
||||
array|string $search,
|
||||
array|string $replace,
|
||||
array|string $subject,
|
||||
int &$count = 0
|
||||
): array|string|false {
|
||||
): array|string {
|
||||
if (!is_array($search) && is_array($replace)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -288,12 +289,9 @@ class ToolboxHelper
|
|||
public static function getOriginal(Model $model, string $attribute): mixed
|
||||
{
|
||||
if (\in_array('Spatie\Translatable\HasTranslations', \class_uses_recursive($model))) {
|
||||
// @phpstan-ignore-next-line
|
||||
return $model->getTranslation(
|
||||
$attribute,
|
||||
// @phpstan-ignore-next-line
|
||||
$model->getLocale(),
|
||||
// @phpstan-ignore-next-line
|
||||
$model->useFallbackLocale()
|
||||
);
|
||||
}
|
||||
|
|
@ -363,45 +361,47 @@ class ToolboxHelper
|
|||
/**
|
||||
* Convert deeply an object to array
|
||||
*
|
||||
* @param mixed $input
|
||||
* @param array|object $input
|
||||
* @return array
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function objectToArray(mixed $input): array
|
||||
public static function objectToArray($input): array
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (!(is_object($input) or is_array($input))) {
|
||||
if (is_object($input) or is_array($input)) {
|
||||
$ret = (array)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::objectToArray($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$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 mixed $input
|
||||
* @param array|object $input
|
||||
* @return object
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function arrayToObject(mixed $input): object
|
||||
public static function arrayToObject($input): object
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (!(is_object($input) or is_array($input))) {
|
||||
if (is_object($input) or is_array($input)) {
|
||||
$ret = (object)$input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::arrayToObject($item) : $item;
|
||||
}
|
||||
return $ret;
|
||||
} else {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$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 +409,11 @@ class ToolboxHelper
|
|||
*
|
||||
* @param string $attribute
|
||||
* @param string|null $value
|
||||
* @param callable $fail
|
||||
* @param callback $fail
|
||||
* @param object $sizes
|
||||
* @return void
|
||||
*/
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes): void
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes)
|
||||
{
|
||||
if (!($useStorage = Storage::exists($value)) and !File::exists($value)) {
|
||||
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
||||
|
|
@ -432,7 +432,7 @@ class ToolboxHelper
|
|||
'attribute' => $attribute
|
||||
]));
|
||||
}
|
||||
if (!($dimensions = \getimagesize($fileFullPath))) {
|
||||
if (!($dimensions = \getimagesize($fileFullPath)) or !isset($dimensions[0]) or !isset($dimensions[1])) {
|
||||
$fail(trans(':attribute impossible de valider les dimensions', [
|
||||
'attribute' => $attribute
|
||||
]));
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ namespace App\Mail;
|
|||
use App\Enums\Contact\ObjectEnum;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
use Illuminate\Mail\Mailables\Attachment;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
|
|
@ -16,7 +17,7 @@ class SendContactMail extends Mailable
|
|||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* @var \stdClass
|
||||
* @var \App\Mail\Contact
|
||||
*/
|
||||
private \stdClass $data;
|
||||
|
||||
|
|
@ -39,11 +40,16 @@ class SendContactMail extends Mailable
|
|||
*/
|
||||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
{
|
||||
$subject = ObjectEnum::make($this->data->object) ?
|
||||
ObjectEnum::make($this->data->object)->label() :
|
||||
__('Nouveau message');
|
||||
return new Envelope(
|
||||
subject: sprintf('%s - %s', $subject, config('app.name')),
|
||||
from: new Address(
|
||||
$this->data->email,
|
||||
($this->data->first_name !== null || $this->data->last_name !== null) ?
|
||||
(($this->data->first_name ?? '') . " " . ($this->data->last_name ?? '')) :
|
||||
null
|
||||
),
|
||||
to: [new Address(config('mail.from.address'), config('mail.from.name'))],
|
||||
subject: sprintf('%s - %s', ObjectEnum::make($this->data->object)->label() ??
|
||||
__('Nouveau message'), config('app.name')),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ namespace App\Mail;
|
|||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Address;
|
||||
use Illuminate\Mail\Mailables\Attachment;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
|
|
@ -15,7 +16,7 @@ class SendJoinusMail extends Mailable
|
|||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* @var \stdClass
|
||||
* @var \App\Mail\Joinus
|
||||
*/
|
||||
private \stdClass $data;
|
||||
|
||||
|
|
@ -24,6 +25,7 @@ class SendJoinusMail extends Mailable
|
|||
*
|
||||
* @param \stdClass $data
|
||||
* @return void
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
public function __construct(\stdClass $data)
|
||||
{
|
||||
|
|
@ -38,6 +40,13 @@ class SendJoinusMail extends Mailable
|
|||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
from: new Address(
|
||||
$this->data->email,
|
||||
($this->data->first_name !== null || $this->data->last_name !== null) ?
|
||||
(($this->data->first_name ?? '') . " " . ($this->data->last_name ?? '')) :
|
||||
null
|
||||
),
|
||||
to: [new Address(config('mail.from.address'), config('mail.from.name'))],
|
||||
subject: sprintf('%s - %s', __('Candidature spontanée'), config('app.name')),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,17 +3,18 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* @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 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 \Illuminate\Support\Carbon $created_at Created date.
|
||||
*
|
||||
* @property-read \App\Models\User $user User BelongsTo relation.
|
||||
*/
|
||||
|
|
@ -81,20 +82,19 @@ class ActivityLog extends Model
|
|||
$activity->model_id = $model->getKey();
|
||||
$activity->event = $eventEnum;
|
||||
$activity->data = static::getChangedColumns($activity, $model, $eventEnum);
|
||||
// @phpstan-ignore-next-line
|
||||
$activity->created_at = now();
|
||||
$activity->created_at = Carbon::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
|
||||
* @return array|null
|
||||
*/
|
||||
public static function getChangedColumns(self $activity, Model $model, ActivityLogsEventEnum $eventEnum): array
|
||||
public static function getChangedColumns(self $activity, Model $model, ActivityLogsEventEnum $eventEnum): array|null
|
||||
{
|
||||
$modelClassName = $activity->model_class;
|
||||
/** Get type of each fields of the target model */
|
||||
|
|
@ -103,17 +103,16 @@ class ActivityLog extends Model
|
|||
$activity->model_id
|
||||
)->first();
|
||||
if ($targetModel != null) {
|
||||
// phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
$targetModelTypes = collect($targetModel->toArray())
|
||||
// phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
->map(function ($field, $fieldIndex) use ($targetModel) {
|
||||
return Schema::getColumnType($targetModel->getTable(), $fieldIndex);
|
||||
})->toArray();
|
||||
// phpcs:enable
|
||||
/** Return old, new and type of values changed */
|
||||
return ($eventEnum === ActivityLogsEventEnum::updated) ?
|
||||
array_intersect_key($targetModelTypes, $model->getChanges()) : [];
|
||||
}
|
||||
return [];
|
||||
/** Return old, new and type of values changed */
|
||||
return ($eventEnum === ActivityLogsEventEnum::updated) ?
|
||||
array_intersect_key($targetModelTypes, $model->getChanges()) : null;
|
||||
}
|
||||
|
||||
// * RELATIONS
|
||||
|
|
@ -123,7 +122,7 @@ class ActivityLog extends Model
|
|||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function user(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,11 +11,9 @@ use Illuminate\Database\Eloquent\Model;
|
|||
* @property string $title_part1 Title part 1.
|
||||
* @property string $title_part2 Title part 2.
|
||||
* @property string $title_part3 Title part 3.
|
||||
* @property string|null $picture Path of the picture (640px * 390px).
|
||||
* @property string $picture Path of the picture (640px * 390px).
|
||||
* @property string $picture_alt Picture alt attribute.
|
||||
* @property string $picture_title Picture title attribute.
|
||||
* @property string $video_id The youtube or vimeo video Id.
|
||||
* @property boolean $display_video Wether to display video or picture.
|
||||
* @property string $presentation_title Presentation title.
|
||||
* @property string $presentation_content WYSIWYG - Presentation content.
|
||||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
|
|
@ -40,17 +38,6 @@ class Homepage extends Model
|
|||
'picture_title',
|
||||
'presentation_title',
|
||||
'presentation_content',
|
||||
'video_id',
|
||||
'display_video',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $casts = [
|
||||
'display_video' => 'bool'
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@ use App\Traits\Models\ActivityLog;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||
|
||||
/**
|
||||
* @property string $seo_title SEO title.
|
||||
|
|
@ -34,11 +31,10 @@ use Uwil\Seo\Laravel\Traits\SeoTrait;
|
|||
* @property-read \Carbon\Carbon $created_at Created date.
|
||||
* @property-read \Carbon\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class News extends Model implements SeoInterface
|
||||
class News extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use HasFactory;
|
||||
use SeoTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -202,22 +198,4 @@ class News extends Model implements SeoInterface
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// * SEO TRAIT OVERLOAD
|
||||
/**
|
||||
* Transform to seoModel
|
||||
*
|
||||
* @return \Uwil\Seo\Laravel\Objects\SeoItem
|
||||
*/
|
||||
public function toSeoItem(): SeoItem
|
||||
{
|
||||
return new SeoItem(
|
||||
\trans('models.classes.' . Str::singular($this->getTable())),
|
||||
$this->seo_title,
|
||||
$this->seo_description,
|
||||
$this->published ?? false,
|
||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
||||
$this->published ? \route('fo.' . $this->getTable() . '.show', $this) : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@ use App\Traits\Models\ActivityLog;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||
|
||||
/**
|
||||
* @phpcs:disable Generic.Files.LineLength.TooLong
|
||||
|
|
@ -44,11 +41,10 @@ use Uwil\Seo\Laravel\Traits\SeoTrait;
|
|||
* @property-read \App\Models\Range $range Range Belongs to relationship.
|
||||
* @phpcs:enable
|
||||
*/
|
||||
class Product extends Model implements SeoInterface
|
||||
class Product extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use HasFactory;
|
||||
use SeoTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -193,22 +189,4 @@ class Product extends Model implements SeoInterface
|
|||
{
|
||||
return $this->belongsToMany(Commitment::class);
|
||||
}
|
||||
|
||||
// * SEO TRAIT OVERLOAD
|
||||
/**
|
||||
* Transform to seoModel
|
||||
*
|
||||
* @return \Uwil\Seo\Laravel\Objects\SeoItem
|
||||
*/
|
||||
public function toSeoItem(): SeoItem
|
||||
{
|
||||
return new SeoItem(
|
||||
\trans('models.classes.' . Str::singular($this->getTable())),
|
||||
$this->seo_title,
|
||||
$this->seo_description,
|
||||
$this->published ?? false,
|
||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
||||
$this->published ? \route('fo.' . $this->getTable() . '.show', $this) : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@ use App\Traits\Models\ActivityLog;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||
|
||||
// phpcs:disable Generic.Files.LineLength.TooLong
|
||||
/**
|
||||
|
|
@ -25,7 +22,7 @@ use Uwil\Seo\Laravel\Traits\SeoTrait;
|
|||
* @property string $picture Path of the picture (466px * 440px).
|
||||
* @property string $picture_alt Picture alt attribute.
|
||||
* @property string $picture_title Picture title attribute.
|
||||
* @property string $picture_productsheet Path of the picture of the product sheet (680px * 300px).
|
||||
* @property string $picture_productsheet Path of the picture of the product sheet (332px * 442px).
|
||||
* @property string $picture_productsheet_alt Picture alt attribute of the product sheet.
|
||||
* @property string $picture_productsheet_title Picture title attribute of the product sheet.
|
||||
* @property string $picture_thumbnail Path of the thumbnail (246px * 337px).
|
||||
|
|
@ -39,11 +36,10 @@ use Uwil\Seo\Laravel\Traits\SeoTrait;
|
|||
* @property-read \App\Models\Products $products Products Has Many relationship.
|
||||
*/
|
||||
// phpcs:enable
|
||||
class Range extends Model implements SeoInterface
|
||||
class Range extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use HasFactory;
|
||||
use SeoTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -174,22 +170,4 @@ class Range extends Model implements SeoInterface
|
|||
{
|
||||
return $this->hasMany(Product::class);
|
||||
}
|
||||
|
||||
// * SEO TRAIT OVERLOAD
|
||||
/**
|
||||
* Transform to seoModel
|
||||
*
|
||||
* @return \Uwil\Seo\Laravel\Objects\SeoItem
|
||||
*/
|
||||
public function toSeoItem(): SeoItem
|
||||
{
|
||||
return new SeoItem(
|
||||
\trans('models.classes.' . Str::singular($this->getTable())),
|
||||
$this->seo_title,
|
||||
$this->seo_description,
|
||||
$this->published ?? false,
|
||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
||||
$this->published ? \route('fo.' . $this->getTable() . '.show', $this) : ''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ namespace App\Models;
|
|||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
/**
|
||||
* @property string $picture Path of the picture (120px * 120px).
|
||||
|
|
@ -55,14 +54,9 @@ class Stamp extends Model
|
|||
});
|
||||
static::updated(function (self $model) {
|
||||
FileStorageHelper::removeOldFile($model, 'picture');
|
||||
Cache::forget('randomStampsFooter');
|
||||
});
|
||||
static::deleted(function (self $model) {
|
||||
FileStorageHelper::removeFile($model, 'picture');
|
||||
Cache::forget('randomStampsFooter');
|
||||
});
|
||||
static::created(function () {
|
||||
Cache::forget('randomStampsFooter');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@ use App\Traits\Models\ActivityLog;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Str;
|
||||
use Uwil\Seo\Laravel\Interfaces\SeoInterface;
|
||||
use Uwil\Seo\Laravel\Objects\SeoItem;
|
||||
use Uwil\Seo\Laravel\Traits\SeoTrait;
|
||||
|
||||
/**
|
||||
* @property \App\Enums\StaticPageType $type Page type (StaticPageEnum).
|
||||
|
|
@ -22,11 +19,10 @@ use Uwil\Seo\Laravel\Traits\SeoTrait;
|
|||
* @property-read \Illuminate\Support\Carbon $created_at Created date.
|
||||
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
|
||||
*/
|
||||
class StaticPage extends Model implements SeoInterface
|
||||
class StaticPage extends Model
|
||||
{
|
||||
use ActivityLog;
|
||||
use HasFactory;
|
||||
use SeoTrait;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
|
@ -61,7 +57,7 @@ class StaticPage extends Model implements SeoInterface
|
|||
});
|
||||
static::updating(function (self $model) {
|
||||
// * ASSERTIONS
|
||||
self::assertTitleIsUnique($model->title, $model->id);
|
||||
static::assertTitleIsUnique($model->title, $model->id);
|
||||
|
||||
// * CHANGES
|
||||
$model->slug = Str::slug($model->title);
|
||||
|
|
@ -87,22 +83,4 @@ class StaticPage extends Model implements SeoInterface
|
|||
ToolboxHelper::assertFieldIsUnique($table, 'title', $title, $id);
|
||||
ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($title), $id);
|
||||
}
|
||||
|
||||
// * SEO TRAIT OVERLOAD
|
||||
/**
|
||||
* Transform to seoModel
|
||||
*
|
||||
* @return \Uwil\Seo\Laravel\Objects\SeoItem
|
||||
*/
|
||||
public function toSeoItem(): SeoItem
|
||||
{
|
||||
return new SeoItem(
|
||||
\trans('models.classes.' . Str::singular($this->getTable())),
|
||||
$this->seo_title,
|
||||
$this->seo_description,
|
||||
true,
|
||||
\route(\config('seo.bo_route_prefix') . $this->getTable() . '.edit', $this),
|
||||
''
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ 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;
|
||||
|
|
@ -73,7 +72,7 @@ class User extends Authenticatable
|
|||
protected static function booted(): void
|
||||
{
|
||||
static::creating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
static::updatePassword($model);
|
||||
// * Prevent user elevation privileges
|
||||
throw_if(
|
||||
auth('backend')->user() and auth('backend')->user()->role->value() > $model->role->value(),
|
||||
|
|
@ -81,7 +80,7 @@ class User extends Authenticatable
|
|||
);
|
||||
});
|
||||
static::updating(function (self $model) {
|
||||
self::updatePassword($model);
|
||||
static::updatePassword($model);
|
||||
if (optional(auth('backend')->user())->getKey() === $model->getKey()) {
|
||||
\validator(
|
||||
['published' => $model->published],
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class TranslationServiceProvider extends ServiceProvider
|
|||
/**
|
||||
* Gather provided langs checking from files
|
||||
*
|
||||
* @return \Illuminate\Support\Collection<int, string>
|
||||
* @return \Illuminate\Support\Collection<string, string>
|
||||
*/
|
||||
private function collectLocalesStrings(): Collection
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ namespace App\Providers;
|
|||
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
|
@ -21,7 +20,6 @@ class ViewServiceProvider extends ServiceProvider
|
|||
$appInfos = Cache::remember('composer', 360, function () {
|
||||
return json_decode(File::get(\app_path('../composer.json')));
|
||||
});
|
||||
|
||||
// Share composer.json infos.
|
||||
if (isset($appInfos->name) and isset($appInfos->version)) {
|
||||
View::share('cpsr_name', $appInfos->name);
|
||||
|
|
@ -30,33 +28,12 @@ class ViewServiceProvider extends ServiceProvider
|
|||
|
||||
if (!app()->runningInConsole()) {
|
||||
// * FORCE BOOTSTRAP PAGINATOR (or custom if in front)
|
||||
// For the moment, we exclude the seo page because the new pagination system doesn't work in the package.
|
||||
if (
|
||||
collect(explode('/', \request()->getPathInfo()))->get(1) === 'bo' &&
|
||||
collect(explode('/', \request()->getPathInfo()))->last() !== 'seo'
|
||||
) {
|
||||
// Early boot, request wont be filled as expected.
|
||||
if (collect(explode('/', \request()->getPathInfo()))->get(1) === 'bo') {
|
||||
Paginator::defaultView('bo.modules.pagination');
|
||||
} else {
|
||||
Paginator::useBootstrapFive();
|
||||
}
|
||||
|
||||
// Get all the stamps that are pubished.
|
||||
$stamps = Cache::remember('randomStampsFooter', 360, function () {
|
||||
return DB::table('stamps')
|
||||
->select('picture', 'picture_alt', 'picture_title')
|
||||
->where('published', true)
|
||||
->get();
|
||||
});
|
||||
/**
|
||||
* Share a collection of 1 or 2 random stamps for footer.
|
||||
* First, check if $stamps is not empty, if not,
|
||||
* we count if the number of stamp in $stamps is greater than 2.
|
||||
* Then, pick 1 or 2 stamp(s) depending on the number of stamps.
|
||||
*/
|
||||
View::share(
|
||||
'randomStampsFooter',
|
||||
$stamps->isNotEmpty() ? $stamps->random($stamps->count() >= 2 ? 2 : 1) : []
|
||||
);
|
||||
} //end if
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
<?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}$/');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
<?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]$/');
|
||||
}
|
||||
}
|
||||
|
|
@ -37,16 +37,18 @@ trait ChangesModelOrder
|
|||
|
||||
return DB::transaction(function () use ($request, $className, $model) {
|
||||
/** @var \Illuminate\Database\Eloquent\Model|null */
|
||||
$tmp = $className::where('order', $request->direction ? '<' : '>', $model->getOriginal('order'))
|
||||
$tmp = $className::where('order', $request->direction ? '<' : '>', $model->order)
|
||||
->orderBy('order', $request->direction ? 'DESC' : 'ASC')->first();
|
||||
|
||||
if (!$tmp) {
|
||||
return back()->with('error', trans('crud.messages.order_not_changed'));
|
||||
}
|
||||
|
||||
$newOrder = $tmp->getOriginal('order');
|
||||
$tmp->update(['order' => $model->getOriginal('order')]);
|
||||
$model->update(['order' => $newOrder]);
|
||||
$newOrder = $tmp->order;
|
||||
$tmp->order = $model->order;
|
||||
$model->order = $newOrder;
|
||||
$tmp->saveOrFail();
|
||||
$model->saveOrFail();
|
||||
Session::flash('success', trans('crud.messages.order_changed'));
|
||||
|
||||
return back();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ trait UpdateModelPublished
|
|||
*/
|
||||
public function changePublished(Model $model)
|
||||
{
|
||||
$model->update(['published' => !$model->getOriginal('published')]);
|
||||
$model->published = !$model->published;
|
||||
$model->saveOrFail();
|
||||
return redirect()->back()->with('success', trans(__('crud.messages.publish_status_saved')));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,9 +118,9 @@ trait BaseEnum
|
|||
/**
|
||||
* Fetch enum using value.
|
||||
*
|
||||
* @param self|integer|string $value
|
||||
* @param string $field
|
||||
* @return self|null
|
||||
* @param \App\Traits\Enums\BaseEnum|integer|string $value
|
||||
* @param string $field
|
||||
* @return \App\Traits\Enums\BaseEnum|null
|
||||
*/
|
||||
public static function make(self|int|string $value, string $field = 'value'): self|null
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ use Illuminate\Support\Facades\Cache;
|
|||
/**
|
||||
* ! Use this only on limited elements, (not on tags, or products, or posts for ex.)
|
||||
*
|
||||
* @property array<string,string|integer|float|boolean> $cacheConditions
|
||||
* Eloquent condition to cache elements (to be used in where statement).
|
||||
* @property private static array $cacheConditions Eloquent condition to cache elements (to be used in where statement).
|
||||
*/
|
||||
trait IsCachedAsCollection
|
||||
{
|
||||
|
|
|
|||
180
app/Traits/Models/MiniCrudModel.php
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
|
||||
namespace App\Traits\Models;
|
||||
|
||||
use App\Enums\InputType;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
|
||||
trait MiniCrudModel
|
||||
{
|
||||
/**
|
||||
* Fill the model with an array of attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
* @throws \Illuminate\Database\Eloquent\MassAssignmentException If fill prop is not allowed.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
|
||||
*/
|
||||
public function fill(array $attributes)
|
||||
{
|
||||
// phpcs:enable
|
||||
parent::fill($attributes);
|
||||
if (isset($attributes['data'])) {
|
||||
$this->setData($attributes['data']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply function on data typed text while on save event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function minicrudCreating()
|
||||
{
|
||||
/** @var array<string,array> */
|
||||
$data = $this->data;
|
||||
foreach ($data as &$input) {
|
||||
switch ($input['inputType']) {
|
||||
case InputType::text->value:
|
||||
$input['text'] = clean($input['text']);
|
||||
$input['text'] = FileStorageHelper::storeModelFilesFromHtml($this, $input['text']);
|
||||
break;
|
||||
} //end switch
|
||||
} //end foreach
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply function on data typed text while on update event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function minicrudUpdating()
|
||||
{
|
||||
$this->minicrudCreating();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply function on data typed text while on updated event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function minicrudUpdated()
|
||||
{
|
||||
/** @var array */
|
||||
foreach ($this->data as $index => $input) {
|
||||
switch ($input['inputType']) {
|
||||
case InputType::text->value:
|
||||
$original = ToolboxHelper::getOriginal($this, 'data');
|
||||
FileStorageHelper::removeOldModelFilesFromHtml(
|
||||
$input['text'],
|
||||
$original[$index]['text'] ?? ''
|
||||
);
|
||||
break;
|
||||
} //end switch
|
||||
} //end foreach
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply function on data typed text while on deleted event
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function minicrudDeleted()
|
||||
{
|
||||
/** @var array */
|
||||
foreach ($this->data as $input) {
|
||||
switch ($input['inputType']) {
|
||||
case InputType::text->value:
|
||||
FileStorageHelper::removeModelFilesOfHtml($input['text']);
|
||||
break;
|
||||
} //end switch
|
||||
} //end foreach
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific prop
|
||||
*
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
private function setData(array $data): void
|
||||
{
|
||||
$attrs = $this->attributes;
|
||||
if (isset($attrs['data'])) {
|
||||
unset($attrs['data']);
|
||||
}
|
||||
$this->setAttribute('data', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific prop
|
||||
*
|
||||
* @param array $value
|
||||
* @return void
|
||||
*/
|
||||
protected function setDataAttribute(array $value): void
|
||||
{
|
||||
$this->attributes['data'] = $this->castAttributeAsJson(
|
||||
'data',
|
||||
$this->serializeData($value)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a specific prop
|
||||
*
|
||||
* @param string|null $data
|
||||
* @return array
|
||||
*/
|
||||
protected function getDataAttribute(string|null $data): array
|
||||
{
|
||||
return $this->fromJson($data ?? $this->attributes['data'] ?? '[]');
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize properties
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @throws \ErrorException If input type is no handled.
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
private function serializeData(array $data): array
|
||||
{
|
||||
foreach ($data as $o => $input) {
|
||||
switch ($input['inputType']) {
|
||||
case InputType::image->value:
|
||||
$data[$o]['value'] = \preg_replace(
|
||||
'/^\/|^/',
|
||||
'',
|
||||
FileStorageHelper::storeFile($this, $input['value'], true)
|
||||
);
|
||||
break;
|
||||
case InputType::selectEnum->value:
|
||||
case InputType::boolean->value:
|
||||
case InputType::password->value:
|
||||
case InputType::email->value:
|
||||
case InputType::number->value:
|
||||
case InputType::videoVimeo->value:
|
||||
case InputType::videoYoutube->value:
|
||||
case InputType::video->value:
|
||||
break;
|
||||
case InputType::string->value:
|
||||
case InputType::text->value:
|
||||
case InputType::url->value:
|
||||
ToolboxHelper::assertNoInternalBoUrls('content', $input['value']);
|
||||
break;
|
||||
default:
|
||||
throw new \ErrorException(sprintf(
|
||||
'Unknown input Type %s',
|
||||
$input['inputType']
|
||||
));
|
||||
} //end switch
|
||||
} //end foreach
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
|
@ -45,11 +45,9 @@ trait HasPicture
|
|||
* @param integer|null $minHeight
|
||||
* @param integer|null $maxWith
|
||||
* @param integer|null $maxHeight
|
||||
* @param boolean $nullable
|
||||
* @param integer|null $size
|
||||
* @param boolean $nullable
|
||||
* @param string|null $requiredWith
|
||||
* @param string|null $requiredWithout
|
||||
* @param string|null $requiredIf
|
||||
* @return array
|
||||
*/
|
||||
public function pictureRules(
|
||||
|
|
@ -58,11 +56,9 @@ trait HasPicture
|
|||
?int $minHeight = null,
|
||||
?int $maxWith = null,
|
||||
?int $maxHeight = null,
|
||||
bool $nullable = false,
|
||||
?int $size = null,
|
||||
bool $nullable = false,
|
||||
?string $requiredWith = null,
|
||||
?string $requiredWithout = null,
|
||||
?string $requiredIf = null,
|
||||
): array {
|
||||
$dimensions = (object)[
|
||||
'minWith' => $minWith ?? $this->minWith,
|
||||
|
|
@ -73,12 +69,10 @@ trait HasPicture
|
|||
return [
|
||||
$name => [
|
||||
!$nullable ? 'required' : 'nullable',
|
||||
(!empty($requiredWith)) ? "required_with:{$requiredWith}" : '',
|
||||
(!empty($requiredWithout)) ? "required_without:{$requiredWithout}" : '',
|
||||
(!empty($requiredIf)) ? "required_if:{$requiredIf}" : '',
|
||||
($size) ? "max:{$size}" : '',
|
||||
(strlen($requiredWith)) ? 'required_with:' . $requiredWith : '',
|
||||
($size) ? 'max:' . $size : '',
|
||||
function (string $attribute, $value, callable $fail) use ($dimensions) {
|
||||
ToolboxHelper::validatePicture($attribute, $value, $fail, $dimensions);
|
||||
return ToolboxHelper::validatePicture($attribute, $value, $fail, $dimensions);
|
||||
}
|
||||
]
|
||||
];
|
||||
|
|
@ -113,7 +107,7 @@ trait HasPicture
|
|||
"{$name}Validate.*" => [
|
||||
'required',
|
||||
function (string $attribute, $value, callable $fail) use ($sizes) {
|
||||
ToolboxHelper::validatePicture($attribute, $value, $fail, $sizes);
|
||||
return $this->validatePicture($attribute, $value, $fail, $sizes);
|
||||
}
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,26 +1,22 @@
|
|||
{
|
||||
"name": "uwil/agis",
|
||||
"version": "2.0.0",
|
||||
"version": "1.0.0",
|
||||
"type": "project",
|
||||
"description": "Agis website.",
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"diglactic/laravel-breadcrumbs": "^8.0",
|
||||
"doctrine/dbal": "^3.7",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^10.0",
|
||||
"laravel/tinker": "^2.8",
|
||||
"laravel/ui": "^4.2",
|
||||
"ldc/sitemap-generator": "^2.0",
|
||||
"ldc/web-admin-secure-laravel": "^2.0",
|
||||
"mews/purifier": "^3.4",
|
||||
"sentry/sentry-laravel": "*",
|
||||
"uwil/k8s-laravel": "^1.2",
|
||||
"uwil/seo-laravel": "^2.0"
|
||||
"sentry/sentry-laravel": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"larastan/larastan": "^2.8",
|
||||
"kitloong/laravel-migrations-generator": "^6.8",
|
||||
"krlove/eloquent-model-generator": "dev-l10-compatibility",
|
||||
"laravel-lang/common": "^4.0",
|
||||
"laravel/pint": "^1.0",
|
||||
"laravel/sail": "^1.18",
|
||||
|
|
@ -28,7 +24,8 @@
|
|||
"nunomaduro/collision": "^7.0",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"slevomat/coding-standard": "^8.10",
|
||||
"spatie/laravel-ignition": "^2.0"
|
||||
"spatie/laravel-ignition": "^2.0",
|
||||
"thedoctor0/laravel-factory-generator": "^1.2"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
@ -39,8 +36,8 @@
|
|||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "https://lab.s-web.fr/api/v4/group/23/-/packages/composer/packages.json"
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/laravel-shift/eloquent-model-generator.git"
|
||||
}
|
||||
],
|
||||
"autoload-dev": {
|
||||
|
|
|
|||
4752
composer.lock
generated
|
|
@ -96,10 +96,6 @@ return [
|
|||
'name' => env('MAIL_FROM_NAME', 'Example'),
|
||||
],
|
||||
|
||||
'contactform' => [
|
||||
'receiver' => explode(',', env('MAIL_CONTACTFORM_RECEIVER', 'hello@example.com'))
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Markdown Mail Settings
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'bo_route_prefix' => 'bo.',
|
||||
'blade' => 'bo.pages.seo.index',
|
||||
'middlewares' => [
|
||||
'web',
|
||||
'admin-secure',
|
||||
'auth:backend'
|
||||
],
|
||||
'guard' => 'backend'
|
||||
];
|
||||
|
|
@ -38,8 +38,4 @@ return [
|
|||
'version' => env('GOOGLE_RECAPTCHA_VERSION', "3") === "3" ? true : false
|
||||
]
|
||||
],
|
||||
|
||||
'matomo' => [
|
||||
'site_id' => env('MATOMO_SITE_ID')
|
||||
]
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,101 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Spatie\Sitemap\Tags\Url;
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* A list of url to ignore
|
||||
* These are hard coded
|
||||
* Each url does not have to be exhaustive
|
||||
*
|
||||
* For example, if you want to ignore all routes
|
||||
* of the backoffice group
|
||||
* just add 'bo' into this table
|
||||
*
|
||||
* * Note that this can take route names (both partially or full)
|
||||
* * You can use a wild card just as for routeIs method
|
||||
*/
|
||||
'ignoreRoutes' => [
|
||||
'back.*',
|
||||
'bo.*',
|
||||
'fo.verification.*',
|
||||
'fo.password.*',
|
||||
'front.frame',
|
||||
'cspReportUri',
|
||||
],
|
||||
|
||||
/**
|
||||
* This should be filled using the command `php artisan sitemap:install-completer`
|
||||
*
|
||||
* 'completeWith' => [CLASS, 'METHOD'],
|
||||
* eg : 'completeWith' => [CompleteSitemapWith::class, 'append'],
|
||||
*
|
||||
* This should point to a static method which will be called with the folowing parameter
|
||||
* (LDC\SitemapGenerator\Lib\Sitemap $sitemap)
|
||||
*
|
||||
* You may now use $sitemap->addLinks('route.myRouteName', string[] $links)
|
||||
*/
|
||||
'completeWith' => null,
|
||||
|
||||
/**
|
||||
* The default route frequency to use with sitemap generator
|
||||
*/
|
||||
'routeDefaultFrequency' => Url::CHANGE_FREQUENCY_DAILY,
|
||||
|
||||
/**
|
||||
* The default route priority to use with sitemap generator
|
||||
*
|
||||
* priority should be a number between 0 and 1
|
||||
* https://www.sitemaps.org/protocol.html
|
||||
*/
|
||||
'routeDefaultPriority' => 0.5,
|
||||
|
||||
/**
|
||||
* Frequencies for routes
|
||||
* use the full or partial route name as index
|
||||
* and a frequency within \Spatie\Sitemap\Tags\Url constants
|
||||
*
|
||||
* eg: 'engagments.*' => \Spatie\Sitemap\Tags\Url::CHANGE_FREQUENCY_HOURLY
|
||||
*/
|
||||
'routeFrequencies' => [],
|
||||
|
||||
/**
|
||||
* Priorities for routes
|
||||
* use the full or partial route name as index
|
||||
* and a priority in 1.0, 0.9, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, and 0.0.
|
||||
*
|
||||
* 1.0 is the Highest
|
||||
*
|
||||
* eg: 'engagments.*' => 1.0
|
||||
*/
|
||||
'routePriorities' => [],
|
||||
|
||||
/**
|
||||
* Enable or disable schedule for the job
|
||||
* If set to true the sitemap generator will be run
|
||||
* using the 'cron' instruction
|
||||
*/
|
||||
'schedule' => true,
|
||||
|
||||
/**
|
||||
* If you want to set specific
|
||||
* instruction for when to schedule job
|
||||
* you can set this with a cron instruction
|
||||
* You can generate one using https://crontab.guru/
|
||||
*
|
||||
* schedule must be set to true
|
||||
*
|
||||
* Default is every day at 15:45
|
||||
*/
|
||||
'cron' => '45 15 * * *',
|
||||
|
||||
/**
|
||||
* The sitemap generator can execute JavaScript on each page so it will
|
||||
* discover links that are generated by your JS scripts. This feature
|
||||
* is powered by headless Chrome.
|
||||
*
|
||||
* ! This needs pupetter installed with npm : npm i puppeteer (not to put in dev dependencies)
|
||||
*/
|
||||
'executeJavascript' => false,
|
||||
];
|
||||
|
|
@ -20,35 +20,35 @@ class ProductFactory extends Factory
|
|||
|
||||
$nutritionnal_values = [
|
||||
'energyKj' => [
|
||||
'label' => 'ÉNERGIE (kj)',
|
||||
'label' => 'Energie en Kj',
|
||||
'value' => fake()->randomFloat(2, 0, 70)
|
||||
],
|
||||
'energyKcal' => [
|
||||
'label' => 'ÉNERGIE (kcal)',
|
||||
'label' => 'Energie en kcal',
|
||||
'value' => fake()->randomFloat(2, 0, 70)
|
||||
],
|
||||
'fat' => [
|
||||
'label' => 'MATIÈRES GRASSES (g)',
|
||||
'label' => 'Matières grasses',
|
||||
'value' => fake()->randomFloat(2, 0, 70)
|
||||
],
|
||||
'saturated-fat' => [
|
||||
'label' => 'ACIDES GRAS SATURÉS (g)',
|
||||
'label' => 'dont acides gras saturés',
|
||||
'value' => fake()->randomFloat(2, 0, 70)
|
||||
],
|
||||
'carbohydrate' => [
|
||||
'label' => 'GLUCIDES (g)',
|
||||
'label' => 'Glucides',
|
||||
'value' => fake()->randomFloat(2, 0, 70)
|
||||
],
|
||||
'sugar' => [
|
||||
'label' => 'SUCRES (g)',
|
||||
'label' => 'dont sucres',
|
||||
'value' => fake()->randomFloat(2, 0, 70)
|
||||
],
|
||||
'proteins' => [
|
||||
'label' => 'PROTÉINES (g)',
|
||||
'label' => 'Protéines',
|
||||
'value' => fake()->randomFloat(2, 0, 70)
|
||||
],
|
||||
'salt' => [
|
||||
'label' => 'SEL (g)',
|
||||
'label' => 'Sel',
|
||||
'value' => fake()->randomFloat(2, 0, 70)
|
||||
],
|
||||
];
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class UserFactory extends Factory
|
|||
*/
|
||||
public function unverified(): static
|
||||
{
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
return $this->state(fn (array $attributes) => [
|
||||
'email_verified_at' => null,
|
||||
]);
|
||||
|
|
|
|||
BIN
database/factories/assets/ranges/default-picture-332x442.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
|
@ -15,14 +15,14 @@ return new class extends Migration
|
|||
{
|
||||
Schema::create('convictionpages', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->float('key_feed', 12)->comment('Chiffre clé \'bien nourrir\'');
|
||||
$table->float('key_earth_1', 12)->comment('Chiffre clé \'respecter la terre\' 1');
|
||||
$table->float('key_earth_2', 12)->comment('Chiffre clé \'respecter la terre\' 2');
|
||||
$table->float('key_together_1', 12)->comment('Chiffre clé \'vivre ensemble\' 1');
|
||||
$table->float('key_together_2', 12)->comment('Chiffre clé \'vivre ensemble\' 2');
|
||||
$table->float('key_together_3', 12)->comment('Chiffre clé \'vivre ensemble\' 3');
|
||||
$table->float('key_together_4', 12)->comment('Chiffre clé \'vivre ensemble\' 4');
|
||||
$table->float('key_territory', 12)->comment('Chiffre clé \'intégrer son territoire\'');
|
||||
$table->float('key_feed')->comment('Chiffre clé \'bien nourrir\'');
|
||||
$table->float('key_earth_1')->comment('Chiffre clé \'respecter la terre\' 1');
|
||||
$table->float('key_earth_2')->comment('Chiffre clé \'respecter la terre\' 2');
|
||||
$table->float('key_together_1')->comment('Chiffre clé \'vivre ensemble\' 1');
|
||||
$table->float('key_together_2')->comment('Chiffre clé \'vivre ensemble\' 2');
|
||||
$table->float('key_together_3')->comment('Chiffre clé \'vivre ensemble\' 3');
|
||||
$table->float('key_together_4')->comment('Chiffre clé \'vivre ensemble\' 4');
|
||||
$table->float('key_territory')->comment('Chiffre clé \'intégrer son territoire\'');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ return new class extends Migration
|
|||
$table->string('picture_alt')->comment('Attribut alt pour l\'image picture');
|
||||
$table->string('picture_title')->comment('Attribut title pour l\'image picture');
|
||||
$table->string('picture_productsheet')
|
||||
->comment('Path de l\'image à afficher sur les fiches produits de cette gamme (680px * 300px)');
|
||||
->comment('Path de l\'image à afficher sur les fiches produits de cette gamme (332px * 442px)');
|
||||
$table->string('picture_productsheet_alt')
|
||||
->comment('Attribut alt de l\'image à afficher sur les fiches produits');
|
||||
$table->string('picture_productsheet_title')
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('homepages', function (Blueprint $table) {
|
||||
$table->string('picture')->nullable()->change()
|
||||
->comment('Path de l\'image de la page d\'accueil (640px * 390px)');
|
||||
$table->string('youtube_video_id')->after('picture_title')
|
||||
->nullable()
|
||||
->default(null)
|
||||
->comment('L\ídentifiant de la vidéo Youtube');
|
||||
$table->boolean('display_video')->after('youtube_video_id')
|
||||
->default(false)
|
||||
->comment('Afficher la video ou l\'image');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('homepages', function (Blueprint $table) {
|
||||
$table->string('picture')->change()
|
||||
->comment('Path de l\'image de la page d\'accueil (640px * 390px)');
|
||||
$table->dropColumn('youtube_video_id');
|
||||
$table->dropColumn('display_video');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('homepages', function (Blueprint $table) {
|
||||
$table->renameColumn('youtube_video_id', 'video_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('homepages', function (Blueprint $table) {
|
||||
$table->renameColumn('video_id', 'youtube_video_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -21,7 +21,7 @@ class RangeSeeder extends Seeder
|
|||
'../database/factories/assets/ranges/default-picture-466x440.png'
|
||||
)));
|
||||
$range->picture_productsheet = FileStorageHelper::storeFile($range, new \SplFileInfo(\resource_path(
|
||||
'../database/factories/assets/ranges/default-picture-680x300.png'
|
||||
'../database/factories/assets/ranges/default-picture-332x442.png'
|
||||
)));
|
||||
$range->picture_thumbnail = FileStorageHelper::storeFile($range, new \SplFileInfo(\resource_path(
|
||||
'../database/factories/assets/ranges/default-picture-246x337.png'
|
||||
|
|
|
|||
177
manifest.yaml
|
|
@ -1,177 +0,0 @@
|
|||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
data:
|
||||
APP_NAME: "${APP_APP_NAME}"
|
||||
APP_ENV: "${APP_APP_ENV}"
|
||||
APP_KEY: "${APP_APP_KEY}"
|
||||
APP_DEBUG: "${APP_APP_DEBUG}"
|
||||
APP_URL: "https://www.${APP_DOMAIN}"
|
||||
LOG_CHANNEL: "k8s"
|
||||
DB_HOST: "mariadb-service.common-services"
|
||||
DB_DATABASE: "${APP_DB_DATABASE}"
|
||||
DB_USERNAME: "${APP_DB_USERNAME}"
|
||||
DB_PASSWORD: "${APP_DB_PASSWORD}"
|
||||
MAIL_HOST: "${APP_MAIL_HOST}"
|
||||
MAIL_PORT: "${APP_MAIL_PORT}"
|
||||
MAIL_USERNAME: "${APP_MAIL_USERNAME}"
|
||||
MAIL_PASSWORD: "${APP_MAIL_PASSWORD}"
|
||||
MAIL_ENCRYPTION: "${APP_MAIL_ENCRYPTION}"
|
||||
MAIL_FROM_ADDRESS: "${APP_MAIL_FROM_ADDRESS}"
|
||||
MAIL_FROM_NAME: "${APP_APP_NAME}"
|
||||
MAIL_CONTACTFORM_RECEIVER: "${APP_MAIL_CONTACTFORM_RECEIVER}"
|
||||
LDC_WEB_API_KEY: "${APP_LDC_WEB_API_KEY}"
|
||||
GOOGLE_RECAPTCHA_PRIVATE: "${APP_GOOGLE_RECAPTCHA_PRIVATE}"
|
||||
GOOGLE_RECAPTCHA_PUBLIC: "${APP_GOOGLE_RECAPTCHA_PUBLIC}"
|
||||
GOOGLE_RECAPTCHA_VERSION: "${APP_GOOGLE_RECAPTCHA_VERSION}"
|
||||
SENTRY_LARAVEL_DSN: "${APP_SENTRY_LARAVEL_DSN}"
|
||||
MATOMO_SITE_ID: "${APP_MATOMO_SITE_ID}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
spec:
|
||||
storageClassName: "csi-cinder-classic"
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: $APP_PVC_SIZE
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-deployment
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ${CI_PROJECT_PATH_SLUG}-app
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: ${CI_PROJECT_PATH_SLUG}-app
|
||||
spec:
|
||||
containers:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-container
|
||||
image: $IMAGE_TAG
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /app/srcs/storage
|
||||
imagePullSecrets:
|
||||
- name: docker-registry-credentials
|
||||
securityContext:
|
||||
runAsUser: 33
|
||||
runAsGroup: 33
|
||||
fsGroup: 33
|
||||
fsGroupChangePolicy: "OnRootMismatch"
|
||||
volumes:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-service
|
||||
spec:
|
||||
selector:
|
||||
app: ${CI_PROJECT_PATH_SLUG}-app
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: 443
|
||||
|
||||
---
|
||||
apiVersion: traefik.containo.us/v1alpha1
|
||||
kind: IngressRoute
|
||||
metadata:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-ingress-route
|
||||
spec:
|
||||
entryPoints:
|
||||
- web
|
||||
- websecure
|
||||
routes:
|
||||
- match: Host(`${APP_DOMAIN}`, `www.${APP_DOMAIN}`)
|
||||
kind: Rule
|
||||
services:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-service
|
||||
port: 80
|
||||
middlewares:
|
||||
- name: redirect-no-www-to-www
|
||||
namespace: common-services
|
||||
tls:
|
||||
secretName: $APP_DOMAIN
|
||||
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: $APP_DOMAIN
|
||||
spec:
|
||||
dnsNames:
|
||||
- $APP_DOMAIN
|
||||
- www.${APP_DOMAIN}
|
||||
secretName: $APP_DOMAIN
|
||||
issuerRef:
|
||||
name: $APP_CERT_ISSUER
|
||||
kind: ClusterIssuer
|
||||
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: CronJob
|
||||
metadata:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-cronjob
|
||||
spec:
|
||||
schedule: "* * * * *"
|
||||
jobTemplate:
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
affinity:
|
||||
podAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- ${CI_PROJECT_PATH_SLUG}-app
|
||||
topologyKey: "kubernetes.io/hostname"
|
||||
namespaces: [$KUBE_NAMESPACE]
|
||||
containers:
|
||||
- name: ${CI_PROJECT_PATH_SLUG}-scheduled
|
||||
image: $IMAGE_TAG
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- "php"
|
||||
args:
|
||||
- "artisan"
|
||||
- "schedule:run"
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: ${CI_PROJECT_PATH_SLUG}-config-map
|
||||
volumeMounts:
|
||||
- name: storage
|
||||
mountPath: /app/srcs/storage
|
||||
imagePullSecrets:
|
||||
- name: docker-registry-credentials
|
||||
volumes:
|
||||
- name: storage
|
||||
persistentVolumeClaim:
|
||||
claimName: ${CI_PROJECT_PATH_SLUG}-pvc-storage
|
||||
securityContext:
|
||||
runAsUser: 33
|
||||
runAsGroup: 33
|
||||
fsGroup: 33
|
||||
fsGroupChangePolicy: "OnRootMismatch"
|
||||
restartPolicy: OnFailure
|
||||
2928
package-lock.json
generated
42
package.json
|
|
@ -1,6 +1,5 @@
|
|||
{
|
||||
"private": true,
|
||||
"name": "srcs",
|
||||
"scripts": {
|
||||
"vite": "vite --clearScreen false",
|
||||
"prod": "vite build --mode production",
|
||||
|
|
@ -16,11 +15,12 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.22.11",
|
||||
"@babel/types": "^7.21.2",
|
||||
"@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",
|
||||
"@ldc-web/cookie-notice": "^4.0.1",
|
||||
"@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",
|
||||
"@ldc-web/cookie-notice": "^3.0.9",
|
||||
"@sipec/vue3-tags-input": "^3.0.4",
|
||||
"@types/bootstrap": "^5.2.7",
|
||||
"@types/node": "^20.8.2",
|
||||
|
|
@ -28,10 +28,11 @@
|
|||
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
||||
"@typescript-eslint/parser": "^5.36.2",
|
||||
"@vitejs/plugin-basic-ssl": "^1.0.1",
|
||||
"@vitejs/plugin-vue": "^4.6.2",
|
||||
"@vitejs/plugin-legacy": "latest",
|
||||
"@vitejs/plugin-vue": "latest",
|
||||
"@vue/compiler-sfc": "latest",
|
||||
"@vue/eslint-config-typescript": "latest",
|
||||
"@vue/tsconfig": "^0.4.0",
|
||||
"@vue/tsconfig": "latest",
|
||||
"axios": "^1.5.1",
|
||||
"bootstrap": "^5.3.2",
|
||||
"chart.js": "^4.4.0",
|
||||
|
|
@ -39,34 +40,33 @@
|
|||
"eslint": "latest",
|
||||
"eslint-import-resolver-alias": "^1.1.2",
|
||||
"eslint-plugin-vue": "latest",
|
||||
"laravel-vite-plugin": "^0.8.1",
|
||||
"laravel-vite-plugin": "latest",
|
||||
"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": "latest",
|
||||
"stylelint-config-idiomatic-order": "github:ream88/stylelint-config-idiomatic-order",
|
||||
"stylelint-config-sass-guidelines": "^10.0.0",
|
||||
"stylelint-config-standard-scss": "^11.1.0",
|
||||
"stylelint-scss": "^5.3.2",
|
||||
"stylelint-config-sass-guidelines": "latest",
|
||||
"stylelint-config-standard-scss": "latest",
|
||||
"stylelint-scss": "latest",
|
||||
"sweetalert2": "^11.7.31",
|
||||
"swiper": "^11.0.5",
|
||||
"swiper": "^10.2.0",
|
||||
"terser": "latest",
|
||||
"toastify-js": "^1.12.0",
|
||||
"ts-loader": "^9.3.1",
|
||||
"typescript": ">=3.3.1 <5.2.0",
|
||||
"typescript-eslint": "latest",
|
||||
"vite": "^4.5.1",
|
||||
"typescript": "latest",
|
||||
"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-eslint-parser": "^9.3.2",
|
||||
"vue-loader": "^17.3.1",
|
||||
"vue-tsc": "1.8.11"
|
||||
"vue-tsc": "1.6.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
phpstan.neon
|
|
@ -1,10 +0,0 @@
|
|||
includes:
|
||||
- vendor/larastan/larastan/extension.neon
|
||||
|
||||
parameters:
|
||||
|
||||
paths:
|
||||
- app/
|
||||
|
||||
# Level 9 is the highest level
|
||||
level: 5
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 0 B |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#ffc40d</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
|
Before Width: | Height: | Size: 656 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 9 KiB |
|
|
@ -1,173 +0,0 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="330.000000pt" height="330.000000pt" viewBox="0 0 330.000000 330.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,330.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1565 3286 c-113 -31 -202 -130 -219 -240 -4 -22 -8 -41 -10 -43 -1
|
||||
-2 -38 -14 -82 -27 -464 -136 -823 -506 -947 -976 -25 -94 -32 -134 -43 -240
|
||||
-3 -30 -7 -59 -8 -65 -2 -6 -35 -10 -75 -9 l-71 0 0 -38 0 -38 75 0 75 0 1
|
||||
-32 c3 -160 55 -361 139 -533 80 -164 171 -288 303 -411 159 -149 398 -281
|
||||
583 -324 50 -11 52 -13 58 -53 17 -105 94 -200 192 -236 184 -69 376 45 409
|
||||
242 3 20 12 37 19 37 54 0 306 106 417 175 137 86 292 233 392 373 147 204
|
||||
248 496 256 740 1 21 5 22 76 22 l75 0 0 38 0 39 -71 -1 c-39 -1 -72 2 -74 5
|
||||
-2 3 -6 26 -9 52 -14 116 -16 134 -22 162 -51 281 -199 551 -413 754 -150 143
|
||||
-371 267 -582 326 -54 15 -57 18 -64 53 -18 100 -91 195 -177 232 -60 26 -145
|
||||
32 -203 16z m135 -70 c0 11 80 -38 108 -67 27 -28 68 -116 59 -126 -2 -2 -37
|
||||
0 -78 5 -88 9 -220 8 -306 -2 -71 -9 -75 -4 -50 57 39 92 148 155 235 136 17
|
||||
-4 32 -5 32 -3z m120 -271 c136 -20 253 -55 390 -117 105 -48 262 -161 358
|
||||
-257 214 -216 348 -505 376 -814 4 -51 3 -57 -12 -53 -9 3 -93 28 -187 56 -93
|
||||
28 -173 54 -176 58 -3 4 -19 48 -34 97 -93 304 -313 529 -615 628 -181 60
|
||||
-429 54 -605 -15 -285 -110 -495 -341 -578 -633 l-23 -79 -187 -57 c-103 -31
|
||||
-188 -53 -188 -50 -2 9 -2 9 5 89 14 152 79 353 161 497 131 229 321 408 560
|
||||
525 152 75 266 109 425 126 30 4 56 8 58 9 6 5 226 -3 272 -10z m35 -464 c244
|
||||
-65 441 -225 555 -451 33 -66 74 -179 67 -186 -1 -1 -36 8 -77 21 -41 13 -113
|
||||
35 -160 49 -47 14 -200 61 -341 104 l-255 78 -205 -62 c-112 -34 -300 -91
|
||||
-416 -127 -140 -42 -213 -61 -213 -52 0 51 95 247 158 325 130 163 346 292
|
||||
527 316 28 3 52 8 54 10 13 12 235 -7 306 -25z m-251 -543 c-1 -35 -2 -66 -3
|
||||
-69 -1 -4 -15 -9 -33 -13 -41 -8 -119 -88 -134 -138 -34 -111 38 -255 139
|
||||
-275 15 -3 27 -8 28 -12 4 -23 3 -134 -1 -136 -6 -4 -156 41 -695 205 -148 45
|
||||
-316 96 -372 113 -57 17 -103 34 -103 37 0 4 10 10 23 12 12 3 195 58 407 123
|
||||
619 188 735 223 741 219 3 -1 4 -31 3 -66z m118 63 c13 -6 264 -82 558 -171
|
||||
294 -88 546 -166 560 -172 23 -10 19 -12 -55 -35 -44 -13 -87 -26 -95 -28 -16
|
||||
-4 -540 -163 -992 -301 -16 -5 -18 3 -18 64 l0 70 55 27 c30 14 67 41 80 60
|
||||
90 117 42 286 -97 342 l-38 15 0 69 c0 71 3 76 42 60z m-12 -226 c46 -24 73
|
||||
-71 73 -125 0 -139 -174 -194 -258 -82 -14 19 -20 43 -20 82 0 62 21 100 70
|
||||
124 38 20 98 20 135 1z m-1187 -226 c95 -29 178 -55 186 -59 8 -4 25 -44 37
|
||||
-89 75 -258 253 -471 499 -594 64 -32 169 -64 253 -78 65 -10 226 -14 267 -5
|
||||
11 2 40 7 64 11 70 12 175 50 259 95 216 116 386 329 455 567 13 46 26 85 29
|
||||
88 6 7 357 115 371 115 22 0 -19 -238 -63 -372 -59 -176 -136 -304 -290 -481
|
||||
-34 -39 -180 -157 -245 -199 -318 -205 -738 -257 -1106 -137 -436 141 -764
|
||||
501 -869 954 -20 87 -36 235 -26 235 4 0 84 -23 179 -51z m922 -285 c99 -30
|
||||
187 -55 195 -55 17 -1 71 15 525 154 171 52 311 94 313 93 1 -2 -7 -32 -19
|
||||
-67 -81 -248 -264 -443 -504 -538 -44 -17 -91 -34 -105 -36 -204 -40 -390 -24
|
||||
-552 48 -142 63 -283 183 -369 314 -47 73 -101 191 -113 249 l-7 31 228 -69
|
||||
c125 -38 309 -94 408 -124z m200 -998 c44 0 112 3 151 7 l72 7 -8 -35 c-41
|
||||
-181 -301 -224 -405 -67 -13 20 -27 52 -31 69 l-6 32 73 -7 c41 -3 110 -6 154
|
||||
-6z"/>
|
||||
<path d="M1589 2881 c-11 -5 -14 -32 -14 -115 0 -106 1 -109 23 -111 14 -1 22
|
||||
4 23 14 1 9 2 25 3 36 2 31 26 24 45 -14 10 -21 25 -36 39 -38 26 -3 27 3 8
|
||||
48 -13 30 -13 36 2 52 21 23 21 83 -1 104 -17 17 -104 33 -128 24z m98 -67 c5
|
||||
-17 -14 -35 -41 -38 -23 -3 -26 0 -22 23 2 14 5 29 5 33 1 9 54 -6 58 -18z"/>
|
||||
<path d="M1320 2843 c-42 -13 -60 -29 -74 -63 -40 -100 51 -197 147 -157 89
|
||||
38 97 157 14 207 -31 20 -57 23 -87 13z m53 -52 c23 -9 36 -31 43 -68 4 -21
|
||||
-29 -52 -59 -57 -19 -3 -33 1 -47 17 -11 11 -20 23 -21 26 0 3 -2 14 -4 25 -4
|
||||
18 35 66 54 66 5 0 21 -4 34 -9z"/>
|
||||
<path d="M1890 2808 c-14 -23 -32 -54 -41 -69 -8 -15 -23 -39 -33 -53 -9 -15
|
||||
-14 -31 -11 -36 9 -15 43 -12 52 5 13 22 67 5 71 -22 2 -13 13 -23 29 -26 l25
|
||||
-5 -5 116 c-5 116 -11 132 -47 132 -8 0 -26 -19 -40 -42z m40 -63 c0 -28 -4
|
||||
-35 -20 -35 -11 0 -20 3 -20 6 0 7 33 64 37 64 2 0 3 -16 3 -35z"/>
|
||||
<path d="M2096 2775 c-9 -23 -9 -23 18 -37 l24 -13 -27 -55 c-52 -108 -51
|
||||
-105 -30 -118 17 -11 23 -4 59 68 22 44 44 80 48 80 4 0 14 -4 22 -10 16 -10
|
||||
40 4 40 25 0 9 -69 46 -136 72 -6 2 -14 -3 -18 -12z"/>
|
||||
<path d="M1026 2717 c-17 -13 -16 -18 34 -108 29 -52 54 -95 56 -97 1 -2 27
|
||||
11 58 28 49 28 54 34 46 51 -12 21 -21 24 -35 10 -6 -5 -20 -12 -32 -15 -19
|
||||
-6 -26 1 -52 51 -45 88 -53 96 -75 80z"/>
|
||||
<path d="M2290 2573 c-36 -46 -66 -87 -68 -92 -1 -4 22 -27 52 -50 55 -41 55
|
||||
-41 67 -19 10 18 8 24 -12 39 -13 10 -27 19 -31 19 -13 0 -9 27 5 39 11 8 18
|
||||
6 32 -9 22 -25 41 -26 50 -3 4 12 -2 24 -19 38 -19 16 -23 24 -15 38 10 16 12
|
||||
16 40 -8 17 -14 34 -25 39 -25 14 0 33 31 24 39 -5 4 -29 24 -54 43 l-45 35
|
||||
-65 -84z"/>
|
||||
<path d="M832 2579 c-23 -17 -42 -36 -42 -42 0 -7 20 -32 43 -57 23 -26 54
|
||||
-61 69 -79 25 -29 30 -31 48 -18 l20 14 -21 27 -21 26 26 31 c29 34 31 47 15
|
||||
82 -12 26 -47 47 -78 47 -9 0 -36 -14 -59 -31z m87 -38 c8 -14 6 -23 -10 -37
|
||||
-20 -18 -21 -18 -39 6 -17 22 -17 25 -2 37 24 18 40 16 51 -6z"/>
|
||||
<path d="M2490 2423 c-30 -25 -60 -53 -67 -62 -36 -47 18 -140 75 -126 28 6
|
||||
73 35 130 83 30 25 31 29 19 47 -14 18 -17 17 -82 -33 -56 -43 -70 -50 -87
|
||||
-41 -30 16 -19 38 48 95 48 40 59 55 52 68 -14 24 -28 19 -88 -31z"/>
|
||||
<path d="M680 2425 c-11 -13 -10 -22 3 -51 l17 -34 -39 6 c-33 5 -41 3 -50
|
||||
-15 -7 -11 -10 -21 -9 -22 6 -1 53 -9 80 -13 38 -6 41 -9 68 -65 13 -28 26
|
||||
-51 29 -51 4 0 12 9 19 20 10 17 10 26 -3 50 -20 39 -20 40 17 29 27 -7 36 -5
|
||||
52 11 25 24 22 27 -34 35 -71 10 -75 12 -100 65 -25 54 -31 58 -50 35z"/>
|
||||
<path d="M2630 2175 c-76 -34 -94 -47 -92 -61 6 -28 10 -29 44 -16 45 17 56
|
||||
-4 21 -40 -20 -21 -24 -33 -19 -54 l7 -27 33 32 c27 26 38 31 65 26 26 -4 37
|
||||
0 62 25 26 26 30 35 23 62 -8 38 -35 98 -43 97 -3 0 -49 -20 -101 -44z m94
|
||||
-40 c15 -39 -25 -66 -49 -32 -14 20 -14 23 2 34 23 17 40 16 47 -2z"/>
|
||||
<path d="M515 2154 c-14 -31 -25 -59 -25 -63 0 -7 153 -79 185 -87 18 -4 25 4
|
||||
48 57 21 48 24 65 15 71 -24 15 -35 8 -50 -31 -13 -33 -20 -39 -37 -34 -25 6
|
||||
-25 6 -6 43 14 27 14 30 -4 40 -27 14 -28 14 -40 -20 -10 -31 -17 -35 -39 -21
|
||||
-11 6 -10 15 5 45 15 32 15 38 3 46 -25 16 -29 12 -55 -46z"/>
|
||||
<path d="M1170 2213 l0 -93 48 0 c52 0 73 14 90 60 13 35 -4 87 -34 106 -13 9
|
||||
-42 17 -64 18 l-40 2 0 -93z m98 3 c4 -32 -13 -56 -39 -56 -16 0 -19 8 -19 48
|
||||
0 27 3 52 7 55 12 13 48 -20 51 -47z"/>
|
||||
<path d="M1374 2302 c-5 -4 -9 -45 -9 -92 l0 -85 58 -3 c52 -3 57 -1 57 18 0
|
||||
17 -6 20 -40 20 -37 0 -40 2 -31 19 7 12 18 17 33 14 18 -3 24 0 25 16 1 17
|
||||
-4 21 -28 21 -22 0 -29 5 -29 19 0 12 7 18 23 18 42 1 47 3 47 21 0 15 -9 19
|
||||
-48 19 -27 1 -53 -2 -58 -5z"/>
|
||||
<path d="M1541 2300 c-4 -3 -8 -45 -8 -93 0 -84 1 -88 21 -85 15 2 20 9 19 26
|
||||
-2 12 1 23 5 23 4 1 18 3 31 4 39 4 61 39 50 77 -7 27 -21 45 -39 49 -18 4
|
||||
-72 4 -79 -1z m79 -60 c0 -25 -38 -33 -45 -9 -4 10 -4 23 -1 28 10 15 46 0 46
|
||||
-19z"/>
|
||||
<path d="M1700 2234 c0 -66 3 -78 24 -99 18 -18 31 -23 53 -19 47 8 57 27 59
|
||||
106 1 84 0 88 -24 82 -14 -4 -17 -17 -18 -70 0 -45 -5 -68 -14 -74 -25 -16
|
||||
-39 10 -42 77 -2 54 -6 67 -20 69 -16 2 -18 -7 -18 -72z"/>
|
||||
<path d="M1903 2302 c-6 -4 -11 -45 -11 -94 0 -79 2 -88 19 -88 13 0 19 7 20
|
||||
23 4 134 3 157 -7 161 -6 2 -15 1 -21 -2z"/>
|
||||
<path d="M2011 2293 c-13 -9 -21 -25 -21 -43 0 -24 7 -33 40 -50 22 -11 40
|
||||
-25 40 -30 0 -17 -16 -19 -42 -6 -22 12 -26 11 -36 -4 -8 -14 -6 -20 11 -29
|
||||
40 -21 66 -21 93 2 22 19 24 26 15 50 -6 15 -25 34 -46 44 -19 9 -35 20 -35
|
||||
24 0 16 20 20 41 8 17 -9 23 -8 30 2 20 33 -52 59 -90 32z"/>
|
||||
<path d="M2616 1392 c-2 -4 -13 -33 -24 -65 l-21 -58 27 -10 c37 -15 176 -59
|
||||
184 -59 3 0 16 28 27 62 16 48 18 64 8 70 -23 15 -34 8 -46 -32 -12 -42 -17
|
||||
-45 -40 -31 -12 8 -13 14 -2 37 10 22 10 29 -1 35 -23 15 -36 10 -47 -21 -6
|
||||
-17 -17 -30 -27 -30 -17 0 -16 13 2 76 4 16 0 23 -15 27 -12 3 -23 2 -25 -1z"/>
|
||||
<path d="M600 1355 c-9 -11 -23 -13 -50 -9 -65 11 -100 -51 -66 -114 8 -15 17
|
||||
-39 21 -54 6 -32 21 -37 29 -10 4 12 15 17 38 16 49 -2 60 4 47 28 -6 11 -17
|
||||
17 -24 14 -20 -7 -28 9 -11 24 10 7 21 8 33 2 58 -30 105 37 63 91 -24 30 -61
|
||||
35 -80 12z m53 -50 c1 -5 -6 -11 -15 -13 -11 -2 -18 3 -18 13 0 17 30 18 33 0z
|
||||
m-99 -17 c-18 -32 -27 -39 -35 -27 -11 18 1 39 23 39 12 0 17 -4 12 -12z"/>
|
||||
<path d="M2521 1164 c-22 -28 -21 -33 19 -74 3 -3 18 -20 34 -38 l30 -32 -55
|
||||
17 c-74 23 -99 22 -116 -4 -14 -21 -11 -24 72 -85 47 -35 90 -64 95 -66 5 -2
|
||||
13 5 19 16 9 17 3 24 -39 53 -28 19 -50 37 -50 41 0 3 25 -2 55 -13 67 -23 72
|
||||
-24 84 0 11 19 10 19 -63 100 l-31 34 50 -28 c28 -16 56 -33 63 -38 12 -10 42
|
||||
7 42 24 0 4 -33 27 -72 50 -40 23 -83 49 -94 56 -20 13 -24 11 -43 -13z"/>
|
||||
<path d="M689 1085 c-38 -21 -59 -58 -59 -106 0 -35 6 -47 36 -75 42 -40 68
|
||||
-42 108 -10 l30 23 -23 36 c-25 41 -33 44 -51 22 -10 -12 -10 -18 -1 -29 19
|
||||
-22 -7 -31 -30 -10 -40 36 -8 114 48 114 30 0 63 -34 58 -59 -2 -14 3 -25 16
|
||||
-32 26 -14 31 -9 32 34 2 84 -87 134 -164 92z"/>
|
||||
<path d="M2311 903 c-67 -35 -85 -120 -37 -176 53 -61 133 -57 185 9 26 33 27
|
||||
79 1 121 -33 55 -95 74 -149 46z m72 -44 c37 -17 53 -53 39 -84 -26 -56 -105
|
||||
-50 -120 9 -10 35 8 72 36 79 9 3 18 5 19 6 1 0 13 -4 26 -10z"/>
|
||||
<path d="M880 844 c-47 -30 -89 -59 -94 -65 -15 -14 26 -40 41 -27 21 17 66
|
||||
-18 59 -46 -4 -15 1 -29 13 -40 17 -16 20 -12 64 84 26 55 47 104 47 109 0 8
|
||||
-33 41 -41 41 -2 0 -42 -25 -89 -56z m56 -43 c-11 -20 -21 -28 -31 -25 -21 8
|
||||
-19 15 13 40 34 28 38 24 18 -15z"/>
|
||||
<path d="M1079 759 c-25 -25 -20 -56 18 -106 18 -24 23 -37 16 -44 -14 -14
|
||||
-53 6 -53 27 0 22 -44 14 -48 -8 -4 -23 38 -65 74 -74 39 -10 78 14 82 50 3
|
||||
20 -6 42 -27 71 -17 24 -31 46 -31 49 0 15 40 4 54 -15 18 -26 52 -22 48 6 -5
|
||||
30 -49 65 -83 65 -16 0 -38 -9 -50 -21z"/>
|
||||
<path d="M2123 769 l-22 -8 25 -56 c14 -31 24 -58 23 -60 -2 -2 -29 16 -60 39
|
||||
-44 34 -60 41 -77 35 -25 -9 -24 -12 30 -124 48 -99 46 -97 68 -83 17 11 17
|
||||
13 -5 65 -13 29 -22 53 -19 53 3 0 28 -16 57 -35 54 -37 64 -40 85 -27 10 7 1
|
||||
33 -35 109 -44 93 -50 100 -70 92z"/>
|
||||
<path d="M1265 693 c-3 -10 -2 -19 3 -21 5 -1 17 -9 27 -16 16 -12 16 -17 -8
|
||||
-94 -24 -78 -24 -82 -6 -87 22 -7 39 1 39 18 0 6 10 42 21 79 20 63 23 66 45
|
||||
58 19 -8 26 -5 34 10 5 10 10 21 10 23 0 5 -132 47 -148 47 -5 0 -13 -8 -17
|
||||
-17z"/>
|
||||
<path d="M1783 655 c-82 -35 -81 -163 1 -207 46 -25 122 -4 149 41 35 59 12
|
||||
137 -49 166 -39 18 -59 18 -101 0z m96 -61 c41 -52 18 -104 -44 -104 -58 0
|
||||
-86 69 -45 110 28 28 64 25 89 -6z"/>
|
||||
<path d="M1486 642 c-3 -9 -8 -61 -11 -114 l-6 -98 25 0 c23 0 26 4 26 35 0
|
||||
23 5 35 13 35 14 0 37 -40 37 -65 0 -10 10 -15 30 -15 l29 0 -14 41 c-14 37
|
||||
-13 42 5 62 42 45 6 126 -57 128 -15 0 -38 2 -50 5 -14 2 -24 -2 -27 -14z
|
||||
m101 -58 c9 -23 -18 -44 -44 -34 -15 6 -20 15 -16 29 6 25 51 29 60 5z"/>
|
||||
<path d="M1279 1166 c-1 -1 -3 -13 -5 -28 -2 -19 2 -28 12 -28 17 0 16 7 18
|
||||
-110 l1 -95 28 -3 28 -3 -3 132 -3 133 -37 1 c-21 1 -39 1 -39 1z"/>
|
||||
<path d="M1456 1149 c-13 -10 -27 -30 -30 -43 -11 -46 25 -105 67 -106 21 0
|
||||
21 -2 -3 -50 -11 -22 -20 -41 -20 -43 0 -2 14 -4 31 -5 28 -1 33 5 65 71 39
|
||||
81 43 131 14 165 -26 32 -90 37 -124 11z m82 -51 c14 -14 -2 -48 -22 -48 -20
|
||||
0 -37 25 -30 44 7 19 35 21 52 4z"/>
|
||||
<path d="M1703 1158 c-30 -14 -48 -70 -33 -98 8 -15 8 -25 1 -34 -49 -59 23
|
||||
-150 103 -130 49 12 89 99 55 119 -6 4 -8 22 -4 46 9 51 -1 76 -35 94 -33 17
|
||||
-56 18 -87 3z m70 -62 c8 -19 -16 -38 -37 -30 -16 6 -21 25 -9 37 12 12 41 7
|
||||
46 -7z m7 -110 c0 -28 -33 -41 -51 -20 -17 20 -3 44 26 44 20 0 25 -5 25 -24z"/>
|
||||
<path d="M1883 1163 c-7 -3 -13 -16 -13 -29 0 -22 4 -24 45 -24 30 0 45 -4 45
|
||||
-13 0 -7 -13 -52 -29 -99 -16 -48 -27 -89 -23 -92 12 -13 50 -5 57 12 15 37
|
||||
72 237 69 241 -5 5 -137 9 -151 4z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
|
@ -1,19 +0,0 @@
|
|||
{
|
||||
"name": "Agis",
|
||||
"short_name": "Agis",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-256x256.png",
|
||||
"sizes": "256x256",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||