Compare commits

...
Sign in to create a new pull request.

9 commits

Author SHA1 Message Date
Jérémy Munsch
2093fc32e3
WIP (A tester MANQUE MESBR): Add CRM V3 + Remove Arcadia Stuff + Some refactor + Win List Save comments + MAIL_ADMIN check on boot + add Swal + Vues blades mis à jour (pas dans basic example) 2022-03-18 14:44:37 +01:00
Jérémy Munsch
fbcb8bc5bf
Customer and User separation 2022-03-16 10:47:17 +01:00
Jérémy Munsch
0457681ef8
Instant Win refactorize + add Big prize always at then end of the game 2022-03-11 14:52:48 +01:00
Jérémy Munsch
1ae5307b55
phpcbf pass 2022-03-11 09:59:44 +01:00
Jérémy Munsch
2831d422c9
Refactorize Settings BO save
- require composer kwaadpepper/enum
- User->role is now an enum
- Add isLocal and isAdmin to user model
- changed multiple fields casts on model Settings
- added validation for settings
2022-03-11 09:59:40 +01:00
Jérémy Munsch
189f2feb29
Upgrade Flash message module 2022-03-10 13:57:09 +01:00
Jérémy Munsch
bbb175ad61
Fully remove 'teaser_end_activity' from settings 2022-03-10 13:56:56 +01:00
Jérémy Munsch
0781344016
composer update 2022-03-10 13:35:58 +01:00
Jérémy Munsch
b0f0763351
Force add project color 2022-03-10 13:34:00 +01:00
164 changed files with 4782 additions and 115348 deletions

View file

@ -32,5 +32,7 @@ MAIL_ADMIN=informatique.internet@ldc.fr
# CRM
CRM_ENDPOINT=
CRM_TOKEN=
CRM_PASSWORD=
# MESBR
MESBR_ENDPOINT=

22
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,22 @@
{
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#221b6c",
"activityBar.activeBorder": "#b3382d",
"activityBar.background": "#221b6c",
"activityBar.foreground": "#e7e7e7",
"activityBar.inactiveForeground": "#e7e7e799",
"activityBarBadge.background": "#b3382d",
"activityBarBadge.foreground": "#e7e7e7",
"sash.hoverBorder": "#221b6c",
"statusBar.background": "#151143",
"statusBar.foreground": "#e7e7e7",
"statusBarItem.hoverBackground": "#221b6c",
"statusBarItem.remoteBackground": "#151143",
"statusBarItem.remoteForeground": "#e7e7e7",
"titleBar.activeBackground": "#151143",
"titleBar.activeForeground": "#e7e7e7",
"titleBar.inactiveBackground": "#15114399",
"titleBar.inactiveForeground": "#e7e7e799"
},
"peacock.remoteColor": "#151143"
}

View file

@ -2,9 +2,13 @@
namespace App\Console\Commands;
use App\Enums\UserRole;
use App\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\ValidationException;
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
class CreateAdmin extends Command
{
@ -20,7 +24,7 @@ class CreateAdmin extends Command
*
* @var string
*/
protected $description = 'Command description';
protected $description = 'Create an admin user';
/**
* Execute the console command.
@ -29,26 +33,77 @@ class CreateAdmin extends Command
*/
public function handle()
{
$firstname = $this->ask('What is the firstname?', 'Informatique');
$lastname = $this->ask('What is the lastname?', 'Internet');
$email = $this->ask('What is the email?', 'equipe.web@ldc.fr');
$pwd = $this->secret('What is the password?');
$role = $this->ask('Role ?', '1');
$name = null;
while (is_null($name)) {
try {
$tmp = $this->ask('What is the name?', 'Equipe Web');
$validator = Validator::make(['name' => $tmp], [
'name' => 'required|min:5,max:255'
]);
$validator->validate();
$name = $tmp;
} catch (ValidationException $e) {
$this->error(sprintf(
'Please provide a valid name %s',
\implode(',', collect($e->errors())->flatten()->all())
));
continue;
}
}
$user = new User();
$user->firstname = $firstname;
$user->lastname = $lastname;
$user->birth_date = now();
$user->email = $email;
$user->password = Hash::make($pwd);
$user->address = "-";
$user->town = "Le Mans";
$user->postal_code = "72000";
$user->country = "France";
$user->email_verify_token = "-";
$user->email_verified = 1;
$user->role = $role;
$user->save();
$email = null;
while (is_null($email)) {
try {
$tmp = $this->ask('What is the email?', 'equipe.web@ldc.fr');
$validator = Validator::make(['email' => $tmp], [
'email' => 'required|unique:users,email|email:rfc,dns'
]);
$validator->validate();
$email = $tmp;
} catch (ValidationException $e) {
$this->error(sprintf(
'Please provide a valid email %s',
\implode(',', collect($e->errors())->flatten()->all())
));
continue;
}
}
$role = null;
while (is_null($role)) {
try {
$tmp = $this->ask('Type the wanted user role', sprintf(
'%d (%s), %d (%s)',
UserRole::admin()->value,
UserRole::admin()->label,
UserRole::brand()->value,
UserRole::brand()->label
));
$validator = Validator::make(['role' => $tmp], [
'role' => [
'required', new EnumIsValidRule(UserRole::class),
sprintf('in:%d,%d', UserRole::admin()->value, UserRole::brand()->value)
]
]);
$validator->validate();
$role = $tmp;
} catch (ValidationException $e) {
$this->error(sprintf(
'Please provide a valid role %s',
\implode(',', collect($e->errors())->flatten()->all())
));
continue;
} //end try
} //end while
$password = $this->secret('What is the password?');
$user = new User();
$user->name = $name;
$user->email = $email;
$user->password = Hash::make($password);
$user->role = $role;
$user->saveOrFail();
$this->info('User created.');

View file

@ -0,0 +1,39 @@
<?php
namespace App\Console\Commands;
use App\Models\Customer;
use Carbon\Carbon;
use Illuminate\Console\Command;
class DeleteNotConfirmedCustomer extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'customers:deletenc';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Remove customers who have not confirmed their accounts within 24 hours of registration';
/**
* Execute the console command.
*
* @return integer
*/
public function handle()
{
$customers = Customer::where([['email_verified', false], ['created_at', '<', Carbon::now()->subDay()]])->get();
foreach ($customers as $customer) {
$customers->delete();
}
return 0;
}
}

View file

@ -1,39 +0,0 @@
<?php
namespace App\Console\Commands;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Console\Command;
class DeleteNotConfirmedUser extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'users:deletenc';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Remove users who have not confirmed their accounts within 24 hours of registration';
/**
* Execute the console command.
*
* @return integer
*/
public function handle()
{
$users = User::where([['email_verified', 0], ['created_at', '<', Carbon::now()->subDay()]])->get();
foreach ($users as $user) {
$user->delete();
}
return 0;
}
}

View file

@ -0,0 +1,41 @@
<?php
namespace App\Enums;
use Kwaadpepper\Enum\BaseEnumRoutable;
/**
* @method static self legals()
* @method static self charte()
* @method static self reglement()
*/
final class ContentPageType extends BaseEnumRoutable
{
/**
* Enum values
*
* @return array
*/
protected static function values(): array
{
return [
'legals' => 1,
'charte' => 2,
'reglement' => 3
];
}
/**
* Enum values
*
* @return array
*/
protected static function labels(): array
{
return [
'legals' => trans('Mentions légales'),
'charte' => trans('Charte'),
'reglement' => trans('Règlement')
];
}
}

38
app/Enums/UserRole.php Normal file
View file

@ -0,0 +1,38 @@
<?php
namespace App\Enums;
use Kwaadpepper\Enum\BaseEnumRoutable;
/**
* @method static self admin()
* @method static self brand()
*/
final class UserRole extends BaseEnumRoutable
{
/**
* Enum values
*
* @return array
*/
protected static function values(): array
{
return [
'admin' => 0,
'brand' => 1
];
}
/**
* Enum labels
*
* @return array
*/
protected static function labels(): array
{
return [
'admin' => trans('enums.admin'),
'brand' => trans('enums.brand')
];
}
}

View file

@ -2,7 +2,9 @@
namespace App\Exceptions;
use Illuminate\Session\TokenMismatchException;
use Kwaadpepper\ExceptionHandler\Exceptions\ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
@ -24,4 +26,22 @@ class Handler extends ExceptionHandler
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param \Throwable $e
* @return void
*
* @throws \Exception .
*/
public function report(Throwable $e)
{
if (\get_class($e) === TokenMismatchException::class) {
abort(\request()->routeIs('bo.*') ?
response()->redirectToRoute('bo.dashboard') :
response()->redirectToRoute('home'));
}
parent::report($e);
}
}

View file

