Compare commits
5 commits
master
...
dependenci
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1732a52355 | ||
|
|
dafef6e5d5 | ||
|
|
e5380fcacf | ||
|
|
2cf5c76b35 | ||
|
|
2fd635c116 |
279 changed files with 9657 additions and 7481 deletions
26
.gitignore
vendored
26
.gitignore
vendored
|
|
@ -31,16 +31,42 @@ resources/theme
|
|||
.npm/
|
||||
.composer/
|
||||
.zshrc
|
||||
.rector-cache/
|
||||
|
||||
# Ignore public favicon
|
||||
/public/android-chrome-192x192.png
|
||||
/public/android-chrome-512x512.png
|
||||
/public/android-icon-144x144.png
|
||||
/public/android-icon-192x192.png
|
||||
/public/android-icon-36x36.png
|
||||
/public/android-icon-48x48.png
|
||||
/public/android-icon-72x72.png
|
||||
/public/android-icon-96x96.png
|
||||
/public/apple-chrome-192x192.png
|
||||
/public/apple-chrome-512x512.png
|
||||
/public/apple-icon-114x114.png
|
||||
/public/apple-icon-120x120.png
|
||||
/public/apple-icon-144x144.png
|
||||
/public/apple-icon-152x152.png
|
||||
/public/apple-icon-180x180.png
|
||||
/public/apple-icon-57x57.png
|
||||
/public/apple-icon-60x60.png
|
||||
/public/apple-icon-72x72.png
|
||||
/public/apple-icon-76x76.png
|
||||
/public/apple-icon-precomposed.png
|
||||
/public/apple-icon.png
|
||||
/public/apple-touch-icon.png
|
||||
/public/browserconfig.xml
|
||||
/public/browserconfig.xml
|
||||
/public/favicon-16x16.png
|
||||
/public/favicon-32x32.png
|
||||
/public/favicon-96x96.png
|
||||
/public/favicon.ico
|
||||
/public/manifest.json
|
||||
/public/ms-icon-144x144.png
|
||||
/public/ms-icon-150x150.png
|
||||
/public/ms-icon-310x310.png
|
||||
/public/ms-icon-70x70.png
|
||||
/public/mstile-150x150.png
|
||||
/public/safari-pinned-tab.svg
|
||||
/public/site.webmanifest
|
||||
|
|
|
|||
|
|
@ -1,20 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Auth;
|
||||
|
||||
use App\Models\Customer;
|
||||
use ErrorException;
|
||||
use Exception;
|
||||
use Illuminate\Auth\EloquentUserProvider;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as UserContract;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Contracts\Auth\UserProvider as UserProviderContract;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use LDC\LDCCRM\CrmApiV4;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
use RuntimeException;
|
||||
use SensitiveParameter;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Crm user provider to integrate nicely with Laravel
|
||||
|
|
@ -23,32 +30,28 @@ class CrmUserProvider extends EloquentUserProvider implements UserProviderContra
|
|||
{
|
||||
/**
|
||||
* The model to use, specified in auth config guard.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $usedModel = Customer::class;
|
||||
private string $usedModel = Customer::class;
|
||||
|
||||
/**
|
||||
* Retrieve a user by the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
*/
|
||||
public function retrieveByCredentials(array $credentials)
|
||||
{
|
||||
// * Let laravel find a model
|
||||
$model = parent::retrieveByCredentials($credentials) ??
|
||||
self::retrieveTrashed($credentials);
|
||||
$model = parent::retrieveByCredentials($credentials) ?? self::retrieveTrashed($credentials);
|
||||
|
||||
try {
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('crmAPI');
|
||||
/** @var CrmApiV4 */
|
||||
$crm = resolve('crmAPI');
|
||||
|
||||
// Si pas de compte local.
|
||||
if (!$model) {
|
||||
if (! $model) {
|
||||
$crmCustomer = $crm->getCustomer($credentials['email']);
|
||||
|
||||
if (!$crmCustomer) {
|
||||
if (! $crmCustomer) {
|
||||
// * Customer is not found on CRM.
|
||||
return null;
|
||||
}
|
||||
|
|
@ -63,40 +66,38 @@ class CrmUserProvider extends EloquentUserProvider implements UserProviderContra
|
|||
}
|
||||
report($e);
|
||||
Log::error('Unhandled response ' . $e->getApiError()->label());
|
||||
} catch (CrmException | \Exception $e) {
|
||||
} catch (CrmException | Exception $e) {
|
||||
report($e);
|
||||
|
||||
// Une erreur critique est survenue avec la CRM.
|
||||
return null;
|
||||
} //end try
|
||||
Log::error(__CLASS__ . '::retrieveByCredentials reached end of possibilities.');
|
||||
} // end try
|
||||
Log::error(self::class . '::retrieveByCredentials reached end of possibilities.');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a user against the given credentials.
|
||||
*
|
||||
* @param UserContract $model
|
||||
* @param array $credentials
|
||||
* @return boolean|null
|
||||
* @throws \RuntimeException If model provided is not a Customer or connection to server fails.
|
||||
* @throws \LDC\LDCCRM\Exceptions\CrmException On CRM call error.
|
||||
* @throws \Exception On CRM call error.
|
||||
* @throws RuntimeException If model provided is not a Customer or connection to server fails.
|
||||
* @throws CrmException On CRM call error.
|
||||
* @throws Exception On CRM call error.
|
||||
*/
|
||||
public function validateCredentials(UserContract $model, array $credentials): bool|null
|
||||
public function validateCredentials(UserContract $model, array $credentials): ?bool
|
||||
{
|
||||
/** @var \App\Models\Customer $model */
|
||||
if (\get_class($model) !== $this->usedModel) {
|
||||
throw new \RuntimeException('Cannot authenticate any thing else than ' . $this->usedModel);
|
||||
/** @var Customer $model */
|
||||
if ($model::class !== $this->usedModel) {
|
||||
throw new RuntimeException('Cannot authenticate any thing else than ' . $this->usedModel);
|
||||
}
|
||||
|
||||
try {
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('crmAPI');
|
||||
/** @var CrmApiV4 */
|
||||
$crm = resolve('crmAPI');
|
||||
|
||||
// * If has trait soft delete and customer trashed, then restore customer.
|
||||
if (
|
||||
\in_array(\Illuminate\Database\Eloquent\SoftDeletes::class, \class_uses_recursive($model)) and
|
||||
$model->trashed()
|
||||
\in_array(SoftDeletes::class, \class_uses_recursive($model)) && $model->trashed()
|
||||
) {
|
||||
$model->restore();
|
||||
}
|
||||
|
|
@ -105,10 +106,10 @@ class CrmUserProvider extends EloquentUserProvider implements UserProviderContra
|
|||
return $crm->login($credentials['email'], $credentials['password']);
|
||||
} catch (ApiErrorException $e) {
|
||||
if (
|
||||
$e->getApiError()->equals(ApiError::modelNotFound) ||
|
||||
($e->getApiError()->equals(ApiError::authFailed) && !$model->existsInCrm())
|
||||
$e->getApiError()->equals(ApiError::modelNotFound) || ($e->getApiError()->equals(ApiError::authFailed) && ! $model->existsInCrm())
|
||||
) {
|
||||
$model->delete();
|
||||
|
||||
return false;
|
||||
}
|
||||
if ($e->getApiError()->equals(ApiError::authFailed)) {
|
||||
|
|
@ -120,32 +121,42 @@ class CrmUserProvider extends EloquentUserProvider implements UserProviderContra
|
|||
$model->save();
|
||||
$model->sendEmailVerificationNotification();
|
||||
Session::flash('warning', \trans('front.messages.account_not_activated'));
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (CrmException | \Exception $e) {
|
||||
} catch (CrmException | Exception $e) {
|
||||
report($e);
|
||||
if (config('app.debug')) {
|
||||
throw $e;
|
||||
}
|
||||
return false;
|
||||
} //end try
|
||||
throw_if(config('app.debug'), $e);
|
||||
|
||||
return false;
|
||||
} // end try
|
||||
|
||||
Log::error(self::class . '::validateCredentials reached end of possibilities.');
|
||||
|
||||
Log::error(__CLASS__ . '::validateCredentials reached end of possibilities.');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a local customer
|
||||
* CRM customer passwordless (Laravel 11 introduces password rehashing after login).
|
||||
*/
|
||||
public function rehashPasswordIfRequired(
|
||||
UserContract $user,
|
||||
#[SensitiveParameter] array $credentials,
|
||||
bool $force = false
|
||||
): void {
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a local customer.
|
||||
*
|
||||
* @param \LDC\LDCCRM\Models\Customer $crmCustomer
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \Throwable If saving to DB failed.
|
||||
* @throws Throwable If saving to DB failed.
|
||||
*/
|
||||
private function createLocalCustomer(\LDC\LDCCRM\Models\Customer $crmCustomer): Model
|
||||
{
|
||||
/** @var \App\Models\Customer $model */
|
||||
/** @var Customer $model */
|
||||
$model = $this->usedModel::withTrashed()->firstOrNew([
|
||||
'email' => $crmCustomer->email
|
||||
'email' => $crmCustomer->email,
|
||||
]);
|
||||
$model->hashcode = $crmCustomer->hashcode;
|
||||
$model->email_verified_at = $crmCustomer->status ? now() : null;
|
||||
|
|
@ -160,14 +171,12 @@ class CrmUserProvider extends EloquentUserProvider implements UserProviderContra
|
|||
/**
|
||||
* Retrieve a trashed customer by the given credentials.
|
||||
*
|
||||
* @param array $credentials
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
* @throws \ErrorException If cannot connect to LDAP.
|
||||
* @throws ErrorException If cannot connect to LDAP.
|
||||
*/
|
||||
private function retrieveTrashed(array $credentials): ?Authenticatable
|
||||
private function retrieveTrashed(array $credentials): ?UserContract
|
||||
{
|
||||
// * Make changes
|
||||
if (empty($credentials)) {
|
||||
if ($credentials === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -177,12 +186,12 @@ class CrmUserProvider extends EloquentUserProvider implements UserProviderContra
|
|||
$query = $this->createModel()->newQuery();
|
||||
|
||||
foreach ($credentials as $key => $value) {
|
||||
if (!Str::contains($key, 'password')) {
|
||||
if (! Str::contains($key, 'password')) {
|
||||
$query->where($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/** @var \App\Models\Customer|null $query */
|
||||
/** @var Customer|null $query */
|
||||
return $query->withTrashed()->first();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,30 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\Lib\Discount;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class AsArrayOfDiscount implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Cast the given value.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return array<\App\Lib\Discount>
|
||||
* @param Model $model
|
||||
* @param mixed $value
|
||||
* @return array<Discount>
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes): array
|
||||
{
|
||||
// phpcs:enable
|
||||
return \collect(\json_decode($value, true))->map(function ($input) use ($model, $key, $attributes) {
|
||||
return \collect(\json_decode($value, true))->map(function ($input) use ($model, $key, $attributes): Discount {
|
||||
$inputCast = new AsDiscount();
|
||||
|
||||
return $inputCast->get($model, $key, \json_encode($input), $attributes);
|
||||
})->all();
|
||||
}
|
||||
|
|
@ -28,11 +32,10 @@ class AsArrayOfDiscount implements CastsAttributes
|
|||
/**
|
||||
* Prepare the given value for storage.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param \App\Lib\Discount $value
|
||||
* @param array $attributes
|
||||
* @param Model $model
|
||||
* @param Discount $value
|
||||
* @return string Json encoded array<\App\Lib\Discount>
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
|
|
@ -40,6 +43,7 @@ class AsArrayOfDiscount implements CastsAttributes
|
|||
// phpcs:enable
|
||||
return \json_encode(\collect($value)->map(function ($input) use ($model, $key, $attributes) {
|
||||
$inputCast = new AsDiscount();
|
||||
|
||||
return \json_decode($inputCast->set($model, $key, $input, $attributes));
|
||||
})->all());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,64 +1,69 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use App\Lib\Discount;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use RuntimeException;
|
||||
|
||||
class AsDiscount implements CastsAttributes
|
||||
{
|
||||
/**
|
||||
* Cast the given value.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return \App\Lib\Discount
|
||||
* @param Model $model
|
||||
* @param mixed $value
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
*/
|
||||
public function get($model, string $key, $value, array $attributes): Discount
|
||||
{
|
||||
// phpcs:enable
|
||||
$inputData = \json_decode($value, true);
|
||||
|
||||
return Discount::make(...\array_values($inputData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the given value for storage.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @param Model $model
|
||||
* @param mixed $value
|
||||
* @return string Json encoded \App\Lib\Inputs\Definition\Input
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
{
|
||||
// phpcs:enable
|
||||
$this->assertIsInput($value);
|
||||
/** @var \App\Lib\Discount $value */
|
||||
|
||||
/** @var Discount $value */
|
||||
return $value->toJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert is instance of \App\Lib\Discount
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws \RuntimeException If the value is not an input.
|
||||
* @throws RuntimeException If the value is not an input.
|
||||
*/
|
||||
private function assertIsInput(mixed $value): void
|
||||
{
|
||||
if (!\is_object($value) or !($value instanceof Discount)) {
|
||||
if (! \is_object($value) || ! ($value instanceof Discount)) {
|
||||
$value = \json_encode($value);
|
||||
throw new \RuntimeException(
|
||||
__CLASS__ . ' needs value to be array of \'' . Discount::class . "' given is {$value}"
|
||||
throw new RuntimeException(
|
||||
self::class . ' needs value to be array of \'' . Discount::class . "' given is {$value}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use IPLib\Address\AddressInterface;
|
||||
use IPLib\Factory;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @template TGet
|
||||
|
|
@ -14,30 +19,30 @@ class Ip implements CastsAttributes
|
|||
/**
|
||||
* Transform the attribute from the underlying model values.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array<string,mixed> $attributes
|
||||
* @return \IPLib\Address\AddressInterface|null
|
||||
* @param array<string,mixed> $attributes
|
||||
* @return AddressInterface|null
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
*/
|
||||
public function get(Model $model, string $key, mixed $value, array $attributes)
|
||||
{
|
||||
// phpcs:enable
|
||||
return \IPLib\Factory::parseAddressString($value);
|
||||
return Factory::parseAddressString($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the attribute to its underlying model values.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param \IPLib\Address\AddressInterface|string|null $value
|
||||
* @param array<string,mixed> $attributes
|
||||
* @param AddressInterface|string|null $value
|
||||
* @param array<string,mixed> $attributes
|
||||
* @return mixed
|
||||
* @throws \RuntimeException If value is not or instance of \IPLib\Address\AddressInterface.
|
||||
*
|
||||
* @throws RuntimeException If value is not or instance of \IPLib\Address\AddressInterface.
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceAfterLastUsed
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInImplementedInterfaceBeforeLastUsed
|
||||
*/
|
||||
public function set(Model $model, string $key, mixed $value, array $attributes)
|
||||
|
|
@ -47,15 +52,12 @@ class Ip implements CastsAttributes
|
|||
return null;
|
||||
}
|
||||
if (is_string($value)) {
|
||||
$value = \IPLib\Factory::parseAddressString($value);
|
||||
}
|
||||
if (!is_object($value) or !($value instanceof \IPLib\Address\AddressInterface)) {
|
||||
throw new \RuntimeException(
|
||||
"{$key} has to be instance of " .
|
||||
\IPLib\Address\AddressInterface::class
|
||||
);
|
||||
$value = Factory::parseAddressString($value);
|
||||
}
|
||||
throw_if(! is_object($value) || ! ($value instanceof AddressInterface), RuntimeException::class, "{$key} has to be instance of " .
|
||||
AddressInterface::class);
|
||||
$value->getAddressType();
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
|
@ -12,6 +14,7 @@ class TestMail extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $signature = 'uwil:mail:test';
|
||||
|
||||
/**
|
||||
|
|
@ -19,16 +22,15 @@ class TestMail extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $description = 'Send test email to equipe.web@ldc.fr';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
Mail::raw(sprintf('UWIL mail-test from %s %s', \config('app.name'), \config('app.url')), function ($msg) {
|
||||
Mail::raw(sprintf('UWIL mail-test from %s %s', \config('app.name'), \config('app.url')), function ($msg): void {
|
||||
$msg->to('equipe.web@ldc.fr')->subject('Test Email');
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands\Theme;
|
||||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
|
|
@ -18,6 +20,7 @@ class SwitchCommand extends Command implements PromptsForMissingInput
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $signature = 'uwil:theme:switch {theme : The theme folder name on theme-merge project}';
|
||||
|
||||
/**
|
||||
|
|
@ -25,6 +28,7 @@ class SwitchCommand extends Command implements PromptsForMissingInput
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $description = 'Switch GGW theme and install it';
|
||||
|
||||
/**
|
||||
|
|
@ -35,22 +39,20 @@ class SwitchCommand extends Command implements PromptsForMissingInput
|
|||
protected function promptForMissingArgumentsUsing()
|
||||
{
|
||||
return [
|
||||
'theme' => fn () => search(
|
||||
'theme' => fn (): int | string => search(
|
||||
label: 'Search for a theme:',
|
||||
placeholder: 'default-theme',
|
||||
options: fn (string $value): array => \collect(File::directories(\resource_path('theme')))
|
||||
->map(fn (string $dir_path) => \pathinfo($dir_path, \PATHINFO_BASENAME))
|
||||
->map(fn (string $dir_path): string => \pathinfo($dir_path, \PATHINFO_BASENAME))
|
||||
->filter(fn (string $dir_path) => $value ? Str::of($dir_path)->contains($value) : true)
|
||||
->filter(fn (string $dir_path) => $dir_path !== 'mounted')
|
||||
->all()
|
||||
)
|
||||
->filter(fn (string $dir_path): bool => $dir_path !== 'mounted')
|
||||
->all(),
|
||||
placeholder: 'default-theme'
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
|
|
@ -65,7 +67,7 @@ class SwitchCommand extends Command implements PromptsForMissingInput
|
|||
"{$mount_path} is not a link, cannot remove it"
|
||||
);
|
||||
\throw_if(
|
||||
!File::delete($mount_path),
|
||||
! File::delete($mount_path),
|
||||
"{$mount_path} Failed to remove file"
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
use App\Models\User;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
|
|
@ -16,13 +18,15 @@ class UserCreate extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $signature = 'uwil:user:create';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string|null
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $description = 'Create a backend admin user';
|
||||
|
||||
/**
|
||||
|
|
@ -62,8 +66,6 @@ class UserCreate extends Command
|
|||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
|
|
@ -83,13 +85,13 @@ class UserCreate extends Command
|
|||
$this->addRole();
|
||||
|
||||
$user = new User([
|
||||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'password' => $this->password,
|
||||
'role' => $this->role,
|
||||
'published' => true,
|
||||
'published_at' => Carbon::now(),
|
||||
'first_name' => $this->first_name,
|
||||
'last_name' => $this->last_name,
|
||||
'email' => $this->email,
|
||||
'password' => $this->password,
|
||||
'role' => $this->role,
|
||||
'published' => true,
|
||||
'published_at' => Date::now(),
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
||||
|
|
@ -100,8 +102,6 @@ class UserCreate extends Command
|
|||
|
||||
/**
|
||||
* Add a first name to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addFirstName(): void
|
||||
{
|
||||
|
|
@ -109,7 +109,7 @@ class UserCreate extends Command
|
|||
try {
|
||||
$tmp = $this->ask('Type the wanted user first name', 'Admin');
|
||||
$validator = Validator::make(['first_name' => $tmp], [
|
||||
'first_name' => 'required|min:3|max:255'
|
||||
'first_name' => 'required|min:3|max:255',
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->first_name = $tmp;
|
||||
|
|
@ -118,15 +118,14 @@ class UserCreate extends Command
|
|||
'Please provide a valid first name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
} // end try
|
||||
} // end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a last name to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addLastName(): void
|
||||
{
|
||||
|
|
@ -134,7 +133,7 @@ class UserCreate extends Command
|
|||
try {
|
||||
$tmp = $this->ask('Type the wanted user last name', 'Saïtama');
|
||||
$validator = Validator::make(['last_name' => $tmp], [
|
||||
'last_name' => 'required|min:3|max:255'
|
||||
'last_name' => 'required|min:3|max:255',
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->last_name = $tmp;
|
||||
|
|
@ -143,15 +142,14 @@ class UserCreate extends Command
|
|||
'Please provide a valid last_name %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
} // end try
|
||||
} // end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an email to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addEmail(): void
|
||||
{
|
||||
|
|
@ -159,7 +157,7 @@ class UserCreate extends Command
|
|||
try {
|
||||
$tmp = $this->ask('Type the wanted user email', 'equipe.web@ldc.fr');
|
||||
$validator = Validator::make(['email' => $tmp], [
|
||||
'email' => 'required|unique:users,email|email:rfc,dns'
|
||||
'email' => 'required|unique:users,email|email:rfc,dns',
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->email = $tmp;
|
||||
|
|
@ -168,31 +166,26 @@ class UserCreate extends Command
|
|||
'Please provide a valid email %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
} // end try
|
||||
} // end while
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a password to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addPassword(): void
|
||||
{
|
||||
while (
|
||||
($this->password = $this->secret(
|
||||
(!\is_null($this->password) ? 'Failed to confirm, ' : '') . 'Type the wanted user password'
|
||||
)) !== $this->secret('Confirm the password')
|
||||
) {
|
||||
continue;
|
||||
}; //end while
|
||||
do {
|
||||
$prefix = $this->password !== null ? 'Failed to confirm, ' : '';
|
||||
$this->password = $this->secret($prefix . 'Type the wanted user password');
|
||||
$confirmation = $this->secret('Confirm the password');
|
||||
} while ($this->password !== $confirmation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a role to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addRole(): void
|
||||
{
|
||||
|
|
@ -215,7 +208,7 @@ class UserCreate extends Command
|
|||
$tmp = RoleEnum::marketing;
|
||||
}
|
||||
$validator = Validator::make(['role' => $tmp], [
|
||||
'role' => 'required'
|
||||
'role' => 'required',
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->role = $tmp;
|
||||
|
|
@ -224,8 +217,9 @@ class UserCreate extends Command
|
|||
'Please choose from the selection %s',
|
||||
\implode(',', collect($e->errors())->flatten()->all())
|
||||
));
|
||||
|
||||
continue;
|
||||
} //end try
|
||||
}; //end while
|
||||
} // end try
|
||||
} // end while
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Jobs\DeleteOlds\DeleteOldCustomers;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
|
|
@ -13,12 +14,12 @@ class Kernel extends ConsoleKernel
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
#[\Override]
|
||||
protected $commands = [];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums\ActivityLogs;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
@ -25,7 +27,6 @@ enum ActivityLogsEventEnum: int
|
|||
self::deleted->name => 'Suppression',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Custom added classes definition
|
||||
*/
|
||||
|
|
@ -38,8 +39,6 @@ enum ActivityLogsEventEnum: int
|
|||
|
||||
/**
|
||||
* Get Class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function bootstrapClass(): string
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums\Pagination;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums\Theme;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums\Users;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
|
@ -10,15 +12,17 @@ class Handler extends ExceptionHandler
|
|||
/**
|
||||
* A list of exception types with their corresponding custom log levels.
|
||||
*
|
||||
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
|
||||
* @var array<class-string<Throwable>, \Psr\Log\LogLevel::*>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $levels = [];
|
||||
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<\Throwable>>
|
||||
* @var array<int, class-string<Throwable>>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $dontReport = [];
|
||||
|
||||
/**
|
||||
|
|
@ -26,6 +30,7 @@ class Handler extends ExceptionHandler
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
|
|
@ -34,14 +39,12 @@ class Handler extends ExceptionHandler
|
|||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
public function register(): void
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
$this->reportable(function (Throwable $e): void {
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
resolve('sentry')->captureException($e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\ActivityLog;
|
||||
use App\Traits\Controllers\ChangesModelOrder;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ActivityLogController extends Controller
|
||||
|
|
@ -15,14 +19,12 @@ class ActivityLogController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
$this->authorize('isConceptor');
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
|
||||
/** @var Builder $query */
|
||||
$query = ActivityLog::query()->with('user');
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -45,25 +47,32 @@ class ActivityLogController extends Controller
|
|||
/** Custom pagination */
|
||||
$activitylogModels = $this->paginate($query);
|
||||
|
||||
return view('back::pages.activity_logs.index', compact('activitylogModels', 'search', 'searchFields'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.activity_logs.index';
|
||||
|
||||
return view($view, [
|
||||
'activitylogModels' => $activitylogModels,
|
||||
'search' => $search,
|
||||
'searchFields' => $searchFields,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\ActivityLog $activity_log
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(ActivityLog $activity_log): \Illuminate\Contracts\View\View
|
||||
public function show(ActivityLog $activity_log): View
|
||||
{
|
||||
$this->authorize('isConceptor');
|
||||
$targetModelClass = $activity_log->model_class;
|
||||
$targetModel = $activity_log->model_class::where(
|
||||
(new $targetModelClass())->getRouteKeyName(),
|
||||
new $targetModelClass()->getRouteKeyName(),
|
||||
$activity_log->model_id
|
||||
)->first();
|
||||
|
||||
return view('back::pages.activity_logs.show', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.activity_logs.show';
|
||||
|
||||
return view($view, [
|
||||
'activitylogModel' => $activity_log,
|
||||
'targetModel' => $targetModel,
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -15,8 +17,6 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -25,8 +25,6 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
|
|
@ -35,18 +33,17 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showLoginForm(): View
|
||||
{
|
||||
return view('back::auth.login');
|
||||
/** @var view-string $view */
|
||||
$view = 'back::auth.login';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
|
|
@ -56,14 +53,14 @@ class LoginController extends Controller
|
|||
/**
|
||||
* Attempt to log the user into the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
protected function attemptLogin(Request $request)
|
||||
{
|
||||
$credentials = $this->credentials($request);
|
||||
// * Attempt login only using published users.
|
||||
$credentials['published'] = true;
|
||||
|
||||
return $this->guard()->attempt(
|
||||
$credentials,
|
||||
$request->boolean('remember')
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -13,8 +15,6 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
|
|
@ -23,8 +23,6 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\BannedIps\StoreBannedIpRequest;
|
||||
use App\Http\Requests\Bo\BannedIps\UpdateBannedIpRequest;
|
||||
use App\Models\BannedIp;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -22,13 +27,10 @@ class BannedIpController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $bannedipModels */
|
||||
/** @var Builder $bannedipModels */
|
||||
$bannedipModels = BannedIp::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -49,43 +51,42 @@ class BannedIpController extends Controller
|
|||
/** Custom pagination */
|
||||
$bannedipModels = $this->paginate($bannedipModels);
|
||||
|
||||
return view('back::pages.banned-ips.index', compact('bannedipModels', 'search', 'searchFields'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.banned-ips.index';
|
||||
|
||||
return view($view, ['bannedipModels' => $bannedipModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\BannedIp $banned_ip
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(BannedIp $banned_ip): \Illuminate\Contracts\View\View
|
||||
public function create(BannedIp $banned_ip): View
|
||||
{
|
||||
return view('back::pages.banned-ips.create', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.banned-ips.create';
|
||||
|
||||
return view($view, [
|
||||
'bannedipModel' => $banned_ip,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\BannedIps\StoreBannedIpRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreBannedIpRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StoreBannedIpRequest $request): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$banned_ip = new BannedIp();
|
||||
$banned_ip->fill($request->validated());
|
||||
if ($banned_ip->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.banned_ips.edit', $banned_ip)
|
||||
return to_route('bo.banned_ips.edit', $banned_ip)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
|
|
@ -95,38 +96,33 @@ class BannedIpController extends Controller
|
|||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\BannedIp $banned_ip
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(BannedIp $banned_ip): \Illuminate\Contracts\View\View
|
||||
public function edit(BannedIp $banned_ip): View
|
||||
{
|
||||
return view('back::pages.banned-ips.edit', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.banned-ips.edit';
|
||||
|
||||
return view($view, [
|
||||
'bannedipModel' => $banned_ip,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\BannedIps\UpdateBannedIpRequest $request
|
||||
* @param \App\Models\BannedIp $banned_ip
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateBannedIpRequest $request, BannedIp $banned_ip): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdateBannedIpRequest $request, BannedIp $banned_ip): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $banned_ip) {
|
||||
$banned_ip->fill($request->validated());
|
||||
if ($banned_ip->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.banned_ips.edit', $banned_ip)
|
||||
return to_route('bo.banned_ips.edit', $banned_ip)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
|
|
@ -136,23 +132,19 @@ class BannedIpController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\BannedIp $banned_ip
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(BannedIp $banned_ip): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(BannedIp $banned_ip): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($banned_ip) {
|
||||
if ($banned_ip->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.banned_ips.index')
|
||||
return to_route('bo.banned_ips.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -12,21 +14,22 @@ use App\Models\Code;
|
|||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Kwaadpepper\Serial\Exceptions\SerialCasterException;
|
||||
use Throwable;
|
||||
|
||||
class CodeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show code form to generate and export
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
public function index(): View
|
||||
{
|
||||
$this->authorize('generate', Code::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
$nbCodeBase = Code::query()->max('id');
|
||||
$nbCodeUsed = Code::query()->whereHas(
|
||||
'participations',
|
||||
|
|
@ -35,22 +38,23 @@ class CodeController extends Controller
|
|||
)->count();
|
||||
$nbCodeExported = Code::query()->where('code_exported', true)->count();
|
||||
$nbCodeRemainingToExport = Code::query()->where('code_exported', false)->count();
|
||||
return view('back::pages.codes.index', compact(
|
||||
'settings',
|
||||
'nbCodeBase',
|
||||
'nbCodeUsed',
|
||||
'nbCodeExported',
|
||||
'nbCodeRemainingToExport'
|
||||
));
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.codes.index';
|
||||
|
||||
return view($view, [
|
||||
'settings' => $settings,
|
||||
'nbCodeBase' => $nbCodeBase,
|
||||
'nbCodeUsed' => $nbCodeUsed,
|
||||
'nbCodeExported' => $nbCodeExported,
|
||||
'nbCodeRemainingToExport' => $nbCodeRemainingToExport,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run generate codes action
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Codes\GenerateCodesRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function generate(GenerateCodesRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function generate(GenerateCodesRequest $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('generate', Code::class);
|
||||
Queue::push(
|
||||
|
|
@ -66,7 +70,7 @@ class CodeController extends Controller
|
|||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'La tache de génération à été ajoutée, un mail de notification sera envoyé à l\'adresse :email lorsque le traitement sera terminé.',
|
||||
[
|
||||
'email' => config('mail.admin')
|
||||
'email' => config('mail.admin'),
|
||||
]
|
||||
)
|
||||
);
|
||||
|
|
@ -74,11 +78,8 @@ class CodeController extends Controller
|
|||
|
||||
/**
|
||||
* Run export codes
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Codes\ExportCodesRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function export(ExportCodesRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function export(ExportCodesRequest $request): RedirectResponse
|
||||
{
|
||||
$this->authorize('export', Code::class);
|
||||
Queue::push(
|
||||
|
|
@ -93,25 +94,22 @@ class CodeController extends Controller
|
|||
'success',
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
__('L\'export des codes à commencé, un mail de notification sera envoyé à l\'adresse :emaillorsque le traitement sera terminé.', [
|
||||
'email' => config('mail.admin')
|
||||
'email' => config('mail.admin'),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a specific code.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Codes\CodeSearchRequest $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function search(CodeSearchRequest $request): \Illuminate\Contracts\View\View
|
||||
public function search(CodeSearchRequest $request): View
|
||||
{
|
||||
$this->authorize('search', Code::class);
|
||||
$code = null;
|
||||
try {
|
||||
$code = Code::query()->where('id', Code::serialToInt($request->code))->first();
|
||||
} catch (\Throwable $e) {
|
||||
if (\get_class($e) === SerialCasterException::class) {
|
||||
} catch (Throwable $e) {
|
||||
if ($e::class === SerialCasterException::class) {
|
||||
$code = false;
|
||||
}
|
||||
} finally {
|
||||
|
|
@ -126,10 +124,13 @@ class CodeController extends Controller
|
|||
$used_counter = null;
|
||||
if ($code) {
|
||||
$used_counter = Participation::query()
|
||||
->whereHas('code', fn(Builder $q) => $q->where('id', $code->id))
|
||||
->whereHas('code', fn (Builder $q) => $q->where('id', $code->id))
|
||||
->count();
|
||||
}
|
||||
|
||||
return view('back::pages.codes.search', compact('code', 'used_counter'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.codes.search';
|
||||
|
||||
return view($view, ['code' => $code, 'used_counter' => $used_counter]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,60 +1,62 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* Dashboard Page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
public function index(): View
|
||||
{
|
||||
// * Pour les stats.
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
$avgParticipUser = 0;
|
||||
$participationPeriod = [];
|
||||
$statsUnique = [];
|
||||
$query = DB::table((new Participation())->getTable());
|
||||
$dateFrmtr = function (object $row) {
|
||||
$row->date = Carbon::parse($row->date)->isoFormat('DD/MM/YYYY');
|
||||
$query = DB::table(new Participation()->getTable());
|
||||
$dateFrmtr = function (object $row): object {
|
||||
$row->date = Date::parse($row->date)->isoFormat('DD/MM/YYYY');
|
||||
|
||||
return $row;
|
||||
};
|
||||
|
||||
/** @var \Illuminate\Support\Collection<string,object> */
|
||||
/** @var Collection<string, object> */
|
||||
$participationsPerDay = (clone $query)
|
||||
->selectRaw('COUNT(*) AS count, DATE(created_at) AS date')
|
||||
->groupByRaw('DATE(created_at)')->get()->map($dateFrmtr)->keyBy('date');
|
||||
|
||||
/** @var \Illuminate\Support\Collection<object> */
|
||||
/** @var Collection<object> */
|
||||
$participationsUniquePerDay = (clone $query)
|
||||
->selectRaw('DISTINCT customer_id AS user, COUNT(*) AS count, DATE(created_at) AS date')
|
||||
->groupByRaw('DATE(created_at), user')->get()->map($dateFrmtr);
|
||||
|
||||
/** @var \Illuminate\Support\Collection<object> */
|
||||
/** @var Collection<object> */
|
||||
$participationsUniquePerCustomer = (clone $query)
|
||||
->selectRaw("DISTINCT customer_id AS user, COUNT(*) AS count")
|
||||
->selectRaw('DISTINCT customer_id AS user, COUNT(*) AS count')
|
||||
->groupBy('user')->orderBy('user')->get();
|
||||
|
||||
$participationsTotal = Participation::query()->count();
|
||||
|
||||
/** @var \Illuminate\Support\Collection<object> 3 codes EAN les plus utilisés */
|
||||
/** @var Collection<object> 3 codes EAN les plus utilisés */
|
||||
$codesEan = (clone $query)
|
||||
->selectRaw('COUNT(product_id) AS nb_usage, product_id, ean_code')
|
||||
->join('products', 'product_id', '=', 'products.id')
|
||||
->groupBy('product_id', 'ean_code')
|
||||
->orderByDesc('nb_usage')->limit(3)->get();
|
||||
|
||||
$participationsUniquePerDay->each(function (object $row) use (&$statsUnique) {
|
||||
$participationsUniquePerDay->each(function (object $row) use (&$statsUnique): void {
|
||||
Arr::set($statsUnique, $row->date, (Arr::get($statsUnique, $row->date) ?? 0) + 1);
|
||||
});
|
||||
|
||||
|
|
@ -62,23 +64,22 @@ class DashboardController extends Controller
|
|||
if ($participationsUniquePerCustomer->count() > 0) {
|
||||
$avgParticipUser = round($participationsTotal / $participationsUniquePerCustomer->count(), 1);
|
||||
}
|
||||
|
||||
// * Création des tableaux avec toutes les dates depuis le début du jeu
|
||||
// * et le nombre de participations associées pour le graph JS.
|
||||
$start_date = $settings->start_date;
|
||||
$end_date = now()->lt($settings->end_date) ? now() : $settings->end_date;
|
||||
now()->lt($settings->end_date) ? now() : $settings->end_date;
|
||||
$dates = $participationsPerDay->keys();
|
||||
$count = $participationsPerDay->pluck('count');
|
||||
$countUnique = $dates->map(fn (string $formated_date) => Arr::get($statsUnique, $formated_date, 0));
|
||||
|
||||
return view('back::pages.dashboard.index', compact(
|
||||
'dates',
|
||||
'count',
|
||||
'countUnique',
|
||||
'participationsTotal',
|
||||
'avgParticipUser',
|
||||
'codesEan',
|
||||
'settings'
|
||||
));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.dashboard.index';
|
||||
|
||||
return view($view, [
|
||||
'dates' => $dates,
|
||||
'count' => $count,
|
||||
'countUnique' => $countUnique,
|
||||
'participationsTotal' => $participationsTotal,
|
||||
'avgParticipUser' => $avgParticipUser,
|
||||
'codesEan' => $codesEan,
|
||||
'settings' => $settings,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -7,6 +9,9 @@ use App\Http\Requests\Bo\FaqQuestions\StoreFaqQuestionRequest;
|
|||
use App\Http\Requests\Bo\FaqQuestions\UpdateFaqQuestionRequest;
|
||||
use App\Models\FaqQuestion;
|
||||
use App\Models\FaqTheme;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -23,13 +28,10 @@ class FaqQuestionController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $faqQuestionModels */
|
||||
/** @var Builder $faqQuestionModels */
|
||||
$faqQuestionModels = FaqQuestion::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -55,38 +57,42 @@ class FaqQuestionController extends Controller
|
|||
/** Custom pagination */
|
||||
$faqQuestionModels = $this->paginate($faqQuestionModels);
|
||||
|
||||
return view('back::pages.faq-questions.index', compact('faqQuestionModels', 'search', 'searchFields'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-questions.index';
|
||||
|
||||
return view($view, [
|
||||
'faqQuestionModels' => $faqQuestionModels,
|
||||
'search' => $search,
|
||||
'searchFields' => $searchFields,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(FaqQuestion $faqQuestion): \Illuminate\Contracts\View\View
|
||||
public function create(FaqQuestion $faqQuestion): View
|
||||
{
|
||||
$faqThemeModels = FaqTheme::all();
|
||||
return view('back::pages.faq-questions.create', [
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-questions.create';
|
||||
|
||||
return view($view, [
|
||||
'faqQuestionModel' => $faqQuestion,
|
||||
'faqThemeModels' => $faqThemeModels
|
||||
'faqThemeModels' => $faqThemeModels,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\FaqQuestions\StoreFaqQuestionRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreFaqQuestionRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StoreFaqQuestionRequest $request): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$faqQuestion = new FaqQuestion();
|
||||
$faqQuestion->fill($request->validated());
|
||||
if ($faqQuestion->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.faq-questions.edit', $faqQuestion)
|
||||
return to_route('bo.faq-questions.edit', $faqQuestion)
|
||||
->with(
|
||||
'success',
|
||||
trans(
|
||||
|
|
@ -95,8 +101,8 @@ class FaqQuestionController extends Controller
|
|||
)
|
||||
);
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
|
|
@ -106,45 +112,38 @@ class FaqQuestionController extends Controller
|
|||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(FaqQuestion $faqQuestion): \Illuminate\Contracts\View\View
|
||||
public function edit(FaqQuestion $faqQuestion): View
|
||||
{
|
||||
$faqThemeModels = FaqTheme::all();
|
||||
return view('back::pages.faq-questions.edit', [
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-questions.edit';
|
||||
|
||||
return view($view, [
|
||||
'faqQuestionModel' => $faqQuestion,
|
||||
'faqThemeModels' => $faqThemeModels
|
||||
'faqThemeModels' => $faqThemeModels,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\FaqQuestions\UpdateFaqQuestionRequest $request
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(
|
||||
UpdateFaqQuestionRequest $request,
|
||||
FaqQuestion $faqQuestion
|
||||
): \Illuminate\Http\RedirectResponse {
|
||||
): RedirectResponse {
|
||||
return DB::transaction(function () use ($request, $faqQuestion) {
|
||||
$faqQuestion->fill($request->validated());
|
||||
if ($faqQuestion->saveOrFail()) {
|
||||
return redirect()
|
||||
->route(
|
||||
'bo.faq-questions.edit',
|
||||
$faqQuestion
|
||||
)
|
||||
return to_route('bo.faq-questions.edit', $faqQuestion)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
|
|
@ -154,23 +153,19 @@ class FaqQuestionController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(FaqQuestion $faqQuestion): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(FaqQuestion $faqQuestion): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($faqQuestion) {
|
||||
if ($faqQuestion->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.faq-questions.index')
|
||||
return to_route('bo.faq-questions.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\FaqThemes\StoreFaqThemeRequest;
|
||||
use App\Http\Requests\Bo\FaqThemes\UpdateFaqThemeRequest;
|
||||
use App\Models\FaqTheme;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -22,13 +27,10 @@ class FaqThemeController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $faqThemeModels */
|
||||
/** @var Builder $faqThemeModels */
|
||||
$faqThemeModels = FaqTheme::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -49,36 +51,35 @@ class FaqThemeController extends Controller
|
|||
/** Custom pagination */
|
||||
$faqThemeModels = $this->paginate($faqThemeModels);
|
||||
|
||||
return view('back::pages.faq-themes.index', compact('faqThemeModels', 'search', 'searchFields'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-themes.index';
|
||||
|
||||
return view($view, ['faqThemeModels' => $faqThemeModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(FaqTheme $faqTheme): \Illuminate\Contracts\View\View
|
||||
public function create(FaqTheme $faqTheme): View
|
||||
{
|
||||
return view('back::pages.faq-themes.create', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-themes.create';
|
||||
|
||||
return view($view, [
|
||||
'faqThemeModel' => $faqTheme,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\FaqThemes\StoreFaqThemeRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreFaqThemeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StoreFaqThemeRequest $request): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$faqTheme = new FaqTheme();
|
||||
$faqTheme->fill($request->validated());
|
||||
if ($faqTheme->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.faq-themes.edit', $faqTheme)
|
||||
return to_route('bo.faq-themes.edit', $faqTheme)
|
||||
->with(
|
||||
'success',
|
||||
trans(
|
||||
|
|
@ -87,8 +88,8 @@ class FaqThemeController extends Controller
|
|||
)
|
||||
);
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
|
|
@ -98,43 +99,35 @@ class FaqThemeController extends Controller
|
|||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(FaqTheme $faqTheme): \Illuminate\Contracts\View\View
|
||||
public function edit(FaqTheme $faqTheme): View
|
||||
{
|
||||
return view('back::pages.faq-themes.edit', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-themes.edit';
|
||||
|
||||
return view($view, [
|
||||
'faqThemeModel' => $faqTheme,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\FaqThemes\UpdateFaqThemeRequest $request
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(
|
||||
UpdateFaqThemeRequest $request,
|
||||
FaqTheme $faqTheme
|
||||
): \Illuminate\Http\RedirectResponse {
|
||||
): RedirectResponse {
|
||||
return DB::transaction(function () use ($request, $faqTheme) {
|
||||
$faqTheme->fill($request->validated());
|
||||
if ($faqTheme->saveOrFail()) {
|
||||
return redirect()
|
||||
->route(
|
||||
'bo.faq-themes.edit',
|
||||
$faqTheme
|
||||
)
|
||||
return to_route('bo.faq-themes.edit', $faqTheme)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
|
|
@ -144,23 +137,19 @@ class FaqThemeController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(FaqTheme $faqTheme): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(FaqTheme $faqTheme): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($faqTheme) {
|
||||
if ($faqTheme->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.faq-themes.index')
|
||||
return to_route('bo.faq-themes.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', __(
|
||||
'crud.messages.cannot_be_deleted',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
|
|
|
|||
|
|
@ -1,15 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\InstantWin;
|
||||
use App\Models\Prize;
|
||||
use App\Models\Settings;
|
||||
use Carbon\Carbon;
|
||||
use Carbon\CarbonInterface;
|
||||
use Carbon\CarbonInterval;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use stdClass;
|
||||
|
||||
class InstantWinController extends Controller
|
||||
{
|
||||
|
|
@ -23,22 +29,21 @@ class InstantWinController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
public function index(): View
|
||||
{
|
||||
$instantWinModelList = InstantWin::query()->orderBy('available_at')->get();
|
||||
$instantWinModelList = InstantWin::query()->oldest('available_at')->get();
|
||||
|
||||
return view('back::pages.instant-win.index', [
|
||||
'instantWinModelList' => $instantWinModelList
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.instant-win.index';
|
||||
|
||||
return view($view, [
|
||||
'instantWinModelList' => $instantWinModelList,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns generated instant win.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function generate(): JsonResponse
|
||||
{
|
||||
|
|
@ -56,23 +61,20 @@ class InstantWinController extends Controller
|
|||
*/
|
||||
$day_end = now()->setTime(22, 29);
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
$prizeModelList = Prize::all();
|
||||
|
||||
/** @var \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinDayCalendar> */
|
||||
/** @var Collection<array-key, WinDayCalendar> */
|
||||
$datesGlobal = collect();
|
||||
/**
|
||||
* @var \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinTimeElement>
|
||||
* Liste de tous les lots à gagner
|
||||
*/
|
||||
/** @var Collection<array-key, WinTimeElement> Liste de tous les lots à gagner */
|
||||
$lotsGlobal = collect();
|
||||
|
||||
// * Seed srand !
|
||||
\mt_srand(time());
|
||||
|
||||
// * Init prize list
|
||||
$prizeModelList->each(function (Prize $prize) use ($lotsGlobal, $day_start, $day_end) {
|
||||
$prizeModelList->each(function (Prize $prize) use ($lotsGlobal, $day_start, $day_end): void {
|
||||
for ($i = 0; $i < $prize->quantity; $i++) {
|
||||
$el = new WinTimeElement();
|
||||
$el->prize = $prize;
|
||||
|
|
@ -84,7 +86,7 @@ class InstantWinController extends Controller
|
|||
}
|
||||
});
|
||||
|
||||
$lotsGlobal->shuffle(time());
|
||||
$lotsGlobal->shuffle();
|
||||
|
||||
// * Init days calendar
|
||||
foreach ($settings->start_date->toPeriod($settings->end_date, CarbonInterval::make('1day')) as $date) {
|
||||
|
|
@ -95,8 +97,8 @@ class InstantWinController extends Controller
|
|||
}
|
||||
|
||||
// * Save Instant wins
|
||||
$this->generateArray($lotsGlobal, $datesGlobal, 0)->each(function (WinDayCalendar $winDayCalendar) {
|
||||
$winDayCalendar->lots->each(function (WinTimeElement $winTimeElement) {
|
||||
$this->generateArray($lotsGlobal, $datesGlobal, 0)->each(function (WinDayCalendar $winDayCalendar): void {
|
||||
$winDayCalendar->lots->each(function (WinTimeElement $winTimeElement): void {
|
||||
$instantWin = new InstantWin();
|
||||
$instantWin->available_at = $winTimeElement->time;
|
||||
$instantWin->prize()->associate($winTimeElement->prize);
|
||||
|
|
@ -114,11 +116,11 @@ class InstantWinController extends Controller
|
|||
*
|
||||
* Même algo que celui implémenté par Romain.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinTimeElement> $lotsGlobal
|
||||
* Liste de tous les lots à gagner
|
||||
* @param \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinDayCalendar> $dateGlobal
|
||||
* @param integer $prizesDone
|
||||
* @return \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinDayCalendar>
|
||||
* @param Collection<array-key, WinTimeElement> $lotsGlobal
|
||||
* Liste de tous les lots à gagner
|
||||
* @param Collection<array-key, WinDayCalendar> $dateGlobal
|
||||
* @return Collection<array-key, WinDayCalendar>
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
private function generateArray(Collection $lotsGlobal, Collection $dateGlobal, int $prizesDone): Collection
|
||||
|
|
@ -129,7 +131,7 @@ class InstantWinController extends Controller
|
|||
|
||||
// ? À-t-on déjà assigné un lot par jour (au moins) ?
|
||||
// ? Le jour aléatoire sélectionné à déja un lot ?
|
||||
if ($prizesDone < $dateGlobal->count() and $dateGlobal->get($rKey)->lots->count() > 0) {
|
||||
if ($prizesDone < $dateGlobal->count() && $dateGlobal->get($rKey)->lots->count() > 0) {
|
||||
return $this->generateArray($lotsGlobal, $dateGlobal, $prizesDone);
|
||||
}
|
||||
|
||||
|
|
@ -142,15 +144,15 @@ class InstantWinController extends Controller
|
|||
}
|
||||
|
||||
// * Tri par heure et assignation du jour correct.
|
||||
$dateGlobal->each(function (WinDayCalendar $date) {
|
||||
$date->lots = $date->lots->sort(fn (WinTimeElement $a, WinTimeElement $b) =>
|
||||
$a->time->timestamp - $b->time->timestamp)
|
||||
->map(function (WinTimeElement $time) use ($date) {
|
||||
$dateGlobal->each(function (WinDayCalendar $date): void {
|
||||
$date->lots = $date->lots->sort(fn (WinTimeElement $a, WinTimeElement $b): int | float => $a->time->timestamp - $b->time->timestamp)
|
||||
->map(function (WinTimeElement $time) use ($date): WinTimeElement {
|
||||
$time->time->setDate(
|
||||
$date->time->year,
|
||||
$date->time->month,
|
||||
$date->time->day
|
||||
);
|
||||
|
||||
return $time;
|
||||
});
|
||||
});
|
||||
|
|
@ -160,23 +162,25 @@ class InstantWinController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* @property \App\Models\Prize $prize Le lot à gagner.
|
||||
* @property \Carbon\Carbon $time Une heure aléatoire.
|
||||
* @property Prize $prize Le lot à gagner.
|
||||
* @property Carbon $time Une heure aléatoire.
|
||||
*
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
|
||||
*/
|
||||
class WinTimeElement extends \stdClass
|
||||
class WinTimeElement extends stdClass
|
||||
{
|
||||
// phpcs:enable
|
||||
}
|
||||
|
||||
/**
|
||||
* @property \Carbon\Carbon|\Carbon\CarbonInterface $time
|
||||
* Un jour dans le temps.
|
||||
* @property \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinTimeElement> $lots
|
||||
* Liste des lots tombant ce jour.
|
||||
* @property Carbon|CarbonInterface $time
|
||||
* Un jour dans le temps.
|
||||
* @property Collection<array-key, WinTimeElement> $lots
|
||||
* Liste des lots tombant ce jour.
|
||||
*
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
|
||||
*/
|
||||
class WinDayCalendar extends \stdClass
|
||||
class WinDayCalendar extends stdClass
|
||||
{
|
||||
// phpcs:enable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Participation;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
||||
class ParticipationController extends Controller
|
||||
|
|
@ -19,15 +22,15 @@ class ParticipationController extends Controller
|
|||
|
||||
/**
|
||||
* View all winners
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function viewWinnerList(): View
|
||||
{
|
||||
$this->authorize('viewWinnerList', Participation::class);
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $participationModels */
|
||||
$participationModels = Participation::query()->with(['customer', 'code', 'instantWin', 'product'])->whereHas('instantWin');
|
||||
/** @var Builder $participationModels */
|
||||
$participationModels = Participation::query()
|
||||
->with(['customer', 'code', 'instantWin', 'product'])
|
||||
->whereHas('instantWin');
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($participationModels);
|
||||
|
|
@ -35,36 +38,37 @@ class ParticipationController extends Controller
|
|||
/** Custom pagination */
|
||||
$participationModels = $this->paginate($participationModels);
|
||||
|
||||
return view('back::pages.winners-list.index', compact(
|
||||
'participationModels'
|
||||
));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.winners-list.index';
|
||||
|
||||
return view($view, ['participationModels' => $participationModels]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display participation form
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function setComment(Participation $participation): View
|
||||
{
|
||||
$this->authorize('setComment', $participation);
|
||||
return view('back::pages.winners-list.set-comment', [
|
||||
'participationModel' => $participation
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.winners-list.set-comment';
|
||||
|
||||
return view($view, [
|
||||
'participationModel' => $participation,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Comment
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function setCommentSubmit(Participation $participation): RedirectResponse
|
||||
{
|
||||
$this->authorize('setComment', $participation);
|
||||
$participation->comment = request()->string('comment');
|
||||
|
||||
$participation->comment = request()->string('comment')->toString();
|
||||
$participation->saveOrFail();
|
||||
|
||||
return back()->with('success', \trans(
|
||||
'Le commentaire à bien été mis à jour'
|
||||
));
|
||||
|
|
@ -72,15 +76,13 @@ class ParticipationController extends Controller
|
|||
|
||||
/**
|
||||
* Change prize sent
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function changePrizeSent(Participation $participation): RedirectResponse
|
||||
{
|
||||
$this->authorize('changePrizeSent', $participation);
|
||||
$participation->prize_sent = true;
|
||||
$participation->saveOrFail();
|
||||
|
||||
return back()->with('success', \trans(
|
||||
'Le lot est bien marqué comme envoyé et une notification à été envoyé au gagant'
|
||||
));
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Prizes\StorePrizeRequest;
|
||||
use App\Http\Requests\Bo\Prizes\UpdatePrizeRequest;
|
||||
use App\Models\Prize;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -22,13 +27,10 @@ class PrizeController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $prizeModels */
|
||||
/** @var Builder $prizeModels */
|
||||
$prizeModels = Prize::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -52,54 +54,53 @@ class PrizeController extends Controller
|
|||
/** Custom pagination */
|
||||
$prizeModels = $this->paginate($prizeModels);
|
||||
|
||||
return view('back::pages.prizes.index', compact('prizeModels', 'search', 'searchFields'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.prizes.index';
|
||||
|
||||
return view($view, ['prizeModels' => $prizeModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Prize $prize): \Illuminate\Contracts\View\View
|
||||
public function show(Prize $prize): View
|
||||
{
|
||||
return view('back::pages.prizes.show', ['prizeModel' => $prize]);
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.prizes.show';
|
||||
|
||||
return view($view, ['prizeModel' => $prize]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Prize $prize): \Illuminate\Contracts\View\View
|
||||
public function create(Prize $prize): View
|
||||
{
|
||||
return view('back::pages.prizes.create', [
|
||||
'prizeModel' => $prize
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.prizes.create';
|
||||
|
||||
return view($view, [
|
||||
'prizeModel' => $prize,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Prizes\StorePrizeRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StorePrizeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StorePrizeRequest $request): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$prize = new Prize();
|
||||
$prize->fill($request->validated());
|
||||
if ($prize->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.prizes.edit', $prize)
|
||||
return to_route('bo.prizes.edit', $prize)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
|
|
@ -109,38 +110,33 @@ class PrizeController extends Controller
|
|||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Prize $prize): \Illuminate\Contracts\View\View
|
||||
public function edit(Prize $prize): View
|
||||
{
|
||||
return view('back::pages.prizes.edit', [
|
||||
'prizeModel' => $prize
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.prizes.edit';
|
||||
|
||||
return view($view, [
|
||||
'prizeModel' => $prize,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Prizes\UpdatePrizeRequest $request
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdatePrizeRequest $request, Prize $prize): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdatePrizeRequest $request, Prize $prize): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $prize) {
|
||||
$prize->fill($request->validated());
|
||||
if ($prize->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.prizes.edit', $prize)
|
||||
return to_route('bo.prizes.edit', $prize)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
|
|
@ -150,23 +146,19 @@ class PrizeController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Prize $prize): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(Prize $prize): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($prize) {
|
||||
if ($prize->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.prizes.index')
|
||||
return to_route('bo.prizes.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -7,6 +9,9 @@ use App\Http\Requests\Bo\Products\StoreProductRequest;
|
|||
use App\Http\Requests\Bo\Products\UpdateProductRequest;
|
||||
use App\Models\Product;
|
||||
use App\Models\Range;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -23,13 +28,10 @@ class ProductController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $productModels */
|
||||
/** @var Builder $productModels */
|
||||
$productModels = Product::query()->with('range');
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -55,63 +57,63 @@ class ProductController extends Controller
|
|||
/** Custom pagination */
|
||||
$productModels = $this->paginate($productModels);
|
||||
|
||||
return view('back::pages.products.index', compact('productModels', 'search', 'searchFields'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.products.index';
|
||||
|
||||
return view($view, ['productModels' => $productModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Product $product): \Illuminate\Contracts\View\View
|
||||
public function show(Product $product): View
|
||||
{
|
||||
return view('back::pages.products.show', ['productModel' => $product]);
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.products.show';
|
||||
|
||||
return view($view, ['productModel' => $product]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function create(Product $product): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
public function create(Product $product): View | RedirectResponse
|
||||
{
|
||||
$rangeModels = Range::all();
|
||||
if (!count($rangeModels)) {
|
||||
return \redirect()->route('bo.ranges.index')
|
||||
if (! count($rangeModels)) {
|
||||
return to_route('bo.ranges.index')
|
||||
->with(
|
||||
'error',
|
||||
'Vous devez ajouter une gamme avant de pouvoir ajouter un produit'
|
||||
);
|
||||
}
|
||||
return view('back::pages.products.create', [
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.products.create';
|
||||
|
||||
return view($view, [
|
||||
'productModel' => $product,
|
||||
'rangeModels' => $rangeModels
|
||||
'rangeModels' => $rangeModels,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Products\StoreProductRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreProductRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StoreProductRequest $request): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$product = new Product();
|
||||
$product->fill($request->validated());
|
||||
if ($product->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.edit', $product)
|
||||
return to_route('bo.products.edit', $product)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
|
|
@ -121,40 +123,36 @@ class ProductController extends Controller
|
|||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Product $product): \Illuminate\Contracts\View\View
|
||||
public function edit(Product $product): View
|
||||
{
|
||||
$rangeModels = Range::all();
|
||||
return view('back::pages.products.edit', [
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.products.edit';
|
||||
|
||||
return view($view, [
|
||||
'productModel' => $product,
|
||||
'rangeModels' => $rangeModels
|
||||
'rangeModels' => $rangeModels,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Products\UpdateProductRequest $request
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdateProductRequest $request, Product $product): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $product) {
|
||||
$product->fill($request->validated());
|
||||
if ($product->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.edit', $product)
|
||||
return to_route('bo.products.edit', $product)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
|
|
@ -164,23 +162,19 @@ class ProductController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Product $product): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(Product $product): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($product) {
|
||||
if ($product->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.products.index')
|
||||
return to_route('bo.products.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\Ranges\StoreRangeRequest;
|
||||
use App\Http\Requests\Bo\Ranges\UpdateRangeRequest;
|
||||
use App\Models\Range;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -22,13 +27,10 @@ class RangeController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $rangeModels */
|
||||
/** @var Builder $rangeModels */
|
||||
$rangeModels = Range::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -49,54 +51,53 @@ class RangeController extends Controller
|
|||
/** Custom pagination */
|
||||
$rangeModels = $this->paginate($rangeModels);
|
||||
|
||||
return view('back::pages.ranges.index', compact('rangeModels', 'search', 'searchFields'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.ranges.index';
|
||||
|
||||
return view($view, ['rangeModels' => $rangeModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Range $range): \Illuminate\Contracts\View\View
|
||||
public function show(Range $range): View
|
||||
{
|
||||
return view('back::pages.ranges.show', ['rangeModel' => $range]);
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.ranges.show';
|
||||
|
||||
return view($view, ['rangeModel' => $range]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(Range $range): \Illuminate\Contracts\View\View
|
||||
public function create(Range $range): View
|
||||
{
|
||||
return view('back::pages.ranges.create', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.ranges.create';
|
||||
|
||||
return view($view, [
|
||||
'rangeModel' => $range,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Ranges\StoreRangeRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreRangeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StoreRangeRequest $request): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$range = new Range();
|
||||
$range->fill($request->validated());
|
||||
if ($range->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.ranges.edit', $range)
|
||||
return to_route('bo.ranges.edit', $range)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
|
|
@ -106,38 +107,33 @@ class RangeController extends Controller
|
|||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Range $range): \Illuminate\Contracts\View\View
|
||||
public function edit(Range $range): View
|
||||
{
|
||||
return view('back::pages.ranges.edit', [
|
||||
'rangeModel' => $range
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.ranges.edit';
|
||||
|
||||
return view($view, [
|
||||
'rangeModel' => $range,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Ranges\UpdateRangeRequest $request
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateRangeRequest $request, Range $range): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdateRangeRequest $request, Range $range): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $range) {
|
||||
$range->fill($request->validated());
|
||||
if ($range->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.ranges.edit', $range)
|
||||
return to_route('bo.ranges.edit', $range)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
|
|
@ -147,28 +143,25 @@ class RangeController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Range $range): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(Range $range): RedirectResponse
|
||||
{
|
||||
if ($range->products()->count()) {
|
||||
return back()->withError(
|
||||
'Cette gamme est associé a des produits, la supression n\'est pas possible'
|
||||
);
|
||||
}
|
||||
|
||||
return DB::transaction(function () use ($range) {
|
||||
if ($range->deleteOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.ranges.index')
|
||||
return to_route('bo.ranges.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
|
|
|
|||
|
|
@ -1,16 +1,20 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Lib\Discount;
|
||||
use App\Mail\Won\DiscountWonMail;
|
||||
use App\Mail\Won\PrizeIsSentMail;
|
||||
use App\Mail\Won\PrizeWonMail;
|
||||
use App\Mail\Won\WinningProofSubmitedMail;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Prize;
|
||||
use App\Models\Settings;
|
||||
use App\Lib\Discount;
|
||||
use App\Models\Participation;
|
||||
use App\Models\User;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
|
@ -21,209 +25,216 @@ class Re7Controller extends Controller
|
|||
{
|
||||
/**
|
||||
* Re7Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(function (Request $request, \Closure $next) {
|
||||
$this->middleware(function (Request $request, Closure $next) {
|
||||
$this->authorize('fo.showRe7');
|
||||
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Home page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function home(): View
|
||||
{
|
||||
return view('theme::pages.home');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.home';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Teaser page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function teaser(): View
|
||||
{
|
||||
return view('theme::pages.teaser');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.teaser';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Teaser page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function endGame(): View
|
||||
{
|
||||
return view('theme::pages.end-game');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.end-game';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show code input page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participate(): View
|
||||
{
|
||||
return view('theme::pages.participation.participate');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.participate';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show code input page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participationExhausted(): View
|
||||
{
|
||||
return view('theme::pages.participation.participation-exhausted');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.participation-exhausted';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
// * -- Participation
|
||||
|
||||
/**
|
||||
* Show prize page
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function prize(Prize $prize): View
|
||||
{
|
||||
// * Fake participation model
|
||||
$participationModel = new Participation();
|
||||
$participationModel = 9999999;
|
||||
return view('theme::pages.participation.won', [
|
||||
'prizeModel' => $prize,
|
||||
'participationModel' => $participationModel
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won';
|
||||
|
||||
return view($view, [
|
||||
'prizeModel' => $prize,
|
||||
'participationModel' => $participationModel,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show discount page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function discount(): View
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var \App\Lib\Discount */
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var Discount */
|
||||
$discount = Arr::get(
|
||||
$settings->web_coupons,
|
||||
$this->getRandomWeightedElementIndex($settings->web_coupons)
|
||||
);
|
||||
|
||||
if (!$settings->discounts_activated) {
|
||||
if (! $settings->discounts_activated) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
$mesBrDiscount = new Discount();
|
||||
return view('theme::pages.participation.won', compact('discount', 'mesBrDiscount'));
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won';
|
||||
|
||||
return view($view, ['discount' => $discount, 'mesBrDiscount' => $mesBrDiscount]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show loose page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function loose(): View
|
||||
{
|
||||
return view('theme::pages.participation.loose');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.home';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
// * -- END Participation
|
||||
|
||||
/**
|
||||
* View won prize mail
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailPrize(Prize $prize): View
|
||||
{
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.re7-preview-mail';
|
||||
|
||||
return view($view, [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'prize',
|
||||
'prize' => $prize
|
||||
])
|
||||
'type' => 'prize',
|
||||
'prize' => $prize,
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View won discount mail
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailDiscount(): View
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->discounts_activated) {
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
if (! $settings->discounts_activated) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.re7-preview-mail';
|
||||
|
||||
return view($view, [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'discount'
|
||||
])
|
||||
'type' => 'discount',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View proof mail received mail
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailProofReceived(): View
|
||||
{
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.re7-preview-mail';
|
||||
|
||||
return view($view, [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'proof'
|
||||
])
|
||||
'type' => 'proof',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View sent prize mail
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailPrizeSent(): View
|
||||
{
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.re7-preview-mail';
|
||||
|
||||
return view($view, [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'prize-sent'
|
||||
])
|
||||
'type' => 'prize-sent',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a specific mail
|
||||
*
|
||||
* @param string $type
|
||||
* @param \App\Models\Prize|null $prize
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function mailPrint(string $type, Prize|null $prize = null): Response
|
||||
public function mailPrint(string $type, ?Prize $prize = null): Response
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
/** @var User */
|
||||
$user = auth('backend')->user();
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
|
||||
switch ($type) {
|
||||
case 'discount':
|
||||
/** @var \App\Lib\Discount */
|
||||
/** @var Discount */
|
||||
$discount = Arr::get(
|
||||
$settings->web_coupons,
|
||||
$this->getRandomWeightedElementIndex($settings->web_coupons)
|
||||
);
|
||||
|
||||
return response((new DiscountWonMail(
|
||||
return response(new DiscountWonMail(
|
||||
new Address(
|
||||
$user->email,
|
||||
$user->first_name
|
||||
|
|
@ -232,9 +243,9 @@ class Re7Controller extends Controller
|
|||
$discount,
|
||||
config('app.url'),
|
||||
$settings->company,
|
||||
))->render());
|
||||
)->render());
|
||||
case 'prize':
|
||||
return response((new PrizeWonMail(
|
||||
return response(new PrizeWonMail(
|
||||
new Address(
|
||||
$user->email,
|
||||
$user->first_name
|
||||
|
|
@ -243,27 +254,27 @@ class Re7Controller extends Controller
|
|||
$prize,
|
||||
config('app.url'),
|
||||
$settings->company,
|
||||
))->render());
|
||||
)->render());
|
||||
case 'prize-sent':
|
||||
return response((new PrizeIsSentMail(
|
||||
return response(new PrizeIsSentMail(
|
||||
new Address(
|
||||
$user->email,
|
||||
$user->first_name
|
||||
),
|
||||
$settings->name,
|
||||
$settings->company,
|
||||
))->render());
|
||||
)->render());
|
||||
case 'proof':
|
||||
return response((new WinningProofSubmitedMail(
|
||||
return response(new WinningProofSubmitedMail(
|
||||
new Address(
|
||||
$user->email,
|
||||
$user->first_name
|
||||
),
|
||||
$settings->name,
|
||||
$settings->company,
|
||||
))->render());
|
||||
)->render());
|
||||
default:
|
||||
return response('', 404);
|
||||
} //end switch
|
||||
} // end switch
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -7,9 +9,14 @@ use App\Http\Requests\Bo\Settings\UpdateSettingsRequest;
|
|||
use App\Lib\Discount;
|
||||
use App\Lib\Helpers\FileStorageHelper;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
use RuntimeException;
|
||||
use TypeError;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
|
|
@ -23,45 +30,39 @@ class SettingsController extends Controller
|
|||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\Settings $settings
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(Settings $settings): \Illuminate\Contracts\View\View
|
||||
public function edit(Settings $settings): View
|
||||
{
|
||||
return view('back::pages.settings.edit', [
|
||||
'settingsModel' => $settings
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.settings.edit';
|
||||
return view($view, [
|
||||
'settingsModel' => $settings,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Settings\UpdateSettingsRequest $request
|
||||
* @param \App\Models\Settings $settings
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateSettingsRequest $request, Settings $settings): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdateSettingsRequest $request, Settings $settings): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $settings) {
|
||||
$data = $request->validated();
|
||||
|
||||
// * Assign parsed Web coupon objects
|
||||
Arr::set($data, 'web_coupons', collect(Arr::get($data, 'web_coupons'))->filter()
|
||||
->map(fn (array $coupon) => $this->parseWebCoupon($coupon))
|
||||
->map(fn (array $coupon): ?\App\Lib\Discount => $this->parseWebCoupon($coupon))
|
||||
->filter()->all());
|
||||
|
||||
$settings->fill($data);
|
||||
if ($settings->saveOrFail()) {
|
||||
return redirect()
|
||||
->route('bo.settings.edit', $settings)
|
||||
return to_route('bo.settings.edit', $settings)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.settings'))]
|
||||
));
|
||||
}
|
||||
return redirect()
|
||||
->back()
|
||||
|
||||
return back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.settings'))]
|
||||
|
|
@ -69,18 +70,16 @@ class SettingsController extends Controller
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to parse webCoupon
|
||||
*
|
||||
* @param array<string,string> $coupon
|
||||
* @return \App\Lib\Discount|null
|
||||
* @param array<string,string> $coupon
|
||||
*/
|
||||
private function parseWebCoupon(array $coupon): Discount | null
|
||||
private function parseWebCoupon(array $coupon): ?Discount
|
||||
{
|
||||
/** @var \Illuminate\Http\UploadedFile|string */
|
||||
/** @var UploadedFile|string */
|
||||
$picture = Arr::get($coupon, 'picture');
|
||||
if (is_object($picture) and ($picture instanceof \Illuminate\Http\UploadedFile)) {
|
||||
if ($picture instanceof UploadedFile) {
|
||||
$picture = FileStorageHelper::storeFile(
|
||||
new Settings(),
|
||||
$picture,
|
||||
|
|
@ -96,7 +95,7 @@ class SettingsController extends Controller
|
|||
Arr::get($coupon, 'percentage'),
|
||||
Arr::get($coupon, 'web_coupon_identifiant'),
|
||||
);
|
||||
} catch (\RuntimeException | \TypeError) {
|
||||
} catch (RuntimeException | TypeError) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Bo\StaticPages\UpdateStaticPageRequest;
|
||||
use App\Models\StaticPage;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -21,13 +26,10 @@ class StaticPageController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
/** @var Builder $query */
|
||||
$query = StaticPage::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -50,41 +52,44 @@ class StaticPageController extends Controller
|
|||
/** Custom pagination */
|
||||
$staticPageModelList = $this->paginate($query);
|
||||
|
||||
return view('back::pages.static_pages.index', compact('staticPageModelList', 'search', 'searchFields'));
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.static_pages.index';
|
||||
|
||||
return view($view, [
|
||||
'staticPageModelList' => $staticPageModelList,
|
||||
'search' => $search,
|
||||
'searchFields' => $searchFields,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\StaticPage $static_page
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(StaticPage $static_page): \Illuminate\Contracts\View\View
|
||||
public function edit(StaticPage $static_page): View
|
||||
{
|
||||
return view('back::pages.static_pages.edit', ['staticPageModel' => $static_page]);
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.static_pages.edit';
|
||||
return view($view, ['staticPageModel' => $static_page]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\StaticPages\UpdateStaticPageRequest $request
|
||||
* @param \App\Models\StaticPage $static_page
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateStaticPageRequest $request, StaticPage $static_page): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdateStaticPageRequest $request, StaticPage $static_page): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $static_page) {
|
||||
$static_page->fill($request->validated());
|
||||
|
||||
if ($static_page->saveOrFail()) {
|
||||
return redirect()->route('bo.static_pages.edit', $static_page)
|
||||
return to_route('bo.static_pages.edit', $static_page)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(\trans_choice('models.classes.static_page', 1))
|
||||
'model' => Str::ucfirst(\trans_choice('models.classes.static_page', 1)),
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.static_pages.edit', $static_page)
|
||||
|
||||
return to_route('bo.static_pages.edit', $static_page)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(\trans_choice('models.classes.static_page', 1))
|
||||
'model' => Str::ucfirst(\trans_choice('models.classes.static_page', 1)),
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -7,6 +9,9 @@ use App\Http\Requests\Bo\Users\StoreUserRequest;
|
|||
use App\Http\Requests\Bo\Users\UpdateUserRequest;
|
||||
use App\Models\User;
|
||||
use App\Traits\Controllers\UpdateModelPublished;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -25,13 +30,10 @@ class UserController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
public function index(Request $request): View
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $userModels */
|
||||
/** @var Builder $userModels */
|
||||
$userModels = User::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -60,109 +62,101 @@ class UserController extends Controller
|
|||
/** Custom pagination */
|
||||
$userModels = $this->paginate($userModels);
|
||||
|
||||
return view('back::pages.users.index', compact('userModels', 'search', 'searchFields'));
|
||||
}
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.users.index';
|
||||
|
||||
return view($view, ['userModels' => $userModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(User $user): \Illuminate\Contracts\View\View
|
||||
public function create(User $user): View
|
||||
{
|
||||
return view('back::pages.users.create', ['userModel' => $user]);
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.users.create';
|
||||
|
||||
return view($view, ['userModel' => $user]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Users\StoreUserRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(StoreUserRequest $request): \Illuminate\Http\RedirectResponse
|
||||
public function store(StoreUserRequest $request): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$user = new User();
|
||||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
return redirect()->route('bo.users.edit', $user)
|
||||
return to_route('bo.users.edit', $user)
|
||||
->with('success', __('crud.messages.has_been_created', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
'model' => Str::ucfirst(__('models.classes.user')),
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
|
||||
return back()
|
||||
->with('error', __('crud.messages.cannot_be_created', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
'model' => Str::ucfirst(__('models.classes.user')),
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function edit(User $user): \Illuminate\Contracts\View\View
|
||||
public function edit(User $user): View
|
||||
{
|
||||
return view('back::pages.users.edit', ['userModel' => $user]);
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.users.edit';
|
||||
|
||||
return view($view, ['userModel' => $user]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Users\UpdateUserRequest $request
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function update(UpdateUserRequest $request, User $user): \Illuminate\Http\RedirectResponse
|
||||
public function update(UpdateUserRequest $request, User $user): RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $user) {
|
||||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
return redirect()->route('bo.users.edit', $user)
|
||||
return to_route('bo.users.edit', $user)
|
||||
->with('success', __('crud.messages.has_been_updated', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
'model' => Str::ucfirst(__('models.classes.user')),
|
||||
]));
|
||||
}
|
||||
return redirect()->route('bo.users.edit', $user)
|
||||
|
||||
return to_route('bo.users.edit', $user)
|
||||
->with('error', __('crud.messages.cannot_be_updated', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
'model' => Str::ucfirst(__('models.classes.user')),
|
||||
]));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(User $user): \Illuminate\Http\RedirectResponse
|
||||
public function destroy(User $user): RedirectResponse
|
||||
{
|
||||
if ($user->deleteOrFail()) {
|
||||
return redirect()->route('bo.users.index')
|
||||
return to_route('bo.users.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
'model' => Str::ucfirst(__('models.classes.user')),
|
||||
]));
|
||||
}
|
||||
return redirect()->back()
|
||||
|
||||
return back()
|
||||
->with('error', __('crud.messages.cannot_be_deleted', [
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
'model' => Str::ucfirst(__('models.classes.user')),
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate the specified resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function duplicate(User $user): \Illuminate\Contracts\View\View
|
||||
public function duplicate(User $user): View
|
||||
{
|
||||
return $this->create($user->replicate());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,18 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Enums\Pagination\ItemsPerPaginationEnum;
|
||||
use App\Enums\Theme\BootstrapThemeEnum;
|
||||
use App\Lib\Discount;
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
|
@ -20,7 +25,6 @@ class Controller extends BaseController
|
|||
use AuthorizesRequests;
|
||||
use ValidatesRequests;
|
||||
|
||||
|
||||
/**
|
||||
* Utility function for getting random values with weighting.
|
||||
* Pass in an associative array, such as array('A'=>5, 'B'=>45, 'C'=>50)
|
||||
|
|
@ -30,8 +34,9 @@ class Controller extends BaseController
|
|||
* weight was 2, and the other weight of 1, the value with the weight of 2 has about a 66%
|
||||
* chance of being selected. Also note that weights should be integers.
|
||||
*
|
||||
* @param array<\App\Lib\Discount> $weightedValues
|
||||
* @return integer The winning key
|
||||
* @param array<Discount> $weightedValues
|
||||
* @return int The winning key
|
||||
*
|
||||
* @url https://stackoverflow.com/a/11872928/4355295
|
||||
*/
|
||||
protected function getRandomWeightedElementIndex(array $weightedValues): int
|
||||
|
|
@ -45,13 +50,12 @@ class Controller extends BaseController
|
|||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
return $rand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the redirection path for FO Auth controllers
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function authLoggedRedirectPath(): string
|
||||
{
|
||||
|
|
@ -62,63 +66,57 @@ class Controller extends BaseController
|
|||
* Build Search query on specified fields
|
||||
* splitting search into words or using whole sentence
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query The eloquent query builder.
|
||||
* @param string $search The query string.
|
||||
* @param callable $searchQuery The query string.
|
||||
* @param string ...$fields Either a simple array or a string
|
||||
* in case of a string the two fields
|
||||
* would be concatenate to make the search.
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
* @param Builder $query The eloquent query builder.
|
||||
* @param string $search The query string.
|
||||
* @param callable $searchQuery The query string.
|
||||
* @param string ...$fields Either a simple array or a string
|
||||
* in case of a string the two fields
|
||||
* would be concatenate to make the search.
|
||||
*/
|
||||
protected function searchQuery(
|
||||
Builder $query,
|
||||
string $search,
|
||||
callable $searchQuery = null,
|
||||
?callable $searchQuery = null,
|
||||
string ...$fields
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
): Builder {
|
||||
if (count($fields)) {
|
||||
// Search using words.
|
||||
$words = explode(' ', $search);
|
||||
$query->where(function ($query) use ($searchQuery, $words, $search, $fields) {
|
||||
$query->where(function (\Illuminate\Contracts\Database\Query\Builder $query) use ($searchQuery, $words, $search, $fields): void {
|
||||
foreach ($words as $word) {
|
||||
if (!strlen($word)) {
|
||||
if (! strlen($word)) {
|
||||
continue;
|
||||
}
|
||||
$this->searchOnFields($query, $word, $fields);
|
||||
} //end foreach
|
||||
} // end foreach
|
||||
// Search whole using whole sentence.
|
||||
$this->searchOnFields($query, $search, $fields);
|
||||
if ($searchQuery) {
|
||||
$searchQuery($query);
|
||||
}
|
||||
});
|
||||
} //end if
|
||||
} // end if
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build query search on all fields
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $search
|
||||
* @param array $fields
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
private function searchOnFields(
|
||||
Builder $query,
|
||||
string $search,
|
||||
array $fields
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
): Builder {
|
||||
$table = $query->getModel()->getTable();
|
||||
foreach ($fields as $field) {
|
||||
$field = str_replace('?', '\?', $field);
|
||||
if (is_array($field)) {
|
||||
$query->orWhereRaw(
|
||||
sprintf("UPPER(CONCAT(%s)) LIKE UPPER(?)", collect($field)->map(function ($q) use ($table) {
|
||||
return "`$table`.`$q`";
|
||||
})->implode(', \' \', ')),
|
||||
sprintf('UPPER(CONCAT(%s)) LIKE UPPER(?)', collect($field)->map(fn ($q): string => "`$table`.`$q`")->implode(', \' \', ')),
|
||||
['%' . htmlspecialchars($search) . '%']
|
||||
);
|
||||
|
||||
return $query;
|
||||
}
|
||||
// Get models woth enum's label.
|
||||
|
|
@ -129,62 +127,56 @@ class Controller extends BaseController
|
|||
['%' . htmlspecialchars($array->value) . '%']
|
||||
);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
// Get models with relation's name/label.
|
||||
if (Str::endsWith($field, '_id')) {
|
||||
$query->orWhereHas(Str::remove('_id', $field), function ($queryRelation) use ($field, $search) {
|
||||
if (Schema::hasColumn(Str::remove('_id', $field) . 's', 'name')) {
|
||||
$queryRelation->where('name', 'like', '%' . $search . '%');
|
||||
} elseif (Schema::hasColumn(Str::remove('_id', $field) . 's', 'label')) {
|
||||
$queryRelation->where('label', 'like', '%' . $search . '%');
|
||||
$query->orWhereHas(
|
||||
Str::remove('_id', $field),
|
||||
function (\Illuminate\Contracts\Database\Query\Builder $queryRelation) use ($field, $search): void {
|
||||
if (Schema::hasColumn(Str::remove('_id', $field) . 's', 'name')) {
|
||||
$queryRelation->where('name', 'like', '%' . $search . '%');
|
||||
} elseif (Schema::hasColumn(Str::remove('_id', $field) . 's', 'label')) {
|
||||
$queryRelation->where('label', 'like', '%' . $search . '%');
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
return $query;
|
||||
}
|
||||
$query->orWhereRaw(
|
||||
"UPPER(`$table`.`$field`) LIKE UPPER(?)",
|
||||
['%' . htmlspecialchars($this->getSearchValue($query, $search, $field)) . '%']
|
||||
);
|
||||
} //end foreach
|
||||
} // end foreach
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the search value (on string or Enum).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param string $search
|
||||
* @param string $field
|
||||
* @return string|array
|
||||
*/
|
||||
protected function getSearchValue(Builder $query, string $search, string $field): string|array
|
||||
protected function getSearchValue(Builder $query, string $search, string $field): string | array
|
||||
{
|
||||
$cast = $query->getModel()->getCasts()[$field] ?? null;
|
||||
if (
|
||||
count($query->getModel()->getCasts()) and // Check if the model has casts.
|
||||
$cast and // Check if there is cast about specific field.
|
||||
enum_exists($cast) // Check if the cast is an enum.
|
||||
count($query->getModel()->getCasts()) && $cast && enum_exists($cast) // Check if the cast is an enum.
|
||||
) {
|
||||
// @phpstan-ignore-next-line
|
||||
$cases = collect($cast::toArray());
|
||||
$enum = $cases->filter(function ($item) use ($search) {
|
||||
return preg_match('/' . Str::lower($search) . '/', Str::lower($item->label));
|
||||
});
|
||||
$enum = $cases->filter(fn ($item): int | false => preg_match('/' . Str::lower($search) . '/', Str::lower($item->label)));
|
||||
|
||||
return $enum->toArray();
|
||||
} else {
|
||||
return $search;
|
||||
}
|
||||
|
||||
return $search;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort columns with a query.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param array $ignore
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function sortQuery(Builder $query, array $ignore = []): \Illuminate\Database\Eloquent\Builder
|
||||
protected function sortQuery(Builder $query, array $ignore = []): Builder
|
||||
{
|
||||
$rName = request()->route()->getName();
|
||||
$table = $query->getModel()->getTable();
|
||||
|
|
@ -201,8 +193,8 @@ class Controller extends BaseController
|
|||
Session::remove("$rName.sort_col");
|
||||
Session::remove("$rName.sort_way");
|
||||
}
|
||||
if (request()->sort_col and request()->sort_way and Schema::hasColumn($table, request()->sort_col)) {
|
||||
if (!in_array(request()->sort_col, $ignore)) {
|
||||
if (request()->sort_col && request()->sort_way && Schema::hasColumn($table, request()->sort_col)) {
|
||||
if (! in_array(request()->sort_col, $ignore)) {
|
||||
$query = $query->orderBy(\sprintf("$table.%s", request()->sort_col), request()->sort_way);
|
||||
}
|
||||
} elseif (Schema::hasColumn($table, 'order')) {
|
||||
|
|
@ -210,59 +202,55 @@ class Controller extends BaseController
|
|||
Session::put("$rName.sort_col", 'order');
|
||||
Session::put("$rName.sort_way", 'asc');
|
||||
} elseif (Schema::hasColumn($table, 'updated_at')) {
|
||||
$query = $query->orderBy('updated_at', 'DESC');
|
||||
$query = $query->latest('updated_at');
|
||||
Session::put("$rName.sort_col", 'updated_at');
|
||||
Session::put("$rName.sort_way", 'desc');
|
||||
} elseif (Schema::hasColumn($table, 'created_at')) {
|
||||
$query = $query->orderBy('created_at', 'DESC');
|
||||
$query = $query->latest();
|
||||
Session::put("$rName.sort_col", 'created_at');
|
||||
Session::put("$rName.sort_way", 'desc');
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Customize pagination with cache or config (default).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query
|
||||
* @param \App\Enums\Pagination\ItemsPerPaginationEnum|null $pagination
|
||||
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
protected function paginate(
|
||||
Builder $query,
|
||||
ItemsPerPaginationEnum $pagination = null
|
||||
): \Illuminate\Contracts\Pagination\LengthAwarePaginator {
|
||||
?ItemsPerPaginationEnum $pagination = null
|
||||
): LengthAwarePaginator {
|
||||
$currentRoutePath = Str::slug(request()->route()->getName());
|
||||
$cacheKey = "pagination.{$currentRoutePath}";
|
||||
$pagination = $pagination ?? ItemsPerPaginationEnum::twelve;
|
||||
$pagination ??= ItemsPerPaginationEnum::twelve;
|
||||
$pagination = ToolboxHelper::getValidatedEnum(
|
||||
Cache::get($cacheKey, $pagination->value()),
|
||||
'pagination',
|
||||
'\App\Enums\Pagination\ItemsPerPaginationEnum',
|
||||
ItemsPerPaginationEnum::class,
|
||||
);
|
||||
if (Cache::get($cacheKey) !== $pagination) {
|
||||
Cache::put($cacheKey, $pagination);
|
||||
}
|
||||
$query = $query->paginate($pagination);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the bootstrap theme or light (default).
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function setTheme(Request $request): \Illuminate\Http\RedirectResponse
|
||||
protected function setTheme(Request $request): RedirectResponse
|
||||
{
|
||||
$theme = ToolboxHelper::getValidatedEnum(
|
||||
$request->theme ?: Cache::get('theme', BootstrapThemeEnum::light->value()),
|
||||
'theme',
|
||||
'\App\Http\Controllers\BootstrapThemeEnum',
|
||||
);
|
||||
if (Cache::get("theme") !== $theme) {
|
||||
Cache::put("theme", $theme);
|
||||
if (Cache::get('theme') !== $theme) {
|
||||
Cache::put('theme', $theme);
|
||||
}
|
||||
return redirect()->back()->with('success', __('crud.messages.theme_updated'));
|
||||
|
||||
return back()->with('success', __('crud.messages.theme_updated'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,21 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ConfirmsPasswords;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ConfirmPasswordController extends Controller
|
||||
{
|
||||
use ConfirmsPasswords;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -23,21 +24,21 @@ class ConfirmPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Display the password confirmation view.
|
||||
*
|
||||
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function showConfirmForm(): \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
public function showConfirmForm(): View | RedirectResponse
|
||||
{
|
||||
if (Auth::guard('frontend')->check()) {
|
||||
return \response()->redirectToRoute('home');
|
||||
}
|
||||
return view('theme::auth.passwords.confirm');
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.passwords.confirm';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Contracts\Auth\PasswordBroker;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
|
|
@ -16,16 +19,13 @@ class ForgotPasswordController extends Controller
|
|||
/**
|
||||
* Message to user
|
||||
*
|
||||
* @var string
|
||||
*
|
||||
* @phpcs:disable Generic.Files.LineLength.TooLong
|
||||
*/
|
||||
private $message = 'front.messages.password_reset_email_sent';
|
||||
//phpcs:enable
|
||||
|
||||
private string $message = 'front.messages.password_reset_email_sent';
|
||||
// phpcs:enable
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -39,13 +39,14 @@ class ForgotPasswordController extends Controller
|
|||
*/
|
||||
public function showLinkRequestForm(): View
|
||||
{
|
||||
return view('theme::auth.passwords.email');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.passwords.email';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker(): PasswordBroker
|
||||
{
|
||||
|
|
@ -56,7 +57,7 @@ class ForgotPasswordController extends Controller
|
|||
* Get the response for a successful password reset link.
|
||||
* ! Dans les deux cas on ne divulgue pas si un user existe.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
protected function sendResetLinkResponse()
|
||||
{
|
||||
|
|
@ -67,9 +68,7 @@ class ForgotPasswordController extends Controller
|
|||
* Get the response for a failed password reset link.
|
||||
* ! Dans les deux cas on ne divulgue pas si un user existe.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
protected function sendResetLinkFailedResponse(Request $request, string $response)
|
||||
{
|
||||
|
|
@ -77,6 +76,7 @@ class ForgotPasswordController extends Controller
|
|||
if ($response === 'passwords.user') {
|
||||
return back()->with('info', trans($this->message));
|
||||
}
|
||||
|
||||
// * Renvoyer les autres message d'erreur style throttle.
|
||||
return back()
|
||||
->withInput($request->only('email'))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -28,8 +30,6 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -38,8 +38,6 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
|
|
@ -53,15 +51,15 @@ class LoginController extends Controller
|
|||
*/
|
||||
public function showLoginForm(): View
|
||||
{
|
||||
return view('theme::auth.login');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.login';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the authenticated user can access the game
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \App\Models\Customer $user
|
||||
* @return void
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing, Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
*/
|
||||
protected function authenticated(Request $request, Customer $user): void
|
||||
|
|
@ -69,11 +67,11 @@ class LoginController extends Controller
|
|||
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
|
||||
$crmCustomer = $user->api_data;
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
$countries = $settings->authorized_countries;
|
||||
|
||||
if (count($countries) && !in_array($crmCustomer->country->value, $countries)) {
|
||||
if (count($countries) && ! in_array($crmCustomer->country->value, $countries)) {
|
||||
$this->logout($request);
|
||||
Session::flash('info', trans('front.messages.game_not_available_in_country'));
|
||||
} else {
|
||||
|
|
@ -86,8 +84,6 @@ class LoginController extends Controller
|
|||
/**
|
||||
* The user has logged out of the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return void
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
protected function loggedOut(Request $request): void
|
||||
|
|
@ -97,8 +93,6 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Customers\CreateAccountRequest;
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Contracts\Validation\Validator as ValidationValidator;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Support\Arr;
|
||||
|
|
@ -14,10 +17,12 @@ use Illuminate\Support\Facades\Log;
|
|||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException as IlluminateValidationException;
|
||||
use Illuminate\View\View;
|
||||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
use RuntimeException;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
|
|
@ -25,8 +30,6 @@ class RegisterController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -36,7 +39,7 @@ class RegisterController extends Controller
|
|||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
* @return StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
|
|
@ -46,19 +49,21 @@ class RegisterController extends Controller
|
|||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
* @return View
|
||||
*/
|
||||
public function showRegistrationForm()
|
||||
{
|
||||
return view('theme::auth.register');
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.register';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a validator for an incoming registration request.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Contracts\Validation\Validator
|
||||
* @throws IlluminateValidationException If data is incorrect.
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
protected function validator(array $data): ValidationValidator
|
||||
|
|
@ -66,6 +71,7 @@ class RegisterController extends Controller
|
|||
// phpcs:enable
|
||||
$request = CreateAccountRequest::capture();
|
||||
$request->prepareForValidation();
|
||||
|
||||
return Validator::make(
|
||||
$request->validationData(),
|
||||
$request->rules(),
|
||||
|
|
@ -77,10 +83,8 @@ class RegisterController extends Controller
|
|||
/**
|
||||
* Create a new user instance after a valid registration.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \App\Models\Customer
|
||||
* @throws IlluminateValidationException If there are validation errors.
|
||||
* @throws \RuntimeException On unhandled api Error.
|
||||
* @throws RuntimeException On unhandled api Error.
|
||||
*/
|
||||
protected function create(array $data): Customer
|
||||
{
|
||||
|
|
@ -107,7 +111,7 @@ class RegisterController extends Controller
|
|||
// * Enregistrement du Hashcode
|
||||
/** @var \App\Models\Customer $customer */
|
||||
$customer = Customer::withTrashed()->firstOrNew([
|
||||
'email' => $data['email']
|
||||
'email' => $data['email'],
|
||||
]);
|
||||
$customer->fill(Arr::only($data, $customer->getFillable()));
|
||||
$customer->hashcode = $crmCustomer->hashcode;
|
||||
|
|
@ -127,30 +131,28 @@ class RegisterController extends Controller
|
|||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::customerExists)) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => trans('front.messages.email_already_in_use')
|
||||
'error' => trans('front.messages.email_already_in_use'),
|
||||
]);
|
||||
}
|
||||
if ($e->getApiError()->equals(ApiError::validationFailed)) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::create reached end of possibilities.');
|
||||
throw new \RuntimeException(__CLASS__ . '::create reached end of possibilities.');
|
||||
Log::error(self::class . '::create reached end of possibilities.');
|
||||
throw new RuntimeException(self::class . '::create reached end of possibilities.', $e->getCode(), $e);
|
||||
} catch (CrmValidationException $e) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
} //end try
|
||||
} // end try
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath()
|
||||
public function redirectPath(): string
|
||||
{
|
||||
return $this->authLoggedRedirectPath();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,26 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
use Illuminate\Contracts\Auth\PasswordBroker;
|
||||
use Illuminate\Contracts\Auth\StatefulGuard;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use LDC\LDCCRM\CrmApiV4;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as ExceptionsValidationException;
|
||||
use TypeError;
|
||||
|
||||
class ResetPasswordController extends Controller
|
||||
{
|
||||
|
|
@ -22,8 +28,6 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -34,8 +38,6 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
|
|
@ -46,15 +48,15 @@ class ResetPasswordController extends Controller
|
|||
* Display the password reset view for the given token.
|
||||
*
|
||||
* If no token is present, display the link request form.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showResetForm(Request $request): \Illuminate\Contracts\View\View
|
||||
public function showResetForm(Request $request): View
|
||||
{
|
||||
$token = $request->route()->parameter('token');
|
||||
|
||||
return view('theme::auth.passwords.reset')->with(
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.passwords.reset';
|
||||
|
||||
return view($view)->with(
|
||||
['token' => $token, 'email' => $request->email]
|
||||
);
|
||||
}
|
||||
|
|
@ -62,32 +64,29 @@ class ResetPasswordController extends Controller
|
|||
/**
|
||||
* Reset the given user's password.
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @param string $password
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If something goes wrong.
|
||||
*/
|
||||
protected function resetPassword(\App\Models\Customer $customer, string $password): void
|
||||
protected function resetPassword(Customer $customer, string $password): void
|
||||
{
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('crmAPI');
|
||||
/** @var CrmApiV4 */
|
||||
$crm = resolve('crmAPI');
|
||||
|
||||
try {
|
||||
if (!($crmCustomer = $crm->getCustomer($customer->hashcode))) {
|
||||
if (! ($crmCustomer = $crm->getCustomer($customer->hashcode))) {
|
||||
throw ValidationException::withMessages([
|
||||
'error' => trans('Changement impossible, compte inexistant.')
|
||||
'error' => trans('Changement impossible, compte inexistant.'),
|
||||
]);
|
||||
}
|
||||
$crmCustomer->password = $password;
|
||||
$crmCustomer->save();
|
||||
} catch (\TypeError | CrmException | ApiErrorException $e) {
|
||||
} catch (TypeError | CrmException | ApiErrorException $e) {
|
||||
report($e);
|
||||
throw ValidationException::withMessages([
|
||||
'error' => trans('front.messages.unexpected_error_try_later')
|
||||
'error' => trans('front.messages.unexpected_error_try_later'),
|
||||
]);
|
||||
} catch (ExceptionsValidationException $e) {
|
||||
throw ValidationException::withMessages([
|
||||
'password' => $e->getMessage()
|
||||
'password' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -102,8 +101,6 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
|
|
@ -112,8 +109,6 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker(): PasswordBroker
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -8,6 +10,7 @@ use Illuminate\Auth\Access\AuthorizationException;
|
|||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
|
@ -23,8 +26,6 @@ class VerificationController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -35,15 +36,15 @@ class VerificationController extends Controller
|
|||
|
||||
/**
|
||||
* Show the email verification notice.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Request $request): RedirectResponse|View
|
||||
public function show(Request $request): RedirectResponse | View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.verify';
|
||||
|
||||
return $request->user('frontend')->hasVerifiedEmail()
|
||||
? redirect($this->redirectPath())
|
||||
: view('theme::auth.verify');
|
||||
: view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -51,22 +52,16 @@ class VerificationController extends Controller
|
|||
*
|
||||
* ! Overloaded trait
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException If request is invalid.
|
||||
* @throws AuthorizationException If request is invalid.
|
||||
*/
|
||||
public function verify(Request $request): JsonResponse|RedirectResponse
|
||||
public function verify(Request $request): JsonResponse | RedirectResponse
|
||||
{
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$user = Customer::findOrFail($request->route('id'));
|
||||
|
||||
if (!hash_equals((string) $request->route('id'), (string) $user->getKey())) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
throw_unless(hash_equals((string) $request->route('id'), (string) $user->getKey()), AuthorizationException::class);
|
||||
|
||||
if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
throw_unless(hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification())), AuthorizationException::class);
|
||||
|
||||
if ($user->hasVerifiedEmail()) {
|
||||
return $request->wantsJson()
|
||||
|
|
@ -74,7 +69,7 @@ class VerificationController extends Controller
|
|||
: redirect($this->redirectPath());
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($user) {
|
||||
DB::transaction(function () use ($user): void {
|
||||
if ($user->markEmailAsVerified()) {
|
||||
$this->setCrmCustomerAsVerified($user);
|
||||
event(new Verified($user));
|
||||
|
|
@ -93,8 +88,8 @@ class VerificationController extends Controller
|
|||
/**
|
||||
* The user has been verified.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed
|
||||
*
|
||||
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
|
||||
*/
|
||||
protected function verified(Request $request)
|
||||
|
|
@ -107,8 +102,6 @@ class VerificationController extends Controller
|
|||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
|
|
@ -118,9 +111,7 @@ class VerificationController extends Controller
|
|||
/**
|
||||
* Set Crm Customer active
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException In case of failure.
|
||||
* @throws HttpResponseException In case of failure.
|
||||
*/
|
||||
private function setCrmCustomerAsVerified(Customer $customer): void
|
||||
{
|
||||
|
|
@ -137,12 +128,11 @@ class VerificationController extends Controller
|
|||
if ($e->getApiError()->equals(ApiError::customerAlreadyActive)) {
|
||||
// * Ignore this and continue, as it may be activated via another CRM service.
|
||||
return;
|
||||
} else {
|
||||
report($e);
|
||||
redirect($this->redirectPath())->with('error', trans(
|
||||
'front.messages.unexpected_error_try_later'
|
||||
))->throwResponse();
|
||||
}
|
||||
report($e);
|
||||
redirect($this->redirectPath())->with('error', trans(
|
||||
'front.messages.unexpected_error_try_later'
|
||||
))->throwResponse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Customers\VerifyInformationsRequest;
|
||||
use App\Http\Requests\Fo\Customers\SingleOptinRequest;
|
||||
use App\Http\Requests\Fo\Customers\VerifyInformationsRequest;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Participation;
|
||||
use App\Repositories\Fo\CrmRepository;
|
||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
|
|
@ -19,16 +24,15 @@ use LDC\LDCCRM\Exceptions\ApiErrorException;
|
|||
use LDC\LDCCRM\Exceptions\CrmException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
|
||||
use LDC\LDCCRM\Models\SingleOptin;
|
||||
use LDC\MESBR\MesBr;
|
||||
use Illuminate\Http\Response;
|
||||
|
||||
class CustomerController extends Controller
|
||||
{
|
||||
/** @var \App\Repositories\Fo\CrmRepository $crmRepository */
|
||||
private $crmRepository;
|
||||
private readonly CrmRepository $crmRepository;
|
||||
|
||||
/**
|
||||
* ParticipateController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -37,26 +41,24 @@ class CustomerController extends Controller
|
|||
|
||||
/**
|
||||
* Verify profil info form
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function profilVerify(): View
|
||||
{
|
||||
// ! Pas de Gate/Policies Ici volontairement, vu avec Vincent
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
return view('theme::auth.profil-verify', compact('crmCustomer'));
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.profil-verify';
|
||||
|
||||
return view($view, ['crmCustomer' => $crmCustomer]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile verify
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\Customers\VerifyInformationsRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws IlluminateValidationException In case of any error validation or within the crm.
|
||||
*/
|
||||
public function profilVerifySubmit(VerifyInformationsRequest $request): RedirectResponse
|
||||
|
|
@ -65,7 +67,7 @@ class CustomerController extends Controller
|
|||
try {
|
||||
return DB::transaction(function () use ($request) {
|
||||
// * --- FILL AND SAVE CUSTOMER
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
// * Màj, on ne mets pas à jour le mdp ou l'adresse email, juste les champs pour mesBr
|
||||
|
|
@ -89,86 +91,93 @@ class CustomerController extends Controller
|
|||
} catch (CrmValidationException $e) {
|
||||
// * Local Validation failure
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::validationFailed)) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::update reached end of possibilities.');
|
||||
Log::error(self::class . '::update reached end of possibilities.');
|
||||
} catch (CrmException $e) {
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::error occured on calling crm.');
|
||||
Log::error(self::class . '::error occured on calling crm.');
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => trans('Une erreur est survenue, veuillez réssayer plus tard')
|
||||
'error' => trans('Une erreur est survenue, veuillez réssayer plus tard'),
|
||||
]);
|
||||
} //end try
|
||||
} // end try
|
||||
|
||||
return back()->withInput()->withErrors(trans('front.messages.unexpected_error_try_later'));
|
||||
}
|
||||
|
||||
/**
|
||||
* View all customer winnig participations
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function viewWinningParticipations(): View
|
||||
{
|
||||
$this->authorize('viewWonList', \App\Models\Participation::class);
|
||||
$this->authorize('viewWonList', Participation::class);
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
// * Recupération des informations CRM
|
||||
/** @var \LDC\LDCCRM\Models\Customer*/
|
||||
/** @var \LDC\LDCCRM\Models\Customer */
|
||||
$crmUser = $this->crmRepository->fetchCrmCustomer($customer);
|
||||
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('mesBrAPI');
|
||||
/** @var MesBr $mesBr */
|
||||
$mesBr = resolve('mesBrAPI');
|
||||
|
||||
/** @var array{coupons?: list<array{quantity: int|string, printed: int|string}>} $brBasket */
|
||||
$brBasket = $mesBr->getBasket($crmUser);
|
||||
if (!empty($brBasket['coupons'])) {
|
||||
$canPrint = (collect($brBasket['coupons'])->sum('quantity') - collect($brBasket['coupons'])->sum('printed'));
|
||||
|
||||
if (! empty($brBasket['coupons'])) {
|
||||
$coupons = collect($brBasket['coupons']);
|
||||
$canPrint = $coupons->sum('quantity') - $coupons->sum('printed');
|
||||
}
|
||||
|
||||
$winningList = $customer->participations()
|
||||
->with(['instantWin'])->where(function (Builder $q) {
|
||||
->with(['instantWin'])->where(function (Builder $q): void {
|
||||
$q->whereHas('instantWin');
|
||||
})->get();
|
||||
|
||||
return view('theme::pages.participation.winning-participations', [
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.winning-participations';
|
||||
|
||||
return view($view, [
|
||||
'winningList' => $winningList,
|
||||
'canPrint' => $canPrint ?? null
|
||||
'canPrint' => $canPrint ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the CRM to add a single optin
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\Customers\SingleOptinRequest $request
|
||||
* @return string|array|null|\Illuminate\Contracts\Translation\Translator
|
||||
* @throws \LDC\LDCCRM\Exceptions\ValidationException ValidationException.
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException BindingResolutionException.
|
||||
* @throws BindingResolutionException BindingResolutionException.
|
||||
*/
|
||||
public function addOptIn(SingleOptinRequest $request)
|
||||
public function addOptIn(SingleOptinRequest $request): Response | string
|
||||
{
|
||||
try {
|
||||
SingleOptin::setStatus($request->email, true);
|
||||
return \response(trans("front.messages.newsletter_subscription_success"), 200);
|
||||
|
||||
return \response(trans('front.messages.newsletter_subscription_success'), 200);
|
||||
} catch (ApiErrorException $e) {
|
||||
// Il y a deja un customerInfo avec optin a true pour ce customer.
|
||||
if ($e->getApiError()->equals(ApiError::singleOptinCustomerExists)) {
|
||||
return trans('front.messages.newsletter_email_already_subscribed');
|
||||
}
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
resolve('sentry')->captureException($e);
|
||||
}
|
||||
|
||||
return \response(trans('front.messages.unexpected_error_try_later'), 404);
|
||||
} catch (CrmException $e) {
|
||||
if (app()->bound('sentry')) {
|
||||
app('sentry')->captureException($e);
|
||||
resolve('sentry')->captureException($e);
|
||||
}
|
||||
|
||||
return \response(trans('front.messages.unexpected_error_try_later'), 404);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,34 +1,37 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Customer;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Arr;
|
||||
use LDC\MESBR\MesBr;
|
||||
use RuntimeException;
|
||||
|
||||
class DiscountController extends Controller
|
||||
{
|
||||
/**
|
||||
* Fetch PDF BR.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function fetchBrPdf(): \Illuminate\Http\RedirectResponse
|
||||
public function fetchBrPdf(): RedirectResponse
|
||||
{
|
||||
/** @var \App\Models\Customer $customer */
|
||||
/** @var Customer $customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$pdf = $this->fetchBrPdfFromMesBr($customer);
|
||||
|
||||
if ($pdf === null) {
|
||||
\back()->withErrors([
|
||||
'coupon' => trans('front.messages.pdf_download_error')
|
||||
'coupon' => trans('front.messages.pdf_download_error'),
|
||||
])->throwResponse();
|
||||
}
|
||||
|
||||
return redirect()->to(
|
||||
sprintf(
|
||||
"%s/basket/%s/print",
|
||||
'%s/basket/%s/print',
|
||||
config('mesbr.endpoint'),
|
||||
$pdf
|
||||
)
|
||||
|
|
@ -38,53 +41,54 @@ class DiscountController extends Controller
|
|||
/**
|
||||
* Fetch coupons PDF.
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @return string|null
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
private function fetchBrPdfFromMesBr(Customer $customer): ?string
|
||||
{
|
||||
// phpcs:enable
|
||||
// * Phase - 1 Recupération des informations CRM
|
||||
/** @var \App\Models\Customer $customer */
|
||||
/** @var Customer $customer */
|
||||
$customer = auth('frontend')->user();
|
||||
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
try {
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('mesBrAPI');
|
||||
/** @var MesBr */
|
||||
$mesBr = resolve('mesBrAPI');
|
||||
$result = $mesBr->getBasket($crmCustomer);
|
||||
$result = \is_object($result) ? (array) $result : $result;
|
||||
|
||||
if (Arr::get($result, 'status') !== "OK") {
|
||||
report(new \RuntimeException(
|
||||
if (Arr::get($result, 'status') !== 'OK') {
|
||||
report(new RuntimeException(
|
||||
\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
Arr::get($result, 'code') ?? 'Undefined',
|
||||
Arr::get($result, 'code') ?? 'Undefined',
|
||||
Arr::get($result, 'message') ?? 'Undefined',
|
||||
)
|
||||
));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// * La réponse est conforme ?
|
||||
$needed_fields = ['uuid'];
|
||||
if (!Arr::has($result, $needed_fields)) {
|
||||
report(new \RuntimeException(sprintf(
|
||||
if (! Arr::has($result, $needed_fields)) {
|
||||
report(new RuntimeException(sprintf(
|
||||
'MESBR : Il manques des champs dans la réponse, attendu => %s, donné => %s',
|
||||
json_encode($needed_fields),
|
||||
json_encode($result),
|
||||
)));
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// * Tout est OK
|
||||
return Arr::get($result, 'uuid') ?: null;
|
||||
} catch (\RuntimeException $e) {
|
||||
} catch (RuntimeException $e) {
|
||||
report($e);
|
||||
|
||||
// * Retenter ?
|
||||
return null;
|
||||
} //end try
|
||||
} // end try
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -7,89 +9,100 @@ use App\Models\FaqQuestion;
|
|||
use App\Models\FaqTheme;
|
||||
use App\Models\Range;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display home page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function home(): \Illuminate\Contracts\View\View
|
||||
public function home(): View
|
||||
{
|
||||
if (!Gate::check('fo.gameEnabled')) {
|
||||
if (! Gate::check('fo.gameEnabled')) {
|
||||
\session()->flash('warning', trans('front.messages.game_missing_required_elements'));
|
||||
}
|
||||
return view('theme::pages.home');
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.home';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display products with game stickers
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @phpcs:ignore Squiz.Commenting.FunctionComment.EmptyThrows
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException
|
||||
*
|
||||
* @throws HttpResponseException
|
||||
*/
|
||||
public function showProducts(): \Illuminate\Contracts\View\View
|
||||
public function showProducts(): View
|
||||
{
|
||||
// ? Show product list authorized ?
|
||||
if (!Gate::allows('fo.showProducts')) {
|
||||
if (! Gate::allows('fo.showProducts')) {
|
||||
\response()->redirectToRoute('fo.homepage')->throwResponse();
|
||||
}
|
||||
|
||||
$rangeModelList = Range::query()->with('products')->orderBy('id')->get();
|
||||
return view('theme::pages.products', compact('rangeModelList'));
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.products';
|
||||
|
||||
return view($view, ['rangeModelList' => $rangeModelList]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Faq page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showFaq(): \Illuminate\Contracts\View\View
|
||||
public function showFaq(): View
|
||||
{
|
||||
// ? Show QA authorized ?
|
||||
if (!Gate::allows('fo.showFaq')) {
|
||||
if (! Gate::allows('fo.showFaq')) {
|
||||
\response()->redirectToRoute('fo.homepage')->throwResponse();
|
||||
}
|
||||
|
||||
$questionModelList = FaqQuestion::getCached();
|
||||
$themeModelList = FaqTheme::getCached();
|
||||
|
||||
return view('theme::pages.faq', compact(
|
||||
'questionModelList',
|
||||
'themeModelList'
|
||||
));
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.faq';
|
||||
|
||||
return view($view, ['questionModelList' => $questionModelList, 'themeModelList' => $themeModelList]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the teaser page if it is activated
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function teaser(): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
public function teaser(): View | RedirectResponse
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->should_display_teaser_page) {
|
||||
return redirect()->route('fo.homepage');
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
if (! $settings->should_display_teaser_page) {
|
||||
return to_route('fo.homepage');
|
||||
}
|
||||
return view('theme::pages.teaser');
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.teaser';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the end game page if it is activated
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function endGame(): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
public function endGame(): View | RedirectResponse
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->should_display_end_page) {
|
||||
return redirect()->route('fo.homepage');
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
if (! $settings->should_display_end_page) {
|
||||
return to_route('fo.homepage');
|
||||
}
|
||||
return view('theme::pages.end-game');
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.end-game';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -7,13 +9,18 @@ use App\Http\Requests\Fo\Customers\CreateAccountRequest;
|
|||
use App\Http\Requests\Fo\ParticipateRequest;
|
||||
use App\Lib\Discount as LibDiscount;
|
||||
use App\Mail\Won\PrizeWonAdminMail;
|
||||
use App\Models\Code;
|
||||
use App\Models\Customer;
|
||||
use App\Models\InstantWin;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Product;
|
||||
use App\Models\Settings;
|
||||
use App\Notifications\Customer\HasWonDiscount;
|
||||
use App\Notifications\Customer\HasWonInstantWin;
|
||||
use App\Repositories\Fo\CrmRepository;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
|
@ -22,15 +29,15 @@ use Illuminate\Support\Facades\Mail;
|
|||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use LDC\MESBR\MesBr;
|
||||
use RuntimeException;
|
||||
|
||||
class ParticipateController extends Controller
|
||||
{
|
||||
/** @var \App\Repositories\Fo\CrmRepository $crmRepository */
|
||||
private $crmRepository;
|
||||
private readonly CrmRepository $crmRepository;
|
||||
|
||||
/**
|
||||
* ParticipateController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -38,53 +45,55 @@ class ParticipateController extends Controller
|
|||
$this->middleware(function (Request $request, callable $next) {
|
||||
$this->authorize('fo.gameEnabled');
|
||||
$this->assertUserHasEnoughInfoToUseMesBr();
|
||||
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display participation form
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participate(): \Illuminate\Contracts\View\View
|
||||
public function participate(): View
|
||||
{
|
||||
if (!Gate::check('participate', Participation::class)) {
|
||||
return view('theme::pages.participation.participation-exhausted');
|
||||
if (! Gate::check('participate', Participation::class)) {
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.participation-exhausted';
|
||||
return view($view);
|
||||
}
|
||||
return view('theme::pages.participation.participate');
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.participate';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Participate Method
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\ParticipateRequest $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participateSubmit(ParticipateRequest $request): \Illuminate\Contracts\View\View
|
||||
public function participateSubmit(ParticipateRequest $request): View
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
// ! On verrouille le ou les instants gagnant
|
||||
/** @var \App\Models\InstantWin|null */
|
||||
/** @var InstantWin|null */
|
||||
$instantWin = InstantWin::query()->lockForUpdate()
|
||||
->where('available_at', '<', now())
|
||||
->whereDoesntHave('participation')
|
||||
->get()->sortBy('available_at')->first();
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
/** @var \App\Models\Code|null */
|
||||
/** @var Code|null */
|
||||
$code = $request->post('unique_code');
|
||||
/** @var \App\Models\Product|null */
|
||||
/** @var Product|null */
|
||||
$product = $request->post('product');
|
||||
|
||||
// * Make new participation
|
||||
$participation = Participation::makeNew(
|
||||
app('clientIp'),
|
||||
resolve('clientIp'),
|
||||
$customer,
|
||||
$code,
|
||||
$product
|
||||
|
|
@ -92,19 +101,21 @@ class ParticipateController extends Controller
|
|||
|
||||
// * Si l'utilisateur actuel à déjà gagné un gros lot, pas d'instant gagnant.
|
||||
// ? As-t-on un instant gagnant ?
|
||||
if (Participation::customerAlreadyHasAnInstantWin($customer) or !$instantWin) {
|
||||
if (Participation::customerAlreadyHasAnInstantWin($customer) || ! $instantWin) {
|
||||
// * --- DISCOUNT WIN ---
|
||||
// ? Les BR sont activés ?
|
||||
if (!$settings->discounts_activated) {
|
||||
if (! $settings->discounts_activated) {
|
||||
// * On enregistre la participation du joueur.
|
||||
$participation->save();
|
||||
|
||||
// * Pas de coupons disponibles, le joueur à perdu
|
||||
return view('theme::pages.participation.loose');
|
||||
/** @var view-string $view Pas de coupons disponibles, le joueur à perdu. */
|
||||
$view = 'theme::pages.participation.loose';
|
||||
|
||||
return view($view);
|
||||
}
|
||||
|
||||
// * Le joueur à gagné un coupon.
|
||||
/** @var \App\Lib\Discount Coupon aléatoire en fonction du ratio de chaque coupon */
|
||||
/** @var \App\Lib\Discount Coupon aléatoire en fonction du ratio de chaque coupon */
|
||||
$discount = Arr::get(
|
||||
$settings->web_coupons,
|
||||
$this->getRandomWeightedElementIndex($settings->web_coupons)
|
||||
|
|
@ -124,8 +135,11 @@ class ParticipateController extends Controller
|
|||
$crmCustomer->firstname
|
||||
));
|
||||
|
||||
return view('theme::pages.participation.won', compact('discount'));
|
||||
} //end if
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won';
|
||||
|
||||
return view($view, ['discount' => $discount]);
|
||||
} // end if
|
||||
|
||||
// * --- INSTANT WIN ---
|
||||
// * On enregistre la participation du joueur.
|
||||
|
|
@ -148,43 +162,42 @@ class ParticipateController extends Controller
|
|||
$participation->created_at,
|
||||
$instantWin->prize->label,
|
||||
$crmCustomer,
|
||||
optional($code)->code_unique,
|
||||
optional($product)->ean_code
|
||||
$code?->code_unique,
|
||||
$product?->ean_code
|
||||
));
|
||||
|
||||
return view('theme::pages.participation.won', [
|
||||
'prizeModel' => $instantWin->prize,
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won';
|
||||
return view($view, [
|
||||
'prizeModel' => $instantWin->prize,
|
||||
'participationModel' => $participation,
|
||||
'crmCustomer' => $crmCustomer
|
||||
'crmCustomer' => $crmCustomer,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
// * --- PRIVATE METHODS ---
|
||||
|
||||
/**
|
||||
* Try Call CRM + MesBr to setup discount
|
||||
*
|
||||
* @param \App\Models\Customer $customer
|
||||
* @param LibDiscount $discount
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException If Any error occurs.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
* @throws HttpResponseException If Any error occurs.
|
||||
*
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity
|
||||
*/
|
||||
private function setDiscountAsWon(Customer $customer, LibDiscount $discount): void
|
||||
{
|
||||
// phpcs:enable
|
||||
// * Phase - 1 Recupération des informations CRM
|
||||
/** @var \LDC\LDCCRM\Models\Customer*/
|
||||
/** @var \LDC\LDCCRM\Models\Customer */
|
||||
$crmUser = $this->crmRepository->fetchCrmCustomer($customer);
|
||||
|
||||
// * Phase - 2 Mise à jour du coupon dans MesBr
|
||||
try {
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('mesBrAPI');
|
||||
/** @var MesBr */
|
||||
$mesBr = resolve('mesBrAPI');
|
||||
|
||||
// * MaJ Customer
|
||||
/** @var string */
|
||||
|
|
@ -195,23 +208,24 @@ class ParticipateController extends Controller
|
|||
*
|
||||
* Id est necessaire pour update panier..
|
||||
*/
|
||||
/** @var object|null $result */
|
||||
$result = $mesBr->updateCustomer($crmUser->hashcode, $crmUser->email, $crmUser->country->label());
|
||||
if (optional($result)->status !== "OK") {
|
||||
throw new \RuntimeException(
|
||||
if ($result?->status !== 'OK') {
|
||||
throw new RuntimeException(
|
||||
\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
$result->code ?? 'Undefined',
|
||||
$result->code ?? 'Undefined',
|
||||
$result->message ?? 'Undefined'
|
||||
)
|
||||
);
|
||||
}
|
||||
/** @var object|null */
|
||||
$crm_customer = optional($result)->customer;
|
||||
if (empty(optional($crm_customer)->hashcode)) {
|
||||
throw new \RuntimeException(
|
||||
'MESBR : Une erreur est survenue. Update Customer n\'as pas retourné le customer hashcode'
|
||||
);
|
||||
}
|
||||
/** @var object|null $crm_customer */
|
||||
$crm_customer = $result->customer ?? null;
|
||||
throw_if(
|
||||
empty($crm_customer->hashcode),
|
||||
RuntimeException::class,
|
||||
'MESBR : Une erreur est survenue. Update Customer n\'as pas retourné le customer hashcode',
|
||||
);
|
||||
|
||||
return $crm_customer->hashcode;
|
||||
}, 100);
|
||||
|
|
@ -222,11 +236,11 @@ class ParticipateController extends Controller
|
|||
strval($discount->web_coupon_identifiant)
|
||||
);
|
||||
|
||||
if (Arr::get($result, 'status') === "OK") {
|
||||
if (Arr::get($result, 'status') === 'OK') {
|
||||
// * La réponse est conforme ?
|
||||
$needed_fields = ['ref'];
|
||||
if (!Arr::has($result, $needed_fields)) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
if (! Arr::has($result, $needed_fields)) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'MESBR : Il manques des champs dans la réponse, attendu => %s, donné => %s',
|
||||
json_encode($needed_fields),
|
||||
json_encode($result),
|
||||
|
|
@ -237,20 +251,18 @@ class ParticipateController extends Controller
|
|||
return;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(
|
||||
throw new RuntimeException(
|
||||
\sprintf(
|
||||
'MESBR : Une erreur est survenue. Code : %s Message : %s',
|
||||
$result["code"] ?? 'Undefined',
|
||||
$result["message"] ?? 'Undefined'
|
||||
$result['code'] ?? 'Undefined',
|
||||
$result['message'] ?? 'Undefined'
|
||||
)
|
||||
);
|
||||
} catch (\RuntimeException $e) {
|
||||
} catch (RuntimeException $e) {
|
||||
report($e);
|
||||
// * Retenter ?
|
||||
back()->with('error', trans('front.messages.unexpected_error_try_later'))->throwResponse();
|
||||
} //end try
|
||||
|
||||
throw new \Error('Should not reach this point');
|
||||
} // end try
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -258,35 +270,34 @@ class ParticipateController extends Controller
|
|||
* Or redirect him to the fill form
|
||||
* ! Also validates its birth date (because beeing an adult is required to participate)
|
||||
*
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException If customer data doest not validate
|
||||
* or and error occurs.
|
||||
* @throws HttpResponseException If customer data doest not validate
|
||||
* or and error occurs.
|
||||
*/
|
||||
private function assertUserHasEnoughInfoToUseMesBr(): void
|
||||
{
|
||||
|
||||
// * Valider que le client dispose des donnés requises pour MesBr
|
||||
try {
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$authUser = auth('frontend')->user();
|
||||
$crmCustomer = $this->crmRepository->fetchCrmCustomer($authUser);
|
||||
|
||||
// * On valide les données selon les critères du site
|
||||
$rules = collect((new CreateAccountRequest())->rules());
|
||||
$rules = collect(new CreateAccountRequest()->rules());
|
||||
Validator::make(
|
||||
[
|
||||
'birth_date' => $crmCustomer->birth_date,
|
||||
'address' => $crmCustomer->address,
|
||||
'birth_date' => $crmCustomer->birth_date,
|
||||
'address' => $crmCustomer->address,
|
||||
'postal_code' => $crmCustomer->postcode,
|
||||
'country' => $crmCustomer->country->value,
|
||||
'city' => $crmCustomer->city
|
||||
'country' => $crmCustomer->country->value,
|
||||
'city' => $crmCustomer->city,
|
||||
],
|
||||
[
|
||||
'birth_date' => $rules->get('birth_date'),
|
||||
'address' => $rules->get('address'),
|
||||
'birth_date' => $rules->get('birth_date'),
|
||||
'address' => $rules->get('address'),
|
||||
'postal_code' => $rules->get('postal_code'),
|
||||
'country' => $rules->get('country'),
|
||||
'city' => $rules->get('city')
|
||||
'country' => $rules->get('country'),
|
||||
'city' => $rules->get('city'),
|
||||
]
|
||||
)->validate();
|
||||
Session::remove('needCrmInfoUpdate');
|
||||
|
|
@ -295,13 +306,13 @@ class ParticipateController extends Controller
|
|||
->with('warning', trans(
|
||||
'front.messages.profile_incomplete_cannot_play'
|
||||
))->throwResponse();
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
report($e);
|
||||
// * Retenter ?
|
||||
response()->redirectToRoute('fo.homepage')
|
||||
->with('error', trans('front.messages.unexpected_error_try_later'))
|
||||
->throwResponse();
|
||||
} //end try
|
||||
} // end try
|
||||
}
|
||||
|
||||
// * --- END PRIVATE METHODS ---
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
|
|
@ -11,47 +13,44 @@ class StaticPageController extends Controller
|
|||
{
|
||||
/**
|
||||
* Show the rules view
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function reglement()
|
||||
public function reglement(): View
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::rules)->firstOrFail();
|
||||
|
||||
return $this->viewStaticPage($staticPageModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the privacy view
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function charte()
|
||||
public function charte(): View
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::confidentiality)->firstOrFail();
|
||||
|
||||
return $this->viewStaticPage($staticPageModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the legals view
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function legals()
|
||||
public function legals(): View
|
||||
{
|
||||
$staticPageModel = StaticPage::query()->where('type', StaticPageType::legals)->firstOrFail();
|
||||
|
||||
return $this->viewStaticPage($staticPageModel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a static page
|
||||
*
|
||||
* @param \App\Models\StaticPage $staticPageModel
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
private function viewStaticPage(StaticPage $staticPageModel): View
|
||||
{
|
||||
return view('theme::pages.static_page', [
|
||||
'staticPageModel' => $staticPageModel
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.static_page';
|
||||
|
||||
return view($view, [
|
||||
'staticPageModel' => $staticPageModel,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\SubmitWinningProofRequest;
|
||||
use App\Mail\Won\WinningProofAdminMail;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use App\Notifications\Customer\HasSubmitedWinProof;
|
||||
|
|
@ -19,42 +22,42 @@ use Illuminate\Validation\ValidationException as IlluminateValidationException;
|
|||
use LDC\LDCCRM\Enums\ApiError;
|
||||
use LDC\LDCCRM\Exceptions\ApiErrorException;
|
||||
use LDC\LDCCRM\Exceptions\ValidationException as CrmValidationException;
|
||||
use RuntimeException;
|
||||
|
||||
class WinningProofController extends Controller
|
||||
{
|
||||
/**
|
||||
* WinningProofController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(function (Request $request, callable $next) {
|
||||
$this->authorize('fo.gameEnabled');
|
||||
$this->authorize('submitProof', $request->route('participation'));
|
||||
|
||||
return $next($request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Display winning proof form
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function displayForm(Participation $participation): View
|
||||
{
|
||||
$participation->load('instantWin.prize');
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
return view('theme::pages.participation.won-form-only', [
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won-form-only';
|
||||
|
||||
return view($view, [
|
||||
'participationModel' => $participation,
|
||||
'prizeModel' => $participation->instantWin->prize,
|
||||
'crmCustomer' => $crmCustomer
|
||||
'prizeModel' => $participation->instantWin->prize,
|
||||
'crmCustomer' => $crmCustomer,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -64,10 +67,8 @@ class WinningProofController extends Controller
|
|||
* - 2 Save les pictures de preuve de gains
|
||||
* - 3 Envoi un mail au abonnés (settings notification_emails) avec les infos client
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\SubmitWinningProofRequest $request
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws IlluminateValidationException In case of failure.
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
*/
|
||||
public function displayFormSubmit(
|
||||
|
|
@ -80,14 +81,14 @@ class WinningProofController extends Controller
|
|||
$participation->load([
|
||||
'instantWin.prize',
|
||||
'code',
|
||||
'product'
|
||||
'product',
|
||||
]);
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
|
||||
// * --- PHASE 1 Update Crm Customer ---
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
|
@ -118,7 +119,7 @@ class WinningProofController extends Controller
|
|||
$participation->fill(Arr::only($request->validated(), [
|
||||
'barcode',
|
||||
'ticket',
|
||||
'sticker'
|
||||
'sticker',
|
||||
]));
|
||||
$participation->save();
|
||||
|
||||
|
|
@ -130,8 +131,8 @@ class WinningProofController extends Controller
|
|||
$participation->created_at,
|
||||
$participation->instantWin->prize->label,
|
||||
$crmCustomer,
|
||||
optional($participation->code)->code_unique,
|
||||
optional($participation->product)->ean_code,
|
||||
$participation->code?->code_unique,
|
||||
$participation->product?->ean_code,
|
||||
$participation->sticker,
|
||||
$participation->ticket,
|
||||
$participation->barcode,
|
||||
|
|
@ -145,16 +146,16 @@ class WinningProofController extends Controller
|
|||
} catch (ApiErrorException $e) {
|
||||
if ($e->getApiError()->equals(ApiError::validationFailed)) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
report($e);
|
||||
Log::error(__CLASS__ . '::create reached end of possibilities.');
|
||||
throw new \RuntimeException(__CLASS__ . '::create reached end of possibilities.');
|
||||
Log::error(self::class . '::create reached end of possibilities.');
|
||||
throw new RuntimeException(self::class . '::create reached end of possibilities.', $e->getCode(), $e);
|
||||
} catch (CrmValidationException $e) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
} //end try
|
||||
} // end try
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,37 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use App\Http\Middleware\Authenticate;
|
||||
use App\Http\Middleware\CheckGameStatus;
|
||||
use App\Http\Middleware\CheckThemeVersion;
|
||||
use App\Http\Middleware\EncryptCookies;
|
||||
use App\Http\Middleware\HtmlSanitizer;
|
||||
use App\Http\Middleware\PreventRequestsDuringMaintenance;
|
||||
use App\Http\Middleware\RedirectIfAuthenticated;
|
||||
use App\Http\Middleware\SecureHeaders;
|
||||
use App\Http\Middleware\TrimStrings;
|
||||
use App\Http\Middleware\TrustHosts;
|
||||
use App\Http\Middleware\TrustProxies;
|
||||
use App\Http\Middleware\ValidateSignature;
|
||||
use App\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
|
||||
use Illuminate\Auth\Middleware\Authorize;
|
||||
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
|
||||
use Illuminate\Auth\Middleware\RequirePassword;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
|
||||
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
|
||||
use Illuminate\Http\Middleware\HandleCors;
|
||||
use Illuminate\Http\Middleware\SetCacheHeaders;
|
||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
|
|
@ -13,14 +42,15 @@ class Kernel extends HttpKernel
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $middleware = [
|
||||
\App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
TrustHosts::class,
|
||||
TrustProxies::class,
|
||||
HandleCors::class,
|
||||
PreventRequestsDuringMaintenance::class,
|
||||
ValidatePostSize::class,
|
||||
TrimStrings::class,
|
||||
ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -28,22 +58,23 @@ class Kernel extends HttpKernel
|
|||
*
|
||||
* @var array<string, array<int, string>>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
'htmlsanitize',
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\SecureHeaders::class,
|
||||
\App\Http\Middleware\CheckThemeVersion::class
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
SubstituteBindings::class,
|
||||
SecureHeaders::class,
|
||||
CheckThemeVersion::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
ThrottleRequests::class . ':api',
|
||||
SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
|
|
@ -54,18 +85,19 @@ class Kernel extends HttpKernel
|
|||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'check-game-status' => \App\Http\Middleware\CheckGameStatus::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'htmlsanitize' => \App\Http\Middleware\HtmlSanitizer::class,
|
||||
#[\Override]
|
||||
protected $middlewareAliases = [
|
||||
'auth' => Authenticate::class,
|
||||
'auth.basic' => AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => AuthenticateSession::class,
|
||||
'cache.headers' => SetCacheHeaders::class,
|
||||
'can' => Authorize::class,
|
||||
'guest' => RedirectIfAuthenticated::class,
|
||||
'password.confirm' => RequirePassword::class,
|
||||
'check-game-status' => CheckGameStatus::class,
|
||||
'signed' => ValidateSignature::class,
|
||||
'throttle' => ThrottleRequests::class,
|
||||
'verified' => EnsureEmailIsVerified::class,
|
||||
'htmlsanitize' => HtmlSanitizer::class,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
|
@ -10,27 +12,25 @@ class Authenticate extends Middleware
|
|||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo(Request $request): ?string
|
||||
{
|
||||
$logins = [
|
||||
'backend' => route('bo.login')
|
||||
'backend' => route('bo.login'),
|
||||
];
|
||||
if (!$request->expectsJson()) {
|
||||
if (! $request->expectsJson()) {
|
||||
// * Notify must login
|
||||
Session::flash('warning', trans('Veuillez vous connecter pour continuer'));
|
||||
|
||||
foreach ($request->route()->gatherMiddleware() as $middleware) {
|
||||
if (\is_string($middleware) and strpos($middleware, 'auth:') !== false) {
|
||||
if (\is_string($middleware) && str_contains($middleware, 'auth:')) {
|
||||
$route = $logins[str_replace('auth:', '', $middleware)] ?? null;
|
||||
if ($route) {
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return route('fo.login');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use RuntimeException;
|
||||
|
||||
class CheckGameStatus
|
||||
{
|
||||
|
|
@ -12,21 +16,20 @@ class CheckGameStatus
|
|||
*
|
||||
* * Check with game settings which page should be shown and redirect if needed.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
* @throws \RuntimeException If tha game has an unhandled state.
|
||||
*
|
||||
* @throws RuntimeException If tha game has an unhandled state.
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next)
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings $settings */
|
||||
$settings = resolve(Settings::class);
|
||||
|
||||
return match (true) {
|
||||
// * End page
|
||||
$settings->should_display_end_page => redirect()->route('fo.end'),
|
||||
$settings->should_display_end_page => to_route('fo.end'),
|
||||
// * Teaser
|
||||
$settings->should_display_teaser_page => redirect()->route('fo.teaser'),
|
||||
$settings->should_display_teaser_page => to_route('fo.teaser'),
|
||||
// * Game is ended
|
||||
$settings->game_has_ended => redirect($settings->redirect_close),
|
||||
// * Game has started
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
|
|
@ -15,27 +18,22 @@ class CheckThemeVersion
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request):(\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @param Closure(Request):Response $next
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next): Response
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
// phpcs:enable
|
||||
|
||||
if (!app()->runningInConsole()) {
|
||||
$appInfos = Cache::remember('composer', 84600, function () {
|
||||
return json_decode(File::get(\app_path('../composer.json')));
|
||||
});
|
||||
if (! app()->runningInConsole()) {
|
||||
$appInfos = Cache::remember('composer', 84600, fn (): mixed => json_decode(File::get(\app_path('../composer.json'))));
|
||||
// * Assert theme version does not diverge more than minor
|
||||
$appVer = Str::of($appInfos->version)->explode('.');
|
||||
$themeVer = Str::of(config('theme.version'))->explode('.');
|
||||
if (
|
||||
// * Major check
|
||||
Arr::get($appVer, 0) !== Arr::get($themeVer, 0) or
|
||||
// * Patch check
|
||||
Arr::get($appVer, 1) !== Arr::get($themeVer, 1)
|
||||
Arr::get($appVer, 0) !== Arr::get($themeVer, 0) || Arr::get($appVer, 1) !== Arr::get($themeVer, 1)
|
||||
) {
|
||||
Session::flash('warning', trans(
|
||||
'Ce thème n\'a semble t-il pas été vérifié pour cette version du moteur'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
|
@ -11,5 +13,6 @@ class EncryptCookies extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
|
|
@ -10,19 +13,14 @@ class HtmlSanitizer
|
|||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|array ...$params
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next, string|array ...$params): Response
|
||||
public function handle(Request $request, Closure $next, string | array ...$params): Response
|
||||
{
|
||||
$inputs = $request->all();
|
||||
/** @var callable|null */
|
||||
$cleanInput = null;
|
||||
$cleanInput = function (
|
||||
null|string|array &$input,
|
||||
null | string | array &$input,
|
||||
string $name,
|
||||
?string $rootName = null
|
||||
) use (
|
||||
|
|
@ -33,14 +31,14 @@ class HtmlSanitizer
|
|||
if (is_array($input)) {
|
||||
array_walk_recursive($input, $cleanInput, $name);
|
||||
}
|
||||
if (!is_string($input)) {
|
||||
if (! is_string($input)) {
|
||||
return;
|
||||
}
|
||||
if (in_array($name, $params) or in_array($rootName ?? $name, $params)) {
|
||||
if (in_array($name, $params) || in_array($rootName ?? $name, $params)) {
|
||||
// ? Is a json input ?
|
||||
if ($isJson = \json_decode($input, true) and is_array($isJson)) {
|
||||
// ! Decode each json field recursive.
|
||||
\array_walk_recursive($isJson, function (string|array &$item) {
|
||||
\array_walk_recursive($isJson, function (string | array &$item): void {
|
||||
if (\is_string($item)) {
|
||||
$item = clean($item);
|
||||
$item = ToolboxHelper::stripCkEditorSchemesOnMediaInputs($item);
|
||||
|
|
@ -56,6 +54,7 @@ class HtmlSanitizer
|
|||
};
|
||||
\array_walk($inputs, $cleanInput);
|
||||
$request->merge($inputs);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
|
@ -11,5 +13,6 @@ class PreventRequestsDuringMaintenance extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
|
|
@ -10,30 +14,31 @@ class RedirectIfAuthenticated
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \RuntimeException If guard is unhandled.
|
||||
* @param Closure(Request):Response $next
|
||||
* @param string|null ...$guards
|
||||
*
|
||||
* @throws RuntimeException If guard is unhandled.
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function handle(Request $request, \Closure $next, ...$guards): Response
|
||||
public function handle(Request $request, Closure $next, ...$guards): Response
|
||||
{
|
||||
// phpcs:enable phpcs:disable
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
$guards = $guards === [] ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (auth($guard)->check()) {
|
||||
switch ($guard) {
|
||||
case 'frontend':
|
||||
return \redirect()->route('fo.homepage');
|
||||
return to_route('fo.homepage');
|
||||
case 'backend':
|
||||
if (!$request->routeIs('bo.*')) {
|
||||
if (! $request->routeIs('bo.*')) {
|
||||
continue 2;
|
||||
}
|
||||
return \redirect()->route('bo.dashboard');
|
||||
|
||||
return to_route('bo.dashboard');
|
||||
default:
|
||||
throw new \RuntimeException("Unhandled guard `{$guard}` .");
|
||||
throw new RuntimeException("Unhandled guard `{$guard}` .");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
|
@ -11,7 +13,7 @@ use Symfony\Component\HttpFoundation\Response;
|
|||
|
||||
class SecureHeaders
|
||||
{
|
||||
private $unwantedHeaderList = [
|
||||
private array $unwantedHeaderList = [
|
||||
'X-Powered-By',
|
||||
'Server',
|
||||
];
|
||||
|
|
@ -47,7 +49,7 @@ class SecureHeaders
|
|||
"connect-src 'self' blob: " . implode(' ', array_filter([
|
||||
$viteDevSocket,
|
||||
$viteDevOrigin,
|
||||
'https://yl.s-web.fr'
|
||||
'https://yl.s-web.fr',
|
||||
])) . ';',
|
||||
"img-src 'self' data: blob: " . implode(' ', array_filter([
|
||||
$viteDevOrigin,
|
||||
|
|
@ -56,11 +58,11 @@ class SecureHeaders
|
|||
"frame-src 'self' " . implode(' ', [
|
||||
'https://www.google.com/recaptcha/',
|
||||
'https://recaptcha.google.com/recaptcha/',
|
||||
'https://www.google.com/maps/'
|
||||
'https://www.google.com/maps/',
|
||||
]) . ';',
|
||||
"font-src 'self' data: " . implode(' ', array_filter([
|
||||
$viteDevOrigin,
|
||||
'https://fonts.gstatic.com' // <-- Point-virgule retiré ici
|
||||
'https://fonts.gstatic.com',
|
||||
])) . ';',
|
||||
"style-src 'self' 'unsafe-inline' " . implode(' ', array_filter([
|
||||
'https://cdnjs.cloudflare.com',
|
||||
|
|
@ -76,7 +78,7 @@ class SecureHeaders
|
|||
'https://cdnjs.cloudflare.com',
|
||||
"$scheme://www.google-analytics.com",
|
||||
$viteDevOrigin,
|
||||
])) . ';'
|
||||
])) . ';',
|
||||
];
|
||||
|
||||
$response->headers->set(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
|
@ -11,6 +13,7 @@ class TrimStrings extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
|
|
@ -12,15 +14,17 @@ class TrustProxies extends Middleware
|
|||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
#[\Override]
|
||||
protected $proxies = '*';
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var integer
|
||||
* @var int
|
||||
*/
|
||||
#[\Override]
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
|
@ -11,7 +13,8 @@ class VerifyCsrfToken extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $except = [
|
||||
'/csp-report'
|
||||
'/csp-report',
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\BannedIps;
|
||||
|
||||
use App\Models\BannedIp;
|
||||
|
|
@ -11,7 +13,7 @@ class StoreBannedIpRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -20,10 +22,8 @@ class StoreBannedIpRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'ip' => 'required|ip|unique:banned_ips,ip',
|
||||
|
|
@ -32,8 +32,6 @@ class StoreBannedIpRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\BannedIps;
|
||||
|
||||
use App\Models\BannedIp;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
|
|
@ -10,7 +13,7 @@ class UpdateBannedIpRequest extends StoreBannedIpRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -19,18 +22,17 @@ class UpdateBannedIpRequest extends StoreBannedIpRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \App\Models\BannedIp */
|
||||
/** @var BannedIp */
|
||||
$ipToBanModel = $this->route('banned_ip');
|
||||
|
||||
return [
|
||||
'ip' => [
|
||||
'required', 'ip',
|
||||
Rule::unique('banned_ips', 'ip')
|
||||
->ignore($ipToBanModel->ip, 'ip')
|
||||
->ignore($ipToBanModel->ip, 'ip'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Codes;
|
||||
|
||||
use App\Models\Code;
|
||||
|
|
@ -11,7 +13,7 @@ class CodeSearchRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -26,7 +28,7 @@ class CodeSearchRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'code' => 'required|string|min:1|max:25'
|
||||
'code' => 'required|string|min:1|max:25',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +40,7 @@ class CodeSearchRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'code' => trans('code')
|
||||
'code' => trans('code'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Codes;
|
||||
|
||||
use App\Models\Code;
|
||||
|
|
@ -10,31 +12,28 @@ class ExportCodesRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('export', Code::class) and $this->json();
|
||||
return Gate::check('export', Code::class) && $this->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$codesAvailableToExport = Code::query()->where('code_exported', false);
|
||||
/** @var integer|null */
|
||||
$lastExportedId = optional(Code::query()->where('code_exported', true)
|
||||
->orderBy('id', 'desc')->first())->id ?? null;
|
||||
|
||||
/** @var int|null $lastExportedId */
|
||||
$lastExportedId = Code::query()->where('code_exported', true)->max('id');
|
||||
|
||||
if ($lastExportedId) {
|
||||
$codesAvailableToExport = $codesAvailableToExport
|
||||
->where('id', '>', $lastExportedId);
|
||||
$codesAvailableToExport->where('id', '>', $lastExportedId);
|
||||
}
|
||||
|
||||
$this->merge([
|
||||
'available_export' => $codesAvailableToExport->count()
|
||||
'available_export' => $codesAvailableToExport->count(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -46,10 +45,10 @@ class ExportCodesRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'nb_code_tot' => 'required|integer|min:1|lte:available_export',
|
||||
'nb_code_fic' => 'required|integer|min:1',
|
||||
'nb_code_ligne' => 'required|integer|min:1',
|
||||
'available_export' => 'required|integer'
|
||||
'nb_code_tot' => 'required|integer|min:1|lte:available_export',
|
||||
'nb_code_fic' => 'required|integer|min:1',
|
||||
'nb_code_ligne' => 'required|integer|min:1',
|
||||
'available_export' => 'required|integer',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -61,10 +60,10 @@ class ExportCodesRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'nb_code_fic' => trans('nombre total de codes à exporter'),
|
||||
'nb_code_tot' => trans('nombre de codes par fichier'),
|
||||
'nb_code_ligne' => trans('nombre de codes par ligne'),
|
||||
'available_export' => trans('nombre de codes restant à exporté(s)')
|
||||
'nb_code_fic' => trans('nombre total de codes à exporter'),
|
||||
'nb_code_tot' => trans('nombre de codes par fichier'),
|
||||
'nb_code_ligne' => trans('nombre de codes par ligne'),
|
||||
'available_export' => trans('nombre de codes restant à exporté(s)'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Codes;
|
||||
|
||||
use App\Models\Code;
|
||||
|
|
@ -10,12 +12,10 @@ class GenerateCodesRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return Gate::check('generate', Code::class) and $this->json();
|
||||
return Gate::check('generate', Code::class) && $this->json();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -26,7 +26,7 @@ class GenerateCodesRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'quantity' => 'required|integer|min:1'
|
||||
'quantity' => 'required|integer|min:1',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ class GenerateCodesRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'quantity' => trans('validation.custom.quantity')
|
||||
'quantity' => trans('validation.custom.quantity'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\FaqQuestions;
|
||||
|
||||
use App\Models\FaqQuestion;
|
||||
|
|
@ -11,7 +13,7 @@ class StoreFaqQuestionRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -20,28 +22,24 @@ class StoreFaqQuestionRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'question' => 'required|string|min:3|max:255',
|
||||
'answer' => 'required|string|min:3',
|
||||
'answer' => 'required|string|min:3',
|
||||
'theme_id' => 'required|exists:faq_themes,id',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'question' => trans('validation.custom.question'),
|
||||
'answer' => trans('validation.custom.answer'),
|
||||
'answer' => trans('validation.custom.answer'),
|
||||
'theme_id' => trans_choice('models.classes.faq-themes', 1),
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\FaqQuestions;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -9,7 +11,7 @@ class UpdateFaqQuestionRequest extends StoreFaqQuestionRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\FaqThemes;
|
||||
|
||||
use App\Models\FaqTheme;
|
||||
|
|
@ -11,7 +13,7 @@ class StoreFaqThemeRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -20,20 +22,16 @@ class StoreFaqThemeRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|min:3|max:255'
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\FaqThemes;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -9,7 +11,7 @@ class UpdateFaqThemeRequest extends StoreFaqThemeRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Prizes;
|
||||
|
||||
use App\Models\Prize;
|
||||
|
|
@ -14,7 +16,7 @@ class StorePrizeRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -23,37 +25,34 @@ class StorePrizeRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'pdf_winning_proof' => $this->input('pdf_winning_proof')
|
||||
'pdf_winning_proof' => $this->input('pdf_winning_proof'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'label' => 'required|string|min:3|max:255',
|
||||
'picture_alt' => 'required|string|between:3,255',
|
||||
'picture_title' => 'required|string|between:3,255',
|
||||
'arg_title' => 'required|string|min:3|max:255',
|
||||
'arg_subtitle' => 'nullable|string|min:3|max:255',
|
||||
'arg_content' => 'required|string|min:15',
|
||||
'quantity' => 'required|numeric|min:1',
|
||||
'label' => 'required|string|min:3|max:255',
|
||||
'picture_alt' => 'required|string|between:3,255',
|
||||
'picture_title' => 'required|string|between:3,255',
|
||||
'arg_title' => 'required|string|min:3|max:255',
|
||||
'arg_subtitle' => 'nullable|string|min:3|max:255',
|
||||
'arg_content' => 'required|string|min:15',
|
||||
'quantity' => 'required|numeric|min:1',
|
||||
'pdf_winning_proof' => 'nullable|file|mimes:pdf',
|
||||
];
|
||||
$min_width = config('theme.models.prizes.picture_min_width');
|
||||
$min_height = config('theme.models.prizes.picture_min_height');
|
||||
$max_width = config('theme.models.prizes.picture_max_width');
|
||||
$max_height = config('theme.models.prizes.picture_max_height');
|
||||
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', $min_width, $min_height, $max_width, $max_height),
|
||||
|
|
@ -62,20 +61,18 @@ class StorePrizeRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'label' => trans('validation.custom.label'),
|
||||
'picture' => trans('validation.custom.picture'),
|
||||
'picture_alt' => trans('validation.custom.picture_alt'),
|
||||
'picture_title' => trans('validation.custom.picture_title'),
|
||||
'arg_title' => trans('validation.attributes.title'),
|
||||
'arg_subtitle' => trans('validation.custom.subtitle'),
|
||||
'arg_content' => trans('validation.attributes.content'),
|
||||
'quantity' => trans('validation.custom.quantity'),
|
||||
'label' => trans('validation.custom.label'),
|
||||
'picture' => trans('validation.custom.picture'),
|
||||
'picture_alt' => trans('validation.custom.picture_alt'),
|
||||
'picture_title' => trans('validation.custom.picture_title'),
|
||||
'arg_title' => trans('validation.attributes.title'),
|
||||
'arg_subtitle' => trans('validation.custom.subtitle'),
|
||||
'arg_content' => trans('validation.attributes.content'),
|
||||
'quantity' => trans('validation.custom.quantity'),
|
||||
'pdf_winning_proof' => trans('validation.custom.pdf_winning_proof'),
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Prizes;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -9,7 +11,7 @@ class UpdatePrizeRequest extends StorePrizeRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Products;
|
||||
|
||||
use App\Models\Product;
|
||||
|
|
@ -15,7 +17,7 @@ class StoreProductRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -34,13 +36,11 @@ class StoreProductRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'ean_code' => [
|
||||
'required',
|
||||
'unique:products,ean_code',
|
||||
|
|
@ -48,10 +48,11 @@ class StoreProductRequest extends FormRequest
|
|||
],
|
||||
'picture_alt' => 'nullable|required_with:picture|string|between:3,255',
|
||||
'picture_title' => 'nullable|required_with:picture|string|between:3,255',
|
||||
'range_id' => 'exists:ranges,id'
|
||||
'range_id' => 'exists:ranges,id',
|
||||
];
|
||||
$width = config('theme.models.products.picture_max_width');
|
||||
$height = config('theme.models.products.picture_max_height');
|
||||
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', $width, $height, $width, $height, true),
|
||||
|
|
@ -60,28 +61,26 @@ class StoreProductRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'name' => trans('validation.attributes.name'),
|
||||
'name' => trans('validation.attributes.name'),
|
||||
'picture_title' => trans(':field1 :inter1:field2 :inter2:model', [
|
||||
'field1' => Str::ucfirst(trans('validation.custom.attribute_title')),
|
||||
'inter1' => trans('validation.custom.of_the.vowel'),
|
||||
'field2' => trans('validation.attributes.image'),
|
||||
'inter2' => trans('validation.custom.of_the.male'),
|
||||
'model' => trans('models.classes.product'),
|
||||
'model' => trans('models.classes.product'),
|
||||
]),
|
||||
'picture_alt' => trans(':field1 :inter1:field2 :inter2:model', [
|
||||
'field1' => Str::ucfirst(trans('validation.custom.attribute_alt')),
|
||||
'inter1' => trans('validation.custom.of_the.vowel'),
|
||||
'field2' => trans('validation.attributes.image'),
|
||||
'inter2' => trans('validation.custom.of_the.male'),
|
||||
'model' => trans('models.classes.product'),
|
||||
'model' => trans('models.classes.product'),
|
||||
]),
|
||||
'picture' => trans('validation.attributes.image'),
|
||||
'picture' => trans('validation.attributes.image'),
|
||||
'ean_code' => trans('validation.custom.ean_code'),
|
||||
'range_id' => trans('models.classes.range'),
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Products;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
|
|
@ -10,7 +13,7 @@ class UpdateProductRequest extends StoreProductRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -19,13 +22,12 @@ class UpdateProductRequest extends StoreProductRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \App\Models\Product */
|
||||
/** @var Product */
|
||||
$productModel = $this->route('product');
|
||||
|
||||
return array_merge(parent::rules(), [
|
||||
'ean_code' => [
|
||||
'required',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Ranges;
|
||||
|
||||
use App\Models\Range;
|
||||
|
|
@ -14,7 +16,7 @@ class StoreRangeRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -33,10 +35,8 @@ class StoreRangeRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|string|min:2|max:255',
|
||||
|
|
@ -45,6 +45,7 @@ class StoreRangeRequest extends FormRequest
|
|||
];
|
||||
$width = config('theme.models.ranges.picture_max_width');
|
||||
$height = config('theme.models.ranges.picture_max_height');
|
||||
|
||||
return \array_merge(
|
||||
$rules,
|
||||
$this->pictureRules('picture', $width, $height, $width, $height, false),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Ranges;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -9,7 +11,7 @@ class UpdateRangeRequest extends StoreRangeRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Settings;
|
||||
|
||||
use App\Enums\CodeType;
|
||||
|
|
@ -8,15 +10,13 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use LDC\LDCCRM\Enums\Country;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use LDC\LDCCRM\Enums\Country;
|
||||
|
||||
class UpdateSettingsRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
|
|
@ -25,8 +25,6 @@ class UpdateSettingsRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
|
|
@ -54,48 +52,46 @@ class UpdateSettingsRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'company' => 'required|string|min:3|max:255',
|
||||
'start_date' => 'required|date',
|
||||
'end_date' => 'required|date',
|
||||
'nb_participation_player' => 'required|numeric|min:0',
|
||||
'nb_participation_ip' => 'required|numeric|min:0',
|
||||
'nb_unique_code_use' => 'required|numeric|min:0',
|
||||
'code_type' => ['required', new Enum(CodeType::class)],
|
||||
'activated_teaser' => 'required|boolean',
|
||||
'activated_close_page' => 'required|boolean',
|
||||
'close_page_active_date' => [
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'company' => 'required|string|min:3|max:255',
|
||||
'start_date' => 'required|date',
|
||||
'end_date' => 'required|date',
|
||||
'nb_participation_player' => 'required|numeric|min:0',
|
||||
'nb_participation_ip' => 'required|numeric|min:0',
|
||||
'nb_unique_code_use' => 'required|numeric|min:0',
|
||||
'code_type' => ['required', new Enum(CodeType::class)],
|
||||
'activated_teaser' => 'required|boolean',
|
||||
'activated_close_page' => 'required|boolean',
|
||||
'close_page_active_date' => [
|
||||
'nullable',
|
||||
'required_if:activated_close_page,true,1',
|
||||
'date',
|
||||
'after_or_equal:end_date'
|
||||
'after_or_equal:end_date',
|
||||
],
|
||||
'redirect_close' => 'required|url:http,https',
|
||||
'notify_prize_sent' => 'required|boolean',
|
||||
'discounts_activated' => 'required|boolean',
|
||||
'discounts_site' => 'nullable|required_if:discounts_activated,true,1|string|min:3|max:255',
|
||||
'discounts_campaign' => 'nullable|required_if:discounts_activated,true,1|string|min:3|max:255',
|
||||
'redirect_close' => 'required|url:http,https',
|
||||
'notify_prize_sent' => 'required|boolean',
|
||||
'discounts_activated' => 'required|boolean',
|
||||
'discounts_site' => 'nullable|required_if:discounts_activated,true,1|string|min:3|max:255',
|
||||
'discounts_campaign' => 'nullable|required_if:discounts_activated,true,1|string|min:3|max:255',
|
||||
'web_coupons' => [
|
||||
'present', 'array', function ($attribute, $value, $fail) {
|
||||
if ($this->post('discounts_activated') and !collect($value)->filter()->count()) {
|
||||
'present', 'array', function ($attribute, $value, $fail): void {
|
||||
if ($this->post('discounts_activated') && ! collect($value)->filter()->count()) {
|
||||
$fail(trans('validation.min.array', [
|
||||
'attribute' => Arr::get($this->attributes(), $attribute),
|
||||
'min' => 1
|
||||
'min' => 1,
|
||||
]));
|
||||
}
|
||||
if (collect($value)->sum('percentage') > 100) {
|
||||
$fail(trans('validation.max.numeric', [
|
||||
'attribute' => Arr::get($this->attributes(), $attribute),
|
||||
'max' => 100
|
||||
'max' => 100,
|
||||
]));
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
'web_coupons.*' => 'array',
|
||||
'web_coupons.*.web_coupon_identifiant' => 'required|digits:13',
|
||||
|
|
@ -103,7 +99,7 @@ class UpdateSettingsRequest extends FormRequest
|
|||
'web_coupons.*.face_value' => 'required|numeric|min:10|max:300',
|
||||
'web_coupons.*.valid_on' => 'required|string|min:3|max:255',
|
||||
'web_coupons.*.picture' => [
|
||||
'required', function (string $attribute, $value, callable $fail) {
|
||||
'required', function (string $attribute, ?string $value, callable $fail): void {
|
||||
ToolboxHelper::validatePicture(
|
||||
$attribute,
|
||||
$value,
|
||||
|
|
@ -112,17 +108,17 @@ class UpdateSettingsRequest extends FormRequest
|
|||
'maxHeight' => 409,
|
||||
'maxWith' => 920,
|
||||
'minHeight' => 409,
|
||||
'minWith' => 920
|
||||
'minWith' => 920,
|
||||
]
|
||||
);
|
||||
}
|
||||
},
|
||||
],
|
||||
'notification_emails' => 'required|array|min:1',
|
||||
'notification_emails.*' => 'email:rfc,spoof,dns',
|
||||
'authorized_countries' => 'sometimes|array|max:' . count(Country::getValidCountries()),
|
||||
'authorized_countries.*' => [
|
||||
'sometimes',
|
||||
Rule::in(Country::getValidCountries())
|
||||
Rule::in(Country::getValidCountries()),
|
||||
],
|
||||
|
||||
'winning_proof' => 'required|boolean',
|
||||
|
|
@ -131,8 +127,6 @@ class UpdateSettingsRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\StaticPages;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Str;
|
||||
|
|
@ -11,7 +14,7 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -20,20 +23,18 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'content' => (string) Str::of($this->input('content'))
|
||||
'content' => (string) Str::of($this->input('content')),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -47,8 +48,6 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
|
@ -8,8 +10,6 @@ class UpdateChangeOrderRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
|
|
@ -18,20 +18,16 @@ class UpdateChangeOrderRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'direction' => $this->route('direction') === 'up' ? true : false
|
||||
'direction' => $this->route('direction') === 'up',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Users;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
|
|
@ -14,7 +16,7 @@ class StoreUserRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -29,48 +31,44 @@ class StoreUserRequest extends FormRequest
|
|||
protected function prepareForValidation()
|
||||
{
|
||||
$this->merge([
|
||||
'published' => $this->boolean('published')
|
||||
'published' => $this->boolean('published'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => 'required|string|min:3|max:255',
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'password' => [
|
||||
'last_name' => 'required|string|min:3|max:255',
|
||||
'email' => 'required|email:rfc,strict,dns,spoof,filter|unique:users,email',
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
->letters()
|
||||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
->uncompromised(),
|
||||
],
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'role' => ['required', new Enum(RoleEnum::class)],
|
||||
'published' => 'required|boolean',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'first_name' => trans('validation.attributes.first_name'),
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'password' => trans('validation.attributes.password'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication')
|
||||
'last_name' => trans('validation.attributes.last_name'),
|
||||
'email' => trans('validation.attributes.email'),
|
||||
'password' => trans('validation.attributes.password'),
|
||||
'role' => trans('validation.attributes.role'),
|
||||
'published' => trans('validation.custom.publication'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Users;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
|
@ -11,7 +14,7 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -25,33 +28,32 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
*/
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
/** @var User */
|
||||
$userModel = $this->route('user');
|
||||
$this->merge([
|
||||
'published' => $this->boolean('published'),
|
||||
'password' => $this->input(
|
||||
'password' => $this->input(
|
||||
'password',
|
||||
) ?? $userModel->password,
|
||||
'password_confirmation' => $this->input(
|
||||
'password_confirmation'
|
||||
) ?? $userModel->password
|
||||
) ?? $userModel->password,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \App\Models\User */
|
||||
/** @var User */
|
||||
$userModel = $this->route('user');
|
||||
|
||||
return array_merge(parent::rules(), [
|
||||
'email' => [
|
||||
'required',
|
||||
'email:rfc,strict,dns,spoof,filter',
|
||||
Rule::unique('users', 'email')->ignore($userModel->getRouteKey())
|
||||
Rule::unique('users', 'email')->ignore($userModel->getRouteKey()),
|
||||
],
|
||||
'password' => [
|
||||
'required', 'required_with:password_confirmation', 'confirmed', 'max:255', Password::min(8)
|
||||
|
|
@ -59,7 +61,7 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised()
|
||||
->uncompromised(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
use App\Models\Customer;
|
||||
use App\Models\Settings;
|
||||
use App\Repositories\Fo\CrmRepository;
|
||||
use App\Rules\IsAdult;
|
||||
use Closure;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -18,8 +22,6 @@ class CreateAccountRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
|
|
@ -28,35 +30,30 @@ class CreateAccountRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'phone' => $this->input('phone'),
|
||||
'opt_in' => $this->boolean('opt_in'),
|
||||
'ok_cgv' => $this->boolean('ok_cgv')
|
||||
'ok_cgv' => $this->boolean('ok_cgv'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings $settings */
|
||||
$settings = resolve(Settings::class);
|
||||
|
||||
/** @var \App\Models\Customer|null */
|
||||
$authUser = auth('frontend')->user();
|
||||
$countryCode = null;
|
||||
|
||||
$countryCode = $this->integer('country') != 0 ?
|
||||
$this->integer('country') : ($authUser ?
|
||||
(new CrmRepository())->fetchCrmCustomer($authUser)->country->value : 0);
|
||||
new CrmRepository()->fetchCrmCustomer($authUser)->country->value : 0);
|
||||
$countryRules = match ($countryCode) {
|
||||
Country::belgium->value => [
|
||||
'phone' => 'phone:BE',
|
||||
|
|
@ -105,13 +102,13 @@ class CreateAccountRequest extends FormRequest
|
|||
'max:255',
|
||||
// * Does email already exists in CRM ?
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function (string $attribute, $value, \Closure $fail) {
|
||||
if (CrmCustomer::findWithEmail(\strval($value))) {
|
||||
function (string $attribute, $value, Closure $fail): void {
|
||||
if (CrmCustomer::findWithEmail(\strval($value)) instanceof CrmCustomer) {
|
||||
$fail('Un compte existe déjà avec cette adresse.');
|
||||
} else {
|
||||
// ! Si le compte n'existe pas en CRM mais existe en local.
|
||||
// ! On le soft-delete pour permettre l'inscription et la restauration propre.
|
||||
$localCustomer = \App\Models\Customer::where('email', \strval($value))->first();
|
||||
$localCustomer = Customer::where('email', \strval($value))->first();
|
||||
if ($localCustomer) {
|
||||
$localCustomer->delete();
|
||||
}
|
||||
|
|
@ -123,7 +120,7 @@ class CreateAccountRequest extends FormRequest
|
|||
'required',
|
||||
'confirmed',
|
||||
Password::min(8)->mixedCase()
|
||||
->numbers()->symbols()->uncompromised()
|
||||
->numbers()->symbols()->uncompromised(),
|
||||
],
|
||||
'ok_cgv' => 'accepted',
|
||||
'opt_in' => 'required|boolean',
|
||||
|
|
@ -132,8 +129,6 @@ class CreateAccountRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
@ -157,30 +152,28 @@ class CreateAccountRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom messages for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function messages(): array
|
||||
{
|
||||
$messages = [
|
||||
'postal_code' => trans('validation.postal_code', [
|
||||
'countries' => \implode(', ', Country::getValidCountriesLabel()),
|
||||
'examples' => 72000
|
||||
'examples' => 72000,
|
||||
]),
|
||||
'phone.phone' => trans('validation.phone', [
|
||||
'countries' => \implode(', ', Country::getValidCountriesLabel())
|
||||
'countries' => \implode(', ', Country::getValidCountriesLabel()),
|
||||
]),
|
||||
'email.unique' => trans('Un compte existe déjà avec cette adresse.'),
|
||||
'ok_cgv.accepted' => trans('Vous devez accepter les conditions d\'utilisation du site pour continuer.')
|
||||
];
|
||||
'ok_cgv.accepted' => trans('Vous devez accepter les conditions d\'utilisation du site pour continuer.'),
|
||||
]; // end match
|
||||
|
||||
$messages = match ($this->integer('country')) {
|
||||
return match ($this->integer('country')) {
|
||||
Country::belgium->value => array_merge(
|
||||
$messages,
|
||||
[
|
||||
'postal_code' => trans('validation.postal_code', [
|
||||
'countries' => Country::belgium->label(),
|
||||
'examples' => 1000
|
||||
'examples' => 1000,
|
||||
]),
|
||||
]
|
||||
),
|
||||
|
|
@ -189,7 +182,7 @@ class CreateAccountRequest extends FormRequest
|
|||
[
|
||||
'postal_code' => trans('validation.postal_code', [
|
||||
'countries' => Country::luxembourg->label(),
|
||||
'examples' => 1111
|
||||
'examples' => 1111,
|
||||
]),
|
||||
]
|
||||
),
|
||||
|
|
@ -198,7 +191,7 @@ class CreateAccountRequest extends FormRequest
|
|||
[
|
||||
'postal_code' => trans('validation.postal_code', [
|
||||
'countries' => Country::germany->label(),
|
||||
'examples' => 10115
|
||||
'examples' => 10115,
|
||||
]),
|
||||
]
|
||||
),
|
||||
|
|
@ -214,12 +207,10 @@ class CreateAccountRequest extends FormRequest
|
|||
array_search(Country::germany->label(), Country::getValidCountriesLabel()),
|
||||
]
|
||||
)),
|
||||
'examples' => 72000
|
||||
'examples' => 72000,
|
||||
]),
|
||||
]
|
||||
),
|
||||
}; //end match
|
||||
|
||||
return $messages;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
|
@ -8,20 +10,16 @@ class SingleOptinRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email:rfc,dns,spoof',
|
||||
|
|
|
|||
|
|
@ -1,15 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class VerifyInformationsRequest extends CreateAccountRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
|
|
@ -19,7 +20,7 @@ class VerifyInformationsRequest extends CreateAccountRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Fo;
|
||||
|
||||
use App\Enums\CodeType;
|
||||
use App\Models\Code;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Product;
|
||||
use App\Models\Settings;
|
||||
|
|
@ -19,30 +22,27 @@ class ParticipateRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
// * Use rate limiter to prevent brute force sticker code
|
||||
if (RateLimiter::tooManyAttempts("participate:{$customer->id}", $perMinute = 5)) {
|
||||
return false;
|
||||
}
|
||||
RateLimiter::hit("participate:{$customer->id}");
|
||||
|
||||
return Gate::check('participate', Participation::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
if ($settings->code_type->equals(CodeType::unique) || $settings->code_type->equals(CodeType::both)) {
|
||||
try {
|
||||
$this->merge([
|
||||
|
|
@ -83,18 +83,16 @@ class ParticipateRequest extends FormRequest
|
|||
->first(),
|
||||
'game_rules' => $this->boolean('game_rules'),
|
||||
]);
|
||||
} //end if
|
||||
} // end if
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
|
||||
$rules = [
|
||||
'game_rules' => 'required|boolean|accepted',
|
||||
|
|
@ -105,17 +103,18 @@ class ParticipateRequest extends FormRequest
|
|||
$rules = \array_merge($rules, ['unique_code' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function (string $attribute, $value, callable $fail) {
|
||||
function (string $attribute, $value, callable $fail): void {
|
||||
// ? Le Code unique est resolved ?
|
||||
if ($value === false or !\is_object($value) or \get_class($value) !== Code::class) {
|
||||
if ($value === false || ! \is_object($value) || $value::class !== Code::class) {
|
||||
$fail(trans('front.messages.unique_code_invalid'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
/** @var Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
/** @var \App\Models\Code $value */
|
||||
/** @var Code $value */
|
||||
// * Check si l'utilisateur n'a pas déjà utilisé ce code.
|
||||
$query = Participation::query()
|
||||
->whereHas('code', fn (Builder $q) => $q->where('id', $value->id))
|
||||
|
|
@ -123,6 +122,7 @@ class ParticipateRequest extends FormRequest
|
|||
// ! Une seule participation avec un code donné par joueur
|
||||
if ($query->exists()) {
|
||||
$fail(trans('front.messages.unique_code_already_used'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -131,37 +131,36 @@ class ParticipateRequest extends FormRequest
|
|||
if ($value->has_been_used_too_many_times) {
|
||||
// * Ne pas laisser d'indices, message générique
|
||||
$fail(trans('front.messages.unique_code_invalid'));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
]]);
|
||||
} //end if
|
||||
} // end if
|
||||
|
||||
// ? Does the game use EAN Codes ?
|
||||
if ($settings->code_type->equals(CodeType::ean) || $settings->code_type->equals(CodeType::both)) {
|
||||
$rules = \array_merge($rules, ['ean_code' => [
|
||||
return \array_merge($rules, ['ean_code' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) {
|
||||
function ($attribute, $value, $fail): void {
|
||||
// phpcs:enable
|
||||
/** @var \App\Models\Produt|mixed */
|
||||
$product = $this->input('product');
|
||||
if (
|
||||
empty($product) or !is_object($product) or
|
||||
!($product instanceof Model) or !$product->exists
|
||||
empty($product) || ! is_object($product) || ! ($product instanceof Model) || ! $product->exists
|
||||
) {
|
||||
$fail(trans('front.messages.barcode_invalid'));
|
||||
}
|
||||
}
|
||||
},
|
||||
]]);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Fo;
|
||||
|
||||
use App\Http\Requests\Fo\Customers\CreateAccountRequest;
|
||||
use App\Repositories\Fo\CrmRepository;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use LDC\LDCCRM\Enums\Country;
|
||||
|
|
@ -12,26 +15,23 @@ class SubmitWinningProofRequest extends CreateAccountRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return auth('frontend')->check() &&
|
||||
Gate::check('submitProof', $this->route('participation'));
|
||||
return auth('frontend')->check() && Gate::check('submitProof', $this->route('participation'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
$authUser = auth('frontend')->user();
|
||||
$authUser = auth('frontend')->user();
|
||||
$countryCode = $this->integer('country') != 0 ?
|
||||
$this->integer('country') : ($authUser ?
|
||||
(new CrmRepository())->fetchCrmCustomer($authUser)->country->value : 0);
|
||||
new CrmRepository()->fetchCrmCustomer($authUser)->country->value : 0);
|
||||
$countryRules = match ($countryCode) {
|
||||
Country::belgium->value => ['phone' => 'phone:BE'],
|
||||
Country::luxembourg->value => ['phone' => 'phone:LU'],
|
||||
|
|
@ -75,14 +75,12 @@ class SubmitWinningProofRequest extends CreateAccountRequest
|
|||
|
||||
return collect(['sticker', 'ticket', 'barcode'])
|
||||
->filter(fn (string $proof) => config("proofs.$proof"))
|
||||
->mapWithKeys(fn (string $proof) => [$proof => $fileRules])
|
||||
->mapWithKeys(fn (string $proof): array => [$proof => $fileRules])
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
@ -90,7 +88,7 @@ class SubmitWinningProofRequest extends CreateAccountRequest
|
|||
parent::attributes(),
|
||||
[
|
||||
'sticker' => trans('validation.custom.sticker'),
|
||||
'ticket' => trans('validation.custom.ticket'),
|
||||
'ticket' => trans('validation.custom.ticket'),
|
||||
'barcode' => trans('validation.custom.barcode'),
|
||||
]
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Jobs\DeleteOlds;
|
||||
|
||||
use App\Models\Customer;
|
||||
|
|
@ -12,12 +14,10 @@ class DeleteOldCustomers
|
|||
{
|
||||
/**
|
||||
* Called when the job will be executed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
Log::debug(__CLASS__ . ' Removing old customers');
|
||||
Log::debug(self::class . ' Removing old customers');
|
||||
Customer::query()->withTrashed()->where('last_connection', '<=', now()->subMonths(36))->forceDelete();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +1,32 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Mail\Jobs\CodeExportSucceed;
|
||||
use App\Mail\Jobs\JobFailed;
|
||||
use App\Models\Code;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Exception;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Foundation\Queue\Queueable;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Throwable;
|
||||
use ZipArchive;
|
||||
|
||||
class ProcessExportCodesUniques implements ShouldQueue, ShouldBeUnique
|
||||
class ProcessExportCodesUniques implements ShouldBeUnique, ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of seconds the job can run before timing out.
|
||||
*
|
||||
* 28800 seconds (8 hours)
|
||||
*
|
||||
* @var integer
|
||||
* @var int
|
||||
*/
|
||||
public $timeout = 28800;
|
||||
|
||||
|
|
@ -36,15 +35,14 @@ class ProcessExportCodesUniques implements ShouldQueue, ShouldBeUnique
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $exportFileName = null;
|
||||
protected $exportFileName;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param integer $nbCodeFic Nombre de codes par fichiers.
|
||||
* @param integer $nbCodeTot Nombre total de codes à exporter.
|
||||
* @param integer $nbCodeLigne Nombre de codes par ligne.
|
||||
* @return void
|
||||
* @param int $nbCodeFic Nombre de codes par fichiers.
|
||||
* @param int $nbCodeTot Nombre total de codes à exporter.
|
||||
* @param int $nbCodeLigne Nombre de codes par ligne.
|
||||
*/
|
||||
public function __construct(
|
||||
protected int $nbCodeFic,
|
||||
|
|
@ -55,12 +53,10 @@ class ProcessExportCodesUniques implements ShouldQueue, ShouldBeUnique
|
|||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
DB::transaction(function () {
|
||||
DB::transaction(function (): void {
|
||||
$this->exportFileName = sprintf(
|
||||
'CodesUniques_%s',
|
||||
date('dmY_His')
|
||||
|
|
@ -76,8 +72,8 @@ class ProcessExportCodesUniques implements ShouldQueue, ShouldBeUnique
|
|||
$filesPath = $this->generateCsvFiles($lastExportedCodeId);
|
||||
|
||||
// * Compression des fichiers.
|
||||
$zip = new \ZipArchive();
|
||||
if ($zip->open($exportFilePath, \ZipArchive::CREATE) === true) {
|
||||
$zip = new ZipArchive();
|
||||
if ($zip->open($exportFilePath, ZipArchive::CREATE) === true) {
|
||||
foreach ($filesPath as $filePath) {
|
||||
if (File::exists($filePath)) {
|
||||
$zip->addFile($filePath, \pathinfo($filePath, \PATHINFO_BASENAME));
|
||||
|
|
@ -100,21 +96,22 @@ class ProcessExportCodesUniques implements ShouldQueue, ShouldBeUnique
|
|||
$this->nbCodeLigne,
|
||||
$exportFilePath
|
||||
));
|
||||
} catch (\Exception $e) {
|
||||
} catch (Exception $e) {
|
||||
// * Clear exported file in case of Failure.
|
||||
if (File::exists($exportFilePath)) {
|
||||
File::delete($exportFilePath);
|
||||
}
|
||||
throw $e;
|
||||
} //end try
|
||||
} // end try
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate CSV File using the job parameters
|
||||
*
|
||||
* @param integer|null $lastExportedCodeId
|
||||
* @param int|null $lastExportedCodeId
|
||||
* @return array Array of temp files
|
||||
*
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
private function generateCsvFiles($lastExportedCodeId = null): array
|
||||
|
|
@ -152,7 +149,7 @@ class ProcessExportCodesUniques implements ShouldQueue, ShouldBeUnique
|
|||
} else {
|
||||
File::append($tempFilePath, Code::intToSerial($code) . ';');
|
||||
$currentLineCodes++;
|
||||
} //end if
|
||||
} // end if
|
||||
|
||||
$totalExportedCodes++;
|
||||
$currentExportedCodes++;
|
||||
|
|
@ -175,29 +172,26 @@ class ProcessExportCodesUniques implements ShouldQueue, ShouldBeUnique
|
|||
Code::query()->whereIn('id', $exportedCodesId)->update(['code_exported' => true]);
|
||||
$exportedCodesId = [];
|
||||
}
|
||||
} //end if
|
||||
} //end foreach
|
||||
} // end if
|
||||
} // end foreach
|
||||
|
||||
// ? Are there exported codes to save ?
|
||||
if (count($exportedCodesId)) {
|
||||
Code::query()->whereIn('id', $exportedCodesId)->update(['code_exported' => true]);
|
||||
}
|
||||
|
||||
return $outPaths;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In case of job failure
|
||||
*
|
||||
* @param \Throwable $exception
|
||||
* @return void
|
||||
*/
|
||||
public function failed(\Throwable $exception)
|
||||
public function failed(Throwable $exception): void
|
||||
{
|
||||
Mail::to(config('mail.admin'))->send(
|
||||
new JobFailed(__CLASS__, [
|
||||
new JobFailed(self::class, [
|
||||
'message' => $exception->getMessage(),
|
||||
'trace' => $exception->getTraceAsString()
|
||||
'trace' => $exception->getTraceAsString(),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +1,39 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Mail\Jobs\CodeGenerationSucceed;
|
||||
use App\Mail\Jobs\JobFailed;
|
||||
use App\Models\Code;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Foundation\Queue\Queueable;
|
||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Throwable;
|
||||
|
||||
class ProcessUniqueCode implements ShouldQueue, ShouldBeUnique
|
||||
class ProcessUniqueCode implements ShouldBeUnique, ShouldQueue
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of seconds the job can run before timing out.
|
||||
*
|
||||
* 7200 seconds (2 hours)
|
||||
*
|
||||
* @var integer
|
||||
* @var int
|
||||
*/
|
||||
public $timeout = 7200;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param integer $amount Amount of code to generate.
|
||||
* @param integer $length Length of each code to generate.
|
||||
* @return void
|
||||
* @param int $amount Amount of code to generate.
|
||||
* @param int $length Length of each code to generate.
|
||||
*/
|
||||
public function __construct(protected int $amount, protected int $length)
|
||||
{
|
||||
|
|
@ -45,38 +41,29 @@ class ProcessUniqueCode implements ShouldQueue, ShouldBeUnique
|
|||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
public function handle(): void
|
||||
{
|
||||
DB::transaction(function () {
|
||||
DB::transaction(function (): void {
|
||||
// ! Le premier code commence à 1
|
||||
$last_id = (Code::query()->max('id') ?? 0) + 1;
|
||||
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var Settings $settings */
|
||||
$settings = resolve(Settings::class);
|
||||
|
||||
$maxSQLPlaceholders = 65535;
|
||||
|
||||
$insertColumns = collect(DB::getSchemaBuilder()
|
||||
->getColumnListing((new Code())->getTable()))
|
||||
->filter(function ($name) {
|
||||
// * Ignorer les colonnes avec valeurs par défaut sur la table.
|
||||
return !in_array($name, ['id', 'code_exported']);
|
||||
})->count() + 1;
|
||||
->getColumnListing(new Code()->getTable()))
|
||||
->reject(fn ($name): bool => in_array($name, ['id', 'code_exported']))->count() + 1;
|
||||
|
||||
/**
|
||||
* Nombre d'insertions max sur un seule requète
|
||||
*
|
||||
* @var integer $perPage
|
||||
*/
|
||||
$perPage = \floor($maxSQLPlaceholders / $insertColumns);
|
||||
|
||||
/**
|
||||
* Nombre de page totale à insérer.
|
||||
*
|
||||
* @var integer $totalPages
|
||||
*/
|
||||
$totalPages = \ceil($this->amount / $perPage);
|
||||
|
||||
|
|
@ -87,7 +74,7 @@ class ProcessUniqueCode implements ShouldQueue, ShouldBeUnique
|
|||
$insertToGenerate = min($perPage, $this->amount - $totalGeneratedInserts);
|
||||
do {
|
||||
$inserts[] = [
|
||||
'id' => $last_id++,
|
||||
'id' => $last_id++,
|
||||
'date_creation' => now()->format('Y-m-d'),
|
||||
];
|
||||
} while (($totalGeneratedInserts < $this->amount) && --$insertToGenerate);
|
||||
|
|
@ -108,16 +95,13 @@ class ProcessUniqueCode implements ShouldQueue, ShouldBeUnique
|
|||
|
||||
/**
|
||||
* In case of job failure
|
||||
*
|
||||
* @param \Throwable $exception
|
||||
* @return void
|
||||
*/
|
||||
public function failed(\Throwable $exception)
|
||||
public function failed(Throwable $exception): void
|
||||
{
|
||||
Mail::to(config('mail.admin'))->send(
|
||||
new JobFailed(__CLASS__, [
|
||||
new JobFailed(self::class, [
|
||||
'message' => $exception->getMessage(),
|
||||
'trace' => $exception->getTraceAsString()
|
||||
'trace' => $exception->getTraceAsString(),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
|
@ -130,8 +114,8 @@ class ProcessUniqueCode implements ShouldQueue, ShouldBeUnique
|
|||
public function middleware(): array
|
||||
{
|
||||
return [
|
||||
(new WithoutOverlapping('code_generation'))
|
||||
->releaseAfter(60)
|
||||
new WithoutOverlapping('code_generation')
|
||||
->releaseAfter(60),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,30 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Lib;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Contracts\Support\Jsonable;
|
||||
use Illuminate\Support\Arr;
|
||||
use JsonSerializable;
|
||||
use ReturnTypeWillChange;
|
||||
use RuntimeException;
|
||||
use stdClass;
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Ligne de Coupon stocké dans settings
|
||||
*
|
||||
* @property integer $web_coupon_identifiant EAN 13 format (Mais ne représente pas un EAN 13),
|
||||
* Format utilisé dans MesBr.
|
||||
* @property integer $percentage Pourcentage de chance de gagner le lot nombre de 1 à 100.
|
||||
* @property integer $face_value Valeur faciale en centimes.
|
||||
* @property string $valid_on Text valable sur.. (duplicat de ce qui est inscrit dans MesBr)
|
||||
* Pour affichage sur la page de gain est dans le mail.
|
||||
* @property string $picture Image locale du Coupon.
|
||||
* @package App\Lib\Inputs
|
||||
* @property int $web_coupon_identifiant EAN 13 format (Mais ne représente pas un EAN 13),
|
||||
* Format utilisé dans MesBr.
|
||||
* @property int $percentage Pourcentage de chance de gagner le lot nombre de 1 à 100.
|
||||
* @property int $face_value Valeur faciale en centimes.
|
||||
* @property string $valid_on Text valable sur.. (duplicat de ce qui est inscrit dans MesBr)
|
||||
* Pour affichage sur la page de gain est dans le mail.
|
||||
* @property string $picture Image locale du Coupon.
|
||||
*/
|
||||
class Discount extends \stdClass implements Jsonable, Arrayable, \JsonSerializable
|
||||
class Discount extends stdClass implements Arrayable, Jsonable, JsonSerializable
|
||||
{
|
||||
/**
|
||||
* Properties list
|
||||
|
|
@ -36,33 +42,31 @@ class Discount extends \stdClass implements Jsonable, Arrayable, \JsonSerializab
|
|||
/**
|
||||
* Get property
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
* @throws \TypeError If prop is undefined.
|
||||
*
|
||||
* @throws TypeError If prop is undefined.
|
||||
*/
|
||||
public function __get(string $name)
|
||||
public function __get(string $name): mixed
|
||||
{
|
||||
if (
|
||||
in_array($name, self::$propertiesList)
|
||||
) {
|
||||
return $this->{$name};
|
||||
}
|
||||
throw new \TypeError("undefined property {$name}");
|
||||
throw new TypeError("undefined property {$name}");
|
||||
}
|
||||
|
||||
/**
|
||||
* Make and instance
|
||||
*
|
||||
* @param string $picture Image locale du Coupon.
|
||||
* @param string $valid_on Text valable sur.. (duplicat de ce qui est inscrit dans MesBr)
|
||||
* Pour affichage sur la page de gain est dans le mail.
|
||||
* @param integer $face_value Valeur faciale en centimes.
|
||||
* @param integer $percentage Pourcentage de chance de gagner le lot nombre de 1 à 100.
|
||||
* @param integer $web_coupon_identifiant EAN 13 format (Mais ne représente pas un EAN 13),
|
||||
* format utilisé dans MesBr.
|
||||
* @param string $picture Image locale du Coupon.
|
||||
* @param string $valid_on Text valable sur.. (duplicat de ce qui est inscrit dans MesBr)
|
||||
* Pour affichage sur la page de gain est dans le mail.
|
||||
* @param int $face_value Valeur faciale en centimes.
|
||||
* @param int $percentage Pourcentage de chance de gagner le lot nombre de 1 à 100.
|
||||
* @param int $web_coupon_identifiant EAN 13 format (Mais ne représente pas un EAN 13),
|
||||
* format utilisé dans MesBr.
|
||||
*
|
||||
* @return \App\Lib\Discount
|
||||
* @throws \RuntimeException If $type or $data is wrong.
|
||||
* @throws RuntimeException If $type or $data is wrong.
|
||||
*/
|
||||
public static function make(
|
||||
string $picture,
|
||||
|
|
@ -78,54 +82,42 @@ class Discount extends \stdClass implements Jsonable, Arrayable, \JsonSerializab
|
|||
$ipTypeData->valid_on = $valid_on;
|
||||
$ipTypeData->picture = $picture;
|
||||
self::assertIsInputTypeData($ipTypeData);
|
||||
|
||||
return $ipTypeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm $data is of type InputTypeData
|
||||
*
|
||||
* @param \App\Lib\Discount $data
|
||||
* @return void
|
||||
* @throws \RuntimeException If $data is wrong.
|
||||
*
|
||||
* @throws RuntimeException If $data is wrong.
|
||||
*/
|
||||
public static function assertIsInputTypeData(Discount $data)
|
||||
public static function assertIsInputTypeData(Discount $data): void
|
||||
{
|
||||
if (!\is_int($data->web_coupon_identifiant)) {
|
||||
throw new \RuntimeException("InputTypeData 'web_coupon_identifiant' should be an integer");
|
||||
}
|
||||
if (!\is_int($data->percentage)) {
|
||||
throw new \RuntimeException("InputTypeData 'percentage' should be an integer");
|
||||
}
|
||||
if (!\is_int($data->face_value)) {
|
||||
throw new \RuntimeException("InputTypeData 'face_value' should be an integer");
|
||||
}
|
||||
if (!\is_string($data->valid_on)) {
|
||||
throw new \RuntimeException("InputTypeData 'valid_on' should be a string");
|
||||
}
|
||||
if (!\is_string($data->picture)) {
|
||||
throw new \RuntimeException("InputTypeData 'picture' should be a string");
|
||||
}
|
||||
throw_unless(\is_int($data->web_coupon_identifiant), RuntimeException::class, "InputTypeData 'web_coupon_identifiant' should be an integer");
|
||||
throw_unless(\is_int($data->percentage), RuntimeException::class, "InputTypeData 'percentage' should be an integer");
|
||||
throw_unless(\is_int($data->face_value), RuntimeException::class, "InputTypeData 'face_value' should be an integer");
|
||||
throw_unless(\is_string($data->valid_on), RuntimeException::class, "InputTypeData 'valid_on' should be a string");
|
||||
throw_unless(\is_string($data->picture), RuntimeException::class, "InputTypeData 'picture' should be a string");
|
||||
}
|
||||
|
||||
// * TRANSFORMERS
|
||||
|
||||
/**
|
||||
* Get the instance as an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return collect(Arr::mapWithKeys(self::$propertiesList, fn (string $property) => [
|
||||
$property => $this->{$property}
|
||||
return collect(Arr::mapWithKeys(self::$propertiesList, fn (string $property): array => [
|
||||
$property => $this->{$property},
|
||||
]))->filter()->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to its JSON representation.
|
||||
*
|
||||
* @param integer $options
|
||||
* @return string
|
||||
* @param int $options
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
||||
*/
|
||||
public function toJson($options = 0): string
|
||||
|
|
@ -139,7 +131,7 @@ class Discount extends \stdClass implements Jsonable, Arrayable, \JsonSerializab
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
#[ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
|
|
@ -11,10 +13,6 @@ class CollectionHelper
|
|||
{
|
||||
/**
|
||||
* Paginate a collection
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $results
|
||||
* @param integer $pageSize
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public static function paginate(Collection $results, int $pageSize): LengthAwarePaginator
|
||||
{
|
||||
|
|
@ -25,18 +23,13 @@ class CollectionHelper
|
|||
|
||||
/**
|
||||
* Paginate a collection
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $results
|
||||
* @param integer $pageSize
|
||||
* @param integer $page
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
public static function paginateManually(Collection $results, int $pageSize, int $page = 1): LengthAwarePaginator
|
||||
{
|
||||
$total = $results->count();
|
||||
|
||||
return self::paginator($results->forPage($page, $pageSize), $total, $pageSize, $page, [
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'path' => Paginator::resolveCurrentPath(),
|
||||
'pageName' => 'page',
|
||||
]);
|
||||
}
|
||||
|
|
@ -44,21 +37,16 @@ class CollectionHelper
|
|||
/**
|
||||
* Create a new length-aware paginator instance.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $items
|
||||
* @param integer $total
|
||||
* @param integer $perPage
|
||||
* @param integer $currentPage
|
||||
* @param array $options
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
* @return LengthAwarePaginator
|
||||
*/
|
||||
protected static function paginator(Collection $items, int $total, int $perPage, int $currentPage, array $options)
|
||||
{
|
||||
return Container::getInstance()->makeWith(LengthAwarePaginator::class, [
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'perPage' => $perPage,
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'perPage' => $perPage,
|
||||
'currentPage' => $currentPage,
|
||||
'options' => $options
|
||||
'options' => $options,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,55 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use Sentry\Event;
|
||||
use Sentry\ExceptionDataBag;
|
||||
use Sentry\Frame;
|
||||
use Sentry\Stacktrace;
|
||||
use Throwable;
|
||||
|
||||
class ExceptionsHelper
|
||||
{
|
||||
/**
|
||||
* Handle sentry event
|
||||
*
|
||||
* @param \Sentry\Event $event
|
||||
* @return null|\Sentry\Event
|
||||
*/
|
||||
public static function sentryEventHandler(\Sentry\Event $event): ?\Sentry\Event
|
||||
public static function sentryEventHandler(Event $event): ?Event
|
||||
{
|
||||
// Remove unwanted reports.
|
||||
$event->setModules([]);
|
||||
$event->setOsContext(null);
|
||||
|
||||
/** @var \Sentry\ExceptionDataBag[] */
|
||||
/** @var ExceptionDataBag[] */
|
||||
$exceptionBag = [];
|
||||
foreach ($event->getExceptions() as $exceptionDataBag) {
|
||||
$exceptionBag[] = self::getAnonymizedSentryException($exceptionDataBag);
|
||||
}
|
||||
$event->setExceptions($exceptionBag);
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Anonimize Sentry Exception bag
|
||||
*
|
||||
* @param \Sentry\ExceptionDataBag $exceptionDataBag
|
||||
* @return \Sentry\ExceptionDataBag
|
||||
*/
|
||||
private static function getAnonymizedSentryException(
|
||||
\Sentry\ExceptionDataBag $exceptionDataBag
|
||||
): \Sentry\ExceptionDataBag {
|
||||
ExceptionDataBag $exceptionDataBag
|
||||
): ExceptionDataBag {
|
||||
$exceptionDataBag->setValue(self::getAnonymizedMessage($exceptionDataBag->getValue()));
|
||||
if ($stackTrace = $exceptionDataBag->getStacktrace()) {
|
||||
if (($stackTrace = $exceptionDataBag->getStacktrace()) instanceof Stacktrace) {
|
||||
$exceptionDataBag->setStacktrace(self::getAnonymizedSentryStackTrace($stackTrace));
|
||||
}
|
||||
|
||||
return $exceptionDataBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Anonymise sentry stacktrace
|
||||
*
|
||||
* @param \Sentry\Stacktrace $stackTrace
|
||||
* @return \Sentry\Stacktrace
|
||||
*/
|
||||
private static function getAnonymizedSentryStackTrace(\Sentry\Stacktrace $stackTrace): \Sentry\Stacktrace
|
||||
private static function getAnonymizedSentryStackTrace(Stacktrace $stackTrace): Stacktrace
|
||||
{
|
||||
/** @var \Sentry\Frame[] */
|
||||
/** @var Frame[] */
|
||||
$frames = \array_reverse($stackTrace->getFrames(), true);
|
||||
$i = \count($frames) - 1;
|
||||
// * Remove all but keep first (index.php).
|
||||
|
|
@ -66,13 +67,14 @@ class ExceptionsHelper
|
|||
$stackTrace->removeFrame(count($stackTrace->getFrames()) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
return $stackTrace;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get anonymized sentry params
|
||||
*
|
||||
* @param mixed[] $params
|
||||
* @param mixed[] $params
|
||||
* @return string[]
|
||||
*/
|
||||
private static function getAnonymizedSentryParams(array $params): array
|
||||
|
|
@ -86,46 +88,44 @@ class ExceptionsHelper
|
|||
case $type === 'lambda':
|
||||
case $type === 'object':
|
||||
continue 2;
|
||||
case $type === 'array' and \is_array($param):
|
||||
case $type === 'array' && \is_array($param):
|
||||
$param = sprintf('Array(%d)', \count($param));
|
||||
|
||||
continue 2;
|
||||
default:
|
||||
if (\is_numeric($param)) {
|
||||
$param = \ucfirst($type);
|
||||
|
||||
continue 2;
|
||||
}
|
||||
if (\is_string($param)) {
|
||||
$param = sprintf('String(%d)', \strlen($param));
|
||||
|
||||
continue 2;
|
||||
}
|
||||
} //end switch
|
||||
} //end foreach
|
||||
} // end switch
|
||||
} // end foreach
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Anonymize at least Sql queries
|
||||
*
|
||||
* @param string $message
|
||||
* @return string
|
||||
*/
|
||||
public static function getAnonymizedMessage(string $message): string
|
||||
{
|
||||
$message = \preg_replace('/^(.*)( \(SQL:.*\))$/', '$1', $message) ?? $message;
|
||||
if ($sqlPos = \strpos($message, 'to use near')) {
|
||||
$message = \mb_strcut($message, 0, $sqlPos);
|
||||
return \mb_strcut($message, 0, $sqlPos);
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Anonymize stack trace
|
||||
*
|
||||
* @param \Throwable $e
|
||||
* @return string
|
||||
*/
|
||||
public static function getAnonymizedStackTrace(\Throwable $e): string
|
||||
public static function getAnonymizedStackTrace(Throwable $e): string
|
||||
{
|
||||
$projectPath = \realpath(\sprintf('%s/../', \app_path()));
|
||||
$traceStack = $e->getTrace();
|
||||
|
|
@ -152,17 +152,15 @@ class ExceptionsHelper
|
|||
}
|
||||
$traceStr .= ")\n";
|
||||
}
|
||||
} //end foreach
|
||||
} // end foreach
|
||||
$maxStackStage++;
|
||||
$traceStr .= "#$maxStackStage {main}";
|
||||
|
||||
return $traceStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Args
|
||||
*
|
||||
* @param array $stack
|
||||
* @return string
|
||||
*/
|
||||
public static function handleArgs(array $stack): string
|
||||
{
|
||||
|
|
@ -170,21 +168,15 @@ class ExceptionsHelper
|
|||
$argsCount = count($stack['args']);
|
||||
for ($i = 0; $i < $argsCount; $i++) {
|
||||
$type = \gettype($stack['args'][$i]);
|
||||
switch ($type) {
|
||||
case 'object':
|
||||
$traceArgs .= sprintf('Object(%s)', \get_class($stack['args'][$i]));
|
||||
break;
|
||||
case 'array':
|
||||
$traceArgs .= sprintf('Array(%d)', \count($stack['args'][$i]));
|
||||
break;
|
||||
case 'string':
|
||||
$traceArgs .= sprintf('String(%d)', \strlen($stack['args'][$i]));
|
||||
break;
|
||||
default:
|
||||
$traceArgs .= \gettype($stack['args'][$i]);
|
||||
}
|
||||
match ($type) {
|
||||
'object' => $traceArgs .= sprintf('Object(%s)', $stack['args'][$i]::class),
|
||||
'array' => $traceArgs .= sprintf('Array(%d)', \count($stack['args'][$i])),
|
||||
'string' => $traceArgs .= sprintf('String(%d)', \strlen($stack['args'][$i])),
|
||||
default => $traceArgs .= \gettype($stack['args'][$i]),
|
||||
};
|
||||
$traceArgs .= ($i !== ($argsCount - 1) ? ',' : '');
|
||||
}
|
||||
|
||||
return $traceArgs;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,17 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use RuntimeException;
|
||||
use SplFileInfo;
|
||||
|
||||
/**
|
||||
* This class is used to handle files in LDC Laravel stack
|
||||
|
|
@ -33,28 +39,25 @@ class FileStorageHelper
|
|||
/**
|
||||
* Remove all files from string attribute html that are stored in public
|
||||
*
|
||||
* @param string $publicStorageFilePath The file path from public directory.
|
||||
* @param string $publicStorageFilePath The file path from public directory.
|
||||
* @return string The local storage path.
|
||||
*/
|
||||
public static function getFileFullPath(string $publicStorageFilePath): string
|
||||
{
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
/** @var FilesystemAdapter */
|
||||
$disk = Storage::disk('public');
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
|
||||
return $disk->path($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the file associate with the attribute.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $attribute
|
||||
* @return void
|
||||
*/
|
||||
public static function removeFile(Model $model, string $attribute): void
|
||||
{
|
||||
$path = \ltrim(\urldecode($model->{$attribute}), '/');
|
||||
if (\strpos($path, 'storage') !== 0) {
|
||||
if (! str_starts_with($path, 'storage')) {
|
||||
return;
|
||||
}
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', $path);
|
||||
|
|
@ -65,20 +68,15 @@ class FileStorageHelper
|
|||
|
||||
/**
|
||||
* Destroy the file associate with the attribute old value (before updated to DB).
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $attribute
|
||||
* @param boolean $onlyIfUpdated
|
||||
* @return void
|
||||
*/
|
||||
public static function removeOldFile(Model $model, string $attribute, bool $onlyIfUpdated = true): void
|
||||
{
|
||||
// * Ignore If removal has to be done only if the field has changed and it actually hasnt.
|
||||
if ($onlyIfUpdated and $model->{$attribute} === ToolboxHelper::getOriginal($model, $attribute)) {
|
||||
if ($onlyIfUpdated && $model->{$attribute} === ToolboxHelper::getOriginal($model, $attribute)) {
|
||||
return;
|
||||
}
|
||||
$originalPath = \ltrim(\urldecode(ToolboxHelper::getOriginal($model, $attribute)), '/');
|
||||
if (\strpos($originalPath, 'storage') !== 0) {
|
||||
if (! str_starts_with($originalPath, 'storage')) {
|
||||
return;
|
||||
}
|
||||
$originalPath = ToolboxHelper::mbReplace('storage/', '', $originalPath);
|
||||
|
|
@ -92,37 +90,39 @@ class FileStorageHelper
|
|||
*
|
||||
* You can use filename param to overload file name.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model The model that will hold the picture.
|
||||
* @param \Illuminate\Http\UploadedFile|\SplFileInfo|string $file The file, will just return itself is string.
|
||||
* @param boolean $slugify Force filename slugification.
|
||||
* @param string|null $filename This string may be used to store the file.
|
||||
* @param boolean $private To store the file in a private space.
|
||||
* @return string
|
||||
* @throws \RuntimeException If file copy fails.
|
||||
* @param Model $model The model that will hold the picture.
|
||||
* @param UploadedFile|SplFileInfo|string $file The file, will just return itself is string.
|
||||
* @param bool $slugify Force filename slugification.
|
||||
* @param string|null $filename This string may be used to store the file.
|
||||
* @param bool $private To store the file in a private space.
|
||||
*
|
||||
* @throws RuntimeException If file copy fails.
|
||||
*
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
public static function storeFile(
|
||||
Model $model,
|
||||
$file,
|
||||
bool $slugify = false,
|
||||
string $filename = null,
|
||||
?string $filename = null,
|
||||
bool $private = false
|
||||
): string {
|
||||
// phpcs:enable
|
||||
$tableName = $model->getTable();
|
||||
if (\is_object($file) and $file instanceof \Illuminate\Http\UploadedFile) {
|
||||
/** @var \Illuminate\Http\UploadedFile $file */
|
||||
if ($file instanceof UploadedFile) {
|
||||
/** @var UploadedFile $file */
|
||||
$filename = $filename ?: $file->getClientOriginalName();
|
||||
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
|
||||
$newPath = self::prepareMoveFile($tableName, $filename, $private);
|
||||
$newPath = str_replace(storage_path('app'), '', $newPath);
|
||||
|
||||
if (!$private) {
|
||||
if (! $private) {
|
||||
// * Store public file.
|
||||
$file->storePubliclyAs(
|
||||
pathinfo($newPath, \PATHINFO_DIRNAME),
|
||||
pathinfo($newPath, \PATHINFO_BASENAME)
|
||||
);
|
||||
|
||||
return 'storage' . str_replace('/public', '', $newPath);
|
||||
}
|
||||
|
||||
|
|
@ -132,23 +132,25 @@ class FileStorageHelper
|
|||
);
|
||||
|
||||
return str_replace('/private/', '', $newPath);
|
||||
} //end if
|
||||
if (\is_object($file) and $file instanceof \SplFileInfo) {
|
||||
/** @var \SplFileInfo $file */
|
||||
} // end if
|
||||
if ($file instanceof SplFileInfo) {
|
||||
/** @var SplFileInfo $file */
|
||||
$filename = $filename ?: $file->getBaseName();
|
||||
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
|
||||
$newPath = self::prepareMoveFile($tableName, $filename, $private);
|
||||
if (!File::copy($file->getRealPath(), $newPath)) {
|
||||
throw new \RuntimeException(sprintf(
|
||||
if (! File::copy($file->getRealPath(), $newPath)) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'Failed to copy file %s to %s',
|
||||
$file->getRealPath(),
|
||||
$newPath
|
||||
));
|
||||
}
|
||||
|
||||
return $private ?
|
||||
\ltrim(str_replace(\storage_path('app/private'), '/storage/app/private', $newPath), '/') :
|
||||
\ltrim(str_replace(\storage_path('app/public'), '/storage', $newPath), '/');
|
||||
}
|
||||
|
||||
return strval($file);
|
||||
}
|
||||
|
||||
|
|
@ -157,22 +159,22 @@ class FileStorageHelper
|
|||
* If oldHtmlString is passed, a diff is done with new and old files
|
||||
* to keep only files that are present in the new html string.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model The model that will hold the picture.
|
||||
* @param string $htmlString The html string to parse and modify files.
|
||||
* @param string|null $oldHtmlString The old html string with alreadyParsed
|
||||
* files using storeModelFilesFromHtml.
|
||||
* @param Model $model The model that will hold the picture.
|
||||
* @param string $htmlString The html string to parse and modify files.
|
||||
* @param string|null $oldHtmlString The old html string with alreadyParsed
|
||||
* files using storeModelFilesFromHtml.
|
||||
* @return string Html with files pathes replaced using storage strategy.
|
||||
*/
|
||||
public static function storeModelFilesFromHtml(
|
||||
Model $model,
|
||||
string $htmlString,
|
||||
string $oldHtmlString = null
|
||||
?string $oldHtmlString = null
|
||||
): string {
|
||||
\collect(self::onlyUploadedFilesWithFileManager(self::findFilesInHtml($htmlString)))
|
||||
->each(function (string $path) use ($model, &$htmlString) {
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
->each(function (string $path) use ($model, &$htmlString): void {
|
||||
/** @var FilesystemAdapter */
|
||||
$disk = Storage::disk('uploads');
|
||||
$fileInfo = new \SplFileInfo($disk->path(
|
||||
$fileInfo = new SplFileInfo($disk->path(
|
||||
ToolboxHelper::mbReplace('/uploads/', '', \urldecode($path))
|
||||
));
|
||||
$htmlString = ToolboxHelper::mbReplace(
|
||||
|
|
@ -193,9 +195,8 @@ class FileStorageHelper
|
|||
* Remove all old files from string attribute html that are stored in public that
|
||||
* are nove present anymore on new html string
|
||||
*
|
||||
* @param string $newHtmlString The html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
* @param string $oldHtmlString The old html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
* @return void
|
||||
* @param string $newHtmlString The html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
* @param string $oldHtmlString The old html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
*/
|
||||
public static function removeOldModelFilesFromHtml(string $newHtmlString, string $oldHtmlString): void
|
||||
{
|
||||
|
|
@ -206,16 +207,15 @@ class FileStorageHelper
|
|||
* Remove all old files that are stored in public that
|
||||
* are not present anymore on new array files
|
||||
*
|
||||
* @param string[] $oldFiles The old array files.
|
||||
* @param string[] $newFiles The new array files.
|
||||
* @return void
|
||||
* @param string[] $oldFiles The old array files.
|
||||
* @param string[] $newFiles The new array files.
|
||||
*/
|
||||
public static function removeOldFiles(array $oldFiles, array $newFiles): void
|
||||
{
|
||||
$oldFiles = \collect(self::onlyUploadedFilesWithFileStorageHelper($oldFiles));
|
||||
$filesToKeep = \collect(self::onlyUploadedFilesWithFileStorageHelper($newFiles));
|
||||
$filesToRemove = $oldFiles->diff($filesToKeep);
|
||||
$filesToRemove->each(function (string $publicStorageFilePath) {
|
||||
$filesToRemove->each(function (string $publicStorageFilePath): void {
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
|
|
@ -226,13 +226,12 @@ class FileStorageHelper
|
|||
/**
|
||||
* Remove all files from string attribute html that are stored in public
|
||||
*
|
||||
* @param string $htmlString The html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
* @return void
|
||||
* @param string $htmlString The html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
*/
|
||||
public static function removeModelFilesOfHtml(string $htmlString): void
|
||||
{
|
||||
$filesToRemove = \collect(self::onlyUploadedFilesWithFileStorageHelper(self::findFilesInHtml($htmlString)));
|
||||
$filesToRemove->each(function (string $publicStorageFilePath) {
|
||||
$filesToRemove->each(function (string $publicStorageFilePath): void {
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
|
|
@ -242,13 +241,11 @@ class FileStorageHelper
|
|||
|
||||
/**
|
||||
* Find all occurence of files in html
|
||||
*
|
||||
* @param string $html
|
||||
* @return array
|
||||
*/
|
||||
public static function findFilesInHtml(string $html): array
|
||||
{
|
||||
preg_match_all('/href="(?P<href>.*)"|src="(?P<src>.*)"|url="(?P<url>.*)"/Um', $html, $m, PREG_SET_ORDER, 0);
|
||||
|
||||
return collect($m)->pluck('href')->filter()
|
||||
->concat(collect($m)->pluck('url')->filter())
|
||||
->concat(collect($m)->pluck('src')->filter())
|
||||
|
|
@ -258,19 +255,18 @@ class FileStorageHelper
|
|||
/**
|
||||
* Filter array to get only uploaded files that exists
|
||||
* on disk 'public' (using helper storage strategy)
|
||||
*
|
||||
* @param array $urls
|
||||
* @return array
|
||||
*/
|
||||
public static function onlyUploadedFilesWithFileStorageHelper(array $urls): array
|
||||
{
|
||||
return \collect($urls)->unique()
|
||||
// * Filter to get only /uploads and using app url or empty
|
||||
->filter(function (string $url) {
|
||||
->filter(function (string $url): bool {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return \strpos(\ltrim($path, '/'), 'storage/modelfiles') === 0;
|
||||
|
||||
return str_starts_with(\ltrim($path, '/'), 'storage/modelfiles');
|
||||
})->filter(function (string $url) {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
|
||||
return Storage::disk('public')
|
||||
->exists(ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($path), '/')));
|
||||
})->all();
|
||||
|
|
@ -279,21 +275,19 @@ class FileStorageHelper
|
|||
/**
|
||||
* Filter array to get only uploaded files that exists
|
||||
* on disk 'uploads'
|
||||
*
|
||||
* @param array $urls
|
||||
* @return array
|
||||
*/
|
||||
private static function onlyUploadedFilesWithFileManager(array $urls): array
|
||||
{
|
||||
return \collect($urls)->unique()
|
||||
// * Filter to get only /uploads and using app url or empty
|
||||
->filter(function (string $url) {
|
||||
->filter(function (string $url): bool {
|
||||
$host = \parse_url($url, \PHP_URL_HOST);
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
return ($host === \parse_url(config('app.url'), PHP_URL_HOST) or \is_null($host)) and
|
||||
\strpos(\ltrim($path, '/'), 'uploads') === 0;
|
||||
|
||||
return ($host === \parse_url(config('app.url'), PHP_URL_HOST) || \is_null($host)) && str_starts_with(\ltrim($path, '/'), 'uploads');
|
||||
})->filter(function (string $url) {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
|
||||
return Storage::disk('uploads')
|
||||
->exists(ToolboxHelper::mbReplace('uploads/', '', \ltrim(\urldecode($path), '/')));
|
||||
})->all();
|
||||
|
|
@ -303,10 +297,9 @@ class FileStorageHelper
|
|||
* Prepare storage path and return
|
||||
* the file full path
|
||||
*
|
||||
* @param string $tableName Model table name.
|
||||
* @param string $filename The basename for the file.
|
||||
* @param boolean $private May the file be stored in a private dir.
|
||||
* @return string
|
||||
* @param string $tableName Model table name.
|
||||
* @param string $filename The basename for the file.
|
||||
* @param bool $private May the file be stored in a private dir.
|
||||
*/
|
||||
private static function prepareMoveFile(string $tableName, string $filename, bool $private = false): string
|
||||
{
|
||||
|
|
@ -325,6 +318,7 @@ class FileStorageHelper
|
|||
$filename,
|
||||
);
|
||||
$filename = self::getFileUniqueName($folderPath, $filename);
|
||||
|
||||
return "{$folderPath}/{$filename}";
|
||||
}
|
||||
|
||||
|
|
@ -332,11 +326,6 @@ class FileStorageHelper
|
|||
* Create sub folders to store files using pattern
|
||||
* storage/modelfiles/posts/10/04/19/5f
|
||||
* year/month/day/md5 first 2 letters
|
||||
*
|
||||
* @param string $storage_dir
|
||||
* @param string $table
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
private static function getStoragePath(string $storage_dir, string $table, string $filename): string
|
||||
{
|
||||
|
|
@ -350,40 +339,34 @@ class FileStorageHelper
|
|||
gmdate('d'),
|
||||
substr($filenameHash, 0, 2)
|
||||
));
|
||||
if (!File::exists($pathFolder)) {
|
||||
if (! File::exists($pathFolder)) {
|
||||
File::makeDirectory($pathFolder, 0755, true);
|
||||
}
|
||||
|
||||
return $pathFolder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique filename if the path is already occupied
|
||||
*
|
||||
* @param string $folderPath
|
||||
* @param string $filename
|
||||
* @return string
|
||||
* @throws \RuntimeException If a unique filename cannot be obtained.
|
||||
* @throws RuntimeException If a unique filename cannot be obtained.
|
||||
*/
|
||||
private static function getFileUniqueName(string $folderPath, string $filename): string
|
||||
{
|
||||
$attempts = 0;
|
||||
$maxAttempts = 20;
|
||||
while (File::exists("{$folderPath}/{$filename}")) {
|
||||
if ($attempts++ >= $maxAttempts) {
|
||||
throw new \RuntimeException("Failed to have a unique filename for {$folderPath}/{$filename}");
|
||||
}
|
||||
throw_if($attempts++ >= $maxAttempts, RuntimeException::class, "Failed to have a unique filename for {$folderPath}/{$filename}");
|
||||
$filename = pathinfo($filename, \PATHINFO_FILENAME) .
|
||||
\uniqid('-') . '.' .
|
||||
pathinfo($filename, \PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Slugify the filename
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public static function slugifyFileName(string $filename): string
|
||||
{
|
||||
|
|
@ -393,8 +376,8 @@ class FileStorageHelper
|
|||
/**
|
||||
* Sanitize File name for uploaded files
|
||||
*
|
||||
* @param string $filename The original uploaded client file name.
|
||||
* @param boolean $beautify Beautify the filename.
|
||||
* @param string $filename The original uploaded client file name.
|
||||
* @param bool $beautify Beautify the filename.
|
||||
* @return string The sanitized file name.
|
||||
*/
|
||||
public static function sanitizeFileName(string $filename, bool $beautify = true): string
|
||||
|
|
@ -417,7 +400,7 @@ class FileStorageHelper
|
|||
$filename = Str::of($filename)->ltrim('.-');
|
||||
// * Optional beautification
|
||||
if ($beautify) {
|
||||
$filename = self::beautifyFilename($filename);
|
||||
$filename = self::beautifyFilename($filename->value());
|
||||
}
|
||||
// * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
||||
/** @var string */
|
||||
|
|
@ -426,20 +409,18 @@ class FileStorageHelper
|
|||
$filename = pathinfo($filename, \PATHINFO_FILENAME);
|
||||
|
||||
$encoding = mb_detect_encoding($filename);
|
||||
$encoding = $encoding ? $encoding : null;
|
||||
$encoding = $encoding ?: null;
|
||||
|
||||
return \mb_strcut(
|
||||
$filename,
|
||||
0,
|
||||
255 - (!empty($extension) ? strlen($extension) + 1 : 0),
|
||||
255 - (! empty($extension) ? strlen($extension) + 1 : 0),
|
||||
$encoding
|
||||
) . (!empty($extension) ? ".$extension" : '');
|
||||
) . (! empty($extension) ? ".$extension" : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Beautify a filename
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
private static function beautifyFilename(string $filename): string
|
||||
{
|
||||
|
|
@ -450,18 +431,19 @@ class FileStorageHelper
|
|||
// * "file___name.zip" becomes 'file-name.zip'
|
||||
'/_+/',
|
||||
// * "file---name.zip" becomes 'file-name.zip'
|
||||
'/-+/'
|
||||
'/-+/',
|
||||
], '-', $filename);
|
||||
$filename = preg_replace([
|
||||
// * "file--.--.-.--name.zip" becomes "file.name.zip"
|
||||
'/-*\.-*/',
|
||||
// * "file...name..zip" becomes "file.name.zip"
|
||||
'/\.{2,}/'
|
||||
'/\.{2,}/',
|
||||
], '.', $filename);
|
||||
// Lowercase for windows/unix interoperability http://support.microsoft.com/kb/100625 .
|
||||
$filename = mb_strtolower($filename, mb_detect_encoding($filename));
|
||||
// * ".file-name.-" becomes "file-name"
|
||||
$filename = trim($filename, '.-');
|
||||
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,75 +1,84 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Carbon\Carbon;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Process\Exceptions\ProcessTimedOutException;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Date;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Process;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Process\Exception\LogicException;
|
||||
|
||||
class ToolboxHelper
|
||||
{
|
||||
/**
|
||||
* Run a terminal command and gives the output
|
||||
* Run a terminal command and gives the output.
|
||||
*
|
||||
* @param array|string $command The command to execute on terminal.
|
||||
* @param boolean $throw Wether to throw en esception on failure or not.
|
||||
* @param array|string $command The command to execute on terminal.
|
||||
* @param bool $throw Wether to throw en esception on failure or not.
|
||||
* @return string|false Return false on failure only if $throw is false.
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
* @throws \Illuminate\Process\Exceptions\ProcessTimedOutException
|
||||
* @throws \Symfony\Component\Process\Exception\LogicException
|
||||
* @throws \Symfony\Component\Process\Exception\InvalidArgumentException
|
||||
*
|
||||
* @throws ProcessTimedOutException
|
||||
* @throws LogicException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws \Symfony\Component\Process\Exception\RuntimeException
|
||||
* @throws \LogicException
|
||||
* @throws \RuntimeException If the command fails.
|
||||
* @throws RuntimeException If the command fails.
|
||||
*/
|
||||
public static function runConsoleCommand(array|string $command, bool $throw = true): string | false
|
||||
public static function runConsoleCommand(array | string $command, bool $throw = true): string | false
|
||||
{
|
||||
// phpcs:enable
|
||||
$process = \Illuminate\Support\Facades\Process::command($command)->run();
|
||||
$process = Process::command($command)->run();
|
||||
if ($process->failed()) {
|
||||
$code = $process->exitCode();
|
||||
$ouput = $process->errorOutput();
|
||||
if ($throw) {
|
||||
throw new \RuntimeException("Failed to run command exit code {$code} with output \n{$ouput}");
|
||||
}
|
||||
throw_if($throw, RuntimeException::class, "Failed to run command exit code {$code} with output \n{$ouput}");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return $process->output();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert game is not oppened
|
||||
* Assert game is not oppened.
|
||||
*
|
||||
* @return void
|
||||
* @throws \RuntimeException If game has started.
|
||||
* @throws RuntimeException If game has started.
|
||||
*/
|
||||
public static function assertGameIsNotOppened(): void
|
||||
{
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if ($settings->game_is_open) {
|
||||
throw new \RuntimeException('Cannot delete prize while game is oppened');
|
||||
}
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
throw_if($settings->game_is_open, RuntimeException::class, 'Cannot delete prize while game is oppened');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int|string, mixed> $array1
|
||||
* @param array<int|string, mixed> $array2
|
||||
*
|
||||
* @param array<int|string, mixed> $array1
|
||||
* @param array<int|string, mixed> $array2
|
||||
* @return array<int|string, mixed>
|
||||
*/
|
||||
public static function arrayMergeRecursiveDistinct(array &$array1, array &$array2): array
|
||||
|
|
@ -87,89 +96,69 @@ class ToolboxHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Validate recaptcha
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param boolean $isV3
|
||||
* @return void
|
||||
* Validate recaptcha.
|
||||
*/
|
||||
public static function validateRecaptcha(Request $request, bool $isV3 = true)
|
||||
public static function validateRecaptcha(Request $request, bool $isV3 = true): void
|
||||
{
|
||||
Validator::validate($request->all(), [
|
||||
'g-recaptcha-response' => [
|
||||
'required', 'string',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed, Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) use ($isV3) {
|
||||
// @phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed, Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) use ($isV3): void {
|
||||
try {
|
||||
$response = Http::asForm()->post('https://www.google.com/recaptcha/api/siteverify', [
|
||||
'secret' => config('services.google.recaptcha.private'),
|
||||
'secret' => config('services.google.recaptcha.private'),
|
||||
'response' => \strval($value),
|
||||
'remoteip' => app('clientIp')
|
||||
'remoteip' => resolve('clientIp'),
|
||||
]);
|
||||
if ($e = $response->toException()) {
|
||||
throw $e;
|
||||
}
|
||||
throw_if($e = $response->toException(), $e);
|
||||
if ($isV3) {
|
||||
if (
|
||||
!$response->json('success') or
|
||||
!$response->json('challenge_ts') or
|
||||
Carbon::parse($response->json('challenge_ts'))->lessThan(\now('utc')->subMinutes(5)) or
|
||||
$response->json('hostname') !== \parse_url(config('app.url'), \PHP_URL_HOST) or
|
||||
!$response->json('score')
|
||||
) {
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
throw_if(! $response->json('success')
|
||||
|| ! $response->json('challenge_ts')
|
||||
|| Date::parse($response->json('challenge_ts'))->lessThan(\now('utc')->subMinutes(5))
|
||||
|| $response->json('hostname') !== \parse_url(config('app.url'), \PHP_URL_HOST)
|
||||
|| ! $response->json('score'), RuntimeException::class);
|
||||
if (\floatval($response->json('score')) < 0.8) {
|
||||
$fail(trans('recaptcha.not_enough_score'));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!$response->json('success') or
|
||||
!$response->json('challenge_ts') or
|
||||
Carbon::parse($response->json('challenge_ts'))->lessThan(\now('utc')->subMinutes(5)) or
|
||||
$response->json('hostname') !== \parse_url(config('app.url'), \PHP_URL_HOST)
|
||||
) {
|
||||
throw new \RuntimeException();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
throw_if(! $response->json('success')
|
||||
|| ! $response->json('challenge_ts')
|
||||
|| Date::parse($response->json('challenge_ts'))->lessThan(\now('utc')->subMinutes(5))
|
||||
|| $response->json('hostname') !== \parse_url(config('app.url'), \PHP_URL_HOST), RuntimeException::class);
|
||||
} catch (Exception) {
|
||||
$fail(trans('recaptcha.error'));
|
||||
} //end try
|
||||
}
|
||||
]
|
||||
} // end try
|
||||
},
|
||||
],
|
||||
], [], ['g-recaptcha-response' => 'reCaptcha']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip scheme (https) on oembed urls
|
||||
* Strip scheme (https) on oembed urls.
|
||||
* Only embed allowed are for MP4 self hosted videos right now
|
||||
*
|
||||
* https is force by ckeditor MediaElements which natively supports
|
||||
* only cloud hosted medias (youtube, spotify etc..)
|
||||
*
|
||||
* @param string $input
|
||||
* @return string
|
||||
*/
|
||||
public static function stripCkEditorSchemesOnMediaInputs(string $input): string
|
||||
{
|
||||
$input = \preg_replace('/(?<=<oembed url=")(https:\/\/)(?=.*?">)/m', '', $input);
|
||||
return $input;
|
||||
return \preg_replace('/(?<=<oembed url=")(https:\/\/)(?=.*?">)/m', '', $input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That no Back Office url is present on txt
|
||||
* Assert That no Back Office url is present on txt.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
* @throws ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalBoUrls(string $field, string $text): string
|
||||
{
|
||||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'/(?P<url>(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))/',
|
||||
function ($matches) use ($routes, $field) {
|
||||
$match = collect($matches)->first() ?? '';
|
||||
|
|
@ -178,34 +167,33 @@ class ToolboxHelper
|
|||
$request = Request::create($url);
|
||||
// If a route is match then it do not throws exception.
|
||||
if (
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST) &&
|
||||
trim($routes->match($request)->getPrefix() ?? '', '/') === 'bo'
|
||||
\parse_url(config('app.url'), \PHP_URL_HOST) === \parse_url($url, \PHP_URL_HOST)
|
||||
&& trim($routes->match($request)->getPrefix() ?? '', '/') === 'bo'
|
||||
) {
|
||||
// Removes the matched url.
|
||||
throw ValidationException::withMessages([
|
||||
$field => trans(
|
||||
'crud.libs.toolbox.assertNoInternalBoUrls',
|
||||
['attribute' => $field]
|
||||
)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
return $match;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
} catch (NotFoundHttpException) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That only external url is present on txt
|
||||
* Assert That only external url is present on txt.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
* @throws ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalUrls(string $field, string $text): string
|
||||
{
|
||||
|
|
@ -213,7 +201,7 @@ class ToolboxHelper
|
|||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
'/(?P<url>(?:http[s]?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@%._\+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_\+.~#?&\/\/=]*))/',
|
||||
function ($matches) use ($routes, $field) {
|
||||
$match = collect($matches)->first() ?? '';
|
||||
|
|
@ -229,35 +217,31 @@ class ToolboxHelper
|
|||
$field => trans(
|
||||
'crud.libs.toolbox.assertNoInternalUrls',
|
||||
['attribute' => $field, 'appname' => config('app.name')]
|
||||
)
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
return $match;
|
||||
} catch (NotFoundHttpException $e) {
|
||||
} catch (NotFoundHttpException) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutltibyte string replace
|
||||
*
|
||||
* @param array|string $search
|
||||
* @param array|string $replace
|
||||
* @param array|string $subject
|
||||
* @param integer $count
|
||||
* @return array|string|false
|
||||
* Mutltibyte string replace.
|
||||
*/
|
||||
public static function mbReplace(
|
||||
array|string $search,
|
||||
array|string $replace,
|
||||
array|string $subject,
|
||||
array | string $search,
|
||||
array | string $replace,
|
||||
array | string $subject,
|
||||
int &$count = 0
|
||||
): array|string|false {
|
||||
if (!is_array($search) && is_array($replace)) {
|
||||
): array | string | false {
|
||||
if (! is_array($search) && is_array($replace)) {
|
||||
return false;
|
||||
}
|
||||
if (is_array($subject)) {
|
||||
|
|
@ -266,7 +250,7 @@ class ToolboxHelper
|
|||
$string = &self::mbReplace($search, $replace, $string, $count);
|
||||
}
|
||||
} elseif (is_array($search)) {
|
||||
if (!is_array($replace)) {
|
||||
if (! is_array($replace)) {
|
||||
foreach ($search as &$string) {
|
||||
$subject = self::mbReplace($string, $replace, $subject, $count);
|
||||
}
|
||||
|
|
@ -280,37 +264,37 @@ class ToolboxHelper
|
|||
}
|
||||
} else {
|
||||
$parts = mb_split(preg_quote($search), $subject);
|
||||
// @phpstan-ignore-next-line
|
||||
$count = count($parts) - 1;
|
||||
$subject = implode($replace, $parts);
|
||||
} //end if
|
||||
} // end if
|
||||
|
||||
return $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the field is unique
|
||||
* Asserts that the field is unique.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $field
|
||||
* @param string|integer|float|boolean|null|array $value
|
||||
* @param integer|null $id
|
||||
* @param callable|null $query
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If the field is not unique.
|
||||
*
|
||||
* @throws ValidationException If the field is not unique.
|
||||
*/
|
||||
public static function assertFieldIsUnique(
|
||||
string $table,
|
||||
string $field,
|
||||
string|int|float|bool|null|array $value,
|
||||
string | int | float | bool | null | array $value,
|
||||
?int $id = null,
|
||||
?callable $query = null
|
||||
) {
|
||||
if (!$query) {
|
||||
): void {
|
||||
if (! $query) {
|
||||
Validator::make([$field => $value], [
|
||||
self::mbReplace('.', '\.', $field) => Rule::unique($table, $field)->ignore($id),
|
||||
], [
|
||||
self::mbReplace('.', '\.', "{$field}.unique")
|
||||
=> trans('crud.libs.toolbox.assertFieldIsUnique', ['attribute' => $field, 'value' => $value])
|
||||
self::mbReplace('.', '\.', "{$field}.unique") => trans('crud.libs.toolbox.assertFieldIsUnique', [
|
||||
'attribute' => $field,
|
||||
'value' => $value,
|
||||
]),
|
||||
])->validate();
|
||||
|
||||
return;
|
||||
}
|
||||
Validator::make([$field => $value], [
|
||||
|
|
@ -319,16 +303,12 @@ class ToolboxHelper
|
|||
$field . '.unique' => trans(
|
||||
'crud.libs.toolbox.assertFieldIsUnique',
|
||||
['attribute' => $field, 'value' => $value]
|
||||
)
|
||||
),
|
||||
])->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get original polyfill with autotranslate behavior
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $attribute
|
||||
* @return mixed
|
||||
* Get original polyfill with autotranslate behavior.
|
||||
*/
|
||||
public static function getOriginal(Model $model, string $attribute): mixed
|
||||
{
|
||||
|
|
@ -342,17 +322,12 @@ class ToolboxHelper
|
|||
$model->useFallbackLocale()
|
||||
);
|
||||
}
|
||||
|
||||
return $model->getOriginal($attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamic model query
|
||||
*
|
||||
* @param string $defaultLocale
|
||||
* @param \Illuminate\Database\Eloquent\Builder $q
|
||||
* @param string $column
|
||||
* @param string $value
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
* Dynamic model query.
|
||||
*/
|
||||
public static function queryColumnWithLocales(
|
||||
string $defaultLocale,
|
||||
|
|
@ -362,17 +337,17 @@ class ToolboxHelper
|
|||
): Builder {
|
||||
$currentLocale = app()->currentLocale();
|
||||
$locales = collect(config('app.locales'))
|
||||
->mapWithKeys(fn (string $locale) => [$locale => $locale]);
|
||||
if (!$locales->has($defaultLocale)) {
|
||||
->mapWithKeys(fn (string $locale): array => [$locale => $locale]);
|
||||
if (! $locales->has($defaultLocale)) {
|
||||
// * Remove default locale.
|
||||
$locales->pull($defaultLocale);
|
||||
}
|
||||
if (!$locales->has($currentLocale)) {
|
||||
if (! $locales->has($currentLocale)) {
|
||||
// * Remove current locale.
|
||||
$locales->pull($currentLocale);
|
||||
}
|
||||
|
||||
return $q->where(function (Builder $q) use ($defaultLocale, $currentLocale, $locales, $column, $value) {
|
||||
return $q->where(function (Builder $q) use ($defaultLocale, $currentLocale, $locales, $column, $value): void {
|
||||
// * Query default locale
|
||||
$q->whereRaw("JSON_EXTRACT({$column}, '$.{$defaultLocale}') = '{$value}'");
|
||||
if ($defaultLocale !== $currentLocale) {
|
||||
|
|
@ -387,12 +362,7 @@ class ToolboxHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates an array from a dot separated string
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $value
|
||||
* @param string $separator
|
||||
* @return array
|
||||
* Generates an array from a dot separated string.
|
||||
*/
|
||||
public static function dotStringToNestedArray(string $path, mixed $value, string $separator = '.'): array
|
||||
{
|
||||
|
|
@ -402,85 +372,77 @@ class ToolboxHelper
|
|||
foreach ($keys as $key) {
|
||||
$arr = [$key => $arr];
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an object to array
|
||||
* Convert deeply an object to array.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return array
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
* @throws RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function objectToArray(mixed $input): array
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (!(is_object($input) or is_array($input))) {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
if (!is_object($input) && !is_array($input)) {
|
||||
throw new RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$ret = (array) $input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
$item = (is_object($item) || is_array($item)) ?
|
||||
self::objectToArray($item) : $item;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an array to object
|
||||
* Convert deeply an array to object.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return object
|
||||
* @throws \RuntimeException If $input var is a scalar value.
|
||||
* @throws RuntimeException If $input var is a scalar value.
|
||||
*/
|
||||
public static function arrayToObject(mixed $input): object
|
||||
{
|
||||
// Only process if it's an object or array being passed to the function.
|
||||
if (!(is_object($input) or is_array($input))) {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
if (!is_object($input) && !is_array($input)) {
|
||||
throw new RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$ret = (object) $input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
$item = (is_object($item) || is_array($item)) ?
|
||||
self::arrayToObject($item) : $item;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Validate picture
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|null $value
|
||||
* @param callable $fail
|
||||
* @param object $sizes
|
||||
* @return void
|
||||
* Validate picture.
|
||||
*/
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes)
|
||||
public static function validatePicture(string $attribute, ?string $value, callable $fail, object $sizes): void
|
||||
{
|
||||
if (!($useStorage = Storage::exists($value)) and !File::exists($value)) {
|
||||
if (! ($useStorage = Storage::exists($value)) && ! File::exists($value)) {
|
||||
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
||||
'attribute' => $attribute
|
||||
'attribute' => $attribute,
|
||||
]));
|
||||
|
||||
return;
|
||||
}
|
||||
/** @var string */
|
||||
$fileFullPath = self::getUploadedFileFullPath($value, $useStorage);
|
||||
if (
|
||||
!\in_array(self::getUploadedFileMimeType($value, $useStorage), [
|
||||
'image/jpeg', 'image/jpg', 'image/png', 'image/gif'
|
||||
! \in_array(self::getUploadedFileMimeType($value, $useStorage), [
|
||||
'image/jpeg', 'image/jpg', 'image/png', 'image/gif',
|
||||
])
|
||||
) {
|
||||
$fail(trans(':attribute doit être une image de type \'image/jpeg,image/jpg,image/png,image/gif\'', [
|
||||
'attribute' => $attribute
|
||||
'attribute' => $attribute,
|
||||
]));
|
||||
}
|
||||
if (!($dimensions = \getimagesize($fileFullPath))) {
|
||||
if (! ($dimensions = \getimagesize($fileFullPath))) {
|
||||
$fail(trans(':attribute impossible de valider les dimensions', [
|
||||
'attribute' => $attribute
|
||||
'attribute' => $attribute,
|
||||
]));
|
||||
} else {
|
||||
$width = intval($dimensions[0]);
|
||||
|
|
@ -499,60 +461,52 @@ class ToolboxHelper
|
|||
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minHeight}px");
|
||||
}
|
||||
|
||||
if (($width < $sizes->minWith) or ($width > $sizes->maxWith)) {
|
||||
if ($width < $sizes->minWith || $width > $sizes->maxWith) {
|
||||
$fail($xMessage);
|
||||
}
|
||||
if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) {
|
||||
if ($height < $sizes->minHeight || $height > $sizes->maxHeight) {
|
||||
$fail($yMessage);
|
||||
}
|
||||
} //end if
|
||||
} // end if
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file full path
|
||||
*
|
||||
* @param string $value
|
||||
* @param boolean $useStorage
|
||||
* @return string
|
||||
* Get the file full path.
|
||||
*/
|
||||
private static function getUploadedFileFullPath(string $value, bool $useStorage): string
|
||||
{
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
/** @var FilesystemAdapter */
|
||||
$disk = Storage::disk();
|
||||
return !$useStorage ? (realpath($value) ?: $value) : $disk->path($value);
|
||||
|
||||
return ! $useStorage ? (realpath($value) ?: $value) : $disk->path($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file mimetype
|
||||
* Get the file mimetype.
|
||||
*
|
||||
* @param string $value
|
||||
* @param boolean $useStorage
|
||||
* @return string|false
|
||||
*/
|
||||
private static function getUploadedFileMimeType(string $value, bool $useStorage)
|
||||
{
|
||||
return !$useStorage ? File::mimeType($value) : Storage::mimeType($value);
|
||||
return ! $useStorage ? File::mimeType($value) : Storage::mimeType($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch class list from a specific namespace
|
||||
* Fetch class list from a specific namespace.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @return array<string> An array of classe namespaces
|
||||
*/
|
||||
public static function getClassesUsingNamespace(string $namespace): array
|
||||
{
|
||||
return collect(File::files(\app_path(Str::of($namespace)->replaceFirst('\App', ''))))
|
||||
->filter(fn (SplFileInfo $splFileInfo) => $splFileInfo->getExtension() === 'php')
|
||||
return collect(File::files(\app_path(Str::of($namespace)->replaceFirst('\App', '')->value())))
|
||||
->filter(fn (SplFileInfo $splFileInfo): bool => $splFileInfo->getExtension() === 'php')
|
||||
->map(fn (SplFileInfo $splFileInfo) => Str::of($splFileInfo->getBasename())
|
||||
->replace('.' . $splFileInfo->getExtension(), '')->prepend("{$namespace}\\"))->all();
|
||||
->replace('.' . $splFileInfo->getExtension(), '')->prepend("{$namespace}\\")->value())->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all classes from a specific namespace that implement a specific interface
|
||||
* Get all classes from a specific namespace that implement a specific interface.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $interface
|
||||
* @return array<string> An array of classe namespaces
|
||||
*/
|
||||
public static function getClassesUsingInterface(string $namespace, string $interface): array
|
||||
|
|
@ -560,17 +514,12 @@ class ToolboxHelper
|
|||
return Arr::where(
|
||||
static::getClassesUsingNamespace($namespace),
|
||||
fn (string $class_namespace) => \collect(class_implements($class_namespace, true))->filter()
|
||||
->contains(fn (string $class_interface) => $class_interface === $interface)
|
||||
->contains(fn (string $class_interface): bool => $class_interface === $interface)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get validated pagination from request.
|
||||
*
|
||||
* @param integer $default
|
||||
* @param string $field
|
||||
* @param string $enumPath
|
||||
* @return integer
|
||||
*/
|
||||
public static function getValidatedEnum(int $default, string $field, string $enumPath): int
|
||||
{
|
||||
|
|
@ -579,7 +528,7 @@ class ToolboxHelper
|
|||
[$field => \request()->get($field)],
|
||||
[$field => new Enum($enumPath)]
|
||||
)->validated()[$field]);
|
||||
} catch (ValidationException $e) {
|
||||
} catch (ValidationException) {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
85
app/Lib/vendor/LDCWEB/MesBr.php
vendored
85
app/Lib/vendor/LDCWEB/MesBr.php
vendored
|
|
@ -7,17 +7,8 @@ use LDC\LDCCRM\Models\Customer;
|
|||
|
||||
class MesBr
|
||||
{
|
||||
private $endpoint;
|
||||
|
||||
private $refCamp;
|
||||
|
||||
private $refSite;
|
||||
|
||||
public function __construct($endpoint, $refCamp, $refSite)
|
||||
public function __construct(private $endpoint, private $refCamp, private $refSite)
|
||||
{
|
||||
$this->endpoint = $endpoint;
|
||||
$this->refCamp = $refCamp;
|
||||
$this->refSite = $refSite;
|
||||
}
|
||||
|
||||
public function createCustomer(string $hashcode, string $email, string $country)
|
||||
|
|
@ -43,70 +34,63 @@ class MesBr
|
|||
public function printCoupons(string $hashcode, array $coupons)
|
||||
{
|
||||
return $this->callApi("GET", '/coupons/print', [
|
||||
'refcamp' => $this->refCamp,
|
||||
'refcamp' => $this->refCamp,
|
||||
'hashcode' => $hashcode,
|
||||
'coupons' => implode(",", $coupons)
|
||||
'coupons' => implode(",", $coupons)
|
||||
]);
|
||||
}
|
||||
private function callApi($method, $url, $data = [], $path = '/api/v1')
|
||||
private function callApi(string $method, string $url, array $data = [], string $path = '/api/v1')
|
||||
{
|
||||
$url = $this->endpoint . $path . $url;
|
||||
$curl = curl_init();
|
||||
switch ($method) {
|
||||
case "POST":
|
||||
curl_setopt($curl, CURLOPT_POST, 1);
|
||||
if ($data) {
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
if ($data !== []) {
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
}
|
||||
break;
|
||||
case "PUT":
|
||||
case "DELETE":
|
||||
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
|
||||
if ($data) {
|
||||
if ($data !== []) {
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ($data) {
|
||||
if ($data !== []) {
|
||||
$url = sprintf("%s?%s", $url, http_build_query($data));
|
||||
}
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_COOKIESESSION, true);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
$result = curl_exec($curl);
|
||||
if (!curl_errno($curl)) {
|
||||
$http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||
if (!in_array($http_code, [200, 201])) {
|
||||
return (object)[
|
||||
'status' => 'KO',
|
||||
'code' => 500,
|
||||
'status' => 'KO',
|
||||
'code' => 500,
|
||||
'message' => 'Connection to API failed - Code HTTP : ' . $http_code
|
||||
];
|
||||
}
|
||||
} else {
|
||||
return (object)[
|
||||
'status' => 'KO',
|
||||
'code' => 500,
|
||||
'status' => 'KO',
|
||||
'code' => 500,
|
||||
'message' => 'Connection to API failed : ' . curl_error($curl)
|
||||
];
|
||||
}
|
||||
curl_close($curl);
|
||||
return json_decode($result);
|
||||
}
|
||||
|
||||
// * Added METHODS
|
||||
|
||||
/** .
|
||||
* Update panier
|
||||
*
|
||||
* @param \LDC\LDCCRM\Models\Customer $crm_customer
|
||||
* @param string $crm_customer_hashcode
|
||||
* @param string $ref_site
|
||||
* @param string $coupon_id
|
||||
* @param integer $quantity
|
||||
* @return array<string,string>
|
||||
* @return array<string,int|string>
|
||||
* 'status' => 'OK',
|
||||
* 'link' => URL,
|
||||
* 'verif' => URL,
|
||||
|
|
@ -120,16 +104,16 @@ class MesBr
|
|||
int $quantity = 1
|
||||
): array {
|
||||
$res = $this->callAPI("GET", "/updatebasket", [
|
||||
'refsite' => $ref_site,
|
||||
'refcamp' => $this->refCamp,
|
||||
'refsite' => $ref_site,
|
||||
'refcamp' => $this->refCamp,
|
||||
'refadherent' => $crm_customer_hashcode,
|
||||
'nom' => $crm_customer->lastname,
|
||||
'prenom' => $crm_customer->firstname,
|
||||
'email' => $crm_customer->email,
|
||||
'nom' => $crm_customer->lastname,
|
||||
'prenom' => $crm_customer->firstname,
|
||||
'email' => $crm_customer->email,
|
||||
'code_postal' => $crm_customer->postcode,
|
||||
'commune' => $crm_customer->city,
|
||||
'pays' => $this->getCountry($crm_customer->country),
|
||||
'panier' => "({$quantity}){$coupon_id}"
|
||||
'commune' => $crm_customer->city,
|
||||
'pays' => $this->getCountry($crm_customer->country),
|
||||
'panier' => "({$quantity}){$coupon_id}"
|
||||
], '');
|
||||
|
||||
if (!$res) {
|
||||
|
|
@ -148,10 +132,7 @@ class MesBr
|
|||
/** .
|
||||
* Update basket
|
||||
*
|
||||
* @param \LDC\LDCCRM\Models\Customer $crm_customer
|
||||
* @param string $coupon_id
|
||||
* @param integer $quantity
|
||||
* @return array<string,string>
|
||||
* @return array<string,int|string>
|
||||
* 'status' => 'OK',
|
||||
* 'ref' => 'Basket REF'
|
||||
*/
|
||||
|
|
@ -161,10 +142,10 @@ class MesBr
|
|||
int $quantity = 1
|
||||
): array {
|
||||
$res = $this->callAPI("GET", "/customer/basket/update", [
|
||||
'refsite' => $this->refSite,
|
||||
'refcamp' => $this->refCamp,
|
||||
'refsite' => $this->refSite,
|
||||
'refcamp' => $this->refCamp,
|
||||
'customer_hashcode' => $crm_customer->hashcode,
|
||||
'panier' => "({$quantity}){$coupon_id}"
|
||||
'panier' => "({$quantity}){$coupon_id}"
|
||||
]);
|
||||
|
||||
if (!$res) {
|
||||
|
|
@ -181,15 +162,14 @@ class MesBr
|
|||
|
||||
/**
|
||||
* Get customer basket
|
||||
*
|
||||
* @param \LDC\LDCCRM\Models\Customer $crm_customer
|
||||
* @return array
|
||||
*
|
||||
* @return array<string,int|string>
|
||||
*/
|
||||
public function getBasket(
|
||||
Customer $crm_customer,
|
||||
): array {
|
||||
$res = $this->callApi("GET", '/customer/basket', [
|
||||
'refcamp' => $this->refCamp,
|
||||
'refcamp' => $this->refCamp,
|
||||
'hashcode' => $crm_customer->hashcode
|
||||
]);
|
||||
|
||||
|
|
@ -208,15 +188,12 @@ class MesBr
|
|||
|
||||
/**
|
||||
* Translate country to MesBr Country
|
||||
*
|
||||
* @param \LDC\LDCCRM\Enums\Country $country
|
||||
* @return inteager
|
||||
*/
|
||||
private function getCountry(Country $country): int
|
||||
{
|
||||
return match ($country) {
|
||||
Country::belgium() => 56,
|
||||
Country::luxembourg() => 442,
|
||||
Country::belgium => 56,
|
||||
Country::luxembourg => 442,
|
||||
// * France
|
||||
default => 250
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -17,11 +19,10 @@ class CodeExportSucceed extends Mailable
|
|||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param integer $nbCodeFic Nombre de codes par fichiers.
|
||||
* @param integer $nbCodeTot Nombre total de codes à exporter.
|
||||
* @param integer $nbCodeLigne Nombre de codes par ligne.
|
||||
* @param string $archive_path Nom de l'archive crée.
|
||||
* @return void
|
||||
* @param int $nbCodeFic Nombre de codes par fichiers.
|
||||
* @param int $nbCodeTot Nombre total de codes à exporter.
|
||||
* @param int $nbCodeLigne Nombre de codes par ligne.
|
||||
* @param string $archive_path Nom de l'archive crée.
|
||||
*/
|
||||
public function __construct(
|
||||
protected int $nbCodeFic,
|
||||
|
|
@ -33,10 +34,8 @@ class CodeExportSucceed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
to: [new Address(\config('mail.admin'))],
|
||||
|
|
@ -46,18 +45,16 @@ class CodeExportSucceed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content(): \Illuminate\Mail\Mailables\Content
|
||||
public function content(): Content
|
||||
{
|
||||
return new Content(
|
||||
markdown: 'mails.jobs.code-unique-export-succeed',
|
||||
with: [
|
||||
'archive_path' => $this->archive_path,
|
||||
'nbCodeFic' => $this->nbCodeFic,
|
||||
'nbCodeTot' => $this->nbCodeTot,
|
||||
'nbCodeLigne' => $this->nbCodeLigne
|
||||
'nbCodeFic' => $this->nbCodeFic,
|
||||
'nbCodeTot' => $this->nbCodeTot,
|
||||
'nbCodeLigne' => $this->nbCodeLigne,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -17,9 +19,8 @@ class CodeGenerationSucceed extends Mailable
|
|||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param integer $amount Amount of code to generate.
|
||||
* @param string $gameName The game name.
|
||||
* @return void
|
||||
* @param int $amount Amount of code to generate.
|
||||
* @param string $gameName The game name.
|
||||
*/
|
||||
public function __construct(private int $amount, private string $gameName)
|
||||
{
|
||||
|
|
@ -27,10 +28,8 @@ class CodeGenerationSucceed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
to: [new Address(\config('mail.admin'))],
|
||||
|
|
@ -40,16 +39,14 @@ class CodeGenerationSucceed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content(): \Illuminate\Mail\Mailables\Content
|
||||
public function content(): Content
|
||||
{
|
||||
return new Content(
|
||||
markdown: 'mails.jobs.code-generation-succeed',
|
||||
with: [
|
||||
'quantity' => $this->amount,
|
||||
'gameName' => $this->gameName
|
||||
'gameName' => $this->gameName,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -16,10 +18,6 @@ class JobFailed extends Mailable
|
|||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param string $job
|
||||
* @param array $exception
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(public string $job, public array $exception)
|
||||
{
|
||||
|
|
@ -27,10 +25,8 @@ class JobFailed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
to: [new Address(\config('mail.admin'))],
|
||||
|
|
@ -40,16 +36,14 @@ class JobFailed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content(): \Illuminate\Mail\Mailables\Content
|
||||
public function content(): Content
|
||||
{
|
||||
return new Content(
|
||||
markdown: 'mails.jobs.failure',
|
||||
with: [
|
||||
'job' => $this->job,
|
||||
'exception' => $this->exception
|
||||
'job' => $this->job,
|
||||
'exception' => $this->exception,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Settings;
|
||||
|
|
@ -14,24 +16,12 @@ class PasswordReset extends Mailable implements ShouldQueue
|
|||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/** @var \App\Models\User */
|
||||
protected $user;
|
||||
|
||||
/** @var \App\Models\Settings */
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @param \App\Models\Settings $settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(User $user, Settings $settings)
|
||||
public function __construct(protected User $user, protected Settings $settings)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -41,8 +31,11 @@ class PasswordReset extends Mailable implements ShouldQueue
|
|||
*/
|
||||
public function build()
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'front.basic.password-email';
|
||||
|
||||
return $this->subject('Changement de votre mot de passe')
|
||||
->view('front.basic.password-email')
|
||||
->with(['user' => $this->user, 'settings' => $this->settings]);
|
||||
->view($view)
|
||||
->with(['user' => $this->user, 'settings' => $this->settings]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail\Won;
|
||||
|
||||
use App\Lib\Discount;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
|
|
@ -21,13 +22,11 @@ class DiscountWonMail extends Mailable implements ShouldQueue
|
|||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @param \Illuminate\Mail\Mailables\Address $recipient The winner.
|
||||
* @param string $game_name The game name.
|
||||
* @param \App\Lib\Discount $discount Amount of the won discount in cents.
|
||||
* @param string $print_url Url to print the discount.
|
||||
* @param string $company The company name.
|
||||
*
|
||||
* @return void
|
||||
* @param Address $recipient The winner.
|
||||
* @param string $game_name The game name.
|
||||
* @param Discount $discount Amount of the won discount in cents.
|
||||
* @param string $print_url Url to print the discount.
|
||||
* @param string $company The company name.
|
||||
*/
|
||||
public function __construct(
|
||||
protected Address $recipient,
|
||||
|
|
@ -35,40 +34,41 @@ class DiscountWonMail extends Mailable implements ShouldQueue
|
|||
protected Discount $discount,
|
||||
protected string $print_url,
|
||||
protected string $company
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
to: [$this->recipient],
|
||||
subject: trans('front.mails.subjects.game_winning', [
|
||||
'game_name' => $this->game_name
|
||||
'game_name' => $this->game_name,
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content(): \Illuminate\Mail\Mailables\Content
|
||||
public function content(): Content
|
||||
{
|
||||
// * Fix for async usage
|
||||
View::addNamespace('theme', resource_path('theme/mounted/views'));
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::mails.won-discount';
|
||||
|
||||
return new Content(
|
||||
markdown: 'theme::mails.won-discount',
|
||||
markdown: $view,
|
||||
with: [
|
||||
'first_name' => $this->recipient->name ?? $this->recipient->address,
|
||||
'game_name' => $this->game_name,
|
||||
'discount' => $this->discount,
|
||||
'print_url' => $this->print_url,
|
||||
'company' => $this->company,
|
||||
'game_name' => $this->game_name,
|
||||
'discount' => $this->discount,
|
||||
'print_url' => $this->print_url,
|
||||
'company' => $this->company,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue