419 lines
15 KiB
PHP
Executable File
419 lines
15 KiB
PHP
Executable File
<?php
|
|
|
|
namespace Modules\AffiliatesAdmin\Controllers;
|
|
|
|
use App\Controllers\BaseAdminController;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Modules\AffiliatesAdmin\Models\Affiliate;
|
|
use Modules\AffiliatesAdmin\Models\AffiliateCommission;
|
|
use Modules\AffiliatesAdmin\Models\AffiliateBanner;
|
|
use Modules\AffiliatesAdmin\Models\AffiliateClick;
|
|
use Modules\Auth\Models\User;
|
|
|
|
class AffiliatesAdminController extends BaseAdminController
|
|
{
|
|
/**
|
|
* Check if user has permission.
|
|
*
|
|
* @param string $permission
|
|
* @return void
|
|
*/
|
|
protected function checkPermission(string $permission)
|
|
{
|
|
$user = $this->getCurrentUser();
|
|
if (!$user || !$user->hasPermission($permission)) {
|
|
$this->addFlash('error', 'Você não tem permissão para acessar esta área.');
|
|
$this->redirect('admin/dashboard')->send();
|
|
exit;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Display a listing of the affiliates.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
public function index(Request $request): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.view');
|
|
$affiliates = Affiliate::all();
|
|
return $this->renderAdminView('@affiliatesadmin/index.twig', ['affiliates' => $affiliates]);
|
|
}
|
|
|
|
/**
|
|
* Show the form for creating a new affiliate.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
public function create(Request $request): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage');
|
|
return $this->renderAdminView('@affiliatesadmin/form.twig');
|
|
}
|
|
|
|
/**
|
|
* Store a newly created affiliate in storage.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
public function store(Request $request): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage');
|
|
$data = $request->request->all();
|
|
|
|
if (empty($data['affiliates_name']) || empty($data['affiliates_email'])) {
|
|
$this->addFlash('error', __('affiliatesadmin.validation_name_email_required'));
|
|
return $this->redirect('/admin/affiliatesadmin/create');
|
|
}
|
|
|
|
if (!filter_var($data['affiliates_email'], FILTER_VALIDATE_EMAIL)) {
|
|
$this->addFlash('error', __('affiliatesadmin.validation_invalid_email'));
|
|
return $this->redirect('/admin/affiliatesadmin/create');
|
|
}
|
|
|
|
if (Affiliate::where('affiliates_email', $data['affiliates_email'])->exists()) {
|
|
$this->addFlash('error', __('affiliatesadmin.validation_email_exists'));
|
|
return $this->redirect('/admin/affiliatesadmin/create');
|
|
}
|
|
|
|
// Check if user already exists in the system
|
|
$existingUser = User::where('users_email', $data['affiliates_email'])->first();
|
|
|
|
if (!$existingUser && empty($data['password'])) {
|
|
$this->addFlash('error', 'A senha é obrigatória para criar um novo usuário no sistema.');
|
|
return $this->redirect('/admin/affiliatesadmin/create');
|
|
}
|
|
|
|
// Create the Affiliate record
|
|
Affiliate::create($data);
|
|
|
|
if ($existingUser) {
|
|
// Only change role if user is a standard 'user'
|
|
// Prevent downgrading admins or super_admins
|
|
if (in_array($existingUser->users_role, ['user', ''])) {
|
|
$existingUser->users_role = 'member';
|
|
$existingUser->save();
|
|
$this->addFlash('success', __('affiliatesadmin.affiliate_created_successfully') . ' O usuário existente foi promovido para "member".');
|
|
} else {
|
|
$this->addFlash('success', __('affiliatesadmin.affiliate_created_successfully') . ' O usuário existente manteve seu nível de acesso privilegiado: ' . $existingUser->users_role);
|
|
}
|
|
} else {
|
|
// Create a new System User
|
|
$user = new User();
|
|
$user->users_name = $data['affiliates_name'];
|
|
$user->users_email = $data['affiliates_email'];
|
|
$user->users_password = password_hash($data['password'], PASSWORD_DEFAULT);
|
|
$user->users_role = 'member';
|
|
$user->users_status = 'active';
|
|
$user->save();
|
|
$this->addFlash('success', __('affiliatesadmin.affiliate_created_successfully') . ' Um novo usuário com nível "member" foi criado.');
|
|
}
|
|
|
|
return $this->redirect('/admin/affiliatesadmin');
|
|
}
|
|
|
|
/**
|
|
* Display the specified affiliate.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function show(Request $request, int $id): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.view');
|
|
$affiliate = Affiliate::findOrFail($id);
|
|
return $this->renderAdminView('@affiliatesadmin/show.twig', ['affiliate' => $affiliate]);
|
|
}
|
|
|
|
/**
|
|
* Show the form for editing the specified affiliate.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function edit(Request $request, int $id): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage');
|
|
$affiliate = Affiliate::findOrFail($id);
|
|
return $this->renderAdminView('@affiliatesadmin/form.twig', ['affiliate' => $affiliate]);
|
|
}
|
|
|
|
/**
|
|
* Update the specified affiliate in storage.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function update(Request $request, int $id): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage');
|
|
$affiliate = Affiliate::findOrFail($id);
|
|
$data = $request->request->all();
|
|
|
|
if (empty($data['affiliates_name']) || empty($data['affiliates_email'])) {
|
|
$this->addFlash('error', __('affiliatesadmin.validation_name_email_required'));
|
|
return $this->redirect('/admin/affiliatesadmin/' . $id . '/edit');
|
|
}
|
|
|
|
if (!filter_var($data['affiliates_email'], FILTER_VALIDATE_EMAIL)) {
|
|
$this->addFlash('error', __('affiliatesadmin.validation_invalid_email'));
|
|
return $this->redirect('/admin/affiliatesadmin/' . $id . '/edit');
|
|
}
|
|
|
|
if (Affiliate::where('affiliates_email', $data['affiliates_email'])->where('affiliates_id', '!=', $id)->exists()) {
|
|
$this->addFlash('error', __('affiliatesadmin.validation_email_exists'));
|
|
return $this->redirect('/admin/affiliatesadmin/' . $id . '/edit');
|
|
}
|
|
|
|
$affiliate->update($data);
|
|
$this->addFlash('success', __('affiliatesadmin.affiliate_updated_successfully'));
|
|
return $this->redirect('/admin/affiliatesadmin');
|
|
}
|
|
|
|
/**
|
|
* Remove the specified affiliate from storage.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function destroy(Request $request, int $id): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage');
|
|
Affiliate::destroy($id);
|
|
$this->addFlash('success', __('affiliatesadmin.affiliate_deleted_successfully'));
|
|
return $this->redirect('/admin/affiliatesadmin');
|
|
}
|
|
|
|
/**
|
|
* Display a listing of commissions.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
public function commissions(Request $request): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.view_commissions');
|
|
$commissions = AffiliateCommission::all();
|
|
return $this->renderAdminView('@affiliatesadmin/commissions.twig', ['commissions' => $commissions]);
|
|
}
|
|
|
|
/**
|
|
* Approve a commission.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function approveCommission(Request $request, int $id): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage_commissions');
|
|
$commission = AffiliateCommission::findOrFail($id);
|
|
$commission->affiliate_commissions_status = 'approved';
|
|
$commission->save();
|
|
$this->addFlash('success', __('affiliatesadmin.commission_approved_successfully'));
|
|
return $this->redirect('/admin/affiliatesadmin/commissions');
|
|
}
|
|
|
|
/**
|
|
* Reject a commission.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function rejectCommission(Request $request, int $id): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage_commissions');
|
|
$commission = AffiliateCommission::findOrFail($id);
|
|
$commission->affiliate_commissions_status = 'rejected';
|
|
$commission->save();
|
|
$this->addFlash('success', __('affiliatesadmin.commission_rejected_successfully'));
|
|
return $this->redirect('/admin/affiliatesadmin/commissions');
|
|
}
|
|
|
|
/**
|
|
* Display a listing of banners.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
public function banners(Request $request): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.view_banners');
|
|
$banners = AffiliateBanner::all();
|
|
return $this->renderAdminView('@affiliatesadmin/banners.twig', ['banners' => $banners]);
|
|
}
|
|
|
|
/**
|
|
* Show the form for creating a new banner.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
public function createBanner(Request $request): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage_banners');
|
|
return $this->renderAdminView('@affiliatesadmin/banner-form.twig');
|
|
}
|
|
|
|
/**
|
|
* Store a newly created banner in storage.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
public function storeBanner(Request $request): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.manage_banners');
|
|
$data = $request->request->all();
|
|
|
|
if (empty($data['affiliate_banners_name']) || empty($data['affiliate_banners_target_url'])) {
|
|
$this->addFlash('error', __('affiliatesadmin.validation_banner_fields_required'));
|
|
return $this->redirect('/admin/affiliatesadmin/banners/create');
|
|
}
|
|
|
|
if ($request->files->has('banner_file')) {
|
|
$file = $request->files->get('banner_file');
|
|
if ($file && $file->isValid()) {
|
|
$data['affiliate_banners_image_url'] = $this->handleBannerUpload($file);
|
|
}
|
|
}
|
|
|
|
if (empty($data['affiliate_banners_image_url'])) {
|
|
$this->addFlash('error', 'O arquivo de imagem do banner é obrigatório.');
|
|
return $this->redirect('/admin/affiliatesadmin/banners/create');
|
|
}
|
|
|
|
AffiliateBanner::create($data);
|
|
$this->addFlash('success', __('affiliatesadmin.banner_created_successfully'));
|
|
return $this->redirect('/admin/affiliatesadmin/banners');
|
|
}
|
|
|
|
/**
|
|
* Show the form for editing the specified banner.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function editBanner(Request $request, int $id): Response
|
|
{
|
|
$banner = AffiliateBanner::findOrFail($id);
|
|
return $this->renderAdminView('@affiliatesadmin/banner-form.twig', ['banner' => $banner]);
|
|
}
|
|
|
|
/**
|
|
* Update the specified banner in storage.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function updateBanner(Request $request, int $id): Response
|
|
{
|
|
$banner = AffiliateBanner::findOrFail($id);
|
|
$data = $request->request->all();
|
|
|
|
if (empty($data['affiliate_banners_name']) || empty($data['affiliate_banners_target_url'])) {
|
|
$this->addFlash('error', __('affiliatesadmin.validation_banner_fields_required'));
|
|
return $this->redirect('/admin/affiliatesadmin/banners/' . $id . '/edit');
|
|
}
|
|
|
|
if ($request->files->has('banner_file')) {
|
|
$file = $request->files->get('banner_file');
|
|
if ($file && $file->isValid()) {
|
|
// Delete old file if exists
|
|
if ($banner->affiliate_banners_image_url) {
|
|
$oldPath = dirname(__DIR__, 4) . '/storage/uploads/affiliatesadmin/' . $banner->affiliate_banners_image_url;
|
|
if (file_exists($oldPath) && is_file($oldPath)) {
|
|
unlink($oldPath);
|
|
}
|
|
}
|
|
$data['affiliate_banners_image_url'] = $this->handleBannerUpload($file);
|
|
}
|
|
}
|
|
|
|
$banner->update($data);
|
|
$this->addFlash('success', __('affiliatesadmin.banner_updated_successfully'));
|
|
return $this->redirect('/admin/affiliatesadmin/banners');
|
|
}
|
|
|
|
/**
|
|
* Handle banner image upload.
|
|
*
|
|
* @param \Symfony\Component\HttpFoundation\File\UploadedFile $file
|
|
* @return string|null
|
|
*/
|
|
private function handleBannerUpload($file): ?string
|
|
{
|
|
$uploadDir = dirname(__DIR__, 4) . '/storage/uploads/affiliatesadmin';
|
|
if (!is_dir($uploadDir)) {
|
|
if (!mkdir($uploadDir, 0777, true)) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
$filename = uniqid('banner_') . '.' . $file->guessExtension();
|
|
$file->move($uploadDir, $filename);
|
|
|
|
// Store ONLY the filename in the database
|
|
// The view will prepend /storage/uploads/affiliatesadmin/
|
|
return $filename;
|
|
}
|
|
|
|
/**
|
|
* Remove the specified banner from storage.
|
|
*
|
|
* @param Request $request
|
|
* @param int $id
|
|
* @return Response
|
|
*/
|
|
public function destroyBanner(Request $request, int $id): Response
|
|
{
|
|
$banner = AffiliateBanner::findOrFail($id);
|
|
if ($banner->affiliate_banners_image_url) {
|
|
$path = dirname(__DIR__, 4) . '/storage/uploads/affiliatesadmin/' . $banner->affiliate_banners_image_url;
|
|
if (file_exists($path) && is_file($path)) {
|
|
unlink($path);
|
|
}
|
|
}
|
|
AffiliateBanner::destroy($id);
|
|
$this->addFlash('success', __('affiliatesadmin.banner_deleted_successfully'));
|
|
return $this->redirect('/admin/affiliatesadmin/banners');
|
|
}
|
|
|
|
/**
|
|
* Display affiliate statistics.
|
|
*
|
|
* @param Request $request
|
|
* @return Response
|
|
*/
|
|
public function statistics(Request $request): Response
|
|
{
|
|
$this->checkPermission('affiliatesadmin.view_statistics');
|
|
|
|
$stats = [
|
|
'total_affiliates' => Affiliate::count(),
|
|
'total_commissions_approved' => AffiliateCommission::where('affiliate_commissions_status', 'approved')->sum('affiliate_commissions_amount'),
|
|
'total_clicks' => AffiliateClick::count(),
|
|
'conversion_rate' => 0,
|
|
];
|
|
|
|
if ($stats['total_clicks'] > 0) {
|
|
$approvedCount = AffiliateCommission::where('affiliate_commissions_status', 'approved')->count();
|
|
$stats['conversion_rate'] = round(($approvedCount / $stats['total_clicks']) * 100, 2);
|
|
}
|
|
|
|
return $this->renderAdminView('@affiliatesadmin/statistics.twig', [
|
|
'stats' => $stats
|
|
]);
|
|
}
|
|
} |