@ -3,33 +3,50 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\SaveBannedIpListRequest;
use App\Models\BannedIp;
use Illuminate\Http\Request;
class BannedIpController extends Controller
{
/**
* Show banned ips list
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$ips = BannedIp::all();
return view('bo.banned-ip.index', compact('ips'));
}
public function saveDatas(Request $request)
/**
* Ajax save data banned ips
*
* @param SaveBannedIpListRequest $request
* @return array
*/
public function saveDatas(SaveBannedIpListRequest $request)
{
$ips = $request->ips;
/** @var \Illuminate\Support\Collection $ips */
$ips = \collect($request->ips);
for ($i = 0; $i < count($ips); $i++) {
if (!empty($ips[$i]["ip"])) {
$ip = BannedIp::updateOrCreate(['ip' => $ips[$i]["ip"]]);
} else {
unset($ips[$i]);
$i--;
}
}
// * Delete all
BannedIp::query()->delete();
return $ips;
$ips->map(function (string $ip) {
(new BannedIp(['ip' => $ip]))->saveOrFail();
});
return \response()->json(BannedIp::all());
}
/**
* Ajax destroy ip
*
* @param Request $request
* @return string
*/
public function destroy(Request $request)
{
$ip = BannedIp::where("ip", $request->ip);

View file

@ -3,9 +3,9 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\CodeSearchRequest;
use App\Http\Requests\ExportCodesRequest;
use App\Http\Requests\GenerateCodesRequest;
use App\Http\Requests\Bo\CodeSearchRequest;
use App\Http\Requests\Bo\ExportCodesRequest;
use App\Http\Requests\Bo\GenerateCodesRequest;
use App\Jobs\ProcessExportCodesUniques;
use App\Jobs\ProcessUniqueCode;
use App\Models\Code;

View file

@ -3,23 +3,37 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\UpdateContentRequest;
use App\Models\Content;
use Illuminate\Http\Request;
class ContentController extends Controller
{
public function manage($id, Request $request)
/**
* Manage content
*
* @param Content $content
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
*/
public function manage(Content $content)
{
$content = Content::findOrFail($id);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$value = $request->value;
$content->value = $value;
$content->save();
return redirect()->route('bo.content', $content->id)->with('success', 'Enregistré !');
}
return view('bo.content.manage', compact('content'));
}
/**
* Content update
*
* @param UpdateContentRequest $request
* @param Content $content
* @return \Illuminate\Http\RedirectResponse
*/
public function manageSubmit(UpdateContentRequest $request, Content $content)
{
$content->fill($request->validated());
if ($content->saveOrFail()) {
return redirect()->route('bo.contents.manage', $content)
->with('success', 'Enregistré !');
}
return back();
}
}

View file

@ -10,28 +10,34 @@ use Illuminate\Support\Facades\DB;
class DashboardController extends Controller
{
/**
* Show dashboard page
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
// Pour les stats.
$settings = app(Settings::class);
$participations = Participation::selectRaw("COUNT(*) AS count, DATE(created_at) AS date")
$settings = app(Settings::class);
$participations = Participation::selectRaw("COUNT(*) AS count, DATE(created_at) AS date")
->groupByRaw("DATE(created_at)")->get();
$participationsUniquePerDay = Participation::selectRaw("DISTINCT user_id AS user, COUNT(*) AS count, DATE(created_at) AS date")
->groupByRaw("DATE(created_at), user")->get();
//phpcs:ignore Generic.Files.LineLength.TooLong
$participationsUniquePerDay = Participation::selectRaw("DISTINCT customer_id AS customer, COUNT(*) AS count, DATE(created_at) AS date")
->groupByRaw("DATE(created_at), customer")->get();
$statsUnique = [];
foreach ($participationsUniquePerDay as $participationPerDay) {
$dateUnique = Carbon::parse($participationPerDay->date)->format('d/m/Y');
$statsUnique[$dateUnique] = isset($statsUnique[$dateUnique]) ? $statsUnique[$dateUnique] + 1 : 1;
}
$participationsUnique = Participation::selectRaw("DISTINCT user_id AS user, COUNT(*) AS count")
->groupBy("user")->orderBy("user")->get();
$participationsUnique = Participation::selectRaw("DISTINCT customer_id AS customer, COUNT(*) AS count")
->groupBy("customer")->orderBy("customer")->get();
// Données calculées à afficher.
$totalParticipation = Participation::count();
if (count($participationsUnique) > 0) {
$avgParticipUser = round($totalParticipation / count($participationsUnique), 1);
$avgParticipCustomer = round($totalParticipation / count($participationsUnique), 1);
} else {
$avgParticipUser = 0;
$avgParticipCustomer = 0;
}
// Tableau des dates comprises dans la table participation.
@ -65,7 +71,7 @@ class DashboardController extends Controller
'count',
'countUnique',
'totalParticipation',
'avgParticipUser',
'avgParticipCustomer',
'codesEan',
'settings'
));

View file

@ -3,107 +3,152 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Resources\InstantWinResource;
use App\Models\InstantWin;
use App\Models\Prize;
use App\Models\Settings;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
class InstantWinController extends Controller
{
/**
* View Instant gagnants page
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$nbInstantWin = InstantWin::count();
$canGenerate = 0;
if (intval($nbInstantWin) > 0) {
$canGenerate = 0;
} else {
$nbLots = Prize::count();
if (intval($nbLots) > 0) {
$canGenerate = 1;
} else {
$canGenerate = 0;
}
}
// * Can generate only if there are none already generate and prizes on database
$canGenerate = InstantWin::count() ? false : (Prize::sum('quantity') ? true : false);
$instantWin = InstantWin::orderBy('appear_date')->get();
return view('bo.instant-win.index', [
'can_generate' => $canGenerate,
'instant_win' => $instantWin
'instant_win' => new InstantWinResource($instantWin)
]);
}
public function instantWinGenerate()
/**
* Generate Instant wins
*
* @return \Illuminate\Http\JsonResponse
*/
public function instantWinGenerate(): JsonResponse
{
$start_date = Settings::latest()->value("start_date");
$end_date = Settings::latest()->value("end_date");
$lots = Prize::all();
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
/** @var \Illuminate\Support\Carbon $start_date */
$start_date = $settings->start_date;
/** @var \Illuminate\Support\Carbon $end_date */
$end_date = $settings->end_date;
$lots = Prize::orderBy('id')->get();
$begin = new \DateTime($start_date);
$end = new \DateTime($end_date);
$interval = new \DateInterval('P1D');
$daterange = new \DatePeriod($begin, $interval, $end);
$dateGlobal = [];
$lotsGlobal = [];
/** @var \Illuminate\Support\Collection $daterange all days of the game period */
$daterange = collect($start_date->range($end_date)->toArray());
/** @var \Illuminate\Support\Collection $dateGlobal all randomized instant wins */
$dateGlobal = collect();
/** @var \Illuminate\Support\Collection $lotsGlobal All randomized lots */
$lotsGlobal = collect();
foreach ($lots as $k => $lot) {
for ($i = 0; $i < $lot->quantity; $i++) {
$lotsGlobal[] = [
'id' => $lot->id,
'name' => $lot->label_one,
'hour' => str_pad(mt_rand(6, 22), 2, "0", STR_PAD_LEFT)
. ":" . str_pad(mt_rand(0, 59), 2, "0", STR_PAD_LEFT) . ":00"
];
}
}
shuffle($lotsGlobal);
foreach ($daterange as $date) {
array_push($dateGlobal, ['date' => $date->format("Y-m-d"), 'lots' => []]);
}
$res = $this->generate($lotsGlobal, $dateGlobal, 0);
foreach ($res as $date) {
foreach ($date['lots'] as $lot) {
$iw = new InstantWin();
$iw->prize_id = $lot['id'];
$iw->appear_date = date('Y-m-d H:i:s', strtotime($date['date'] . " " . $lot['hour']));
$iw->save();
// * Assign Lots on collection
foreach ($lots as $lot) {
for ($i = $lot->quantity; $i > 0; $i--) {
$lotsGlobal->push($lot);
}
}
$instantWins = InstantWin::all();
return json_encode($instantWins);
$daysRunningGame = clone $daterange;
// * Create Instant wins on collection
for ($i = $lotsGlobal->count(); $i > 0; $i--) {
// * Get each day once then randomize
if ($daysRunningGame->count()) {
/** @var Carbon $dateTime */
$dateTime = $daysRunningGame->shift();
} else {
/** @var Carbon $dateTime */
$dateTime = $daterange->random();
}
// * If end of loop and there are less lots then days
if ($i === 1 and $lotsGlobal->count() < $daysRunningGame->count()) {
// * Make the last instant win on the last day
/** @var Carbon $dateTime */
$dateTime = $daterange->random();
}
$dateGlobal->push(Carbon::parse(sprintf(
'%s %s',
$dateTime->format('Y-m-d'),
$this->getRandomWiningHour()
)));
}//end for
// * Sort dates
$dateGlobal = $dateGlobal->sortBy(function (Carbon $date) {
return $date->getTimestamp();
});
// * Reserve big prize (the first should be ID 1) and last Instant win for the end
/** @var \App\Models\Prize $bigPrize */
$bigPrize = $lotsGlobal->shift();
/** @var Carbon $lastInstantWin */
$lastInstantWin = $dateGlobal->pop();
// * Shuffle Instant wins
// ! Initialize mt rand seed !!
\mt_srand();
$lotsGlobal = $lotsGlobal->shuffle(\mt_rand(0, 99999));
// * Shuffle Lots
// ! Initialize mt rand seed !!
\mt_srand();
$dateGlobal = $dateGlobal->shuffle(\mt_rand(0, 99999));
// ! Return empty if no prizes are available
if (!$bigPrize) {
return \response()->json();
}
$instantWinsLots = $dateGlobal->map(function (Carbon $instantWinDate) use ($lotsGlobal) {
return [
'date' => $instantWinDate,
'lot' => $lotsGlobal->shift()
];
});
// * Save Instant wins
DB::transaction(function () use ($instantWinsLots, $lastInstantWin, $bigPrize) {
$instantWinsLots->map(function (array $instantWinLot) {
$instantWin = new InstantWin();
$instantWin->appear_date = $instantWinLot['date'];
$instantWin->prize()->associate($instantWinLot['lot']);
$instantWin->saveOrFail();
});
// * Insert last Instant win (big prize)
$instantWin = new InstantWin();
$instantWin->appear_date = $lastInstantWin;
$instantWin->prize()->associate($bigPrize);
$instantWin->saveOrFail();
});
return \response()->json(new InstantWinResource(InstantWin::orderBy('appear_date')->get()));
}
private function generate($lotsGlobal, $dateGlobal, $lotsDone)
/**
* Generate a random hour between 06:00 and 22:59
*
* @return string
*/
private function getRandomWiningHour(): string
{
$rKey = array_rand($dateGlobal, 1);
if ($lotsDone < count($dateGlobal)) {
if (count($dateGlobal[$rKey]['lots']) > 0) {
return $this->generate($lotsGlobal, $dateGlobal, $lotsDone);
}
}
array_push($dateGlobal[$rKey]['lots'], $lotsGlobal[$lotsDone++]);
if ($lotsDone < count($lotsGlobal)) {
return $this->generate($lotsGlobal, $dateGlobal, $lotsDone);
}
foreach ($dateGlobal as $k => $date) {
usort($dateGlobal[$k]['lots'], [$this, 'sortFunction']);
}
return $dateGlobal;
}
private function sortFunction($a, $b)
{
return strtotime($a["hour"]) - strtotime($b["hour"]);
// ! Initialize mt rand seed !!
\mt_srand();
return Carbon::parse('22:59')
->subMinutes(\mt_rand(0, (23 - 6) * 60 - 1))->format('H:i');
}
}

View file

@ -33,14 +33,11 @@ class PrizesController extends Controller
if ($prize->id !== null) {
$p = Prize::findOrFail($prize->id);
$p->arcadia_id = $prize->arcadia_id;
$p->label_one = $prize->label_one;
$p->label_many = $prize->label_many;
$p->quantity = $prize->quantity;
$p->arcadia_operation_code = $prize->arcadia_operation_code;
$p->arcadia_support_code = $prize->arcadia_support_code;
$p->need_proof = $prize->need_proof;
$p->gain_view_id = $prize->gain_view_id;
$p->label_one = $prize->label_one;
$p->label_many = $prize->label_many;
$p->quantity = $prize->quantity;
$p->need_proof = $prize->need_proof;
$p->gain_view_id = $prize->gain_view_id;
if (isset($pdfs[$i])) {
$fileName = Str::slug($prize->label_one) . '-' .
@ -52,15 +49,12 @@ class PrizesController extends Controller
$p->save();
} else {
$p = new Prize();
$p->arcadia_id = $prize->arcadia_id;
$p->label_one = $prize->label_one;
$p->label_many = $prize->label_many;
$p->quantity = $prize->quantity;
$p->arcadia_operation_code = $prize->arcadia_operation_code;
$p->arcadia_support_code = $prize->arcadia_support_code;
$p->need_proof = $prize->need_proof;
$p->gain_view_id = $prize->gain_view_id;
$p = new Prize();
$p->label_one = $prize->label_one;
$p->label_many = $prize->label_many;
$p->quantity = $prize->quantity;
$p->need_proof = $prize->need_proof;
$p->gain_view_id = $prize->gain_view_id;
if (isset($pdfs[$i])) {
$fileName = Str::slug($prize->label_one) . '-' .
@ -75,7 +69,6 @@ class PrizesController extends Controller
} //end if
}//end for
} catch (Exception $e) {
//
}//end try
return $prizes;

View file

@ -3,8 +3,8 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreProductRequest;
use App\Http\Requests\UpdateProductRequest;
use App\Http\Requests\Bo\StoreProductRequest;
use App\Http\Requests\Bo\UpdateProductRequest;
use App\Models\Product;
use App\Models\Range;
use Illuminate\Support\Str;
@ -43,7 +43,7 @@ class ProductsController extends Controller
/**
* Store a newly created resource in storage.
*
* @param \App\Http\Requests\StoreProductRequest $request
* @param \App\Http\Requests\Bo\StoreProductRequest $request
* @return \Illuminate\Http\Response
*/
public function store(StoreProductRequest $request)
@ -79,7 +79,6 @@ class ProductsController extends Controller
*/
public function show($id)
{
//
}
/**
@ -105,8 +104,8 @@ class ProductsController extends Controller
/**
* Update the specified resource in storage.
*
* @param \App\Http\Requests\UpdateProductRequest $request
* @param integer $id
* @param \App\Http\Requests\Bo\UpdateProductRequest $request
* @param integer $id
* @return \Illuminate\Http\Response
*/
public function update(UpdateProductRequest $request, $id)

View file

@ -3,8 +3,8 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreRangeRequest;
use App\Http\Requests\UpdateRangeRequest;
use App\Http\Requests\Bo\StoreRangeRequest;
use App\Http\Requests\Bo\UpdateRangeRequest;
use App\Models\Range;
use Illuminate\Support\Str;

View file

@ -3,89 +3,52 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Bo\UpdateSettingsRequest;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Session;
class SettingsController extends Controller
{
public function manage(Request $request)
/**
* Show edit settings page
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function manage()
{
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $request->name;
$startDate = $request->start_date;
$endDate = $request->end_date;
$nbParticipationPlayer = $request->nb_participation_player;
$nbParticipationIp = $request->nb_participation_ip;
$nbUniqueCodeUse = $request->nb_unique_code_use;
$useEanCodes = $request->use_ean_codes === null ? 0 : 1;
$activatedTeaser = $request->activated_teaser === null ? 0 : 1;
$teaserEndActivity = $request->teaser_end_activity;
$activatedClosePage = $request->activated_close_page === null ? 0 : 1;
$closePageActiveDate = $request->close_page_active_date;
$redirectClose = $request->redirect_close;
$reductionsActivated = $request->reductions_activated === null ? 0 : 1;
$reductionsSite = $request->reductions_site;
$reductionsCampaign = $request->reductions_campaign;
$webCoupons = $request->web_coupons;
$facebookActivated = $request->facebook_activated === null ? 0 : 1;
$facebookAppId = $request->facebook_app_id;
$facebookSecret = $request->facebook_secret;
$notificationEmails = $request->notification_emails;
$winningProof = $request->winning_proof === null ? 0 : 1;
$company = $request->company;
$analytics = $request->analytics;
// Check du lien de redirection après fermeture.
if (strpos($redirectClose, 'https://') === false && strpos($redirectClose, 'http://') === false) {
$redirectClose = 'https://' . $redirectClose;
}
$settings->name = $name;
$settings->start_date = $startDate;
$settings->end_date = $endDate;
$settings->nb_participation_player = $nbParticipationPlayer;
$settings->nb_participation_ip = $nbParticipationIp;
$settings->nb_unique_code_use = $nbUniqueCodeUse;
$settings->use_ean_codes = $useEanCodes;
$settings->activated_teaser = $activatedTeaser;
if ($activatedTeaser === 1) {
$settings->teaser_end_activity = Carbon::parse($teaserEndActivity);
}
$settings->activated_close_page = $activatedClosePage;
if ($activatedClosePage === 1) {
$settings->close_page_active_date = Carbon::parse($closePageActiveDate);
}
$settings->redirect_close = $redirectClose;
$settings->reductions_activated = $reductionsActivated;
if ($reductionsActivated === 1) {
$settings->reductions_site = $reductionsSite;
$settings->reductions_campaign = $reductionsCampaign;
$settings->web_coupons = $webCoupons;
}
$settings->facebook_activated = $facebookActivated;
$settings->facebook_app_id = $facebookAppId;
$settings->facebook_secret = $facebookSecret;
$settings->notification_emails = $notificationEmails;
$settings->winning_proof = $winningProof;
$settings->company = $company;
$settings->analytics = $analytics;
$settings->save();
$settingsGlobal = app(Settings::class)
->select('name', 'company', 'analytics', 'start_date', 'end_date')->first();
Cache::put('settingsGlobal', $settingsGlobal);
$success = "Modifications enregistrés !";
return view('bo.settings.manage', compact('settings', 'success'));
}//end if
return view('bo.settings.manage', compact('settings'));
}
/**
* Save settings
*
* @param UpdateSettingsRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function manageSubmit(UpdateSettingsRequest $request)
{
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
$settings->fill($request->validated());
$redirectClose = $request->redirect_close;
// Check du lien de redirection après fermeture.
if (strpos($redirectClose, 'https://') === false && strpos($redirectClose, 'http://') === false) {
$redirectClose = 'https://' . $redirectClose;
}
$settings->redirect_close = $redirectClose;
if ($settings->saveOrFail()) {
$settingsGlobal = app(Settings::class)
->select('name', 'company', 'analytics', 'start_date', 'end_date')->first();
Cache::put('settingsGlobal', $settingsGlobal);
Session::flash('success', 'Modifications enregistrés !');
}
return \back();
}
}

View file

@ -3,115 +3,63 @@
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Mail\CourrierArcadiaError;
use App\Http\Requests\Bo\UpdateWinInfosRequest;
use App\Models\InstantWin;
use App\Models\Participation;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Cache;
class WinnersListController extends Controller
{
private $apiCrm;
public function __construct()
{
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
}
/**
* Show Instant win list
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$winnersList = Participation::has('instantWin')->get();
$settings = Settings::select('use_ean_codes', 'winning_proof')->first();
return view('bo.winners-list.index', compact('winnersList', 'settings'));
$participations = Participation::whereHas('instantWin')->with('code')
->with('instantWin.prize')->with('customer')->with('codeEan')->get();
$settings = Settings::select('use_ean_codes', 'winning_proof')->first();
// * Generate code to show up in front + format date + customer info
$participations = $participations->map(function (Participation $participation) {
$participation->created = $participation->created_at->format('d/m/Y à H:i');
$participation->code->code = $participation->code->code_unique;
$participation->code->code = $participation->code->code_unique;
$participation->customer->setRawAttributes(['data' => Cache::remember(
'winnerList' . $participation->customer->id,
90,
function () use ($participation) {
/** @var \LDC\LDCCRM\Models\Customer|null $crmCustomer */
$crmCustomer = $participation->customer->apiData;
$data = [];
if ($crmCustomer) {
$countryLabel = $crmCustomer->country->label;
$data = collect($crmCustomer)->all();
$data['country'] = $countryLabel;
}
return $data;
}
)]);
return $participation;
});
return view('bo.winners-list.index', compact('participations', 'settings'));
}
public function courrierArcadia($id)
/**
* Update Instant win info
*
* @param UpdateWinInfosRequest $request
* @param InstantWin $instantWin
* @return \Illuminate\Http\JsonResponse
*/
public function updateInstantWinInfos(UpdateWinInfosRequest $request, InstantWin $instantWin)
{
$participation = Participation::findOrFail($id);
$crmUser = $this->apiCrm->getCustomer($participation->user->crm_id);
if ($crmUser->status === 'NOK') {
return back()->withErrors("Erreur lors de la récupération de l'utilisateur dans la CRM : Code : " .
$crmUser->code . " Message : " . $crmUser->message);
$instantWin->done = $request->done;
$instantWin->comment = $request->comment;
if ($instantWin->save()) {
return response()->json();
}
$crmId = $participation->user->crm_id;
$crmUser = $crmUser->user;
$corps = '<arcadia>' . "\n";
$corps .= '<Commande> ' . "\n";
$corps .= "\t" . '<Num_Commande></Num_Commande>' . "\n";
$corps .= "\t" . '<Date_Commande>' . date('d/m/Y') . '</Date_Commande>' . "\n";
$corps .= "\t" . '<Operation></Operation> ' . "\n";
$corps .= "\t" . '<Civilite></Civilite>' . "\n";
$corps .= "\t" . '<Nom><![CDATA[' . trim($crmUser->firstname) . ']]></Nom>' . "\n";
$corps .= "\t" . '<Prenom><![CDATA[' . trim($crmUser->lastname) . ']]></Prenom>' . "\n";
$corps .= "\t" . '<Adresse><![CDATA[' . trim($crmUser->address) . ']]></Adresse>' . "\n";
$corps .= "\t" . '<Adresse_Complementaire><![CDATA[' . trim($crmUser->address2) . ']]></Adresse_Complementaire>' . "\n";
$corps .= "\t" . '<CP><![CDATA[' . trim($crmUser->postcode) . ']]></CP>' . "\n";
$corps .= "\t" . '<Ville><![CDATA[' . trim($crmUser->city) . ']]></Ville>' . "\n";
$corps .= '<Ligne_de_Commande>' . "\n";
$corps .= "\t" . '<Code_Support></Code_Support> ' . "\n";
$corps .= "\t" . '<Libelle_Type_Support></Libelle_Type_Support> ' . "\n";
$corps .= "\t" . '<Quantite>1</Quantite>' . "\n";
$corps .= "\t" . '<Poids_Unitaire_Colis></Poids_Unitaire_Colis>' . "\n";
$corps .= '</Ligne_de_Commande>' . "\n";
$corps .= '</Commande> ' . "\n";
$corps .= '</arcadia>';
return view('bo.winners-list.arcadia', compact('participation', 'corps', 'crmId'));
}
public function createCourrierArcadia(Request $request, $id)
{
$participation = Participation::findOrFail($id);
$instantWin = $participation->instantWin;
if ($instantWin->prize->arcadia_operation_code !== 0 && $instantWin->prize->arcadia_support_code !== 0) {
$fields = [
'root' => [
[
'fieldName' => 'order_date',
'fieldValue' => date('d/m/Y')
],
[
'fieldName' => 'operation',
'fieldValue' => $instantWin->prize->arcadia_operation_code
]
],
'orderLine' => [
[
'fieldName' => 'code_unique',
'fieldValue' => $participation->code->code_unique
],
[
'fieldName' => 'support_code',
'fieldValue' => $instantWin->prize->arcadia_support_code
],
[
'fieldName' => 'label_type_support',
'fieldValue' => 'Gain du lot : ' . $instantWin->prize->label_one
]
]
];
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
if ($settings->use_ean_codes === 1) {
$fields['orderLine'][] = [
'fieldName' => 'code_on_pack',
'fieldValue' => $participation->codeEan->code
];
}
$arcadiaMail = $this->apiCrm->ArcadiaOutgoingMail($participation->user->crm_id, $fields, 'game');
if ($arcadiaMail->status === 'NOK') {
Mail::to(config('mail.MAIL_ADMIN'))->send(new CourrierArcadiaError($participation->user));
return back()->withErrors("Erreur lors de l'envoi du courrier Arcadia. Code : " .
$arcadiaMail->code . " Message : " . $arcadiaMail->message);
}
}//end if
return back()->with('success', 'Courrier envoyé !');
return response()->json([], 500);
}
}

View file

