Merge branch 'clean-phpstan' into 'develop'

fix: 🚨 resolve phpcs/phpstan errors (except fixme notes)

See merge request ldc-web/projets/le-gaulois!220
This commit is contained in:
Vincent BRIDIER 2025-06-11 08:04:20 +00:00
commit 04dab9359a
57 changed files with 394 additions and 257 deletions

View file

@ -105,7 +105,7 @@ enum ContactFormType: int
/**
* Check if the current subject has a file input.
*
* @return array
* @return boolean
*/
public function hasFileInput(): bool
{

View file

@ -4,4 +4,6 @@ namespace App\Exceptions;
use Exception;
class AbortContactMailer extends Exception {}
class AbortContactMailer extends Exception
{
}

View file

@ -5,7 +5,6 @@ namespace App\Http\Controllers\Bo;
use App\Enums\Settings\SettingsType;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\GeneralSettings\UpdateGeneralSettingRequest;
use App\Lib\Definitions\MenuNode;
use App\Lib\Helpers\FileStorageHelper;
use App\Models\GeneralSetting;
use Illuminate\Support\Facades\DB;

View file

@ -229,7 +229,7 @@ class SurveysAnswerController extends Controller
throw new \RuntimeException("The second last param isn't an object.");
}
if (get_class($model) !== (string)Str::of($className)->replaceStart('\\', '')) {
if (get_class($model) !== (string) Str::of($className)->replaceStart('\\', '')) {
throw new \RuntimeException("The {$className} doesn't match second last binded param.");
}

View file

@ -58,11 +58,11 @@ class VerificationController extends Controller
/** @var \App\Models\Customer */
$user = $request->user('club');
if (!hash_equals((string)$request->route('id'), (string)$user->getKey())) {
if (!hash_equals((string) $request->route('id'), (string) $user->getKey())) {
throw new AuthorizationException();
}
if (!hash_equals((string)$request->route('hash'), sha1($user->getEmailForVerification()))) {
if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
throw new AuthorizationException();
}

View file

@ -94,7 +94,7 @@ class DepartaimantController extends Controller
// @phpcs:enable
$itemsPerPage = 15;
$output = collect();
$state = DepartaimantStatus::make((int)$request->input('state'));
$state = DepartaimantStatus::make((int) $request->input('state'));
$pseudo = $request->string('pseudo', '');
$departaimant = Utils::replaceSpecChar(
str_replace(['-', ' ', '\''], '', strtolower($request->string('departaimant', '')))
@ -112,12 +112,12 @@ class DepartaimantController extends Controller
}
/** @var \App\Models\Customer */
$customer = Auth::guard('club')->user();
$ids = collect(BlockList::query()->select('customer_id', 'blocked_id')
$customer = Auth::guard('club')->user();
$ids = collect(BlockList::query()->select('customer_id', 'blocked_id')
->whereHas('customer', fn(Builder $q) => $q->where('id', $customer->getKey()))
->orWhereHas('blocked', fn(Builder $q) => $q->where('id', $customer->getKey()))
->get()->toArray());
$ids = $ids->flatten()->unique();
$ids = $ids->flatten()->unique();
$userDep = $customer->departaimantsCollections()->where('type', $collectiontype->value)->first();
$userDepStatus = [];

View file

@ -38,7 +38,10 @@ class DiscountController extends Controller
/** @var \App\Models\Customer $customer */
$customer = auth('club')->user();
$pdf = $this->fetchBrPdfFromMesBr($customer, $request->post('coupon'));
/** @var array $coupons */
$coupons = $request->post('coupon');
$pdf = $this->fetchBrPdfFromMesBr($customer, $coupons);
if ($pdf === null) {
\back()->withErrors([
@ -117,7 +120,7 @@ class DiscountController extends Controller
// * Maj Panier
$result = $mesBr->printCoupons($crmCustomer->hashcode, $coupons);
$result = \is_object($result) ? (array)$result : $result;
$result = \is_object($result) ? (array) $result : $result;
if (Arr::get($result, 'status') !== "OK") {
report(new \RuntimeException(
@ -197,9 +200,9 @@ class DiscountController extends Controller
$res = $mesBr->getMurCustomer($customer->hashcode);
if (!$res) {
$message = "ERROR MesBR API : getMurCustomer on api failed {$customer->hashcode}";
} elseif (Arr::get((array)$res, 'status') === 'KO') {
} elseif (Arr::get((array) $res, 'status') === 'KO') {
$message = Arr::get(
(array)$res,
(array) $res,
'message',
"ERROR MesBR API : getMurCustomer on api failed (no message) {$customer->hashcode}"
);
@ -243,9 +246,9 @@ class DiscountController extends Controller
$res = $mesBr->createCustomer($customer->hashcode, $customer->email, 'France');
if (!$res) {
$message = "ERROR MesBR API : createCustomer on api failed {$customer->hashcode}";
} elseif (Arr::get((array)$res, 'status') === 'KO') {
} elseif (Arr::get((array) $res, 'status') === 'KO') {
$message = Arr::get(
(array)$res,
(array) $res,
'message',
"ERROR MesBR API : createCustomer on api failed (no message) {$customer->hashcode}"
);

View file

@ -111,7 +111,7 @@ class MessageController extends Controller
$message = Message::findOrFail($request->input('message'));
$conversations = $customer->conversations();
foreach ($conversations as $conversation) {
$conversation = (object)$conversation;
$conversation = (object) $conversation;
if ($conversation->id != $message->getKey()) {
continue;
}

View file

@ -66,9 +66,10 @@ class ShopController extends Controller
// * Pseudo mutex let database fail (unique ref) to check if order has already been processed
try {
$order = new Order();
$order->ref = str_replace('-', '', $request->ref);
$order->civility = Civility::make(intval($request->civility));
$order = new Order();
$order->ref = str_replace('-', '', $request->ref);
// @phpstan-ignore assign.propertyType
$order->civility = Civility::make(intval($request->coords->civility));
$order->payementType = OrderType::make(intval($request->payementMethod));
$order->status = OrderStatus::waiting;
$order->customer_id = $customerModel->getKey();
@ -130,8 +131,6 @@ class ShopController extends Controller
} finally {
return response()->json(['redirect' => route('club.shop.validated', compact('order'))]);
}
break;
// * not used
default:
abort(422);
} //end switch
@ -184,11 +183,16 @@ class ShopController extends Controller
}
$totalToPay = $order->sellItems->map(function ($sellItem) {
/**
* Defined in Order model
*
* @phpstan-ignore property.notFound
*/
return $sellItem->pivot->quantity * $sellItem->price;
})->sum();
// * Convert total in cents
$totalToPay = (int)(\number_format((float)$totalToPay, 2) * 100);
$totalToPay = (int) (\number_format((float) $totalToPay, 2)) * 100;
$mercanet = $this->getMercanet($order);
@ -251,10 +255,10 @@ class ShopController extends Controller
): \Illuminate\Http\Response|\Illuminate\Contracts\Routing\ResponseFactory {
// phpcs:enable
try {
\extract($this->getMercanetData($request));
$data = $this->getMercanetData($request);
/** @var \App\Models\Order */
$order = Order::query()->where('ref', $ref)->firstOrFail();
$order = Order::query()->where('ref', $data['ref'])->firstOrFail();
$mercanet = $this->getMercanet($order);
$mercanet->setResponse($request->post());
@ -262,10 +266,11 @@ class ShopController extends Controller
if (!$mercanet->isValid()) {
$order->status = OrderStatus::failed;
$order->save();
// @phpstan-ignore finally.exitPoint
throw new CBPayementError('Data were altered from response');
}
switch ($responseCode) {
switch ($data['responseCode']) {
case TransactionResponse::accepted:
$order->status = OrderStatus::payed;
$order->save();
@ -287,11 +292,12 @@ class ShopController extends Controller
}
break;
case TransactionResponse::technicalIssue:
// @phpstan-ignore finally.exitPoint
throw new CBPayementError(sprintf(
'Error from Mercanet Server %s on ref %s, %s',
$responseCode,
$ref,
json_encode($returnDatas)
$data['responseCode'],
$data['ref'],
json_encode($data['returnDatas']),
));
default:
// * ERROR
@ -302,11 +308,12 @@ class ShopController extends Controller
$order->status = OrderStatus::failed;
$order->save();
}
// @phpstan-ignore finally.exitPoint
throw new CBPayementError(sprintf(
'Un handled response from Mercanet Server %s on ref %s',
$responseCode,
$ref,
json_encode($returnDatas)
'Un handled response from Mercanet Server %s on ref %s, %s',
$data['responseCode'],
$data['ref'],
json_encode($data['returnDatas']),
));
} //end switch
} catch (ModelNotFoundException | CBPayementError | \Exception $e) {
@ -317,6 +324,7 @@ class ShopController extends Controller
$e->getMessage()
));
} finally {
// @phpstan-ignore finally.exitPoint
return response('', 200);
} //end try
}
@ -356,9 +364,9 @@ class ShopController extends Controller
}
}
\extract($this->getMercanetData($request));
$data = $this->getMercanetData($request);
switch ($responseCode) {
switch ($data['responseCode']) {
case PaymentResponse::ok:
try {
$status = $order->status;
@ -395,15 +403,15 @@ class ShopController extends Controller
$order->saveOrFail();
throw new CBPayementError(sprintf(
"Error response from Mercanet Lib : %s\n %s",
PaymentResponse::make($responseCode)->label,
json_encode($returnDatas)
PaymentResponse::make($data['responseCode'])->label(),
json_encode($data['returnDatas'])
));
default:
$order->status = OrderStatus::failed;
$order->save();
throw new CBPayementError(sprintf(
'Un handled response from Mercanet Lib %s',
json_encode($returnDatas)
json_encode($data['returnDatas'])
));
} //end switch
} catch (ModelNotFoundException | CBPayementError $e) {
@ -438,7 +446,7 @@ class ShopController extends Controller
* Get Mercanet ref and responseCode for request.
*
* @param \Illuminate\Http\Request $request
* @return array<string,string> array['ref' => 'value', 'responseCode' => 'value']
* @return array<string,string> array['ref' => 'value', 'responseCode' => 'value', 'returnDatas' => 'value']
*/
private function getMercanetData(Request $request): array
{

View file

@ -79,7 +79,7 @@ class Controller extends BaseController
*
* @param \Illuminate\Database\Eloquent\Builder $query The eloquent query builder.
* @param string $search The query string.
* @param callable $searchQuery The query string.
* @param callable|null $searchQuery The query string.
* @param string ...$fields Either a simple array or a string
* in case of a string the two fields
* would be concatenate to make the search.
@ -88,7 +88,7 @@ class Controller extends BaseController
protected function searchQuery(
Builder $query,
string $search,
callable $searchQuery = null,
callable|null $searchQuery = null,
string ...$fields
): \Illuminate\Database\Eloquent\Builder {
if (count($fields)) {
@ -253,7 +253,7 @@ class Controller extends BaseController
*/
protected function paginate(
Builder $query,
ItemsPerPaginationEnum $pagination = null
ItemsPerPaginationEnum|null $pagination = null
): \Illuminate\Contracts\Pagination\LengthAwarePaginator {
$currentRoutePath = Str::slug(request()->route()->getName());
$cacheKey = "pagination.{$currentRoutePath}";
@ -333,7 +333,7 @@ class Controller extends BaseController
if (
strlen($word) > 3
&& !in_array($word, $modelsTitles)
&& ((!is_null($searchLower)) ? str_contains($word, $searchLower) : true)
&& str_contains($word, $searchLower)
) {
$modelsTitles[] = $word;
}

View file

@ -29,7 +29,7 @@ class BreedingController extends Controller
*
* @return \Illuminate\Contracts\View\View
*/
public function OcbBreederPage(): \Illuminate\Contracts\View\View
public function ocbBreederPage(): \Illuminate\Contracts\View\View
{
$ocbBreederModels = OcbBreeder::getOcbBreederCards();
return view('fo.pages.breeding.oui-c-est-bon', [

View file

@ -12,7 +12,6 @@ use App\Jobs\Mails\SendNLMail;
use App\Jobs\Mails\SendPasserelleMail;
use App\Models\MailContactData;
use App\Models\StaticPage;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
@ -82,15 +81,15 @@ class ContactController extends Controller
*/
private function storeFile(\Illuminate\Http\UploadedFile|null $file): string|null
{
$joinFilePath = null;
$joinFile = '';
$joinFilePath = null;
$joinFile = '';
if ($file) {
$uniqIdDirectory = \uniqid();
$joinFile = Storage::disk('local')->put(
$joinFile = Storage::disk('local')->put(
sprintf('public/tmp/%s', $uniqIdDirectory),
$file
);
$joinFilePath = storage_path('app/' . $joinFile);
$joinFilePath = storage_path('app/' . $joinFile);
}
return $joinFilePath;

View file

@ -12,7 +12,7 @@ use App\Models\Recipe;
use App\Models\StaticPage;
use App\Models\Submeat;
use App\Models\Subrange;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
@ -31,18 +31,18 @@ class ProductController extends Controller
/**
* Get products by a specific range into a json response.
*
* @param \Illuminate\Contracts\Pagination\LengthAwarePaginator|null $productModelsFiltered
* @param \Illuminate\Support\Collection<\App\Models\Subrange>|null $subrangeModelsFiltered
* @param \Illuminate\Support\Collection<\App\Models\Submeat>|null $submeatModelsFiltered
* @param \Illuminate\Pagination\LengthAwarePaginator|null $productModelsFiltered
* @param \Illuminate\Support\Collection<\App\Models\Subrange>|null $subrangeModelsFiltered
* @param \Illuminate\Support\Collection<\App\Models\Submeat>|null $submeatModelsFiltered
* @return \Illuminate\Contracts\View\View
*/
public function index(
LengthAwarePaginator $productModelsFiltered = null,
Collection $subrangeModelsFiltered = null,
Collection $submeatModelsFiltered = null,
LengthAwarePaginator|null $productModelsFiltered = null,
Collection|null $subrangeModelsFiltered = null,
Collection|null $submeatModelsFiltered = null,
): \Illuminate\Contracts\View\View {
/** @var \Illuminate\Contracts\Pagination\LengthAwarePaginator $productModels */
/** @var \Illuminate\Pagination\LengthAwarePaginator $productModels */
$productModels = $productModelsFiltered ?? Product::query()
->where('published', true)
->orderBy('slug')
@ -133,11 +133,13 @@ class ProductController extends Controller
/** @var string $slug */
$slug = $filter
? ((is_null($productModel->{$filter})
? $productModel->{"sub" . $this->cleanSubSubFilter($filter)}->{$this->cleanSubSubFilter($filter)} ?? null
? $productModel->{"sub" . $this->cleanSubSubFilter($filter)}
->{$this->cleanSubSubFilter($filter)} ?? null
: $productModel->{$filter})->slug ?? "")
: "";
// FIXME: the previous element are added on 30/10/24 to avoid error when productFilters was set on "submeat" for example and user access to product which not have submeat relation -> "Attempt to read property 'sub***' on null"
// FIXME: the previous element are added on 30/10/24 to avoid error when productFilters was set on "submeat"
// for example and user access to product which not have submeat relation -> "Attempt to read property 'sub***' on null"
// this fix will just avoid the error, but in this case, product.show have no previous or next product.
/** @var \Illuminate\Support\Collection $productModelsList */
@ -145,7 +147,7 @@ class ProductController extends Controller
->with('range', 'subrange', 'meat', 'submeat')
->when(in_array($filter, ['range', 'meat']), function (Builder $q) use ($slug, $filter) {
$q->where('published', true)
->whereHas($filter, function (Builder $q) use ($slug, $filter) {
->whereHas($filter, function (Builder $q) use ($slug) {
$q->where('published', true)->where('slug', $slug);
})
->orWhereHas('sub' . $filter, function (Builder $q) use ($slug, $filter) {
@ -569,10 +571,10 @@ class ProductController extends Controller
* Delete the "sub" start filter to avoid "subsubrange" when user has some filters
* and hard visit a total different product filter
*
* @var string $filter
* @param string $filter
* @return mixed
*/
private function cleanSubSubFilter($filter): mixed
private function cleanSubSubFilter(string $filter): mixed
{
return str_starts_with($filter, "sub") ? preg_replace('/^sub/', '', $filter) : $filter;
}

View file

@ -12,7 +12,7 @@ use Illuminate\Database\Eloquent\Builder;
use App\Models\Recipe;
use App\Models\StaticPage;
use App\Models\Submeat;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
@ -30,15 +30,15 @@ class RecipeController extends Controller
/**
* Get recipes by a specific range into a json response.
*
* @param \Illuminate\Contracts\Pagination\LengthAwarePaginator|null $recipeModelsFiltered
* @param \Illuminate\Support\Collection<\App\Models\Submeat>|null $submeatModelsFiltered
* @param \Illuminate\Pagination\LengthAwarePaginator|null $recipeModelsFiltered
* @param \Illuminate\Support\Collection<\App\Models\Submeat>|null $submeatModelsFiltered
* @return \Illuminate\Contracts\View\View
*/
public function index(
LengthAwarePaginator $recipeModelsFiltered = null,
Collection $submeatModelsFiltered = null,
LengthAwarePaginator|null $recipeModelsFiltered = null,
Collection|null $submeatModelsFiltered = null,
): \Illuminate\Contracts\View\View {
/** @var \Illuminate\Contracts\Pagination\LengthAwarePaginator $recipeModels */
/** @var \Illuminate\Pagination\LengthAwarePaginator $recipeModels */
$recipeModels = $recipeModelsFiltered ?? Recipe::query()
->with(['products', 'products.meat', 'products.submeat', 'consumptionMoment'])
->where('published', true)

View file

@ -50,8 +50,7 @@ class SearchController extends Controller
* Search string on multiple models.
*
* @param string|null $search
* @param string $class
* @param integer $itemsPerPage
* @param string $className
* @param integer $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
@ -70,6 +69,7 @@ class SearchController extends Controller
* Search string on multiple models.
*
* @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $models
* @param string $className
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function getViewsFromMeilisearchPagination(
@ -94,8 +94,12 @@ class SearchController extends Controller
* @param string $className
* @return string
*/
public function transformClassNameToSnakeCase($className): string
public function transformClassNameToSnakeCase(string $className): string
{
return Str::lower(preg_replace('/(?<!^)[A-Z]/', '-$0', class_basename(explode('App\\Models\\', $className)[1])));
return Str::lower(preg_replace(
'/(?<!^)[A-Z]/',
'-$0',
class_basename(explode('App\\Models\\', $className)[1])
));
}
}

View file

@ -127,7 +127,7 @@ abstract class UpdateMiniCrudRequest extends FormRequest
}) : $input['dimensions'];
// * Adapt dimensions
$sizes = (object)[
$sizes = (object) [
'minHeight' => $dim['height'],
'maxHeight' => $dim['height'],
'minWidth' => $dim['width'],

View file

@ -57,9 +57,9 @@ class StoreCustomerRequest extends FormRequest
{
ToolboxHelper::validateRecaptcha($this, \config('services.google.recaptcha.version'));
/** @var \App\Models\Customer $customerModel */
/** @var \App\Models\Customer|null $customerModel */
$customerModel = auth('club')->user();
$customerId = $customerModel ? $customerModel->getKey() : null;
$customerId = $customerModel ? $customerModel->getKey() : null;
$countryList = implode(',', Country::getValidIsoAplha2Codes());
return [

View file

@ -24,8 +24,10 @@ class PrintCouponsRequest extends FormRequest
*/
public function prepareForValidation(): void
{
/** @var array $coupons */
$coupons = $this->post('coupon');
$this->merge([
'coupon' => collect($this->post('coupon'))
'coupon' => collect($coupons)
->filter()
->map(fn(string $value) => \is_numeric($value) ? intval($value) : $value)
->all()

View file

@ -6,7 +6,6 @@ use App\Enums\ContactFormCivility;
use App\Enums\ContactFormType;
use App\Lib\Helpers\ToolboxHelper;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Route;
use Illuminate\Validation\Rule;
class ContactFormRequest extends FormRequest

View file

@ -28,7 +28,7 @@ class DemarcheSlidesStatusUpdate
foreach ($demarcheSlidesListToUnPublish as $demarcheSlide) {
$demarcheSlide->published_at = null;
$demarcheSlide->unpublished_at = null;
$demarcheSlide->published = false;
$demarcheSlide->published = false;
$demarcheSlide->saveOrFail();
}
/** @var \Illuminate\Database\Eloquent\Collection<array-key,\App\Models\DemarcheSlide> */
@ -47,7 +47,7 @@ class DemarcheSlidesStatusUpdate
}
foreach ($demarcheSlidesListToPublish as $demarcheSlide) {
$demarcheSlide->published_at = null;
$demarcheSlide->published = true;
$demarcheSlide->published = true;
$demarcheSlide->saveOrFail();
}
}

View file

@ -67,7 +67,7 @@ class FetchDigitalRecruiterOffers
*
* @param \Illuminate\Support\Collection $offers
* @return void
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.MaxExceeded
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
*/
private function saveOffers(Collection $offers): void
{

View file

@ -35,6 +35,7 @@ class SendArcadiaMail implements ShouldQueue
* Create a new job instance.
*
* @param \App\Models\MailContactData $data
* @param string|null $file
* @return void
*/
public function __construct(MailContactData $data, string|null $file = null)

View file

@ -34,6 +34,7 @@ class SendNLMail implements ShouldQueue
* Create a new job instance.
*
* @param \App\Models\MailContactData $data
* @param string|null $file
* @return void
*/
public function __construct(MailContactData $data, string|null $file = null)

View file

@ -54,6 +54,10 @@ class SendPasserelleMail implements ShouldQueue
if (file_exists($this->file)) {
File::deleteDirectory(File::dirname($this->file));
}
Log::debug(sprintf('Sent %s to %s', ContactComplainMail::class, implode(',', config('mail.contactsList.passerelle'))));
Log::debug(sprintf(
'Sent %s to %s',
ContactComplainMail::class,
implode(',', config('mail.contactsList.passerelle'))
));
}
}

View file

@ -28,7 +28,7 @@ class MainSlidesStatusUpdate
foreach ($mainSlidesListToUnPublished as $mainSlide) {
$mainSlide->published_at = null;
$mainSlide->unpublished_at = null;
$mainSlide->published = false;
$mainSlide->published = false;
$mainSlide->saveOrFail();
}
/** @var \Illuminate\Database\Eloquent\Collection<array-key,\App\Models\MainSlide> */
@ -47,7 +47,7 @@ class MainSlidesStatusUpdate
}
foreach ($mainSlidesListToPublished as $mainSlide) {
$mainSlide->published_at = null;
$mainSlide->published = true;
$mainSlide->published = true;
$mainSlide->saveOrFail();
}
}

View file

@ -39,7 +39,7 @@ class CollectionHelper
$total = $results->count();
return self::paginator($results->forPage($page, $pageSize), $total, $pageSize, $page, [
'path' => Paginator::resolveCurrentPath(),
'path' => Paginator::resolveCurrentPath(),
'pageName' => 'page',
]);
}
@ -73,14 +73,16 @@ class CollectionHelper
/**
* Get an array of views for each recipe models given.
*
* @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $models
* @param string $path
* @param string $key
* @param \Illuminate\Pagination\LengthAwarePaginator $models
* @param string $path
* @param string $key
* @return array
*/
public static function getViewsFromPaginateModels(LengthAwarePaginator $models, string $path, string $key): array
{
// @phpstan-ignore-next-line
public static function getViewsFromPaginateModels(
LengthAwarePaginator $models,
string $path,
string $key
): array {
return $models->through(function ($model) use ($path, $key) {
return view($path, [$key => $model])->render();
})->toArray();

View file

@ -8,7 +8,7 @@ class ExceptionsHelper
* Handle sentry event.
*
* @param \Sentry\Event $event
* @return null|\Sentry\Event
* @return \Sentry\Event|null
*/
public static function sentryEventHandler(\Sentry\Event $event): ?\Sentry\Event
{

View file

@ -3,9 +3,11 @@
namespace App\Lib\Helpers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use SplFileInfo;
/**
* This class is used to handle files in LDC Laravel stack
@ -100,14 +102,14 @@ class FileStorageHelper
*/
public static function storeFile(
Model $model,
\Illuminate\Http\UploadedFile|\SplFileInfo|string|null $file,
UploadedFile|SplFileInfo|string|null $file,
bool $slugify = false,
string $filename = null,
string|null $filename = null,
bool $private = false
): string {
// phpcs:enable
$tableName = $model->getTable();
if (\is_object($file) and $file instanceof \Illuminate\Http\UploadedFile) {
if (\is_object($file) and $file instanceof UploadedFile) {
/** @var \Illuminate\Http\UploadedFile $file */
$filename = $filename ?: $file->getClientOriginalName();
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
@ -130,7 +132,7 @@ class FileStorageHelper
return str_replace('/private/', '', $newPath);
} //end if
if (\is_object($file) and $file instanceof \SplFileInfo) {
if (\is_object($file) and $file instanceof SplFileInfo) {
/** @var \SplFileInfo $file */
$filename = $filename ?: $file->getBaseName();
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
@ -163,7 +165,7 @@ class FileStorageHelper
public static function storeModelFilesFromHtml(
Model $model,
string $htmlString,
string $oldHtmlString = null
string|null $oldHtmlString = null
): string {
\collect(self::onlyUploadedFilesWithFileManager(self::findFilesInHtml($htmlString)))
->each(function (string $path) use ($model, &$htmlString) {

View file

@ -427,7 +427,7 @@ class ToolboxHelper
if (!(is_object($input) or is_array($input))) {
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
}
$ret = (array)$input;
$ret = (array) $input;
foreach ($ret as &$item) {
// Recursively process EACH element only if not scalar.
$item = (is_object($item) or is_array($item)) ?
@ -449,7 +449,7 @@ class ToolboxHelper
if (!(is_object($input) or is_array($input))) {
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
}
$ret = (object)$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;

View file

@ -46,7 +46,7 @@ class Link implements Jsonable, Arrayable, Stringable
/** @var \Illuminate\Routing\Router $router */
$router = app('router');
return (bool)collect($router->getRoutes()->getRoutes())
return (bool) collect($router->getRoutes()->getRoutes())
->filter(fn($route) => Str::of($route->getName())->startsWith('fo.'))
->filter(fn($route) => Str::of($route->getName())->exactly($routeName))->count();
}

View file

@ -9,6 +9,7 @@ use Normalizer;
class Mercanet
{
// phpcs:disable Generic.Files.LineLength.TooLong
public const DEVELOPMENT = "https://payment-webinit-mercanet.test.sips-services.com/rs-services/v2/paymentInit";
public const PRODUCTION = "https://payment-webinit.mercanet.bnpparibas.net/rs-services/v2/paymentInit";
public const VERSION = "1";
@ -17,9 +18,9 @@ class Mercanet
public const INTERFACE_VERSION = "IR_WS_3.4";
public const INSTALMENT = "INSTALMENT";
// BYPASS3DS
public const BYPASS3DS_ALL = "ALL";
public const BYPASS3DS_MERCHANTWALLET = "MERCHANTWALLET";
// phpcs:enable
/** @var array<string> */
private $brandsmap = [
@ -48,8 +49,10 @@ class Mercanet
'KBCONLINE' => 'CREDIT_TRANSFER'
];
/** @var string $secretKey */
private $secretKey;
/** @var string $env */
private $env;
/** @var string $returnUrl */
@ -58,12 +61,13 @@ class Mercanet
/** @var boolean|string */
private $automaticUrl = false;
/** @var string $pspURL */
private $pspURL = self::DEVELOPMENT;
/** @var string */
private $responseData;
/** @var array */
/** @var array<string> */
private $parameters = [];
/** @var array<string> */
@ -183,8 +187,20 @@ class Mercanet
'XOF' => '952'
];
public function __construct($secret, $MerchantId, $env, $returnUrl, $automaticUrl = false)
{
/**
* @param string $secret
* @param string $MerchantId
* @param string $env
* @param string $returnUrl
* @param string|false $automaticUrl
*/
public function __construct(
string $secret,
string $MerchantId,
string $env,
string $returnUrl,
string|false $automaticUrl = false
) {
$this->secretKey = $secret;
$this->parameters['merchantId'] = $MerchantId;
$this->env = $env;
@ -203,7 +219,14 @@ class Mercanet
}
}
public static function convertCurrencyToCurrencyCode($currency)
/**
* Convert currency to currency code.
*
* @param string $currency
* @return string
* @throws \InvalidArgumentException Unknown currencyCode.
*/
public static function convertCurrencyToCurrencyCode(string $currency): string
{
if (!in_array($currency, array_keys(self::$currencies))) {
throw new InvalidArgumentException("Unknown currencyCode $currency.");
@ -211,7 +234,14 @@ class Mercanet
return self::$currencies[$currency];
}
public static function convertCurrencyCodeToCurrency($code)
/**
* Convert currency code to currency.
*
* @param string $code
* @return integer|string|false
* @throws \InvalidArgumentException Unknown Code.
*/
public static function convertCurrencyCodeToCurrency(string $code): int|string|false
{
if (!in_array($code, array_values(self::$currencies))) {
throw new InvalidArgumentException("Unknown Code $code.");
@ -254,6 +284,7 @@ class Mercanet
public function getShaSign(): string
{
$this->validate();
// FIXME: deprecated in 8.2, gonna be deleted in 9.0
return hash_hmac('sha256', utf8_encode($this->shaCompose($this->toArray())), $this->secretKey);
}
@ -306,8 +337,9 @@ class Mercanet
/**
* Set automatic response url.
*
* @param string $url
* @param string $transactionReference
* @return void
* @throws \InvalidArgumentException TransactionReference cannot contain special characters.
*/
public function setTransactionReference(string $transactionReference): void
{
@ -322,6 +354,8 @@ class Mercanet
*
* @param mixed $amount
* @return void
* @throws \InvalidArgumentException Integer expected. Amount is always in cents
* OR Amount must be a positive number.
*/
public function setAmount(mixed $amount): void
{
@ -339,6 +373,7 @@ class Mercanet
*
* @param string $currency
* @return void
* @throws \InvalidArgumentException Unknown currency.
*/
public function setCurrency(string $currency): void
{
@ -353,6 +388,7 @@ class Mercanet
*
* @param string $language
* @return void
* @throws \InvalidArgumentException Invalid language locale.
*/
public function setLanguage(string $language): void
{
@ -378,6 +414,7 @@ class Mercanet
*
* @param array<string> $brands
* @return void
* @throws \InvalidArgumentException Unknown brand.
*/
public function setPaymentBrands(array $brands): void
{
@ -395,6 +432,7 @@ class Mercanet
*
* @param string $email
* @return void
* @throws \InvalidArgumentException Email is too long OR email is invalid.
*/
public function setBillingContactEmail(string $email): void
{
@ -412,6 +450,7 @@ class Mercanet
*
* @param string $street
* @return void
* @throws \InvalidArgumentException Street is too long.
*/
public function setBillingAddressStreet(string $street): void
{
@ -426,6 +465,7 @@ class Mercanet
*
* @param string $nr
* @return void
* @throws \InvalidArgumentException StreetNumber is too long.
*/
public function setBillingAddressStreetNumber(string $nr): void
{
@ -440,6 +480,7 @@ class Mercanet
*
* @param string $zipCode
* @return void
* @throws \InvalidArgumentException ZipCode is too long.
*/
public function setBillingAddressZipCode(string $zipCode): void
{
@ -454,6 +495,7 @@ class Mercanet
*
* @param string $city
* @return void
* @throws \InvalidArgumentException City is too long.
*/
public function setBillingAddressCity(string $city): void
{
@ -468,6 +510,7 @@ class Mercanet
*
* @param string $phone
* @return void
* @throws \InvalidArgumentException Phone is too long.
*/
public function setBillingContactPhone(string $phone): void
{
@ -485,7 +528,7 @@ class Mercanet
*/
public function setBillingContactFirstname(string $firstname): void
{
// replace quotes
// Replace quotes.
$this->parameters['billingContact.firstname'] = str_replace(
array("'", '"'),
'',
@ -501,7 +544,7 @@ class Mercanet
*/
public function setBillingContactLastname(string $lastname): void
{
// replace quotes
// Replace quotes.
$this->parameters['billingContact.lastname'] = str_replace(
array("'", '"'),
'',
@ -514,6 +557,7 @@ class Mercanet
*
* @param string $number
* @return void
* @throws \InvalidArgumentException CaptureDay is too long.
*/
public function setCaptureDay(string $number): void
{
@ -528,6 +572,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException CaptureMode is too long.
*/
public function setCaptureMode(string $value): void
{
@ -542,6 +587,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException MerchantTransactionDateTime is too long.
*/
public function setMerchantTransactionDateTime(string $value): void
{
@ -589,6 +635,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException OrderChannel is too long.
*/
public function setOrderChannel(string $value): void
{
@ -603,6 +650,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException OrderId is too long.
*/
public function setOrderId(string $value): void
{
@ -617,6 +665,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException ReturnContext is too long.
*/
public function setReturnContext(string $value): void
{
@ -631,6 +680,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException TransactionOrigin is too long.
*/
public function setTransactionOrigin(string $value): void
{
@ -643,8 +693,9 @@ class Mercanet
/**
* Set card number.
*
* @param string $value
* @param string $number
* @return void
* @throws \InvalidArgumentException CardNumber is too long OR cardNumber is too short.
*/
public function setCardNumber(string $number): void
{
@ -660,8 +711,9 @@ class Mercanet
/**
* Set card expiry date.
*
* @param string $value
* @param string $date
* @return void
* @throws \InvalidArgumentException CardExpiryDate value is invalid.
*/
public function setCardExpiryDate(string $date): void
{
@ -676,6 +728,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException CardCSCValue value is invalid.
*/
public function setCardCscValue(string $value): void
{
@ -690,6 +743,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException FraudData.bypass3DS is too long.
*/
public function setFraudDataBypass3ds(string $value): void
{
@ -702,8 +756,9 @@ class Mercanet
/**
* Set merchant wallet id.
*
* @param string $value
* @param string $wallet
* @return void
* @throws \InvalidArgumentException MerchantWalletId is too long.
*/
public function setMerchantWalletId(string $wallet): void
{
@ -718,6 +773,7 @@ class Mercanet
*
* @param string $value
* @return void
* @throws \InvalidArgumentException PaymentMeanId is too long.
*/
public function setPaymentMeanId(string $value): void
{
@ -730,8 +786,10 @@ class Mercanet
/**
* Set instalment data number.
*
* @param string $value
* @param string $number
* @return void
* @throws \InvalidArgumentException InstalmentData.number is too long OR
* instalmentData.number invalid value : value must be set between 2 and 50.
*/
public function setInstalmentDataNumber(string $number): void
{
@ -749,7 +807,7 @@ class Mercanet
/**
* Set instalment dates list.
*
* @param string $value
* @param string $datesList
* @return void
*/
public function setInstalmentDatesList(string $datesList): void
@ -760,7 +818,7 @@ class Mercanet
/**
* Set instalment data transaction references list.
*
* @param string $value
* @param string $transactionReferencesList
* @return void
*/
public function setInstalmentDataTransactionReferencesList(string $transactionReferencesList): void
@ -771,7 +829,7 @@ class Mercanet
/**
* Set instalment data amounts list.
*
* @param string $value
* @param string $amountsList
* @return void
*/
public function setInstalmentDataAmountsList(string $amountsList): void
@ -782,7 +840,7 @@ class Mercanet
/**
* Set payment pattern.
*
* @param string $value
* @param string $paymentPattern
* @return void
*/
public function setPaymentPattern(string $paymentPattern): void
@ -790,6 +848,12 @@ class Mercanet
$this->parameters['paymentPattern'] = $paymentPattern;
}
/**
* @param string $method
* @param array $args
* @return mixed
* @throws \BadMethodCallException Unknown method.
*/
public function __call(string $method, array $args)
{
if (substr($method, 0, 3) == 'set') {
@ -834,7 +898,13 @@ class Mercanet
return json_encode($tmp, JSON_UNESCAPED_SLASHES);
}
public function validate()
/**
* Undocumented function
*
* @return void
* @throws \RuntimeException Can not be empty.
*/
public function validate(): void
{
foreach ($this->requiredFields as $field) {
if (empty($this->parameters[$field])) {
@ -848,6 +918,7 @@ class Mercanet
*
* @param string $uri
* @return void
* @throws \InvalidArgumentException Uri is not valid OR Uri is too long.
*/
protected function validateUri(string $uri): void
{
@ -859,8 +930,7 @@ class Mercanet
}
}
// Traitement des reponses de Mercanet
// -----------------------------------
// Traitement des reponses de Mercanet.
/** @var string */
public const SHASIGN_FIELD = "SEAL";
@ -871,10 +941,17 @@ class Mercanet
/** @var string */
private $shaSign;
/** @var string */
private $dataString;
// FIXME: don't know the type here for $responseRequest.
/** @var mixed $responseRequest @phpstan-ignore property.onlyRead */
private $responseRequest;
// FIXME: don't know the type here for $parameterArray.
/** @var mixed $responseRequest @phpstan-ignore property.onlyRead */
private $parameterArray;
/**
@ -898,8 +975,9 @@ class Mercanet
/**
* Filter http request parameters.
*
* @param array $requestParameters
* @param array $httpRequest
* @return array
* @throws \InvalidArgumentException Data parameter not present in parameters.
*/
private function filterRequestParameters(array $httpRequest): array
{
@ -907,7 +985,8 @@ class Mercanet
if (!array_key_exists(self::DATA_FIELD, $httpRequest) || $httpRequest[self::DATA_FIELD] == '') {
throw new InvalidArgumentException('Data parameter not present in parameters.');
}
$this->responseData = $this->dataString = $httpRequest[self::DATA_FIELD];
$this->responseData = $httpRequest[self::DATA_FIELD];
$this->dataString = $httpRequest[self::DATA_FIELD];
return \json_decode($this->dataString, true);
}
@ -921,7 +1000,14 @@ class Mercanet
return $this->shaSign;
}
private function extractShaSign(array $parameters)
/**
* Extract sha sign.
*
* @param array $parameters
* @return string
* @throws \InvalidArgumentException SHASIGN parameter not present in parameters.
*/
private function extractShaSign(array $parameters): string
{
if (!array_key_exists(self::SHASIGN_FIELD, $parameters) || $parameters[self::SHASIGN_FIELD] == '') {
throw new InvalidArgumentException('SHASIGN parameter not present in parameters.');
@ -959,22 +1045,24 @@ class Mercanet
if (hash_equals($this->shaSign, $compute)) {
if (
in_array($this->parameters['responseCode'], [
'00', // Paiement accepté
'02', // Demande d’autorisation par téléphone à la banque à cause d’un dépassement du plafond d’autorisation sur la carte, si vous êtes autorisé à forcer les transactions
'03', // Contrat commerçant invalide
'05', // Autorisation refusée Refus 3D Secure, Refus bancaire acquéreur, Repli VADS, Fraude
'11', // Utilisé dans le cas d'un contrôle différé. Le PAN est en opposition
'12', // Transaction invalide, vérifier les paramètres transférés dans la requête
'14', // Coordonnées du moyen de paiement invalides (ex: n° de carte ou cryptogramme visuel de la carte) ou vérification AVS échouée
'17', // Annulation de l’acheteur
'30', // Erreur de format
'34', // Suspicion de fraude (seal erroné), Refus fraude acquéreur
'54', // Date de validité du moyen de paiement dépassée
'60', // Transaction en attente
'75', // Nombre de tentatives de saisie des coordonnées du moyen de paiement sous Sips Paypage dépassé
'90', // Service temporairement indisponible
'94', // Transaction dupliquée : le transactionReference de la transaction est déjà utilisé
'97', // Délai expiré, transaction refusée
'00', // Paiement accepté.
'02', // Demande d'autorisation par téléphone à la banque à cause d'un dépassement du plafond
// d'autorisation sur la carte, si vous êtes autorisé à forcer les transactions.
'03', // Contrat commerçant invalide.
'05', // Autorisation refusée Refus 3D Secure, Refus bancaire acquéreur, Repli VADS, Fraude.
'11', // Utilisé dans le cas d'un contrôle différé. Le PAN est en opposition.
'12', // Transaction invalide, vérifier les paramètres transférés dans la requête.
'14', // Coordonnées du moyen de paiement invalides (ex: n° de carte ou cryptogramme visuel de
// la carte) ou vérification AVS échouée.
'17', // Annulation de l'acheteur.
'30', // Erreur de format.
'34', // Suspicion de fraude (seal erroné), Refus fraude acquéreur.
'54', // Date de validité du moyen de paiement dépassée.
'60', // Transaction en attente.
'75', // Nombre de tentatives de saisie des coordonnées du moyen de paiement sous Sips Paypage dépassé.
'90', // Service temporairement indisponible.
'94', // Transaction dupliquée : le transactionReference de la transaction est déjà utilisé.
'97', // Délai expiré, transaction refusée.
'99' // Problème temporaire du serveur de paiement.
])
) {
@ -987,10 +1075,10 @@ class Mercanet
/**
* Retrieves a response parameter.
*
* @param string $param
* @throws \InvalidArgumentException
* @param string $key
* @return mixed
*/
public function getParam($key)
public function getParam(string $key): mixed
{
return $this->parameterArray[$key];
}
@ -1064,7 +1152,7 @@ class Mercanet
"MERCANET [" . strval($this->parameters['transactionReference']) . "] : curl error: " . curl_error($ch)
);
curl_close($ch);
return (object)['status' => 'KO', 'code' => 500];
return (object) ['status' => 'KO', 'code' => 500];
}
if ($info['http_code'] != 200) {
@ -1075,7 +1163,7 @@ class Mercanet
$result
));
curl_close($ch);
return (object)['status' => 'KO', 'code' => 500];
return (object) ['status' => 'KO', 'code' => 500];
}
curl_close($ch);
@ -1084,23 +1172,27 @@ class Mercanet
"MERCANET [%s] : service did not sent back data",
$this->parameters['transactionReference']
));
return (object)['status' => 'KO', 'code' => 500];
return (object) ['status' => 'KO', 'code' => 500];
}
$result_array = json_decode($result);
if (isset($result_array->redirectionStatusCode)) {
if ($result_array->redirectionStatusCode === '00') {
return (object)[
return (object) [
'status' => 'OK',
'code' => $result_array->redirectionStatusCode,
// @phpstan-ignore property.notFound
'url' => $result_array->redirectionUrl,
// @phpstan-ignore property.notFound
'version' => $result_array->redirectionVersion,
'data' => $result_array->redirectionData
// @phpstan-ignore property.notFound
'data' => $result_array->redirectionData,
];
} else {
return (object)[
return (object) [
'status' => 'KO',
'code' => $result_array->redirectionStatusCode,
'seal' => $result_array->seal
// @phpstan-ignore property.notFound
'seal' => $result_array->seal,
];
}
} else {
@ -1108,7 +1200,7 @@ class Mercanet
"MERCANET [%s] : redirectionStatusCode missing",
$this->parameters['transactionReference']
));
return (object)['status' => 'KO', 'code' => 500];
return (object) ['status' => 'KO', 'code' => 500];
} //end if
}
}

View file

@ -2,12 +2,6 @@
namespace App\Mail;
use App\Models\MailContactData;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Attachment;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\File;
class ContactComplainMail extends ContactMail
{
/**

View file

@ -7,7 +7,6 @@ use Illuminate\Bus\Queueable;
use Illuminate\Mail\Attachment;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\File;
use League\Csv\Bom;
use League\Csv\Writer;
use SplTempFileObject;
@ -35,6 +34,7 @@ class ContactMail extends Mailable
* Create a new message instance.
*
* @param \App\Models\MailContactData $data
* @param string|null $file
* @return void
*/
public function __construct(MailContactData $data, string|null $file = null)

View file

@ -158,8 +158,12 @@ class Customer extends Authenticatable implements MustVerifyEmail
$output = $receivedM->mapWithKeys(
function (array $messagesArray, string $fromUsername) use (&$sentM, $dateSort) {
// @phpstan-ignore-next-line
$responses = collect(\array_merge($sentM->pull($fromUsername) ?? [], $messagesArray))->sort($dateSort);
$responses = collect(\array_merge(
$sentM->pull($fromUsername) ?? [],
$messagesArray
))
// @phpstan-ignore-next-line
->sort($dateSort);
$last = $responses->last();
$fromCustomer = collect($messagesArray)->first()->fromCustomer;
return [$fromUsername => collect([
@ -408,7 +412,7 @@ class Customer extends Authenticatable implements MustVerifyEmail
return collect(array_merge(
parent::toArray(),
// @phpstan-ignore-next-line
(array)$this->apiData
(array) $this->apiData
))->intersectByKeys([
'email' => '',
'firstname' => '',

View file

@ -24,8 +24,8 @@ use Illuminate\Support\Facades\Cache;
* @property boolean $button_2_status Slide button n°2 publish status.
* @property boolean $button_2_target Slide button n°2 target.
* @property boolean $published Slide publish status.
* @property-read \Illuminate\Support\Carbon $published_at Slide published at.
* @property-read \Illuminate\Support\Carbon $unpublished_at Slide unpublished at.
* @property \Illuminate\Support\Carbon|null $published_at Slide published at.
* @property \Illuminate\Support\Carbon|null $unpublished_at Slide unpublished at.
* @property-read \Carbon\Carbon $created_at Created date.
* @property-read \Carbon\Carbon $updated_at Updated date.
*/
@ -138,7 +138,7 @@ class DemarcheSlide extends Model
$published_at = $demarcheSlide->published_at;
/** @var \Carbon\Carbon|null */
$unpublished_at = $demarcheSlide->unpublished_at;
$wantedStatus = $demarcheSlide->published;
$wantedStatus = $demarcheSlide->published;
if ($published_at or $unpublished_at) {
$demarcheSlide->published = $demarcheSlide->planificated_status;
}

View file

@ -313,7 +313,7 @@ class DepartaimantsCollection extends Model
foreach (self::getDepKeys($this->type) as $depKey) {
/** @var \App\Enums\Departaimants\IDepartaimant */
$dep = \forward_static_call([$className, 'make'], $depKey);
$deps[$depKey] = (object)[
$deps[$depKey] = (object) [
'departaimant' => $dep,
'status' => $this->getStatus($dep)
];
@ -342,7 +342,7 @@ class DepartaimantsCollection extends Model
/** @var \App\Enums\Departaimants\IDepartaimant */
$dep = \forward_static_call([$className, 'make'], $depKey);
if ($status->equals($this->getStatus($dep))) {
$deps[$depKey] = (object)[
$deps[$depKey] = (object) [
'departaimant' => $dep,
'status' => $this->getStatus($dep)
];
@ -377,7 +377,7 @@ class DepartaimantsCollection extends Model
$fieldCols = self::getTableColumnWith();
$totalFieldCols = self::$tableFields * $fieldCols;
$depsPerField = floor($totalFieldCols / self::$tableFields);
return (int)floor((array_search(
return (int) floor((array_search(
'.' . $dep->value(),
array_keys(self::getDeps($depColtype))
) + $depsPerField) / $depsPerField);

View file

@ -128,9 +128,9 @@ class Discount extends Model
$res = $mesBr->getMur();
if (!$res) {
$message = 'ERROR MesBR API : getMur on api failed';
} elseif (Arr::get((array)$res, 'status') === 'KO') {
} elseif (Arr::get((array) $res, 'status') === 'KO') {
$message = Arr::get(
(array)$res,
(array) $res,
'message',
'ERROR MesBR API : getMur on api failed (no message)'
);
@ -189,7 +189,7 @@ class Discount extends Model
) : $url;
$res->coupons = collect($res->coupons)->map(fn(object $coupon) =>
(object)array_merge((array)$coupon, [
(object) array_merge((array) $coupon, [
'desktop_image_available' => $replaceUrl($coupon->desktop_image_available),
'desktop_image_unavailable' => $replaceUrl($coupon->desktop_image_unavailable),
'mobile_image_available' => $replaceUrl($coupon->mobile_image_available),
@ -205,7 +205,7 @@ class Discount extends Model
*/
public static function getCachedDiscounts(): \Illuminate\Database\Eloquent\Collection
{
return Cache::remember('publishedDiscounts', 86400, function () {
return Cache::remember('publishedDiscounts', 86400, function () {
return self::query()->get();
});
}

View file

@ -10,6 +10,8 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
/**
* @phpcs:disable Generic.Files.LineLength.TooLong
*
* @property \Carbon\Carbon $year Historical milestone year.
* @property string $title Historical milestone title.
* @property string $description Historical milestone description.
@ -25,6 +27,8 @@ use Illuminate\Support\Facades\Cache;
* @property boolean $published Historical milestone publish status.
* @property-read \Illuminate\Support\Carbon $created_at Created date.
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
*
* @phpcs:enable
*/
class HistoricalMilestone extends Model
{

View file

@ -101,6 +101,10 @@ class MailContactData extends Model
'consumptionDateYear' => '0000',
];
/**
* @param array $attributes
* @param string|null $filePath
*/
public function __construct(array $attributes = [], string|null $filePath = '')
{
parent::__construct($attributes);
@ -189,6 +193,12 @@ class MailContactData extends Model
];
}
/**
* Get the file name.
*
* @param string $filePath
* @return string
*/
private function getFileName(string $filePath): string
{
if (!File::exists($filePath)) {

View file

@ -35,8 +35,8 @@ use Illuminate\Support\Facades\Cache;
* @property boolean $button_2_target Slide button n°2 target.
* @property boolean $new Slide picto new.
* @property boolean $published Slide publish status.
* @property-read \Illuminate\Support\Carbon $published_at Slide published_at.
* @property-read \Illuminate\Support\Carbon $unpublished_at Slide unpublished_at.
* @property \Illuminate\Support\Carbon|null $published_at Slide published_at.
* @property \Illuminate\Support\Carbon|null $unpublished_at Slide unpublished_at.
* @property-read \Illuminate\Support\Carbon $created_at Created date.
* @property-read \Illuminate\Support\Carbon $updated_at Updated date.
*/
@ -188,7 +188,7 @@ class MainSlide extends Model
$published_at = $mainSlide->published_at;
/** @var \Carbon\Carbon|null */
$unpublished_at = $mainSlide->unpublished_at;
$wantedStatus = $mainSlide->published;
$wantedStatus = $mainSlide->published;
if ($published_at or $unpublished_at) {
$mainSlide->published = $mainSlide->planificated_status;
}

View file

@ -87,7 +87,7 @@ class News extends Model implements Sitemapable, SchemaOrgInterface
/**
* Get model's setting to apply on scout search (meilisearch).
*
* @return array
* @var array
*/
public static $searchSettings = [
'filterableAttributes' => ['title', 'content', 'published'],

View file

@ -71,7 +71,7 @@ class NewsBreeding extends Model
/**
* Get model's setting to apply on scout search (meilisearch).
*
* @return array
* @var array
*/
public static $searchSettings = [
'filterableAttributes' => ['title', 'content', 'published'],

View file

@ -57,7 +57,9 @@ class OcbBreeder extends Model
})
->paginate(perPage: 9, page: $page)
->through(function (OcbBreeder $ocbBreederModel) {
return view('components.fo.breeding.card-ocb-breeder', ['ocbBreederModel' => $ocbBreederModel])->render();
return view('components.fo.breeding.card-ocb-breeder', [
'ocbBreederModel' => $ocbBreederModel
])->render();
})->toArray();
}
}

View file

@ -105,7 +105,7 @@ class Product extends Model implements SeoInterface, Sitemapable, SchemaOrgInter
/**
* Get model's setting to apply on scout search (meilisearch).
*
* @return array
* @var array
*/
public static $searchSettings = [
'filterableAttributes' => ['label', 'description', 'preparation', 'ingredients', 'published'],

View file

@ -94,7 +94,7 @@ class Recipe extends Model implements SeoInterface, Sitemapable, SchemaOrgInterf
/**
* Get model's setting to apply on scout search (meilisearch).
*
* @return array
* @var array
*/
public static $searchSettings = [
'filterableAttributes' => ['title', 'preparation', 'advice', 'published'],

View file

@ -59,7 +59,7 @@ class Hex implements ValidationRule
$pattern .= ')$/';
if (!(bool)preg_match($pattern, $value)) {
if (!(bool) preg_match($pattern, $value)) {
$fail(trans($this->message()));
}
}

View file

@ -32,7 +32,7 @@ trait ChangesModelOrder
throw new \RuntimeException("The second last param isn't an object.");
}
if (get_class($model) !== (string)Str::of($className)->replaceStart('\\', '')) {
if (get_class($model) !== (string) Str::of($className)->replaceStart('\\', '')) {
throw new \RuntimeException("The {$className} doesn't match second last binded param.");
}

View file

@ -109,7 +109,7 @@ trait BaseEnum
}
$baseArray[$index] = $elements[$enum->name];
}
return [$enum->name => (object)$baseArray];
return [$enum->name => (object) $baseArray];
})->all());
}
return self::getCache('enums');

View file

@ -64,7 +64,7 @@ trait HasPicture
?string $requiredWithout = null,
bool $sometimes = false,
): array {
$dimensions = (object)[
$dimensions = (object) [
'minWidth' => $minWidth ?? $this->minWidth,
'minHeight' => $minHeight ?? $this->minHeight,
'maxWidth' => $maxWidth ?? $this->maxWidth,
@ -107,7 +107,7 @@ trait HasPicture
int $limitMax = 5,
bool $nullable = false
): array {
$sizes = (object)[
$sizes = (object) [
'minWidth' => $minWidth ?? $this->minWidth,
'minHeight' => $minHeight ?? $this->minHeight,
'maxWidth' => $maxWidth ?? $this->maxWidth,

View file

@ -92,6 +92,12 @@
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
],
"phpcs": [
"./vendor/bin/phpcs"
],
"phpstan": [
"./vendor/bin/phpstan"
]
},
"extra": {

View file

@ -41,7 +41,7 @@ return [
|
*/
'debug' => (bool)env('APP_DEBUG', false),
'debug' => (bool) env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------

View file

@ -8,69 +8,69 @@ use App\Models\Recipe;
return [
/*
|--------------------------------------------------------------------------
| Default Search Engine
|--------------------------------------------------------------------------
|
| This option controls the default search connection that gets used while
| using Laravel Scout. This connection is used when syncing all models
| to the search service. You should adjust this based on your needs.
|
| Supported: "algolia", "meilisearch", "typesense",
| "database", "collection", "null"
|
|--------------------------------------------------------------------------
| Default Search Engine
|--------------------------------------------------------------------------
|
| This option controls the default search connection that gets used while
| using Laravel Scout. This connection is used when syncing all models
| to the search service. You should adjust this based on your needs.
|
| Supported: "algolia", "meilisearch", "typesense",
| "database", "collection", "null"
|
*/
'driver' => env('SCOUT_DRIVER', 'meilisearch'),
/*
|--------------------------------------------------------------------------
| Index Prefix
|--------------------------------------------------------------------------
|
| Here you may specify a prefix that will be applied to all search index
| names used by Scout. This prefix may be useful if you have multiple
| "tenants" or applications sharing the same search infrastructure.
|
|--------------------------------------------------------------------------
| Index Prefix
|--------------------------------------------------------------------------
|
| Here you may specify a prefix that will be applied to all search index
| names used by Scout. This prefix may be useful if you have multiple
| "tenants" or applications sharing the same search infrastructure.
|
*/
'prefix' => env('SCOUT_PREFIX', ''),
/*
|--------------------------------------------------------------------------
| Queue Data Syncing
|--------------------------------------------------------------------------
|
| This option allows you to control if the operations that sync your data
| with your search engines are queued. When this is set to "true" then
| all automatic data syncing will get queued for better performance.
|
|--------------------------------------------------------------------------
| Queue Data Syncing
|--------------------------------------------------------------------------
|
| This option allows you to control if the operations that sync your data
| with your search engines are queued. When this is set to "true" then
| all automatic data syncing will get queued for better performance.
|
*/
'queue' => env('SCOUT_QUEUE', false),
/*
|--------------------------------------------------------------------------
| Database Transactions
|--------------------------------------------------------------------------
|
| This configuration option determines if your data will only be synced
| with your search indexes after every open database transaction has
| been committed, thus preventing any discarded data from syncing.
|
|--------------------------------------------------------------------------
| Database Transactions
|--------------------------------------------------------------------------
|
| This configuration option determines if your data will only be synced
| with your search indexes after every open database transaction has
| been committed, thus preventing any discarded data from syncing.
|
*/
'after_commit' => true,
/*
|--------------------------------------------------------------------------
| Chunk Sizes
|--------------------------------------------------------------------------
|
| These options allow you to control the maximum chunk size when you are
| mass importing data into the search engine. This allows you to fine
| tune each of these chunk sizes based on the power of the servers.
|
|--------------------------------------------------------------------------
| Chunk Sizes
|--------------------------------------------------------------------------
|
| These options allow you to control the maximum chunk size when you are
| mass importing data into the search engine. This allows you to fine
| tune each of these chunk sizes based on the power of the servers.
|
*/
'chunk' => [
@ -79,29 +79,29 @@ return [
],
/*
|--------------------------------------------------------------------------
| Soft Deletes
|--------------------------------------------------------------------------
|
| This option allows to control whether to keep soft deleted records in
| the search indexes. Maintaining soft deleted records can be useful
| if your application still needs to search for the records later.
|
|--------------------------------------------------------------------------
| Soft Deletes
|--------------------------------------------------------------------------
|
| This option allows to control whether to keep soft deleted records in
| the search indexes. Maintaining soft deleted records can be useful
| if your application still needs to search for the records later.
|
*/
'soft_delete' => false,
/*
|--------------------------------------------------------------------------
| Meilisearch Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your Meilisearch settings. Meilisearch is an open
| source search engine with minimal configuration. Below, you can state
| the host and key information for your own Meilisearch installation.
|
| See: https://www.meilisearch.com/docs/learn/configuration/instance_options#all-instance-options
|
|--------------------------------------------------------------------------
| Meilisearch Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your Meilisearch settings. Meilisearch is an open
| source search engine with minimal configuration. Below, you can state
| the host and key information for your own Meilisearch installation.
|
| See: https://www.meilisearch.com/docs/learn/configuration/instance_options#all-instance-options
|
*/
'meilisearch' => [

View file

@ -55,7 +55,7 @@ return [
'send_default_pii' => env('SENTRY_SEND_DEFAULT_PII', false),
// @see: https://docs.sentry.io/platforms/php/guides/laravel/configuration/options/#traces-sample-rate.
'traces_sample_rate' => env('SENTRY_TRACES_SAMPLE_RATE') === null ? null : (float)env('SENTRY_TRACES_SAMPLE_RATE'),
'traces_sample_rate' => env('SENTRY_TRACES_SAMPLE_RATE') === null ? null : (float) env('SENTRY_TRACES_SAMPLE_RATE'),
'before_send' => [\App\Lib\Helpers\ExceptionsHelper::class, 'sentryEventHandler'],
];

View file

@ -42,7 +42,8 @@ class BreederFactory extends Factory
'geo_type' => \collect(GeoType::toArray())->random()->value,
'ocbStatus' => \collect(OCBStatus::toArray())->random()->value,
'ocbType' => \collect(OCBType::toArray())->random()->value,
'audit' => 1, // FIXME: utilité de ce champs, aucune indication
// FIXME: utilité de ce champs, aucune indication
'audit' => 1,
'valid_marketing_date' => Carbon::now(),
'approaches' => [],
'is_highlighted' => fake()->boolean(75),

View file

@ -30,8 +30,7 @@
<rule ref="Generic.Files.LineLength"/>
<rule ref="Generic.Formatting.DisallowMultipleStatements"/>
<rule ref="Generic.Formatting.MultipleStatementAlignment"/>
<rule ref="Generic.Formatting.NoSpaceAfterCast"/>
<rule ref="Generic.Functions.CallTimePassByReference"/>
<rule ref="Generic.Formatting.SpaceAfterCast"/>
<rule ref="Generic.Functions.FunctionCallArgumentSpacing"/>
<rule ref="Generic.Metrics.CyclomaticComplexity"/>
<rule ref="Generic.Metrics.NestingLevel"/>
@ -45,9 +44,6 @@
<rule ref="Generic.Strings.UnnecessaryStringConcat"/>
<rule ref="Generic.WhiteSpace.DisallowTabIndent"/>
<rule ref="Generic.WhiteSpace.ScopeIndent"/>
<rule ref="MySource.PHP.EvalObjectFactory"/>
<rule ref="MySource.PHP.GetRequestData"/>
<rule ref="MySource.PHP.AjaxNullComparison"/>
<rule ref="PEAR.Classes.ClassDeclaration"/>
<rule ref="PEAR.Commenting.InlineComment"/>
<rule ref="PSR1.Classes.ClassDeclaration"/>
@ -80,7 +76,7 @@
<rule ref="Squiz.Scope.MemberVarScope"/>
<rule ref="Squiz.Scope.MethodScope"/>
<rule ref="Squiz.Scope.StaticThisUsage"/>
<rule ref="Squiz.WhiteSpace.LanguageConstructSpacing"/>
<rule ref="Generic.WhiteSpace.LanguageConstructSpacing"/>
<rule ref="Squiz.WhiteSpace.LogicalOperatorSpacing"/>
<rule ref="Squiz.WhiteSpace.MemberVarSpacing">
<properties>

View file

@ -18,16 +18,16 @@
<td class="text-center align-middle">{{ $sellItemModel->type->label() }}</td>
<td class="text-center align-middle">@money($sellItemModel->price)</td>
<td class="text-center align-middle">
<img class="image-preview" src="{{ asset($sellItemModel->picture) }}" title="{{ $sellItemModel->picture_title }}"
alt="{{ $sellItemModel->picture_alt }}">
<img class="image-preview" src="{{ asset($sellItemModel->picture) }}"
title="{{ $sellItemModel->picture_title }}" alt="{{ $sellItemModel->picture_alt }}">
</td>
<td class="text-center align-middle">
<span class="badge text-bg-secondary">{{ $sellItemModel->updated_at->isoFormat('LLLL') }}</span>
</td>
<td class="text-end align-middle">
@canAny(['show', 'duplicate', 'update', 'delete'], $sellItemModel)
<form class="btn-group confirmDeleteTS" action="{{ route('bo.sell_items.destroy', $sellItemModel) }}"
method="POST" novalidate>
<form class="btn-group confirmDeleteTS"
action="{{ route('bo.sell_items.destroy', $sellItemModel) }}" method="POST" novalidate>
@can('view', $sellItemModel)
<a class="btn btn-sm btn-warning" data-bs-toggle="tooltip"
href="{{ route('bo.sell_items.show', ['sell_item' => $sellItemModel]) }}"

View file

@ -133,7 +133,7 @@ Route::middleware(['throttle:web'])->name('fo.')->group(function () {
->name('breeding.')
->group(function () {
Route::view('/', 'fo.pages.breeding.index')->name('index');
Route::get('/oui-c-est-bon', [BreedingController::class, 'OCBbreederPage'])->name('oui-c-est-bon');
Route::get('/oui-c-est-bon', [BreedingController::class, 'ocbBreederPage'])->name('oui-c-est-bon');
Route::view('/sortant-a-l-exterieur', 'fo.pages.breeding.sortant-a-l-exterieur')
->name('sortant-a-l-exterieur');
Route::get('/{breeding_static_page:slug}', [BreedingController::class, 'breedingPage'])