Compare commits
No commits in common. "dependencies" and "master" have entirely different histories.
dependenci
...
master
279 changed files with 7457 additions and 9633 deletions
26
.gitignore
vendored
26
.gitignore
vendored
|
|
@ -31,42 +31,16 @@ 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,27 +1,20 @@
|
|||
<?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 RuntimeException;
|
||||
use SensitiveParameter;
|
||||
use Throwable;
|
||||
use LDC\LDCCRM\Models\Customer as CrmCustomer;
|
||||
|
||||
/**
|
||||
* Crm user provider to integrate nicely with Laravel
|
||||
|
|
@ -30,28 +23,32 @@ class CrmUserProvider extends EloquentUserProvider implements UserProviderContra
|
|||
{
|
||||
/**
|
||||
* The model to use, specified in auth config guard.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private string $usedModel = Customer::class;
|
||||
private $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 CrmApiV4 */
|
||||
$crm = resolve('crmAPI');
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('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;
|
||||
}
|
||||
|
|
@ -66,38 +63,40 @@ 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(self::class . '::retrieveByCredentials reached end of possibilities.');
|
||||
|
||||
} //end try
|
||||
Log::error(__CLASS__ . '::retrieveByCredentials reached end of possibilities.');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a user against the given credentials.
|
||||
*
|
||||
* @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.
|
||||
* @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.
|
||||
*/
|
||||
public function validateCredentials(UserContract $model, array $credentials): ?bool
|
||||
public function validateCredentials(UserContract $model, array $credentials): bool|null
|
||||
{
|
||||
/** @var Customer $model */
|
||||
if ($model::class !== $this->usedModel) {
|
||||
throw new RuntimeException('Cannot authenticate any thing else than ' . $this->usedModel);
|
||||
/** @var \App\Models\Customer $model */
|
||||
if (\get_class($model) !== $this->usedModel) {
|
||||
throw new \RuntimeException('Cannot authenticate any thing else than ' . $this->usedModel);
|
||||
}
|
||||
|
||||
try {
|
||||
/** @var CrmApiV4 */
|
||||
$crm = resolve('crmAPI');
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('crmAPI');
|
||||
|
||||
// * If has trait soft delete and customer trashed, then restore customer.
|
||||
if (
|
||||
\in_array(SoftDeletes::class, \class_uses_recursive($model)) && $model->trashed()
|
||||
\in_array(\Illuminate\Database\Eloquent\SoftDeletes::class, \class_uses_recursive($model)) and
|
||||
$model->trashed()
|
||||
) {
|
||||
$model->restore();
|
||||
}
|
||||
|
|
@ -106,10 +105,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)) {
|
||||
|
|
@ -121,42 +120,32 @@ 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);
|
||||
throw_if(config('app.debug'), $e);
|
||||
|
||||
if (config('app.debug')) {
|
||||
throw $e;
|
||||
}
|
||||
return false;
|
||||
} // end try
|
||||
|
||||
Log::error(self::class . '::validateCredentials reached end of possibilities.');
|
||||
} //end try
|
||||
|
||||
Log::error(__CLASS__ . '::validateCredentials reached end of possibilities.');
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Create a local customer
|
||||
*
|
||||
* @throws Throwable If saving to DB failed.
|
||||
* @param \LDC\LDCCRM\Models\Customer $crmCustomer
|
||||
* @return \Illuminate\Database\Eloquent\Model
|
||||
* @throws \Throwable If saving to DB failed.
|
||||
*/
|
||||
private function createLocalCustomer(\LDC\LDCCRM\Models\Customer $crmCustomer): Model
|
||||
{
|
||||
/** @var Customer $model */
|
||||
/** @var \App\Models\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;
|
||||
|
|
@ -171,12 +160,14 @@ class CrmUserProvider extends EloquentUserProvider implements UserProviderContra
|
|||
/**
|
||||
* Retrieve a trashed customer by the given credentials.
|
||||
*
|
||||
* @throws ErrorException If cannot connect to LDAP.
|
||||
* @param array $credentials
|
||||
* @return \Illuminate\Contracts\Auth\Authenticatable|null
|
||||
* @throws \ErrorException If cannot connect to LDAP.
|
||||
*/
|
||||
private function retrieveTrashed(array $credentials): ?UserContract
|
||||
private function retrieveTrashed(array $credentials): ?Authenticatable
|
||||
{
|
||||
// * Make changes
|
||||
if ($credentials === []) {
|
||||
if (empty($credentials)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -186,12 +177,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 Customer|null $query */
|
||||
/** @var \App\Models\Customer|null $query */
|
||||
return $query->withTrashed()->first();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,26 @@
|
|||
<?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 Model $model
|
||||
* @param mixed $value
|
||||
* @return array<Discount>
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return array<\App\Lib\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): Discount {
|
||||
return \collect(\json_decode($value, true))->map(function ($input) use ($model, $key, $attributes) {
|
||||
$inputCast = new AsDiscount();
|
||||
|
||||
return $inputCast->get($model, $key, \json_encode($input), $attributes);
|
||||
})->all();
|
||||
}
|
||||
|
|
@ -32,10 +28,11 @@ class AsArrayOfDiscount implements CastsAttributes
|
|||
/**
|
||||
* Prepare the given value for storage.
|
||||
*
|
||||
* @param Model $model
|
||||
* @param Discount $value
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param \App\Lib\Discount $value
|
||||
* @param array $attributes
|
||||
* @return string Json encoded array<\App\Lib\Discount>
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.TypeHintMissing
|
||||
*/
|
||||
public function set($model, string $key, $value, array $attributes)
|
||||
|
|
@ -43,7 +40,6 @@ 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,69 +1,64 @@
|
|||
<?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 Model $model
|
||||
* @param mixed $value
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return \App\Lib\Discount
|
||||
* @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 Model $model
|
||||
* @param mixed $value
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @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 Discount $value */
|
||||
/** @var \App\Lib\Discount $value */
|
||||
return $value->toJson();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert is instance of \App\Lib\Discount
|
||||
*
|
||||
* @throws RuntimeException If the value is not an input.
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
* @throws \RuntimeException If the value is not an input.
|
||||
*/
|
||||
private function assertIsInput(mixed $value): void
|
||||
{
|
||||
if (! \is_object($value) || ! ($value instanceof Discount)) {
|
||||
if (!\is_object($value) or !($value instanceof Discount)) {
|
||||
$value = \json_encode($value);
|
||||
throw new RuntimeException(
|
||||
self::class . ' needs value to be array of \'' . Discount::class . "' given is {$value}"
|
||||
throw new \RuntimeException(
|
||||
__CLASS__ . ' needs value to be array of \'' . Discount::class . "' given is {$value}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
<?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
|
||||
|
|
@ -19,30 +14,30 @@ class Ip implements CastsAttributes
|
|||
/**
|
||||
* Transform the attribute from the underlying model values.
|
||||
*
|
||||
* @param array<string,mixed> $attributes
|
||||
* @return AddressInterface|null
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array<string,mixed> $attributes
|
||||
* @return \IPLib\Address\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 Factory::parseAddressString($value);
|
||||
return \IPLib\Factory::parseAddressString($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the attribute to its underlying model values.
|
||||
*
|
||||
* @param AddressInterface|string|null $value
|
||||
* @param array<string,mixed> $attributes
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param \IPLib\Address\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)
|
||||
|
|
@ -52,12 +47,15 @@ class Ip implements CastsAttributes
|
|||
return null;
|
||||
}
|
||||
if (is_string($value)) {
|
||||
$value = Factory::parseAddressString($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
|
||||
);
|
||||
}
|
||||
throw_if(! is_object($value) || ! ($value instanceof AddressInterface), RuntimeException::class, "{$key} has to be instance of " .
|
||||
AddressInterface::class);
|
||||
$value->getAddressType();
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
|
|
@ -14,7 +12,6 @@ class TestMail extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $signature = 'uwil:mail:test';
|
||||
|
||||
/**
|
||||
|
|
@ -22,15 +19,16 @@ 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(): void
|
||||
public function handle()
|
||||
{
|
||||
Mail::raw(sprintf('UWIL mail-test from %s %s', \config('app.name'), \config('app.url')), function ($msg): void {
|
||||
Mail::raw(sprintf('UWIL mail-test from %s %s', \config('app.name'), \config('app.url')), function ($msg) {
|
||||
$msg->to('equipe.web@ldc.fr')->subject('Test Email');
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Console\Commands\Theme;
|
||||
|
||||
use App\Lib\Helpers\ToolboxHelper;
|
||||
|
|
@ -20,7 +18,6 @@ class SwitchCommand extends Command implements PromptsForMissingInput
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $signature = 'uwil:theme:switch {theme : The theme folder name on theme-merge project}';
|
||||
|
||||
/**
|
||||
|
|
@ -28,7 +25,6 @@ class SwitchCommand extends Command implements PromptsForMissingInput
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $description = 'Switch GGW theme and install it';
|
||||
|
||||
/**
|
||||
|
|
@ -39,20 +35,22 @@ class SwitchCommand extends Command implements PromptsForMissingInput
|
|||
protected function promptForMissingArgumentsUsing()
|
||||
{
|
||||
return [
|
||||
'theme' => fn (): int | string => search(
|
||||
'theme' => fn () => 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): string => \pathinfo($dir_path, \PATHINFO_BASENAME))
|
||||
->map(fn (string $dir_path) => \pathinfo($dir_path, \PATHINFO_BASENAME))
|
||||
->filter(fn (string $dir_path) => $value ? Str::of($dir_path)->contains($value) : true)
|
||||
->filter(fn (string $dir_path): bool => $dir_path !== 'mounted')
|
||||
->all(),
|
||||
placeholder: 'default-theme'
|
||||
),
|
||||
->filter(fn (string $dir_path) => $dir_path !== 'mounted')
|
||||
->all()
|
||||
)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
{
|
||||
|
|
@ -67,7 +65,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,13 +1,11 @@
|
|||
<?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;
|
||||
|
||||
|
|
@ -18,15 +16,13 @@ class UserCreate extends Command
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
#[\Override]
|
||||
protected $signature = 'uwil:user:create';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
*/
|
||||
#[\Override]
|
||||
protected $description = 'Create a backend admin user';
|
||||
|
||||
/**
|
||||
|
|
@ -66,6 +62,8 @@ class UserCreate extends Command
|
|||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
|
|
@ -85,13 +83,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' => Date::now(),
|
||||
'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(),
|
||||
]);
|
||||
$user->saveOrFail();
|
||||
|
||||
|
|
@ -102,6 +100,8 @@ 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,14 +118,15 @@ 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
|
||||
{
|
||||
|
|
@ -133,7 +134,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;
|
||||
|
|
@ -142,14 +143,15 @@ 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
|
||||
{
|
||||
|
|
@ -157,7 +159,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;
|
||||
|
|
@ -166,26 +168,31 @@ 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
|
||||
{
|
||||
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);
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a role to the user.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function addRole(): void
|
||||
{
|
||||
|
|
@ -208,7 +215,7 @@ class UserCreate extends Command
|
|||
$tmp = RoleEnum::marketing;
|
||||
}
|
||||
$validator = Validator::make(['role' => $tmp], [
|
||||
'role' => 'required',
|
||||
'role' => 'required'
|
||||
]);
|
||||
$validator->validate();
|
||||
$this->role = $tmp;
|
||||
|
|
@ -217,9 +224,8 @@ 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,9 +1,8 @@
|
|||
<?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;
|
||||
|
||||
|
|
@ -14,12 +13,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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums\ActivityLogs;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
@ -27,6 +25,7 @@ enum ActivityLogsEventEnum: int
|
|||
self::deleted->name => 'Suppression',
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Custom added classes definition
|
||||
*/
|
||||
|
|
@ -39,6 +38,8 @@ enum ActivityLogsEventEnum: int
|
|||
|
||||
/**
|
||||
* Get Class
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function bootstrapClass(): string
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums\Pagination;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums\Theme;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Enums\Users;
|
||||
|
||||
use App\Traits\Enums\BaseEnum;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
|
@ -12,17 +10,15 @@ 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 = [];
|
||||
|
||||
/**
|
||||
|
|
@ -30,7 +26,6 @@ class Handler extends ExceptionHandler
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
|
|
@ -39,12 +34,14 @@ class Handler extends ExceptionHandler
|
|||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(): void
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e): void {
|
||||
$this->reportable(function (Throwable $e) {
|
||||
if (app()->bound('sentry')) {
|
||||
resolve('sentry')->captureException($e);
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,11 @@
|
|||
<?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
|
||||
|
|
@ -19,12 +15,14 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$this->authorize('isConceptor');
|
||||
|
||||
/** @var Builder $query */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
$query = ActivityLog::query()->with('user');
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -47,32 +45,25 @@ class ActivityLogController extends Controller
|
|||
/** Custom pagination */
|
||||
$activitylogModels = $this->paginate($query);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.activity_logs.index';
|
||||
|
||||
return view($view, [
|
||||
'activitylogModels' => $activitylogModels,
|
||||
'search' => $search,
|
||||
'searchFields' => $searchFields,
|
||||
]);
|
||||
return view('back::pages.activity_logs.index', compact('activitylogModels', 'search', '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): View
|
||||
public function show(ActivityLog $activity_log): \Illuminate\Contracts\View\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();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.activity_logs.show';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.activity_logs.show', [
|
||||
'activitylogModel' => $activity_log,
|
||||
'targetModel' => $targetModel,
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -17,6 +15,8 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -25,6 +25,8 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
|
|
@ -33,17 +35,18 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showLoginForm(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::auth.login';
|
||||
|
||||
return view($view);
|
||||
return view('back::auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
|
|
@ -53,14 +56,14 @@ class LoginController extends Controller
|
|||
/**
|
||||
* Attempt to log the user into the application.
|
||||
*
|
||||
* @return bool
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return boolean
|
||||
*/
|
||||
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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -15,6 +13,8 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
|
|
@ -23,6 +23,8 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Where to redirect users after login.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function redirectTo(): string
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
<?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;
|
||||
|
|
@ -27,10 +22,13 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var Builder $bannedipModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $bannedipModels */
|
||||
$bannedipModels = BannedIp::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -51,42 +49,43 @@ class BannedIpController extends Controller
|
|||
/** Custom pagination */
|
||||
$bannedipModels = $this->paginate($bannedipModels);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.banned-ips.index';
|
||||
|
||||
return view($view, ['bannedipModels' => $bannedipModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
return view('back::pages.banned-ips.index', compact('bannedipModels', 'search', '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): View
|
||||
public function create(BannedIp $banned_ip): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.banned-ips.create';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.banned-ips.create', [
|
||||
'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): RedirectResponse
|
||||
public function store(StoreBannedIpRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$banned_ip = new BannedIp();
|
||||
$banned_ip->fill($request->validated());
|
||||
if ($banned_ip->saveOrFail()) {
|
||||
return to_route('bo.banned_ips.edit', $banned_ip)
|
||||
return redirect()
|
||||
->route('bo.banned_ips.edit', $banned_ip)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
|
|
@ -96,33 +95,38 @@ 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): View
|
||||
public function edit(BannedIp $banned_ip): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.banned-ips.edit';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.banned-ips.edit', [
|
||||
'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): RedirectResponse
|
||||
public function update(UpdateBannedIpRequest $request, BannedIp $banned_ip): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $banned_ip) {
|
||||
$banned_ip->fill($request->validated());
|
||||
if ($banned_ip->saveOrFail()) {
|
||||
return to_route('bo.banned_ips.edit', $banned_ip)
|
||||
return redirect()
|
||||
->route('bo.banned_ips.edit', $banned_ip)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
|
|
@ -132,19 +136,23 @@ 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): RedirectResponse
|
||||
public function destroy(BannedIp $banned_ip): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($banned_ip) {
|
||||
if ($banned_ip->deleteOrFail()) {
|
||||
return to_route('bo.banned_ips.index')
|
||||
return redirect()
|
||||
->route('bo.banned_ips.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(trans('models.classes.banned_ips'))]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -14,22 +12,21 @@ 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(): View
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$this->authorize('generate', Code::class);
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
$nbCodeBase = Code::query()->max('id');
|
||||
$nbCodeUsed = Code::query()->whereHas(
|
||||
'participations',
|
||||
|
|
@ -38,23 +35,22 @@ class CodeController extends Controller
|
|||
)->count();
|
||||
$nbCodeExported = Code::query()->where('code_exported', true)->count();
|
||||
$nbCodeRemainingToExport = Code::query()->where('code_exported', false)->count();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.codes.index';
|
||||
|
||||
return view($view, [
|
||||
'settings' => $settings,
|
||||
'nbCodeBase' => $nbCodeBase,
|
||||
'nbCodeUsed' => $nbCodeUsed,
|
||||
'nbCodeExported' => $nbCodeExported,
|
||||
'nbCodeRemainingToExport' => $nbCodeRemainingToExport,
|
||||
]);
|
||||
return view('back::pages.codes.index', compact(
|
||||
'settings',
|
||||
'nbCodeBase',
|
||||
'nbCodeUsed',
|
||||
'nbCodeExported',
|
||||
'nbCodeRemainingToExport'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Run generate codes action
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Codes\GenerateCodesRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function generate(GenerateCodesRequest $request): RedirectResponse
|
||||
public function generate(GenerateCodesRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$this->authorize('generate', Code::class);
|
||||
Queue::push(
|
||||
|
|
@ -70,7 +66,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')
|
||||
]
|
||||
)
|
||||
);
|
||||
|
|
@ -78,8 +74,11 @@ class CodeController extends Controller
|
|||
|
||||
/**
|
||||
* Run export codes
|
||||
*
|
||||
* @param \App\Http\Requests\Bo\Codes\ExportCodesRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function export(ExportCodesRequest $request): RedirectResponse
|
||||
public function export(ExportCodesRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$this->authorize('export', Code::class);
|
||||
Queue::push(
|
||||
|
|
@ -94,22 +93,25 @@ 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): View
|
||||
public function search(CodeSearchRequest $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$this->authorize('search', Code::class);
|
||||
$code = null;
|
||||
try {
|
||||
$code = Code::query()->where('id', Code::serialToInt($request->code))->first();
|
||||
} catch (Throwable $e) {
|
||||
if ($e::class === SerialCasterException::class) {
|
||||
} catch (\Throwable $e) {
|
||||
if (\get_class($e) === SerialCasterException::class) {
|
||||
$code = false;
|
||||
}
|
||||
} finally {
|
||||
|
|
@ -124,13 +126,10 @@ 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();
|
||||
}
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.codes.search';
|
||||
|
||||
return view($view, ['code' => $code, 'used_counter' => $used_counter]);
|
||||
return view('back::pages.codes.search', compact('code', 'used_counter'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,62 +1,60 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Settings;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Carbon\Carbon;
|
||||
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(): View
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
// * Pour les stats.
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
$avgParticipUser = 0;
|
||||
$participationPeriod = [];
|
||||
$statsUnique = [];
|
||||
$query = DB::table(new Participation()->getTable());
|
||||
$dateFrmtr = function (object $row): object {
|
||||
$row->date = Date::parse($row->date)->isoFormat('DD/MM/YYYY');
|
||||
|
||||
$query = DB::table((new Participation())->getTable());
|
||||
$dateFrmtr = function (object $row) {
|
||||
$row->date = Carbon::parse($row->date)->isoFormat('DD/MM/YYYY');
|
||||
return $row;
|
||||
};
|
||||
|
||||
/** @var Collection<string, object> */
|
||||
/** @var \Illuminate\Support\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 Collection<object> */
|
||||
/** @var \Illuminate\Support\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 Collection<object> */
|
||||
/** @var \Illuminate\Support\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 Collection<object> 3 codes EAN les plus utilisés */
|
||||
/** @var \Illuminate\Support\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): void {
|
||||
$participationsUniquePerDay->each(function (object $row) use (&$statsUnique) {
|
||||
Arr::set($statsUnique, $row->date, (Arr::get($statsUnique, $row->date) ?? 0) + 1);
|
||||
});
|
||||
|
||||
|
|
@ -64,22 +62,23 @@ class DashboardController extends Controller
|
|||
if ($participationsUniquePerCustomer->count() > 0) {
|
||||
$avgParticipUser = round($participationsTotal / $participationsUniquePerCustomer->count(), 1);
|
||||
}
|
||||
now()->lt($settings->end_date) ? now() : $settings->end_date;
|
||||
|
||||
// * 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;
|
||||
$dates = $participationsPerDay->keys();
|
||||
$count = $participationsPerDay->pluck('count');
|
||||
$countUnique = $dates->map(fn (string $formated_date) => Arr::get($statsUnique, $formated_date, 0));
|
||||
|
||||
/** @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,
|
||||
]);
|
||||
return view('back::pages.dashboard.index', compact(
|
||||
'dates',
|
||||
'count',
|
||||
'countUnique',
|
||||
'participationsTotal',
|
||||
'avgParticipUser',
|
||||
'codesEan',
|
||||
'settings'
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -9,9 +7,6 @@ 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;
|
||||
|
|
@ -28,10 +23,13 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var Builder $faqQuestionModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $faqQuestionModels */
|
||||
$faqQuestionModels = FaqQuestion::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -57,42 +55,38 @@ class FaqQuestionController extends Controller
|
|||
/** Custom pagination */
|
||||
$faqQuestionModels = $this->paginate($faqQuestionModels);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-questions.index';
|
||||
|
||||
return view($view, [
|
||||
'faqQuestionModels' => $faqQuestionModels,
|
||||
'search' => $search,
|
||||
'searchFields' => $searchFields,
|
||||
]);
|
||||
return view('back::pages.faq-questions.index', compact('faqQuestionModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(FaqQuestion $faqQuestion): View
|
||||
public function create(FaqQuestion $faqQuestion): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$faqThemeModels = FaqTheme::all();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-questions.create';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.faq-questions.create', [
|
||||
'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): RedirectResponse
|
||||
public function store(StoreFaqQuestionRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$faqQuestion = new FaqQuestion();
|
||||
$faqQuestion->fill($request->validated());
|
||||
if ($faqQuestion->saveOrFail()) {
|
||||
return to_route('bo.faq-questions.edit', $faqQuestion)
|
||||
return redirect()
|
||||
->route('bo.faq-questions.edit', $faqQuestion)
|
||||
->with(
|
||||
'success',
|
||||
trans(
|
||||
|
|
@ -101,8 +95,8 @@ class FaqQuestionController extends Controller
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
|
|
@ -112,38 +106,45 @@ 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): View
|
||||
public function edit(FaqQuestion $faqQuestion): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$faqThemeModels = FaqTheme::all();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-questions.edit';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.faq-questions.edit', [
|
||||
'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
|
||||
): RedirectResponse {
|
||||
): \Illuminate\Http\RedirectResponse {
|
||||
return DB::transaction(function () use ($request, $faqQuestion) {
|
||||
$faqQuestion->fill($request->validated());
|
||||
if ($faqQuestion->saveOrFail()) {
|
||||
return to_route('bo.faq-questions.edit', $faqQuestion)
|
||||
return redirect()
|
||||
->route(
|
||||
'bo.faq-questions.edit',
|
||||
$faqQuestion
|
||||
)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
|
|
@ -153,19 +154,23 @@ class FaqQuestionController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\FaqQuestion $faqQuestion
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(FaqQuestion $faqQuestion): RedirectResponse
|
||||
public function destroy(FaqQuestion $faqQuestion): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($faqQuestion) {
|
||||
if ($faqQuestion->deleteOrFail()) {
|
||||
return to_route('bo.faq-questions.index')
|
||||
return redirect()
|
||||
->route('bo.faq-questions.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => trans_choice('models.classes.faq-questions', 1)]
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
<?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;
|
||||
|
|
@ -27,10 +22,13 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var Builder $faqThemeModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $faqThemeModels */
|
||||
$faqThemeModels = FaqTheme::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -51,35 +49,36 @@ class FaqThemeController extends Controller
|
|||
/** Custom pagination */
|
||||
$faqThemeModels = $this->paginate($faqThemeModels);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-themes.index';
|
||||
|
||||
return view($view, ['faqThemeModels' => $faqThemeModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
return view('back::pages.faq-themes.index', compact('faqThemeModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(FaqTheme $faqTheme): View
|
||||
public function create(FaqTheme $faqTheme): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-themes.create';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.faq-themes.create', [
|
||||
'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): RedirectResponse
|
||||
public function store(StoreFaqThemeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$faqTheme = new FaqTheme();
|
||||
$faqTheme->fill($request->validated());
|
||||
if ($faqTheme->saveOrFail()) {
|
||||
return to_route('bo.faq-themes.edit', $faqTheme)
|
||||
return redirect()
|
||||
->route('bo.faq-themes.edit', $faqTheme)
|
||||
->with(
|
||||
'success',
|
||||
trans(
|
||||
|
|
@ -88,8 +87,8 @@ class FaqThemeController extends Controller
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
|
|
@ -99,35 +98,43 @@ 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): View
|
||||
public function edit(FaqTheme $faqTheme): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.faq-themes.edit';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.faq-themes.edit', [
|
||||
'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
|
||||
): RedirectResponse {
|
||||
): \Illuminate\Http\RedirectResponse {
|
||||
return DB::transaction(function () use ($request, $faqTheme) {
|
||||
$faqTheme->fill($request->validated());
|
||||
if ($faqTheme->saveOrFail()) {
|
||||
return to_route('bo.faq-themes.edit', $faqTheme)
|
||||
return redirect()
|
||||
->route(
|
||||
'bo.faq-themes.edit',
|
||||
$faqTheme
|
||||
)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
|
|
@ -137,19 +144,23 @@ class FaqThemeController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\FaqTheme $faqTheme
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(FaqTheme $faqTheme): RedirectResponse
|
||||
public function destroy(FaqTheme $faqTheme): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($faqTheme) {
|
||||
if ($faqTheme->deleteOrFail()) {
|
||||
return to_route('bo.faq-themes.index')
|
||||
return redirect()
|
||||
->route('bo.faq-themes.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
'crud.messages.cannot_be_deleted',
|
||||
['model' => trans_choice('models.classes.faq-themes', 1)]
|
||||
|
|
|
|||
|
|
@ -1,21 +1,15 @@
|
|||
<?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
|
||||
{
|
||||
|
|
@ -29,21 +23,22 @@ class InstantWinController extends Controller
|
|||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function index(): View
|
||||
public function index(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$instantWinModelList = InstantWin::query()->oldest('available_at')->get();
|
||||
$instantWinModelList = InstantWin::query()->orderBy('available_at')->get();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.instant-win.index';
|
||||
|
||||
return view($view, [
|
||||
'instantWinModelList' => $instantWinModelList,
|
||||
return view('back::pages.instant-win.index', [
|
||||
'instantWinModelList' => $instantWinModelList
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns generated instant win.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function generate(): JsonResponse
|
||||
{
|
||||
|
|
@ -61,20 +56,23 @@ class InstantWinController extends Controller
|
|||
*/
|
||||
$day_end = now()->setTime(22, 29);
|
||||
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
$prizeModelList = Prize::all();
|
||||
|
||||
/** @var Collection<array-key, WinDayCalendar> */
|
||||
/** @var \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\WinDayCalendar> */
|
||||
$datesGlobal = collect();
|
||||
/** @var Collection<array-key, WinTimeElement> Liste de tous les lots à gagner */
|
||||
/**
|
||||
* @var \Illuminate\Support\Collection<array-key,\App\Http\Controllers\Bo\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): void {
|
||||
$prizeModelList->each(function (Prize $prize) use ($lotsGlobal, $day_start, $day_end) {
|
||||
for ($i = 0; $i < $prize->quantity; $i++) {
|
||||
$el = new WinTimeElement();
|
||||
$el->prize = $prize;
|
||||
|
|
@ -86,7 +84,7 @@ class InstantWinController extends Controller
|
|||
}
|
||||
});
|
||||
|
||||
$lotsGlobal->shuffle();
|
||||
$lotsGlobal->shuffle(time());
|
||||
|
||||
// * Init days calendar
|
||||
foreach ($settings->start_date->toPeriod($settings->end_date, CarbonInterval::make('1day')) as $date) {
|
||||
|
|
@ -97,8 +95,8 @@ class InstantWinController extends Controller
|
|||
}
|
||||
|
||||
// * Save Instant wins
|
||||
$this->generateArray($lotsGlobal, $datesGlobal, 0)->each(function (WinDayCalendar $winDayCalendar): void {
|
||||
$winDayCalendar->lots->each(function (WinTimeElement $winTimeElement): void {
|
||||
$this->generateArray($lotsGlobal, $datesGlobal, 0)->each(function (WinDayCalendar $winDayCalendar) {
|
||||
$winDayCalendar->lots->each(function (WinTimeElement $winTimeElement) {
|
||||
$instantWin = new InstantWin();
|
||||
$instantWin->available_at = $winTimeElement->time;
|
||||
$instantWin->prize()->associate($winTimeElement->prize);
|
||||
|
|
@ -116,11 +114,11 @@ class InstantWinController extends Controller
|
|||
*
|
||||
* Même algo que celui implémenté par Romain.
|
||||
*
|
||||
* @param Collection<array-key, WinTimeElement> $lotsGlobal
|
||||
* Liste de tous les lots à gagner
|
||||
* @param Collection<array-key, WinDayCalendar> $dateGlobal
|
||||
* @return Collection<array-key, WinDayCalendar>
|
||||
*
|
||||
* @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>
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
private function generateArray(Collection $lotsGlobal, Collection $dateGlobal, int $prizesDone): Collection
|
||||
|
|
@ -131,7 +129,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() && $dateGlobal->get($rKey)->lots->count() > 0) {
|
||||
if ($prizesDone < $dateGlobal->count() and $dateGlobal->get($rKey)->lots->count() > 0) {
|
||||
return $this->generateArray($lotsGlobal, $dateGlobal, $prizesDone);
|
||||
}
|
||||
|
||||
|
|
@ -144,15 +142,15 @@ class InstantWinController extends Controller
|
|||
}
|
||||
|
||||
// * Tri par heure et assignation du jour correct.
|
||||
$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 {
|
||||
$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) {
|
||||
$time->time->setDate(
|
||||
$date->time->year,
|
||||
$date->time->month,
|
||||
$date->time->day
|
||||
);
|
||||
|
||||
return $time;
|
||||
});
|
||||
});
|
||||
|
|
@ -162,25 +160,23 @@ class InstantWinController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* @property Prize $prize Le lot à gagner.
|
||||
* @property Carbon $time Une heure aléatoire.
|
||||
*
|
||||
* @property \App\Models\Prize $prize Le lot à gagner.
|
||||
* @property \Carbon\Carbon $time Une heure aléatoire.
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
|
||||
*/
|
||||
class WinTimeElement extends stdClass
|
||||
class WinTimeElement extends \stdClass
|
||||
{
|
||||
// phpcs:enable
|
||||
}
|
||||
|
||||
/**
|
||||
* @property Carbon|CarbonInterface $time
|
||||
* Un jour dans le temps.
|
||||
* @property Collection<array-key, WinTimeElement> $lots
|
||||
* Liste des lots tombant ce jour.
|
||||
*
|
||||
* @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.
|
||||
* @phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
|
||||
*/
|
||||
class WinDayCalendar extends stdClass
|
||||
class WinDayCalendar extends \stdClass
|
||||
{
|
||||
// phpcs:enable
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
<?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
|
||||
|
|
@ -22,15 +19,15 @@ class ParticipationController extends Controller
|
|||
|
||||
/**
|
||||
* View all winners
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function viewWinnerList(): View
|
||||
{
|
||||
$this->authorize('viewWinnerList', Participation::class);
|
||||
|
||||
/** @var Builder $participationModels */
|
||||
$participationModels = Participation::query()
|
||||
->with(['customer', 'code', 'instantWin', 'product'])
|
||||
->whereHas('instantWin');
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $participationModels */
|
||||
$participationModels = Participation::query()->with(['customer', 'code', 'instantWin', 'product'])->whereHas('instantWin');
|
||||
|
||||
/** Sort columns with a query */
|
||||
$this->sortQuery($participationModels);
|
||||
|
|
@ -38,37 +35,36 @@ class ParticipationController extends Controller
|
|||
/** Custom pagination */
|
||||
$participationModels = $this->paginate($participationModels);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.winners-list.index';
|
||||
|
||||
return view($view, ['participationModels' => $participationModels]);
|
||||
return view('back::pages.winners-list.index', compact(
|
||||
'participationModels'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display participation form
|
||||
*
|
||||
* @param \App\Models\Participation $participation
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function setComment(Participation $participation): View
|
||||
{
|
||||
$this->authorize('setComment', $participation);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.winners-list.set-comment';
|
||||
|
||||
return view($view, [
|
||||
'participationModel' => $participation,
|
||||
return view('back::pages.winners-list.set-comment', [
|
||||
'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')->toString();
|
||||
$participation->comment = request()->string('comment');
|
||||
$participation->saveOrFail();
|
||||
|
||||
return back()->with('success', \trans(
|
||||
'Le commentaire à bien été mis à jour'
|
||||
));
|
||||
|
|
@ -76,13 +72,15 @@ 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,16 +1,11 @@
|
|||
<?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;
|
||||
|
|
@ -27,10 +22,13 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var Builder $prizeModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $prizeModels */
|
||||
$prizeModels = Prize::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -54,53 +52,54 @@ class PrizeController extends Controller
|
|||
/** Custom pagination */
|
||||
$prizeModels = $this->paginate($prizeModels);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.prizes.index';
|
||||
|
||||
return view($view, ['prizeModels' => $prizeModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
return view('back::pages.prizes.index', compact('prizeModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Prize $prize): View
|
||||
public function show(Prize $prize): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.prizes.show';
|
||||
|
||||
return view($view, ['prizeModel' => $prize]);
|
||||
return view('back::pages.prizes.show', ['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): View
|
||||
public function create(Prize $prize): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.prizes.create';
|
||||
|
||||
return view($view, [
|
||||
'prizeModel' => $prize,
|
||||
return view('back::pages.prizes.create', [
|
||||
'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): RedirectResponse
|
||||
public function store(StorePrizeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$prize = new Prize();
|
||||
$prize->fill($request->validated());
|
||||
if ($prize->saveOrFail()) {
|
||||
return to_route('bo.prizes.edit', $prize)
|
||||
return redirect()
|
||||
->route('bo.prizes.edit', $prize)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
|
|
@ -110,33 +109,38 @@ 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): View
|
||||
public function edit(Prize $prize): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.prizes.edit';
|
||||
|
||||
return view($view, [
|
||||
'prizeModel' => $prize,
|
||||
return view('back::pages.prizes.edit', [
|
||||
'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): RedirectResponse
|
||||
public function update(UpdatePrizeRequest $request, Prize $prize): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $prize) {
|
||||
$prize->fill($request->validated());
|
||||
if ($prize->saveOrFail()) {
|
||||
return to_route('bo.prizes.edit', $prize)
|
||||
return redirect()
|
||||
->route('bo.prizes.edit', $prize)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
|
|
@ -146,19 +150,23 @@ class PrizeController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Prize $prize): RedirectResponse
|
||||
public function destroy(Prize $prize): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($prize) {
|
||||
if ($prize->deleteOrFail()) {
|
||||
return to_route('bo.prizes.index')
|
||||
return redirect()
|
||||
->route('bo.prizes.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.prize'))]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -9,9 +7,6 @@ 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;
|
||||
|
|
@ -28,10 +23,13 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var Builder $productModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $productModels */
|
||||
$productModels = Product::query()->with('range');
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -57,63 +55,63 @@ class ProductController extends Controller
|
|||
/** Custom pagination */
|
||||
$productModels = $this->paginate($productModels);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.products.index';
|
||||
|
||||
return view($view, ['productModels' => $productModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
return view('back::pages.products.index', compact('productModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Product $product): View
|
||||
public function show(Product $product): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.products.show';
|
||||
|
||||
return view($view, ['productModel' => $product]);
|
||||
return view('back::pages.products.show', ['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): View | RedirectResponse
|
||||
public function create(Product $product): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$rangeModels = Range::all();
|
||||
if (! count($rangeModels)) {
|
||||
return to_route('bo.ranges.index')
|
||||
if (!count($rangeModels)) {
|
||||
return \redirect()->route('bo.ranges.index')
|
||||
->with(
|
||||
'error',
|
||||
'Vous devez ajouter une gamme avant de pouvoir ajouter un produit'
|
||||
);
|
||||
}
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.products.create';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.products.create', [
|
||||
'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): RedirectResponse
|
||||
public function store(StoreProductRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$product = new Product();
|
||||
$product->fill($request->validated());
|
||||
if ($product->saveOrFail()) {
|
||||
return to_route('bo.products.edit', $product)
|
||||
return redirect()
|
||||
->route('bo.products.edit', $product)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
|
|
@ -123,36 +121,40 @@ 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): View
|
||||
public function edit(Product $product): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$rangeModels = Range::all();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.products.edit';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.products.edit', [
|
||||
'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): RedirectResponse
|
||||
public function update(UpdateProductRequest $request, Product $product): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $product) {
|
||||
$product->fill($request->validated());
|
||||
if ($product->saveOrFail()) {
|
||||
return to_route('bo.products.edit', $product)
|
||||
return redirect()
|
||||
->route('bo.products.edit', $product)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
|
|
@ -162,19 +164,23 @@ class ProductController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Product $product
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Product $product): RedirectResponse
|
||||
public function destroy(Product $product): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($product) {
|
||||
if ($product->deleteOrFail()) {
|
||||
return to_route('bo.products.index')
|
||||
return redirect()
|
||||
->route('bo.products.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.product'))]
|
||||
|
|
|
|||
|
|
@ -1,16 +1,11 @@
|
|||
<?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;
|
||||
|
|
@ -27,10 +22,13 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var Builder $rangeModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $rangeModels */
|
||||
$rangeModels = Range::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -51,53 +49,54 @@ class RangeController extends Controller
|
|||
/** Custom pagination */
|
||||
$rangeModels = $this->paginate($rangeModels);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.ranges.index';
|
||||
|
||||
return view($view, ['rangeModels' => $rangeModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
return view('back::pages.ranges.index', compact('rangeModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function show(Range $range): View
|
||||
public function show(Range $range): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.ranges.show';
|
||||
|
||||
return view($view, ['rangeModel' => $range]);
|
||||
return view('back::pages.ranges.show', ['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): View
|
||||
public function create(Range $range): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.ranges.create';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.ranges.create', [
|
||||
'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): RedirectResponse
|
||||
public function store(StoreRangeRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$range = new Range();
|
||||
$range->fill($request->validated());
|
||||
if ($range->saveOrFail()) {
|
||||
return to_route('bo.ranges.edit', $range)
|
||||
return redirect()
|
||||
->route('bo.ranges.edit', $range)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_created',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_created',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
|
|
@ -107,33 +106,38 @@ 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): View
|
||||
public function edit(Range $range): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.ranges.edit';
|
||||
|
||||
return view($view, [
|
||||
'rangeModel' => $range,
|
||||
return view('back::pages.ranges.edit', [
|
||||
'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): RedirectResponse
|
||||
public function update(UpdateRangeRequest $request, Range $range): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $range) {
|
||||
$range->fill($request->validated());
|
||||
if ($range->saveOrFail()) {
|
||||
return to_route('bo.ranges.edit', $range)
|
||||
return redirect()
|
||||
->route('bo.ranges.edit', $range)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
|
|
@ -143,25 +147,28 @@ class RangeController extends Controller
|
|||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param \App\Models\Range $range
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Range $range): RedirectResponse
|
||||
public function destroy(Range $range): \Illuminate\Http\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 to_route('bo.ranges.index')
|
||||
return redirect()
|
||||
->route('bo.ranges.index')
|
||||
->with('success', __(
|
||||
'crud.messages.has_been_deleted',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', __(
|
||||
':crud.messages.cannot_be_deleted',
|
||||
['model' => Str::singular(__('models.classes.range'))]
|
||||
|
|
|
|||
|
|
@ -1,20 +1,16 @@
|
|||
<?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\Models\User;
|
||||
use Closure;
|
||||
use App\Lib\Discount;
|
||||
use App\Models\Participation;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
|
@ -25,216 +21,209 @@ 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
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.home';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.home');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Teaser page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function teaser(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.teaser';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.teaser');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show Teaser page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function endGame(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.end-game';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.end-game');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show code input page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participate(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.participate';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.participation.participate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show code input page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participationExhausted(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.participation-exhausted';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.participation.participation-exhausted');
|
||||
}
|
||||
|
||||
// * -- 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;
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won';
|
||||
|
||||
return view($view, [
|
||||
'prizeModel' => $prize,
|
||||
'participationModel' => $participationModel,
|
||||
return view('theme::pages.participation.won', [
|
||||
'prizeModel' => $prize,
|
||||
'participationModel' => $participationModel
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show discount page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function discount(): View
|
||||
{
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var Discount */
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
/** @var \App\Lib\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();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won';
|
||||
|
||||
return view($view, ['discount' => $discount, 'mesBrDiscount' => $mesBrDiscount]);
|
||||
return view('theme::pages.participation.won', compact('discount', 'mesBrDiscount'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show loose page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function loose(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.home';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.participation.loose');
|
||||
}
|
||||
|
||||
// * -- END Participation
|
||||
|
||||
/**
|
||||
* View won prize mail
|
||||
*
|
||||
* @param \App\Models\Prize $prize
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailPrize(Prize $prize): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.re7-preview-mail';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
'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 Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
if (! $settings->discounts_activated) {
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->discounts_activated) {
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.re7-preview-mail';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'discount',
|
||||
]),
|
||||
'type' => 'discount'
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View proof mail received mail
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailProofReceived(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.re7-preview-mail';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
'render_url' => route('re7.mail-print', [
|
||||
'type' => 'proof',
|
||||
]),
|
||||
'type' => 'proof'
|
||||
])
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* View sent prize mail
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function mailPrizeSent(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.re7-preview-mail';
|
||||
|
||||
return view($view, [
|
||||
return view('back::pages.re7-preview-mail', [
|
||||
'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 $prize = null): Response
|
||||
public function mailPrint(string $type, Prize|null $prize = null): Response
|
||||
{
|
||||
/** @var User */
|
||||
/** @var \App\Models\User */
|
||||
$user = auth('backend')->user();
|
||||
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
switch ($type) {
|
||||
case 'discount':
|
||||
/** @var Discount */
|
||||
/** @var \App\Lib\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
|
||||
|
|
@ -243,9 +232,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
|
||||
|
|
@ -254,27 +243,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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -9,14 +7,9 @@ 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
|
||||
{
|
||||
|
|
@ -30,39 +23,45 @@ 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): View
|
||||
public function edit(Settings $settings): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.settings.edit';
|
||||
return view($view, [
|
||||
'settingsModel' => $settings,
|
||||
return view('back::pages.settings.edit', [
|
||||
'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): RedirectResponse
|
||||
public function update(UpdateSettingsRequest $request, Settings $settings): \Illuminate\Http\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): ?\App\Lib\Discount => $this->parseWebCoupon($coupon))
|
||||
->map(fn (array $coupon) => $this->parseWebCoupon($coupon))
|
||||
->filter()->all());
|
||||
|
||||
$settings->fill($data);
|
||||
if ($settings->saveOrFail()) {
|
||||
return to_route('bo.settings.edit', $settings)
|
||||
return redirect()
|
||||
->route('bo.settings.edit', $settings)
|
||||
->with('success', trans(
|
||||
'crud.messages.has_been_updated',
|
||||
['model' => Str::singular(__('models.classes.settings'))]
|
||||
));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()
|
||||
->back()
|
||||
->with('error', trans(
|
||||
'crud.messages.cannot_be_updated',
|
||||
['model' => Str::singular(__('models.classes.settings'))]
|
||||
|
|
@ -70,16 +69,18 @@ class SettingsController extends Controller
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to parse webCoupon
|
||||
*
|
||||
* @param array<string,string> $coupon
|
||||
* @param array<string,string> $coupon
|
||||
* @return \App\Lib\Discount|null
|
||||
*/
|
||||
private function parseWebCoupon(array $coupon): ?Discount
|
||||
private function parseWebCoupon(array $coupon): Discount | null
|
||||
{
|
||||
/** @var UploadedFile|string */
|
||||
/** @var \Illuminate\Http\UploadedFile|string */
|
||||
$picture = Arr::get($coupon, 'picture');
|
||||
if ($picture instanceof UploadedFile) {
|
||||
if (is_object($picture) and ($picture instanceof \Illuminate\Http\UploadedFile)) {
|
||||
$picture = FileStorageHelper::storeFile(
|
||||
new Settings(),
|
||||
$picture,
|
||||
|
|
@ -95,7 +96,7 @@ class SettingsController extends Controller
|
|||
Arr::get($coupon, 'percentage'),
|
||||
Arr::get($coupon, 'web_coupon_identifiant'),
|
||||
);
|
||||
} catch (RuntimeException | TypeError) {
|
||||
} catch (\RuntimeException | \TypeError) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,10 @@
|
|||
<?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;
|
||||
|
|
@ -26,10 +21,13 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var Builder $query */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $query */
|
||||
$query = StaticPage::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -52,44 +50,41 @@ class StaticPageController extends Controller
|
|||
/** Custom pagination */
|
||||
$staticPageModelList = $this->paginate($query);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.static_pages.index';
|
||||
|
||||
return view($view, [
|
||||
'staticPageModelList' => $staticPageModelList,
|
||||
'search' => $search,
|
||||
'searchFields' => $searchFields,
|
||||
]);
|
||||
return view('back::pages.static_pages.index', compact('staticPageModelList', 'search', '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): View
|
||||
public function edit(StaticPage $static_page): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.static_pages.edit';
|
||||
return view($view, ['staticPageModel' => $static_page]);
|
||||
return view('back::pages.static_pages.edit', ['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): RedirectResponse
|
||||
public function update(UpdateStaticPageRequest $request, StaticPage $static_page): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $static_page) {
|
||||
$static_page->fill($request->validated());
|
||||
|
||||
if ($static_page->saveOrFail()) {
|
||||
return to_route('bo.static_pages.edit', $static_page)
|
||||
return redirect()->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 to_route('bo.static_pages.edit', $static_page)
|
||||
return redirect()->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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -9,9 +7,6 @@ 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;
|
||||
|
|
@ -30,10 +25,13 @@ 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): View
|
||||
public function index(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var Builder $userModels */
|
||||
/** @var \Illuminate\Database\Eloquent\Builder $userModels */
|
||||
$userModels = User::query();
|
||||
|
||||
/** @var string $search Search field */
|
||||
|
|
@ -62,101 +60,109 @@ class UserController extends Controller
|
|||
/** Custom pagination */
|
||||
$userModels = $this->paginate($userModels);
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.users.index';
|
||||
|
||||
return view($view, ['userModels' => $userModels, 'search' => $search, 'searchFields' => $searchFields]);
|
||||
return view('back::pages.users.index', compact('userModels', 'search', 'searchFields'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function create(User $user): View
|
||||
public function create(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.users.create';
|
||||
|
||||
return view($view, ['userModel' => $user]);
|
||||
return view('back::pages.users.create', ['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): RedirectResponse
|
||||
public function store(StoreUserRequest $request): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
$user = new User();
|
||||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
return to_route('bo.users.edit', $user)
|
||||
return redirect()->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 back()
|
||||
return redirect()->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): View
|
||||
public function edit(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'back::pages.users.edit';
|
||||
|
||||
return view($view, ['userModel' => $user]);
|
||||
return view('back::pages.users.edit', ['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): RedirectResponse
|
||||
public function update(UpdateUserRequest $request, User $user): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
return DB::transaction(function () use ($request, $user) {
|
||||
$user->fill($request->validated());
|
||||
|
||||
if ($user->saveOrFail()) {
|
||||
return to_route('bo.users.edit', $user)
|
||||
return redirect()->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 to_route('bo.users.edit', $user)
|
||||
return redirect()->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): RedirectResponse
|
||||
public function destroy(User $user): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if ($user->deleteOrFail()) {
|
||||
return to_route('bo.users.index')
|
||||
return redirect()->route('bo.users.index')
|
||||
->with('success', __('crud.messages.has_been_deleted', [
|
||||
'model' => Str::ucfirst(__('models.classes.user')),
|
||||
'model' => Str::ucfirst(__('models.classes.user'))
|
||||
]));
|
||||
}
|
||||
|
||||
return back()
|
||||
return redirect()->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): View
|
||||
public function duplicate(User $user): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return $this->create($user->replicate());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,13 @@
|
|||
<?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;
|
||||
|
|
@ -25,6 +20,7 @@ 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)
|
||||
|
|
@ -34,9 +30,8 @@ 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<Discount> $weightedValues
|
||||
* @return int The winning key
|
||||
*
|
||||
* @param array<\App\Lib\Discount> $weightedValues
|
||||
* @return integer The winning key
|
||||
* @url https://stackoverflow.com/a/11872928/4355295
|
||||
*/
|
||||
protected function getRandomWeightedElementIndex(array $weightedValues): int
|
||||
|
|
@ -50,12 +45,13 @@ class Controller extends BaseController
|
|||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
return $rand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the redirection path for FO Auth controllers
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function authLoggedRedirectPath(): string
|
||||
{
|
||||
|
|
@ -66,57 +62,63 @@ class Controller extends BaseController
|
|||
* Build Search query on specified fields
|
||||
* splitting search into words or using whole sentence
|
||||
*
|
||||
* @param Builder $query The eloquent query builder.
|
||||
* @param string $search The query string.
|
||||
* @param callable $searchQuery The query string.
|
||||
* @param string ...$fields Either a simple array or a string
|
||||
* in case of a string the two fields
|
||||
* would be concatenate to make the search.
|
||||
* @param \Illuminate\Database\Eloquent\Builder $query The eloquent query builder.
|
||||
* @param string $search The query string.
|
||||
* @param callable $searchQuery The query string.
|
||||
* @param string ...$fields Either a simple array or a string
|
||||
* in case of a string the two fields
|
||||
* would be concatenate to make the search.
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected function searchQuery(
|
||||
Builder $query,
|
||||
string $search,
|
||||
?callable $searchQuery = null,
|
||||
callable $searchQuery = null,
|
||||
string ...$fields
|
||||
): Builder {
|
||||
): \Illuminate\Database\Eloquent\Builder {
|
||||
if (count($fields)) {
|
||||
// Search using words.
|
||||
$words = explode(' ', $search);
|
||||
$query->where(function (\Illuminate\Contracts\Database\Query\Builder $query) use ($searchQuery, $words, $search, $fields): void {
|
||||
$query->where(function ($query) use ($searchQuery, $words, $search, $fields) {
|
||||
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
|
||||
): Builder {
|
||||
): \Illuminate\Database\Eloquent\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(fn ($q): string => "`$table`.`$q`")->implode(', \' \', ')),
|
||||
sprintf("UPPER(CONCAT(%s)) LIKE UPPER(?)", collect($field)->map(function ($q) use ($table) {
|
||||
return "`$table`.`$q`";
|
||||
})->implode(', \' \', ')),
|
||||
['%' . htmlspecialchars($search) . '%']
|
||||
);
|
||||
|
||||
return $query;
|
||||
}
|
||||
// Get models woth enum's label.
|
||||
|
|
@ -127,56 +129,62 @@ 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 (\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 . '%');
|
||||
}
|
||||
$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 . '%');
|
||||
}
|
||||
);
|
||||
|
||||
});
|
||||
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()) && $cast && enum_exists($cast) // Check if the cast is an enum.
|
||||
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.
|
||||
) {
|
||||
// @phpstan-ignore-next-line
|
||||
$cases = collect($cast::toArray());
|
||||
$enum = $cases->filter(fn ($item): int | false => preg_match('/' . Str::lower($search) . '/', Str::lower($item->label)));
|
||||
|
||||
$enum = $cases->filter(function ($item) use ($search) {
|
||||
return 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 = []): Builder
|
||||
protected function sortQuery(Builder $query, array $ignore = []): \Illuminate\Database\Eloquent\Builder
|
||||
{
|
||||
$rName = request()->route()->getName();
|
||||
$table = $query->getModel()->getTable();
|
||||
|
|
@ -193,8 +201,8 @@ class Controller extends BaseController
|
|||
Session::remove("$rName.sort_col");
|
||||
Session::remove("$rName.sort_way");
|
||||
}
|
||||
if (request()->sort_col && request()->sort_way && Schema::hasColumn($table, request()->sort_col)) {
|
||||
if (! in_array(request()->sort_col, $ignore)) {
|
||||
if (request()->sort_col and request()->sort_way and 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')) {
|
||||
|
|
@ -202,55 +210,59 @@ class Controller extends BaseController
|
|||
Session::put("$rName.sort_col", 'order');
|
||||
Session::put("$rName.sort_way", 'asc');
|
||||
} elseif (Schema::hasColumn($table, 'updated_at')) {
|
||||
$query = $query->latest('updated_at');
|
||||
$query = $query->orderBy('updated_at', 'DESC');
|
||||
Session::put("$rName.sort_col", 'updated_at');
|
||||
Session::put("$rName.sort_way", 'desc');
|
||||
} elseif (Schema::hasColumn($table, 'created_at')) {
|
||||
$query = $query->latest();
|
||||
$query = $query->orderBy('created_at', 'DESC');
|
||||
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
|
||||
): LengthAwarePaginator {
|
||||
ItemsPerPaginationEnum $pagination = null
|
||||
): \Illuminate\Contracts\Pagination\LengthAwarePaginator {
|
||||
$currentRoutePath = Str::slug(request()->route()->getName());
|
||||
$cacheKey = "pagination.{$currentRoutePath}";
|
||||
$pagination ??= ItemsPerPaginationEnum::twelve;
|
||||
$pagination = $pagination ?? ItemsPerPaginationEnum::twelve;
|
||||
$pagination = ToolboxHelper::getValidatedEnum(
|
||||
Cache::get($cacheKey, $pagination->value()),
|
||||
'pagination',
|
||||
ItemsPerPaginationEnum::class,
|
||||
'\App\Enums\Pagination\ItemsPerPaginationEnum',
|
||||
);
|
||||
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): RedirectResponse
|
||||
protected function setTheme(Request $request): \Illuminate\Http\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 back()->with('success', __('crud.messages.theme_updated'));
|
||||
return redirect()->back()->with('success', __('crud.messages.theme_updated'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,20 @@
|
|||
<?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()
|
||||
{
|
||||
|
|
@ -24,21 +23,21 @@ class ConfirmPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Display the password confirmation view.
|
||||
*
|
||||
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function showConfirmForm(): View | RedirectResponse
|
||||
public function showConfirmForm(): \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
if (Auth::guard('frontend')->check()) {
|
||||
return \response()->redirectToRoute('home');
|
||||
}
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.passwords.confirm';
|
||||
|
||||
return view($view);
|
||||
return view('theme::auth.passwords.confirm');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
<?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;
|
||||
|
||||
|
|
@ -19,13 +16,16 @@ class ForgotPasswordController extends Controller
|
|||
/**
|
||||
* Message to user
|
||||
*
|
||||
*
|
||||
* @var string
|
||||
* @phpcs:disable Generic.Files.LineLength.TooLong
|
||||
*/
|
||||
private string $message = 'front.messages.password_reset_email_sent';
|
||||
// phpcs:enable
|
||||
private $message = 'front.messages.password_reset_email_sent';
|
||||
//phpcs:enable
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -39,14 +39,13 @@ class ForgotPasswordController extends Controller
|
|||
*/
|
||||
public function showLinkRequestForm(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.passwords.email';
|
||||
|
||||
return view($view);
|
||||
return view('theme::auth.passwords.email');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker(): PasswordBroker
|
||||
{
|
||||
|
|
@ -57,7 +56,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 RedirectResponse
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function sendResetLinkResponse()
|
||||
{
|
||||
|
|
@ -68,7 +67,9 @@ 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.
|
||||
*
|
||||
* @return RedirectResponse
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string $response
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
protected function sendResetLinkFailedResponse(Request $request, string $response)
|
||||
{
|
||||
|
|
@ -76,7 +77,6 @@ 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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -30,6 +28,8 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -38,6 +38,8 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
|
|
@ -51,15 +53,15 @@ class LoginController extends Controller
|
|||
*/
|
||||
public function showLoginForm(): View
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.login';
|
||||
|
||||
return view($view);
|
||||
return view('theme::auth.login');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -67,11 +69,11 @@ class LoginController extends Controller
|
|||
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
|
||||
$crmCustomer = $user->api_data;
|
||||
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(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 {
|
||||
|
|
@ -84,6 +86,8 @@ 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
|
||||
|
|
@ -93,6 +97,8 @@ class LoginController extends Controller
|
|||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
<?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;
|
||||
|
|
@ -17,12 +14,10 @@ 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
|
||||
{
|
||||
|
|
@ -30,6 +25,8 @@ class RegisterController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -39,7 +36,7 @@ class RegisterController extends Controller
|
|||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return StatefulGuard
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard()
|
||||
{
|
||||
|
|
@ -49,21 +46,19 @@ class RegisterController extends Controller
|
|||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
* @return View
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showRegistrationForm()
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.register';
|
||||
|
||||
return view($view);
|
||||
return view('theme::auth.register');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -71,7 +66,6 @@ class RegisterController extends Controller
|
|||
// phpcs:enable
|
||||
$request = CreateAccountRequest::capture();
|
||||
$request->prepareForValidation();
|
||||
|
||||
return Validator::make(
|
||||
$request->validationData(),
|
||||
$request->rules(),
|
||||
|
|
@ -83,8 +77,10 @@ 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
|
||||
{
|
||||
|
|
@ -111,7 +107,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;
|
||||
|
|
@ -131,28 +127,30 @@ 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(self::class . '::create reached end of possibilities.');
|
||||
throw new RuntimeException(self::class . '::create reached end of possibilities.', $e->getCode(), $e);
|
||||
Log::error(__CLASS__ . '::create reached end of possibilities.');
|
||||
throw new \RuntimeException(__CLASS__ . '::create reached end of possibilities.');
|
||||
} 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(): string
|
||||
public function redirectPath()
|
||||
{
|
||||
return $this->authLoggedRedirectPath();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +1,20 @@
|
|||
<?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
|
||||
{
|
||||
|
|
@ -28,6 +22,8 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -38,6 +34,8 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Get the guard to be used during authentication.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\StatefulGuard
|
||||
*/
|
||||
protected function guard(): StatefulGuard
|
||||
{
|
||||
|
|
@ -48,15 +46,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): View
|
||||
public function showResetForm(Request $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
$token = $request->route()->parameter('token');
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.passwords.reset';
|
||||
|
||||
return view($view)->with(
|
||||
return view('theme::auth.passwords.reset')->with(
|
||||
['token' => $token, 'email' => $request->email]
|
||||
);
|
||||
}
|
||||
|
|
@ -64,29 +62,32 @@ 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(Customer $customer, string $password): void
|
||||
protected function resetPassword(\App\Models\Customer $customer, string $password): void
|
||||
{
|
||||
/** @var CrmApiV4 */
|
||||
$crm = resolve('crmAPI');
|
||||
/** @var \LDC\LDCCRM\CrmApiV4 */
|
||||
$crm = app('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()
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -101,6 +102,8 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
|
|
@ -109,6 +112,8 @@ class ResetPasswordController extends Controller
|
|||
|
||||
/**
|
||||
* Get the broker to be used during password reset.
|
||||
*
|
||||
* @return \Illuminate\Contracts\Auth\PasswordBroker
|
||||
*/
|
||||
public function broker(): PasswordBroker
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -10,7 +8,6 @@ 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;
|
||||
|
|
@ -26,6 +23,8 @@ class VerificationController extends Controller
|
|||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -36,15 +35,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($view);
|
||||
: view('theme::auth.verify');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -52,16 +51,22 @@ class VerificationController extends Controller
|
|||
*
|
||||
* ! Overloaded trait
|
||||
*
|
||||
* @throws AuthorizationException If request is invalid.
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
|
||||
* @throws \Illuminate\Auth\Access\AuthorizationException If request is invalid.
|
||||
*/
|
||||
public function verify(Request $request): JsonResponse | RedirectResponse
|
||||
public function verify(Request $request): JsonResponse|RedirectResponse
|
||||
{
|
||||
/** @var Customer */
|
||||
/** @var \App\Models\Customer */
|
||||
$user = Customer::findOrFail($request->route('id'));
|
||||
|
||||
throw_unless(hash_equals((string) $request->route('id'), (string) $user->getKey()), AuthorizationException::class);
|
||||
if (!hash_equals((string) $request->route('id'), (string) $user->getKey())) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
|
||||
throw_unless(hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification())), AuthorizationException::class);
|
||||
if (!hash_equals((string) $request->route('hash'), sha1($user->getEmailForVerification()))) {
|
||||
throw new AuthorizationException();
|
||||
}
|
||||
|
||||
if ($user->hasVerifiedEmail()) {
|
||||
return $request->wantsJson()
|
||||
|
|
@ -69,7 +74,7 @@ class VerificationController extends Controller
|
|||
: redirect($this->redirectPath());
|
||||
}
|
||||
|
||||
DB::transaction(function () use ($user): void {
|
||||
DB::transaction(function () use ($user) {
|
||||
if ($user->markEmailAsVerified()) {
|
||||
$this->setCrmCustomerAsVerified($user);
|
||||
event(new Verified($user));
|
||||
|
|
@ -88,8 +93,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)
|
||||
|
|
@ -102,6 +107,8 @@ class VerificationController extends Controller
|
|||
|
||||
/**
|
||||
* Get the post register / login redirect path.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function redirectPath(): string
|
||||
{
|
||||
|
|
@ -111,7 +118,9 @@ class VerificationController extends Controller
|
|||
/**
|
||||
* Set Crm Customer active
|
||||
*
|
||||
* @throws HttpResponseException In case of failure.
|
||||
* @param \App\Models\Customer $customer
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException In case of failure.
|
||||
*/
|
||||
private function setCrmCustomerAsVerified(Customer $customer): void
|
||||
{
|
||||
|
|
@ -128,11 +137,12 @@ 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,16 +1,11 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Customers\SingleOptinRequest;
|
||||
use App\Http\Requests\Fo\Customers\VerifyInformationsRequest;
|
||||
use App\Models\Customer;
|
||||
use App\Models\Participation;
|
||||
use App\Http\Requests\Fo\Customers\SingleOptinRequest;
|
||||
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;
|
||||
|
|
@ -24,15 +19,16 @@ 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
|
||||
{
|
||||
private readonly CrmRepository $crmRepository;
|
||||
/** @var \App\Repositories\Fo\CrmRepository $crmRepository */
|
||||
private $crmRepository;
|
||||
|
||||
/**
|
||||
* ParticipateController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -41,24 +37,26 @@ 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 Customer */
|
||||
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::auth.profil-verify';
|
||||
|
||||
return view($view, ['crmCustomer' => $crmCustomer]);
|
||||
return view('theme::auth.profil-verify', compact('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
|
||||
|
|
@ -67,7 +65,7 @@ class CustomerController extends Controller
|
|||
try {
|
||||
return DB::transaction(function () use ($request) {
|
||||
// * --- FILL AND SAVE CUSTOMER
|
||||
/** @var Customer */
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
// * Màj, on ne mets pas à jour le mdp ou l'adresse email, juste les champs pour mesBr
|
||||
|
|
@ -91,93 +89,86 @@ 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(self::class . '::update reached end of possibilities.');
|
||||
Log::error(__CLASS__ . '::update reached end of possibilities.');
|
||||
} catch (CrmException $e) {
|
||||
report($e);
|
||||
Log::error(self::class . '::error occured on calling crm.');
|
||||
Log::error(__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', Participation::class);
|
||||
$this->authorize('viewWonList', \App\Models\Participation::class);
|
||||
|
||||
/** @var Customer */
|
||||
/** @var \App\Models\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 MesBr $mesBr */
|
||||
$mesBr = resolve('mesBrAPI');
|
||||
|
||||
/** @var array{coupons?: list<array{quantity: int|string, printed: int|string}>} $brBasket */
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('mesBrAPI');
|
||||
$brBasket = $mesBr->getBasket($crmUser);
|
||||
|
||||
if (! empty($brBasket['coupons'])) {
|
||||
$coupons = collect($brBasket['coupons']);
|
||||
$canPrint = $coupons->sum('quantity') - $coupons->sum('printed');
|
||||
if (!empty($brBasket['coupons'])) {
|
||||
$canPrint = (collect($brBasket['coupons'])->sum('quantity') - collect($brBasket['coupons'])->sum('printed'));
|
||||
}
|
||||
|
||||
$winningList = $customer->participations()
|
||||
->with(['instantWin'])->where(function (Builder $q): void {
|
||||
->with(['instantWin'])->where(function (Builder $q) {
|
||||
$q->whereHas('instantWin');
|
||||
})->get();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.winning-participations';
|
||||
|
||||
return view($view, [
|
||||
return view('theme::pages.participation.winning-participations', [
|
||||
'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 BindingResolutionException BindingResolutionException.
|
||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException BindingResolutionException.
|
||||
*/
|
||||
public function addOptIn(SingleOptinRequest $request): Response | string
|
||||
public function addOptIn(SingleOptinRequest $request)
|
||||
{
|
||||
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')) {
|
||||
resolve('sentry')->captureException($e);
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
|
||||
return \response(trans('front.messages.unexpected_error_try_later'), 404);
|
||||
} catch (CrmException $e) {
|
||||
if (app()->bound('sentry')) {
|
||||
resolve('sentry')->captureException($e);
|
||||
app('sentry')->captureException($e);
|
||||
}
|
||||
|
||||
return \response(trans('front.messages.unexpected_error_try_later'), 404);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,34 @@
|
|||
<?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(): RedirectResponse
|
||||
public function fetchBrPdf(): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var Customer $customer */
|
||||
/** @var \App\Models\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
|
||||
)
|
||||
|
|
@ -41,54 +38,53 @@ 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 Customer $customer */
|
||||
/** @var \App\Models\Customer $customer */
|
||||
$customer = auth('frontend')->user();
|
||||
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
try {
|
||||
/** @var MesBr */
|
||||
$mesBr = resolve('mesBrAPI');
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -9,100 +7,89 @@ 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(): View
|
||||
public function home(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
if (! Gate::check('fo.gameEnabled')) {
|
||||
if (!Gate::check('fo.gameEnabled')) {
|
||||
\session()->flash('warning', trans('front.messages.game_missing_required_elements'));
|
||||
}
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.home';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.home');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display products with game stickers
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
* @phpcs:ignore Squiz.Commenting.FunctionComment.EmptyThrows
|
||||
*
|
||||
* @throws HttpResponseException
|
||||
* @throws \Illuminate\Http\Exceptions\HttpResponseException
|
||||
*/
|
||||
public function showProducts(): View
|
||||
public function showProducts(): \Illuminate\Contracts\View\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();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.products';
|
||||
|
||||
return view($view, ['rangeModelList' => $rangeModelList]);
|
||||
return view('theme::pages.products', compact('rangeModelList'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display Faq page
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function showFaq(): View
|
||||
public function showFaq(): \Illuminate\Contracts\View\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();
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.faq';
|
||||
|
||||
return view($view, ['questionModelList' => $questionModelList, 'themeModelList' => $themeModelList]);
|
||||
return view('theme::pages.faq', compact(
|
||||
'questionModelList',
|
||||
'themeModelList'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the teaser page if it is activated
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function teaser(): View | RedirectResponse
|
||||
public function teaser(): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
if (! $settings->should_display_teaser_page) {
|
||||
return to_route('fo.homepage');
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->should_display_teaser_page) {
|
||||
return redirect()->route('fo.homepage');
|
||||
}
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.teaser';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.teaser');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the end game page if it is activated
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function endGame(): View | RedirectResponse
|
||||
public function endGame(): \Illuminate\Contracts\View\View|\Illuminate\Http\RedirectResponse
|
||||
{
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
if (! $settings->should_display_end_page) {
|
||||
return to_route('fo.homepage');
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if (!$settings->should_display_end_page) {
|
||||
return redirect()->route('fo.homepage');
|
||||
}
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.end-game';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.end-game');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
|
@ -9,18 +7,13 @@ 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;
|
||||
|
|
@ -29,15 +22,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
|
||||
{
|
||||
private readonly CrmRepository $crmRepository;
|
||||
|
||||
/** @var \App\Repositories\Fo\CrmRepository $crmRepository */
|
||||
private $crmRepository;
|
||||
/**
|
||||
* ParticipateController
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
|
@ -45,55 +38,53 @@ 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(): View
|
||||
public function participate(): \Illuminate\Contracts\View\View
|
||||
{
|
||||
if (! Gate::check('participate', Participation::class)) {
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.participation-exhausted';
|
||||
return view($view);
|
||||
if (!Gate::check('participate', Participation::class)) {
|
||||
return view('theme::pages.participation.participation-exhausted');
|
||||
}
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.participate';
|
||||
|
||||
return view($view);
|
||||
return view('theme::pages.participation.participate');
|
||||
}
|
||||
|
||||
/**
|
||||
* Participate Method
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\ParticipateRequest $request
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function participateSubmit(ParticipateRequest $request): View
|
||||
public function participateSubmit(ParticipateRequest $request): \Illuminate\Contracts\View\View
|
||||
{
|
||||
return DB::transaction(function () use ($request) {
|
||||
// ! On verrouille le ou les instants gagnant
|
||||
/** @var InstantWin|null */
|
||||
/** @var \App\Models\InstantWin|null */
|
||||
$instantWin = InstantWin::query()->lockForUpdate()
|
||||
->where('available_at', '<', now())
|
||||
->whereDoesntHave('participation')
|
||||
->get()->sortBy('available_at')->first();
|
||||
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
/** @var Customer */
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
/** @var Code|null */
|
||||
/** @var \App\Models\Code|null */
|
||||
$code = $request->post('unique_code');
|
||||
/** @var Product|null */
|
||||
/** @var \App\Models\Product|null */
|
||||
$product = $request->post('product');
|
||||
|
||||
// * Make new participation
|
||||
$participation = Participation::makeNew(
|
||||
resolve('clientIp'),
|
||||
app('clientIp'),
|
||||
$customer,
|
||||
$code,
|
||||
$product
|
||||
|
|
@ -101,21 +92,19 @@ 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) || ! $instantWin) {
|
||||
if (Participation::customerAlreadyHasAnInstantWin($customer) or !$instantWin) {
|
||||
// * --- DISCOUNT WIN ---
|
||||
// ? Les BR sont activés ?
|
||||
if (! $settings->discounts_activated) {
|
||||
if (!$settings->discounts_activated) {
|
||||
// * On enregistre la participation du joueur.
|
||||
$participation->save();
|
||||
|
||||
/** @var view-string $view Pas de coupons disponibles, le joueur à perdu. */
|
||||
$view = 'theme::pages.participation.loose';
|
||||
|
||||
return view($view);
|
||||
// * Pas de coupons disponibles, le joueur à perdu
|
||||
return view('theme::pages.participation.loose');
|
||||
}
|
||||
|
||||
// * 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)
|
||||
|
|
@ -135,11 +124,8 @@ class ParticipateController extends Controller
|
|||
$crmCustomer->firstname
|
||||
));
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won';
|
||||
|
||||
return view($view, ['discount' => $discount]);
|
||||
} // end if
|
||||
return view('theme::pages.participation.won', compact('discount'));
|
||||
} //end if
|
||||
|
||||
// * --- INSTANT WIN ---
|
||||
// * On enregistre la participation du joueur.
|
||||
|
|
@ -162,42 +148,43 @@ class ParticipateController extends Controller
|
|||
$participation->created_at,
|
||||
$instantWin->prize->label,
|
||||
$crmCustomer,
|
||||
$code?->code_unique,
|
||||
$product?->ean_code
|
||||
optional($code)->code_unique,
|
||||
optional($product)->ean_code
|
||||
));
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won';
|
||||
return view($view, [
|
||||
'prizeModel' => $instantWin->prize,
|
||||
return view('theme::pages.participation.won', [
|
||||
'prizeModel' => $instantWin->prize,
|
||||
'participationModel' => $participation,
|
||||
'crmCustomer' => $crmCustomer,
|
||||
'crmCustomer' => $crmCustomer
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
// * --- PRIVATE METHODS ---
|
||||
|
||||
/**
|
||||
* Try Call CRM + MesBr to setup discount
|
||||
*
|
||||
* @throws HttpResponseException If Any error occurs.
|
||||
*
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity
|
||||
* @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
|
||||
*/
|
||||
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 Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
/** @var MesBr */
|
||||
$mesBr = resolve('mesBrAPI');
|
||||
/** @var \LDC\MESBR\MesBr */
|
||||
$mesBr = app('mesBrAPI');
|
||||
|
||||
// * MaJ Customer
|
||||
/** @var string */
|
||||
|
|
@ -208,24 +195,23 @@ 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 ($result?->status !== 'OK') {
|
||||
throw new RuntimeException(
|
||||
if (optional($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 */
|
||||
$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',
|
||||
);
|
||||
/** @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'
|
||||
);
|
||||
}
|
||||
|
||||
return $crm_customer->hashcode;
|
||||
}, 100);
|
||||
|
|
@ -236,11 +222,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),
|
||||
|
|
@ -251,18 +237,20 @@ 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
|
||||
} //end try
|
||||
|
||||
throw new \Error('Should not reach this point');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -270,34 +258,35 @@ class ParticipateController extends Controller
|
|||
* Or redirect him to the fill form
|
||||
* ! Also validates its birth date (because beeing an adult is required to participate)
|
||||
*
|
||||
* @throws HttpResponseException If customer data doest not validate
|
||||
* or and error occurs.
|
||||
* @return void
|
||||
* @throws \Illuminate\Http\Exceptions\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 Customer */
|
||||
/** @var \App\Models\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');
|
||||
|
|
@ -306,13 +295,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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Enums\StaticPageType;
|
||||
|
|
@ -13,44 +11,47 @@ class StaticPageController extends Controller
|
|||
{
|
||||
/**
|
||||
* Show the rules view
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function reglement(): View
|
||||
public function reglement()
|
||||
{
|
||||
$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(): View
|
||||
public function charte()
|
||||
{
|
||||
$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(): View
|
||||
public function legals()
|
||||
{
|
||||
$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
|
||||
{
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.static_page';
|
||||
|
||||
return view($view, [
|
||||
'staticPageModel' => $staticPageModel,
|
||||
return view('theme::pages.static_page', [
|
||||
'staticPageModel' => $staticPageModel
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
<?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;
|
||||
|
|
@ -22,42 +19,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 Customer */
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
||||
/** @var view-string $view */
|
||||
$view = 'theme::pages.participation.won-form-only';
|
||||
|
||||
return view($view, [
|
||||
return view('theme::pages.participation.won-form-only', [
|
||||
'participationModel' => $participation,
|
||||
'prizeModel' => $participation->instantWin->prize,
|
||||
'crmCustomer' => $crmCustomer,
|
||||
'prizeModel' => $participation->instantWin->prize,
|
||||
'crmCustomer' => $crmCustomer
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -67,8 +64,10 @@ 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(
|
||||
|
|
@ -81,14 +80,14 @@ class WinningProofController extends Controller
|
|||
$participation->load([
|
||||
'instantWin.prize',
|
||||
'code',
|
||||
'product',
|
||||
'product'
|
||||
]);
|
||||
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
// * --- PHASE 1 Update Crm Customer ---
|
||||
/** @var Customer */
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
$crmCustomer = $customer->api_data;
|
||||
|
|
@ -119,7 +118,7 @@ class WinningProofController extends Controller
|
|||
$participation->fill(Arr::only($request->validated(), [
|
||||
'barcode',
|
||||
'ticket',
|
||||
'sticker',
|
||||
'sticker'
|
||||
]));
|
||||
$participation->save();
|
||||
|
||||
|
|
@ -131,8 +130,8 @@ class WinningProofController extends Controller
|
|||
$participation->created_at,
|
||||
$participation->instantWin->prize->label,
|
||||
$crmCustomer,
|
||||
$participation->code?->code_unique,
|
||||
$participation->product?->ean_code,
|
||||
optional($participation->code)->code_unique,
|
||||
optional($participation->product)->ean_code,
|
||||
$participation->sticker,
|
||||
$participation->ticket,
|
||||
$participation->barcode,
|
||||
|
|
@ -146,16 +145,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(self::class . '::create reached end of possibilities.');
|
||||
throw new RuntimeException(self::class . '::create reached end of possibilities.', $e->getCode(), $e);
|
||||
Log::error(__CLASS__ . '::create reached end of possibilities.');
|
||||
throw new \RuntimeException(__CLASS__ . '::create reached end of possibilities.');
|
||||
} catch (CrmValidationException $e) {
|
||||
throw IlluminateValidationException::withMessages([
|
||||
'error' => $e->getMessage(),
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
} // end try
|
||||
} //end try
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,37 +1,8 @@
|
|||
<?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
|
||||
{
|
||||
|
|
@ -42,15 +13,14 @@ class Kernel extends HttpKernel
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $middleware = [
|
||||
TrustHosts::class,
|
||||
TrustProxies::class,
|
||||
HandleCors::class,
|
||||
PreventRequestsDuringMaintenance::class,
|
||||
ValidatePostSize::class,
|
||||
TrimStrings::class,
|
||||
ConvertEmptyStringsToNull::class,
|
||||
\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,
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -58,23 +28,22 @@ class Kernel extends HttpKernel
|
|||
*
|
||||
* @var array<string, array<int, string>>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
'htmlsanitize',
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
SubstituteBindings::class,
|
||||
SecureHeaders::class,
|
||||
CheckThemeVersion::class,
|
||||
\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
|
||||
],
|
||||
|
||||
'api' => [
|
||||
ThrottleRequests::class . ':api',
|
||||
SubstituteBindings::class,
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
|
|
@ -85,19 +54,18 @@ class Kernel extends HttpKernel
|
|||
*
|
||||
* @var array<string, string>
|
||||
*/
|
||||
#[\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,
|
||||
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,
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
|
@ -12,25 +10,27 @@ 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) && str_contains($middleware, 'auth:')) {
|
||||
if (\is_string($middleware) and strpos($middleware, 'auth:') !== false) {
|
||||
$route = $logins[str_replace('auth:', '', $middleware)] ?? null;
|
||||
if ($route) {
|
||||
return $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return route('fo.login');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,9 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use RuntimeException;
|
||||
|
||||
class CheckGameStatus
|
||||
{
|
||||
|
|
@ -16,20 +12,21 @@ 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 Settings $settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
return match (true) {
|
||||
// * End page
|
||||
$settings->should_display_end_page => to_route('fo.end'),
|
||||
$settings->should_display_end_page => redirect()->route('fo.end'),
|
||||
// * Teaser
|
||||
$settings->should_display_teaser_page => to_route('fo.teaser'),
|
||||
$settings->should_display_teaser_page => redirect()->route('fo.teaser'),
|
||||
// * Game is ended
|
||||
$settings->game_has_ended => redirect($settings->redirect_close),
|
||||
// * Game has started
|
||||
|
|
|
|||
|
|
@ -1,15 +1,12 @@
|
|||
<?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\File;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
|
|
@ -18,22 +15,27 @@ class CheckThemeVersion
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Closure(Request):Response $next
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request):(\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
public function handle(Request $request, \Closure $next): Response
|
||||
{
|
||||
// phpcs:enable
|
||||
|
||||
if (! app()->runningInConsole()) {
|
||||
$appInfos = Cache::remember('composer', 84600, fn (): mixed => json_decode(File::get(\app_path('../composer.json'))));
|
||||
if (!app()->runningInConsole()) {
|
||||
$appInfos = Cache::remember('composer', 84600, function () {
|
||||
return 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) || Arr::get($appVer, 1) !== Arr::get($themeVer, 1)
|
||||
Arr::get($appVer, 0) !== Arr::get($themeVer, 0) or
|
||||
// * Patch check
|
||||
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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
|
@ -13,6 +11,5 @@ class EncryptCookies extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,8 @@
|
|||
<?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;
|
||||
|
||||
|
|
@ -13,14 +10,19 @@ 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 (
|
||||
|
|
@ -31,14 +33,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) || in_array($rootName ?? $name, $params)) {
|
||||
if (in_array($name, $params) or in_array($rootName ?? $name, $params)) {
|
||||
// ? Is a json input ?
|
||||
if ($isJson = \json_decode($input, true) and is_array($isJson)) {
|
||||
// ! Decode each json field recursive.
|
||||
\array_walk_recursive($isJson, function (string | array &$item): void {
|
||||
\array_walk_recursive($isJson, function (string|array &$item) {
|
||||
if (\is_string($item)) {
|
||||
$item = clean($item);
|
||||
$item = ToolboxHelper::stripCkEditorSchemesOnMediaInputs($item);
|
||||
|
|
@ -54,7 +56,6 @@ class HtmlSanitizer
|
|||
};
|
||||
\array_walk($inputs, $cleanInput);
|
||||
$request->merge($inputs);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
|
@ -13,6 +11,5 @@ class PreventRequestsDuringMaintenance extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $except = [];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,8 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use RuntimeException;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
|
|
@ -14,31 +10,30 @@ class RedirectIfAuthenticated
|
|||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param Closure(Request):Response $next
|
||||
* @param string|null ...$guards
|
||||
*
|
||||
* @throws RuntimeException If guard is unhandled.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
* @param string|null ...$guards
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \RuntimeException If guard is unhandled.
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.IncorrectTypeHint
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, ...$guards): Response
|
||||
public function handle(Request $request, \Closure $next, ...$guards): Response
|
||||
{
|
||||
// phpcs:enable phpcs:disable
|
||||
$guards = $guards === [] ? [null] : $guards;
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (auth($guard)->check()) {
|
||||
switch ($guard) {
|
||||
case 'frontend':
|
||||
return to_route('fo.homepage');
|
||||
return \redirect()->route('fo.homepage');
|
||||
case 'backend':
|
||||
if (! $request->routeIs('bo.*')) {
|
||||
if (!$request->routeIs('bo.*')) {
|
||||
continue 2;
|
||||
}
|
||||
|
||||
return to_route('bo.dashboard');
|
||||
return \redirect()->route('bo.dashboard');
|
||||
default:
|
||||
throw new RuntimeException("Unhandled guard `{$guard}` .");
|
||||
throw new \RuntimeException("Unhandled guard `{$guard}` .");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
|
|
@ -13,7 +11,7 @@ use Symfony\Component\HttpFoundation\Response;
|
|||
|
||||
class SecureHeaders
|
||||
{
|
||||
private array $unwantedHeaderList = [
|
||||
private $unwantedHeaderList = [
|
||||
'X-Powered-By',
|
||||
'Server',
|
||||
];
|
||||
|
|
@ -49,7 +47,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,
|
||||
|
|
@ -58,11 +56,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',
|
||||
'https://fonts.gstatic.com' // <-- Point-virgule retiré ici
|
||||
])) . ';',
|
||||
"style-src 'self' 'unsafe-inline' " . implode(' ', array_filter([
|
||||
'https://cdnjs.cloudflare.com',
|
||||
|
|
@ -78,7 +76,7 @@ class SecureHeaders
|
|||
'https://cdnjs.cloudflare.com',
|
||||
"$scheme://www.google-analytics.com",
|
||||
$viteDevOrigin,
|
||||
])) . ';',
|
||||
])) . ';'
|
||||
];
|
||||
|
||||
$response->headers->set(
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
|
@ -13,7 +11,6 @@ class TrimStrings extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
|
|
@ -14,17 +12,15 @@ class TrustProxies extends Middleware
|
|||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
#[\Override]
|
||||
protected $proxies = '*';
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
* @var integer
|
||||
*/
|
||||
#[\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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
|
@ -13,8 +11,7 @@ class VerifyCsrfToken extends Middleware
|
|||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
#[\Override]
|
||||
protected $except = [
|
||||
'/csp-report',
|
||||
'/csp-report'
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\BannedIps;
|
||||
|
||||
use App\Models\BannedIp;
|
||||
|
|
@ -13,7 +11,7 @@ class StoreBannedIpRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -22,8 +20,10 @@ class StoreBannedIpRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'ip' => 'required|ip|unique:banned_ips,ip',
|
||||
|
|
@ -32,6 +32,8 @@ class StoreBannedIpRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\BannedIps;
|
||||
|
||||
use App\Models\BannedIp;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
|
|
@ -13,7 +10,7 @@ class UpdateBannedIpRequest extends StoreBannedIpRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -22,17 +19,18 @@ class UpdateBannedIpRequest extends StoreBannedIpRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
public function rules()
|
||||
{
|
||||
/** @var BannedIp */
|
||||
/** @var \App\Models\BannedIp */
|
||||
$ipToBanModel = $this->route('banned_ip');
|
||||
|
||||
return [
|
||||
'ip' => [
|
||||
'required', 'ip',
|
||||
Rule::unique('banned_ips', 'ip')
|
||||
->ignore($ipToBanModel->ip, 'ip'),
|
||||
->ignore($ipToBanModel->ip, 'ip')
|
||||
],
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Codes;
|
||||
|
||||
use App\Models\Code;
|
||||
|
|
@ -13,7 +11,7 @@ class CodeSearchRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -28,7 +26,7 @@ class CodeSearchRequest extends FormRequest
|
|||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'code' => 'required|string|min:1|max:25',
|
||||
'code' => 'required|string|min:1|max:25'
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +38,7 @@ class CodeSearchRequest extends FormRequest
|
|||
public function attributes(): array
|
||||
{
|
||||
return [
|
||||
'code' => trans('code'),
|
||||
'code' => trans('code')
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Codes;
|
||||
|
||||
use App\Models\Code;
|
||||
|
|
@ -12,28 +10,31 @@ 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) && $this->json();
|
||||
return Gate::check('export', Code::class) and $this->json();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$codesAvailableToExport = Code::query()->where('code_exported', false);
|
||||
|
||||
/** @var int|null $lastExportedId */
|
||||
$lastExportedId = Code::query()->where('code_exported', true)->max('id');
|
||||
|
||||
/** @var integer|null */
|
||||
$lastExportedId = optional(Code::query()->where('code_exported', true)
|
||||
->orderBy('id', 'desc')->first())->id ?? null;
|
||||
if ($lastExportedId) {
|
||||
$codesAvailableToExport->where('id', '>', $lastExportedId);
|
||||
$codesAvailableToExport = $codesAvailableToExport
|
||||
->where('id', '>', $lastExportedId);
|
||||
}
|
||||
|
||||
$this->merge([
|
||||
'available_export' => $codesAvailableToExport->count(),
|
||||
'available_export' => $codesAvailableToExport->count()
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
@ -45,10 +46,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'
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -60,10 +61,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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Codes;
|
||||
|
||||
use App\Models\Code;
|
||||
|
|
@ -12,10 +10,12 @@ 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) && $this->json();
|
||||
return Gate::check('generate', Code::class) and $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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\FaqQuestions;
|
||||
|
||||
use App\Models\FaqQuestion;
|
||||
|
|
@ -13,7 +11,7 @@ class StoreFaqQuestionRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -22,24 +20,28 @@ class StoreFaqQuestionRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
public function rules()
|
||||
{
|
||||
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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\FaqQuestions;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -11,7 +9,7 @@ class UpdateFaqQuestionRequest extends StoreFaqQuestionRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\FaqThemes;
|
||||
|
||||
use App\Models\FaqTheme;
|
||||
|
|
@ -13,7 +11,7 @@ class StoreFaqThemeRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -22,16 +20,20 @@ class StoreFaqThemeRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
public function rules()
|
||||
{
|
||||
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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\FaqThemes;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -11,7 +9,7 @@ class UpdateFaqThemeRequest extends StoreFaqThemeRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Prizes;
|
||||
|
||||
use App\Models\Prize;
|
||||
|
|
@ -16,7 +14,7 @@ class StorePrizeRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -25,34 +23,37 @@ 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(): array
|
||||
public function rules()
|
||||
{
|
||||
$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),
|
||||
|
|
@ -61,18 +62,20 @@ 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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Prizes;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -11,7 +9,7 @@ class UpdatePrizeRequest extends StorePrizeRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Products;
|
||||
|
||||
use App\Models\Product;
|
||||
|
|
@ -17,7 +15,7 @@ class StoreProductRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -36,11 +34,13 @@ class StoreProductRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'name' => 'required|string|min:3|max:255',
|
||||
'ean_code' => [
|
||||
'required',
|
||||
'unique:products,ean_code',
|
||||
|
|
@ -48,11 +48,10 @@ 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),
|
||||
|
|
@ -61,26 +60,28 @@ 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,10 +1,7 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Products;
|
||||
|
||||
use App\Models\Product;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
|
|
@ -13,7 +10,7 @@ class UpdateProductRequest extends StoreProductRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -22,12 +19,13 @@ class UpdateProductRequest extends StoreProductRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
public function rules()
|
||||
{
|
||||
/** @var Product */
|
||||
/** @var \App\Models\Product */
|
||||
$productModel = $this->route('product');
|
||||
|
||||
return array_merge(parent::rules(), [
|
||||
'ean_code' => [
|
||||
'required',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Ranges;
|
||||
|
||||
use App\Models\Range;
|
||||
|
|
@ -16,7 +14,7 @@ class StoreRangeRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -35,8 +33,10 @@ class StoreRangeRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
'name' => 'required|string|min:2|max:255',
|
||||
|
|
@ -45,7 +45,6 @@ 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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Ranges;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
|
@ -11,7 +9,7 @@ class UpdateRangeRequest extends StoreRangeRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Settings;
|
||||
|
||||
use App\Enums\CodeType;
|
||||
|
|
@ -10,13 +8,15 @@ use Illuminate\Foundation\Http\FormRequest;
|
|||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use LDC\LDCCRM\Enums\Country;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
|
||||
class UpdateSettingsRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
|
|
@ -25,6 +25,8 @@ class UpdateSettingsRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
|
|
@ -52,46 +54,48 @@ 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): void {
|
||||
if ($this->post('discounts_activated') && ! collect($value)->filter()->count()) {
|
||||
'present', 'array', function ($attribute, $value, $fail) {
|
||||
if ($this->post('discounts_activated') and !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',
|
||||
|
|
@ -99,7 +103,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, ?string $value, callable $fail): void {
|
||||
'required', function (string $attribute, $value, callable $fail) {
|
||||
ToolboxHelper::validatePicture(
|
||||
$attribute,
|
||||
$value,
|
||||
|
|
@ -108,17 +112,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',
|
||||
|
|
@ -127,6 +131,8 @@ class UpdateSettingsRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
<?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;
|
||||
|
|
@ -14,7 +11,7 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -23,18 +20,20 @@ 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, ValidationRule|array<mixed>|string>
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
@ -48,6 +47,8 @@ class UpdateStaticPageRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
|
@ -10,6 +8,8 @@ class UpdateChangeOrderRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
|
|
@ -18,16 +18,20 @@ class UpdateChangeOrderRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Prepare the data for validation.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareForValidation(): void
|
||||
{
|
||||
$this->merge([
|
||||
'direction' => $this->route('direction') === 'up',
|
||||
'direction' => $this->route('direction') === 'up' ? true : false
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Bo\Users;
|
||||
|
||||
use App\Enums\Users\RoleEnum;
|
||||
|
|
@ -16,7 +14,7 @@ class StoreUserRequest extends FormRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -31,44 +29,48 @@ 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,10 +1,7 @@
|
|||
<?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;
|
||||
|
|
@ -14,7 +11,7 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
|
|
@ -28,32 +25,33 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
*/
|
||||
protected function prepareForValidation()
|
||||
{
|
||||
/** @var User */
|
||||
/** @var \App\Models\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 User */
|
||||
/** @var \App\Models\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)
|
||||
|
|
@ -61,7 +59,7 @@ class UpdateUserRequest extends StoreUserRequest
|
|||
->mixedCase()
|
||||
->numbers()
|
||||
->symbols()
|
||||
->uncompromised(),
|
||||
->uncompromised()
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,10 @@
|
|||
<?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;
|
||||
|
|
@ -22,6 +18,8 @@ class CreateAccountRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
|
|
@ -30,30 +28,35 @@ 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 Settings $settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(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',
|
||||
|
|
@ -102,13 +105,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): void {
|
||||
if (CrmCustomer::findWithEmail(\strval($value)) instanceof CrmCustomer) {
|
||||
function (string $attribute, $value, \Closure $fail) {
|
||||
if (CrmCustomer::findWithEmail(\strval($value))) {
|
||||
$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 = Customer::where('email', \strval($value))->first();
|
||||
$localCustomer = \App\Models\Customer::where('email', \strval($value))->first();
|
||||
if ($localCustomer) {
|
||||
$localCustomer->delete();
|
||||
}
|
||||
|
|
@ -120,7 +123,7 @@ class CreateAccountRequest extends FormRequest
|
|||
'required',
|
||||
'confirmed',
|
||||
Password::min(8)->mixedCase()
|
||||
->numbers()->symbols()->uncompromised(),
|
||||
->numbers()->symbols()->uncompromised()
|
||||
],
|
||||
'ok_cgv' => 'accepted',
|
||||
'opt_in' => 'required|boolean',
|
||||
|
|
@ -129,6 +132,8 @@ class CreateAccountRequest extends FormRequest
|
|||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
@ -152,28 +157,30 @@ 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.'),
|
||||
]; // end match
|
||||
'ok_cgv.accepted' => trans('Vous devez accepter les conditions d\'utilisation du site pour continuer.')
|
||||
];
|
||||
|
||||
return match ($this->integer('country')) {
|
||||
$messages = match ($this->integer('country')) {
|
||||
Country::belgium->value => array_merge(
|
||||
$messages,
|
||||
[
|
||||
'postal_code' => trans('validation.postal_code', [
|
||||
'countries' => Country::belgium->label(),
|
||||
'examples' => 1000,
|
||||
'examples' => 1000
|
||||
]),
|
||||
]
|
||||
),
|
||||
|
|
@ -182,7 +189,7 @@ class CreateAccountRequest extends FormRequest
|
|||
[
|
||||
'postal_code' => trans('validation.postal_code', [
|
||||
'countries' => Country::luxembourg->label(),
|
||||
'examples' => 1111,
|
||||
'examples' => 1111
|
||||
]),
|
||||
]
|
||||
),
|
||||
|
|
@ -191,7 +198,7 @@ class CreateAccountRequest extends FormRequest
|
|||
[
|
||||
'postal_code' => trans('validation.postal_code', [
|
||||
'countries' => Country::germany->label(),
|
||||
'examples' => 10115,
|
||||
'examples' => 10115
|
||||
]),
|
||||
]
|
||||
),
|
||||
|
|
@ -207,10 +214,12 @@ class CreateAccountRequest extends FormRequest
|
|||
array_search(Country::germany->label(), Country::getValidCountriesLabel()),
|
||||
]
|
||||
)),
|
||||
'examples' => 72000,
|
||||
'examples' => 72000
|
||||
]),
|
||||
]
|
||||
),
|
||||
};
|
||||
}; //end match
|
||||
|
||||
return $messages;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Requests\Fo\Customers;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
|
@ -10,16 +8,20 @@ class SingleOptinRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules(): array
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'required|email:rfc,dns,spoof',
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
<?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
|
||||
{
|
||||
|
|
@ -20,7 +19,7 @@ class VerifyInformationsRequest extends CreateAccountRequest
|
|||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
<?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;
|
||||
|
|
@ -22,27 +19,30 @@ class ParticipateRequest extends FormRequest
|
|||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
/** @var Customer */
|
||||
/** @var \App\Models\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 Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if ($settings->code_type->equals(CodeType::unique) || $settings->code_type->equals(CodeType::both)) {
|
||||
try {
|
||||
$this->merge([
|
||||
|
|
@ -83,16 +83,18 @@ 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 Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
$rules = [
|
||||
'game_rules' => 'required|boolean|accepted',
|
||||
|
|
@ -103,18 +105,17 @@ class ParticipateRequest extends FormRequest
|
|||
$rules = \array_merge($rules, ['unique_code' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function (string $attribute, $value, callable $fail): void {
|
||||
function (string $attribute, $value, callable $fail) {
|
||||
// ? Le Code unique est resolved ?
|
||||
if ($value === false || ! \is_object($value) || $value::class !== Code::class) {
|
||||
if ($value === false or !\is_object($value) or \get_class($value) !== Code::class) {
|
||||
$fail(trans('front.messages.unique_code_invalid'));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/** @var Customer */
|
||||
/** @var \App\Models\Customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
/** @var Code $value */
|
||||
/** @var \App\Models\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))
|
||||
|
|
@ -122,7 +123,6 @@ 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,36 +131,37 @@ 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)) {
|
||||
return \array_merge($rules, ['ean_code' => [
|
||||
$rules = \array_merge($rules, ['ean_code' => [
|
||||
'required',
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail): void {
|
||||
function ($attribute, $value, $fail) {
|
||||
// phpcs:enable
|
||||
/** @var \App\Models\Produt|mixed */
|
||||
$product = $this->input('product');
|
||||
if (
|
||||
empty($product) || ! is_object($product) || ! ($product instanceof Model) || ! $product->exists
|
||||
empty($product) or !is_object($product) or
|
||||
!($product instanceof Model) or !$product->exists
|
||||
) {
|
||||
$fail(trans('front.messages.barcode_invalid'));
|
||||
}
|
||||
},
|
||||
}
|
||||
]]);
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,9 @@
|
|||
<?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;
|
||||
|
|
@ -15,23 +12,26 @@ 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, ValidationRule|array<mixed>|string>
|
||||
* @return array<string, \Illuminate\Contracts\Validation\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,12 +75,14 @@ class SubmitWinningProofRequest extends CreateAccountRequest
|
|||
|
||||
return collect(['sticker', 'ticket', 'barcode'])
|
||||
->filter(fn (string $proof) => config("proofs.$proof"))
|
||||
->mapWithKeys(fn (string $proof): array => [$proof => $fileRules])
|
||||
->mapWithKeys(fn (string $proof) => [$proof => $fileRules])
|
||||
->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get custom attributes for validator errors.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function attributes(): array
|
||||
{
|
||||
|
|
@ -88,7 +90,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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Jobs\DeleteOlds;
|
||||
|
||||
use App\Models\Customer;
|
||||
|
|
@ -14,10 +12,12 @@ class DeleteOldCustomers
|
|||
{
|
||||
/**
|
||||
* Called when the job will be executed.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
public function handle()
|
||||
{
|
||||
Log::debug(self::class . ' Removing old customers');
|
||||
Log::debug(__CLASS__ . ' Removing old customers');
|
||||
Customer::query()->withTrashed()->where('last_connection', '<=', now()->subMonths(36))->forceDelete();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,33 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Mail\Jobs\CodeExportSucceed;
|
||||
use App\Mail\Jobs\JobFailed;
|
||||
use App\Models\Code;
|
||||
use Exception;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Queue\Queueable;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Throwable;
|
||||
use ZipArchive;
|
||||
|
||||
class ProcessExportCodesUniques implements ShouldBeUnique, ShouldQueue
|
||||
class ProcessExportCodesUniques implements ShouldQueue, ShouldBeUnique
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of seconds the job can run before timing out.
|
||||
*
|
||||
* 28800 seconds (8 hours)
|
||||
*
|
||||
* @var int
|
||||
* @var integer
|
||||
*/
|
||||
public $timeout = 28800;
|
||||
|
||||
|
|
@ -35,14 +36,15 @@ class ProcessExportCodesUniques implements ShouldBeUnique, ShouldQueue
|
|||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $exportFileName;
|
||||
protected $exportFileName = null;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @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 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
|
||||
*/
|
||||
public function __construct(
|
||||
protected int $nbCodeFic,
|
||||
|
|
@ -53,10 +55,12 @@ class ProcessExportCodesUniques implements ShouldBeUnique, ShouldQueue
|
|||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
public function handle()
|
||||
{
|
||||
DB::transaction(function (): void {
|
||||
DB::transaction(function () {
|
||||
$this->exportFileName = sprintf(
|
||||
'CodesUniques_%s',
|
||||
date('dmY_His')
|
||||
|
|
@ -72,8 +76,8 @@ class ProcessExportCodesUniques implements ShouldBeUnique, ShouldQueue
|
|||
$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));
|
||||
|
|
@ -96,22 +100,21 @@ class ProcessExportCodesUniques implements ShouldBeUnique, ShouldQueue
|
|||
$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 int|null $lastExportedCodeId
|
||||
* @param integer|null $lastExportedCodeId
|
||||
* @return array Array of temp files
|
||||
*
|
||||
* @phpcs:disable Generic.Metrics.CyclomaticComplexity.TooHigh
|
||||
*/
|
||||
private function generateCsvFiles($lastExportedCodeId = null): array
|
||||
|
|
@ -149,7 +152,7 @@ class ProcessExportCodesUniques implements ShouldBeUnique, ShouldQueue
|
|||
} else {
|
||||
File::append($tempFilePath, Code::intToSerial($code) . ';');
|
||||
$currentLineCodes++;
|
||||
} // end if
|
||||
} //end if
|
||||
|
||||
$totalExportedCodes++;
|
||||
$currentExportedCodes++;
|
||||
|
|
@ -172,26 +175,29 @@ class ProcessExportCodesUniques implements ShouldBeUnique, ShouldQueue
|
|||
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): void
|
||||
public function failed(\Throwable $exception)
|
||||
{
|
||||
Mail::to(config('mail.admin'))->send(
|
||||
new JobFailed(self::class, [
|
||||
new JobFailed(__CLASS__, [
|
||||
'message' => $exception->getMessage(),
|
||||
'trace' => $exception->getTraceAsString(),
|
||||
'trace' => $exception->getTraceAsString()
|
||||
])
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,43 @@
|
|||
<?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\Queue\Queueable;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Throwable;
|
||||
|
||||
class ProcessUniqueCode implements ShouldBeUnique, ShouldQueue
|
||||
class ProcessUniqueCode implements ShouldQueue, ShouldBeUnique
|
||||
{
|
||||
use Dispatchable;
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
|
||||
/**
|
||||
* The number of seconds the job can run before timing out.
|
||||
*
|
||||
* 7200 seconds (2 hours)
|
||||
*
|
||||
* @var int
|
||||
* @var integer
|
||||
*/
|
||||
public $timeout = 7200;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param int $amount Amount of code to generate.
|
||||
* @param int $length Length of each code to generate.
|
||||
* @param integer $amount Amount of code to generate.
|
||||
* @param integer $length Length of each code to generate.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(protected int $amount, protected int $length)
|
||||
{
|
||||
|
|
@ -41,29 +45,38 @@ class ProcessUniqueCode implements ShouldBeUnique, ShouldQueue
|
|||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(): void
|
||||
public function handle()
|
||||
{
|
||||
DB::transaction(function (): void {
|
||||
DB::transaction(function () {
|
||||
// ! Le premier code commence à 1
|
||||
$last_id = (Code::query()->max('id') ?? 0) + 1;
|
||||
|
||||
/** @var Settings $settings */
|
||||
$settings = resolve(Settings::class);
|
||||
/** @var \App\Models\Settings $settings */
|
||||
$settings = app(Settings::class);
|
||||
|
||||
$maxSQLPlaceholders = 65535;
|
||||
|
||||
$insertColumns = collect(DB::getSchemaBuilder()
|
||||
->getColumnListing(new Code()->getTable()))
|
||||
->reject(fn ($name): bool => in_array($name, ['id', 'code_exported']))->count() + 1;
|
||||
->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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
|
|
@ -74,7 +87,7 @@ class ProcessUniqueCode implements ShouldBeUnique, ShouldQueue
|
|||
$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);
|
||||
|
|
@ -95,13 +108,16 @@ class ProcessUniqueCode implements ShouldBeUnique, ShouldQueue
|
|||
|
||||
/**
|
||||
* In case of job failure
|
||||
*
|
||||
* @param \Throwable $exception
|
||||
* @return void
|
||||
*/
|
||||
public function failed(Throwable $exception): void
|
||||
public function failed(\Throwable $exception)
|
||||
{
|
||||
Mail::to(config('mail.admin'))->send(
|
||||
new JobFailed(self::class, [
|
||||
new JobFailed(__CLASS__, [
|
||||
'message' => $exception->getMessage(),
|
||||
'trace' => $exception->getTraceAsString(),
|
||||
'trace' => $exception->getTraceAsString()
|
||||
])
|
||||
);
|
||||
}
|
||||
|
|
@ -114,8 +130,8 @@ class ProcessUniqueCode implements ShouldBeUnique, ShouldQueue
|
|||
public function middleware(): array
|
||||
{
|
||||
return [
|
||||
new WithoutOverlapping('code_generation')
|
||||
->releaseAfter(60),
|
||||
(new WithoutOverlapping('code_generation'))
|
||||
->releaseAfter(60)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,30 +1,24 @@
|
|||
<?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 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.
|
||||
* @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
|
||||
*/
|
||||
class Discount extends stdClass implements Arrayable, Jsonable, JsonSerializable
|
||||
class Discount extends \stdClass implements Jsonable, Arrayable, \JsonSerializable
|
||||
{
|
||||
/**
|
||||
* Properties list
|
||||
|
|
@ -42,31 +36,33 @@ class Discount extends stdClass implements Arrayable, Jsonable, JsonSerializable
|
|||
/**
|
||||
* Get property
|
||||
*
|
||||
*
|
||||
* @throws TypeError If prop is undefined.
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
* @throws \TypeError If prop is undefined.
|
||||
*/
|
||||
public function __get(string $name): mixed
|
||||
public function __get(string $name)
|
||||
{
|
||||
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 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.
|
||||
* @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.
|
||||
*
|
||||
* @throws RuntimeException If $type or $data is wrong.
|
||||
* @return \App\Lib\Discount
|
||||
* @throws \RuntimeException If $type or $data is wrong.
|
||||
*/
|
||||
public static function make(
|
||||
string $picture,
|
||||
|
|
@ -82,42 +78,54 @@ class Discount extends stdClass implements Arrayable, Jsonable, JsonSerializable
|
|||
$ipTypeData->valid_on = $valid_on;
|
||||
$ipTypeData->picture = $picture;
|
||||
self::assertIsInputTypeData($ipTypeData);
|
||||
|
||||
return $ipTypeData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm $data is of type InputTypeData
|
||||
*
|
||||
*
|
||||
* @throws RuntimeException If $data is wrong.
|
||||
* @param \App\Lib\Discount $data
|
||||
* @return void
|
||||
* @throws \RuntimeException If $data is wrong.
|
||||
*/
|
||||
public static function assertIsInputTypeData(Discount $data): void
|
||||
public static function assertIsInputTypeData(Discount $data)
|
||||
{
|
||||
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");
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
// * TRANSFORMERS
|
||||
|
||||
/**
|
||||
* Get the instance as an array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
return collect(Arr::mapWithKeys(self::$propertiesList, fn (string $property): array => [
|
||||
$property => $this->{$property},
|
||||
return collect(Arr::mapWithKeys(self::$propertiesList, fn (string $property) => [
|
||||
$property => $this->{$property}
|
||||
]))->filter()->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to its JSON representation.
|
||||
*
|
||||
* @param int $options
|
||||
*
|
||||
* @param integer $options
|
||||
* @return string
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.ScalarTypeHintMissing
|
||||
*/
|
||||
public function toJson($options = 0): string
|
||||
|
|
@ -131,7 +139,7 @@ class Discount extends stdClass implements Arrayable, Jsonable, JsonSerializable
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
#[ReturnTypeWillChange]
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize()
|
||||
{
|
||||
return $this->toArray();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
|
|
@ -13,6 +11,10 @@ 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
|
||||
{
|
||||
|
|
@ -23,13 +25,18 @@ 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',
|
||||
]);
|
||||
}
|
||||
|
|
@ -37,16 +44,21 @@ class CollectionHelper
|
|||
/**
|
||||
* Create a new length-aware paginator instance.
|
||||
*
|
||||
* @return LengthAwarePaginator
|
||||
* @param \Illuminate\Support\Collection $items
|
||||
* @param integer $total
|
||||
* @param integer $perPage
|
||||
* @param integer $currentPage
|
||||
* @param array $options
|
||||
* @return \Illuminate\Pagination\LengthAwarePaginator
|
||||
*/
|
||||
protected static function paginator(Collection $items, int $total, int $perPage, int $currentPage, array $options)
|
||||
{
|
||||
return Container::getInstance()->makeWith(LengthAwarePaginator::class, [
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'perPage' => $perPage,
|
||||
'items' => $items,
|
||||
'total' => $total,
|
||||
'perPage' => $perPage,
|
||||
'currentPage' => $currentPage,
|
||||
'options' => $options,
|
||||
'options' => $options
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,56 +1,55 @@
|
|||
<?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(Event $event): ?Event
|
||||
public static function sentryEventHandler(\Sentry\Event $event): ?\Sentry\Event
|
||||
{
|
||||
// Remove unwanted reports.
|
||||
$event->setModules([]);
|
||||
$event->setOsContext(null);
|
||||
|
||||
/** @var ExceptionDataBag[] */
|
||||
/** @var \Sentry\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(
|
||||
ExceptionDataBag $exceptionDataBag
|
||||
): ExceptionDataBag {
|
||||
\Sentry\ExceptionDataBag $exceptionDataBag
|
||||
): \Sentry\ExceptionDataBag {
|
||||
$exceptionDataBag->setValue(self::getAnonymizedMessage($exceptionDataBag->getValue()));
|
||||
if (($stackTrace = $exceptionDataBag->getStacktrace()) instanceof Stacktrace) {
|
||||
if ($stackTrace = $exceptionDataBag->getStacktrace()) {
|
||||
$exceptionDataBag->setStacktrace(self::getAnonymizedSentryStackTrace($stackTrace));
|
||||
}
|
||||
|
||||
return $exceptionDataBag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Anonymise sentry stacktrace
|
||||
*
|
||||
* @param \Sentry\Stacktrace $stackTrace
|
||||
* @return \Sentry\Stacktrace
|
||||
*/
|
||||
private static function getAnonymizedSentryStackTrace(Stacktrace $stackTrace): Stacktrace
|
||||
private static function getAnonymizedSentryStackTrace(\Sentry\Stacktrace $stackTrace): \Sentry\Stacktrace
|
||||
{
|
||||
/** @var Frame[] */
|
||||
/** @var \Sentry\Frame[] */
|
||||
$frames = \array_reverse($stackTrace->getFrames(), true);
|
||||
$i = \count($frames) - 1;
|
||||
// * Remove all but keep first (index.php).
|
||||
|
|
@ -67,14 +66,13 @@ 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
|
||||
|
|
@ -88,44 +86,46 @@ class ExceptionsHelper
|
|||
case $type === 'lambda':
|
||||
case $type === 'object':
|
||||
continue 2;
|
||||
case $type === 'array' && \is_array($param):
|
||||
case $type === 'array' and \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')) {
|
||||
return \mb_strcut($message, 0, $sqlPos);
|
||||
$message = \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,15 +152,17 @@ 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
|
||||
{
|
||||
|
|
@ -168,15 +170,21 @@ class ExceptionsHelper
|
|||
$argsCount = count($stack['args']);
|
||||
for ($i = 0; $i < $argsCount; $i++) {
|
||||
$type = \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]),
|
||||
};
|
||||
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]);
|
||||
}
|
||||
$traceArgs .= ($i !== ($argsCount - 1) ? ',' : '');
|
||||
}
|
||||
|
||||
return $traceArgs;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,17 +1,11 @@
|
|||
<?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
|
||||
|
|
@ -39,25 +33,28 @@ 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 FilesystemAdapter */
|
||||
/** @var \Illuminate\Filesystem\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 (! str_starts_with($path, 'storage')) {
|
||||
if (\strpos($path, 'storage') !== 0) {
|
||||
return;
|
||||
}
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', $path);
|
||||
|
|
@ -68,15 +65,20 @@ 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 && $model->{$attribute} === ToolboxHelper::getOriginal($model, $attribute)) {
|
||||
if ($onlyIfUpdated and $model->{$attribute} === ToolboxHelper::getOriginal($model, $attribute)) {
|
||||
return;
|
||||
}
|
||||
$originalPath = \ltrim(\urldecode(ToolboxHelper::getOriginal($model, $attribute)), '/');
|
||||
if (! str_starts_with($originalPath, 'storage')) {
|
||||
if (\strpos($originalPath, 'storage') !== 0) {
|
||||
return;
|
||||
}
|
||||
$originalPath = ToolboxHelper::mbReplace('storage/', '', $originalPath);
|
||||
|
|
@ -90,39 +92,37 @@ class FileStorageHelper
|
|||
*
|
||||
* You can use filename param to overload file name.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
* @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 ($file instanceof UploadedFile) {
|
||||
/** @var UploadedFile $file */
|
||||
if (\is_object($file) and $file instanceof \Illuminate\Http\UploadedFile) {
|
||||
/** @var \Illuminate\Http\UploadedFile $file */
|
||||
$filename = $filename ?: $file->getClientOriginalName();
|
||||
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
|
||||
$newPath = self::prepareMoveFile($tableName, $filename, $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,25 +132,23 @@ class FileStorageHelper
|
|||
);
|
||||
|
||||
return str_replace('/private/', '', $newPath);
|
||||
} // end if
|
||||
if ($file instanceof SplFileInfo) {
|
||||
/** @var SplFileInfo $file */
|
||||
} //end if
|
||||
if (\is_object($file) and $file instanceof \SplFileInfo) {
|
||||
/** @var \SplFileInfo $file */
|
||||
$filename = $filename ?: $file->getBaseName();
|
||||
$filename = $slugify ? self::slugifyFileName($filename) : $filename;
|
||||
$newPath = self::prepareMoveFile($tableName, $filename, $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);
|
||||
}
|
||||
|
||||
|
|
@ -159,22 +157,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 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 \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.
|
||||
* @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): void {
|
||||
/** @var FilesystemAdapter */
|
||||
->each(function (string $path) use ($model, &$htmlString) {
|
||||
/** @var \Illuminate\Filesystem\FilesystemAdapter */
|
||||
$disk = Storage::disk('uploads');
|
||||
$fileInfo = new SplFileInfo($disk->path(
|
||||
$fileInfo = new \SplFileInfo($disk->path(
|
||||
ToolboxHelper::mbReplace('/uploads/', '', \urldecode($path))
|
||||
));
|
||||
$htmlString = ToolboxHelper::mbReplace(
|
||||
|
|
@ -195,8 +193,9 @@ 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.
|
||||
* @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
|
||||
*/
|
||||
public static function removeOldModelFilesFromHtml(string $newHtmlString, string $oldHtmlString): void
|
||||
{
|
||||
|
|
@ -207,15 +206,16 @@ 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.
|
||||
* @param string[] $oldFiles The old array files.
|
||||
* @param string[] $newFiles The new array files.
|
||||
* @return void
|
||||
*/
|
||||
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): void {
|
||||
$filesToRemove->each(function (string $publicStorageFilePath) {
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
|
|
@ -226,12 +226,13 @@ 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.
|
||||
* @param string $htmlString The html string with alreadyParsed files using storeModelFilesFromHtml.
|
||||
* @return void
|
||||
*/
|
||||
public static function removeModelFilesOfHtml(string $htmlString): void
|
||||
{
|
||||
$filesToRemove = \collect(self::onlyUploadedFilesWithFileStorageHelper(self::findFilesInHtml($htmlString)));
|
||||
$filesToRemove->each(function (string $publicStorageFilePath): void {
|
||||
$filesToRemove->each(function (string $publicStorageFilePath) {
|
||||
$path = ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($publicStorageFilePath), '/'));
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
Storage::disk('public')->delete($path);
|
||||
|
|
@ -241,11 +242,13 @@ 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())
|
||||
|
|
@ -255,18 +258,19 @@ 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): bool {
|
||||
->filter(function (string $url) {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
|
||||
return str_starts_with(\ltrim($path, '/'), 'storage/modelfiles');
|
||||
return \strpos(\ltrim($path, '/'), 'storage/modelfiles') === 0;
|
||||
})->filter(function (string $url) {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
|
||||
return Storage::disk('public')
|
||||
->exists(ToolboxHelper::mbReplace('storage/', '', \ltrim(\urldecode($path), '/')));
|
||||
})->all();
|
||||
|
|
@ -275,19 +279,21 @@ 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): bool {
|
||||
->filter(function (string $url) {
|
||||
$host = \parse_url($url, \PHP_URL_HOST);
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
|
||||
return ($host === \parse_url(config('app.url'), PHP_URL_HOST) || \is_null($host)) && str_starts_with(\ltrim($path, '/'), 'uploads');
|
||||
return ($host === \parse_url(config('app.url'), PHP_URL_HOST) or \is_null($host)) and
|
||||
\strpos(\ltrim($path, '/'), 'uploads') === 0;
|
||||
})->filter(function (string $url) {
|
||||
$path = \parse_url($url, \PHP_URL_PATH);
|
||||
|
||||
return Storage::disk('uploads')
|
||||
->exists(ToolboxHelper::mbReplace('uploads/', '', \ltrim(\urldecode($path), '/')));
|
||||
})->all();
|
||||
|
|
@ -297,9 +303,10 @@ 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 bool $private May the file be stored in a private dir.
|
||||
* @param string $tableName Model table name.
|
||||
* @param string $filename The basename for the file.
|
||||
* @param boolean $private May the file be stored in a private dir.
|
||||
* @return string
|
||||
*/
|
||||
private static function prepareMoveFile(string $tableName, string $filename, bool $private = false): string
|
||||
{
|
||||
|
|
@ -318,7 +325,6 @@ class FileStorageHelper
|
|||
$filename,
|
||||
);
|
||||
$filename = self::getFileUniqueName($folderPath, $filename);
|
||||
|
||||
return "{$folderPath}/{$filename}";
|
||||
}
|
||||
|
||||
|
|
@ -326,6 +332,11 @@ 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
|
||||
{
|
||||
|
|
@ -339,34 +350,40 @@ 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
|
||||
*
|
||||
* @throws RuntimeException If a unique filename cannot be obtained.
|
||||
* @param string $folderPath
|
||||
* @param string $filename
|
||||
* @return string
|
||||
* @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}")) {
|
||||
throw_if($attempts++ >= $maxAttempts, RuntimeException::class, "Failed to have a unique filename for {$folderPath}/{$filename}");
|
||||
if ($attempts++ >= $maxAttempts) {
|
||||
throw new \RuntimeException("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
|
||||
{
|
||||
|
|
@ -376,8 +393,8 @@ class FileStorageHelper
|
|||
/**
|
||||
* Sanitize File name for uploaded files
|
||||
*
|
||||
* @param string $filename The original uploaded client file name.
|
||||
* @param bool $beautify Beautify the filename.
|
||||
* @param string $filename The original uploaded client file name.
|
||||
* @param boolean $beautify Beautify the filename.
|
||||
* @return string The sanitized file name.
|
||||
*/
|
||||
public static function sanitizeFileName(string $filename, bool $beautify = true): string
|
||||
|
|
@ -400,7 +417,7 @@ class FileStorageHelper
|
|||
$filename = Str::of($filename)->ltrim('.-');
|
||||
// * Optional beautification
|
||||
if ($beautify) {
|
||||
$filename = self::beautifyFilename($filename->value());
|
||||
$filename = self::beautifyFilename($filename);
|
||||
}
|
||||
// * Maximize filename length to 255 bytes http://serverfault.com/a/9548/44086
|
||||
/** @var string */
|
||||
|
|
@ -409,18 +426,20 @@ class FileStorageHelper
|
|||
$filename = pathinfo($filename, \PATHINFO_FILENAME);
|
||||
|
||||
$encoding = mb_detect_encoding($filename);
|
||||
$encoding = $encoding ?: null;
|
||||
|
||||
$encoding = $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
|
||||
{
|
||||
|
|
@ -431,19 +450,18 @@ 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,84 +1,75 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Lib\Helpers;
|
||||
|
||||
use App\Models\Settings;
|
||||
use Exception;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Process\Exceptions\ProcessTimedOutException;
|
||||
use Illuminate\Support\Str;
|
||||
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 RuntimeException;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Process\Exception\LogicException;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
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 bool $throw Wether to throw en esception on failure or not.
|
||||
* @param array|string $command The command to execute on terminal.
|
||||
* @param boolean $throw Wether to throw en esception on failure or not.
|
||||
* @return string|false Return false on failure only if $throw is false.
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionComment.EmptyThrows
|
||||
*
|
||||
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
|
||||
*
|
||||
* @throws ProcessTimedOutException
|
||||
* @throws LogicException
|
||||
* @throws InvalidArgumentException
|
||||
* @throws \Illuminate\Process\Exceptions\ProcessTimedOutException
|
||||
* @throws \Symfony\Component\Process\Exception\LogicException
|
||||
* @throws \Symfony\Component\Process\Exception\InvalidArgumentException
|
||||
* @throws \Symfony\Component\Process\Exception\RuntimeException
|
||||
* @throws \LogicException
|
||||
* @throws RuntimeException If the command fails.
|
||||
* @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 = Process::command($command)->run();
|
||||
$process = \Illuminate\Support\Facades\Process::command($command)->run();
|
||||
if ($process->failed()) {
|
||||
$code = $process->exitCode();
|
||||
$ouput = $process->errorOutput();
|
||||
throw_if($throw, RuntimeException::class, "Failed to run command exit code {$code} with output \n{$ouput}");
|
||||
|
||||
if ($throw) {
|
||||
throw new \RuntimeException("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
|
||||
*
|
||||
* @throws RuntimeException If game has started.
|
||||
* @return void
|
||||
* @throws \RuntimeException If game has started.
|
||||
*/
|
||||
public static function assertGameIsNotOppened(): void
|
||||
{
|
||||
/** @var Settings */
|
||||
$settings = resolve(Settings::class);
|
||||
throw_if($settings->game_is_open, RuntimeException::class, 'Cannot delete prize while game is oppened');
|
||||
/** @var \App\Models\Settings */
|
||||
$settings = app(Settings::class);
|
||||
if ($settings->game_is_open) {
|
||||
throw new \RuntimeException('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
|
||||
|
|
@ -96,69 +87,89 @@ class ToolboxHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Validate recaptcha.
|
||||
* Validate recaptcha
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param boolean $isV3
|
||||
* @return void
|
||||
*/
|
||||
public static function validateRecaptcha(Request $request, bool $isV3 = true): void
|
||||
public static function validateRecaptcha(Request $request, bool $isV3 = true)
|
||||
{
|
||||
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): void {
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed, Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed
|
||||
function ($attribute, $value, $fail) use ($isV3) {
|
||||
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' => resolve('clientIp'),
|
||||
'remoteip' => app('clientIp')
|
||||
]);
|
||||
throw_if($e = $response->toException(), $e);
|
||||
if ($e = $response->toException()) {
|
||||
throw $e;
|
||||
}
|
||||
if ($isV3) {
|
||||
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 (
|
||||
!$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();
|
||||
}
|
||||
if (\floatval($response->json('score')) < 0.8) {
|
||||
$fail(trans('recaptcha.not_enough_score'));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
$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
|
||||
{
|
||||
return \preg_replace('/(?<=<oembed url=")(https:\/\/)(?=.*?">)/m', '', $input);
|
||||
$input = \preg_replace('/(?<=<oembed url=")(https:\/\/)(?=.*?">)/m', '', $input);
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That no Back Office url is present on txt.
|
||||
* Assert That no Back Office url is present on txt
|
||||
*
|
||||
* @throws ValidationException If url is a bo url.
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalBoUrls(string $field, string $text): string
|
||||
{
|
||||
$routes = Route::getRoutes();
|
||||
// * Url replace and email replace.
|
||||
$text = preg_replace_callback(
|
||||
// @phpcs:ignore Generic.Files.LineLength.TooLong
|
||||
// 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() ?? '';
|
||||
|
|
@ -167,33 +178,34 @@ 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) {
|
||||
} catch (NotFoundHttpException $e) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert That only external url is present on txt.
|
||||
* Assert That only external url is present on txt
|
||||
*
|
||||
* @throws ValidationException If url is a bo url.
|
||||
* @param string $field
|
||||
* @param string $text
|
||||
* @return string
|
||||
* @throws \Illuminate\Validation\ValidationException If url is a bo url.
|
||||
*/
|
||||
public static function assertNoInternalUrls(string $field, string $text): string
|
||||
{
|
||||
|
|
@ -201,7 +213,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() ?? '';
|
||||
|
|
@ -217,31 +229,35 @@ class ToolboxHelper
|
|||
$field => trans(
|
||||
'crud.libs.toolbox.assertNoInternalUrls',
|
||||
['attribute' => $field, 'appname' => config('app.name')]
|
||||
),
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
return $match;
|
||||
} catch (NotFoundHttpException) {
|
||||
} catch (NotFoundHttpException $e) {
|
||||
return $match;
|
||||
}
|
||||
},
|
||||
$text
|
||||
);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mutltibyte string replace.
|
||||
* Mutltibyte string replace
|
||||
*
|
||||
* @param array|string $search
|
||||
* @param array|string $replace
|
||||
* @param array|string $subject
|
||||
* @param integer $count
|
||||
* @return array|string|false
|
||||
*/
|
||||
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)) {
|
||||
|
|
@ -250,7 +266,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);
|
||||
}
|
||||
|
|
@ -264,37 +280,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
|
||||
*
|
||||
*
|
||||
* @throws ValidationException If the field is not unique.
|
||||
* @param string $table
|
||||
* @param string $field
|
||||
* @param string|integer|float|boolean|null|array $value
|
||||
* @param integer|null $id
|
||||
* @param callable|null $query
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If the field is not unique.
|
||||
*/
|
||||
public static function assertFieldIsUnique(
|
||||
string $table,
|
||||
string $field,
|
||||
string | int | float | bool | null | array $value,
|
||||
string|int|float|bool|null|array $value,
|
||||
?int $id = null,
|
||||
?callable $query = null
|
||||
): void {
|
||||
if (! $query) {
|
||||
) {
|
||||
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], [
|
||||
|
|
@ -303,12 +319,16 @@ class ToolboxHelper
|
|||
$field . '.unique' => trans(
|
||||
'crud.libs.toolbox.assertFieldIsUnique',
|
||||
['attribute' => $field, 'value' => $value]
|
||||
),
|
||||
)
|
||||
])->validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get original polyfill with autotranslate behavior.
|
||||
* Get original polyfill with autotranslate behavior
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $attribute
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getOriginal(Model $model, string $attribute): mixed
|
||||
{
|
||||
|
|
@ -322,12 +342,17 @@ class ToolboxHelper
|
|||
$model->useFallbackLocale()
|
||||
);
|
||||
}
|
||||
|
||||
return $model->getOriginal($attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dynamic model query.
|
||||
* Dynamic model query
|
||||
*
|
||||
* @param string $defaultLocale
|
||||
* @param \Illuminate\Database\Eloquent\Builder $q
|
||||
* @param string $column
|
||||
* @param string $value
|
||||
* @return \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
public static function queryColumnWithLocales(
|
||||
string $defaultLocale,
|
||||
|
|
@ -337,17 +362,17 @@ class ToolboxHelper
|
|||
): Builder {
|
||||
$currentLocale = app()->currentLocale();
|
||||
$locales = collect(config('app.locales'))
|
||||
->mapWithKeys(fn (string $locale): array => [$locale => $locale]);
|
||||
if (! $locales->has($defaultLocale)) {
|
||||
->mapWithKeys(fn (string $locale) => [$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): void {
|
||||
return $q->where(function (Builder $q) use ($defaultLocale, $currentLocale, $locales, $column, $value) {
|
||||
// * Query default locale
|
||||
$q->whereRaw("JSON_EXTRACT({$column}, '$.{$defaultLocale}') = '{$value}'");
|
||||
if ($defaultLocale !== $currentLocale) {
|
||||
|
|
@ -362,7 +387,12 @@ class ToolboxHelper
|
|||
}
|
||||
|
||||
/**
|
||||
* Generates an array from a dot separated string.
|
||||
* Generates an array from a dot separated string
|
||||
*
|
||||
* @param string $path
|
||||
* @param mixed $value
|
||||
* @param string $separator
|
||||
* @return array
|
||||
*/
|
||||
public static function dotStringToNestedArray(string $path, mixed $value, string $separator = '.'): array
|
||||
{
|
||||
|
|
@ -372,77 +402,85 @@ class ToolboxHelper
|
|||
foreach ($keys as $key) {
|
||||
$arr = [$key => $arr];
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an object to array.
|
||||
* Convert deeply an object to array
|
||||
*
|
||||
* @throws RuntimeException If $input var is a scalar value.
|
||||
* @param mixed $input
|
||||
* @return array
|
||||
* @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) && !is_array($input)) {
|
||||
throw new RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
if (!(is_object($input) or is_array($input))) {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$ret = (array) $input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) || is_array($item)) ?
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::objectToArray($item) : $item;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert deeply an array to object.
|
||||
* Convert deeply an array to object
|
||||
*
|
||||
* @throws RuntimeException If $input var is a scalar value.
|
||||
* @param mixed $input
|
||||
* @return object
|
||||
* @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) && !is_array($input)) {
|
||||
throw new RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
if (!(is_object($input) or is_array($input))) {
|
||||
throw new \RuntimeException('Cannot handle $input of type ' . \gettype($input));
|
||||
}
|
||||
$ret = (object) $input;
|
||||
foreach ($ret as &$item) {
|
||||
// Recursively process EACH element only if not scalar.
|
||||
$item = (is_object($item) || is_array($item)) ?
|
||||
$item = (is_object($item) or is_array($item)) ?
|
||||
self::arrayToObject($item) : $item;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate picture.
|
||||
*/
|
||||
public static function validatePicture(string $attribute, ?string $value, callable $fail, object $sizes): void
|
||||
{
|
||||
if (! ($useStorage = Storage::exists($value)) && ! File::exists($value)) {
|
||||
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
||||
'attribute' => $attribute,
|
||||
]));
|
||||
|
||||
/**
|
||||
* Validate picture
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string|null $value
|
||||
* @param callable $fail
|
||||
* @param object $sizes
|
||||
* @return void
|
||||
*/
|
||||
public static function validatePicture(string $attribute, string|null $value, callable $fail, object $sizes)
|
||||
{
|
||||
if (!($useStorage = Storage::exists($value)) and !File::exists($value)) {
|
||||
$fail(trans(':attribute n\'existe pas dans le système de fichier', [
|
||||
'attribute' => $attribute
|
||||
]));
|
||||
return;
|
||||
}
|
||||
/** @var string */
|
||||
$fileFullPath = self::getUploadedFileFullPath($value, $useStorage);
|
||||
if (
|
||||
! \in_array(self::getUploadedFileMimeType($value, $useStorage), [
|
||||
'image/jpeg', 'image/jpg', 'image/png', 'image/gif',
|
||||
!\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]);
|
||||
|
|
@ -461,52 +499,60 @@ class ToolboxHelper
|
|||
$yMessage = trans(":attribute la hauteur doit être de {$sizes->minHeight}px");
|
||||
}
|
||||
|
||||
if ($width < $sizes->minWith || $width > $sizes->maxWith) {
|
||||
if (($width < $sizes->minWith) or ($width > $sizes->maxWith)) {
|
||||
$fail($xMessage);
|
||||
}
|
||||
if ($height < $sizes->minHeight || $height > $sizes->maxHeight) {
|
||||
if (($height < $sizes->minHeight) or ($height > $sizes->maxHeight)) {
|
||||
$fail($yMessage);
|
||||
}
|
||||
} // end if
|
||||
} //end if
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the file full path.
|
||||
* Get the file full path
|
||||
*
|
||||
* @param string $value
|
||||
* @param boolean $useStorage
|
||||
* @return string
|
||||
*/
|
||||
private static function getUploadedFileFullPath(string $value, bool $useStorage): string
|
||||
{
|
||||
/** @var FilesystemAdapter */
|
||||
/** @var \Illuminate\Filesystem\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', '')->value())))
|
||||
->filter(fn (SplFileInfo $splFileInfo): bool => $splFileInfo->getExtension() === 'php')
|
||||
return collect(File::files(\app_path(Str::of($namespace)->replaceFirst('\App', ''))))
|
||||
->filter(fn (SplFileInfo $splFileInfo) => $splFileInfo->getExtension() === 'php')
|
||||
->map(fn (SplFileInfo $splFileInfo) => Str::of($splFileInfo->getBasename())
|
||||
->replace('.' . $splFileInfo->getExtension(), '')->prepend("{$namespace}\\")->value())->all();
|
||||
->replace('.' . $splFileInfo->getExtension(), '')->prepend("{$namespace}\\"))->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
|
||||
|
|
@ -514,12 +560,17 @@ class ToolboxHelper
|
|||
return Arr::where(
|
||||
static::getClassesUsingNamespace($namespace),
|
||||
fn (string $class_namespace) => \collect(class_implements($class_namespace, true))->filter()
|
||||
->contains(fn (string $class_interface): bool => $class_interface === $interface)
|
||||
->contains(fn (string $class_interface) => $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
|
||||
{
|
||||
|
|
@ -528,7 +579,7 @@ class ToolboxHelper
|
|||
[$field => \request()->get($field)],
|
||||
[$field => new Enum($enumPath)]
|
||||
)->validated()[$field]);
|
||||
} catch (ValidationException) {
|
||||
} catch (ValidationException $e) {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
85
app/Lib/vendor/LDCWEB/MesBr.php
vendored
85
app/Lib/vendor/LDCWEB/MesBr.php
vendored
|
|
@ -7,8 +7,17 @@ use LDC\LDCCRM\Models\Customer;
|
|||
|
||||
class MesBr
|
||||
{
|
||||
public function __construct(private $endpoint, private $refCamp, private $refSite)
|
||||
private $endpoint;
|
||||
|
||||
private $refCamp;
|
||||
|
||||
private $refSite;
|
||||
|
||||
public function __construct($endpoint, $refCamp, $refSite)
|
||||
{
|
||||
$this->endpoint = $endpoint;
|
||||
$this->refCamp = $refCamp;
|
||||
$this->refSite = $refSite;
|
||||
}
|
||||
|
||||
public function createCustomer(string $hashcode, string $email, string $country)
|
||||
|
|
@ -34,63 +43,70 @@ 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(string $method, string $url, array $data = [], string $path = '/api/v1')
|
||||
private function callApi($method, $url, $data = [], $path = '/api/v1')
|
||||
{
|
||||
$url = $this->endpoint . $path . $url;
|
||||
$curl = curl_init();
|
||||
switch ($method) {
|
||||
case "POST":
|
||||
curl_setopt($curl, CURLOPT_POST, true);
|
||||
if ($data !== []) {
|
||||
curl_setopt($curl, CURLOPT_POST, 1);
|
||||
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, true);
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
|
||||
$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
|
||||
*
|
||||
* @return array<string,int|string>
|
||||
* @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>
|
||||
* 'status' => 'OK',
|
||||
* 'link' => URL,
|
||||
* 'verif' => URL,
|
||||
|
|
@ -104,16 +120,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) {
|
||||
|
|
@ -132,7 +148,10 @@ class MesBr
|
|||
/** .
|
||||
* Update basket
|
||||
*
|
||||
* @return array<string,int|string>
|
||||
* @param \LDC\LDCCRM\Models\Customer $crm_customer
|
||||
* @param string $coupon_id
|
||||
* @param integer $quantity
|
||||
* @return array<string,string>
|
||||
* 'status' => 'OK',
|
||||
* 'ref' => 'Basket REF'
|
||||
*/
|
||||
|
|
@ -142,10 +161,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) {
|
||||
|
|
@ -162,14 +181,15 @@ class MesBr
|
|||
|
||||
/**
|
||||
* Get customer basket
|
||||
*
|
||||
* @return array<string,int|string>
|
||||
*
|
||||
* @param \LDC\LDCCRM\Models\Customer $crm_customer
|
||||
* @return array
|
||||
*/
|
||||
public function getBasket(
|
||||
Customer $crm_customer,
|
||||
): array {
|
||||
$res = $this->callApi("GET", '/customer/basket', [
|
||||
'refcamp' => $this->refCamp,
|
||||
'refcamp' => $this->refCamp,
|
||||
'hashcode' => $crm_customer->hashcode
|
||||
]);
|
||||
|
||||
|
|
@ -188,12 +208,15 @@ 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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -19,10 +17,11 @@ class CodeExportSucceed extends Mailable
|
|||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @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.
|
||||
* @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
|
||||
*/
|
||||
public function __construct(
|
||||
protected int $nbCodeFic,
|
||||
|
|
@ -34,8 +33,10 @@ class CodeExportSucceed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope(): Envelope
|
||||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
to: [new Address(\config('mail.admin'))],
|
||||
|
|
@ -45,16 +46,18 @@ class CodeExportSucceed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content(): Content
|
||||
public function content(): \Illuminate\Mail\Mailables\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,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -19,8 +17,9 @@ class CodeGenerationSucceed extends Mailable
|
|||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param int $amount Amount of code to generate.
|
||||
* @param string $gameName The game name.
|
||||
* @param integer $amount Amount of code to generate.
|
||||
* @param string $gameName The game name.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(private int $amount, private string $gameName)
|
||||
{
|
||||
|
|
@ -28,8 +27,10 @@ class CodeGenerationSucceed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope(): Envelope
|
||||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
to: [new Address(\config('mail.admin'))],
|
||||
|
|
@ -39,14 +40,16 @@ class CodeGenerationSucceed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content(): Content
|
||||
public function content(): \Illuminate\Mail\Mailables\Content
|
||||
{
|
||||
return new Content(
|
||||
markdown: 'mails.jobs.code-generation-succeed',
|
||||
with: [
|
||||
'quantity' => $this->amount,
|
||||
'gameName' => $this->gameName,
|
||||
'gameName' => $this->gameName
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
|
|
@ -18,6 +16,10 @@ 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)
|
||||
{
|
||||
|
|
@ -25,8 +27,10 @@ class JobFailed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message envelope.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Envelope
|
||||
*/
|
||||
public function envelope(): Envelope
|
||||
public function envelope(): \Illuminate\Mail\Mailables\Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
to: [new Address(\config('mail.admin'))],
|
||||
|
|
@ -36,14 +40,16 @@ class JobFailed extends Mailable
|
|||
|
||||
/**
|
||||
* Get the message content definition.
|
||||
*
|
||||
* @return \Illuminate\Mail\Mailables\Content
|
||||
*/
|
||||
public function content(): Content
|
||||
public function content(): \Illuminate\Mail\Mailables\Content
|
||||
{
|
||||
return new Content(
|
||||
markdown: 'mails.jobs.failure',
|
||||
with: [
|
||||
'job' => $this->job,
|
||||
'exception' => $this->exception,
|
||||
'job' => $this->job,
|
||||
'exception' => $this->exception
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Models\Settings;
|
||||
|
|
@ -16,12 +14,24 @@ 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(protected User $user, protected Settings $settings)
|
||||
public function __construct(User $user, Settings $settings)
|
||||
{
|
||||
$this->user = $user;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -31,11 +41,8 @@ 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($view)
|
||||
->with(['user' => $this->user, 'settings' => $this->settings]);
|
||||
->view('front.basic.password-email')
|
||||
->with(['user' => $this->user, 'settings' => $this->settings]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
<?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;
|
||||
|
|
@ -22,11 +21,13 @@ class DiscountWonMail extends Mailable implements ShouldQueue
|
|||
/**
|
||||
* Create a new message instance.
|
||||
*
|
||||
* @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.
|
||||
* @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
|
||||
*/
|
||||
public function __construct(
|
||||
protected Address $recipient,
|
||||
|
|
@ -34,41 +35,40 @@ 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(): Envelope
|
||||
public function envelope(): \Illuminate\Mail\Mailables\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(): Content
|
||||
public function content(): \Illuminate\Mail\Mailables\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: $view,
|
||||
markdown: 'theme::mails.won-discount',
|
||||
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