@ -1,290 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Http\Requests\ParticipateRequest;
use App\Mail\CourrierArcadiaError;
use App\Mail\NotifAdmin;
use App\Mail\NotifWinAdmin;
use App\Mail\PrizeWon;
use App\Mail\ReductionWon;
use App\Models\BannedIp;
use App\Models\InstantWin;
use App\Models\Participation;
use App\Models\Reduction;
use LDCWeb\MesBR;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
class EnterCodeController extends Controller
{
/**
*
* @var \LDCCRM\ApiV1
*/
private $apiCrm;
/**
* EnterCodeController
*/
public function __construct()
{
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
}
/**
* Show enter code form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$nbParticipations = Participation::where('user_id', Auth::user()->id)->count();
$settings = app(Settings::class)->select('use_ean_codes', 'nb_participation_player')->first();
if ($nbParticipations >= $settings->nb_participation_player) {
return view('front.basic.participation-exhausted', compact('settings'));
}
return view('front.basic.enter-code', compact('settings'));
}
/**
* Participate Method
*
* @param ParticipateRequest $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function participate(ParticipateRequest $request)
{
// Récupération des données à utilisées.
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
// * Cas IP bannie.
$ipBanned = BannedIp::where('ip', app('clientIp'))->first() === null ? 0 : 1;
if ($ipBanned) {
return view('front.basic.participation-exhausted', compact('settings'));
}
// * Cas nombre de participation maximale atteint.
$nbParticipations = Participation::where('user_id', auth()->user()->id)->count();
if ($nbParticipations >= $settings->nb_participation_player) {
return view('front.basic.participation-exhausted', compact('settings'));
}
// * Tous les cas "bloquants" sont passé, l'utilisateur participe à partir d'ici.
$participation = new Participation();
$participation->user_id = auth()->user()->id;
$participation->code_unique_id = $request->code->id;
$participation->code_ean_id = $request->code_ean ? $request->code_ean->id : null;
$participation->ip = app('clientIp');
$participation->save();
// * Gestion des instants gagnants.
$userAlreadyWon = Participation::has('instantWin')
->whereHas('user', function ($q) {
$q->whereId(auth()->user()->id);
})->first();
// * Si l'utilisateur actuel à déjà gagné un gros lot, pas d'instant gagnant.
if ($userAlreadyWon) {
return $this->serveCouponWin($settings, $participation);
}
$instantWin = InstantWin::where([['appear_date', '<', now()], ['won', 0]])
->orderBy('appear_date', 'ASC')->first();
if ($instantWin) {
// Ici si fail car unique dupliqué catch.
try {
// Gain d'un gros lot.
return $this->instantWin($settings, $request, $participation, $instantWin);
} catch (\ErrorException $e) {
// Unbind instant gagnant.
$participation->instantWin()->delete();
// TODO: si erreur il faut envoyer un mail à equipe.web@ldc.fr
} //end try
}
return $this->serveCouponWin($settings, $participation);
}
/**
* Handle instant wins
*
* @param Settings $settings
* @param Request $request
* @param Participation $participation
* @param InstantWin|null $instantWin
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
private function instantWin(Settings $settings, Request $request, Participation &$participation, $instantWin)
{
$instantWin->won = true;
// Should save now to prevent next player win on the same winning moment.
$instantWin->save();
$participation->instantWin()->save($instantWin);
// Envoi du courrier Arcadia.
if (
$instantWin->prize->arcadia_operation_code !== 0 &&
$instantWin->prize->arcadia_support_code !== 0
) {
$crmId = auth()->user()->crm_id;
$fields = [
'root' => [
[
'fieldName' => 'order_date',
'fieldValue' => date('d/m/Y')
],
[
'fieldName' => 'operation',
'fieldValue' => $instantWin->prize->arcadia_operation_code
]
],
'orderLine' => [
[
'fieldName' => 'code_unique',
'fieldValue' => $request->serial
],
[
'fieldName' => 'support_code',
'fieldValue' => $instantWin->prize->arcadia_support_code
],
[
'fieldName' => 'label_type_support',
'fieldValue' => 'Gain du lot : ' . $instantWin->prize->label_one
]
]
];
if ($settings->use_ean_codes === 1) {
$codeEan = $request->code_ean;
$fields['orderLine'][] = [
'fieldName' => 'code_on_pack',
'fieldValue' => "$codeEan"
];
}
$arcadiaMail = $this->apiCrm->ArcadiaOutgoingMail($crmId, $fields, 'game');
if ($arcadiaMail->status === 'KO') {
Mail::to(config('mail.MAIL_ADMIN'))->send(new CourrierArcadiaError(auth()->user()));
}
} //end if
Mail::to(auth()->user()->email)->send(new PrizeWon(auth()->user(), $instantWin->prize, $settings));
$mails = json_decode($settings->notification_emails);
foreach ($mails as $mail) {
Mail::to($mail->email)->send(new NotifWinAdmin($settings, $participation));
}
$participation->save();
return view("front.basic." . $instantWin->prize->gain_view->file_name, compact('settings'))
->with('prize', $instantWin->prize);
}
/**
* Détermine si un BR doit être servi
* renvoi la vue de gain BR ou la vue "Perdu"
*
* @param Settings $settings
* @param Participation $participation
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
private function serveCouponWin(Settings $settings, Participation $participation)
{
// Si le jeu est 100% gagnant.
if ($settings->reductions_activated === 1) {
$coupon = $this->getRandomCoupon($settings);
$crmCoupon = $this->updateCoupon($settings, $coupon->web_coupon_identifiant, $participation);
if (!$crmCoupon) {
$participation->delete();
return back()->withErrors("Une erreur est survenue, merci de réessayez ultérieurement.");
}
Mail::to(Auth::user()->email)->send(new ReductionWon(Auth::user(), $coupon, $settings, $crmCoupon));
return view('front.basic.reduction', compact('crmCoupon', 'coupon'));
} else {
return view('front.basic.loose');
}
}
/**
* Get a random coupon
*
* @param Settings $settings
* @return mixed
*/
private function getRandomCoupon(Settings $settings)
{
$webCoupons = json_decode($settings->web_coupons);
if (count($webCoupons) > 1) {
$lots = [];
foreach ($webCoupons as $webCoupon) {
$lots[] = $webCoupon;
}
foreach ($lots as $lot) {
for ($i = 0; $i < $lot->percentage; $i++) {
$tmp[] = $lot;
}
}
shuffle($tmp);
return $tmp[0];
} else {
return $webCoupons[0];
}
}
/**
* Update a coupon
*
* @param Settings $settings
* @param mixed $coupon
* @param Participation $participation
* @return \App\Models\Reduction|null
*/
private function updateCoupon(Settings $settings, $coupon, Participation $participation)
{
$reduction = null;
$mesBR = new MesBR(config('mesbr.endpoint'), $settings->reductions_site, $settings->reductions_campaign);
$crmUser = $this->apiCrm->getCustomer(Auth::user()->crm_id);
if ($crmUser->status === 'OK') {
$mesBR->updateContact($crmUser->user);
$result = $mesBR->updatePanier($crmUser->user, $coupon);
if ($result["status"] === "OK") {
$reduction = new Reduction();
$reduction->link = $result["link"];
$reduction->verification = $result["verif"];
$reduction->basket_id = $result["basketId"];
$reduction->save();
$participation->reduction_id = $reduction->id;
$participation->save();
} else {
Mail::to(config('mail.MAIL_ADMIN'))
->send(new NotifAdmin(\sprintf(
'MESBR : Une erreur est survenue. Code : %s Message : %s',
$result["code"],
$result["message"]
)));
}
} //end if
return $reduction;
}
/**
* Undocumented function
*
* @return \Illuminate\Http\Response
*/
public function formWinningProof()
{
$participation = Participation::where([
['user_id', Auth::user()->id],
['sticker', null],
['ticket', null],
['barcode', null]
])->has('instantWin')->first();
if ($participation) {
return view('front.basic.winning-proof', compact('participation'));
}
return redirect()->route('home');
}
}

View file

@ -0,0 +1,54 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\CompleteInfosRequest;
use Illuminate\Support\Facades\Session;
use LDC\LDCCRM\Exceptions\ApiErrorException;
use LDC\LDCCRM\Exceptions\CrmException;
use LDC\LDCCRM\Exceptions\ValidationException;
class CustomerController extends Controller
{
/**
* Show customer complete form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function completeInfos()
{
/** @var \App\Models\Customer $customer */
$customer = auth('customer')->user();
return view('front.basic.complete-infos', ['customer' => $customer]);
}
/**
* Update account info
*
* @param CompleteInfosRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function completeInfosSubmit(CompleteInfosRequest $request)
{
/** @var \App\Models\Customer $customer */
$customer = auth('customer')->user();
try {
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
$crmCustomer = $customer->apiData;
$crmCustomer->fill($request->validated());
$crmCustomer->save();
Session::remove('needCrmInfoUpdate');
return redirect()->route('saisir-code');
} catch (ApiErrorException | ValidationException $e) {
return back()->withErrors($e->getMessage());
} catch (\Exception | \TypeError | CrmException $e) {
\report($e);
} //end try
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
}
}

View file

@ -1,11 +1,17 @@
<?php
namespace App\Http\Controllers;
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Models\Settings;
class EndPageController extends Controller
{
/**
* Ended game page
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$settings = app(Settings::class)
@ -13,7 +19,7 @@ class EndPageController extends Controller
->first();
if (
$settings->end_date < now() &&
$settings->activated_close_page === 1 &&
$settings->activated_close_page &&
$settings->close_page_active_date > now()
) {
return view('front.basic.end', compact('settings'));

View file

@ -0,0 +1,301 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\ParticipateRequest;
use App\Mail\NotifAdmin;
use App\Mail\NotifWinAdmin;
use App\Mail\PrizeWon;
use App\Mail\ReductionWon;
use App\Models\BannedIp;
use App\Models\Customer;
use App\Models\InstantWin;
use App\Models\Participation;
use App\Models\Reduction;
use LDCWeb\MesBR;
use App\Models\Settings;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
class EnterCodeController extends Controller
{
/**
* Show enter code form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
/** @var \App\Models\Customer|null $customer */
$customer = auth('customer')->user();
// * Only auth customer can access
if (!auth('customer')->check()) {
return redirect()->route('home');
}
$nbParticipations = Participation::whereHas('customer', function ($q) use ($customer) {
$q->whereId($customer->id);
})->count();
$settings = app(Settings::class)->select('use_ean_codes', 'nb_participation_player')->first();
if ($nbParticipations >= $settings->nb_participation_player) {
return view('front.basic.participation-exhausted', compact('settings'));
}
return view('front.basic.enter-code', compact('settings'));
}
/**
* Participate Method
*
* @param ParticipateRequest $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function participate(ParticipateRequest $request)
{
try {
return DB::transaction(function () use ($request) {
// Récupération des données à utilisées.
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
/** @var \App\Models\Customer $customer */
$customer = auth('customer')->user();
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
$crmCustomer = $customer->apiData;
// * Cas IP bannie.
if (BannedIp::where('ip', app('clientIp'))->exists()) {
return view('front.basic.participation-exhausted', compact('settings'));
}
// * Cas nombre de participation maximale atteint.
$nbParticipations = Participation::whereHas('customer', function ($q) use ($customer) {
$q->whereId($customer->id);
})->count();
if ($nbParticipations >= $settings->nb_participation_player) {
return view('front.basic.participation-exhausted', compact('settings'));
}
// * Tous les cas "bloquants" sont passé, l'utilisateur participe à partir d'ici.
$participation = new Participation();
$participation->code_unique_id = $request->code->id;
$participation->code_ean_id = $request->code_ean ? $request->code_ean->id : null;
$participation->ip = app('clientIp');
$participation->customer()->associate($customer);
$participation->saveOrFail();
// * Gestion des instants gagnants.
$userAlreadyWon = Participation::has('instantWin')
->whereHas('customer', function ($q) use ($customer) {
$q->whereId($customer->id);
})->first();
// * Si l'utilisateur actuel à déjà gagné un gros lot, pas d'instant gagnant.
if ($userAlreadyWon) {
return $this->serveCouponWin($settings, $participation, $crmCustomer);
}
/** @var \App\Models\InstantWin|null */
$instantWin = InstantWin::where('appear_date', '<', now())
->whereDoesntHave('participation')->orderBy('appear_date', 'ASC')
->lockForUpdate()->first();
if ($instantWin) {
// Ici si fail car unique dupliqué catch.
try {
// Gain d'un gros lot.
return $this->instantWin(
$settings,
$participation,
$crmCustomer,
$instantWin
);
} catch (\ErrorException $e) {
report($e);
// Unbind instant gagnant.
$participation->instantWin()->deleteOrFail();
} //end try
}
return $this->serveCouponWin(
$settings,
$participation,
$crmCustomer
);
});
} catch (\ErrorException $e) {
report($e);
return back()
->withErrors('Une erreur est survenue, merci de réessayez ultérieurement.');
}//end try
}
/**
* Handle instant wins
*
* @param Settings $settings
* @param Participation $participation
* @param CrmCustomer $crmCustomer
* @param InstantWin $instantWin
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
private function instantWin(
Settings $settings,
Participation &$participation,
CrmCustomer $crmCustomer,
InstantWin $instantWin
) {
$participation->instantWin()->save($instantWin);
Mail::to($crmCustomer->email)->send(new PrizeWon($crmCustomer, $instantWin->prize, $settings));
$mails = collect($settings->notification_emails);
// ? Is settings.notification_emails empty ?
if (!$mails->count()) {
// ! Send to null (will send to MAIL_ADMIN and print warning in mail object)
$mails = [null];
}
foreach ($mails as $mail) {
Mail::to($mail)->send(new NotifWinAdmin(
$crmCustomer,
$settings,
$participation
));
}
return view("front.basic." . $instantWin->prize->gain_view->file_name, compact('settings'))
->with('prize', $instantWin->prize);
}
/**
* Détermine si un BR doit être servi
* renvoi la vue de gain BR ou la vue "Perdu"
*
* @param Settings $settings
* @param Participation $participation
* @param CrmCustomer $crmCustomer
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
* @throws \ErrorException If no web coupons are available.
*/
private function serveCouponWin(Settings $settings, Participation $participation, CrmCustomer $crmCustomer)
{
// Si le jeu est 100% gagnant.
if ($settings->reductions_activated) {
if (!($coupon = $this->getRandomCoupon($settings))) {
throw new \ErrorException('No web coupons are available');
}
$reduction = $this->updateCoupon(
$settings,
$coupon['web_coupon_identifiant'],
$participation,
$crmCustomer
);
if (!$reduction) {
$participation->deleteOrFail();
abort(back()->withErrors('Une erreur est survenue, merci de réessayez ultérieurement.'));
}
Mail::to($crmCustomer->email)
->send(new ReductionWon($crmCustomer, $coupon['face_value'], $settings, $reduction));
return view('front.basic.reduction', compact('crmCoupon', 'coupon'));
} else {
return view('front.basic.loose');
}
}
/**
* Get a random coupon
*
* @param Settings $settings
* @return array|null
*/
private function getRandomCoupon(Settings $settings): ?array
{
$webCoupons = $settings->web_coupons;
if (count($webCoupons) > 1) {
$lots = [];
foreach ($webCoupons as $webCoupon) {
$lots[] = $webCoupon;
}
foreach ($lots as $lot) {
for ($i = 0; $i < $lot->percentage; $i++) {
$tmp[] = $lot;
}
}
shuffle($tmp);
return $tmp[0];
} else {
return $webCoupons[0] ?? null;
}
}
/**
* Update a coupon
*
* FIXME: When mes BR will be updated.
*
* @param Settings $settings
* @param integer $couponId
* @param Participation $participation
* @param CrmCustomer $crmCustomer
* @return \App\Models\Reduction|null
*/
private function updateCoupon(
Settings $settings,
int $couponId,
Participation $participation,
CrmCustomer $crmCustomer
) {
$reduction = null;
$mesBR = new MesBR(config('mesbr.endpoint'), $settings->reductions_site, $settings->reductions_campaign);
if ($crmUser->status === 'OK') {
$mesBR->updateContact($crmUser->user);
$result = $mesBR->updatePanier($crmUser->user, $couponId);
if ($result["status"] === "OK") {
$reduction = new Reduction();
$reduction->link = $result["link"];
$reduction->verification = $result["verif"];
$reduction->basket_id = $result["basketId"];
$reduction->saveOrFail();
$participation->reduction_id = $reduction->id;
$participation->saveOrFail();
} else {
Mail::to(config('mail.MAIL_ADMIN'))
->send(new NotifAdmin(\sprintf(
'MESBR : Une erreur est survenue. Code : %s Message : %s',
$result["code"],
$result["message"]
)));
}
} //end if
return $reduction;
}
/**
* Show Wining proof form
*
* @return \Illuminate\Http\Response
*/
public function formWinningProof()
{
/** @var \App\Models\Customer|null $customer */
$customer = auth('customer')->user();
// * Only auth customer can access
if (!auth('customer')->check() or \get_class($customer) === Customer::class) {
return redirect()->route('home');
}
$participation = Participation::whereHas('customer', function ($q) use ($customer) {
$q->whereId($customer->id);
})->whereHas('instantWin')->where([
['sticker', null],
['ticket', null],
['barcode', null]
])->first();
if ($participation) {
return view('front.basic.winning-proof', compact('participation'));
}
return redirect()->route('home');
}
}

View file

@ -1,12 +1,18 @@
<?php
namespace App\Http\Controllers;
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Models\FaqQuestion;
use App\Models\FaqTheme;
class FAQController extends Controller
{
/**
* Faq page
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$questions = FaqQuestion::all();

View file

@ -1,9 +1,16 @@
<?php
namespace App\Http\Controllers;
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
class GainsController extends Controller
{
/**
* Gains page
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
if (view()->exists('front.basic.gains')) {

View file

@ -0,0 +1,18 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
class HomeController extends Controller
{
/**
* Home page
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function home()
{
return view('front.basic.home');
}
}

View file

@ -1,9 +1,16 @@
<?php
namespace App\Http\Controllers;
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
class HowToPlayController extends Controller
{
/**
* How to play page
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
if (view()->exists('front.basic.how-to-play')) {

View file

@ -0,0 +1,443 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\AuthenticateRequest;
use App\Http\Requests\Fo\RegisterRequest;
use App\Http\Requests\Fo\UpdatePasswordRequest;
use App\Http\Requests\Fo\ForgotPasswordRequest;
use App\Lib\ToolboxHelper;
use App\Mail\PasswordReset;
use App\Mail\VerifyEmail;
use App\Models\Customer;
use App\Models\Settings;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\Validator;
use LDC\LDCCRM\Enums\ApiError;
use LDC\LDCCRM\Exceptions\ApiErrorException;
use LDC\LDCCRM\Exceptions\CrmException;
use LDC\LDCCRM\Exceptions\ValidationException;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
class LoginController extends Controller
{
/**
* Show login form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function loginForm()
{
if (!ToolboxHelper::isLoginAccessAllowed()) {
abort(\response()->redirectToRoute('home'));
}
return view('front.basic.login');
}
/**
* Authenticate user
*
* @param AuthenticateRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function loginFormSubmit(AuthenticateRequest $request)
{
$this->authenticateUser($request);
$this->authenticateCustomer($request);
return back()->withInput($request->except('password'))
->withErrors('Les identifiants entrés sont incorrects.');
}
/**
* Log out
*
* @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
*/
public function logout()
{
auth('web')->logout();
auth('customer')->logout();
return redirect()->route('home');
}
/**
* Confirm Email
*
* @param mixed $verifyToken
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function confirmEmail($verifyToken)
{
$result = false;
/** @var \App\Models\Customer $customer */
if (!($customer = Customer::select('hashcode')->where('email_verify_token', $verifyToken)->first())) {
return view('front.basic.confirm-email', compact('result'));
}
try {
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
$crmCustomer = $customer->apiData;
if ($crmCustomer->activate()) {
$result = true;
}
} catch (ApiErrorException $e) {
if ($e->getApiError()->equals(ApiError::customerAlreadyActive())) {
return view('front.auth.activate')
->with(
'message',
'Votre compte est déjà activé, vous pouvez dès à présent vous connecter avec celui-ci.'
);
}
// ! Une erreur critique est survenue avec la CRM.
report($e);
} catch (CrmException $e) {
// ! Une erreur critique est survenue avec la CRM.
report($e);
} //end try
return view('front.basic.confirm-email', compact('result'));
}
/**
* Forgot Password form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function forgotPassword()
{
return view('front.basic.forgot-password');
}
/**
* forgotPassword submit
*
* @param ForgotPasswordRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function forgotPasswordSubmit(ForgotPasswordRequest $request)
{
if (!($crmCustomer = $this->getCustomerFromCrm($request->email))) {
return back()->withInput($request->only('email'))
->withErrors('Le mail que vous avez entré n\'est pas enregistré dans nos services.');
}
/** @var \App\Models\Customer $customer */
$customer = $this->createLocalCustomer($crmCustomer);
$customer->password_token = Str::uuid();
$customer->saveOrFail();
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
Mail::to($request->email)->send(new PasswordReset($customer, $settings));
return redirect()->route('login')
->with('success', 'Un mail de réinitialisation de votre mot de passe vous a été envoyé(e).');
}
/**
* Forgot password form show
*
* @param Request $request
* @param mixed $token
* @return \Illuminate\Http\RedirectResponse
*/
public function forgotPasswordReset(Request $request, $token)
{
if (!$request->hasValidSignature(false)) {
return redirect()->route('login')
->withErrors('Le lien de changement de votre mot de passe n\'est plus valide, veuillez réessayer. ');
}
if (!Customer::where('password_token', $token)->exists()) {
return redirect()->route('forgot-password', ['tokenValid' => false])
->withErrors('Le lien de changement du mot de passe est incorrect.');
}
return view('front.basic.forgot-password', [
'tokenValid' => true,
'token' => $token
]);
}
/**
* Change password form submit
*
* @param UpdatePasswordRequest $request
* @param mixed $token
* @return \Illuminate\Http\RedirectResponse
*/
public function forgotPasswordResetSubmit(UpdatePasswordRequest $request, $token)
{
/** @var \App\Models\Customer $customer */
if (!$request->hasValidSignature(false) or !($customer = Customer::where('password_token', $token)->first())) {
return redirect()->route('forgot-password', ['tokenValid' => false])
->withErrors('Le lien de changement du mot de passe est incorrect.');
}
/** @var \LDC\LDCCRM\CrmApiV2 */
$crm = app('crmAPI');
try {
// Ne devrait pas survenir, $crm->login throws ApiError::authFailed() .
if ($crm->login($customer->email, $request->password)) {
// Mauvais identifiants.
return back()->withErrors('Vous ne pouvez pas utiliser un de vos anciens mot de passe.');
}
// phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedCatch
} catch (ApiErrorException $e) {
// * Continue
} catch (\TypeError | CrmException | ApiErrorException $e) {
report($e);
// ! Une erreur critique est survenue avec la CRM.
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
}
try {
if (!($crmCustomer = $crm->getCustomer($customer->hashcode))) {
return back()->withErrors('Changement impossible, compte inexistant.');
}
$crmCustomer->password = $request->password;
$crmCustomer->save();
$customer->password_token = null;
$customer->saveOrFail();
return redirect()->route('login')
->with('success', 'Vous pouvez désormais vous connecter avec votre nouveau mot de passe.');
} catch (\TypeError | CrmException | ApiErrorException $e) {
report($e);
// ! Une erreur critique est survenue avec la CRM
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
} catch (ValidationException $e) {
return back()->withErrors(sprintf('Nouveau mot de passe : %s', $e->getMessage()));
}
}
/**
* Try Login User if exists (email)
*
* Does nothing if email does not exists in users table.
*
* @param AuthenticateRequest $request
* @return void
* @throws \Symfony\Component\HttpKernel\Exception\HttpException If user is logged in.
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException If redirect route is not found.
*/
private function authenticateUser(AuthenticateRequest $request)
{
if (
User::whereEmail($request->email)->exists() and
\auth('web')->attempt([
'email' => $request->email,
'password' => $request->password
], $request->remember)
) {
abort(redirect()->route('bo.dashboard'));
}
}
/**
* Try Login Customer if exists (email)
*
* Does nothing if email does not exists in customers table.
*
* @param AuthenticateRequest $request
* @return void
* @throws \Symfony\Component\HttpKernel\Exception\HttpException If user is logged in.
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException If redirect route is not found.
* @phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.Missing
*/
private function authenticateCustomer(AuthenticateRequest $request)
{
/** @var \App\Models\Customer|null $customerLocal */
$customer = Customer::where('email', $request->email)->first();
/** @var \LDC\LDCCRM\CrmApiV2 */
$crm = app('crmAPI');
try {
$crm->login($request->email, $request->password);
if (!($crmCustomer = $this->getCustomerFromCrm($request->email))) {
abort(back()->withInput($request->except('password'))
->withErrors('Une erreur est survenue veuillez réssayer plus tard.'));
}
// ? Test is user data valid ?
try {
/**
* On va tester de mettre a jour uniquement les champs
* requis pour mes br afin de detecter si ils doivent etre mis à jour
* la validation va se faire par la crm (ou le client).
*/
$crmCustomer->fill([
'birth_date' => $crmCustomer->birth_date,
'address' => $crmCustomer->address,
'postcode' => $crmCustomer->postcode,
'country' => $crmCustomer->country,
'city' => $crmCustomer->city
]);
// * On valide les données selon les critères de registerController
$rules = collect((new RegisterRequest())->rules());
$validator = Validator::make(
[
'birth_date' => $crmCustomer->birth_date,
'address' => $crmCustomer->address,
'postcode' => $crmCustomer->postcode,
'country' => $crmCustomer->country->value,
'city' => $crmCustomer->city
],
[
'birth_date' => $rules->get('birth_date'),
'address' => $rules->get('address'),
'postcode' => $rules->get('postcode'),
'country' => $rules->get('country'),
'city' => $rules->get('city')
]
);
if ($validator->fails()) {
throw new ValidationException();
} else {
Session::remove('needCrmInfoUpdate', true);
}
} catch (ValidationException $e) {
Session::push('needCrmInfoUpdate', true);
} catch (ApiErrorException $e) {
if (!$e->getApiError()->equals(ApiError::validationFailed())) {
throw $e;
}
Session::push('needCrmInfoUpdate', true);
} //end try
// * Si pas de compte local mais existe en CRM.
if (!$customer) {
$customer = $this->createLocalCustomer($crmCustomer);
}
abort($this->processLogin($customer, $request->remember));
} catch (ApiErrorException $e) {
abort($this->handleLoginApiErrorException($e, $request));
} catch (CrmException $e) {
\report($e);
abort(back()->withInput($request->except('password'))
->withErrors('La connexion est impossible pour le moment, veuillez réessayer plus tard.'));
} //end try
}
/**
* Handle Api error exception
*
* @param ApiErrorException $e
* @param AuthenticateRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
private function handleLoginApiErrorException(ApiErrorException $e, AuthenticateRequest $request)
{
/** @var Customers|null */
$customer = Customer::where('email', $request->email)->first();
/** @var \LDC\LDCCRM\CrmApiV2 */
$crm = app('crmAPI');
switch ($e->getApiError()) {
case ApiError::authFailed():
// * Mauvais identifiants
return back()->withInput($request->except('password'))
->withErrors('Email ou mot de passe incorrect.');
case ApiError::customerNotActivated():
// * Le compte n'est pas activé
try {
if (!($crmCustomer = $crm->getCustomer($request->email))) {
Log::critical(sprintf('Customer %s could not be retrieved from crm', $request->email));
return back()->withErrors(
__('Une erreur est survenue, merci de réessayer ultérieurement.')
);
}
if (!$customer) {
$customer = $this->createLocalCustomer($crmCustomer);
}
$tokenMail = Str::uuid();
Mail::to($request->email)->send(new VerifyEmail($crmCustomer, $tokenMail));
$customer->email_verify_token = $tokenMail;
$customer->saveOrFail();
return back()
->withErrors(
__('Votre compte n\'est pas activé, vérifiez dans vos emails pour y trouver
le mail de confirmation. Un lien d\'activation vous a été renvoyé.')
);
} catch (CrmException | ApiErrorException $e) {
report($e);
// ! Une erreur critique est survenue avec la CRM
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
} //end try
default:
report($e);
// ! Une erreur non gérée
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
} //end switch
}
/**
* Get Local customer using email and update info from crm.
*
* @param string $email
* @return CrmCustomer|null
*/
private function getCustomerFromCrm(string $email): ?CrmCustomer
{
try {
return CrmCustomer::findWithEmail($email);
} catch (ApiErrorException $e) {
if ($e->getApiError()->equals(ApiError::modelNotFound())) {
return null;
}
abort(back()->withErrors($e->getMessage()));
} catch (CrmException $e) {
report($e);
abort(back()->withErrors('Une erreur est survenue'));
}
}
/**
* Create a local customer
*
* @param CrmCustomer $crmCustomer
* @return Customer
*/
private function createLocalCustomer(CrmCustomer $crmCustomer): Customer
{
/** @var \App\Models\Customer $customer */
$customer = Customer::firstOrNew([
'email' => $crmCustomer->email
]);
$customer->hashcode = $crmCustomer->hashcode;
$customer->saveOrFail();
return $customer;
}
/**
* Login a customer
*
* @param Customer $customer
* @param boolean $remember
* @return \Illuminate\Routing\Redirector|\Illuminate\Http\RedirectResponse
*/
private function processLogin(Customer $customer, bool $remember)
{
/** @var \Illuminate\Auth\SessionGuard */
$guard = auth('customer');
$guard->login($customer, $remember);
$url = Session::pull('url.intended');
Session::forget('url.intended');
Session::save();
return $url ? redirect()->to($url) : response()->redirectToRoute('saisir-code');
}
}

View file

@ -1,11 +1,17 @@
<?php
namespace App\Http\Controllers;
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Models\Range;
class ProduitsController extends Controller
{
/**
* Produits porteurs pages
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$ranges = Range::with('products')->orderBy('id')->get();

View file

@ -0,0 +1,104 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\RegisterRequest;
use App\Mail\VerifyEmail;
use App\Models\Customer;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Str;
use LDC\LDCCRM\Enums\ApiError;
use LDC\LDCCRM\Exceptions\ApiErrorException;
use LDC\LDCCRM\Exceptions\CrmException;
use LDC\LDCCRM\Exceptions\ValidationException;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
class RegisterController extends Controller
{
/**
* Register form
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function register()
{
return view('front.basic.register-crm');
}
/**
* Register form submit
*
* @param RegisterRequest $request
* @return \Illuminate\Http\RedirectResponse
*/
public function registerSubmit(RegisterRequest $request)
{
if (!Carbon::parse($request->birth_date)->lessThanOrEqualTo(Carbon::now()->subYears(18))) {
return back()
->withInput($request->except('password'))
->withErrors("Vous devez être majeur pour vous inscrire au jeu.");
}
$crmCustomer = null;
try {
$crmCustomer = new CrmCustomer(\array_intersect_key(
$request->validated(),
[
'firstname' => '',
'lastname' => '',
'birth_date' => '',
'address' => '',
'postcode' => '',
'country' => '',
'city' => '',
'phone' => '',
'email' => '',
'password' => '',
'opt_in' => '',
]
));
$crmCustomer->password = $request->password;
$crmCustomer->save();
$tokenMail = Str::uuid();
Mail::to($request->email)->send(new VerifyEmail($crmCustomer, $tokenMail));
$customer = new Customer();
$customer->email = $crmCustomer->email;
$customer->hashcode = $crmCustomer->hashcode;
$customer->email_verify_token = $tokenMail;
$customer->saveOrFail();
return redirect()->route('login')
->with('success', sprintf(
'%s %s %s %s %s',
'Pour finaliser votre inscription, merci de cliquer sur le lien qui vient de vous être envoyé par',
'email<br> Informations complémentaires :<br>',
'- Vérifiez vos spams : l\'email de confirmation s\'y trouve peut-être<br>',
'- Attention : le mail peut parfois mettre quelques minutes à vous parvenir<br>',
//phpcs:ignore Generic.Files.LineLength.TooLong
'- L\'activation de votre compte doit se faire dans les 24 heures qui suivent la demande de création.'
));
} catch (ApiErrorException $e) {
if ($e->getApiError()->equals(ApiError::customerExists())) {
return back()->withErrors('Un compte est déjà associé à cette adresse email.');
}
if ($e->getApiError()->equals(ApiError::validationFailed())) {
return back()->withErrors($e->getMessage());
}
report($e);
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
} catch (ValidationException $e) {
return back()->withErrors($e->getMessage());
} catch (\Exception | \TypeError | CrmException $e) {
\report($e);
// ! Une erreur critique est survenue avec la CRM.
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
} //end try
return back()->withErrors('Une erreur est survenue, merci de réessayer ultérieurement.');
}
}

View file

@ -1,16 +1,22 @@
<?php
namespace App\Http\Controllers;
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Models\Settings;
class TeaserController extends Controller
{
/**
* Teaser page
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function index()
{
$settings = app(Settings::class)
->select('start_date', 'end_date', 'activated_teaser', 'teaser_end_activity')->first();
if ($settings->activated_teaser === 1 && $settings->teaser_end_activity > now()) {
->select('start_date', 'end_date', 'activated_teaser')->first();
if ($settings->activated_teaser) {
return view('front.basic.teaser', compact('settings'));
}
return redirect()->route('home');

View file

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Enums\ContentPageType;
use App\Http\Controllers\Controller;
use App\Models\Content;
class ViewContentController extends Controller
{
/**
* Reglement page
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function reglement()
{
$content = Content::findOrFail(ContentPageType::reglement()->value);
return view('front.basic.reglement', compact('content'));
}
/**
* Charte page
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function charte()
{
$content = Content::findOrFail(ContentPageType::charte()->value);
return view('front.basic.charte', compact('content'));
}
/**
* Legals page
*
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function legals()
{
$content = Content::findOrFail(ContentPageType::legals()->value);
return view('front.basic.legals', compact('content'));
}
}

View file

@ -0,0 +1,116 @@
<?php
namespace App\Http\Controllers\Fo;
use App\Http\Controllers\Controller;
use App\Http\Requests\Fo\SubmitWinningProofRequest;
use App\Mail\WinningProofMail;
use App\Models\Participation;
use App\Models\Settings;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use LDC\LDCCRM\Exceptions\ApiErrorException;
use LDC\LDCCRM\Exceptions\CrmException;
use LDC\LDCCRM\Exceptions\ValidationException;
class WinningProofController extends Controller
{
/**
* Submit Winning proof
*
* @param SubmitWinningProofRequest $request
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
*/
public function sendWinningProof(SubmitWinningProofRequest $request)
{
try {
return DB::transaction(function () use ($request) {
/** @var \App\Models\Customer $customer */
$customer = auth('customer')->user();
/** @var \LDC\LDCCRM\Models\Customer $crmCustomer */
$crmCustomer = $customer->apiData;
// On récupère la participation gagnante en attente des infos.
/** @var \App\Models\Participation|null $participation */
$participation = Participation::whereHas('customer', function ($q) use ($customer) {
$q->whereId($customer->id);
})->whereHas('instantWin')->where([
['sticker', null],
['ticket', null],
['barcode', null]
])->first();
if (!$participation) {
return redirect()->route('home');
}
/** @var \Illuminate\Http\UploadedFile $sticker */
$sticker = $request->sticker;
/** @var \Illuminate\Http\UploadedFile $ticket */
$ticket = $request->ticket;
/** @var \Illuminate\Http\UploadedFile $barcode */
$barcode = $request->barcode;
// * Mise à jour utilisateur dans la CRM.
try {
$crmCustomer->fill(\array_intersect_key($request->validated(), [
'firstname' => '',
'lastname' => '',
'address' => '',
'postcode' => '',
'country' => '',
'city' => '',
'phone' => '',
]));
$crmCustomer->save();
} catch (ApiErrorException | ValidationException $e) {
return back()->withErrors($e->getMessage());
} catch (\Exception | \TypeError | CrmException $e) {
\report($e);
} //end try
$participationId = $participation->id;
$stickerFileName = $participationId . '-sticker.' . $sticker->extension();
$sticker->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $stickerFileName);
$stickerPath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $stickerFileName;
$ticketFileName = $participationId . '-ticket.' . $ticket->extension();
$ticket->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $ticketFileName);
$ticketPath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $ticketFileName;
$barcodeFileName = $participationId . '-code-barre.' . $barcode->extension();
$barcode->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $barcodeFileName);
$barcodePath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $barcodeFileName;
$participation->sticker = $stickerFileName;
$participation->ticket = $ticketFileName;
$participation->barcode = $barcodeFileName;
$participation->saveOrFail();
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
$mails = \collect($settings->notification_emails);
// ? Is settings.notification_emails empty ?
if (!$mails->count()) {
// ! Send to null (will send to MAIL_ADMIN and print warning in mail object)
$mails = [null];
}
foreach ($mails as $mail) {
Mail::to($mail)->send(new WinningProofMail(
$stickerPath,
$ticketPath,
$barcodePath,
$participation,
$crmCustomer,
$settings
));
}
return view('front.basic.replay');
});
} catch (\Exception $e) {
report($e);
return back()->withErrors('Une erreur est survenue, merci de réessayez ultérieurement.');
}//end try
}
}

View file

@ -1,11 +0,0 @@
<?php
namespace App\Http\Controllers;
class HomeController extends Controller
{
public function home()
{
return view('front.basic.home');
}
}

View file

@ -1,275 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Mail\PasswordReset;
use App\Mail\VerifyEmail;
use App\Models\Settings;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;
use App\Models\User;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
class LoginController extends Controller
{
private $apiCrm;
public function __construct()
{
$this->middleware('guest')->except('logout');
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
}
public function index()
{
return view('front.basic.login');
}
public function authenticate(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$email = filter_var($request->email, FILTER_SANITIZE_EMAIL);
$password = $request->password;
$remember = $request->remember !== null ? true : false;
$userLocal = User::where('email', $email)->first();
if ($userLocal) {
if ($userLocal->email_verified === 1) {
if ($userLocal->role > 2) {
$connect = $this->apiCrm->loginCustomer($email, $password);
if ($connect->status === 'KO') {
if ($connect->code === 500) {
return back()->withInput($request->except("password"))
->withErrors("La connexion est impossible pour le moment, veuillez réessayer plus tard.");
} else {
return back()->withInput($request->except("password"))
->withErrors("Email ou mot de passe incorrect.");
}
}
}
} else {
$userLocal->email_verify_token = Str::uuid();
$userLocal->save();
Mail::to($email)->send(new VerifyEmail($userLocal));
return back()->withInput($request->except("password"))
->withErrors("Votre compte existe mais votre email n'est pas confirmé, merci de vérifier vos emails.");
}//end if
} else {
$connect = $this->apiCrm->loginCustomer($email, $password);
if ($connect->status === 'OK') {
$userLocal = User::create([
'crm_id' => $connect->user->crm_id,
'firstname' => $connect->user->firstname,
'lastname' => $connect->user->lastname,
'birth_date' => $connect->user->birth_date,
'email' => $email,
// TODO : MOTDEPASSE ???.
'password' => Hash::make("MOTDEPASSE"),
'address' => $connect->user->address,
'address2' => $connect->user->address2,
'town' => $connect->user->city,
'postal_code' => $connect->user->postcode,
'country' => $connect->user->country,
'email_verified' => 1
]);
} else {
// Compte existant mais non activé.
if ($connect->code === 116) {
$userLocal = User::create([
'crm_id' => $connect->user->crm_id,
'firstname' => $connect->user->firstname,
'lastname' => $connect->user->lastname,
'birth_date' => $connect->user->birth_date,
'email' => $email,
// TODO : MOTDEPASSE ???.
'password' => Hash::make("MOTDEPASSE"),
'address' => $connect->user->address,
'address2' => $connect->user->address2,
'town' => $connect->user->city,
'postal_code' => $connect->user->postcode,
'country' => $connect->user->country
]);
$userLocal->email_verify_token = Str::uuid();
$userLocal->save();
Mail::to($email)->send(new VerifyEmail($userLocal));
return back()->withInput($request->except("password"))
->withErrors("Votre compte existe mais votre email n'est pas confirmé, merci de vérifier vos emails.");
} elseif ($connect->code === 500) {
return back()->withInput($request->except("password"))
->withErrors("La connexion est impossible pour le moment, veuillez réessayer plus tard.");
} else {
return back()->withInput($request->except("password"))
->withErrors("Email ou mot de passe incorrect.");
} //end if
} //end if
}//end if
// TODO : Modifier avec separation guard.
$tmpPwd = "MOTDEPASSE";
if ($userLocal->role <= 2) {
$tmpPwd = $password;
}
if (Auth::attempt(["email" => $email, "password" => $tmpPwd], $remember)) {
if ($userLocal->role <= 2) {
return redirect()->route('bo.dashboard');
}
return redirect()->route('saisir-code');
} else {
return back()->withInput($request->except('password'))->withErrors('Les identifiants entrés sont incorrects.');
}
}
public function logout()
{
Auth::logout();
return redirect()->route('home');
}
public function confirmEmail($verifyToken)
{
$result = false;
$user = User::where('email_verify_token', $verifyToken)->first();
if (!$user) {
return view('front.basic.confirm-email', compact('result'));
}
$activation = $this->apiCrm->activateCustomer($user->crm_id);
if ($activation->status === 'OK') {
$user->email_verified = 1;
$user->email_verify_token = null;
$user->save();
$result = true;
} else {
// User already active.
if ($activation->code === 110) {
$user->email_verified = 1;
$user->email_verify_token = null;
$user->save();
$result = true;
}
}
return view('front.basic.confirm-email', compact('result'));
}
public function forgotPassword(Request $request)
{
if ($request->tokenValid && $request->token) {
$tokenValid = $request->tokenValid;
$token = $request->token;
return view('front.basic.forgot-password', compact('tokenValid', 'token'));
}
return view('front.basic.forgot-password');
}
public function forgotPasswordReset(Request $request, $token)
{
if (!$request->hasValidSignature(false)) {
return redirect()->route('login')
->withErrors("Le lien de changement de votre mot de passe n'est plus valide, veuillez réessayer.");
}
$tokenValid = false;
$user = User::where('password_token', $token)->first();
if (!$user) {
return redirect()->route('forgot-password', compact('tokenValid'))
->withErrors('Le lien de changement du mot de passe est incorrect.');
}
$tokenValid = true;
return redirect()->route('forgot-password', compact('tokenValid', 'token'));
}
public function mailPassword(Request $request)
{
$email = filter_var($request->email, FILTER_SANITIZE_STRING);
$user = User::where('email', $email)->first();
if (!$user) {
$userCrm = $this->apiCrm->getCustomerByEmail($email);
if ($userCrm->status === 'OK') {
$user = User::create([
'crm_id' => $userCrm->user->crm_id,
'firstname' => $userCrm->user->firstname,
'lastname' => $userCrm->user->lastname,
'birth_date' => $userCrm->user->birth_date,
'email' => $email,
// TODO : MOTDEPASSE ???
'password' => Hash::make("MOTDEPASSE"),
'address' => $userCrm->user->address,
'address2' => $userCrm->user->address2,
'town' => $userCrm->user->city,
'postal_code' => $userCrm->user->postcode,
'country' => $userCrm->user->country,
'email_verified' => 1
]);
if ($userCrm->user->status === 0) {
$user->email_verified = 0;
$user->email_verify_token = Str::uuid();
$user->save();
Mail::to($email)->send(new VerifyEmail($user));
return back()->withInput($request->except("password"))
->withErrors("Votre compte existe mais votre email n'est pas confirmé, merci de vérifier vos emails.");
}
} else {
if ($userCrm->code === 101) {
return back()->withInput($request->only('email'))
->withErrors("Le mail que vous avez entré n'est pas enregistré dans nos services.");
} else {
return back()->withErrors("Une erreur est survenue, veuillez réessayer plus tard.");
}
} //end if
}//end if
$user->password_token = Str::uuid();
$user->save();
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
Mail::to($email)->send(new PasswordReset($user, $settings));
return redirect()->route('login')
->with('success', 'Un mail de réinitialisation de votre mot de passe vous a été envoyé(e).');
}
public function changePassword(Request $request)
{
$request->validate([
'password' => 'required|min:8|confirmed',
]);
$user = User::where('password_token', filter_var($request->token, FILTER_SANITIZE_STRING))->first();
if (!$user) {
return back()->withErrors('Le lien de changement de votre mot de passe est incorrect, veuillez réessayer.');
}
// TODO : Ajouter controle du contenu du mot de passe.
$newPassword = $request->password;
$update = $this->apiCrm->changePwdCustomer($user->crm_id, $newPassword);
if ($update->status === 'OK') {
$user->password_token = null;
$user->save();
return redirect()->route('login')
->with('success', 'Vous pouvez désormais vous connecter avec votre nouveau mot de passe.');
} else {
if ($update->code === 123) {
return back()
->withErrors("Il semblerait que vous ayez déjà utilisé ce mot de passe pour votre compte. Veuillez réessayer en changeant de mot de passe.");
} else {
return back()->withErrors("Une erreur est survenue, veuillez réessayer plus tard.");
}
}
}
}

View file

@ -1,143 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Mail\VerifyEmail;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Carbon\Carbon;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Mail;
class RegisterController extends Controller
{
use RegistersUsers;
// TODO : Utilité ??
protected $redirectTo = RouteServiceProvider::HOME;
private $apiCrm;
public function __construct()
{
$this->middleware('guest');
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
}
public function index()
{
return view('front.basic.register-crm');
}
public function register(Request $request)
{
$request->validate([
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'birth_date' => 'required|string|max:10',
'email' => 'required|string|email|max:255|unique:users|confirmed',
'password' => 'required|string|min:8|confirmed',
'address' => 'required|string|max:255',
'address2' => 'max:255',
'town' => 'required|string|max:255',
'postal_code' => 'required|string|max:255',
'country' => 'required|string|max:255',
'reglement' => 'accepted',
]);
$lastname = filter_var($request->lastname, FILTER_SANITIZE_STRING);
$firstname = filter_var($request->firstname, FILTER_SANITIZE_STRING);
$birthdate = $request->birth_date;
$email = filter_var($request->email, FILTER_SANITIZE_EMAIL);
$password = $request->password;
$address = filter_var($request->address, FILTER_SANITIZE_STRING);
$address2 = $request->address2 !== null ? filter_var($request->address2, FILTER_SANITIZE_STRING) : null;
$town = filter_var($request->town, FILTER_SANITIZE_STRING);
$postcode = filter_var($request->postal_code, FILTER_SANITIZE_STRING);
$country = filter_var($request->country, FILTER_SANITIZE_STRING);
$optin = $request->news !== null ? 1 : 0;
$tokenMail = Str::uuid();
$MJ = Carbon::now()->subYears(18);
if ($this->isSQLDate($birthdate)) {
$d = Carbon::createFromFormat('Y-m-d', $birthdate);
if (!$d->lessThanOrEqualTo($MJ)) {
return back()
->withInput($request->except('password'))
->withErrors("Vous devez être majeur pour vous inscrire au jeu.");
}
} elseif ($this->isFormDate($birthdate)) {
$d = Carbon::createFromFormat('d/m/Y', $birthdate);
if (!$d->lessThanOrEqualTo($MJ)) {
return back()
->withInput($request->except('password'))
->withErrors("Vous devez être majeur pour vous inscrire au jeu.");
}
$birthdate = $d->toDateString();
} else {
return back()
->withInput($request->except('password'))
->withErrors("Erreur sur le champs : date de naissance.");
}
$crmUser = $this->apiCrm->createCustomer($email, $password, $firstname, $lastname, $optin, $birthdate, null, $address, $address2, $town, $postcode, ucfirst($country));
if ($crmUser->status === 'OK') {
$user = User::create([
'crm_id' => $crmUser->user->crm_id,
'firstname' => $firstname,
'lastname' => $lastname,
'birth_date' => $birthdate,
'email' => $email,
'password' => Hash::make("MOTDEPASSE"), // TODO : ???
'address' => $address,
'address2' => $address2,
'town' => $town,
'postal_code' => $postcode,
'country' => ucfirst($country),
'email_verify_token' => $tokenMail,
]);
Mail::to($email)->send(new VerifyEmail($user));
return redirect()->route('login')
->with('success', "Pour finaliser votre inscription, merci de cliquer sur le lien qui vient de vous être envoyé par email<br>" .
"Informations complémentaires :<br>" .
"- Vérifiez vos spams : l'email de confirmation s'y trouve peut-être<br>" .
"- Attention : le mail peut parfois mettre quelques minutes à vous parvenir<br>" .
"- L'activation de votre compte doit se faire dans les 24 heures qui suivent la demande de création.");
} else {
if ($crmUser->code === 103) {
return back()
->withInput($request->except('password'))
->withErrors("Un compte utilisateur est déjà associé à votre email.");
} else {
return back()
->withInput($request->except('password'))
->withErrors("Une erreur est survenue, merci de recommencer.");
}
}//end if
}
private function isSQLDate($date)
{
if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/", $date)) {
return true;
}
return false;
}
private function isFormDate($date)
{
if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])\/(0[1-9]|1[0-2])\/[0-9]{4}$/", $date)) {
return true;
}
return false;
}
}

View file

@ -1,26 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Models\Content;
class ViewContentController extends Controller
{
public function reglement()
{
$content = Content::find(3);
return view('front.basic.reglement', compact('content'));
}
public function charte()
{
$content = Content::find(2);
return view('front.basic.charte', compact('content'));
}
public function legals()
{
$content = Content::find(1);
return view('front.basic.legals', compact('content'));
}
}

View file

@ -1,133 +0,0 @@
<?php
namespace App\Http\Controllers;
use App\Mail\NotifAdmin;
use App\Mail\WinningProof;
use App\Models\Participation;
use App\Models\Settings;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
class WinningProofController extends Controller
{
private $apiCrm;
public function __construct()
{
$this->apiCrm = new \LDCCRM\ApiV1(config('crm.endpoint'), config('crm.token'));
}
public function sendWinningProof(Request $request)
{
// On récupère la participation gagnante en attente des infos
$participation = Participation::where([
['user_id', Auth::user()->id],
['sticker', null],
['ticket', null],
['barcode', null]
])->has('instantWin')->first();
if (!$participation) {
return redirect()->route('home');
}
$request->validate([
'lastname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'address' => 'required|string|max:255',
'address2' => 'max:255',
'town' => 'required|string|max:255',
'postal_code' => 'required|max:255',
'country' => 'required|string|max:255',
'phone' => 'required|string|max:50',
'sticker' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
'ticket' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
'barcode' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
]);
$lastname = filter_var($request->lastname, FILTER_SANITIZE_STRING);
$firstname = filter_var($request->firstname, FILTER_SANITIZE_STRING);
$address = filter_var($request->address, FILTER_SANITIZE_STRING);
$address2 = $request->address2 !== null ? filter_var($request->address2, FILTER_SANITIZE_STRING) : null;
$town = filter_var($request->town, FILTER_SANITIZE_STRING);
$postalCode = filter_var($request->postal_code, FILTER_SANITIZE_STRING);
$country = filter_var($request->country, FILTER_SANITIZE_STRING);
$phone = filter_var($request->phone, FILTER_SANITIZE_STRING);
$sticker = $request->sticker;
$ticket = $request->ticket;
$barcode = $request->barcode;
// Mise à jour de l'utilisateur en local.
$user = User::find(Auth::user()->id);
$user->lastname = $lastname;
$user->firstname = $firstname;
$user->address = $address;
$user->address2 = $address2;
$user->town = $town;
$user->postal_code = $postalCode;
$user->country = $country;
$user->phone = $phone;
$user->save();
// Mise à jour utilisateur dans la CRM.
$update = $this->apiCrm->updateCustomer(
$user->crm_id,
$firstname,
$lastname,
null,
null,
$phone,
$address,
$address2,
$town,
$postalCode,
ucfirst($country)
);
if ($update->status !== 'OK') {
Log::warning('Erreur lors de la mise a jour du user (crm_id : ' . $user->crm_id .
') - code : ' . $update->code . ' - message : ' . $update->message);
Mail::to(config('mail.MAIL_ADMIN'))->send(new NotifAdmin(
'CRM : Erreur lors de la mise a jour du user (crm_id : ' .
$user->crm_id . ') - code : ' . $update->code . ' - message : ' . $update->message
));
}
$participationId = $participation->id;
$stickerFileName = $participationId . '-sticker.' . $sticker->extension();
$sticker->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $stickerFileName);
$stickerPath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $stickerFileName;
$ticketFileName = $participationId . '-ticket.' . $ticket->extension();
$ticket->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $ticketFileName);
$ticketPath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $ticketFileName;
$barcodeFileName = $participationId . '-code-barre.' . $barcode->extension();
$barcode->move(public_path('fichiers/preuve-de-gain/' . $participationId . '/'), $barcodeFileName);
$barcodePath = public_path() . '/fichiers/preuve-de-gain/' . $participationId . '/' . $barcodeFileName;
$participation->sticker = $stickerFileName;
$participation->ticket = $ticketFileName;
$participation->barcode = $barcodeFileName;
$participation->save();
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
$mails = json_decode($settings->notification_emails);
foreach ($mails as $mail) {
Mail::to($mail->email)->send(new WinningProof(
$stickerPath,
$ticketPath,
$barcodePath,
$participation,
$user,
$settings
));
}
return view('front.basic.replay');
}
}

View file

@ -15,7 +15,7 @@ class re7Controller extends Controller
public function teaser()
{
$settings = app(Settings::class)
->select('start_date', 'end_date', 'activated_teaser', 'teaser_end_activity')->first();
->select('start_date', 'end_date', 'activated_teaser')->first();
return view('front.basic.teaser', compact('settings'));
}
@ -50,7 +50,7 @@ class re7Controller extends Controller
private function getRandomCoupon($settings)
{
$webCoupons = json_decode($settings->web_coupons);
$webCoupons = $settings->web_coupons;
if (count($webCoupons) > 1) {
$lots = [];
foreach ($webCoupons as $webCoupon) {

View file

@ -58,12 +58,13 @@ class Kernel extends HttpKernel
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'game-date' => \App\Http\Middleware\GameCheckDate::class,
'is-admin' => \App\Http\Middleware\isAdmin::class,
'is-super-admin' => \App\Http\Middleware\isSuperAdmin::class,
'is-admin' => \App\Http\Middleware\IsAdmin::class,
'is-super-admin' => \App\Http\Middleware\IsSuperAdmin::class,
're7' => \App\Http\Middleware\re7Middleware::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'crmInfosMustBeComplete' => \App\Http\Middleware\MustCompleteCrmInfo::class
];
}

View file

@ -9,7 +9,7 @@ class Authenticate extends Middleware
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Http\Request $request
* @return string|null
*/
protected function redirectTo($request)

View file

@ -6,13 +6,11 @@ use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
class CheckForMaintenanceMode extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array
*/
protected $except = [
//
];
];
}

View file

@ -6,13 +6,11 @@ use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
//
];
];
}

View file

@ -10,8 +10,8 @@ class GameCheckDate
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param mixed $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
@ -19,17 +19,17 @@ class GameCheckDate
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
// Check si le teaser est actif
// * Check si le teaser est actif.
if ($settings->start_date > now()) {
if ($settings->activated_teaser === 1 && $settings->teaser_end_activity > now()) {
if ($settings->activated_teaser) {
return redirect()->route('teaser');
}
return redirect($settings->redirect_close);
}
// Check si le jeu est terminé
// * Check si le jeu est terminé.
if ($settings->end_date < now()) {
if ($settings->activated_close_page === 1 && $settings->close_page_active_date > now()) {
if ($settings->activated_close_page && $settings->close_page_active_date > now()) {
return redirect()->route('end');
}
return redirect($settings->redirect_close);

View file

@ -0,0 +1,25 @@
<?php
namespace App\Http\Middleware;
use Closure;
class IsAdmin
{
/**
* Handle an incoming request.
*
* @param mixed $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
/** @var \App\Models\User|\App\Models\Customer|null $user */
$user = auth('web')->user() ?? auth('customer')->user();
if ($user and $user->isLocal()) {
return $next($request);
}
abort(404);
}
}

View file

@ -3,21 +3,21 @@
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class isSuperAdmin
class IsSuperAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param mixed $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$role = Auth::user()->role;
if ($role === 1) {
/** @var \App\Models\User|\App\Models\Customer|null $user */
$user = auth('web')->user() ?? auth('customer')->user();
if ($user and $user->isAdmin()) {
return $next($request);
}
return redirect()->route('bo.dashboard');

View file

@ -0,0 +1,31 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Session;
class MustCompleteCrmInfo
{
/**
* Handle an incoming request.
*
* @param mixed $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
/**
* IF session has need crm completion
* then redirect to completion page
*/
if (
Session::get('needCrmInfoUpdate') and
($request->route() and !\in_array($request->route()->getName(), ['completeInfos', 'completeInfosSubmit']))
) {
return response()->redirectToRoute('completeInfos');
}
return $next($request);
}
}

View file

@ -2,8 +2,8 @@
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
@ -11,15 +11,15 @@ class RedirectIfAuthenticated
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
public function handle(Request $request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
return \redirect()->route('login');
}
return $next($request);

View file

@ -6,7 +6,6 @@ use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*

View file

@ -7,7 +7,6 @@ use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
@ -18,7 +17,7 @@ class TrustProxies extends Middleware
/**
* The headers that should be used to detect proxies.
*
* @var int
* @var integer
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}

View file

@ -6,13 +6,11 @@ use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//
];
];
}

View file

@ -1,25 +0,0 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class isAdmin
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$role = Auth::user()->role;
if ($role === 1 || $role === 2) {
return $next($request);
}
abort(404, "Cette page n'existe pas.");
}
}

View file

@ -9,8 +9,8 @@ class re7Middleware
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)

View file

@ -1,6 +1,6 @@
<?php
namespace App\Http\Requests;
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
@ -14,8 +14,9 @@ class CodeSearchRequest extends FormRequest
public function authorize()
{
// ? Is auth and super admin ?
return auth()->check() and
auth()->user()->role === 1;
/** @var \App\Models\User $user */
$user = auth('web')->user();
return auth('web')->check() and $user->isAdmin();
}
/**

View file

@ -1,6 +1,6 @@
<?php
namespace App\Http\Requests;
namespace App\Http\Requests\Bo;
use App\Models\Code;
use Illuminate\Foundation\Http\FormRequest;
@ -26,8 +26,9 @@ class ExportCodesRequest extends FormRequest
'available_export' => $codesAvailableToExport->count()
]);
// ? Is auth and super admin, also is json ?
return auth()->check() and
auth()->user()->role === 1 and $this->json();
/** @var \App\Models\User $user */
$user = auth('web')->user();
return auth('web')->check() and $user->isAdmin() and $this->json();
}
/**

View file

@ -1,6 +1,6 @@
<?php
namespace App\Http\Requests;
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
@ -14,7 +14,9 @@ class GenerateCodesRequest extends FormRequest
public function authorize()
{
// ? Is auth and super admin
return auth()->check() and auth()->user()->role === 1;
/** @var \App\Models\User $user */
$user = auth('web')->user();
return auth('web')->check() and $user->isAdmin();
}
/**

View file

@ -1,6 +1,6 @@
<?php
namespace App\Http\Requests;
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
@ -14,7 +14,7 @@ class StoreProductRequest extends FormRequest
*/
public function authorize()
{
return auth()->check();
return auth('web')->check();
}
/**

View file

@ -1,6 +1,6 @@
<?php
namespace App\Http\Requests;
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
@ -14,7 +14,7 @@ class StoreRangeRequest extends FormRequest
*/
public function authorize()
{
return auth()->check();
return auth('web')->check();
}
/**

View file

@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
class UpdateContentRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return auth('web')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'value' => 'required|min:5'
];
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace App\Http\Requests;
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
@ -14,7 +14,7 @@ class UpdateProductRequest extends FormRequest
*/
public function authorize()
{
return auth()->check();
return auth('web')->check();
}
/**
@ -31,8 +31,8 @@ class UpdateProductRequest extends FormRequest
'mimes:jpeg,png,jpg',
'max:2048',
Rule::dimensions()
->maxWidth(config('theme.product_image_maxwidth'))
->maxHeight(config('theme.product_image_maxheight'))
->maxWidth(config('theme.product_image_maxwidth'))
->maxHeight(config('theme.product_image_maxheight'))
],
'range_id' => 'exists:ranges,id'
];

View file

@ -1,6 +1,6 @@
<?php
namespace App\Http\Requests;
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
@ -14,7 +14,7 @@ class UpdateRangeRequest extends FormRequest
*/
public function authorize()
{
return auth()->check();
return auth('web')->check();
}
/**

View file

@ -0,0 +1,103 @@
<?php
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
class UpdateSettingsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
$this->merge([
'use_ean_codes' => $this->use_ean_codes ? true : false,
'activated_teaser' => $this->activated_teaser ? true : false,
'activated_close_page' => $this->activated_close_page ? true : false,
'winning_proof' => $this->winning_proof ? true : false,
'reductions_activated' => $this->reductions_activated ? true : false,
'facebook_activated' => $this->facebook_activated ? true : false,
'notification_emails' => collect(\json_decode($this->notification_emails, true))->pluck('email')->toArray(),
'web_coupons' => collect(\json_decode($this->web_coupons, true))->toArray(),
]);
/** @var \App\Models\User $user */
$user = auth('web')->user();
return auth('web')->check() and $user->isAdmin();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|min:5|max:255',
'nb_participation_player' => 'required|numeric|min:0|max:500',
'nb_participation_ip' => 'required|numeric|min:0|max:500',
'nb_unique_code_use' => 'required|numeric|min:0|max:500',
'use_ean_codes' => 'required|boolean',
'activated_teaser' => 'required|boolean',
'activated_close_page' => 'required|boolean',
'redirect_close' => 'required|url',
'winning_proof' => 'required|boolean',
'reductions_activated' => 'required|boolean',
'facebook_activated' => 'required|boolean',
'company' => 'required|string|min:2|max:255',
'facebook_app_id' => 'nullable|string|max:255',
'facebook_secret' => 'nullable|string|max:255',
'analytics' => 'nullable|string|regex:/(^UA\-[0-9]{8}\-[0-9]$)/u|max:255',
'reductions_site' => 'required_if:reductions_activated,1|string|min:1|max:255',
'reductions_campaign' => 'required_if:reductions_activated,1|string|min:1|max:255',
'web_coupons' => 'nullable|array',
'web_coupons.*' => 'required|array',
'web_coupons.*.web_coupon_identifiant' => 'required|numeric|min:2|max:50',
'web_coupons.*.percentage' => 'required|numeric',
'web_coupons.*.face_value' => 'required|numeric',
'web_coupons.*.valid_on' => 'required|string|min:2|max:150',
'web_coupons.*.img_name' => 'required|string|min:2|max:150',
'notification_emails' => 'nullable|array',
'notification_emails.*' => 'required|email:rfc,filter,dns',
'start_date' => 'required|date|before:end_date',
'end_date' => 'required|date|after:start_date',
'close_page_active_date' => 'required_if:activated_close_page,true|date|after:end_date',
];
}
/**
* Get custom attributes for validator errors.
*
* @return array
*/
public function attributes()
{
return [
'name' => trans('Nom'),
'nb_participation_player' => trans('Nombre de participation par joueur'),
'nb_participation_ip' => trans('Nombre de participation par adresse IP'),
'nb_unique_code_use' => trans('Nombre d\'utilisation du code unique'),
'use_ean_codes' => trans('Activer les codes EAN'),
'activated_teaser' => trans('Activation du teaser'),
'activated_close_page' => trans('Activation page de fermeture'),
'close_page_active_date' => trans('Page active jusqu\'au'),
'redirect_close' => trans('URL de redirection après la date de fin du jeu'),
'winning_proof' => trans('Activer les preuves de gain'),
'company' => trans('Nom de la société'),
'reductions_activated' => trans('Activer les bons de réduction'),
'reductions_site' => trans('Référence du site'),
'reductions_campaign' => trans('Référence de la campagne'),
'facebook_activated' => trans('Activer Facebook connect'),
'facebook_app_id' => trans('Facebook app_id'),
'facebook_secret' => trans('Facebook app_secret'),
'web_coupons' => trans('Les réductions'),
'analytics' => trans('Clé analytics'),
'start_date' => trans('Date de début'),
'end_date' => trans('Date de fin'),
'notification_emails' => trans('Destinataires des notifications de gain'),
];
}
}

View file

@ -0,0 +1,35 @@
<?php
namespace App\Http\Requests\Bo;
use Illuminate\Foundation\Http\FormRequest;
class UpdateWinInfosRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
$this->merge([
'done' => $this->done ? true : false,
'comment' => $this->comment ?? ''
]);
return $this->ajax() and auth('web')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'done' => 'required|boolean',
'comment' => 'required|string|max:255'
];
}
}

View file

@ -0,0 +1,37 @@
<?php
namespace App\Http\Requests\Fo;
use App\Lib\ToolboxHelper;
use Illuminate\Foundation\Http\FormRequest;
class AuthenticateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
$this->merge([
'remember' => $this->remember ? true : false
]);
return ToolboxHelper::isLoginAccessAllowed();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|email:rfc,dns,spoof,filter',
'password' => 'required',
'remember' => 'required|boolean'
];
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace App\Http\Requests\Fo;
class CompleteInfosRequest extends RegisterRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
$this->merge([
'opt_in' => $this->opt_in ? true : false,
'agree' => $this->agree ? true : false
]);
return auth('customer')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return \array_intersect_key(parent::rules(), [
'firstname' => '',
'lastname' => '',
'birth_date' => '',
'address' => '',
'postcode' => '',
'country' => '',
'city' => '',
'phone' => '',
'opt_in' => ''
]);
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace App\Http\Requests\Fo;
use Illuminate\Foundation\Http\FormRequest;
class ForgotPasswordRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return auth('customer')->guest();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|email:rfc,filter|max:255'
];
}
}

View file

@ -1,6 +1,6 @@
<?php
namespace App\Http\Requests;
namespace App\Http\Requests\Fo;
use App\Models\Code;
use App\Models\CodeEan;
@ -51,7 +51,7 @@ class ParticipateRequest extends FormRequest
]);
}
return auth()->check();
return auth('customer')->check();
}
/**
@ -61,7 +61,9 @@ class ParticipateRequest extends FormRequest
*/
public function rules()
{
$rules = [
/** @var \App\Models\Customer $customer */
$customer = auth('customer')->user();
$rules = [
'accept_rules' => [
'required', 'boolean',
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
@ -74,7 +76,7 @@ class ParticipateRequest extends FormRequest
'code' => [
'required',
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
function ($attribute, $value, $fail) {
function ($attribute, $value, $fail) use ($customer) {
if (
$value === false or
!\is_object($value) or
@ -82,36 +84,45 @@ class ParticipateRequest extends FormRequest
) {
$fail('Code incorrect, veuillez réessayer.');
return false;
} elseif ($value->code_used === 1) {
$fail('Ce code n\'est plus utilisable.');
}
/** @var \App\Models\Code $code */
$code = $value;
// * Check si l'utilisateur n'a pas déjà utilisé ce code.
$query = Participation::whereHas('customer', function ($q) use ($customer) {
$q->whereId($customer->id);
})->whereHas('code', function ($q) use ($code) {
$q->whereId($code->id);
});
if ($query->exists()) {
$fail('Vous avez déjà utilisé ce code.');
return false;
}
// * Check si l'utilisateur n'a pas déjà utilisé ce code.
$query = Participation::where([
['code_unique_id', $this->code->id],
['user_id', auth()->user()->id]
]);
if ($query->exists()) {
$fail('Vous avez déjà utilisé ce code.');
if ($code->code_used) {
$fail('Ce code n\'est plus utilisable.');
return false;
}
/** @var \App\Models\Settings $settings */
$settings = app(Settings::class);
$codeNbUsage = Participation::where('code_unique_id', $this->code->id)
->count();
$codeNbUsage = Participation::whereHas('code', function ($q) use ($code) {
$q->whereId($code->id);
})->count();
// * Gestion du nombre d'utilisation d'un code.
if ($codeNbUsage >= $settings->nb_unique_code_use) {
$this->code->code_used = 1;
return back()->withErrors("Ce code n'est plus utilisable.");
$code->code_used = true;
$code->saveOrFail();
} else {
if ($codeNbUsage + 1 >= $settings->nb_unique_code_use) {
$this->code->code_used = 1;
$code->code_used = true;
$code->saveOrFail();
}
}
$this->code->save();
}
]
];

View file

@ -0,0 +1,78 @@
<?php
namespace App\Http\Requests\Fo;
use ArondeParon\RequestSanitizer\Sanitizers\FilterVars;
use ArondeParon\RequestSanitizer\Sanitizers\Trim;
use ArondeParon\RequestSanitizer\Traits\SanitizesInputs;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Password;
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
use LDC\LDCCRM\Enums\Country;
class RegisterRequest extends FormRequest
{
use SanitizesInputs;
/**
* Using these sanitizers before proceeding the request
* @var array
*/
protected $sanitizers = [
'email' => Trim::class,
'firstname' => [Trim::class, FilterVars::class => ['filter' => FILTER_SANITIZE_STRING]],
'lastname' => [Trim::class, FilterVars::class => ['filter' => FILTER_SANITIZE_STRING]],
'address' => [Trim::class, FilterVars::class => ['filter' => FILTER_SANITIZE_STRING]],
'address2' => [Trim::class, FilterVars::class => ['filter' => FILTER_SANITIZE_STRING]],
'phone' => [Trim::class, FilterVars::class => ['filter' => FILTER_SANITIZE_STRING]],
'city' => [Trim::class, FilterVars::class => ['filter' => FILTER_SANITIZE_STRING]],
];
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
$this->merge([
'opt_in' => $this->opt_in ? true : false,
'agree' => $this->agree ? true : false
]);
return auth('customer')->guest();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|email:rfc,dns,spoof,filter|max:255|unique:customers,email',
'firstname' => 'required|string|min:1|max:255',
'lastname' => 'required|string|max:255',
'birth_date' => 'required|string|date_format:Y-m-d',
'address' => 'required|string|min:2|max:255',
'address2' => 'sometimes|string|max:255',
'phone' => 'sometimes|string|max:255',
'city' => 'required|string|min:2|max:255',
'country' => [
'required', new EnumIsValidRule(Country::class)
],
'postcode' => 'required|numeric|digits_between:4,5',
'password' => [
'required', 'confirmed', 'min:8', 'max:255',
Password::min(8)
->mixedCase()
->letters()
->numbers()
->symbols()
->uncompromised()
],
'opt_in' => 'required|boolean',
'agree' => 'required|boolean'
];
}
}

View file

@ -0,0 +1,38 @@
<?php
namespace App\Http\Requests\Fo;
class SubmitWinningProofRequest extends RegisterRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
return auth('customer')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return \array_merge(\array_intersect_key(parent::rules(), [
'firstname' => '',
'lastname' => '',
'address' => '',
'postcode' => '',
'country' => '',
'city' => '',
'phone' => '',
]), [
'sticker' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
'ticket' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
'barcode' => 'required|mimes:jpeg,png,jpg,pdf|max:2048',
]);
}
}

View file

@ -0,0 +1,40 @@
<?php
namespace App\Http\Requests\Fo;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rules\Password;
class UpdatePasswordRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
// * Autorisation vérifiée dans le controlleur.
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'password' => [
'required', 'confirmed', 'min:8', 'max:255',
Password::min(8)
->mixedCase()
->letters()
->numbers()
->symbols()
->uncompromised()
]
];
}
}

View file

@ -0,0 +1,34 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class SaveBannedIpListRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return boolean
*/
public function authorize()
{
$this->merge([
'ips' => \is_array($this->ips) ? $this->ips : []
]);
return auth('web')->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'ips' => 'required|array',
'ips.*' => 'required|ip'
];
}
}

View file

@ -0,0 +1,28 @@
<?php
namespace App\Http\Resources;
use App\Models\InstantWin;
use Illuminate\Http\Resources\Json\ResourceCollection;
class InstantWinResource extends ResourceCollection
{
/**
* Transform the resource into an array.
*
* @param mixed $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
* @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass
*/
public function toArray($request)
{
return $this->collection->map(function (InstantWin $instantWin) {
return [
'id' => $instantWin->id,
'won' => $instantWin->won,
'appear_date' => $instantWin->appear_date->format('Y-m-d H:i'),
'prize' => $instantWin->prize
];
});
}
}

34
app/Lib/ToolboxHelper.php Normal file
View file

@ -0,0 +1,34 @@
<?php
namespace App\Lib;
use Illuminate\Routing\Route as RoutingRoute;
use Illuminate\Support\Facades\Route;
abstract class ToolboxHelper
{
/**
* * Needed rules as backend and frontend shares the same login functions
* Determine if login is allowed only if:
* Intended url was a BO route (and not already logged in as web guard),
* else customer is not already logged in.
*
* ! The only way to log in as admin is to access a bo route first.
*
* @return boolean
*/
public static function isLoginAccessAllowed(): bool
{
$isBo = false;
$path = \parse_url(\session()->get('url.intended', url('/')), \PHP_URL_PATH);
collect(Route::getRoutes()->getRoutes())
->map(function (RoutingRoute $route) use (&$isBo, $path) {
if (trim($path, '/') === $route->uri() and trim($route->getPrefix(), '/') === 'bo') {
$isBo = true;
}
});
return $isBo ? auth('web')->guest() : auth('customer')->guest();
}
}

View file

@ -1,45 +0,0 @@
<?php
namespace App\Mail;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class CourrierArcadiaError extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
/**
* User
*
* @var \App\Models\User
*/
private $user;
/**
* Create a new message instance.
*
* @param \App\Models\User $user
* @return void
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$user = $this->user;
return $this->subject("Erreur envoi courrier arcadia")
->view('front.basic.error-arcadia-email', compact('user'));
}
}

View file

@ -12,14 +12,15 @@ class NotifAdmin extends Mailable implements ShouldQueue
use Queueable;
use SerializesModels;
/** @var string */
private $msg;
/**
* Create a new message instance.
*
* @return void
* @param string $msg
*/
public function __construct($msg)
public function __construct(string $msg)
{
$this->msg = $msg;
}
@ -32,6 +33,7 @@ class NotifAdmin extends Mailable implements ShouldQueue
public function build()
{
$msg = $this->msg;
return $this->subject(config('app.name') . " : Erreur")->view('front.basic.notif-admin', compact('msg'));
return $this->subject(config('app.name') . ': Erreur')
->view('front.basic.notif-admin', compact('msg'));
}
}

View file

@ -2,25 +2,38 @@
namespace App\Mail;
use App\Models\Participation;
use App\Models\Settings;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
class NotifWinAdmin extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
private $settings, $participation;
/** @var Settings */
private $settings;
/** @var Settings */
private $participation;
/** @var CrmCustomer */
private $crmCustomer;
/**
* Create a new message instance.
*
* @return void
* @param CrmCustomer $crmCustomer
* @param Settings $settings
* @param Participation $participation
*/
public function __construct($settings, $participation)
public function __construct(CrmCustomer $crmCustomer, Settings $settings, Participation $participation)
{
$this->crmCustomer = $crmCustomer;
$this->settings = $settings;
$this->participation = $participation;
}
@ -32,8 +45,16 @@ class NotifWinAdmin extends Mailable implements ShouldQueue
*/
public function build()
{
$participation = $this->participation;
return $this->subject($this->settings->name . " : un lot a été gagné")
->view('front.basic.notif-win-admin-email', compact('participation'));
$subject = '';
if (!collect($this->to)->count()) {
$this->to(config('mail.MAIL_ADMIN'));
$subject = '!!! AUCUNE Valeur configurée dans settings email list. !!!';
}
$subject .= $this->settings->name . ' : un lot a été gagné';
return $this->subject($subject)
->view('front.basic.notif-win-admin-email', [
'crmCustomer' => $this->crmCustomer,
'participation' => $this->participation
]);
}
}

View file

@ -2,6 +2,8 @@
namespace App\Mail;
use App\Models\Customer;
use App\Models\Settings;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
@ -12,16 +14,29 @@ class PasswordReset extends Mailable implements ShouldQueue
use Queueable;
use SerializesModels;
protected $user, $settings;
/**
* Customer
*
* @var Customer
*/
protected $customer;
/**
* Settings
*
* @var Settings
*/
protected $settings;
/**
* Create a new message instance.
*
* @return void
* @param Customer $customer
* @param Settings $settings
*/
public function __construct($user, $settings)
public function __construct(Customer $customer, Settings $settings)
{
$this->user = $user;
$this->customer = $customer;
$this->settings = $settings;
}
@ -32,6 +47,8 @@ class PasswordReset extends Mailable implements ShouldQueue
*/
public function build()
{
return $this->subject('Changement de votre mot de passe')->view('front.basic.password-email')->with(['user' => $this->user, 'settings' => $this->settings]);
return $this->subject('Changement de votre mot de passe')
->view('front.basic.password-email')
->with(['customer' => $this->customer, 'settings' => $this->settings]);
}
}

View file

@ -2,28 +2,40 @@
namespace App\Mail;
use App\Models\Prize;
use App\Models\Settings;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
class PrizeWon extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
private $user, $prize, $settings;
/** @var CrmCustomer */
private $crmCustomer;
/** @var \App\Models\Prize */
private $prize;
/** @var \App\Models\Settings */
private $settings;
/**
* Create a new message instance.
*
* @return void
* @param CrmCustomer $crmCustomer
* @param Prize $prize
* @param Settings $settings
*/
public function __construct($user, $prize, $settings)
public function __construct(CrmCustomer $crmCustomer, Prize $prize, Settings $settings)
{
$this->user = $user;
$this->prize = $prize;
$this->settings = $settings;
$this->crmCustomer = $crmCustomer;
$this->prize = $prize;
$this->settings = $settings;
}
/**
@ -33,7 +45,13 @@ class PrizeWon extends Mailable implements ShouldQueue
*/
public function build()
{
return $this->subject("Félicitations " . $this->user->firstname . ", vous avez remporté 1 " . $this->prize->label_one . " !")->view('front.basic.prize-mail')
->with(['user' => $this->user, 'prize' => $this->prize, 'settings' => $this->settings]);
return $this->subject("Félicitations " . $this->crmCustomer->firstname .
", vous avez remporté 1 " . $this->prize->label_one . " !")
->view('front.basic.prize-mail')
->with([
'crmCustomer' => $this->crmCustomer,
'prize' => $this->prize,
'settings' => $this->settings
]);
}
}

View file

@ -2,29 +2,45 @@
namespace App\Mail;
use App\Models\Reduction;
use App\Models\Settings;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
class ReductionWon extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
private $user, $coupon, $settings, $crmCoupon;
/** @var CrmCustomer */
private $crmCustomer;
/** @var integer */
private $faceValue;
/** @var Settings */
private $settings;
/** @var Reduction */
private $reduction;
/**
* Create a new message instance.
*
* @return void
* @param CrmCustomer $crmCustomer
* @param integer $faceValue
* @param Settings $settings
* @param Reduction $reduction
*/
public function __construct($user, $coupon, $settings, $crmCoupon)
public function __construct(CrmCustomer $crmCustomer, int $faceValue, Settings $settings, Reduction $reduction)
{
$this->user = $user;
$this->coupon = $coupon;
$this->settings = $settings;
$this->crmCoupon = $crmCoupon;
$this->crmCustomer = $crmCustomer;
$this->faceValue = $faceValue;
$this->settings = $settings;
$this->reduction = $reduction;
}
/**
@ -34,7 +50,13 @@ class ReductionWon extends Mailable implements ShouldQueue
*/
public function build()
{
return $this->subject($this->user->firstname . ", n'attendez plus pour imprimer votre bon d'achat " . $this->settings->name . " !")->view('front.basic.reduction-mail')
->with(['user' => $this->user, 'coupon' => $this->coupon, 'settings' => $this->settings, 'crmCoupon' => $this->crmCoupon]);
return $this->subject($this->customer->firstname . ", n'attendez plus pour imprimer votre bon d'achat " .
$this->settings->name . " !")->view('front.basic.reduction-mail')
->with([
'crmCustomer' => $this->crmCustomer,
'faceValue' => $this->faceValue,
'settings' => $this->settings,
'link' => $this->reduction->link
]);
}
}

View file

@ -6,22 +6,29 @@ use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use LDC\LDCCRM\Models\Customer;
class VerifyEmail extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
protected $user;
/** @var \LDC\LDCCRM\Models\Customer $customer */
protected $customer;
/** @var string $emailCheckToken */
protected $emailCheckToken;
/**
* Create a new message instance.
*
* @return void
* @param Customer $customer
* @param string $emailCheckToken
*/
public function __construct($user)
public function __construct(Customer $customer, string $emailCheckToken)
{
$this->user = $user;
$this->customer = $customer;
$this->emailCheckToken = $emailCheckToken;
}
/**
@ -31,6 +38,9 @@ class VerifyEmail extends Mailable implements ShouldQueue
*/
public function build()
{
return $this->subject("Activation du compte")->view('front.basic.verifyemail')->with('user', $this->user);
return $this->subject("Activation du compte")
->view('front.basic.verifyemail')
->with('customer', $this->customer)
->with('emailCheckToken', $this->emailCheckToken);
}
}

View file

@ -1,48 +0,0 @@
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class WinningProof extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
private $sticker, $ticket, $barcode, $participation, $user, $settings;
/**
* Create a new message instance.
*
* @return void
*/
public function __construct($sticker, $ticket, $barcode, $participation, $user, $settings)
{
$this->sticker = $sticker;
$this->ticket = $ticket;
$this->barcode = $barcode;
$this->participation = $participation;
$this->user = $user;
$this->settings = $settings;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$participation = $this->participation;
$user = $this->user;
return $this->subject(
$this->settings->name . " : Preuves de gain de " . $this->user->lastname . " " . $this->user->firstname
)->view(
'front.basic.winning-proof-email',
compact('participation', 'user')
)->attach($this->sticker)->attach($this->ticket)->attach($this->barcode);
}
}

View file

@ -0,0 +1,96 @@
<?php
namespace App\Mail;
use App\Models\Participation;
use App\Models\Settings;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
class WinningProofMail extends Mailable implements ShouldQueue
{
use Queueable;
use SerializesModels;
/** @var string */
private $stickerPath;
/** @var string */
private $ticketPath;
/** @var string */
private $barcodePath;
/**
* Participation
*
* @var Participation
*/
private $participation;
/**
* Customer
*
* @var CrmCustomer
*/
private $crmCustomer;
/**
* Settings
*
* @var Settings
*/
private $settings;
/**
* WinningProofMail
*
* @param string $stickerPath
* @param string $ticketPath
* @param string $barcodePath
* @param Participation $participation
* @param CrmCustomer $crmCustomer
* @param Settings $settings
*/
public function __construct(
string $stickerPath,
string $ticketPath,
string $barcodePath,
Participation $participation,
CrmCustomer $crmCustomer,
Settings $settings
) {
$this->stickerPath = $stickerPath;
$this->ticketPath = $ticketPath;
$this->barcodePath = $barcodePath;
$this->participation = $participation;
$this->crmCustomer = $crmCustomer;
$this->settings = $settings;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$participation = $this->participation;
$customer = $this->customer;
$subject = '';
if (!collect($this->to)->count()) {
$this->to(config('mail.MAIL_ADMIN'));
$subject = '!!! AUCUNE Valeur configurée dans settings email list. !!!';
}
$subject .= $this->settings->name . ' : Preuves de gain de ' .
$customer->lastname . ' ' . $customer->firstname;
return $this->subject($subject)->view(
'front.basic.winning-proof-email',
compact('participation', 'customer')
)->attach($this->stickerPath)->attach($this->ticketPath)
->attach($this->barcodePath);
}
}

View file

@ -20,6 +20,13 @@ class CodeEan extends Model
*/
public $timestamps = false;
// * RELATIONSHIPS
/**
* Has Many Participation relationship
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function participations()
{
return $this->hasMany(Participation::class);

View file

@ -6,4 +6,12 @@ use Illuminate\Database\Eloquent\Model;
class Content extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
public $fillable = [
'value'
];
}

121
app/Models/Customer.php Normal file
View file

@ -0,0 +1,121 @@
<?php
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use LDC\LDCCRM\Exceptions\CrmException;
use LDC\LDCCRM\Models\Customer as CrmCustomer;
class Customer extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'hashcode',
'email',
'email_verify_token'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'remember_token',
];
// * RELATIONSHIPS
/**
* Has Many Participation relation
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function participations()
{
return $this->hasMany(Participation::class, 'customer_id');
}
// * METHODS
/**
* Check if user is admin.
* ! Not local CRM !
*
* @return boolean
*/
public function isAdmin(): bool
{
return false;
}
/**
* Check if user is local.
* ! Not local CRM !
*
* @return boolean
*/
public function isLocal(): bool
{
return false;
}
/**
* Get the crm Data of a customer
*
* @return \LDC\LDCCRM\Models\Customer
* @throws \LDC\LDCCRM\Exceptions\CrmException If an error occurs on server side or on getting response.
* @throws \LDC\LDCCRM\Exceptions\ApiErrorException If any error or \LDC\LDCCRM\Enums\ApiError occurs.
* Possibles are : - modelNotFound, If this customer hashcode could not be found.
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
* @phpcs:ignore Squiz.Commenting.FunctionCommentThrowTag.WrongNumber
*/
public function getApiDataAttribute(): CrmCustomer
{
/** @var \LDC\LDCCRM\CrmApiV2 */
$crm = app('crmAPI');
$crmCustomer = $crm->getCustomer($this->hashcode);
if (!$crmCustomer) {
throw new CrmException('CRM get Customer returned null');
}
return $crmCustomer;
}
/**
* This mutate Customer attributes to array
* including only non critical properties and crm values
* (One that can be send to front office without security breach)
*
* @return array
*/
public function toArray()
{
if ($this->hashcode) {
return collect(array_merge(
parent::toArray(),
(array)$this->apiData
))->intersectByKeys([
'email' => '',
'firstname' => '',
'lastname' => '',
'address' => '',
'address2' => '',
'postcode' => '',
'birth_date' => '',
'city' => '',
'country' => '',
'opt_in' => '',
'phone' => ''
])->toArray();
} else {
return parent::toArray();
}
}
}

View file

@ -16,18 +16,36 @@ class FaqQuestion extends Model
'negative_vote', 'theme_id'
];
// * RELATIONSHIPS
/**
* Belongs To FaqTheme relationship
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function theme()
{
return $this->belongsTo(FaqTheme::class, 'theme_id');
}
public function getUtilityAttribute()
/**
* Get utility attribute
*
* @return float
*/
public function getUtilityAttribute(): float
{
/** @var float */
$pourcent = 0;
if ($this->positive_vote !== null && $this->negative_vote !== null && $this->positive_vote >= $this->negative_vote && $this->positive_vote > 0 && $this->negative_vote > 0) {
$ratio = $this->negative_vote / $this->positive_vote;
$pourcent = ceil((1 - $ratio) * 100);
if (
$this->positive_vote !== null &&
$this->negative_vote !== null &&
$this->positive_vote >= $this->negative_vote &&
$this->positive_vote > 0 && $this->negative_vote > 0
) {
$ratio = \floatval($this->negative_vote / $this->positive_vote);
$pourcent = \floatval(ceil((1 - $ratio) * 100));
}
return $pourcent;

View file

@ -20,6 +20,13 @@ class FaqTheme extends Model
*/
protected $with = ['questions'];
// * RELATIONSHIPS
/**
* Has many FaqQuestion relationship
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function questions()
{
return $this->hasMany(FaqQuestion::class, 'theme_id');

View file

@ -13,6 +13,13 @@ class GainView extends Model
*/
protected $fillable = ['name', 'file_name'];
// * RELATIONSHIPS
/**
* Has many Prize relationship
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function prizes()
{
return $this->hasMany(Prize::class, 'gain_view_id');

View file

@ -26,9 +26,12 @@ class InstantWin extends Model
* @var array
*/
protected $casts = [
'won' => 'bool'
'appear_date' => 'datetime',
'done' => 'bool'
];
// * RELATIONSHIPS
/**
* BelongsTo Prize relation
*
@ -48,4 +51,16 @@ class InstantWin extends Model
{
return $this->belongsTo(Participation::class);
}
// * Methods
/**
* Get won attribute
*
* @return boolean
*/
public function getWonAttribute(): bool
{
return $this->participation()->exists();
}
}

View file

@ -6,14 +6,16 @@ use Illuminate\Database\Eloquent\Model;
class Participation extends Model
{
// * RELATIONSHIPS
/**
* BelongsTo User relation
* BelongsTo Customer relation
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
public function customer()
{
return $this->belongsTo(User::class);
return $this->belongsTo(Customer::class);
}
/**

View file

@ -14,5 +14,27 @@ class Settings extends Model
protected $casts = [
'start_date' => 'datetime',
'end_date' => 'datetime',
'activated_teaser' => 'bool',
'use_ean_codes' => 'bool',
'activated_close_page' => 'bool',
'notification_emails' => 'array',
'web_coupons' => 'array',
'close_page_active_date' => 'datetime'
];
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'start_date', 'nb_participation_player',
'nb_participation_ip', 'nb_unique_code_use',
'use_ean_codes', 'activated_teaser', 'activated_close_page',
'redirect_close', 'winning_proof', 'reductions_activated',
'facebook_activated', 'company', 'facebook_app_id', 'facebook_secret',
'analytics', 'reductions_site', 'reductions_campaign',
'notification_emails', 'start_date', 'end_date', 'close_page_active_date',
'web_coupons'
];
}

View file

@ -2,12 +2,15 @@
namespace App\Models;
use App\Enums\UserRole;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Kwaadpepper\Enum\Traits\CastsEnums;
class User extends Authenticatable
{
use Notifiable;
use CastsEnums;
/**
* The attributes that are mass assignable.
@ -15,18 +18,9 @@ class User extends Authenticatable
* @var array
*/
protected $fillable = [
'crm_id',
'civility',
'firstname',
'lastname',
'birth_date',
'name',
'email',
'password',
'address',
'address2',
'town',
'postal_code',
'country',
'email_verify_token',
'email_verified'
];
@ -50,12 +44,32 @@ class User extends Authenticatable
];
/**
* Has Many Participation relation
* Map attribute names to enum classes.
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
* @var array
*/
public function participations()
protected $enumCasts = [
'role' => UserRole::class
];
/**
* Check if user is admin.
*
* @return boolean
*/
public function isAdmin(): bool
{
return $this->hasMany(Participation::class, 'user_id');
return $this->role->equals(UserRole::admin());
}
/**
* Check if user is local.
* ! IS local no CRM !
*
* @return boolean
*/
public function isLocal(): bool
{
return true;
}
}

View file

@ -11,7 +11,10 @@ use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\View;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\ServiceProvider;
use Illuminate\Validation\ValidationException;
use LDC\LDCCRM\Enums\Country;
class AppServiceProvider extends ServiceProvider
{
@ -19,6 +22,7 @@ class AppServiceProvider extends ServiceProvider
* Bootstrap any application services.
*
* @return void
* @throws \ErrorException If MAIL_ADMIN is not set in .env .
*/
public function boot()
{
@ -56,7 +60,36 @@ class AppServiceProvider extends ServiceProvider
return $settings;
});
// * AvailableCountries
View::share('availableCountries', [
Country::france(),
Country::belgium(),
Country::luxembourg(),
Country::guadeloupe(),
Country::martinique(),
Country::frenchGuiana(),
Country::reunion(),
Country::saintPierreAndMiquelon(),
Country::mayotte(),
Country::saintBarthelemy(),
Country::saintMartinFrenchPart(),
Country::wallisAndFutuna(),
Country::frenchPolynesia(),
Country::newCaledonia()
]);
if (!app()->runningInConsole()) {
// ! MAIL_ADMIN est obligatoire dans le .env
try {
Validator::validate(['mail' => config('mail.MAIL_ADMIN')], [
'mail' => 'required|email:rfc,strict,spoof'
]);
} catch (ValidationException $e) {
throw new \ErrorException(
'La valeur mail doit contenir une adresse email valide dans la configuration.'
);
}
// On ramène le nom du jeu et le nom de la société sur toute les pages.
$settingsGlobal = Cache::get('settingsGlobal');
if (!$settingsGlobal) {
@ -68,16 +101,15 @@ class AppServiceProvider extends ServiceProvider
View::share('settingsGlobal', $settingsGlobal);
// On ramène aussi tout les prix car on en a besoin sur le header.
$prizesGlobal = Cache::get('prizesGlobal');
if (!$prizesGlobal) {
$prizesGlobal = Prize::all();
Cache::put('prizesGlobal', $prizesGlobal);
}
View::share('prizesGlobal', $prizesGlobal);
View::share('prizesGlobal', Cache::remember('prizesGlobal', 60, function () {
return Prize::all();
}));
Blade::if('superadmin', function () {
return auth()->user() && auth()->user()->role == 1;
/** @var \App\Models\User|null $user */
$user = auth('web')->user();
return $user and $user->isAdmin();
});
}//end if
}

View file

@ -0,0 +1,26 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\App;
use Illuminate\Support\ServiceProvider;
use LDC\LDCCRM\CrmApiV2;
class CrmApiServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
App::singleton('crmAPI', function () {
return new CrmApiV2(
config('crm.endpoint'),
config('crm.token'),
config('crm.password')
);
});
}
}

View file

@ -1,162 +0,0 @@
<?php
namespace LDCCRM;
class ApiV1
{
private $endpoint;
private $api_key;
public function __construct($endpoint, $api_key)
{
$this->endpoint = $endpoint;
$this->api_key = $api_key;
}
public function getCustomer($id){
return $this->callAPI('GET', "/customer/id/$id");
}
public function getCustomerByEmail($email){
return $this->callAPI('GET', "/customer/email/$email");
}
public function createCustomer($email, $password, $firstname, $lastname, $optin, $birthdate = null, $phone = null, $address = null, $address2 = null, $city = null, $postcode = null, $country = null){
$user = [
'email' => $email,
'password' => $password,
'firstname' => $firstname,
'lastname' => $lastname,
'opt_in' => $optin,
'birth_date' => $birthdate,
'phone' => $phone,
'address' => $address,
'address2' => $address2,
'city' => $city,
'postcode' => $postcode,
'country' => $country
];
return $this->callAPI('POST', '/customer/create', $user);
}
public function updateCustomer($crmId, $firstname = null, $lastname = null, $optin = null, $birthdate = null, $phone = null, $address = null, $address2 = null, $city = null, $postcode = null, $country = null){
$user = [];
if ($firstname !== null)
$user['firstname'] = $firstname;
if ($lastname !== null)
$user['lastname'] = $lastname;
if ($optin !== null)
$user['opt_in'] = $optin;
if ($birthdate !== null)
$user['birth_date'] = $birthdate;
if ($phone !== null)
$user['phone'] = $phone;
if ($address !== null)
$user['address'] = $address;
if ($address2 !== null)
$user['address2'] = $address2;
if ($city !== null)
$user['city'] = $city;
if ($postcode !== null)
$user['postcode'] = $postcode;
if ($country !== null)
$user['country'] = $country;
return $this->callAPI('PUT', "/customer/$crmId", $user);
}
public function deleteCustomer($id){
return $this->callAPI('DELETE', "/customer/$id");
}
public function changePwdCustomer($id, $password){
return $this->callAPI('POST', "/customer/$id/change-password", ['password' => $password]);
}
public function activateCustomer($id){
return $this->callAPI('POST', "/customer/$id/activate");
}
public function toggleOptInCustomer($id){
return $this->callAPI('POST', "/customer/$id/toggle-optin");
}
public function loginCustomer($email, $password){
return $this->callAPI('POST', "/customer/login", ['email' => $email, 'password' => $password]);
}
public function createSingleOptin($email){
return $this->callAPI('POST', '/single-optin', ['email' => $email]);
}
public function ArcadiaOutgoingMail($crm_id, $fields, $type){
return $this->callAPI('POST', '/arcadia/outgoing-mail', ['crm_id' => $crm_id, 'fields' => json_encode($fields), 'type' => $type]);
}
private function callAPI($method, $url, $data = false){
if (strpos($this->endpoint, "dev")){
if ($data !== false){
$data = array_merge($data, ['api_token' => $this->api_key]);
}else{
$data = ['api_token' => $this->api_key];
}
}
$url = $this->endpoint . '/api/v1' . $url;
$curl = curl_init();
switch ($method){
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
break;
case "DELETE":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_COOKIESESSION, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
if (!strpos($this->endpoint, "dev")) {
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Accept: application/json',
'Authorization: Bearer ' . $this->api_key
));
}
$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, 'message' => 'Connection to API failed - Code HTTP : '. $http_code];
} else {
return (object) ['status' => 'KO', 'code' => 500, 'message' => 'Connection to API failed : '. curl_error($curl)];
}
curl_close($curl);
return json_decode($result);
}
}

View file

@ -11,14 +11,17 @@
"php": "^7.3",
"ext-curl": "*",
"ext-json": "*",
"arondeparon/laravel-request-sanitizer": "^5.0",
"fideloper/proxy": "^4.2",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"kwaadpepper/enum": "^2.1",
"kwaadpepper/exception-handler": "^0.0.6",
"kwaadpepper/serial-int-caster": "^1.0",
"laravel/framework": "^8.0",
"laravel/tinker": "^2.0",
"laravel/ui": "^3.0"
"laravel/ui": "^3.0",
"ldc/ldccrmv2client": "^3.0"
},
"require-dev": {
"doctrine/dbal": "^2.0",
@ -33,8 +36,18 @@
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
}
},
"repositories": [
{
"name": "ldc/ldccrmv2client",
"type": "vcs",
"url": "https://voight001.lesidc.com/crm-client"
}
],
"extra": {
"laravel": {
"dont-discover": []

1102
composer.lock generated

File diff suppressed because it is too large Load diff

View file

@ -3,53 +3,53 @@
return [
/*
|--------------------------------------------------------------------------
| Application Name
|--------------------------------------------------------------------------
|
| This value is the name of your application. This value is used when the
| framework needs to place the application's name in a notification or
| any other location as required by the application or its packages.
|
|--------------------------------------------------------------------------
| Application Name
|--------------------------------------------------------------------------
|
| This value is the name of your application. This value is used when the
| framework needs to place the application's name in a notification or
| any other location as required by the application or its packages.
|
*/
'name' => env('APP_NAME', 'Laravel'),
/*
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services the application utilizes. Set this in your ".env" file.
|
|--------------------------------------------------------------------------
| Application Environment
|--------------------------------------------------------------------------
|
| This value determines the "environment" your application is currently
| running in. This may determine how you prefer to configure various
| services the application utilizes. Set this in your ".env" file.
|
*/
'env' => env('APP_ENV', 'production'),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => (bool)env('APP_DEBUG', false),
/*
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
|--------------------------------------------------------------------------
| Application URL
|--------------------------------------------------------------------------
|
| This URL is used by the console to properly generate URLs when using
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
'url' => env('APP_URL', 'http://localhost'),
@ -57,66 +57,66 @@ return [
'asset_url' => env('ASSET_URL', null),
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'Europe/Paris',
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'fr',
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
'fallback_locale' => 'fr',
/*
|--------------------------------------------------------------------------
| Faker Locale
|--------------------------------------------------------------------------
|
| This locale will be used by the Faker PHP library when generating fake
| data for your database seeds. For example, this will be used to get
| localized telephone numbers, street address information and more.
|
|--------------------------------------------------------------------------
| Faker Locale
|--------------------------------------------------------------------------
|
| This locale will be used by the Faker PHP library when generating fake
| data for your database seeds. For example, this will be used to get
| localized telephone numbers, street address information and more.
|
*/
'faker_locale' => 'en_US',
/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
'key' => env('APP_KEY'),
@ -124,14 +124,14 @@ return [
'cipher' => 'AES-256-CBC',
/*
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [
@ -174,18 +174,19 @@ return [
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Providers\CrmApiServiceProvider::class,
],
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
@ -227,6 +228,8 @@ return [
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
// * Custom class load
'Country' => LDC\LDCCRM\Enums\Country::class
],
];

View file

@ -3,14 +3,14 @@
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
@ -19,20 +19,20 @@ return [
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
@ -41,28 +41,27 @@ return [
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'customer' => [
'driver' => 'session',
'provider' => 'customers',
]
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
@ -70,26 +69,31 @@ return [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'customers' => [
'driver' => 'eloquent',
'model' => App\Models\Customer::class,
]
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'provider' => 'customers',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
@ -97,14 +101,14 @@ return [
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,

View file

@ -3,29 +3,29 @@
return [
/*
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
|
|--------------------------------------------------------------------------
| Default Broadcaster
|--------------------------------------------------------------------------
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
| Supported: "pusher", "redis", "log", "null"
|
*/
'default' => env('BROADCAST_DRIVER', 'null'),
/*
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
|--------------------------------------------------------------------------
| Broadcast Connections
|--------------------------------------------------------------------------
|
| Here you may define all of the broadcast connections that will be used
| to broadcast events to other systems or over websockets. Samples of
| each available type of connection are provided inside this array.
|
*/
'connections' => [

View file

@ -5,30 +5,30 @@ use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Default Cache Store
|--------------------------------------------------------------------------
|
| This option controls the default cache connection that gets used while
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file",
| "memcached", "redis", "dynamodb"
|
|--------------------------------------------------------------------------
| Default Cache Store
|--------------------------------------------------------------------------
|
| This option controls the default cache connection that gets used while
| using this caching library. This connection is used when another is
| not explicitly specified when executing a given caching function.
|
| Supported: "apc", "array", "database", "file",
| "memcached", "redis", "dynamodb"
|
*/
'default' => env('CACHE_DRIVER', 'file'),
/*
|--------------------------------------------------------------------------
| Cache Stores
|--------------------------------------------------------------------------
|
| Here you may define all of the cache "stores" for your application as
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
|--------------------------------------------------------------------------
| Cache Stores
|--------------------------------------------------------------------------
|
| Here you may define all of the cache "stores" for your application as
| well as their drivers. You may even define multiple stores for the
| same cache driver to group types of items stored in your caches.
|
*/
'stores' => [
@ -89,14 +89,14 @@ return [
],
/*
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
|--------------------------------------------------------------------------
| Cache Key Prefix
|--------------------------------------------------------------------------
|
| When utilizing a RAM based store such as APC or Memcached, there might
| be other applications utilizing the same cache. So, we'll specify a
| value to get prefixed to all our keys so we can avoid collisions.
|
*/
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_cache'),

Some files were not shown because too many files have changed in this diff Show more