Inicialización del módulo base
This commit is contained in:
commit
28c3a81b64
28
composer.json
Normal file
28
composer.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"name": "koneko/laravel-vuexy-admin-module",
|
||||
"description": "Base modular para proyectos Laravel altamente personalizados.",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"laravel/framework": "^10.0|^11.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Koneko\\BaseModule\\": "src/"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Koneko\\BaseModule\\BaseServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "Arturo Corro Pacheco",
|
||||
"email": "arturo@koneko.mx"
|
||||
}
|
||||
]
|
||||
}
|
40
src/modules/App/Actions/Fortify/CreateNewUser.php
Normal file
40
src/modules/App/Actions/Fortify/CreateNewUser.php
Normal file
@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Actions\Fortify;
|
||||
|
||||
use Laravel\Fortify\Contracts\CreatesNewUsers;
|
||||
use Modules\Admin\App\Models\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class CreateNewUser implements CreatesNewUsers
|
||||
{
|
||||
use PasswordValidationRules;
|
||||
|
||||
/**
|
||||
* Validate and create a newly registered user.
|
||||
*
|
||||
* @param array<string, string> $input
|
||||
*/
|
||||
public function create(array $input): User
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => [
|
||||
'required',
|
||||
'string',
|
||||
'email',
|
||||
'max:255',
|
||||
Rule::unique(User::class),
|
||||
],
|
||||
'password' => $this->passwordRules(),
|
||||
])->validate();
|
||||
|
||||
return User::create([
|
||||
'name' => $input['name'],
|
||||
'email' => $input['email'],
|
||||
'password' => Hash::make($input['password']),
|
||||
]);
|
||||
}
|
||||
}
|
18
src/modules/App/Actions/Fortify/PasswordValidationRules.php
Normal file
18
src/modules/App/Actions/Fortify/PasswordValidationRules.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Actions\Fortify;
|
||||
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
|
||||
trait PasswordValidationRules
|
||||
{
|
||||
/**
|
||||
* Get the validation rules used to validate passwords.
|
||||
*
|
||||
* @return array<int, \Illuminate\Contracts\Validation\Rule|array<mixed>|string>
|
||||
*/
|
||||
protected function passwordRules(): array
|
||||
{
|
||||
return ['required', 'string', Password::default(), 'confirmed'];
|
||||
}
|
||||
}
|
29
src/modules/App/Actions/Fortify/ResetUserPassword.php
Normal file
29
src/modules/App/Actions/Fortify/ResetUserPassword.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Actions\Fortify;
|
||||
|
||||
use Laravel\Fortify\Contracts\ResetsUserPasswords;
|
||||
use Modules\Admin\App\Models\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ResetUserPassword implements ResetsUserPasswords
|
||||
{
|
||||
use PasswordValidationRules;
|
||||
|
||||
/**
|
||||
* Validate and reset the user's forgotten password.
|
||||
*
|
||||
* @param array<string, string> $input
|
||||
*/
|
||||
public function reset(User $user, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'password' => $this->passwordRules(),
|
||||
])->validate();
|
||||
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($input['password']),
|
||||
])->save();
|
||||
}
|
||||
}
|
32
src/modules/App/Actions/Fortify/UpdateUserPassword.php
Normal file
32
src/modules/App/Actions/Fortify/UpdateUserPassword.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Actions\Fortify;
|
||||
|
||||
use Laravel\Fortify\Contracts\UpdatesUserPasswords;
|
||||
use Modules\Admin\App\Models\User;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class UpdateUserPassword implements UpdatesUserPasswords
|
||||
{
|
||||
use PasswordValidationRules;
|
||||
|
||||
/**
|
||||
* Validate and update the user's password.
|
||||
*
|
||||
* @param array<string, string> $input
|
||||
*/
|
||||
public function update(User $user, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'current_password' => ['required', 'string', 'current_password:web'],
|
||||
'password' => $this->passwordRules(),
|
||||
], [
|
||||
'current_password.current_password' => __('The provided password does not match your current password.'),
|
||||
])->validateWithBag('updatePassword');
|
||||
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($input['password']),
|
||||
])->save();
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Actions\Fortify;
|
||||
|
||||
use Laravel\Fortify\Contracts\UpdatesUserProfileInformation;
|
||||
use Modules\Admin\App\Models\User;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class UpdateUserProfileInformation implements UpdatesUserProfileInformation
|
||||
{
|
||||
/**
|
||||
* Validate and update the given user's profile information.
|
||||
*
|
||||
* @param array<string, string> $input
|
||||
*/
|
||||
public function update(User $user, array $input): void
|
||||
{
|
||||
Validator::make($input, [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
|
||||
'email' => [
|
||||
'required',
|
||||
'string',
|
||||
'email',
|
||||
'max:255',
|
||||
Rule::unique('users')->ignore($user->id),
|
||||
],
|
||||
])->validateWithBag('updateProfileInformation');
|
||||
|
||||
if (
|
||||
$input['email'] !== $user->email &&
|
||||
$user instanceof MustVerifyEmail
|
||||
) {
|
||||
$this->updateVerifiedUser($user, $input);
|
||||
} else {
|
||||
$user->forceFill([
|
||||
'name' => $input['name'],
|
||||
'email' => $input['email'],
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the given verified user's profile information.
|
||||
*
|
||||
* @param array<string, string> $input
|
||||
*/
|
||||
protected function updateVerifiedUser(User $user, array $input): void
|
||||
{
|
||||
$user->forceFill([
|
||||
'name' => $input['name'],
|
||||
'email' => $input['email'],
|
||||
'email_verified_at' => null,
|
||||
])->save();
|
||||
|
||||
$user->sendEmailVerificationNotification();
|
||||
}
|
||||
}
|
43
src/modules/App/Console/Commands/CleanInitialAvatars.php
Normal file
43
src/modules/App/Console/Commands/CleanInitialAvatars.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class CleanInitialAvatars extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'avatars:clean-initial';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Elimina avatares generados automáticamente en el directorio initial-avatars';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$directory = 'initial-avatars';
|
||||
$files = Storage::disk('public')->files($directory);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$lastModified = Storage::disk('public')->lastModified($file);
|
||||
|
||||
// Elimina archivos no accedidos en los últimos 30 días
|
||||
if (now()->timestamp - $lastModified > 30 * 24 * 60 * 60) {
|
||||
Storage::disk('public')->delete($file);
|
||||
}
|
||||
}
|
||||
|
||||
$this->info('Avatares iniciales antiguos eliminados.');
|
||||
}
|
||||
}
|
209
src/modules/App/Helpers/Helpers.php
Normal file
209
src/modules/App/Helpers/Helpers.php
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Helpers;
|
||||
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Helpers
|
||||
{
|
||||
public static function appClasses()
|
||||
{
|
||||
$data = config('custom.custom');
|
||||
|
||||
// default data array
|
||||
$DefaultData = [
|
||||
'myLayout' => 'vertical',
|
||||
'myTheme' => 'theme-default',
|
||||
'myStyle' => 'light',
|
||||
'myRTLSupport' => false,
|
||||
'myRTLMode' => true,
|
||||
'hasCustomizer' => true,
|
||||
'showDropdownOnHover' => true,
|
||||
'displayCustomizer' => true,
|
||||
'contentLayout' => 'compact',
|
||||
'headerType' => 'fixed',
|
||||
'navbarType' => 'fixed',
|
||||
'menuFixed' => true,
|
||||
'menuCollapsed' => false,
|
||||
'footerFixed' => false,
|
||||
'customizerControls' => [
|
||||
'rtl',
|
||||
'style',
|
||||
'headerType',
|
||||
'contentLayout',
|
||||
'layoutCollapsed',
|
||||
'showDropdownOnHover',
|
||||
'layoutNavbarOptions',
|
||||
'themes',
|
||||
],
|
||||
// 'defaultLanguage'=>'en',
|
||||
];
|
||||
|
||||
// if any key missing of array from custom.php file it will be merge and set a default value from dataDefault array and store in data variable
|
||||
$data = array_merge($DefaultData, $data);
|
||||
|
||||
// All options available in the template
|
||||
$allOptions = [
|
||||
'myLayout' => ['vertical', 'horizontal', 'blank', 'front'],
|
||||
'menuCollapsed' => [true, false],
|
||||
'hasCustomizer' => [true, false],
|
||||
'showDropdownOnHover' => [true, false],
|
||||
'displayCustomizer' => [true, false],
|
||||
'contentLayout' => ['compact', 'wide'],
|
||||
'headerType' => ['fixed', 'static'],
|
||||
'navbarType' => ['fixed', 'static', 'hidden'],
|
||||
'myStyle' => ['light', 'dark', 'system'],
|
||||
'myTheme' => ['theme-default', 'theme-bordered', 'theme-semi-dark'],
|
||||
'myRTLSupport' => [true, false],
|
||||
'myRTLMode' => [true, false],
|
||||
'menuFixed' => [true, false],
|
||||
'footerFixed' => [true, false],
|
||||
'customizerControls' => [],
|
||||
// 'defaultLanguage'=>array('en'=>'en','fr'=>'fr','de'=>'de','ar'=>'ar'),
|
||||
];
|
||||
|
||||
//if myLayout value empty or not match with default options in custom.php config file then set a default value
|
||||
foreach ($allOptions as $key => $value) {
|
||||
if (array_key_exists($key, $DefaultData)) {
|
||||
if (gettype($DefaultData[$key]) === gettype($data[$key])) {
|
||||
// data key should be string
|
||||
if (is_string($data[$key])) {
|
||||
// data key should not be empty
|
||||
if (isset($data[$key]) && $data[$key] !== null) {
|
||||
// data key should not be exist inside allOptions array's sub array
|
||||
if (!array_key_exists($data[$key], $value)) {
|
||||
// ensure that passed value should be match with any of allOptions array value
|
||||
$result = array_search($data[$key], $value, 'strict');
|
||||
if (empty($result) && $result !== 0) {
|
||||
$data[$key] = $DefaultData[$key];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if data key not set or
|
||||
$data[$key] = $DefaultData[$key];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$data[$key] = $DefaultData[$key];
|
||||
}
|
||||
}
|
||||
}
|
||||
$styleVal = $data['myStyle'] == "dark" ? "dark" : "light";
|
||||
$styleUpdatedVal = $data['myStyle'] == "dark" ? "dark" : $data['myStyle'];
|
||||
// Determine if the layout is admin or front based on cookies
|
||||
$layoutName = $data['myLayout'];
|
||||
$isAdmin = Str::contains($layoutName, 'front') ? false : true;
|
||||
|
||||
$modeCookieName = $isAdmin ? 'admin-mode' : 'front-mode';
|
||||
$colorPrefCookieName = $isAdmin ? 'admin-colorPref' : 'front-colorPref';
|
||||
|
||||
// Determine style based on cookies, only if not 'blank-layout'
|
||||
if ($layoutName !== 'blank') {
|
||||
if (isset($_COOKIE[$modeCookieName])) {
|
||||
$styleVal = $_COOKIE[$modeCookieName];
|
||||
if ($styleVal === 'system') {
|
||||
$styleVal = isset($_COOKIE[$colorPrefCookieName]) ? $_COOKIE[$colorPrefCookieName] : 'light';
|
||||
}
|
||||
$styleUpdatedVal = $_COOKIE[$modeCookieName];
|
||||
}
|
||||
}
|
||||
|
||||
isset($_COOKIE['theme']) ? $themeVal = $_COOKIE['theme'] : $themeVal = $data['myTheme'];
|
||||
|
||||
$directionVal = isset($_COOKIE['direction']) ? ($_COOKIE['direction'] === "true" ? 'rtl' : 'ltr') : $data['myRTLMode'];
|
||||
|
||||
//layout classes
|
||||
$layoutClasses = [
|
||||
'layout' => $data['myLayout'],
|
||||
'theme' => $themeVal,
|
||||
'themeOpt' => $data['myTheme'],
|
||||
'style' => $styleVal,
|
||||
'styleOpt' => $data['myStyle'],
|
||||
'styleOptVal' => $styleUpdatedVal,
|
||||
'rtlSupport' => $data['myRTLSupport'],
|
||||
'rtlMode' => $data['myRTLMode'],
|
||||
'textDirection' => $directionVal, //$data['myRTLMode'],
|
||||
'menuCollapsed' => $data['menuCollapsed'],
|
||||
'hasCustomizer' => $data['hasCustomizer'],
|
||||
'showDropdownOnHover' => $data['showDropdownOnHover'],
|
||||
'displayCustomizer' => $data['displayCustomizer'],
|
||||
'contentLayout' => $data['contentLayout'],
|
||||
'headerType' => $data['headerType'],
|
||||
'navbarType' => $data['navbarType'],
|
||||
'menuFixed' => $data['menuFixed'],
|
||||
'footerFixed' => $data['footerFixed'],
|
||||
'customizerControls' => $data['customizerControls'],
|
||||
];
|
||||
|
||||
// sidebar Collapsed
|
||||
if ($layoutClasses['menuCollapsed'] == true) {
|
||||
$layoutClasses['menuCollapsed'] = 'layout-menu-collapsed';
|
||||
}
|
||||
|
||||
// Header Type
|
||||
if ($layoutClasses['headerType'] == 'fixed') {
|
||||
$layoutClasses['headerType'] = 'layout-menu-fixed';
|
||||
}
|
||||
// Navbar Type
|
||||
if ($layoutClasses['navbarType'] == 'fixed') {
|
||||
$layoutClasses['navbarType'] = 'layout-navbar-fixed';
|
||||
} elseif ($layoutClasses['navbarType'] == 'static') {
|
||||
$layoutClasses['navbarType'] = '';
|
||||
} else {
|
||||
$layoutClasses['navbarType'] = 'layout-navbar-hidden';
|
||||
}
|
||||
|
||||
// Menu Fixed
|
||||
if ($layoutClasses['menuFixed'] == true) {
|
||||
$layoutClasses['menuFixed'] = 'layout-menu-fixed';
|
||||
}
|
||||
|
||||
// Footer Fixed
|
||||
if ($layoutClasses['footerFixed'] == true) {
|
||||
$layoutClasses['footerFixed'] = 'layout-footer-fixed';
|
||||
}
|
||||
|
||||
// RTL Supported template
|
||||
if ($layoutClasses['rtlSupport'] == true) {
|
||||
$layoutClasses['rtlSupport'] = '/rtl';
|
||||
}
|
||||
|
||||
// RTL Layout/Mode
|
||||
if ($layoutClasses['rtlMode'] == true) {
|
||||
$layoutClasses['rtlMode'] = 'rtl';
|
||||
$layoutClasses['textDirection'] = isset($_COOKIE['direction']) ? ($_COOKIE['direction'] === "true" ? 'rtl' : 'ltr') : 'rtl';
|
||||
} else {
|
||||
$layoutClasses['rtlMode'] = 'ltr';
|
||||
$layoutClasses['textDirection'] = isset($_COOKIE['direction']) && $_COOKIE['direction'] === "true" ? 'rtl' : 'ltr';
|
||||
}
|
||||
|
||||
// Show DropdownOnHover for Horizontal Menu
|
||||
if ($layoutClasses['showDropdownOnHover'] == true) {
|
||||
$layoutClasses['showDropdownOnHover'] = true;
|
||||
} else {
|
||||
$layoutClasses['showDropdownOnHover'] = false;
|
||||
}
|
||||
|
||||
// To hide/show display customizer UI, not js
|
||||
if ($layoutClasses['displayCustomizer'] == true) {
|
||||
$layoutClasses['displayCustomizer'] = true;
|
||||
} else {
|
||||
$layoutClasses['displayCustomizer'] = false;
|
||||
}
|
||||
|
||||
return $layoutClasses;
|
||||
}
|
||||
|
||||
public static function updatePageConfig($pageConfigs)
|
||||
{
|
||||
$demo = 'custom';
|
||||
if (isset($pageConfigs)) {
|
||||
if (count($pageConfigs) > 0) {
|
||||
foreach ($pageConfigs as $config => $val) {
|
||||
Config::set('custom.' . $demo . '.' . $config, $val);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
62
src/modules/App/Http/Controllers/AdminController.php
Normal file
62
src/modules/App/Http/Controllers/AdminController.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Modules\Admin\App\Models\Setting;
|
||||
use Modules\Admin\App\Services\VuexyAdminService;
|
||||
|
||||
class AdminController extends Controller
|
||||
{
|
||||
public function searchNavbar()
|
||||
{
|
||||
abort_if(!request()->expectsJson(), 403, __('errors.ajax_only'));
|
||||
|
||||
$VuexyAdminService = app(VuexyAdminService::class);
|
||||
|
||||
return response()->json($VuexyAdminService->getVuexySearchData());
|
||||
}
|
||||
|
||||
public function quickLinksUpdate(Request $request)
|
||||
{
|
||||
abort_if(!request()->expectsJson(), 403, __('errors.ajax_only'));
|
||||
|
||||
$validated = $request->validate([
|
||||
'action' => 'required|in:update,remove',
|
||||
'route' => 'required|string',
|
||||
]);
|
||||
|
||||
$quickLinks = Setting::where('user_id', Auth::user()->id)
|
||||
->where('key', 'quicklinks')
|
||||
->first();
|
||||
|
||||
$quickLinks = $quickLinks ? json_decode($quickLinks->value, true) : [];
|
||||
|
||||
if ($validated['action'] === 'update') {
|
||||
// Verificar si ya existe
|
||||
if (!in_array($validated['route'], $quickLinks))
|
||||
$quickLinks[] = $validated['route'];
|
||||
} elseif ($validated['action'] === 'remove') {
|
||||
// Eliminar la ruta si existe
|
||||
$quickLinks = array_filter($quickLinks, function ($route) use ($validated) {
|
||||
return $route !== $validated['route'];
|
||||
});
|
||||
}
|
||||
|
||||
Setting::updateOrCreate(['user_id' => Auth::user()->id, 'key' => 'quicklinks'], ['value' => json_encode($quickLinks)]);
|
||||
|
||||
VuexyAdminService::clearQuickLinksCache();
|
||||
}
|
||||
|
||||
public function generalSettings()
|
||||
{
|
||||
return view('admin::admin-settings.webapp-general-settings');
|
||||
}
|
||||
|
||||
public function smtpSettings()
|
||||
{
|
||||
return view('admin::admin-settings.smtp-settings');
|
||||
}
|
||||
}
|
144
src/modules/App/Http/Controllers/AuthController.php
Normal file
144
src/modules/App/Http/Controllers/AuthController.php
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Fortify\Features;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
/*
|
||||
public function loginView()
|
||||
{
|
||||
dd($viewMode);
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.login-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
public function registerView()
|
||||
{
|
||||
if (!Features::enabled(Features::registration()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.register-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function confirmPasswordView()
|
||||
{
|
||||
if (!Features::enabled(Features::registration()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.confirm-password-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
public function resetPasswordView()
|
||||
{
|
||||
if (!Features::enabled(Features::resetPasswords()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.reset-password-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
public function requestPasswordResetLinkView(Request $request)
|
||||
{
|
||||
if (!Features::enabled(Features::resetPasswords()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.reset-password-{$viewMode}", ['pageConfigs' => $pageConfigs, 'request' => $request]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function twoFactorChallengeView()
|
||||
{
|
||||
if (!Features::enabled(Features::registration()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.two-factor-challenge-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
public function twoFactorRecoveryCodesView()
|
||||
{
|
||||
if (!Features::enabled(Features::registration()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.register-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
public function twoFactorAuthenticationView()
|
||||
{
|
||||
if (!Features::enabled(Features::registration()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.register-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function verifyEmailView()
|
||||
{
|
||||
if (!Features::enabled(Features::registration()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.verify-email-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
public function showEmailVerificationForm()
|
||||
{
|
||||
if (!Features::enabled(Features::registration()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.register-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
|
||||
public function userProfileView()
|
||||
{
|
||||
if (!Features::enabled(Features::registration()))
|
||||
abort(403, 'El registro está deshabilitado.');
|
||||
|
||||
$viewMode = config('custom.custom.authViewMode');
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view("admin::auth.register-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
}
|
||||
*/
|
||||
}
|
41
src/modules/App/Http/Controllers/CacheController.php
Normal file
41
src/modules/App/Http/Controllers/CacheController.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Modules\Admin\App\Services\CacheConfigService;
|
||||
|
||||
class CacheController extends Controller
|
||||
{
|
||||
public function generateConfigCache()
|
||||
{
|
||||
try {
|
||||
// Lógica para generar cache
|
||||
Artisan::call('config:cache');
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Cache generado correctamente.']);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => 'Error al generar el cache.', 'error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function generateRouteCache()
|
||||
{
|
||||
try {
|
||||
// Lógica para generar cache de rutas
|
||||
Artisan::call('route:cache');
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Cache de rutas generado correctamente.']);
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => 'Error al generar el cache de rutas.', 'error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function cacheManager(CacheConfigService $cacheConfigService)
|
||||
{
|
||||
$configCache = $cacheConfigService->getConfig();
|
||||
|
||||
return view('admin::cache-manager.index', compact('configCache'));
|
||||
}
|
||||
}
|
32
src/modules/App/Http/Controllers/HomeController.php
Normal file
32
src/modules/App/Http/Controllers/HomeController.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('admin::pages.home');
|
||||
}
|
||||
|
||||
public function about()
|
||||
{
|
||||
return view('admin::pages.about');
|
||||
}
|
||||
|
||||
public function comingsoon()
|
||||
{
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view('admin::pages.comingsoon', compact('pageConfigs'));
|
||||
}
|
||||
|
||||
public function underMaintenance()
|
||||
{
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
return view('admin::pages.under-maintenance', compact('pageConfigs'));
|
||||
}
|
||||
}
|
37
src/modules/App/Http/Controllers/PermissionController.php
Normal file
37
src/modules/App/Http/Controllers/PermissionController.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Yajra\DataTables\Facades\DataTables;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class PermissionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
if ($request->ajax()) {
|
||||
$permissions = Permission::latest()->get();
|
||||
|
||||
return DataTables::of($permissions)
|
||||
->addIndexColumn()
|
||||
->addColumn('assigned_to', function ($row) {
|
||||
return (Arr::pluck($row->roles, ['name']));
|
||||
})
|
||||
->editColumn('created_at', function ($request) {
|
||||
return $request->created_at->format('Y-m-d h:i:s a');
|
||||
})
|
||||
->make(true);
|
||||
}
|
||||
|
||||
return view('admin::permissions.index');
|
||||
}
|
||||
}
|
38
src/modules/App/Http/Controllers/RoleController.php
Normal file
38
src/modules/App/Http/Controllers/RoleController.php
Normal file
@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class RoleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('admin::roles.index');
|
||||
}
|
||||
|
||||
public function checkUniqueRoleName(Request $request)
|
||||
{
|
||||
$id = $request->input('id');
|
||||
$name = $request->input('name');
|
||||
|
||||
// Verificar si el nombre ya existe en la base de datos
|
||||
$existingRole = Role::where('name', $name)
|
||||
->whereNot('id', $id)
|
||||
->first();
|
||||
|
||||
if ($existingRole) {
|
||||
return response()->json(['valid' => false]);
|
||||
}
|
||||
|
||||
return response()->json(['valid' => true]);
|
||||
}
|
||||
}
|
194
src/modules/App/Http/Controllers/SatCatalogController.php
Normal file
194
src/modules/App/Http/Controllers/SatCatalogController.php
Normal file
@ -0,0 +1,194 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use Modules\Admin\App\Imports\SatCatalogsImport;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class SatCatalogController extends Controller
|
||||
{
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function import(Request $request)
|
||||
{
|
||||
// Si es una solicitud POST, procesa la importación
|
||||
if ($request->isMethod('post')) {
|
||||
$validator = Validator::make($request->all(), [
|
||||
'file' => ['required', 'mimes:xls,xlsx'],
|
||||
]);
|
||||
|
||||
if ($validator->fails())
|
||||
return back()->withInput()->withErrors($validator);
|
||||
|
||||
$time_start = microtime(true);
|
||||
$results = [
|
||||
'details' => [],
|
||||
'total_rows' => 0,
|
||||
'total_created' => 0,
|
||||
'total_updated' => 0,
|
||||
'total_time' => 0,
|
||||
];
|
||||
|
||||
$import = new SatCatalogsImport();
|
||||
$filePath = request()->file('file');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('c_FormaPago');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Forma de pago',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('c_Moneda');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Moneda',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('c_CodigoPostal_Parte_1');
|
||||
Excel::import($import, $filePath);
|
||||
$import->onlySheets('c_CodigoPostal_Parte_2');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Código postal',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('c_RegimenFiscal');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Regimen fiscal',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('c_Pais');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'País',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('c_UsoCFDI');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Uso de CFDI',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('C_Colonia_1');
|
||||
Excel::import($import, $filePath);
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('C_Colonia_2');
|
||||
Excel::import($import, $filePath);
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('C_Colonia_3');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Colonia',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('c_Estado');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Estado',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('C_Localidad');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Localidad',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$time_sheet_start = microtime(true);
|
||||
$import->onlySheets('C_Municipio');
|
||||
Excel::import($import, $filePath);
|
||||
$results['details'][] = [
|
||||
'name' => 'Municipio',
|
||||
'time' => round(microtime(true) - $time_sheet_start, 2),
|
||||
'created' => session('created'),
|
||||
'updated' => session('updated'),
|
||||
];
|
||||
$results['total_rows'] += session('created') + session('updated');
|
||||
$results['total_created'] += session('created');
|
||||
$results['total_updated'] += session('updated');
|
||||
|
||||
|
||||
$results['total_time'] = round(microtime(true) - $time_start, 2);
|
||||
|
||||
return back()->with('results', $results);
|
||||
}
|
||||
|
||||
return view('system::import-sat.index');
|
||||
}
|
||||
}
|
182
src/modules/App/Http/Controllers/UserController.php
Normal file
182
src/modules/App/Http/Controllers/UserController.php
Normal file
@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Yajra\DataTables\Facades\DataTables;
|
||||
use Modules\Admin\App\Models\User;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
if ($request->ajax()) {
|
||||
$users = User::when(!Auth::user()->hasRole('SuperAdmin'), function ($query) {
|
||||
$query->where('id', '>', 1);
|
||||
})
|
||||
->latest()
|
||||
->get();
|
||||
|
||||
return DataTables::of($users)
|
||||
->only(['id', 'name', 'email', 'avatar', 'roles', 'status', 'created_at'])
|
||||
->addIndexColumn()
|
||||
->addColumn('avatar', function ($user) {
|
||||
return $user->profile_photo_url;
|
||||
})
|
||||
->addColumn('roles', function ($user) {
|
||||
return (Arr::pluck($user->roles, ['name']));
|
||||
})
|
||||
/*
|
||||
->addColumn('stores', function ($user) {
|
||||
return (Arr::pluck($user->stores, ['nombre']));
|
||||
})
|
||||
y*/
|
||||
->editColumn('created_at', function ($user) {
|
||||
return $user->created_at->format('Y-m-d');
|
||||
})
|
||||
->make(true);
|
||||
}
|
||||
|
||||
return view('admin::users.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'name' => 'required|max:255',
|
||||
'email' => 'required|max:255|unique:users',
|
||||
'photo' => 'nullable|mimes:jpg,jpeg,png|max:1024',
|
||||
'password' => 'required',
|
||||
]);
|
||||
|
||||
if ($validator->fails())
|
||||
return response()->json(['errors' => $validator->errors()->all()]);
|
||||
|
||||
// Preparamos los datos
|
||||
$user_request = array_merge_recursive($request->all(), [
|
||||
'remember_token' => Str::random(10),
|
||||
'created_by' => Auth::user()->id,
|
||||
]);
|
||||
|
||||
$user_request['password'] = bcrypt($request->password);
|
||||
|
||||
// Guardamos el nuevo usuario
|
||||
$user = User::create($user_request);
|
||||
|
||||
// Asignmos los permisos
|
||||
$user->assignRole($request->roles);
|
||||
|
||||
// Asignamos Tiendas
|
||||
//$user->stores()->attach($request->stores);
|
||||
|
||||
if ($request->file('photo'))
|
||||
$user->updateProfilePhoto($request->file('photo'));
|
||||
|
||||
return response()->json(['success' => 'Se agrego correctamente el usuario']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int User $user
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show(User $user)
|
||||
{
|
||||
return view('admin::users.show', compact('user'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int User $user
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function updateAjax(Request $request, User $user)
|
||||
{
|
||||
// Validamos los datos
|
||||
$validator = Validator::make($request->all(), [
|
||||
'name' => 'required|max:191',
|
||||
'email' => "required|max:191|unique:users,email," . $user->id,
|
||||
'photo' => 'nullable|mimes:jpg,jpeg,png|max:2048'
|
||||
]);
|
||||
|
||||
if ($validator->fails())
|
||||
return response()->json(['errors' => $validator->errors()->all()]);
|
||||
|
||||
// Preparamos los datos
|
||||
$user_request = $request->all();
|
||||
|
||||
if ($request->password) {
|
||||
$user_request['password'] = bcrypt($request->password);
|
||||
} else {
|
||||
unset($user_request['password']);
|
||||
}
|
||||
|
||||
// Guardamos los cambios
|
||||
$user->update($user_request);
|
||||
|
||||
// Sincronizamos Roles
|
||||
$user->syncRoles($request->roles);
|
||||
|
||||
// Sincronizamos Tiendas
|
||||
//$user->stores()->sync($request->stores);
|
||||
|
||||
// Actualizamos foto de perfil
|
||||
if ($request->file('photo'))
|
||||
$user->updateProfilePhoto($request->file('photo'));
|
||||
|
||||
return response()->json(['success' => 'Se guardo correctamente los cambios.']);
|
||||
}
|
||||
|
||||
|
||||
public function userSettings(User $user)
|
||||
{
|
||||
return view('admin::users.user-settings', compact('user'));
|
||||
}
|
||||
|
||||
public function generateAvatar(Request $request)
|
||||
{
|
||||
// Validación de entrada
|
||||
$request->validate([
|
||||
'name' => 'nullable|string',
|
||||
'color' => 'nullable|string|size:6',
|
||||
'background' => 'nullable|string|size:6',
|
||||
'size' => 'nullable|integer|min:20|max:1024'
|
||||
]);
|
||||
|
||||
$name = $request->get('name', 'NA');
|
||||
$color = $request->get('color', '7F9CF5');
|
||||
$background = $request->get('background', 'EBF4FF');
|
||||
$size = $request->get('size', 100);
|
||||
|
||||
return User::getAvatarImage($name, $color, $background, $size);
|
||||
|
||||
try {
|
||||
} catch (\Exception $e) {
|
||||
// String base64 de una imagen PNG transparente de 1x1 píxel
|
||||
$transparentBase64 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==';
|
||||
|
||||
return response()->make(base64_decode($transparentBase64), 200, [
|
||||
'Content-Type' => 'image/png'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class WebsiteSettingController extends Controller
|
||||
{
|
||||
public function generalSettings()
|
||||
{
|
||||
return view('admin::website-settings.general-settings-index');
|
||||
}
|
||||
|
||||
public function legal()
|
||||
{
|
||||
return view('admin::website-settings.legal-index');
|
||||
}
|
||||
}
|
32
src/modules/App/Http/Middleware/AdminTemplateMiddleware.php
Normal file
32
src/modules/App/Http/Middleware/AdminTemplateMiddleware.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Modules\Admin\App\Services\AdminTemplateService;
|
||||
use Illuminate\Support\Facades\View;
|
||||
|
||||
class AdminTemplateMiddleware
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
// Verificar si estamos en el contexto de website
|
||||
if (!$request->is('admin/*') && !$request->is('admin')) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
// Compartir variables globalmente solo si es una solicitud HTML
|
||||
if (str_contains($request->header('Accept'), 'text/html')) {
|
||||
$adminVars = app(AdminTemplateService::class)->getAdminVars();
|
||||
|
||||
View::share('_admin', $adminVars);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Http\View\Composers;
|
||||
|
||||
use Illuminate\View\View;
|
||||
use Modules\Admin\App\Services\VuexyAdminService;
|
||||
|
||||
class VuexyTemplateComposer
|
||||
{
|
||||
protected $vuexyAdminService;
|
||||
|
||||
public function __construct(VuexyAdminService $vuexyAdminService)
|
||||
{
|
||||
$this->vuexyAdminService = $vuexyAdminService;
|
||||
}
|
||||
|
||||
public function compose(View $view)
|
||||
{
|
||||
$view->with([
|
||||
'vuexyMenu' => $this->vuexyAdminService->getMenu(),
|
||||
'vuexySearch' => $this->vuexyAdminService->getSearch(),
|
||||
'vuexyQuickLinks' => $this->vuexyAdminService->getQuickLinks(),
|
||||
'vuexyNotifications' => $this->vuexyAdminService->getNotifications(),
|
||||
'vuexyBreadcrumbs' => $this->vuexyAdminService->getBreadcrumbs(),
|
||||
]);
|
||||
}
|
||||
}
|
78
src/modules/App/Imports/SATCodigoPostalImport.php
Normal file
78
src/modules/App/Imports/SATCodigoPostalImport.php
Normal file
@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATCodigoPostalImport implements ToCollection
|
||||
{
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 7 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_codigo_postal' => $row[0],
|
||||
'c_estado' => $row[1],
|
||||
'c_municipio' => $row[2],
|
||||
'c_localidad' => $row[3],
|
||||
'estimulo_franja_fronteriza' => $row[4],
|
||||
'fecha_inicio_de_vigencia' => $row[5] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[5])) :
|
||||
null,
|
||||
'fecha_fin_de_vigencia' => $row[6] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[6])) :
|
||||
null,
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_codigo_postal')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_codigo_postal'
|
||||
],
|
||||
[
|
||||
'c_estado',
|
||||
'c_municipio',
|
||||
'c_localidad',
|
||||
'estimulo_franja_fronteriza',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia'
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
68
src/modules/App/Imports/SATColoniaImport.php
Normal file
68
src/modules/App/Imports/SATColoniaImport.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATColoniaImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 5 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_colonia' => $row[0],
|
||||
'c_codigo_postal' => $row[1],
|
||||
'nombre_del_asentamiento' => $row[2],
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_colonia')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_colonia',
|
||||
'c_codigo_postal',
|
||||
],
|
||||
[
|
||||
'nombre_del_asentamiento',
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
src/modules/App/Imports/SATEstadoImport.php
Normal file
77
src/modules/App/Imports/SATEstadoImport.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATEstadoImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 5 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_estado' => $row[0],
|
||||
'c_pais' => $row[1],
|
||||
'nombre_del_estado' => $row[2],
|
||||
'fecha_inicio_de_vigencia' => $row[3] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[3])) :
|
||||
null,
|
||||
'fecha_fin_de_vigencia' => $row[4] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[4])) :
|
||||
null,
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_estado')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_estado',
|
||||
'c_pais',
|
||||
],
|
||||
[
|
||||
'nombre_del_estado',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
95
src/modules/App/Imports/SATFormaPagoImport.php
Normal file
95
src/modules/App/Imports/SATFormaPagoImport.php
Normal file
@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATFormaPagoImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 6 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_forma_pago' => $row[0],
|
||||
'descripcion' => $row[1],
|
||||
'bancarizado' => $row[2],
|
||||
'numero_de_operacion' => $row[3],
|
||||
'rfc_del_emisor_de_la_cuenta_ordenante' => $row[4],
|
||||
'cuenta_ordenante' => $row[5],
|
||||
'patron_para_cuenta_ordenante' => $row[6],
|
||||
'rfc_del_emisor_cuenta_de_beneficiario' => $row[7],
|
||||
'cuenta_de_benenficiario' => $row[8],
|
||||
'patron_para_cuenta_beneficiaria' => $row[9],
|
||||
'tipo_cadena_pago' => $row[10],
|
||||
'banco_emisor_de_la_cuenta_ordenante' => $row[11],
|
||||
'fecha_inicio_de_vigencia' => $row[12] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[12])) :
|
||||
null,
|
||||
'fecha_fin_de_vigencia' => $row[13] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[13])) :
|
||||
null,
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_forma_pago')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_forma_pago',
|
||||
],
|
||||
[
|
||||
'descripcion',
|
||||
'bancarizado',
|
||||
'numero_de_operacion',
|
||||
'rfc_del_emisor_de_la_cuenta_ordenante',
|
||||
'cuenta_ordenante',
|
||||
'patron_para_cuenta_ordenante',
|
||||
'rfc_del_emisor_cuenta_de_beneficiario',
|
||||
'cuenta_de_benenficiario',
|
||||
'patron_para_cuenta_beneficiaria',
|
||||
'tipo_cadena_pago',
|
||||
'banco_emisor_de_la_cuenta_ordenante',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
src/modules/App/Imports/SATLocalidadImport.php
Normal file
77
src/modules/App/Imports/SATLocalidadImport.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATLocalidadImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 5 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_localidad' => $row[0],
|
||||
'c_estado' => $row[1],
|
||||
'descripcion' => $row[2],
|
||||
'fecha_de_inicio_de_vigencia' => $row[3] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[3])) :
|
||||
null,
|
||||
'fecha_de_fin_de_vigencia' => $row[4] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[4])) :
|
||||
null,
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_localidad')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_localidad',
|
||||
'c_estado',
|
||||
],
|
||||
[
|
||||
'descripcion',
|
||||
'fecha_de_inicio_de_vigencia',
|
||||
'fecha_de_fin_de_vigencia'
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
79
src/modules/App/Imports/SATMonedaImport.php
Normal file
79
src/modules/App/Imports/SATMonedaImport.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATMonedaImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 5 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_moneda' => $row[0],
|
||||
'descripcion' => $row[1],
|
||||
'decimales' => $row[2],
|
||||
'porcentaje_variacion' => $row[3],
|
||||
'fecha_inicio_de_vigencia' => $row[4] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[4])) :
|
||||
null,
|
||||
'fecha_fin_de_vigencia' => $row[5] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[5])) :
|
||||
null,
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_moneda')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_moneda',
|
||||
],
|
||||
[
|
||||
'descripcion',
|
||||
'decimales',
|
||||
'porcentaje_variacion',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
77
src/modules/App/Imports/SATMunicipioImport.php
Normal file
77
src/modules/App/Imports/SATMunicipioImport.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATMunicipioImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 5 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_municipio' => $row[0],
|
||||
'c_estado' => $row[1],
|
||||
'descripcion' => $row[2],
|
||||
'fecha_de_inicio_de_vigencia' => $row[3] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[3])) :
|
||||
null,
|
||||
'fecha_de_fin_de_vigencia' => $row[4] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[4])) :
|
||||
null,
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_municipio')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_municipio',
|
||||
'c_estado',
|
||||
],
|
||||
[
|
||||
'descripcion',
|
||||
'fecha_de_inicio_de_vigencia',
|
||||
'fecha_de_fin_de_vigencia'
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
74
src/modules/App/Imports/SATPaisImport.php
Normal file
74
src/modules/App/Imports/SATPaisImport.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATPaisImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 5 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_pais' => $row[0],
|
||||
'descripcion' => $row[1],
|
||||
'formato_de_codigo_postal' => $row[2],
|
||||
'formato_de_registro_de_identidad_tributaria' => $row[3],
|
||||
'validacion_del_registro_de_identidad_tributaria' => $row[4],
|
||||
'agrupaciones' => $row[5],
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_pais')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_pais',
|
||||
],
|
||||
[
|
||||
'descripcion',
|
||||
'formato_de_codigo_postal',
|
||||
'formato_de_registro_de_identidad_tributaria',
|
||||
'validacion_del_registro_de_identidad_tributaria',
|
||||
'agrupaciones',
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
79
src/modules/App/Imports/SATRegimenFiscalImport.php
Normal file
79
src/modules/App/Imports/SATRegimenFiscalImport.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATRegimenFiscalImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 6 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_regimen_fiscal' => $row[0],
|
||||
'descripcion' => $row[1],
|
||||
'fisica' => $row[2],
|
||||
'moral' => $row[3],
|
||||
'fecha_de_inicio_de_vigencia' => $row[4] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[4])) :
|
||||
null,
|
||||
'fecha_de_fin_de_vigencia' => $row[5] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[5])) :
|
||||
null,
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_regimen_fiscal')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_regimen_fiscal',
|
||||
],
|
||||
[
|
||||
'descripcion',
|
||||
'fisica',
|
||||
'moral',
|
||||
'fecha_de_inicio_de_vigencia',
|
||||
'fecha_de_fin_de_vigencia'
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
81
src/modules/App/Imports/SATUsoCFDIImport.php
Normal file
81
src/modules/App/Imports/SATUsoCFDIImport.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class SATUsoCFDIImport implements ToCollection
|
||||
{
|
||||
/**
|
||||
* @param Collection $collection
|
||||
*/
|
||||
public function collection(Collection $collection)
|
||||
{
|
||||
$batchSize = 1000;
|
||||
$batchData = [];
|
||||
$processedRows = 0;
|
||||
|
||||
foreach ($collection as $key => $row) {
|
||||
if ($key < 6 || !$row[1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$requestArray = [
|
||||
'c_uso_cfdi' => $row[0],
|
||||
'descripcion' => $row[1],
|
||||
'aplica_para_tipo_persona_fisica' => $row[2],
|
||||
'aplica_para_tipo_persona_moral' => $row[3],
|
||||
'fecha_inicio_de_vigencia' => $row[4] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[4])) :
|
||||
null,
|
||||
'fecha_fin_de_vigencia' => $row[5] ?
|
||||
Carbon::instance(\PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($row[5])) :
|
||||
null,
|
||||
'regimen_fiscal_receptor' => $row[6],
|
||||
];
|
||||
|
||||
$batchData[] = $requestArray;
|
||||
$processedRows++;
|
||||
|
||||
if (count($batchData) >= $batchSize) {
|
||||
$this->insertBatch($batchData);
|
||||
$batchData = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($batchData)) {
|
||||
$this->insertBatch($batchData);
|
||||
}
|
||||
|
||||
echo "\n\033[32mImport completed: Processed $processedRows rows.\033[0m\n";
|
||||
}
|
||||
|
||||
private function insertBatch(array $batchData)
|
||||
{
|
||||
try {
|
||||
DB::table('sat_uso_cfdi')->upsert(
|
||||
$batchData,
|
||||
[
|
||||
'c_uso_cfdi',
|
||||
],
|
||||
[
|
||||
'descripcion',
|
||||
'aplica_para_tipo_persona_fisica',
|
||||
'aplica_para_tipo_persona_moral',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
'regimen_fiscal_receptor',
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
echo "Error in batch: " . $e->getMessage() . "\n";
|
||||
|
||||
foreach ($batchData as $row) {
|
||||
echo "Row data: " . json_encode($row) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
31
src/modules/App/Imports/SatCatalogsImport.php
Normal file
31
src/modules/App/Imports/SatCatalogsImport.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Imports;
|
||||
|
||||
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
|
||||
use Maatwebsite\Excel\Concerns\WithConditionalSheets;
|
||||
|
||||
|
||||
class SatCatalogsImport implements WithMultipleSheets
|
||||
{
|
||||
use WithConditionalSheets;
|
||||
|
||||
public function conditionalSheets(): array
|
||||
{
|
||||
return [
|
||||
'c_FormaPago' => new SATFormaPagoImport(),
|
||||
'c_Moneda' => new SATMonedaImport(),
|
||||
'c_CodigoPostal_Parte_1' => new SATCodigoPostalImport(),
|
||||
'c_CodigoPostal_Parte_2' => new SATCodigoPostalImport(),
|
||||
'c_RegimenFiscal' => new SATRegimenFiscalImport(),
|
||||
'c_Pais' => new SATPaisImport(),
|
||||
'c_UsoCFDI' => new SATUsoCFDIImport(),
|
||||
'C_Colonia_1' => new SATColoniaImport(),
|
||||
'C_Colonia_2' => new SATColoniaImport(),
|
||||
'C_Colonia_3' => new SATColoniaImport(),
|
||||
'c_Estado' => new SATEstadoImport(),
|
||||
'C_Localidad' => new SATLocalidadImport(),
|
||||
'C_Municipio' => new SATMunicipioImport(),
|
||||
];
|
||||
}
|
||||
}
|
25
src/modules/App/Listeners/ClearUserCache.php
Normal file
25
src/modules/App/Listeners/ClearUserCache.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Listeners;
|
||||
|
||||
use Illuminate\Auth\Events\Logout;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Admin\App\Services\VuexyAdminService;
|
||||
|
||||
class ClearUserCache
|
||||
{
|
||||
/**
|
||||
* Handle the event.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle(Logout $event)
|
||||
{
|
||||
if ($event->user) {
|
||||
VuexyAdminService::clearUserMenuCache();
|
||||
VuexyAdminService::clearSearchMenuCache();
|
||||
VuexyAdminService::clearQuickLinksCache();
|
||||
VuexyAdminService::clearNotificationsCache();
|
||||
}
|
||||
}
|
||||
}
|
26
src/modules/App/Listeners/HandleUserLogin.php
Normal file
26
src/modules/App/Listeners/HandleUserLogin.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Listeners;
|
||||
|
||||
use Illuminate\Auth\Events\Login;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Modules\Admin\App\Models\UserLogin;
|
||||
|
||||
class HandleUserLogin
|
||||
{
|
||||
public function handle(Login $event)
|
||||
{
|
||||
// Guardar log en base de datos
|
||||
UserLogin::create([
|
||||
'user_id' => $event->user->id,
|
||||
'ip_address' => request()->ip(),
|
||||
'user_agent' => request()->header('User-Agent'),
|
||||
]);
|
||||
|
||||
// Actualizar el último login
|
||||
$event->user->update(['last_login_at' => now(), 'last_login_ip' => request()->ip()]);
|
||||
|
||||
// Enviar notificación de inicio de sesión
|
||||
//Mail::to($event->user->email)->send(new LoginNotification($event->user));
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\AdminSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use Modules\Admin\App\Services\AdminSettingsService;
|
||||
use Modules\Admin\App\Services\AdminTemplateService;
|
||||
|
||||
class ApplicationSettings extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
private $targetNotify = "#application-settings-card .notification-container";
|
||||
|
||||
public $admin_app_name,
|
||||
$admin_image_logo,
|
||||
$admin_image_logo_dark;
|
||||
|
||||
public $upload_image_logo,
|
||||
$upload_image_logo_dark;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings($clearcache = false)
|
||||
{
|
||||
$this->upload_image_logo = null;
|
||||
$this->upload_image_logo_dark = null;
|
||||
|
||||
$adminTemplateService = app(AdminTemplateService::class);
|
||||
|
||||
if ($clearcache) {
|
||||
$adminTemplateService->clearAdminVarsCache();
|
||||
}
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $adminTemplateService->getAdminVars();
|
||||
|
||||
$this->admin_app_name = $settings['app_name'];
|
||||
$this->admin_image_logo = $settings['image_logo']['large'];
|
||||
$this->admin_image_logo_dark = $settings['image_logo']['large_dark'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'admin_app_name' => 'required|string|max:255',
|
||||
'upload_image_logo' => 'nullable|image|mimes:jpeg,png,jpg,svg,webp|max:20480',
|
||||
'upload_image_logo_dark' => 'nullable|image|mimes:jpeg,png,jpg,svg,webp|max:20480',
|
||||
]);
|
||||
|
||||
$adminSettingsService = app(AdminSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$adminSettingsService->updateSetting('admin_app_name', $this->admin_app_name);
|
||||
|
||||
// Procesar favicon si se ha cargado una imagen
|
||||
if ($this->upload_image_logo) {
|
||||
$adminSettingsService->processAndSaveImageLogo($this->upload_image_logo);
|
||||
}
|
||||
|
||||
if ($this->upload_image_logo_dark) {
|
||||
$adminSettingsService->processAndSaveImageLogo($this->upload_image_logo_dark, 'dark');
|
||||
}
|
||||
|
||||
$this->loadSettings(true);
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.admin-settings.application-settings');
|
||||
}
|
||||
}
|
84
src/modules/App/Livewire/AdminSettings/GeneralSettings.php
Normal file
84
src/modules/App/Livewire/AdminSettings/GeneralSettings.php
Normal file
@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\AdminSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use Modules\Admin\App\Services\AdminSettingsService;
|
||||
use Modules\Admin\App\Services\AdminTemplateService;
|
||||
|
||||
class GeneralSettings extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
private $targetNotify = "#general-settings-card .notification-container";
|
||||
|
||||
public $admin_title;
|
||||
public $admin_favicon_16x16,
|
||||
$admin_favicon_76x76,
|
||||
$admin_favicon_120x120,
|
||||
$admin_favicon_152x152,
|
||||
$admin_favicon_180x180,
|
||||
$admin_favicon_192x192;
|
||||
|
||||
public $upload_image_favicon;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings($clearcache = false)
|
||||
{
|
||||
$this->upload_image_favicon = null;
|
||||
|
||||
$adminTemplateService = app(AdminTemplateService::class);
|
||||
|
||||
if ($clearcache) {
|
||||
$adminTemplateService->clearAdminVarsCache();
|
||||
}
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $adminTemplateService->getAdminVars();
|
||||
|
||||
$this->admin_title = $settings['title'];
|
||||
$this->admin_favicon_16x16 = $settings['favicon']['16x16'];
|
||||
$this->admin_favicon_76x76 = $settings['favicon']['76x76'];
|
||||
$this->admin_favicon_120x120 = $settings['favicon']['120x120'];
|
||||
$this->admin_favicon_152x152 = $settings['favicon']['152x152'];
|
||||
$this->admin_favicon_180x180 = $settings['favicon']['180x180'];
|
||||
$this->admin_favicon_192x192 = $settings['favicon']['192x192'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'admin_title' => 'required|string|max:255',
|
||||
'upload_image_favicon' => 'nullable|image|mimes:jpeg,png,jpg,svg,webp|max:20480',
|
||||
]);
|
||||
|
||||
$adminSettingsService = app(AdminSettingsService::class);
|
||||
|
||||
// Guardar título del sitio en configuraciones
|
||||
$adminSettingsService->updateSetting('admin_title', $this->admin_title);
|
||||
|
||||
// Procesar favicon si se ha cargado una imagen
|
||||
if ($this->upload_image_favicon) {
|
||||
$adminSettingsService->processAndSaveFavicon($this->upload_image_favicon);
|
||||
}
|
||||
|
||||
$this->loadSettings(true);
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.admin-settings.general-settings');
|
||||
}
|
||||
}
|
118
src/modules/App/Livewire/AdminSettings/InterfaceSettings.php
Normal file
118
src/modules/App/Livewire/AdminSettings/InterfaceSettings.php
Normal file
@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\AdminSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use Modules\Admin\App\Services\AdminTemplateService;
|
||||
use Modules\Admin\App\Services\GlobalSettingsService;
|
||||
|
||||
class InterfaceSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#interface-settings-card .notification-container";
|
||||
|
||||
public $vuexy_myLayout,
|
||||
$vuexy_myTheme,
|
||||
$vuexy_myStyle,
|
||||
$vuexy_hasCustomizer,
|
||||
$vuexy_displayCustomizer,
|
||||
$vuexy_contentLayout,
|
||||
$vuexy_navbarType,
|
||||
$vuexy_footerFixed,
|
||||
$vuexy_menuFixed,
|
||||
$vuexy_menuCollapsed,
|
||||
$vuexy_headerType,
|
||||
$vuexy_showDropdownOnHover,
|
||||
$vuexy_authViewMode,
|
||||
$vuexy_maxQuickLinks;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$adminTemplateService = app(AdminTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $adminTemplateService->getVuexyCustomizerVars();
|
||||
|
||||
$this->vuexy_myLayout = $settings['myLayout'];
|
||||
$this->vuexy_myTheme = $settings['myTheme'];
|
||||
$this->vuexy_myStyle = $settings['myStyle'];
|
||||
$this->vuexy_hasCustomizer = $settings['hasCustomizer'];
|
||||
$this->vuexy_displayCustomizer = $settings['displayCustomizer'];
|
||||
$this->vuexy_contentLayout = $settings['contentLayout'];
|
||||
$this->vuexy_navbarType = $settings['navbarType'];
|
||||
$this->vuexy_footerFixed = $settings['footerFixed'];
|
||||
$this->vuexy_menuFixed = $settings['menuFixed'];
|
||||
$this->vuexy_menuCollapsed = $settings['menuCollapsed'];
|
||||
$this->vuexy_headerType = $settings['headerType'];
|
||||
$this->vuexy_showDropdownOnHover = $settings['showDropdownOnHover'];
|
||||
$this->vuexy_authViewMode = $settings['authViewMode'];
|
||||
$this->vuexy_maxQuickLinks = $settings['maxQuickLinks'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'vuexy_maxQuickLinks' => 'required|integer|min:2|max:20',
|
||||
]);
|
||||
|
||||
$globalSettingsService = app(GlobalSettingsService::class);
|
||||
|
||||
// Guardar configuraciones
|
||||
$globalSettingsService->updateSetting('config.custom.custom.myLayout', $this->vuexy_myLayout);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.myTheme', $this->vuexy_myTheme);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.myStyle', $this->vuexy_myStyle);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.hasCustomizer', $this->vuexy_hasCustomizer);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.displayCustomizer', $this->vuexy_displayCustomizer);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.contentLayout', $this->vuexy_contentLayout);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.navbarType', $this->vuexy_navbarType);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.footerFixed', $this->vuexy_footerFixed);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.menuFixed', $this->vuexy_menuFixed);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.menuCollapsed', $this->vuexy_menuCollapsed);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.headerType', $this->vuexy_headerType);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.showDropdownOnHover', $this->vuexy_showDropdownOnHover);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.authViewMode', $this->vuexy_authViewMode);
|
||||
$globalSettingsService->updateSetting('config.custom.custom.maxQuickLinks', $this->vuexy_maxQuickLinks);
|
||||
|
||||
$globalSettingsService->clearSystemConfigCache();
|
||||
|
||||
// Refrescar el componente actual
|
||||
$this->dispatch('clearLocalStoregeTemplateCustomizer');
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.',
|
||||
deferReload: true
|
||||
);
|
||||
}
|
||||
|
||||
public function clearCustomConfig()
|
||||
{
|
||||
$globalSettingsService = app(GlobalSettingsService::class);
|
||||
|
||||
$globalSettingsService->clearVuexyCustomConfig();
|
||||
|
||||
// Refrescar el componente actual
|
||||
$this->dispatch('clearLocalStoregeTemplateCustomizer');
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.',
|
||||
deferReload: true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.admin-settings.interface-settings');
|
||||
}
|
||||
}
|
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\AdminSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use Modules\Admin\App\Services\GlobalSettingsService;
|
||||
|
||||
class MailSenderResponseSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#mail-sender-response-settings-card .notification-container";
|
||||
|
||||
public $from_address,
|
||||
$from_name,
|
||||
$reply_to_method,
|
||||
$reply_to_email,
|
||||
$reply_to_name;
|
||||
|
||||
protected $listeners = ['saveMailSenderResponseSettings' => 'save'];
|
||||
|
||||
const REPLY_EMAIL_CREATOR = 1;
|
||||
const REPLY_EMAIL_SENDER = 2;
|
||||
const REPLY_EMAIL_CUSTOM = 3;
|
||||
|
||||
public $reply_email_options = [
|
||||
self::REPLY_EMAIL_CREATOR => 'Responder al creador del documento',
|
||||
self::REPLY_EMAIL_SENDER => 'Responder a quien envía el documento',
|
||||
self::REPLY_EMAIL_CUSTOM => 'Definir dirección de correo electrónico',
|
||||
];
|
||||
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$globalSettingsService = app(GlobalSettingsService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $globalSettingsService->getMailSystemConfig();
|
||||
|
||||
$this->from_address = $settings['from']['address'];
|
||||
$this->from_name = $settings['from']['name'];
|
||||
$this->reply_to_method = $settings['reply_to']['method'];
|
||||
$this->reply_to_email = $settings['reply_to']['email'];
|
||||
$this->reply_to_name = $settings['reply_to']['name'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'from_address' => 'required|email',
|
||||
'from_name' => 'required|string|max:255',
|
||||
'reply_to_method' => 'required|string|max:255',
|
||||
], [
|
||||
'from_address.required' => 'El campo de correo electrónico es obligatorio.',
|
||||
'from_address.email' => 'El formato del correo electrónico no es válido.',
|
||||
'from_name.required' => 'El nombre es obligatorio.',
|
||||
'from_name.string' => 'El nombre debe ser una cadena de texto.',
|
||||
'from_name.max' => 'El nombre no puede tener más de 255 caracteres.',
|
||||
'reply_to_method.required' => 'El método de respuesta es obligatorio.',
|
||||
'reply_to_method.string' => 'El método de respuesta debe ser una cadena de texto.',
|
||||
'reply_to_method.max' => 'El método de respuesta no puede tener más de 255 caracteres.',
|
||||
]);
|
||||
|
||||
if ($this->reply_to_method == self::REPLY_EMAIL_CUSTOM) {
|
||||
$this->validate([
|
||||
'reply_to_email' => ['required', 'email'],
|
||||
'reply_to_name' => ['required', 'string', 'max:255'],
|
||||
], [
|
||||
'reply_to_email.required' => 'El correo de respuesta es obligatorio.',
|
||||
'reply_to_email.email' => 'El formato del correo de respuesta no es válido.',
|
||||
'reply_to_name.required' => 'El nombre de respuesta es obligatorio.',
|
||||
'reply_to_name.string' => 'El nombre de respuesta debe ser una cadena de texto.',
|
||||
'reply_to_name.max' => 'El nombre de respuesta no puede tener más de 255 caracteres.',
|
||||
]);
|
||||
}
|
||||
|
||||
$globalSettingsService = app(GlobalSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$globalSettingsService->updateSetting('mail.from.address', $this->from_address);
|
||||
$globalSettingsService->updateSetting('mail.from.name', $this->from_name);
|
||||
$globalSettingsService->updateSetting('mail.reply_to.method', $this->reply_to_method);
|
||||
$globalSettingsService->updateSetting('mail.reply_to.email', $this->reply_to_method == self::REPLY_EMAIL_CUSTOM ? $this->reply_to_email : '');
|
||||
$globalSettingsService->updateSetting('mail.reply_to.name', $this->reply_to_method == self::REPLY_EMAIL_CUSTOM ? $this->reply_to_name : '');
|
||||
|
||||
$globalSettingsService->clearMailSystemConfigCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.',
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.admin-settings.mail-sender-response-settings');
|
||||
}
|
||||
}
|
175
src/modules/App/Livewire/AdminSettings/MailSmtpSettings.php
Normal file
175
src/modules/App/Livewire/AdminSettings/MailSmtpSettings.php
Normal file
@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\AdminSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Symfony\Component\Mailer\Transport;
|
||||
use Symfony\Component\Mailer\Mailer;
|
||||
use Symfony\Component\Mime\Email;
|
||||
use Modules\Admin\App\Services\GlobalSettingsService;
|
||||
|
||||
|
||||
class MailSmtpSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#mail-smtp-settings-card .notification-container";
|
||||
|
||||
public $change_smtp_settings,
|
||||
$host,
|
||||
$port,
|
||||
$encryption,
|
||||
$username,
|
||||
$password;
|
||||
|
||||
public $save_button_disabled;
|
||||
|
||||
protected $listeners = [
|
||||
'loadSettings',
|
||||
'testSmtpConnection',
|
||||
];
|
||||
|
||||
// the list of smtp_encryption values that can be stored in table
|
||||
const SMTP_ENCRYPTION_SSL = 'SSL';
|
||||
const SMTP_ENCRYPTION_TLS = 'TLS';
|
||||
const SMTP_ENCRYPTION_NONE = 'none';
|
||||
|
||||
public $encryption_options = [
|
||||
self::SMTP_ENCRYPTION_SSL => 'SSL (Secure Sockets Layer)',
|
||||
self::SMTP_ENCRYPTION_TLS => 'TLS (Transport Layer Security)',
|
||||
self::SMTP_ENCRYPTION_NONE => 'Sin encriptación (No recomendado)',
|
||||
];
|
||||
|
||||
public $rules = [
|
||||
[
|
||||
'host' => 'nullable|string|max:255',
|
||||
'port' => 'nullable|integer',
|
||||
'encryption' => 'nullable|string',
|
||||
'username' => 'nullable|string|max:255',
|
||||
'password' => 'nullable|string|max:255',
|
||||
],
|
||||
[
|
||||
'host.string' => 'El servidor SMTP debe ser una cadena de texto.',
|
||||
'host.max' => 'El servidor SMTP no puede exceder los 255 caracteres.',
|
||||
'port.integer' => 'El puerto SMTP debe ser un número entero.',
|
||||
'encryption.string' => 'El tipo de encriptación SMTP debe ser una cadena de texto.',
|
||||
'username.string' => 'El nombre de usuario SMTP debe ser una cadena de texto.',
|
||||
'username.max' => 'El nombre de usuario SMTP no puede exceder los 255 caracteres.',
|
||||
'password.string' => 'La contraseña SMTP debe ser una cadena de texto.',
|
||||
'password.max' => 'La contraseña SMTP no puede exceder los 255 caracteres.',
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$globalSettingsService = app(GlobalSettingsService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $globalSettingsService->getMailSystemConfig();
|
||||
|
||||
$this->change_smtp_settings = false;
|
||||
$this->save_button_disabled = true;
|
||||
|
||||
$this->host = $settings['mailers']['smtp']['host'];
|
||||
$this->port = $settings['mailers']['smtp']['port'];
|
||||
$this->encryption = $settings['mailers']['smtp']['encryption'];
|
||||
$this->username = $settings['mailers']['smtp']['username'];
|
||||
$this->password = null;
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate($this->rules[0]);
|
||||
|
||||
$globalSettingsService = app(GlobalSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$globalSettingsService->updateSetting('mail.mailers.smtp.host', $this->host);
|
||||
$globalSettingsService->updateSetting('mail.mailers.smtp.port', $this->port);
|
||||
$globalSettingsService->updateSetting('mail.mailers.smtp.encryption', $this->encryption);
|
||||
$globalSettingsService->updateSetting('mail.mailers.smtp.username', $this->username);
|
||||
$globalSettingsService->updateSetting('mail.mailers.smtp.password', Crypt::encryptString($this->password));
|
||||
|
||||
$globalSettingsService->clearMailSystemConfigCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function testSmtpConnection()
|
||||
{
|
||||
// Validar los datos del formulario
|
||||
$this->validate($this->rules[0]);
|
||||
|
||||
try {
|
||||
// Verificar la conexión SMTP
|
||||
if ($this->validateSMTPConnection()) {
|
||||
$this->save_button_disabled = false;
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Conexión SMTP exitosa, se guardó los cambios exitosamente.',
|
||||
);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
// Captura y maneja errores de conexión SMTP
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'danger',
|
||||
message: 'Error en la conexión SMTP: ' . $e->getMessage(),
|
||||
notificationTimeout: 15000 // Timeout personalizado
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function validateSMTPConnection()
|
||||
{
|
||||
$dsn = sprintf(
|
||||
'smtp://%s:%s@%s:%s?encryption=%s',
|
||||
urlencode($this->username), // Codificar nombre de usuario
|
||||
urlencode($this->password), // Codificar contraseña
|
||||
$this->host, // Host SMTP
|
||||
$this->port, // Puerto SMTP
|
||||
$this->encryption // Encriptación (tls o ssl)
|
||||
);
|
||||
|
||||
// Crear el transportador usando el DSN
|
||||
$transport = Transport::fromDsn($dsn);
|
||||
|
||||
// Crear el mailer con el transportador personalizado
|
||||
$mailer = new Mailer($transport);
|
||||
|
||||
// Enviar un correo de prueba
|
||||
$email = (new Email())
|
||||
->from($this->username) // Dirección de correo del remitente
|
||||
->to(env('MAIL_SANDBOX')) // Dirección de correo de destino
|
||||
->subject(Config::get('app.name') . ' - Correo de prueba')
|
||||
->text('Este es un correo de prueba para verificar la conexión SMTP.');
|
||||
|
||||
// Enviar el correo
|
||||
$mailer->send($email);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.admin-settings.mail-smtp-settings');
|
||||
}
|
||||
}
|
212
src/modules/App/Livewire/Cache/CacheFunctions.php
Normal file
212
src/modules/App/Livewire/Cache/CacheFunctions.php
Normal file
@ -0,0 +1,212 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Cache;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
|
||||
class CacheFunctions extends Component
|
||||
{
|
||||
private $targetNotify = "#cache-functions-card .notification-container";
|
||||
|
||||
public $cacheCounts = [
|
||||
'general' => 0,
|
||||
'config' => 0,
|
||||
'routes' => 0,
|
||||
'views' => 0,
|
||||
'events' => 0,
|
||||
];
|
||||
|
||||
protected $listeners = [
|
||||
'reloadCacheFunctionsStatsEvent' => 'reloadCacheStats',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->reloadCacheStats(false);
|
||||
}
|
||||
|
||||
public function reloadCacheStats($notify = true)
|
||||
{
|
||||
$cacheDriver = config('cache.default'); // Obtiene el driver configurado para caché
|
||||
|
||||
// Caché General
|
||||
switch ($cacheDriver) {
|
||||
case 'memcached':
|
||||
try {
|
||||
$cacheStore = Cache::getStore()->getMemcached();
|
||||
$stats = $cacheStore->getStats();
|
||||
|
||||
$this->cacheCounts['general'] = array_sum(array_column($stats, 'curr_items')); // Total de claves en Memcached
|
||||
} catch (\Exception $e) {
|
||||
$this->cacheCounts['general'] = 'Error obteniendo datos de Memcached';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'redis':
|
||||
try {
|
||||
$prefix = config('cache.prefix'); // Asegúrate de agregar el sufijo correcto si es necesario
|
||||
$keys = Redis::connection('cache')->keys($prefix . '*');
|
||||
|
||||
$this->cacheCounts['general'] = count($keys); // Total de claves en Redis
|
||||
} catch (\Exception $e) {
|
||||
$this->cacheCounts['general'] = 'Error obteniendo datos de Redis';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'database':
|
||||
try {
|
||||
$this->cacheCounts['general'] = DB::table('cache')->count(); // Total de registros en la tabla de caché
|
||||
} catch (\Exception $e) {
|
||||
$this->cacheCounts['general'] = 'Error obteniendo datos de la base de datos';
|
||||
}
|
||||
break;
|
||||
|
||||
case 'file':
|
||||
try {
|
||||
$cachePath = config('cache.stores.file.path');
|
||||
$files = glob($cachePath . '/*');
|
||||
|
||||
$this->cacheCounts['general'] = count($files);
|
||||
} catch (\Exception $e) {
|
||||
$this->cacheCounts['general'] = 'Error obteniendo datos de archivos';
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->cacheCounts['general'] = 'Driver de caché no soportado';
|
||||
}
|
||||
|
||||
// Configuración
|
||||
$this->cacheCounts['config'] = file_exists(base_path('bootstrap/cache/config.php')) ? 1 : 0;
|
||||
|
||||
// Rutas
|
||||
$this->cacheCounts['routes'] = count(glob(base_path('bootstrap/cache/routes-*.php'))) > 0 ? 1 : 0;
|
||||
|
||||
// Vistas
|
||||
$this->cacheCounts['views'] = count(glob(storage_path('framework/views/*')));
|
||||
|
||||
// Configuración
|
||||
$this->cacheCounts['events'] = file_exists(base_path('bootstrap/cache/events.php')) ? 1 : 0;
|
||||
|
||||
if ($notify) {
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han recargado los estadísticos de caché.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function clearLaravelCache()
|
||||
{
|
||||
Artisan::call('cache:clear');
|
||||
|
||||
sleep(1);
|
||||
|
||||
$this->response('Se han limpiado las cachés de la aplicación.', 'warning');
|
||||
}
|
||||
|
||||
public function clearConfigCache()
|
||||
{
|
||||
Artisan::call('config:clear');
|
||||
|
||||
$this->response('Se ha limpiado la cache de la configuración de Laravel.', 'warning');
|
||||
}
|
||||
|
||||
public function configCache()
|
||||
{
|
||||
Artisan::call('config:cache');
|
||||
}
|
||||
|
||||
public function clearRouteCache()
|
||||
{
|
||||
Artisan::call('route:clear');
|
||||
|
||||
$this->response('Se han limpiado las rutas de Laravel.', 'warning');
|
||||
}
|
||||
|
||||
public function cacheRoutes()
|
||||
{
|
||||
Artisan::call('route:cache');
|
||||
}
|
||||
|
||||
public function clearViewCache()
|
||||
{
|
||||
Artisan::call('view:clear');
|
||||
|
||||
$this->response('Se han limpiado las vistas de Laravel.', 'warning');
|
||||
}
|
||||
|
||||
public function cacheViews()
|
||||
{
|
||||
Artisan::call('view:cache');
|
||||
|
||||
$this->response('Se han cacheado las vistas de Laravel.');
|
||||
}
|
||||
|
||||
public function clearEventCache()
|
||||
{
|
||||
Artisan::call('event:clear');
|
||||
|
||||
$this->response('Se han limpiado los eventos de Laravel.', 'warning');
|
||||
}
|
||||
|
||||
public function cacheEvents()
|
||||
{
|
||||
Artisan::call('event:cache');
|
||||
|
||||
$this->response('Se han cacheado los eventos de Laravel.');
|
||||
}
|
||||
|
||||
public function optimizeClear()
|
||||
{
|
||||
Artisan::call('optimize:clear');
|
||||
|
||||
$this->response('Se han optimizado todos los cachés de Laravel.');
|
||||
}
|
||||
|
||||
public function resetPermissionCache()
|
||||
{
|
||||
Artisan::call('permission:cache-reset');
|
||||
|
||||
$this->response('Se han limpiado los cachés de permisos.', 'warning');
|
||||
}
|
||||
|
||||
public function clearResetTokens()
|
||||
{
|
||||
Artisan::call('auth:clear-resets');
|
||||
|
||||
$this->response('Se han limpiado los tokens de reseteo de contraseña.', 'warning');
|
||||
}
|
||||
|
||||
/**
|
||||
* Genera una respuesta estandarizada.
|
||||
*/
|
||||
private function response(string $message, string $type = 'success'): void
|
||||
{
|
||||
$this->reloadCacheStats(false);
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $type,
|
||||
message: $message,
|
||||
);
|
||||
|
||||
$this->dispatch('reloadCacheStatsEvent', notify: false);
|
||||
$this->dispatch('reloadSessionStatsEvent', notify: false);
|
||||
$this->dispatch('reloadRedisStatsEvent', notify: false);
|
||||
$this->dispatch('reloadMemcachedStatsEvent', notify: false);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.cache.cache-functions');
|
||||
}
|
||||
}
|
65
src/modules/App/Livewire/Cache/CacheStats.php
Normal file
65
src/modules/App/Livewire/Cache/CacheStats.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Cache;
|
||||
|
||||
use Livewire\Component;
|
||||
use Modules\Admin\App\Services\CacheConfigService;
|
||||
use Modules\Admin\App\Services\CacheManagerService;
|
||||
|
||||
class CacheStats extends Component
|
||||
{
|
||||
private $targetNotify = "#cache-stats-card .notification-container";
|
||||
|
||||
public $cacheConfig = [];
|
||||
public $cacheStats = [];
|
||||
|
||||
protected $listeners = ['reloadCacheStatsEvent' => 'reloadCacheStats'];
|
||||
|
||||
public function mount(CacheConfigService $cacheConfigService)
|
||||
{
|
||||
$this->cacheConfig = $cacheConfigService->getConfig();
|
||||
|
||||
$this->reloadCacheStats(false);
|
||||
}
|
||||
|
||||
public function reloadCacheStats($notify = true)
|
||||
{
|
||||
$cacheManagerService = new CacheManagerService();
|
||||
|
||||
$this->cacheStats = $cacheManagerService->getCacheStats();
|
||||
|
||||
if ($notify) {
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $this->cacheStats['status'],
|
||||
message: $this->cacheStats['message']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function clearCache()
|
||||
{
|
||||
$cacheManagerService = new CacheManagerService();
|
||||
|
||||
$message = $cacheManagerService->clearCache();
|
||||
|
||||
$this->reloadCacheStats(false);
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $message['status'],
|
||||
message: $message['message'],
|
||||
);
|
||||
|
||||
$this->dispatch('reloadRedisStatsEvent', notify: false);
|
||||
$this->dispatch('reloadMemcachedStatsEvent', notify: false);
|
||||
$this->dispatch('reloadCacheFunctionsStatsEvent', notify: false);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.cache.cache-stats');
|
||||
}
|
||||
}
|
64
src/modules/App/Livewire/Cache/MemcachedStats.php
Normal file
64
src/modules/App/Livewire/Cache/MemcachedStats.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Cache;
|
||||
|
||||
use Livewire\Component;
|
||||
use Modules\Admin\App\Services\CacheManagerService;
|
||||
|
||||
class MemcachedStats extends Component
|
||||
{
|
||||
private $driver = 'memcached';
|
||||
private $targetNotify = "#memcached-stats-card .notification-container";
|
||||
|
||||
public $memcachedStats = [];
|
||||
|
||||
protected $listeners = ['reloadMemcachedStatsEvent' => 'reloadCacheStats'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->reloadCacheStats(false);
|
||||
}
|
||||
|
||||
public function reloadCacheStats($notify = true)
|
||||
{
|
||||
$cacheManagerService = new CacheManagerService($this->driver);
|
||||
|
||||
$memcachedStats = $cacheManagerService->getMemcachedStats();
|
||||
|
||||
$this->memcachedStats = $memcachedStats['info'];
|
||||
|
||||
if ($notify) {
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $memcachedStats['status'],
|
||||
message: $memcachedStats['message']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function clearCache()
|
||||
{
|
||||
$cacheManagerService = new CacheManagerService($this->driver);
|
||||
|
||||
$message = $cacheManagerService->clearCache();
|
||||
|
||||
$this->reloadCacheStats(false);
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $message['status'],
|
||||
message: $message['message'],
|
||||
);
|
||||
|
||||
$this->dispatch('reloadCacheStatsEvent', notify: false);
|
||||
$this->dispatch('reloadSessionStatsEvent', notify: false);
|
||||
$this->dispatch('reloadCacheFunctionsStatsEvent', notify: false);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.cache.memcached-stats');
|
||||
}
|
||||
}
|
64
src/modules/App/Livewire/Cache/RedisStats.php
Normal file
64
src/modules/App/Livewire/Cache/RedisStats.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Cache;
|
||||
|
||||
use Livewire\Component;
|
||||
use Modules\Admin\App\Services\CacheManagerService;
|
||||
|
||||
class RedisStats extends Component
|
||||
{
|
||||
private $driver = 'redis';
|
||||
private $targetNotify = "#redis-stats-card .notification-container";
|
||||
|
||||
public $redisStats = [];
|
||||
|
||||
protected $listeners = ['reloadRedisStatsEvent' => 'reloadCacheStats'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->reloadCacheStats(false);
|
||||
}
|
||||
|
||||
public function reloadCacheStats($notify = true)
|
||||
{
|
||||
$cacheManagerService = new CacheManagerService($this->driver);
|
||||
|
||||
$redisStats = $cacheManagerService->getRedisStats();
|
||||
|
||||
$this->redisStats = $redisStats['info'];
|
||||
|
||||
if ($notify) {
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $redisStats['status'],
|
||||
message: $redisStats['message']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function clearCache()
|
||||
{
|
||||
$cacheManagerService = new CacheManagerService($this->driver);
|
||||
|
||||
$message = $cacheManagerService->clearCache();
|
||||
|
||||
$this->reloadCacheStats(false);
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $message['status'],
|
||||
message: $message['message'],
|
||||
);
|
||||
|
||||
$this->dispatch('reloadCacheStatsEvent', notify: false);
|
||||
$this->dispatch('reloadSessionStatsEvent', notify: false);
|
||||
$this->dispatch('reloadCacheFunctionsStatsEvent', notify: false);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.cache.redis-stats');
|
||||
}
|
||||
}
|
63
src/modules/App/Livewire/Cache/SessionStats.php
Normal file
63
src/modules/App/Livewire/Cache/SessionStats.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Cache;
|
||||
|
||||
use Livewire\Component;
|
||||
use Modules\Admin\App\Services\CacheConfigService;
|
||||
use Modules\Admin\App\Services\SessionManagerService;
|
||||
|
||||
class SessionStats extends Component
|
||||
{
|
||||
private $targetNotify = "#session-stats-card .notification-container";
|
||||
|
||||
public $cacheConfig = [];
|
||||
public $sessionStats = [];
|
||||
|
||||
protected $listeners = ['reloadSessionStatsEvent' => 'reloadSessionStats'];
|
||||
|
||||
public function mount(CacheConfigService $cacheConfigService)
|
||||
{
|
||||
$this->cacheConfig = $cacheConfigService->getConfig();
|
||||
$this->reloadSessionStats(false);
|
||||
}
|
||||
|
||||
public function reloadSessionStats($notify = true)
|
||||
{
|
||||
$sessionManagerService = new SessionManagerService();
|
||||
|
||||
$this->sessionStats = $sessionManagerService->getSessionStats();
|
||||
|
||||
if ($notify) {
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $this->sessionStats['status'],
|
||||
message: $this->sessionStats['message']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function clearSessions()
|
||||
{
|
||||
$sessionManagerService = new SessionManagerService();
|
||||
|
||||
$message = $sessionManagerService->clearSessions();
|
||||
|
||||
$this->reloadSessionStats(false);
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: $message['status'],
|
||||
message: $message['message'],
|
||||
);
|
||||
|
||||
$this->dispatch('reloadRedisStatsEvent', notify: false);
|
||||
$this->dispatch('reloadMemcachedStatsEvent', notify: false);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.cache.session-stats');
|
||||
}
|
||||
}
|
28
src/modules/App/Livewire/Rbac/PermissionsIndex.php
Normal file
28
src/modules/App/Livewire/Rbac/PermissionsIndex.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Rbac;
|
||||
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class PermissionsIndex extends Component
|
||||
{
|
||||
public $roles_html_select;
|
||||
public $rows_roles;
|
||||
|
||||
public function render()
|
||||
{
|
||||
// Generamos Select y estilos HTML de roles
|
||||
$this->roles_html_select = "<select id=\"UserRole\" class=\"form-select text-capitalize\"><option value=\"\"> Selecciona un rol </option>";
|
||||
|
||||
foreach (Role::all() as $role) {
|
||||
$this->rows_roles[$role->name] = "<span class=\"badge bg-label-{$role->style} m-1\">{$role->name}</span>";
|
||||
$this->roles_html_select .= "<option value=\"{$role->name}\" class=\"text-capitalize\">{$role->name}</option>";
|
||||
}
|
||||
|
||||
$this->roles_html_select .= "</select>";
|
||||
|
||||
return view('admin::livewire.rbac.permissions-index');
|
||||
}
|
||||
}
|
182
src/modules/App/Livewire/Rbac/RoleCards.php
Normal file
182
src/modules/App/Livewire/Rbac/RoleCards.php
Normal file
@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Rbac;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class RoleCards extends Component
|
||||
{
|
||||
public $roles = [];
|
||||
public $permissions = [];
|
||||
public $roleId;
|
||||
public $name;
|
||||
public $style;
|
||||
public $title;
|
||||
public $btn_submit_text;
|
||||
public $permissionsInputs = [];
|
||||
public $destroyRoleId;
|
||||
|
||||
protected $listeners = ['saveRole', 'deleteRole'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadRolesAndPermissions();
|
||||
$this->dispatch('reloadForm');
|
||||
}
|
||||
|
||||
private function loadRolesAndPermissions()
|
||||
{
|
||||
$this->roles = Auth::user()->hasRole('SuperAdmin') ?
|
||||
Role::all() :
|
||||
Role::where('name', '!=', 'SuperAdmin')->get();
|
||||
|
||||
// Obtener todos los permisos
|
||||
$permissions = Permission::all()->map(function ($permission) {
|
||||
$name = $permission->name;
|
||||
$action = substr($name, strrpos($name, '.') + 1);
|
||||
|
||||
return [
|
||||
'group_name' => $permission->group_name,
|
||||
'sub_group_name' => $permission->sub_group_name,
|
||||
$action => $name // Agregar la acción directamente al array
|
||||
];
|
||||
})->groupBy('group_name'); // Agrupar los permisos por grupo
|
||||
|
||||
|
||||
// Procesar los permisos agrupados para cargarlos en el componente
|
||||
$permissionsInputs = [];
|
||||
|
||||
$this->permissions = $permissions->map(function ($groupPermissions) use (&$permissionsInputs) {
|
||||
$permission = [
|
||||
'group_name' => $groupPermissions[0]['group_name'], // Tomar el grupo del primer permiso del grupo
|
||||
'sub_group_name' => $groupPermissions[0]['sub_group_name'], // Tomar la descripción del primer permiso del grupo
|
||||
];
|
||||
|
||||
// Agregar todas las acciones al permissionsInputs y al permission
|
||||
foreach ($groupPermissions as $permissionData) {
|
||||
foreach ($permissionData as $key => $value) {
|
||||
if ($key !== 'sub_group_name' && $key !== 'group_name') {
|
||||
$permissionsInputs[str_replace('.', '_', $value)] = false;
|
||||
$permission[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $permission;
|
||||
});
|
||||
|
||||
$this->permissionsInputs = $permissionsInputs;
|
||||
}
|
||||
|
||||
public function loadRoleData($action, $roleId = false)
|
||||
{
|
||||
$this->resetForm();
|
||||
|
||||
$this->title = 'Agregar un nuevo rol';
|
||||
$this->btn_submit_text = 'Crear nuevo rol';
|
||||
|
||||
if ($roleId) {
|
||||
$role = Role::findOrFail($roleId);
|
||||
|
||||
switch ($action) {
|
||||
case 'view':
|
||||
$this->title = $role->name;
|
||||
$this->name = $role->name;
|
||||
$this->style = $role->style;
|
||||
$this->dispatch('deshabilitarFormulario');
|
||||
break;
|
||||
|
||||
case 'update':
|
||||
$this->title = 'Editar rol';
|
||||
$this->btn_submit_text = 'Guardar cambios';
|
||||
$this->roleId = $roleId;
|
||||
$this->name = $role->name;
|
||||
$this->style = $role->style;
|
||||
$this->dispatch('habilitarFormulario');
|
||||
break;
|
||||
|
||||
case 'clone':
|
||||
$this->style = $role->style;
|
||||
$this->dispatch('habilitarFormulario');
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
foreach ($role->permissions as $permission) {
|
||||
$this->permissionsInputs[str_replace('.', '_', $permission->name)] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->dispatch('reloadForm');
|
||||
}
|
||||
|
||||
public function loadDestroyRoleData() {}
|
||||
|
||||
public function saveRole()
|
||||
{
|
||||
$permissions = [];
|
||||
|
||||
foreach ($this->permissionsInputs as $permission => $value) {
|
||||
if ($value === true)
|
||||
$permissions[] = str_replace('_', '.', $permission);
|
||||
}
|
||||
|
||||
if ($this->roleId) {
|
||||
$role = Role::find($this->roleId);
|
||||
|
||||
$role->name = $this->name;
|
||||
$role->style = $this->style;
|
||||
|
||||
$role->save();
|
||||
|
||||
$role->syncPermissions($permissions);
|
||||
} else {
|
||||
$role = Role::create([
|
||||
'name' => $this->name,
|
||||
'style' => $this->style,
|
||||
]);
|
||||
|
||||
$role->syncPermissions($permissions);
|
||||
}
|
||||
|
||||
$this->loadRolesAndPermissions();
|
||||
|
||||
$this->dispatch('modalHide');
|
||||
$this->dispatch('reloadForm');
|
||||
}
|
||||
|
||||
public function deleteRole()
|
||||
{
|
||||
$role = Role::find($this->destroyRoleId);
|
||||
|
||||
if ($role)
|
||||
$role->delete();
|
||||
|
||||
$this->loadRolesAndPermissions();
|
||||
|
||||
$this->dispatch('modalDeleteHide');
|
||||
$this->dispatch('reloadForm');
|
||||
}
|
||||
|
||||
private function resetForm()
|
||||
{
|
||||
$this->roleId = '';
|
||||
$this->name = '';
|
||||
$this->style = '';
|
||||
|
||||
foreach ($this->permissionsInputs as $key => $permission) {
|
||||
$this->permissionsInputs[$key] = false;
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.rbac.role-cards');
|
||||
}
|
||||
}
|
31
src/modules/App/Livewire/Users/UserCount.php
Normal file
31
src/modules/App/Livewire/Users/UserCount.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Users;
|
||||
|
||||
use Modules\Admin\App\Models\User;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class UserCount extends Component
|
||||
{
|
||||
public $total, $enabled, $disabled;
|
||||
|
||||
protected $listeners = ['refreshUserCount' => 'updateCounts'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->updateCounts();
|
||||
}
|
||||
|
||||
public function updateCounts()
|
||||
{
|
||||
$this->total = User::count();
|
||||
$this->enabled = User::where('status', User::STATUS_ENABLED)->count();
|
||||
$this->disabled = User::where('status', User::STATUS_DISABLED)->count();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.users.user-count');
|
||||
}
|
||||
}
|
115
src/modules/App/Livewire/Users/UserTable.php
Normal file
115
src/modules/App/Livewire/Users/UserTable.php
Normal file
@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\Users;
|
||||
|
||||
use Spatie\Permission\Models\Role;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Modules\Admin\App\Models\User;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class UserTable extends Component
|
||||
{
|
||||
public $statuses;
|
||||
public $status_options;
|
||||
|
||||
public $rows_roles = [];
|
||||
public $roles_options = [];
|
||||
public $roles_html_select;
|
||||
|
||||
public $total, $enabled, $disabled;
|
||||
|
||||
public $indexAlert;
|
||||
|
||||
public $userId, $name, $email, $password, $roles, $status, $photo, $src_photo;
|
||||
public $modalTitle;
|
||||
public $btnSubmitTxt;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->modalTitle = 'Crear usuario nuevo';
|
||||
$this->btnSubmitTxt = 'Crear usuario';
|
||||
|
||||
$this->statuses = [
|
||||
User::STATUS_ENABLED => ['title' => 'Activo', 'class' => 'badge bg-label-' . User::$statusListClass[User::STATUS_ENABLED]],
|
||||
User::STATUS_DISABLED => ['title' => 'Deshabilitado', 'class' => 'badge bg-label-' . User::$statusListClass[User::STATUS_DISABLED]],
|
||||
User::STATUS_REMOVED => ['title' => 'Eliminado', 'class' => 'badge bg-label-' . User::$statusListClass[User::STATUS_REMOVED]],
|
||||
];
|
||||
|
||||
$roles = Role::whereNotIn('name', ['Patient', 'Doctor'])->get();
|
||||
|
||||
$this->roles_html_select = "<select id=\"UserRole\" class=\"form-select text-capitalize\"><option value=\"\"> Selecciona un rol </option>";
|
||||
|
||||
foreach ($roles as $role) {
|
||||
$this->rows_roles[$role->name] = "<span class=\"badge bg-label-" . $role->style . " mx-1\">" . $role->name . "</span>";
|
||||
|
||||
if (Auth::user()->hasRole('SuperAdmin') || $role->name != 'SuperAdmin') {
|
||||
$this->roles_html_select .= "<option value=\"" . $role->name . "\" class=\"text-capitalize\">" . $role->name . "</option>";
|
||||
$this->roles_options[$role->name] = $role->name;
|
||||
}
|
||||
}
|
||||
|
||||
$this->roles_html_select .= "</select>";
|
||||
|
||||
$this->status_options = [
|
||||
User::STATUS_ENABLED => User::$statusList[User::STATUS_ENABLED],
|
||||
User::STATUS_DISABLED => User::$statusList[User::STATUS_DISABLED],
|
||||
];
|
||||
}
|
||||
|
||||
public function countUsers()
|
||||
{
|
||||
$this->total = User::count();
|
||||
$this->enabled = User::where('status', User::STATUS_ENABLED)->count();
|
||||
$this->disabled = User::where('status', User::STATUS_DISABLED)->count();
|
||||
}
|
||||
|
||||
|
||||
public function edit($id)
|
||||
{
|
||||
$user = User::findOrFail($id);
|
||||
|
||||
$this->indexAlert = '';
|
||||
$this->modalTitle = 'Editar usuario: ' . $id;
|
||||
$this->btnSubmitTxt = 'Guardar cambios';
|
||||
|
||||
$this->userId = $user->id;
|
||||
$this->name = $user->name;
|
||||
$this->email = $user->email;
|
||||
$this->password = '';
|
||||
$this->roles = $user->roles->pluck('name')->toArray();
|
||||
$this->src_photo = $user->profile_photo_url;
|
||||
$this->status = $user->status;
|
||||
|
||||
$this->dispatch('openModal');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$user = User::find($id);
|
||||
|
||||
if ($user) {
|
||||
// Eliminar la imagen de perfil si existe
|
||||
if ($user->profile_photo_path)
|
||||
Storage::disk('public')->delete($user->profile_photo_path);
|
||||
|
||||
// Eliminar el usuario
|
||||
$user->delete();
|
||||
|
||||
$this->indexAlert = '<div class="alert alert-warning alert-dismissible" role="alert">Se eliminó correctamente el usuario.<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>';
|
||||
|
||||
$this->dispatch('refreshUserCount');
|
||||
$this->dispatch('afterDelete');
|
||||
} else {
|
||||
$this->indexAlert = '<div class="alert alert-danger alert-dismissible" role="alert">Usuario no encontrado.<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button></div>';
|
||||
}
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.users.user-table', [
|
||||
'users' => User::paginate(10),
|
||||
]);
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class AnalyticsSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-analytics-settings-card .notification-container";
|
||||
|
||||
public $google_analytics_enabled,
|
||||
$google_analytics_id;
|
||||
|
||||
protected $listeners = ['saveAnalyticsSettings' => 'save'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$WebsiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $WebsiteTemplateService->getWebsiteVars('google');
|
||||
|
||||
$this->google_analytics_enabled = $settings['analytics']['enabled'];
|
||||
$this->google_analytics_id = $settings['analytics']['id'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
if ($this->google_analytics_enabled) {
|
||||
$this->validate([
|
||||
'google_analytics_id' => 'required|string|min:12|max:30',
|
||||
]);
|
||||
}
|
||||
|
||||
$websiteSettingsService = app(WebsiteSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$websiteSettingsService->updateSetting('google_analytics_enabled', $this->google_analytics_enabled);
|
||||
$websiteSettingsService->updateSetting('google_analytics_id', $this->google_analytics_id);
|
||||
|
||||
app(WebsiteTemplateService::class)->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.analytics-settings');
|
||||
}
|
||||
}
|
68
src/modules/App/Livewire/WebsiteSettings/ChatSettings.php
Normal file
68
src/modules/App/Livewire/WebsiteSettings/ChatSettings.php
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class ChatSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-chat-settings-card .notification-container";
|
||||
|
||||
public $chat_provider,
|
||||
$chat_whatsapp_number,
|
||||
$chat_whatsapp_message;
|
||||
|
||||
protected $listeners = ['saveChatSettings' => 'save'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getWebsiteVars('chat');
|
||||
|
||||
$this->chat_provider = $settings['provider'];
|
||||
$this->chat_whatsapp_number = $settings['whatsapp_number'];
|
||||
$this->chat_whatsapp_message = $settings['whatsapp_message'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
if ($this->chat_provider == 'whatsapp') {
|
||||
$this->validate([
|
||||
'chat_whatsapp_number' => 'required|string|max:20',
|
||||
'chat_whatsapp_message' => 'required|string|max:255',
|
||||
]);
|
||||
}
|
||||
|
||||
$websiteSettingsService = app(WebsiteSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$websiteSettingsService->updateSetting('chat_provider', $this->chat_provider);
|
||||
$websiteSettingsService->updateSetting('chat_whatsapp_number', preg_replace('/\D/', '', $this->chat_whatsapp_number));
|
||||
$websiteSettingsService->updateSetting('chat_whatsapp_message', $this->chat_whatsapp_message);
|
||||
|
||||
app(WebsiteTemplateService::class)->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.chat-settings');
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class ContactFormSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-contact-form-settings-card .notification-container";
|
||||
|
||||
public $contact_form_email,
|
||||
$contact_form_email_cc,
|
||||
$contact_form_subject;
|
||||
|
||||
protected $listeners = ['saveContactFormSettings' => 'save'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getWebsiteVars();
|
||||
|
||||
$this->contact_form_email = $settings['contact']['form']['email'];
|
||||
$this->contact_form_email_cc = $settings['contact']['form']['email_cc'];
|
||||
$this->contact_form_subject = $settings['contact']['form']['subject'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'contact_form_email' => 'required|email',
|
||||
'contact_form_email_cc' => 'nullable|email',
|
||||
'contact_form_subject' => 'required|string'
|
||||
]);
|
||||
|
||||
$websiteSettingsService = app(WebsiteSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$websiteSettingsService->updateSetting('contact_form_email', $this->contact_form_email);
|
||||
$websiteSettingsService->updateSetting('contact_form_email_cc', $this->contact_form_email_cc);
|
||||
$websiteSettingsService->updateSetting('contact_form_subject', $this->contact_form_subject);
|
||||
|
||||
app(WebsiteTemplateService::class)->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.contact-form-settings');
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class ContactInfoSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-contact-info-settings-card .notification-container";
|
||||
|
||||
public $contact_phone_number,
|
||||
$contact_phone_number_ext,
|
||||
$contact_email;
|
||||
|
||||
protected $listeners = ['saveContactInfoSettings' => 'save'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getWebsiteVars();
|
||||
|
||||
$this->contact_phone_number = $settings['contact']['phone_number'];
|
||||
$this->contact_phone_number_ext = $settings['contact']['phone_number_ext'];
|
||||
$this->contact_email = $settings['contact']['email'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'contact_phone_number' => ['nullable', 'string', 'max:20'],
|
||||
'contact_phone_number_ext' => ['nullable', 'string', 'max:10'],
|
||||
'contact_email' => ['nullable', 'email']
|
||||
]);
|
||||
|
||||
$websiteSettingsService = app(WebsiteSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$websiteSettingsService->updateSetting('contact_phone_number', $this->contact_phone_number);
|
||||
$websiteSettingsService->updateSetting('contact_phone_number_ext', $this->contact_phone_number_ext);
|
||||
$websiteSettingsService->updateSetting('contact_email', $this->contact_email);
|
||||
|
||||
app(WebsiteTemplateService::class)->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.contact-info-settings');
|
||||
}
|
||||
}
|
72
src/modules/App/Livewire/WebsiteSettings/FaviconSettings.php
Normal file
72
src/modules/App/Livewire/WebsiteSettings/FaviconSettings.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class FaviconSettings extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
private $targetNotify = "#website-favicon-settings-card .notification-container";
|
||||
|
||||
public $upload_image_favicon;
|
||||
public $website_favicon_16x16,
|
||||
$website_favicon_76x76,
|
||||
$website_favicon_120x120,
|
||||
$website_favicon_152x152,
|
||||
$website_favicon_180x180,
|
||||
$website_favicon_192x192;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
$this->upload_image_favicon = null;
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getWebsiteVars();
|
||||
|
||||
$this->website_favicon_16x16 = $settings['favicon']['16x16'];
|
||||
$this->website_favicon_76x76 = $settings['favicon']['76x76'];
|
||||
$this->website_favicon_120x120 = $settings['favicon']['120x120'];
|
||||
$this->website_favicon_152x152 = $settings['favicon']['152x152'];
|
||||
$this->website_favicon_180x180 = $settings['favicon']['180x180'];
|
||||
$this->website_favicon_192x192 = $settings['favicon']['192x192'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'upload_image_favicon' => 'required|image|mimes:jpeg,png,jpg,svg,webp|max:20480',
|
||||
]);
|
||||
|
||||
// Procesar favicon si se ha cargado una imagen
|
||||
$websiteSettingsService = app(WebsiteSettingsService::class);
|
||||
$websiteSettingsService->processAndSaveFavicon($this->upload_image_favicon);
|
||||
|
||||
app(WebsiteTemplateService::class)->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.favicon-settings');
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class ImageLogoSettings extends Component
|
||||
{
|
||||
use WithFileUploads;
|
||||
|
||||
private $targetNotify = "#website-image-logo-settings-card .notification-container";
|
||||
|
||||
public $website_image_logo,
|
||||
$website_image_logo_dark;
|
||||
|
||||
public $upload_image_logo,
|
||||
$upload_image_logo_dark;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
$this->upload_image_logo = null;
|
||||
$this->upload_image_logo_dark = null;
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getWebsiteVars();
|
||||
|
||||
$this->website_image_logo = $settings['image_logo']['large'];
|
||||
$this->website_image_logo_dark = $settings['image_logo']['large_dark'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'upload_image_logo' => 'nullable|image|mimes:jpeg,png,jpg,svg,webp|max:20480',
|
||||
'upload_image_logo_dark' => 'nullable|image|mimes:jpeg,png,jpg,svg,webp|max:20480',
|
||||
]);
|
||||
|
||||
$websiteSettingsService = app(WebsiteSettingsService::class);
|
||||
|
||||
// Procesar favicon si se ha cargado una imagen
|
||||
if ($this->upload_image_logo) {
|
||||
$websiteSettingsService->processAndSaveImageLogo($this->upload_image_logo);
|
||||
}
|
||||
|
||||
if ($this->upload_image_logo_dark) {
|
||||
$websiteSettingsService->processAndSaveImageLogo($this->upload_image_logo_dark, 'dark');
|
||||
}
|
||||
|
||||
app(WebsiteTemplateService::class)->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.image-logo-settings');
|
||||
}
|
||||
}
|
108
src/modules/App/Livewire/WebsiteSettings/LegalSettings.php
Normal file
108
src/modules/App/Livewire/WebsiteSettings/LegalSettings.php
Normal file
@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Rules\NotEmptyHtml;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class LegalSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-legal-settings-card .notification-container";
|
||||
|
||||
public $legalVars = [];
|
||||
public $currentSection = null;
|
||||
|
||||
protected $listeners = [
|
||||
'saveLegal' => 'save',
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
|
||||
// Seleccionar la primera sección por defecto
|
||||
$this->currentSection = array_key_first($this->legalVars);
|
||||
}
|
||||
|
||||
function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
switch ($this->currentSection) {
|
||||
case 'legal_terminos_y_condiciones':
|
||||
$this->legalVars['legal_terminos_y_condiciones'] = $websiteTemplateService->getLegalVars('legal_terminos_y_condiciones');
|
||||
break;
|
||||
|
||||
case 'legal_aviso_de_privacidad':
|
||||
$this->legalVars['legal_aviso_de_privacidad'] = $websiteTemplateService->getLegalVars('legal_aviso_de_privacidad');
|
||||
break;
|
||||
|
||||
case 'legal_politica_de_devoluciones':
|
||||
$this->legalVars['legal_politica_de_devoluciones'] = $websiteTemplateService->getLegalVars('legal_politica_de_devoluciones');
|
||||
break;
|
||||
|
||||
case 'legal_politica_de_envios':
|
||||
$this->legalVars['legal_politica_de_envios'] = $websiteTemplateService->getLegalVars('legal_politica_de_envios');
|
||||
break;
|
||||
|
||||
case 'legal_politica_de_cookies':
|
||||
$this->legalVars['legal_politica_de_cookies'] = $websiteTemplateService->getLegalVars('legal_politica_de_cookies');
|
||||
break;
|
||||
|
||||
case 'legal_autorizaciones_y_licencias':
|
||||
$this->legalVars['legal_autorizaciones_y_licencias'] = $websiteTemplateService->getLegalVars('legal_autorizaciones_y_licencias');
|
||||
break;
|
||||
|
||||
case 'legal_informacion_comercial':
|
||||
$this->legalVars['legal_informacion_comercial'] = $websiteTemplateService->getLegalVars('legal_informacion_comercial');
|
||||
break;
|
||||
|
||||
case 'legal_consentimiento_para_el_login_de_terceros':
|
||||
$this->legalVars['legal_consentimiento_para_el_login_de_terceros'] = $websiteTemplateService->getLegalVars('legal_consentimiento_para_el_login_de_terceros');
|
||||
break;
|
||||
|
||||
case 'legal_leyendas_de_responsabilidad':
|
||||
$this->legalVars['legal_leyendas_de_responsabilidad'] = $websiteTemplateService->getLegalVars('legal_leyendas_de_responsabilidad');
|
||||
break;
|
||||
|
||||
default:
|
||||
$this->legalVars = $websiteTemplateService->getLegalVars();
|
||||
}
|
||||
}
|
||||
|
||||
public function rules()
|
||||
{
|
||||
$rules = [];
|
||||
|
||||
if ($this->legalVars[$this->currentSection]['enabled']) {
|
||||
$rules["legalVars.{$this->currentSection}.content"] = ['required', 'string', new NotEmptyHtml];
|
||||
}
|
||||
|
||||
$rules["legalVars.{$this->currentSection}.enabled"] = 'boolean';
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate($this->rules());
|
||||
|
||||
$websiteSettingsService = app(WebsiteSettingsService::class);
|
||||
$websiteSettingsService->updateSetting($this->currentSection . '_enabled', $this->legalVars[$this->currentSection]['enabled']);
|
||||
$websiteSettingsService->updateSetting($this->currentSection . '_content', $this->legalVars[$this->currentSection]['content']);
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.legal-settings');
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class LocationSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-location-settings-card .notification-container";
|
||||
|
||||
public $contact_direccion,
|
||||
$contact_horario,
|
||||
$contact_location_lat,
|
||||
$contact_location_lng;
|
||||
|
||||
protected $listeners = ['saveLocationSettings' => 'save'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getWebsiteVars();
|
||||
|
||||
$this->contact_direccion = $settings['contact']['direccion'];
|
||||
$this->contact_horario = $settings['contact']['horario'];
|
||||
$this->contact_location_lat = $settings['contact']['location']['lat'];
|
||||
$this->contact_location_lng = $settings['contact']['location']['lng'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'contact_direccion' => ['nullable', 'string', 'max:255'],
|
||||
'contact_horario' => ['nullable', 'string', 'max:255'],
|
||||
'contact_location_lat' => ['nullable', 'numeric'],
|
||||
'contact_location_lng' => ['nullable', 'numeric'],
|
||||
]);
|
||||
|
||||
$websiteSettingsService = app(WebsiteSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$websiteSettingsService->updateSetting('contact_direccion', $this->contact_direccion);
|
||||
$websiteSettingsService->updateSetting('contact_horario', $this->contact_horario);
|
||||
$websiteSettingsService->updateSetting('contact_location_lat', $this->contact_location_lat);
|
||||
$websiteSettingsService->updateSetting('contact_location_lng', $this->contact_location_lng);
|
||||
|
||||
app(WebsiteTemplateService::class)->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.location-settings');
|
||||
}
|
||||
}
|
100
src/modules/App/Livewire/WebsiteSettings/SocialSettings.php
Normal file
100
src/modules/App/Livewire/WebsiteSettings/SocialSettings.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
use Modules\Admin\App\Services\WebsiteSettingsService;
|
||||
|
||||
class SocialSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-social-settings-card .notification-container";
|
||||
|
||||
public $social_whatsapp,
|
||||
$social_whatsapp_message,
|
||||
$social_facebook,
|
||||
$social_instagram,
|
||||
$social_linkedin,
|
||||
$social_tiktok,
|
||||
$social_x_twitter,
|
||||
$social_google,
|
||||
$social_pinterest,
|
||||
$social_youtube,
|
||||
$social_vimeo;
|
||||
|
||||
protected $listeners = ['saveSocialSettings' => 'save'];
|
||||
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getSocialVars();
|
||||
|
||||
$this->social_whatsapp = $settings['whatsapp'];
|
||||
$this->social_whatsapp_message = $settings['whatsapp_message'];
|
||||
$this->social_facebook = $settings['facebook'];
|
||||
$this->social_instagram = $settings['instagram'];
|
||||
$this->social_linkedin = $settings['linkedin'];
|
||||
$this->social_tiktok = $settings['tiktok'];
|
||||
$this->social_x_twitter = $settings['x_twitter'];
|
||||
$this->social_google = $settings['google'];
|
||||
$this->social_pinterest = $settings['pinterest'];
|
||||
$this->social_youtube = $settings['youtube'];
|
||||
$this->social_vimeo = $settings['vimeo'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'social_whatsapp' => 'string|max:20',
|
||||
'social_whatsapp_message' => 'string|max:255',
|
||||
'social_facebook' => 'url',
|
||||
'social_instagram' => 'url',
|
||||
'social_linkedin' => 'url',
|
||||
'social_tiktok' => 'url',
|
||||
'social_x_twitter' => 'url',
|
||||
'social_google' => 'url',
|
||||
'social_pinterest' => 'url',
|
||||
'social_youtube' => 'url',
|
||||
'social_vimeo' => 'url',
|
||||
]);
|
||||
|
||||
$websiteSettingsService = app(websiteSettingsService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$websiteSettingsService->updateSetting('social_whatsapp', preg_replace('/\D/', '', $this->social_whatsapp));
|
||||
$websiteSettingsService->updateSetting('social_whatsapp_message', $this->social_whatsapp_message);
|
||||
$websiteSettingsService->updateSetting('social_facebook', $this->social_facebook);
|
||||
$websiteSettingsService->updateSetting('social_instagram', $this->social_instagram);
|
||||
$websiteSettingsService->updateSetting('social_linkedin', $this->social_linkedin);
|
||||
$websiteSettingsService->updateSetting('social_tiktok', $this->social_tiktok);
|
||||
$websiteSettingsService->updateSetting('social_x_twitter', $this->social_x_twitter);
|
||||
$websiteSettingsService->updateSetting('social_google', $this->social_google);
|
||||
$websiteSettingsService->updateSetting('social_pinterest', $this->social_pinterest);
|
||||
$websiteSettingsService->updateSetting('social_youtube', $this->social_youtube);
|
||||
$websiteSettingsService->updateSetting('social_vimeo', $this->social_vimeo);
|
||||
|
||||
app(WebsiteTemplateService::class)->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.social-settings');
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
|
||||
class TemplateSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-template-settings-card .notification-container";
|
||||
|
||||
public $website_tpl_style_switcher,
|
||||
$website_tpl_footer_text;
|
||||
|
||||
protected $listeners = ['saveTemplateSettings' => 'save'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getWebsiteVars();
|
||||
|
||||
$this->website_tpl_style_switcher = $settings['template']['style_switcher'];
|
||||
$this->website_tpl_footer_text = $settings['template']['footer_text'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'website_tpl_footer_text' => 'nullable|string|max:50',
|
||||
]);
|
||||
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$websiteTemplateService->updateSetting('website_tpl_style_switcher', $this->website_tpl_style_switcher);
|
||||
$websiteTemplateService->updateSetting('website_tpl_footer_text', $this->website_tpl_footer_text);
|
||||
|
||||
$websiteTemplateService->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.template-settings');
|
||||
}
|
||||
}
|
62
src/modules/App/Livewire/WebsiteSettings/WebsiteSettings.php
Normal file
62
src/modules/App/Livewire/WebsiteSettings/WebsiteSettings.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Livewire\WebsiteSettings;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Services\WebsiteTemplateService;
|
||||
|
||||
class WebsiteSettings extends Component
|
||||
{
|
||||
private $targetNotify = "#website-settings-card .notification-container";
|
||||
|
||||
public $website_title,
|
||||
$website_description;
|
||||
|
||||
protected $listeners = ['saveWebsiteSettings' => 'save'];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadSettings();
|
||||
}
|
||||
|
||||
public function loadSettings()
|
||||
{
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Obtener los valores de las configuraciones de la base de datos
|
||||
$settings = $websiteTemplateService->getWebsiteVars();
|
||||
|
||||
$this->website_title = $settings['title'];
|
||||
$this->website_description = $settings['description'];
|
||||
}
|
||||
|
||||
public function save()
|
||||
{
|
||||
$this->validate([
|
||||
'website_title' => 'string|required|max:50',
|
||||
'website_description' => 'string|max:160',
|
||||
]);
|
||||
|
||||
$websiteTemplateService = app(WebsiteTemplateService::class);
|
||||
|
||||
// Guardar título del App en configuraciones
|
||||
$websiteTemplateService->updateSetting('website_title', $this->website_title);
|
||||
$websiteTemplateService->updateSetting('website_description', $this->website_description);
|
||||
|
||||
$websiteTemplateService->clearWebsiteVarsCache();
|
||||
|
||||
$this->loadSettings();
|
||||
|
||||
$this->dispatch(
|
||||
'notification',
|
||||
target: $this->targetNotify,
|
||||
type: 'success',
|
||||
message: 'Se han guardado los cambios en las configuraciones.'
|
||||
);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('admin::livewire.website-settings.website-settings');
|
||||
}
|
||||
}
|
71
src/modules/App/Models/ContactableAddress.php
Normal file
71
src/modules/App/Models/ContactableAddress.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models;
|
||||
|
||||
use Modules\Admin\App\Models\Sat\CodigoPostal;
|
||||
use Modules\Admin\App\Models\Sat\Colonia;
|
||||
use Modules\Admin\App\Models\Sat\Estado;
|
||||
use Modules\Admin\App\Models\Sat\Municipio;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ContactableAddress extends Model
|
||||
{
|
||||
protected $table = 'contactable_addresses';
|
||||
|
||||
protected $fillable = [
|
||||
'contactable_id',
|
||||
'contactable_type',
|
||||
'type',
|
||||
'c_estado',
|
||||
'c_municipio',
|
||||
'c_codigo_postal',
|
||||
'c_colonia',
|
||||
'direccion',
|
||||
'num_ext',
|
||||
'num_int',
|
||||
'referencia',
|
||||
'lat',
|
||||
'lng',
|
||||
'preference_level',
|
||||
];
|
||||
|
||||
/**
|
||||
* Casts for the model attributes.
|
||||
*/
|
||||
protected $casts = [
|
||||
'lat' => 'float',
|
||||
'lng' => 'float',
|
||||
'preference_level' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* Polymorphic relationship to the parent model.
|
||||
*/
|
||||
public function contactable()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Relationships to SAT tables.
|
||||
*/
|
||||
public function estado()
|
||||
{
|
||||
return $this->belongsTo(Estado::class, 'c_estado', 'c_estado');
|
||||
}
|
||||
|
||||
public function municipio()
|
||||
{
|
||||
return $this->belongsTo(Municipio::class, 'c_municipio', 'c_municipio');
|
||||
}
|
||||
|
||||
public function codigoPostal()
|
||||
{
|
||||
return $this->belongsTo(CodigoPostal::class, 'c_codigo_postal', 'c_codigo_postal');
|
||||
}
|
||||
|
||||
public function colonia()
|
||||
{
|
||||
return $this->belongsTo(Colonia::class, 'c_colonia', 'c_colonia');
|
||||
}
|
||||
}
|
35
src/modules/App/Models/ContactableItem.php
Normal file
35
src/modules/App/Models/ContactableItem.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ContactableItem extends Model
|
||||
{
|
||||
protected $table = 'contactable_items';
|
||||
|
||||
protected $fillable = [
|
||||
'contactable_id',
|
||||
'contactable_type',
|
||||
'type',
|
||||
'data_contact',
|
||||
'is_preferred',
|
||||
'preference_level',
|
||||
];
|
||||
|
||||
/**
|
||||
* Casts for the model attributes.
|
||||
*/
|
||||
protected $casts = [
|
||||
'is_preferred' => 'boolean',
|
||||
'preference_level' => 'integer',
|
||||
];
|
||||
|
||||
/**
|
||||
* Polymorphic relationship to the parent model.
|
||||
*/
|
||||
public function contactable()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
62
src/modules/App/Models/MediaItem.php
Normal file
62
src/modules/App/Models/MediaItem.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MediaItem extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'url',
|
||||
'imageable_type',
|
||||
'imageable_id',
|
||||
'type',
|
||||
'sub_type',
|
||||
'url',
|
||||
'path',
|
||||
'title',
|
||||
'description',
|
||||
'order',
|
||||
];
|
||||
|
||||
// the list of types values that can be stored in table
|
||||
const TYPE_CARD = 1;
|
||||
const TYPE_BANNER = 2;
|
||||
const TYPE_COVER = 3;
|
||||
const TYPE_GALLERY = 4;
|
||||
const TYPE_BANNER_HOME = 5;
|
||||
const TYPE_CARD2 = 6;
|
||||
const TYPE_BANNER2 = 7;
|
||||
const TYPE_COVER2 = 8;
|
||||
|
||||
/**
|
||||
* List of names for each types.
|
||||
* @var array
|
||||
*/
|
||||
public static $typesList = [
|
||||
self::TYPE_CARD => 'Card',
|
||||
self::TYPE_BANNER => 'Banner',
|
||||
self::TYPE_COVER => 'Cover',
|
||||
self::TYPE_GALLERY => 'Gallery',
|
||||
self::TYPE_BANNER_HOME => 'Banner Home',
|
||||
self::TYPE_CARD2 => 'Card 2',
|
||||
self::TYPE_BANNER2 => 'Banner 2',
|
||||
self::TYPE_COVER2 => 'Cover 2',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the parent imageable model (user or post).
|
||||
*/
|
||||
public function imageable()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
50
src/modules/App/Models/Sat/Banco.php
Normal file
50
src/modules/App/Models/Sat/Banco.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Banco extends Model
|
||||
{
|
||||
// the list of status values that can be stored in table
|
||||
const STATUS_ENABLED = 10;
|
||||
const STATUS_DISABLED = 1;
|
||||
|
||||
/**
|
||||
* List of names for each status.
|
||||
* @var array
|
||||
*/
|
||||
public static $statusList = [
|
||||
self::STATUS_ENABLED => 'Habilitado',
|
||||
self::STATUS_DISABLED => 'Deshabilitado',
|
||||
];
|
||||
|
||||
/**
|
||||
* List of names for each status.
|
||||
* @var array
|
||||
*/
|
||||
public static $statusListClass = [
|
||||
self::STATUS_ENABLED => 'success',
|
||||
self::STATUS_DISABLED => 'warning',
|
||||
];
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_banco';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_banco',
|
||||
'descripcion',
|
||||
'razon_social',
|
||||
'rfc',
|
||||
'status',
|
||||
];
|
||||
}
|
33
src/modules/App/Models/Sat/ClaveProdServ.php
Normal file
33
src/modules/App/Models/Sat/ClaveProdServ.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ClaveProdServ extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_clave_prod_serv';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_clave_prod_serv',
|
||||
'descripcion',
|
||||
'incluir_iva_trasladado',
|
||||
'incluir_ieps_trasladado',
|
||||
'complemento_que_debe_incluir',
|
||||
'fecha_inicio_vigencia',
|
||||
'fecha_fin_vigencia',
|
||||
'estimulo_franja_fronteriza',
|
||||
'palabras_similares',
|
||||
];
|
||||
}
|
42
src/modules/App/Models/Sat/ClaveUnidad.php
Normal file
42
src/modules/App/Models/Sat/ClaveUnidad.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class ClaveUnidad extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_clave_unidad';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_clave_unidad',
|
||||
'nombre',
|
||||
'descripcion',
|
||||
'nota',
|
||||
'fecha_de_inicio_de_vigencia',
|
||||
'fecha_de_fin_de_vigencia',
|
||||
'simbolo',
|
||||
'is_base',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_de_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_de_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
}
|
77
src/modules/App/Models/Sat/CodigoPostal.php
Normal file
77
src/modules/App/Models/Sat/CodigoPostal.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
|
||||
class CodigoPostal extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_codigo_postal';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_codigo_postal',
|
||||
'c_estado',
|
||||
'c_municipio',
|
||||
'c_localidad',
|
||||
'estimulo_franja_fronteriza',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the estado associated with the CodigoPostal.
|
||||
*/
|
||||
public function estado(): HasOne
|
||||
{
|
||||
return $this->hasOne(Estado::class, 'c_estado', 'c_estado');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the municipio associated with the CodigoPostal.
|
||||
*/
|
||||
public function municipio(): HasOne
|
||||
{
|
||||
return $this->hasOne(Municipio::class, 'c_municipio', 'c_municipio')
|
||||
->where('c_estado', $this->c_estado);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the localidad associated with the CodigoPostal.
|
||||
*/
|
||||
public function localidad(): HasOne
|
||||
{
|
||||
return $this->hasOne(Localidad::class, 'c_estado', 'c_estado')
|
||||
->where('c_localidad', $this->c_localidad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the localidad associated with the CodigoPostal.
|
||||
*/
|
||||
public function colonias(): HasMany
|
||||
{
|
||||
return $this->hasMany(Colonia::class, 'c_codigo_postal', 'c_codigo_postal');
|
||||
}
|
||||
}
|
39
src/modules/App/Models/Sat/Colonia.php
Normal file
39
src/modules/App/Models/Sat/Colonia.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Colonia extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_colonia';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_colonia',
|
||||
'c_codigo_postal',
|
||||
'nombre_del_asentamiento',
|
||||
];
|
||||
|
||||
|
||||
public static function selectList($c_codigo_postal, $c_colonia = false)
|
||||
{
|
||||
return self::select('c_colonia', 'nombre_del_asentamiento')
|
||||
->where('c_codigo_postal', $c_codigo_postal)
|
||||
->when($c_colonia, function ($query) use ($c_colonia) {
|
||||
$query->where('c_colonia', $c_colonia);
|
||||
})
|
||||
->orderBy('nombre_del_asentamiento')
|
||||
->pluck('nombre_del_asentamiento', 'c_colonia');
|
||||
}
|
||||
}
|
37
src/modules/App/Models/Sat/Deduccion.php
Normal file
37
src/modules/App/Models/Sat/Deduccion.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Deduccion extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_deduccion';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_deduccion',
|
||||
'descripcion',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
}
|
47
src/modules/App/Models/Sat/Estado.php
Normal file
47
src/modules/App/Models/Sat/Estado.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Estado extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_estado';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_estado',
|
||||
'c_pais',
|
||||
'nombre_del_estado',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
|
||||
public static function selectList($pais = 'MEX')
|
||||
{
|
||||
return self::select('c_estado', 'nombre_del_estado')
|
||||
->where('c_pais', $pais)
|
||||
->orderBy('nombre_del_estado')
|
||||
->pluck('nombre_del_estado', 'c_estado');
|
||||
}
|
||||
}
|
53
src/modules/App/Models/Sat/FormaPago.php
Normal file
53
src/modules/App/Models/Sat/FormaPago.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class FormaPago extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_forma_pago';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_forma_pago',
|
||||
'descripcion',
|
||||
'bancarizado',
|
||||
'numero_de_operacion',
|
||||
'rfc_del_emisor_de_la_cuenta_ordenante',
|
||||
'cuenta_ordenante',
|
||||
'patron_para_cuenta_ordenante',
|
||||
'rfc_del_emisor_cuenta_de_beneficiario',
|
||||
'cuenta_de_benenficiario',
|
||||
'patron_para_cuenta_beneficiaria',
|
||||
'tipo_cadena_pago',
|
||||
'banco_emisor_de_la_cuenta_ordenante',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
|
||||
public static function selectList()
|
||||
{
|
||||
return self::selectRaw('c_forma_pago, CONCAT(c_forma_pago, " - ", descripcion) as value')
|
||||
->pluck('value', 'c_forma_pago');
|
||||
}
|
||||
}
|
17
src/modules/App/Models/Sat/Impuestos.php
Normal file
17
src/modules/App/Models/Sat/Impuestos.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
class Impuestos
|
||||
{
|
||||
// Definición de constantes para c_impuesto
|
||||
const IMPUESTOS_ISR = 1;
|
||||
const IMPUESTOS_IVA = 2;
|
||||
const IMPUESTOS_IEPS = 3;
|
||||
|
||||
public static $catalogo = [
|
||||
self::IMPUESTOS_ISR => 'ISR',
|
||||
self::IMPUESTOS_IVA => 'IVA',
|
||||
self::IMPUESTOS_IEPS => 'IEPS',
|
||||
];
|
||||
}
|
39
src/modules/App/Models/Sat/Localidad.php
Normal file
39
src/modules/App/Models/Sat/Localidad.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Localidad extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_localidad';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_localidad',
|
||||
'c_estado',
|
||||
'descripcion',
|
||||
'fecha_de_inicio_de_vigencia',
|
||||
'fecha_de_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_de_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_de_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
}
|
14
src/modules/App/Models/Sat/MetodoPago.php
Normal file
14
src/modules/App/Models/Sat/MetodoPago.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
class MetodoPago
|
||||
{
|
||||
const METODO_PAGO_PUE = 'PUE';
|
||||
const METODO_PAGO_PPD = 'PPD';
|
||||
|
||||
public static $catalogo = [
|
||||
self::METODO_PAGO_PUE => 'Pago en una sola exhibición',
|
||||
self::METODO_PAGO_PPD => 'Pago en parcialidades o diferido',
|
||||
];
|
||||
}
|
46
src/modules/App/Models/Sat/Moneda.php
Normal file
46
src/modules/App/Models/Sat/Moneda.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Moneda extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_moneda';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_moneda',
|
||||
'descripcion',
|
||||
'decimales',
|
||||
'porcentaje_variacion',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
|
||||
|
||||
public static function selectList()
|
||||
{
|
||||
return self::selectRaw('c_moneda, CONCAT_WS(" ", c_moneda, "-", descripcion) as text')
|
||||
->pluck('text', 'c_moneda');
|
||||
}
|
||||
}
|
51
src/modules/App/Models/Sat/Municipio.php
Normal file
51
src/modules/App/Models/Sat/Municipio.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Municipio extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_municipio';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_municipio',
|
||||
'c_estado',
|
||||
'descripcion',
|
||||
'fecha_de_inicio_de_vigencia',
|
||||
'fecha_de_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_de_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_de_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
|
||||
|
||||
public static function selectList($c_estado, $c_municipio = false)
|
||||
{
|
||||
return self::select('c_municipio', 'descripcion')
|
||||
->where('c_estado', $c_estado)
|
||||
->when($c_municipio, function ($query) use ($c_municipio) {
|
||||
$query->where('c_municipio', $c_municipio);
|
||||
})
|
||||
->orderBy('descripcion')
|
||||
->pluck('descripcion', 'c_municipio');
|
||||
}
|
||||
}
|
21
src/modules/App/Models/Sat/ObjetoImp.php
Normal file
21
src/modules/App/Models/Sat/ObjetoImp.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
class ObjetoImp
|
||||
{
|
||||
// Definición de constantes para c_objeto_imp
|
||||
const OBJETO_IMP_NO_OBJETO = 1;
|
||||
const OBJETO_IMP_SI_OBJETO = 2;
|
||||
const OBJETO_IMP_SI_OBJETO_NO_DESGLOSE = 3;
|
||||
const OBJETO_IMP_SI_OBJETO_NO_CAUSA = 4;
|
||||
const OBJETO_IMP_SI_OBJETO_IVA_CREDITO = 5;
|
||||
|
||||
public static $catalogo = [
|
||||
self::OBJETO_IMP_NO_OBJETO => 'No objeto de impuesto.',
|
||||
self::OBJETO_IMP_SI_OBJETO => 'Sí objeto de impuesto.',
|
||||
self::OBJETO_IMP_SI_OBJETO_NO_DESGLOSE => 'Sí objeto del impuesto y no obligado al desglose.',
|
||||
self::OBJETO_IMP_SI_OBJETO_NO_CAUSA => 'Sí objeto del impuesto y no causa impuesto.',
|
||||
self::OBJETO_IMP_SI_OBJETO_IVA_CREDITO => 'Sí objeto del impuesto, IVA crédito PODEBI.',
|
||||
];
|
||||
}
|
39
src/modules/App/Models/Sat/Pais.php
Normal file
39
src/modules/App/Models/Sat/Pais.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Pais extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_pais';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_pais',
|
||||
'descripcion',
|
||||
'formato_de_codigo_postal',
|
||||
'formato_de_registro_de_identidad_tributaria',
|
||||
'validacion_del_registro_de_identidad_tributaria',
|
||||
'agrupaciones',
|
||||
];
|
||||
|
||||
public static function selectList()
|
||||
{
|
||||
return self::select('c_pais', 'descripcion')
|
||||
->get()
|
||||
->mapWithKeys(function ($item) {
|
||||
return [$item->c_pais => $item->c_pais . ' - ' . $item->descripcion];
|
||||
});
|
||||
}
|
||||
}
|
37
src/modules/App/Models/Sat/Percepcion.php
Normal file
37
src/modules/App/Models/Sat/Percepcion.php
Normal file
@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Percepcion extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_percepcion';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_percepcion',
|
||||
'descripcion',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
}
|
21
src/modules/App/Models/Sat/Periodicidad.php
Normal file
21
src/modules/App/Models/Sat/Periodicidad.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
class Periodicidad
|
||||
{
|
||||
// Definición de constantes para c_periodicidad
|
||||
const PERIODICIDAD_DIARIO = 1;
|
||||
const PERIODICIDAD_SEMANAL = 2;
|
||||
const PERIODICIDAD_QUINCENAL = 3;
|
||||
const PERIODICIDAD_MENSUAL = 4;
|
||||
const PERIODICIDAD_BIMESTRAL = 5;
|
||||
|
||||
public static $catalogo = [
|
||||
self::PERIODICIDAD_DIARIO => 'Diario',
|
||||
self::PERIODICIDAD_SEMANAL => 'Semanal',
|
||||
self::PERIODICIDAD_QUINCENAL => 'Quincenal',
|
||||
self::PERIODICIDAD_MENSUAL => 'Mensual',
|
||||
self::PERIODICIDAD_BIMESTRAL => 'Bimestral',
|
||||
];
|
||||
}
|
33
src/modules/App/Models/Sat/PeriodicidadPago.php
Normal file
33
src/modules/App/Models/Sat/PeriodicidadPago.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
class PeriodicidadPago
|
||||
{
|
||||
// Definición de constantes para Tipos de Periodicidad de Pago
|
||||
const PERIODICIDAD_DIARIO = 1;
|
||||
const PERIODICIDAD_SEMANAL = 2;
|
||||
const PERIODICIDAD_CATORCENAL = 3;
|
||||
const PERIODICIDAD_QUINCENAL = 4;
|
||||
const PERIODICIDAD_MENSUAL = 5;
|
||||
const PERIODICIDAD_BIMESTRAL = 6;
|
||||
const PERIODICIDAD_UNIDAD_OBRA = 7;
|
||||
const PERIODICIDAD_COMISION = 8;
|
||||
const PERIODICIDAD_PRECIO_ALZADO = 9;
|
||||
const PERIODICIDAD_DECENAL = 10;
|
||||
const PERIODICIDAD_OTRA = 99;
|
||||
|
||||
public static $tipoPeriodicidad = [
|
||||
self::PERIODICIDAD_DIARIO => 'Diario',
|
||||
self::PERIODICIDAD_SEMANAL => 'Semanal',
|
||||
self::PERIODICIDAD_CATORCENAL => 'Catorcenal',
|
||||
self::PERIODICIDAD_QUINCENAL => 'Quincenal',
|
||||
self::PERIODICIDAD_MENSUAL => 'Mensual',
|
||||
self::PERIODICIDAD_BIMESTRAL => 'Bimestral',
|
||||
self::PERIODICIDAD_UNIDAD_OBRA => 'Unidad obra',
|
||||
self::PERIODICIDAD_COMISION => 'Comisión',
|
||||
self::PERIODICIDAD_PRECIO_ALZADO => 'Precio alzado',
|
||||
self::PERIODICIDAD_DECENAL => 'Decenal',
|
||||
self::PERIODICIDAD_OTRA => 'Otra Periodicidad'
|
||||
];
|
||||
}
|
46
src/modules/App/Models/Sat/RegimenFiscal.php
Normal file
46
src/modules/App/Models/Sat/RegimenFiscal.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class RegimenFiscal extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_regimen_fiscal';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_regimen_fiscal',
|
||||
'descripcion',
|
||||
'fisica',
|
||||
'moral',
|
||||
'fecha_de_inicio_de_vigencia',
|
||||
'fecha_de_fin_de_vigencia',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_de_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_de_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
|
||||
public static function selectList()
|
||||
{
|
||||
return self::selectRaw('c_regimen_fiscal, CONCAT(c_regimen_fiscal, " - ", descripcion) as value')
|
||||
->pluck('value', 'c_regimen_fiscal');
|
||||
}
|
||||
}
|
21
src/modules/App/Models/Sat/TipoComprobante.php
Normal file
21
src/modules/App/Models/Sat/TipoComprobante.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
class TipoComprobante
|
||||
{
|
||||
// Definición de constantes para c_tipo_de_comprobante
|
||||
const TIPO_COMPROBANTE_INGRESO = 'I';
|
||||
const TIPO_COMPROBANTE_EGRESO = 'E';
|
||||
const TIPO_COMPROBANTE_TRASLADO = 'T';
|
||||
const TIPO_COMPROBANTE_NOMINA = 'N';
|
||||
const TIPO_COMPROBANTE_PAGO = 'P';
|
||||
|
||||
public static $catalogo = [
|
||||
self::TIPO_COMPROBANTE_INGRESO => 'Ingreso',
|
||||
self::TIPO_COMPROBANTE_EGRESO => 'Egreso',
|
||||
self::TIPO_COMPROBANTE_TRASLADO => 'Traslado',
|
||||
self::TIPO_COMPROBANTE_NOMINA => 'Nómina',
|
||||
self::TIPO_COMPROBANTE_PAGO => 'Pago',
|
||||
];
|
||||
}
|
17
src/modules/App/Models/Sat/TipoFactor.php
Normal file
17
src/modules/App/Models/Sat/TipoFactor.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
class TipoFactor
|
||||
{
|
||||
// Definición de constantes para c_tipo_factor
|
||||
const TIPO_FACTOR_TASA = 1;
|
||||
const TIPO_FACTOR_CUOTA = 2;
|
||||
const TIPO_FACTOR_EXENTO = 3;
|
||||
|
||||
public static $catalogo = [
|
||||
self::TIPO_FACTOR_TASA => 'Tasa',
|
||||
self::TIPO_FACTOR_CUOTA => 'Cuota',
|
||||
self::TIPO_FACTOR_EXENTO => 'Exento',
|
||||
];
|
||||
}
|
25
src/modules/App/Models/Sat/TipoRelacion.php
Normal file
25
src/modules/App/Models/Sat/TipoRelacion.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
class TipoRelacion
|
||||
{
|
||||
// Definición de constantes para c_tipo_relacion
|
||||
const TIPO_RELACION_NOTA_CREDITO = 1;
|
||||
const TIPO_RELACION_NOTA_DEBITO = 2;
|
||||
const TIPO_RELACION_DEVOLUCION_MERCANCIA = 3;
|
||||
const TIPO_RELACION_SUSTITUCION_CFDI = 4;
|
||||
const TIPO_RELACION_TRASLADOS_FACTURADOS = 5;
|
||||
const TIPO_RELACION_FACTURA_TRASLADOS = 6;
|
||||
const TIPO_RELACION_CFDI_ANTICIPO = 7;
|
||||
|
||||
public static $catalogo = [
|
||||
self::TIPO_RELACION_NOTA_CREDITO => 'Nota de crédito de los documentos relacionados',
|
||||
self::TIPO_RELACION_NOTA_DEBITO => 'Nota de débito de los documentos relacionados',
|
||||
self::TIPO_RELACION_DEVOLUCION_MERCANCIA => 'Devolución de mercancía sobre facturas o traslados previos',
|
||||
self::TIPO_RELACION_SUSTITUCION_CFDI => 'Sustitución de los CFDI previos',
|
||||
self::TIPO_RELACION_TRASLADOS_FACTURADOS => 'Traslados de mercancías facturados previamente',
|
||||
self::TIPO_RELACION_FACTURA_TRASLADOS => 'Factura generada por los traslados previos',
|
||||
self::TIPO_RELACION_CFDI_ANTICIPO => 'CFDI por aplicación de anticipo',
|
||||
];
|
||||
}
|
47
src/modules/App/Models/Sat/UsoCfdi.php
Normal file
47
src/modules/App/Models/Sat/UsoCfdi.php
Normal file
@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models\Sat;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class UsoCfdi extends Model
|
||||
{
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'sat_uso_cfdi';
|
||||
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
'c_uso_cfdi',
|
||||
'descripcion',
|
||||
'aplica_para_tipo_persona_fisica',
|
||||
'aplica_para_tipo_persona_moral',
|
||||
'fecha_inicio_de_vigencia',
|
||||
'fecha_fin_de_vigencia',
|
||||
'regimen_fiscal_receptor',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'fecha_inicio_de_vigencia' => 'datetime',
|
||||
'fecha_fin_de_vigencia' => 'datetime',
|
||||
];
|
||||
|
||||
public static function selectList()
|
||||
{
|
||||
return self::selectRaw('c_uso_cfdi, CONCAT(c_uso_cfdi, " - ", descripcion) as value')
|
||||
->pluck('value', 'c_uso_cfdi');
|
||||
}
|
||||
}
|
39
src/modules/App/Models/Setting.php
Normal file
39
src/modules/App/Models/Setting.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Setting extends Model
|
||||
{
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'key',
|
||||
'value',
|
||||
'user_id',
|
||||
];
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
// Relación con el usuario
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
// Scope para obtener configuraciones de un usuario específico
|
||||
public function scopeForUser($query, $userId)
|
||||
{
|
||||
return $query->where('user_id', $userId);
|
||||
}
|
||||
|
||||
// Configuraciones globales (sin usuario)
|
||||
public function scopeGlobal($query)
|
||||
{
|
||||
return $query->whereNull('user_id');
|
||||
}
|
||||
}
|
392
src/modules/App/Models/User.php
Normal file
392
src/modules/App/Models/User.php
Normal file
@ -0,0 +1,392 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Intervention\Image\Typography\FontFactory;
|
||||
use Laravel\Fortify\TwoFactorAuthenticatable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
use OwenIt\Auditing\Contracts\Auditable as AuditableContract;
|
||||
use OwenIt\Auditing\Auditable;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
use Modules\Admin\App\Models\Sat\CodigoPostal;
|
||||
use Modules\Admin\App\Models\Sat\RegimenFiscal;
|
||||
use Modules\Admin\App\Models\Sat\UsoCfdi;
|
||||
use Modules\Admin\App\Notifications\CustomResetPasswordNotification;
|
||||
|
||||
class User extends Authenticatable implements MustVerifyEmail, AuditableContract
|
||||
{
|
||||
use HasRoles,
|
||||
HasApiTokens,
|
||||
HasFactory,
|
||||
Notifiable,
|
||||
TwoFactorAuthenticatable,
|
||||
Auditable;
|
||||
|
||||
// the list of status values that can be stored in table
|
||||
const STATUS_ENABLED = 10;
|
||||
const STATUS_DISABLED = 1;
|
||||
const STATUS_REMOVED = 0;
|
||||
|
||||
const AVATAR_DISK = 'public';
|
||||
const PROFILE_PHOTO_DIR = 'profile-photos/';
|
||||
const INITIAL_AVATAR_DIR = 'initial-avatars/';
|
||||
const INITIAL_MAX_LENGTH = 4;
|
||||
|
||||
const AVATAR_WIDTH = 512;
|
||||
const AVATAR_HEIGHT = 512;
|
||||
const AVATAR_BACKGROUND = '#EBF4FF'; // Fondo por defecto
|
||||
const AVATAR_COLORS = [
|
||||
'#7367f0',
|
||||
'#808390',
|
||||
'#28c76f',
|
||||
'#ff4c51',
|
||||
'#ff9f43',
|
||||
'#00bad1',
|
||||
'#4b4b4b',
|
||||
];
|
||||
|
||||
/**
|
||||
* List of names for each status.
|
||||
* @var array
|
||||
*/
|
||||
public static $statusList = [
|
||||
self::STATUS_ENABLED => 'Habilitado',
|
||||
self::STATUS_DISABLED => 'Deshabilitado',
|
||||
self::STATUS_REMOVED => 'Eliminado',
|
||||
];
|
||||
|
||||
/**
|
||||
* List of names for each status.
|
||||
* @var array
|
||||
*/
|
||||
public static $statusListClass = [
|
||||
self::STATUS_ENABLED => 'success',
|
||||
self::STATUS_DISABLED => 'warning',
|
||||
self::STATUS_REMOVED => 'danger',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'contact_code',
|
||||
'name',
|
||||
'last_name',
|
||||
'email',
|
||||
'password',
|
||||
'profile_photo_path',
|
||||
'company',
|
||||
'birth_date',
|
||||
'hire_date',
|
||||
'curp',
|
||||
'nss',
|
||||
'job_title',
|
||||
'face_vector',
|
||||
'rfc',
|
||||
'nombre_fiscal',
|
||||
'tipo_persona',
|
||||
'c_regimen_fiscal',
|
||||
'domicilio_fiscal',
|
||||
'c_uso_cfdi',
|
||||
'is_partner',
|
||||
'is_employee',
|
||||
'is_prospect',
|
||||
'is_customer',
|
||||
'is_provider',
|
||||
'is_user',
|
||||
'status',
|
||||
'created_by',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
'two_factor_recovery_codes',
|
||||
'two_factor_secret',
|
||||
];
|
||||
|
||||
/**
|
||||
* The accessors to append to the model's array form.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $appends = [
|
||||
'profile_photo_url',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
'face_vector' => 'array',
|
||||
'birth_date' => 'date',
|
||||
'hire_date' => 'date',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attributes to include in the Audit.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $auditInclude = [
|
||||
'name',
|
||||
'email',
|
||||
];
|
||||
|
||||
|
||||
public function updateProfilePhoto(UploadedFile $image_avatar)
|
||||
{
|
||||
try {
|
||||
// Verificar si el archivo existe
|
||||
if (!file_exists($image_avatar->getRealPath()))
|
||||
throw new \Exception('El archivo no existe en la ruta especificada.');
|
||||
|
||||
if (!in_array($image_avatar->getClientOriginalExtension(), ['jpg', 'jpeg', 'png']))
|
||||
throw new \Exception('El formato del archivo debe ser JPG o PNG.');
|
||||
|
||||
// Directorio donde se guardarán los avatares
|
||||
$avatarDisk = self::AVATAR_DISK;
|
||||
$avatarPath = self::PROFILE_PHOTO_DIR;
|
||||
$avatarName = uniqid('avatar_') . '.png'; // Nombre único para el avatar
|
||||
|
||||
// Crear la instancia de ImageManager
|
||||
$driver = config('image.driver', 'gd');
|
||||
$manager = new ImageManager($driver);
|
||||
|
||||
// Crear el directorio si no existe
|
||||
if (!Storage::disk($avatarDisk)->exists($avatarPath))
|
||||
Storage::disk($avatarDisk)->makeDirectory($avatarPath);
|
||||
|
||||
// Leer la imagen
|
||||
$image = $manager->read($image_avatar->getRealPath());
|
||||
|
||||
// crop the best fitting 5:3 (600x360) ratio and resize to 600x360 pixel
|
||||
$image->cover(self::AVATAR_WIDTH, self::AVATAR_HEIGHT);
|
||||
|
||||
// Guardar la imagen en el disco de almacenamiento gestionado por Laravel
|
||||
Storage::disk($avatarDisk)->put($avatarPath . $avatarName, $image->toPng(indexed: true));
|
||||
|
||||
// Elimina el avatar existente si hay uno
|
||||
$this->deleteProfilePhoto();
|
||||
|
||||
// Update the user's profile photo path
|
||||
$this->forceFill([
|
||||
'profile_photo_path' => $avatarName,
|
||||
])->save();
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception('Ocurrió un error al actualizar el avatar. ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteProfilePhoto()
|
||||
{
|
||||
if (!empty($this->profile_photo_path)) {
|
||||
$avatarDisk = self::AVATAR_DISK;
|
||||
|
||||
Storage::disk($avatarDisk)->delete($this->profile_photo_path);
|
||||
|
||||
$this->forceFill([
|
||||
'profile_photo_path' => null,
|
||||
])->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function getAvatarColor()
|
||||
{
|
||||
// Selecciona un color basado en el id del usuario
|
||||
return self::AVATAR_COLORS[$this->id % count(self::AVATAR_COLORS)];
|
||||
}
|
||||
|
||||
|
||||
public static function getAvatarImage($name, $color, $background, $size)
|
||||
{
|
||||
$avatarDisk = self::AVATAR_DISK;
|
||||
$directory = self::INITIAL_AVATAR_DIR;
|
||||
$initials = self::getInitials($name);
|
||||
|
||||
$cacheKey = "avatar-{$initials}-{$color}-{$background}-{$size}";
|
||||
$path = "{$directory}/{$cacheKey}.png";
|
||||
$storagePath = storage_path("app/public/{$path}");
|
||||
|
||||
// Verificar si el avatar ya está en caché
|
||||
if (Storage::disk($avatarDisk)->exists($path))
|
||||
return response()->file($storagePath);
|
||||
|
||||
// Crear el avatar
|
||||
$image = self::createAvatarImage($name, $color, $background, $size);
|
||||
|
||||
// Guardar en el directorio de iniciales
|
||||
Storage::disk($avatarDisk)->put($path, $image->toPng(indexed: true));
|
||||
|
||||
// Retornar la imagen directamente
|
||||
return response()->file($storagePath);
|
||||
}
|
||||
|
||||
private static function createAvatarImage($name, $color, $background, $size)
|
||||
{
|
||||
// Usar la configuración del driver de imagen
|
||||
$driver = config('image.driver', 'gd');
|
||||
$manager = new ImageManager($driver);
|
||||
|
||||
$initials = self::getInitials($name);
|
||||
|
||||
// Crear la imagen con fondo
|
||||
$image = $manager->create($size, $size)
|
||||
->fill($background);
|
||||
|
||||
// Escribir texto en la imagen
|
||||
$image->text(
|
||||
$initials,
|
||||
$size / 2, // Centrar horizontalmente
|
||||
$size / 2, // Centrar verticalmente
|
||||
function (FontFactory $font) use ($color, $size) {
|
||||
$font->file(base_path('/modules/Admin/Resources/assets/vendor/fonts/OpenSans/static/OpenSans-Bold.ttf'));
|
||||
$font->size($size * 0.4);
|
||||
$font->color($color);
|
||||
$font->align('center');
|
||||
$font->valign('middle');
|
||||
}
|
||||
);
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
public static function getInitials($name)
|
||||
{
|
||||
// Manejar casos de nombres vacíos o nulos
|
||||
if (empty($name))
|
||||
return 'NA';
|
||||
|
||||
// Usar array_map para mayor eficiencia
|
||||
$initials = implode('', array_map(function ($word) {
|
||||
return mb_substr($word, 0, 1);
|
||||
}, explode(' ', $name)));
|
||||
|
||||
$initials = substr($initials, 0, self::INITIAL_MAX_LENGTH);
|
||||
|
||||
return strtoupper($initials);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function getProfilePhotoUrlAttribute()
|
||||
{
|
||||
if ($this->profile_photo_path)
|
||||
return Storage::url(self::PROFILE_PHOTO_DIR . '/' . $this->profile_photo_path);
|
||||
|
||||
// Generar URL del avatar por iniciales
|
||||
$name = urlencode($this->fullname);
|
||||
$color = ltrim($this->getAvatarColor(), '#');
|
||||
$background = ltrim(self::AVATAR_BACKGROUND, '#');
|
||||
$size = (self::AVATAR_WIDTH + self::AVATAR_HEIGHT) / 2;
|
||||
|
||||
return url("/admin/usuario/avatar?name={$name}&color={$color}&background={$background}&size={$size}");
|
||||
}
|
||||
|
||||
public function getFullnameAttribute()
|
||||
{
|
||||
return trim($this->name . ' ' . $this->last_name);
|
||||
}
|
||||
|
||||
public function getInitialsAttribute()
|
||||
{
|
||||
return self::getInitials($this->fullname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Envía la notificación de restablecimiento de contraseña.
|
||||
*
|
||||
* @param string $token
|
||||
*/
|
||||
public function sendPasswordResetNotification($token)
|
||||
{
|
||||
// Usar la notificación personalizada
|
||||
$this->notify(new CustomResetPasswordNotification($token));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Relations
|
||||
*/
|
||||
|
||||
// User who created this user
|
||||
public function creator()
|
||||
{
|
||||
return $this->belongsTo(self::class, 'created_by');
|
||||
}
|
||||
|
||||
// Regimen fiscal
|
||||
public function regimenFiscal()
|
||||
{
|
||||
return $this->belongsTo(RegimenFiscal::class, 'c_regimen_fiscal', 'c_regimen_fiscal');
|
||||
}
|
||||
|
||||
// Domicilio fiscal
|
||||
public function domicilioFiscal()
|
||||
{
|
||||
return $this->belongsTo(CodigoPostal::class, 'domicilio_fiscal', 'c_codigo_postal');
|
||||
}
|
||||
|
||||
// Uso de CFDI
|
||||
public function usoCfdi()
|
||||
{
|
||||
return $this->belongsTo(UsoCfdi::class, 'c_uso_cfdi', 'c_uso_cfdi');
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper methods
|
||||
*/
|
||||
|
||||
public function isActive()
|
||||
{
|
||||
return $this->status === 1;
|
||||
}
|
||||
|
||||
public function isPartner()
|
||||
{
|
||||
return $this->is_partner === 1;
|
||||
}
|
||||
|
||||
public function isEmployee()
|
||||
{
|
||||
return $this->is_employee === 1;
|
||||
}
|
||||
|
||||
public function isCustomer()
|
||||
{
|
||||
return $this->is_customer === 1;
|
||||
}
|
||||
|
||||
public function isProvider()
|
||||
{
|
||||
return $this->is_provider === 1;
|
||||
}
|
||||
}
|
14
src/modules/App/Models/UserLogin.php
Normal file
14
src/modules/App/Models/UserLogin.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class UserLogin extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'ip_address',
|
||||
'user_agent'
|
||||
];
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Notifications;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Modules\Admin\App\Models\Setting;
|
||||
|
||||
class CustomResetPasswordNotification extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
public $token;
|
||||
|
||||
/**
|
||||
* Crea una nueva instancia de notificación.
|
||||
*/
|
||||
public function __construct($token)
|
||||
{
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configura el canal de la notificación.
|
||||
*/
|
||||
public function via($notifiable)
|
||||
{
|
||||
return ['mail'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configura el mensaje de correo.
|
||||
*/
|
||||
public function toMail($notifiable)
|
||||
{
|
||||
try {
|
||||
// Cargar configuración SMTP desde la base de datos
|
||||
$this->loadDynamicMailConfig();
|
||||
|
||||
$resetUrl = url(route('password.reset', [
|
||||
'token' => $this->token,
|
||||
'email' => $notifiable->getEmailForPasswordReset()
|
||||
], false));
|
||||
|
||||
$appTitle = Setting::global()->where('key', 'website_title')->first()->value ?? Config::get('_var.appTitle');
|
||||
$imageBase64 = 'data:image/png;base64,' . base64_encode(file_get_contents(public_path('/assets/img/logo/koneko-04.png')));
|
||||
$expireMinutes = Config::get('auth.passwords.' . Config::get('auth.defaults.passwords') . '.expire', 60);
|
||||
|
||||
Config::set('app.name', $appTitle);
|
||||
|
||||
return (new MailMessage)
|
||||
->subject("Restablece tu contraseña - {$appTitle}")
|
||||
->markdown('admin::notifications.email', [ // Usar tu plantilla del módulo
|
||||
'greeting' => "Hola {$notifiable->name}",
|
||||
'introLines' => [
|
||||
'Estás recibiendo este correo porque solicitaste restablecer tu contraseña.',
|
||||
],
|
||||
'actionText' => 'Restablecer contraseña',
|
||||
'actionUrl' => $resetUrl,
|
||||
'outroLines' => [
|
||||
"Este enlace expirará en {$expireMinutes} minutos.",
|
||||
'Si no solicitaste este cambio, no se requiere realizar ninguna acción.',
|
||||
],
|
||||
'displayableActionUrl' => $resetUrl, // Para el subcopy
|
||||
'image' => $imageBase64, // Imagen del logo
|
||||
]);
|
||||
|
||||
/*
|
||||
*/
|
||||
} catch (\Exception $e) {
|
||||
// Registrar el error
|
||||
Log::error('Error al enviar el correo de restablecimiento: ' . $e->getMessage());
|
||||
|
||||
// Retornar un mensaje alternativo
|
||||
return (new MailMessage)
|
||||
->subject('Restablece tu contraseña')
|
||||
->line('Ocurrió un error al enviar el correo. Por favor, intenta de nuevo más tarde.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cargar configuración SMTP desde la base de datos.
|
||||
*/
|
||||
protected function loadDynamicMailConfig()
|
||||
{
|
||||
try {
|
||||
$smtpConfig = Setting::where('key', 'LIKE', 'mail_%')
|
||||
->pluck('value', 'key');
|
||||
|
||||
if ($smtpConfig->isEmpty()) {
|
||||
throw new Exception('No SMTP configuration found in the database.');
|
||||
}
|
||||
|
||||
Config::set('mail.mailers.smtp.host', $smtpConfig['mail_mailers_smtp_host'] ?? null);
|
||||
Config::set('mail.mailers.smtp.port', $smtpConfig['mail_mailers_smtp_port'] ?? null);
|
||||
Config::set('mail.mailers.smtp.username', $smtpConfig['mail_mailers_smtp_username'] ?? null);
|
||||
Config::set(
|
||||
'mail.mailers.smtp.password',
|
||||
isset($smtpConfig['mail_mailers_smtp_password'])
|
||||
? Crypt::decryptString($smtpConfig['mail_mailers_smtp_password'])
|
||||
: null
|
||||
);
|
||||
Config::set('mail.mailers.smtp.encryption', $smtpConfig['mail_mailers_smtp_encryption'] ?? null);
|
||||
Config::set('mail.from.address', $smtpConfig['mail_from_address'] ?? null);
|
||||
Config::set('mail.from.name', $smtpConfig['mail_from_name'] ?? null);
|
||||
} catch (Exception $e) {
|
||||
Log::error('SMTP Configuration Error: ' . $e->getMessage());
|
||||
// Opcional: Puedes lanzar la excepción o manejarla de otra manera.
|
||||
throw new Exception('Error al cargar la configuración SMTP.');
|
||||
}
|
||||
}
|
||||
}
|
124
src/modules/App/Providers/FortifyServiceProvider.php
Normal file
124
src/modules/App/Providers/FortifyServiceProvider.php
Normal file
@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Str;
|
||||
use Laravel\Fortify\Fortify;
|
||||
use Modules\Admin\App\Actions\Fortify\CreateNewUser;
|
||||
use Modules\Admin\App\Actions\Fortify\ResetUserPassword;
|
||||
use Modules\Admin\App\Actions\Fortify\UpdateUserPassword;
|
||||
use Modules\Admin\App\Actions\Fortify\UpdateUserProfileInformation;
|
||||
use Modules\Admin\App\Models\User;
|
||||
use Modules\Admin\App\Services\AdminTemplateService;
|
||||
|
||||
class FortifyServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
Fortify::createUsersUsing(CreateNewUser::class);
|
||||
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
|
||||
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
|
||||
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
|
||||
|
||||
RateLimiter::for('login', function (Request $request) {
|
||||
$throttleKey = Str::transliterate(Str::lower($request->input(Fortify::username())) . '|' . $request->ip());
|
||||
|
||||
return Limit::perMinute(5)->by($throttleKey);
|
||||
});
|
||||
|
||||
RateLimiter::for('two-factor', function (Request $request) {
|
||||
return Limit::perMinute(5)->by($request->session()->get('login.id'));
|
||||
});
|
||||
|
||||
Fortify::authenticateUsing(function (Request $request) {
|
||||
$user = User::where('email', $request->email)
|
||||
->where('status', User::STATUS_ENABLED)
|
||||
->first();
|
||||
|
||||
if ($user && Hash::check($request->password, $user->password)) {
|
||||
return $user;
|
||||
}
|
||||
});
|
||||
|
||||
// Simula lo que hace tu middleware y comparte `_admin`
|
||||
$viewMode = Config::get('custom.custom.authViewMode');
|
||||
$adminVars = app(AdminTemplateService::class)->getAdminVars();
|
||||
|
||||
// Configurar la vista del login
|
||||
Fortify::loginView(function () use ($viewMode, $adminVars) {
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
view()->share('_admin', $adminVars);
|
||||
|
||||
return view("admin::auth.login-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
});
|
||||
|
||||
// Configurar la vista del registro (si lo necesitas)
|
||||
Fortify::registerView(function () use ($viewMode, $adminVars) {
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
view()->share('_admin', $adminVars);
|
||||
|
||||
return view("admin::auth.register-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
});
|
||||
|
||||
// Configurar la vista de restablecimiento de contraseñas
|
||||
Fortify::requestPasswordResetLinkView(function () use ($viewMode, $adminVars) {
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
view()->share('_admin', $adminVars);
|
||||
|
||||
return view("admin::auth.forgot-password-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
});
|
||||
|
||||
Fortify::resetPasswordView(function ($request) use ($viewMode, $adminVars) {
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
view()->share('_admin', $adminVars);
|
||||
|
||||
return view("admin::auth.reset-password-{$viewMode}", ['pageConfigs' => $pageConfigs, 'request' => $request]);
|
||||
});
|
||||
|
||||
// Vista de verificación de correo electrónico
|
||||
Fortify::verifyEmailView(function () use ($viewMode, $adminVars) {
|
||||
view()->share('_admin', $adminVars);
|
||||
|
||||
return view("admin::auth.verify-email-{$viewMode}");
|
||||
});
|
||||
|
||||
// Vista de confirmación de contraseña
|
||||
Fortify::confirmPasswordView(function () use ($viewMode, $adminVars) {
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
view()->share('_admin', $adminVars);
|
||||
|
||||
return view("admin::auth.confirm-password-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
});
|
||||
|
||||
// Configurar la vista para la verificación de dos factores
|
||||
Fortify::twoFactorChallengeView(function () use ($viewMode, $adminVars) {
|
||||
$pageConfigs = ['myLayout' => 'blank'];
|
||||
|
||||
view()->share('_admin', $adminVars);
|
||||
|
||||
return view("admin::auth.two-factor-challenge-{$viewMode}", ['pageConfigs' => $pageConfigs]);
|
||||
});
|
||||
}
|
||||
}
|
27
src/modules/App/Providers/GlobalSettingsProvider.php
Normal file
27
src/modules/App/Providers/GlobalSettingsProvider.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Admin\App\Services\GlobalSettingsService;
|
||||
|
||||
class GlobalSettingsProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->mergeConfigFrom(__DIR__ . '/../../Config/_var.php', '_var');
|
||||
$this->mergeConfigFrom(__DIR__ . '/../../Config/custom.php', 'custom');
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap services.
|
||||
*/
|
||||
public function boot(GlobalSettingsService $globalSettingsService): void
|
||||
{
|
||||
$globalSettingsService->loadSystemConfig();
|
||||
}
|
||||
}
|
39
src/modules/App/Providers/VuexyAdminProvider.php
Normal file
39
src/modules/App/Providers/VuexyAdminProvider.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Foundation\AliasLoader;
|
||||
use Modules\Admin\App\Console\Commands\CleanInitialAvatars;
|
||||
use Modules\Admin\App\Http\View\Composers\VuexyTemplateComposer;
|
||||
|
||||
class VuexyAdminProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
// Register the module's aliases
|
||||
AliasLoader::getInstance()->alias('Helper', \Modules\Admin\App\Helpers\Helpers::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
// Register any module-specific event listeners here
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->commands([
|
||||
CleanInitialAvatars::class,
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Composer para las vistas del módulo Admin
|
||||
View::composer('admin::layouts.vuexy.*', VuexyTemplateComposer::class);
|
||||
}
|
||||
}
|
20
src/modules/App/Rules/NotEmptyHtml.php
Normal file
20
src/modules/App/Rules/NotEmptyHtml.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Rules;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
|
||||
class NotEmptyHtml implements ValidationRule
|
||||
{
|
||||
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||
{
|
||||
// Eliminar etiquetas HTML y espacios en blanco
|
||||
$strippedContent = trim(strip_tags($value));
|
||||
|
||||
// Considerar vacío si no queda contenido significativo
|
||||
if (empty($strippedContent)) {
|
||||
$fail('El contenido no puede estar vacío.');
|
||||
}
|
||||
}
|
||||
}
|
215
src/modules/App/Services/AdminSettingsService.php
Normal file
215
src/modules/App/Services/AdminSettingsService.php
Normal file
@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Modules\Admin\App\Models\Setting;
|
||||
|
||||
class AdminSettingsService
|
||||
{
|
||||
private $driver;
|
||||
private $imageDisk = 'public';
|
||||
private $favicon_basePath = 'favicon/';
|
||||
private $image_logo_basePath = 'images/logo/';
|
||||
|
||||
private $faviconsSizes = [
|
||||
'180x180' => [180, 180],
|
||||
'192x192' => [192, 192],
|
||||
'152x152' => [152, 152],
|
||||
'120x120' => [120, 120],
|
||||
'76x76' => [76, 76],
|
||||
'16x16' => [16, 16],
|
||||
];
|
||||
|
||||
private $imageLogoMaxPixels1 = 22500; // Primera versión (px^2)
|
||||
private $imageLogoMaxPixels2 = 75625; // Segunda versión (px^2)
|
||||
private $imageLogoMaxPixels3 = 262144; // Tercera versión (px^2)
|
||||
private $imageLogoMaxPixels4 = 230400; // Tercera versión (px^2) en Base64
|
||||
|
||||
protected $cacheTTL = 60 * 24 * 30; // 30 días en minutos
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->driver = config('image.driver', 'gd');
|
||||
}
|
||||
|
||||
public function updateSetting(string $key, string $value): bool
|
||||
{
|
||||
$setting = Setting::updateOrCreate(
|
||||
['key' => $key],
|
||||
['value' => trim($value)]
|
||||
);
|
||||
|
||||
return $setting->save();
|
||||
}
|
||||
|
||||
public function processAndSaveFavicon($image): void
|
||||
{
|
||||
Storage::makeDirectory($this->imageDisk . '/' . $this->favicon_basePath);
|
||||
|
||||
// Eliminar favicons antiguos
|
||||
$this->deleteOldFavicons();
|
||||
|
||||
// Guardar imagen original
|
||||
$imageManager = new ImageManager($this->driver);
|
||||
|
||||
$imageName = uniqid('admin_favicon_');
|
||||
|
||||
$image = $imageManager->read($image->getRealPath());
|
||||
|
||||
foreach ($this->faviconsSizes as $size => [$width, $height]) {
|
||||
$resizedPath = $this->favicon_basePath . $imageName . "_{$size}.png";
|
||||
|
||||
$image->cover($width, $height);
|
||||
|
||||
Storage::disk($this->imageDisk)->put($resizedPath, $image->toPng(indexed: true));
|
||||
}
|
||||
|
||||
$this->updateSetting('admin_favicon_ns', $this->favicon_basePath . $imageName);
|
||||
}
|
||||
|
||||
protected function deleteOldFavicons(): void
|
||||
{
|
||||
// Obtener el favicon actual desde la base de datos
|
||||
$currentFavicon = Setting::where('key', 'admin_favicon_ns')->value('value');
|
||||
|
||||
if ($currentFavicon) {
|
||||
$filePaths = [
|
||||
$this->imageDisk . '/' . $currentFavicon,
|
||||
$this->imageDisk . '/' . $currentFavicon . '_16x16.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_76x76.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_120x120.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_152x152.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_180x180.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_192x192.png',
|
||||
];
|
||||
|
||||
foreach ($filePaths as $filePath) {
|
||||
if (Storage::exists($filePath)) {
|
||||
Storage::delete($filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function processAndSaveImageLogo($image, string $type = ''): void
|
||||
{
|
||||
// Crear directorio si no existe
|
||||
Storage::makeDirectory($this->imageDisk . '/' . $this->image_logo_basePath);
|
||||
|
||||
// Eliminar imágenes antiguas
|
||||
$this->deleteOldImageWebapp($type);
|
||||
|
||||
// Leer imagen original
|
||||
$imageManager = new ImageManager($this->driver);
|
||||
$image = $imageManager->read($image->getRealPath());
|
||||
|
||||
// Generar tres versiones con diferentes áreas máximas
|
||||
$this->generateAndSaveImage($image, $type, $this->imageLogoMaxPixels1, 'small'); // Versión 1
|
||||
$this->generateAndSaveImage($image, $type, $this->imageLogoMaxPixels2, 'medium'); // Versión 2
|
||||
$this->generateAndSaveImage($image, $type, $this->imageLogoMaxPixels3); // Versión 3
|
||||
$this->generateAndSaveImageAsBase64($image, $type, $this->imageLogoMaxPixels4); // Versión 3
|
||||
}
|
||||
|
||||
private function generateAndSaveImage($image, string $type, int $maxPixels, string $suffix = ''): void
|
||||
{
|
||||
$imageClone = clone $image;
|
||||
|
||||
// Escalar imagen conservando aspecto
|
||||
$this->resizeImageToMaxPixels($imageClone, $maxPixels);
|
||||
|
||||
$imageName = 'admin_image_logo' . ($suffix ? '_' . $suffix : '') . ($type == 'dark' ? '_dark' : '');
|
||||
|
||||
// Generar nombre y ruta
|
||||
$imageNameUid = uniqid($imageName . '_', ".png");
|
||||
$resizedPath = $this->image_logo_basePath . $imageNameUid;
|
||||
|
||||
// Guardar imagen en PNG
|
||||
Storage::disk($this->imageDisk)->put($resizedPath, $imageClone->toPng(indexed: true));
|
||||
|
||||
// Actualizar configuración
|
||||
$this->updateSetting($imageName, $resizedPath);
|
||||
}
|
||||
|
||||
private function resizeImageToMaxPixels($image, int $maxPixels)
|
||||
{
|
||||
// Obtener dimensiones originales de la imagen
|
||||
$originalWidth = $image->width(); // Método para obtener el ancho
|
||||
$originalHeight = $image->height(); // Método para obtener el alto
|
||||
|
||||
// Calcular el aspecto
|
||||
$aspectRatio = $originalWidth / $originalHeight;
|
||||
|
||||
// Calcular dimensiones redimensionadas conservando aspecto
|
||||
if ($aspectRatio > 1) { // Ancho es dominante
|
||||
$newWidth = sqrt($maxPixels * $aspectRatio);
|
||||
$newHeight = $newWidth / $aspectRatio;
|
||||
} else { // Alto es dominante
|
||||
$newHeight = sqrt($maxPixels / $aspectRatio);
|
||||
$newWidth = $newHeight * $aspectRatio;
|
||||
}
|
||||
|
||||
// Redimensionar la imagen
|
||||
$image->resize(
|
||||
round($newWidth), // Redondear para evitar problemas con números decimales
|
||||
round($newHeight),
|
||||
function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
}
|
||||
);
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
|
||||
private function generateAndSaveImageAsBase64($image, string $type, int $maxPixels): void
|
||||
{
|
||||
$imageClone = clone $image;
|
||||
|
||||
// Redimensionar imagen conservando el aspecto
|
||||
$this->resizeImageToMaxPixels($imageClone, $maxPixels);
|
||||
|
||||
// Convertir a Base64
|
||||
$base64Image = (string) $imageClone->toJpg(40)->toDataUri();
|
||||
|
||||
// Guardar como configuración
|
||||
$this->updateSetting(
|
||||
"admin_image_logo_base64" . ($type === 'dark' ? '_dark' : ''),
|
||||
$base64Image // Ya incluye "data:image/png;base64,"
|
||||
);
|
||||
}
|
||||
|
||||
protected function deleteOldImageWebapp(string $type = ''): void
|
||||
{
|
||||
// Determinar prefijo según el tipo (normal o dark)
|
||||
$suffix = $type === 'dark' ? '_dark' : '';
|
||||
|
||||
// Claves relacionadas con las imágenes que queremos limpiar
|
||||
$imageKeys = [
|
||||
"admin_image_logo{$suffix}",
|
||||
"admin_image_logo_small{$suffix}",
|
||||
"admin_image_logo_medium{$suffix}",
|
||||
];
|
||||
|
||||
// Recuperar las imágenes actuales en una sola consulta
|
||||
$settings = Setting::whereIn('key', $imageKeys)->pluck('value', 'key');
|
||||
|
||||
foreach ($imageKeys as $key) {
|
||||
// Obtener la imagen correspondiente
|
||||
$currentImage = $settings[$key] ?? null;
|
||||
|
||||
if ($currentImage) {
|
||||
// Construir la ruta del archivo y eliminarlo si existe
|
||||
$filePath = $this->imageDisk . '/' . $currentImage;
|
||||
if (Storage::exists($filePath)) {
|
||||
Storage::delete($filePath);
|
||||
}
|
||||
|
||||
// Eliminar la configuración de la base de datos
|
||||
Setting::where('key', $key)->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
156
src/modules/App/Services/AdminTemplateService.php
Normal file
156
src/modules/App/Services/AdminTemplateService.php
Normal file
@ -0,0 +1,156 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Modules\Admin\App\Models\Setting;
|
||||
|
||||
class AdminTemplateService
|
||||
{
|
||||
protected $cacheTTL = 60 * 24 * 30; // 30 días en minutos
|
||||
|
||||
public function updateSetting(string $key, string $value): bool
|
||||
{
|
||||
$setting = Setting::updateOrCreate(
|
||||
['key' => $key],
|
||||
['value' => trim($value)]
|
||||
);
|
||||
|
||||
return $setting->save();
|
||||
}
|
||||
|
||||
public function getAdminVars($adminSetting = false): array
|
||||
{
|
||||
try {
|
||||
// Verificar si el sistema está inicializado (la tabla `migrations` existe)
|
||||
if (!Schema::hasTable('migrations')) {
|
||||
return $this->getDefaultAdminVars($adminSetting);
|
||||
}
|
||||
|
||||
// Cargar desde el caché o la base de datos si está disponible
|
||||
return Cache::remember('admin_settings', $this->cacheTTL, function () use ($adminSetting) {
|
||||
$settings = Setting::global()
|
||||
->where('key', 'LIKE', 'admin_%')
|
||||
->pluck('value', 'key')
|
||||
->toArray();
|
||||
|
||||
$adminSettings = $this->buildAdminVarsArray($settings);
|
||||
|
||||
return $adminSetting
|
||||
? $adminSettings[$adminSetting]
|
||||
: $adminSettings;
|
||||
});
|
||||
} catch (\Exception $e) {
|
||||
// En caso de error, devolver valores predeterminados
|
||||
return $this->getDefaultAdminVars($adminSetting);
|
||||
}
|
||||
}
|
||||
|
||||
private function getDefaultAdminVars($adminSetting = false): array
|
||||
{
|
||||
$defaultSettings = [
|
||||
'title' => config('_var.appTitle', 'Default Title'),
|
||||
'author' => config('_var.author', 'Default Author'),
|
||||
'description' => config('_var.description', 'Default Description'),
|
||||
'favicon' => $this->getFaviconPaths([]),
|
||||
'app_name' => config('_var.appName', 'Default App Name'),
|
||||
'image_logo' => $this->getImageLogoPaths([]),
|
||||
];
|
||||
|
||||
return $adminSetting
|
||||
? $defaultSettings[$adminSetting] ?? null
|
||||
: $defaultSettings;
|
||||
}
|
||||
|
||||
private function buildAdminVarsArray(array $settings): array
|
||||
{
|
||||
return [
|
||||
'title' => $settings['admin_title'] ?? config('_var.appTitle'),
|
||||
'author' => config('_var.author'),
|
||||
'description' => config('_var.description'),
|
||||
'favicon' => $this->getFaviconPaths($settings),
|
||||
'app_name' => $settings['admin_app_name'] ?? config('_var.appName'),
|
||||
'image_logo' => $this->getImageLogoPaths($settings),
|
||||
];
|
||||
}
|
||||
|
||||
public function getVuexyCustomizerVars()
|
||||
{
|
||||
// Obtener valores de la base de datos
|
||||
$settings = Setting::global()
|
||||
->where('key', 'LIKE', 'vuexy_%')
|
||||
->pluck('value', 'key')
|
||||
->toArray();
|
||||
|
||||
// Obtener configuraciones predeterminadas
|
||||
$defaultConfig = Config::get('custom.custom', []);
|
||||
|
||||
// Mezclar las configuraciones predeterminadas con las de la base de datos
|
||||
return collect($defaultConfig)
|
||||
->mapWithKeys(function ($defaultValue, $key) use ($settings) {
|
||||
$vuexyKey = 'vuexy_' . $key; // Convertir clave al formato de la base de datos
|
||||
|
||||
// Obtener valor desde la base de datos o usar el predeterminado
|
||||
$value = $settings[$vuexyKey] ?? $defaultValue;
|
||||
|
||||
// Forzar booleanos para claves específicas
|
||||
if (in_array($key, ['displayCustomizer', 'footerFixed', 'menuFixed', 'menuCollapsed', 'showDropdownOnHover'])) {
|
||||
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
return [$key => $value];
|
||||
})
|
||||
->toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los paths de favicon en distintos tamaños.
|
||||
*/
|
||||
private function getFaviconPaths(array $settings): array
|
||||
{
|
||||
$defaultFavicon = config('_var.appFavicon');
|
||||
$namespace = $settings['admin_favicon_ns'] ?? null;
|
||||
|
||||
return [
|
||||
'namespace' => $namespace,
|
||||
'16x16' => $namespace ? "{$namespace}_16x16.png" : $defaultFavicon,
|
||||
'76x76' => $namespace ? "{$namespace}_76x76.png" : $defaultFavicon,
|
||||
'120x120' => $namespace ? "{$namespace}_120x120.png" : $defaultFavicon,
|
||||
'152x152' => $namespace ? "{$namespace}_152x152.png" : $defaultFavicon,
|
||||
'180x180' => $namespace ? "{$namespace}_180x180.png" : $defaultFavicon,
|
||||
'192x192' => $namespace ? "{$namespace}_192x192.png" : $defaultFavicon,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene los paths de los logos en distintos tamaños.
|
||||
*/
|
||||
private function getImageLogoPaths(array $settings): array
|
||||
{
|
||||
$defaultLogo = config('_var.appLogo');
|
||||
|
||||
return [
|
||||
'small' => $this->getImagePath($settings, 'admin_image_logo_small', $defaultLogo),
|
||||
'medium' => $this->getImagePath($settings, 'admin_image_logo_medium', $defaultLogo),
|
||||
'large' => $this->getImagePath($settings, 'admin_image_logo', $defaultLogo),
|
||||
'small_dark' => $this->getImagePath($settings, 'admin_image_logo_small_dark', $defaultLogo),
|
||||
'medium_dark' => $this->getImagePath($settings, 'admin_image_logo_medium_dark', $defaultLogo),
|
||||
'large_dark' => $this->getImagePath($settings, 'admin_image_logo_dark', $defaultLogo),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene un path de imagen o retorna un valor predeterminado.
|
||||
*/
|
||||
private function getImagePath(array $settings, string $key, string $default): string
|
||||
{
|
||||
return $settings[$key] ?? $default;
|
||||
}
|
||||
|
||||
public static function clearAdminVarsCache()
|
||||
{
|
||||
Cache::forget("admin_settings");
|
||||
}
|
||||
}
|
235
src/modules/App/Services/CacheConfigService.php
Normal file
235
src/modules/App/Services/CacheConfigService.php
Normal file
@ -0,0 +1,235 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
|
||||
class CacheConfigService
|
||||
{
|
||||
public function getConfig(): array
|
||||
{
|
||||
return [
|
||||
'cache' => $this->getCacheConfig(),
|
||||
'session' => $this->getSessionConfig(),
|
||||
'database' => $this->getDatabaseConfig(),
|
||||
'driver' => $this->getDriverVersion(),
|
||||
'memcachedInUse' => $this->isDriverInUse('memcached'),
|
||||
'redisInUse' => $this->isDriverInUse('redis'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
private function getCacheConfig(): array
|
||||
{
|
||||
$cacheConfig = Config::get('cache');
|
||||
$driver = $cacheConfig['default'];
|
||||
|
||||
switch ($driver) {
|
||||
case 'redis':
|
||||
$connection = config('database.redis.cache');
|
||||
$cacheConfig['host'] = $connection['host'] ?? 'localhost';
|
||||
$cacheConfig['database'] = $connection['database'] ?? 'N/A';
|
||||
break;
|
||||
|
||||
case 'database':
|
||||
$connection = config('database.connections.' . config('cache.stores.database.connection'));
|
||||
$cacheConfig['host'] = $connection['host'] ?? 'localhost';
|
||||
$cacheConfig['database'] = $connection['database'] ?? 'N/A';
|
||||
break;
|
||||
|
||||
case 'memcached':
|
||||
$servers = config('cache.stores.memcached.servers');
|
||||
$cacheConfig['host'] = $servers[0]['host'] ?? 'localhost';
|
||||
$cacheConfig['database'] = 'N/A';
|
||||
break;
|
||||
|
||||
case 'file':
|
||||
$cacheConfig['host'] = storage_path('framework/cache/data');
|
||||
$cacheConfig['database'] = 'N/A';
|
||||
break;
|
||||
|
||||
default:
|
||||
$cacheConfig['host'] = 'N/A';
|
||||
$cacheConfig['database'] = 'N/A';
|
||||
break;
|
||||
}
|
||||
|
||||
return $cacheConfig;
|
||||
}
|
||||
|
||||
private function getSessionConfig(): array
|
||||
{
|
||||
$sessionConfig = Config::get('session');
|
||||
$driver = $sessionConfig['driver'];
|
||||
|
||||
switch ($driver) {
|
||||
case 'redis':
|
||||
$connection = config('database.redis.sessions');
|
||||
$sessionConfig['host'] = $connection['host'] ?? 'localhost';
|
||||
$sessionConfig['database'] = $connection['database'] ?? 'N/A';
|
||||
break;
|
||||
|
||||
case 'database':
|
||||
$connection = config('database.connections.' . $sessionConfig['connection']);
|
||||
$sessionConfig['host'] = $connection['host'] ?? 'localhost';
|
||||
$sessionConfig['database'] = $connection['database'] ?? 'N/A';
|
||||
break;
|
||||
|
||||
case 'memcached':
|
||||
$servers = config('cache.stores.memcached.servers');
|
||||
$sessionConfig['host'] = $servers[0]['host'] ?? 'localhost';
|
||||
$sessionConfig['database'] = 'N/A';
|
||||
break;
|
||||
|
||||
case 'file':
|
||||
$sessionConfig['host'] = storage_path('framework/sessions');
|
||||
$sessionConfig['database'] = 'N/A';
|
||||
break;
|
||||
|
||||
default:
|
||||
$sessionConfig['host'] = 'N/A';
|
||||
$sessionConfig['database'] = 'N/A';
|
||||
break;
|
||||
}
|
||||
|
||||
return $sessionConfig;
|
||||
}
|
||||
|
||||
private function getDatabaseConfig(): array
|
||||
{
|
||||
$databaseConfig = Config::get('database');
|
||||
$connection = $databaseConfig['default'];
|
||||
|
||||
$connectionConfig = config('database.connections.' . $connection);
|
||||
$databaseConfig['host'] = $connectionConfig['host'] ?? 'localhost';
|
||||
$databaseConfig['database'] = $connectionConfig['database'] ?? 'N/A';
|
||||
|
||||
return $databaseConfig;
|
||||
}
|
||||
|
||||
|
||||
private function getDriverVersion(): array
|
||||
{
|
||||
$drivers = [];
|
||||
$defaultDatabaseDriver = config('database.default'); // Obtén el driver predeterminado
|
||||
|
||||
switch ($defaultDatabaseDriver) {
|
||||
case 'mysql':
|
||||
case 'mariadb':
|
||||
$drivers['mysql'] = [
|
||||
'version' => $this->getMySqlVersion(),
|
||||
'details' => config("database.connections.$defaultDatabaseDriver"),
|
||||
];
|
||||
|
||||
$drivers['mariadb'] = $drivers['mysql'];
|
||||
|
||||
case 'pgsql':
|
||||
$drivers['pgsql'] = [
|
||||
'version' => $this->getPgSqlVersion(),
|
||||
'details' => config("database.connections.pgsql"),
|
||||
];
|
||||
break;
|
||||
|
||||
case 'sqlsrv':
|
||||
$drivers['sqlsrv'] = [
|
||||
'version' => $this->getSqlSrvVersion(),
|
||||
'details' => config("database.connections.sqlsrv"),
|
||||
];
|
||||
break;
|
||||
|
||||
default:
|
||||
$drivers['unknown'] = [
|
||||
'version' => 'No disponible',
|
||||
'details' => 'Driver no identificado',
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
// Opcional: Agrega detalles de Redis y Memcached si están en uso
|
||||
if ($this->isDriverInUse('redis')) {
|
||||
$drivers['redis'] = [
|
||||
'version' => $this->getRedisVersion(),
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->isDriverInUse('memcached')) {
|
||||
$drivers['memcached'] = [
|
||||
'version' => $this->getMemcachedVersion(),
|
||||
];
|
||||
}
|
||||
|
||||
return $drivers;
|
||||
}
|
||||
|
||||
private function getMySqlVersion(): string
|
||||
{
|
||||
try {
|
||||
$version = DB::selectOne('SELECT VERSION() as version');
|
||||
return $version->version ?? 'No disponible';
|
||||
} catch (\Exception $e) {
|
||||
return 'Error: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private function getPgSqlVersion(): string
|
||||
{
|
||||
try {
|
||||
$version = DB::selectOne("SHOW server_version");
|
||||
return $version->server_version ?? 'No disponible';
|
||||
} catch (\Exception $e) {
|
||||
return 'Error: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private function getSqlSrvVersion(): string
|
||||
{
|
||||
try {
|
||||
$version = DB::selectOne("SELECT @@VERSION as version");
|
||||
return $version->version ?? 'No disponible';
|
||||
} catch (\Exception $e) {
|
||||
return 'Error: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private function getMemcachedVersion(): string
|
||||
{
|
||||
try {
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer(
|
||||
Config::get('cache.stores.memcached.servers.0.host'),
|
||||
Config::get('cache.stores.memcached.servers.0.port')
|
||||
);
|
||||
|
||||
$stats = $memcached->getStats();
|
||||
foreach ($stats as $serverStats) {
|
||||
return $serverStats['version'] ?? 'No disponible';
|
||||
}
|
||||
|
||||
return 'No disponible';
|
||||
} catch (\Exception $e) {
|
||||
return 'Error: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
private function getRedisVersion(): string
|
||||
{
|
||||
try {
|
||||
$info = Redis::info();
|
||||
return $info['redis_version'] ?? 'No disponible';
|
||||
} catch (\Exception $e) {
|
||||
return 'Error: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected function isDriverInUse(string $driver): bool
|
||||
{
|
||||
return in_array($driver, [
|
||||
Config::get('cache.default'),
|
||||
Config::get('session.driver'),
|
||||
Config::get('queue.default'),
|
||||
]);
|
||||
}
|
||||
}
|
389
src/modules/App/Services/CacheManagerService.php
Normal file
389
src/modules/App/Services/CacheManagerService.php
Normal file
@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class CacheManagerService
|
||||
{
|
||||
private string $driver;
|
||||
|
||||
public function __construct(string $driver = null)
|
||||
{
|
||||
$this->driver = $driver ?? config('cache.default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene estadísticas de caché para el driver especificado.
|
||||
*/
|
||||
public function getCacheStats(string $driver = null): array
|
||||
{
|
||||
$driver = $driver ?? $this->driver;
|
||||
|
||||
if (!$this->isSupportedDriver($driver)) {
|
||||
return $this->response('warning', 'Driver no soportado o no configurado.');
|
||||
}
|
||||
|
||||
try {
|
||||
return match ($driver) {
|
||||
'database' => $this->_getDatabaseStats(),
|
||||
'file' => $this->_getFilecacheStats(),
|
||||
'redis' => $this->_getRedisStats(),
|
||||
'memcached' => $this->_getMemcachedStats(),
|
||||
default => $this->response('info', 'No hay estadísticas disponibles para este driver.'),
|
||||
};
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al obtener estadísticas: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function clearCache(string $driver = null): array
|
||||
{
|
||||
$driver = $driver ?? $this->driver;
|
||||
|
||||
if (!$this->isSupportedDriver($driver)) {
|
||||
return $this->response('warning', 'Driver no soportado o no configurado.');
|
||||
}
|
||||
|
||||
try {
|
||||
switch ($driver) {
|
||||
case 'redis':
|
||||
$keysCleared = $this->clearRedisCache();
|
||||
|
||||
return $keysCleared
|
||||
? $this->response('warning', 'Se ha purgado toda la caché de Redis.')
|
||||
: $this->response('info', 'No se encontraron claves en Redis para eliminar.');
|
||||
|
||||
case 'memcached':
|
||||
$keysCleared = $this->clearMemcachedCache();
|
||||
|
||||
return $keysCleared
|
||||
? $this->response('warning', 'Se ha purgado toda la caché de Memcached.')
|
||||
: $this->response('info', 'No se encontraron claves en Memcached para eliminar.');
|
||||
|
||||
case 'database':
|
||||
$rowsDeleted = $this->clearDatabaseCache();
|
||||
|
||||
return $rowsDeleted
|
||||
? $this->response('warning', 'Se ha purgado toda la caché almacenada en la base de datos.')
|
||||
: $this->response('info', 'No se encontraron registros en la caché de la base de datos.');
|
||||
|
||||
case 'file':
|
||||
$filesDeleted = $this->clearFilecache();
|
||||
|
||||
return $filesDeleted
|
||||
? $this->response('warning', 'Se ha purgado toda la caché de archivos.')
|
||||
: $this->response('info', 'No se encontraron archivos en la caché para eliminar.');
|
||||
|
||||
default:
|
||||
Cache::flush();
|
||||
|
||||
return $this->response('warning', 'Caché purgada.');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al limpiar la caché: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function getRedisStats()
|
||||
{
|
||||
try {
|
||||
if (!Redis::ping()) {
|
||||
return $this->response('warning', 'No se puede conectar con el servidor Redis.');
|
||||
}
|
||||
|
||||
$info = Redis::info();
|
||||
|
||||
$databases = $this->getRedisDatabases();
|
||||
|
||||
$redisInfo = [
|
||||
'server' => config('database.redis.default.host'),
|
||||
'redis_version' => $info['redis_version'] ?? 'N/A',
|
||||
'os' => $info['os'] ?? 'N/A',
|
||||
'tcp_port' => $info['tcp_port'] ?? 'N/A',
|
||||
'connected_clients' => $info['connected_clients'] ?? 'N/A',
|
||||
'blocked_clients' => $info['blocked_clients'] ?? 'N/A',
|
||||
'maxmemory' => $info['maxmemory'] ?? 0,
|
||||
'used_memory_human' => $info['used_memory_human'] ?? 'N/A',
|
||||
'used_memory_peak' => $info['used_memory_peak'] ?? 'N/A',
|
||||
'used_memory_peak_human' => $info['used_memory_peak_human'] ?? 'N/A',
|
||||
'total_system_memory' => $info['total_system_memory'] ?? 0,
|
||||
'total_system_memory_human' => $info['total_system_memory_human'] ?? 'N/A',
|
||||
'maxmemory_human' => $info['maxmemory_human'] !== '0B' ? $info['maxmemory_human'] : 'Sin Límite',
|
||||
'total_connections_received' => number_format($info['total_connections_received']) ?? 'N/A',
|
||||
'total_commands_processed' => number_format($info['total_commands_processed']) ?? 'N/A',
|
||||
'maxmemory_policy' => $info['maxmemory_policy'] ?? 'N/A',
|
||||
'role' => $info['role'] ?? 'N/A',
|
||||
'cache_database' => '',
|
||||
'sessions_database' => '',
|
||||
'general_database' => ',',
|
||||
'keys' => $databases['total_keys'],
|
||||
'used_memory' => $info['used_memory'] ?? 0,
|
||||
'uptime' => gmdate('H\h i\m s\s', $info['uptime_in_seconds'] ?? 0),
|
||||
'databases' => $databases,
|
||||
];
|
||||
|
||||
return $this->response('success', 'Se a recargado las estadísticas de Redis.', ['info' => $redisInfo]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al conectar con el servidor Redis: ' . Redis::getLastError());
|
||||
}
|
||||
}
|
||||
|
||||
public function getMemcachedStats()
|
||||
{
|
||||
try {
|
||||
$memcachedStats = [];
|
||||
|
||||
// Crear instancia del cliente Memcached
|
||||
$memcached = new \Memcached();
|
||||
$memcached->addServer(config('memcached.host'), config('memcached.port'));
|
||||
|
||||
// Obtener estadísticas del servidor
|
||||
$stats = $memcached->getStats();
|
||||
|
||||
foreach ($stats as $server => $data) {
|
||||
$server = explode(':', $server);
|
||||
|
||||
$memcachedStats[] = [
|
||||
'server' => $server[0],
|
||||
'tcp_port' => $server[1],
|
||||
'uptime' => $data['uptime'] ?? 'N/A',
|
||||
'version' => $data['version'] ?? 'N/A',
|
||||
'libevent' => $data['libevent'] ?? 'N/A',
|
||||
'max_connections' => $data['max_connections'] ?? 0,
|
||||
'total_connections' => $data['total_connections'] ?? 0,
|
||||
'rejected_connections' => $data['rejected_connections'] ?? 0,
|
||||
'curr_items' => $data['curr_items'] ?? 0, // Claves almacenadas
|
||||
'bytes' => $data['bytes'] ?? 0, // Memoria usada
|
||||
'limit_maxbytes' => $data['limit_maxbytes'] ?? 0, // Memoria máxima
|
||||
'cmd_get' => $data['cmd_get'] ?? 0, // Comandos GET ejecutados
|
||||
'cmd_set' => $data['cmd_set'] ?? 0, // Comandos SET ejecutados
|
||||
'get_hits' => $data['get_hits'] ?? 0, // GET exitosos
|
||||
'get_misses' => $data['get_misses'] ?? 0, // GET fallidos
|
||||
'evictions' => $data['evictions'] ?? 0, // Claves expulsadas
|
||||
'bytes_read' => $data['bytes_read'] ?? 0, // Bytes leídos
|
||||
'bytes_written' => $data['bytes_written'] ?? 0, // Bytes escritos
|
||||
'total_items' => $data['total_items'] ?? 0,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->response('success', 'Se a recargado las estadísticas de Memcached.', ['info' => $memcachedStats]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al conectar con el servidor Memcached: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtiene estadísticas para caché en base de datos.
|
||||
*/
|
||||
private function _getDatabaseStats(): array
|
||||
{
|
||||
try {
|
||||
$recordCount = DB::table('cache')->count();
|
||||
$tableInfo = DB::select("SHOW TABLE STATUS WHERE Name = 'cache'");
|
||||
|
||||
$memory_usage = isset($tableInfo[0]) ? $this->formatBytes($tableInfo[0]->Data_length + $tableInfo[0]->Index_length) : 'N/A';
|
||||
|
||||
return $this->response('success', 'Se ha recargado la información de la caché de base de datos.', ['item_count' => $recordCount, 'memory_usage' => $memory_usage]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al obtener estadísticas de la base de datos: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene estadísticas para caché en archivos.
|
||||
*/
|
||||
private function _getFilecacheStats(): array
|
||||
{
|
||||
try {
|
||||
$cachePath = config('cache.stores.file.path');
|
||||
$files = glob($cachePath . '/*');
|
||||
|
||||
$memory_usage = $this->formatBytes(array_sum(array_map('filesize', $files)));
|
||||
|
||||
return $this->response('success', 'Se ha recargado la información de la caché de archivos.', ['item_count' => count($files), 'memory_usage' => $memory_usage]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al obtener estadísticas de archivos: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function _getRedisStats()
|
||||
{
|
||||
try {
|
||||
$prefix = config('cache.prefix'); // Asegúrate de agregar el sufijo correcto si es necesario
|
||||
|
||||
$info = Redis::info();
|
||||
$keys = Redis::connection('cache')->keys($prefix . '*');
|
||||
|
||||
$memory_usage = $this->formatBytes($info['used_memory'] ?? 0);
|
||||
|
||||
return $this->response('success', 'Se ha recargado la información de la caché de Redis.', ['item_count' => count($keys), 'memory_usage' => $memory_usage]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al obtener estadísticas de Redis: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function _getMemcachedStats(): array
|
||||
{
|
||||
try {
|
||||
// Obtener estadísticas generales del servidor
|
||||
$stats = Cache::getStore()->getMemcached()->getStats();
|
||||
|
||||
if (empty($stats)) {
|
||||
return $this->response('error', 'No se pudieron obtener las estadísticas del servidor Memcached.', ['item_count' => 0, 'memory_usage' => 0]);
|
||||
}
|
||||
|
||||
// Usar el primer servidor configurado (en la mayoría de los casos hay uno)
|
||||
$serverStats = array_shift($stats);
|
||||
|
||||
return $this->response(
|
||||
'success',
|
||||
'Estadísticas del servidor Memcached obtenidas correctamente.',
|
||||
[
|
||||
'item_count' => $serverStats['curr_items'] ?? 0, // Número total de claves
|
||||
'memory_usage' => $this->formatBytes($serverStats['bytes'] ?? 0), // Memoria usada
|
||||
'max_memory' => $this->formatBytes($serverStats['limit_maxbytes'] ?? 0), // Memoria máxima asignada
|
||||
]
|
||||
);
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al obtener estadísticas de Memcached: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function getRedisDatabases(): array
|
||||
{
|
||||
// Verificar si Redis está en uso
|
||||
$isRedisUsed = collect([
|
||||
config('cache.default'),
|
||||
config('session.driver'),
|
||||
config('queue.default'),
|
||||
])->contains('redis');
|
||||
|
||||
if (!$isRedisUsed) {
|
||||
return []; // Si Redis no está en uso, devolver un arreglo vacío
|
||||
}
|
||||
|
||||
// Configuraciones de bases de datos de Redis según su uso
|
||||
$databases = [
|
||||
'default' => config('database.redis.default.database', 0), // REDIS_DB
|
||||
'cache' => config('database.redis.cache.database', 0), // REDIS_CACHE_DB
|
||||
'sessions' => config('database.redis.sessions.database', 0), // REDIS_SESSION_DB
|
||||
];
|
||||
|
||||
$result = [];
|
||||
$totalKeys = 0;
|
||||
|
||||
// Recorrer solo las bases configuradas y activas
|
||||
foreach ($databases as $type => $db) {
|
||||
Redis::select($db); // Seleccionar la base de datos
|
||||
|
||||
$keys = Redis::dbsize(); // Contar las claves en la base
|
||||
|
||||
if ($keys > 0) {
|
||||
$result[$type] = [
|
||||
'database' => $db,
|
||||
'keys' => $keys,
|
||||
];
|
||||
|
||||
$totalKeys += $keys;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($result)) {
|
||||
$result['total_keys'] = $totalKeys;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
private function clearDatabaseCache(): bool
|
||||
{
|
||||
$count = DB::table(config('cache.stores.database.table'))->count();
|
||||
|
||||
if ($count > 0) {
|
||||
DB::table(config('cache.stores.database.table'))->truncate();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function clearFilecache(): bool
|
||||
{
|
||||
$cachePath = config('cache.stores.file.path');
|
||||
$files = glob($cachePath . '/*');
|
||||
|
||||
if (!empty($files)) {
|
||||
File::deleteDirectory($cachePath);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function clearRedisCache(): bool
|
||||
{
|
||||
$prefix = config('cache.prefix', '');
|
||||
$keys = Redis::connection('cache')->keys($prefix . '*');
|
||||
|
||||
if (!empty($keys)) {
|
||||
Redis::connection('cache')->flushdb();
|
||||
|
||||
// Simulate cache clearing delay
|
||||
sleep(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function clearMemcachedCache(): bool
|
||||
{
|
||||
// Obtener el cliente Memcached directamente
|
||||
$memcached = Cache::store('memcached')->getStore()->getMemcached();
|
||||
|
||||
// Ejecutar flush para eliminar todo
|
||||
if ($memcached->flush()) {
|
||||
// Simulate cache clearing delay
|
||||
sleep(1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifica si un driver es soportado.
|
||||
*/
|
||||
private function isSupportedDriver(string $driver): bool
|
||||
{
|
||||
return in_array($driver, ['redis', 'memcached', 'database', 'file']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convierte bytes en un formato legible.
|
||||
*/
|
||||
private function formatBytes($bytes)
|
||||
{
|
||||
$sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
||||
$factor = floor((strlen($bytes) - 1) / 3);
|
||||
|
||||
return sprintf('%.2f', $bytes / pow(1024, $factor)) . ' ' . $sizes[$factor];
|
||||
}
|
||||
|
||||
/**
|
||||
* Genera una respuesta estandarizada.
|
||||
*/
|
||||
private function response(string $status, string $message, array $data = []): array
|
||||
{
|
||||
return array_merge(compact('status', 'message'), $data);
|
||||
}
|
||||
}
|
273
src/modules/App/Services/GlobalSettingsService.php
Normal file
273
src/modules/App/Services/GlobalSettingsService.php
Normal file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Services;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Modules\Admin\App\Models\Setting;
|
||||
|
||||
class GlobalSettingsService
|
||||
{
|
||||
/**
|
||||
* Tiempo de vida del caché en minutos (30 días).
|
||||
*/
|
||||
private $cacheTTL = 60 * 24 * 30;
|
||||
|
||||
/**
|
||||
* Actualiza o crea una configuración.
|
||||
*/
|
||||
public function updateSetting(string $key, string $value): bool
|
||||
{
|
||||
$setting = Setting::updateOrCreate(
|
||||
['key' => $key],
|
||||
['value' => trim($value)]
|
||||
);
|
||||
|
||||
return $setting->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Carga y sobrescribe las configuraciones del sistema.
|
||||
*/
|
||||
public function loadSystemConfig(): void
|
||||
{
|
||||
try {
|
||||
if (!Schema::hasTable('migrations')) {
|
||||
// Base de datos no inicializada: usar valores predeterminados
|
||||
$config = $this->getDefaultSystemConfig();
|
||||
} else {
|
||||
// Cargar configuración desde la caché o base de datos
|
||||
$config = Cache::remember('global_system_config', $this->cacheTTL, function () {
|
||||
$settings = Setting::global()
|
||||
->where('key', 'LIKE', 'config.%')
|
||||
->pluck('value', 'key')
|
||||
->toArray();
|
||||
|
||||
return [
|
||||
'servicesFacebook' => $this->buildServiceConfig($settings, 'config.services.facebook.', 'services.facebook'),
|
||||
'servicesGoogle' => $this->buildServiceConfig($settings, 'config.services.google.', 'services.google'),
|
||||
'custom' => $this->buildVuexyCustomConfig($settings),
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
// Aplicar configuración al sistema
|
||||
Config::set('services.facebook', $config['servicesFacebook']);
|
||||
Config::set('services.google', $config['servicesGoogle']);
|
||||
Config::set('custom', $config['custom']);
|
||||
} catch (\Exception $e) {
|
||||
// Manejo silencioso de errores para evitar interrupciones
|
||||
Config::set('services.facebook', config('services.facebook', []));
|
||||
Config::set('services.google', config('services.google', []));
|
||||
Config::set('custom', config('custom', []));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve una configuración predeterminada si la base de datos no está inicializada.
|
||||
*/
|
||||
private function getDefaultSystemConfig(): array
|
||||
{
|
||||
return [
|
||||
'servicesFacebook' => config('services.facebook', [
|
||||
'client_id' => '',
|
||||
'client_secret' => '',
|
||||
'redirect' => '',
|
||||
]),
|
||||
'servicesGoogle' => config('services.google', [
|
||||
'client_id' => '',
|
||||
'client_secret' => '',
|
||||
'redirect' => '',
|
||||
]),
|
||||
'custom' => config('custom', []),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifica si un bloque de configuraciones está presente.
|
||||
*/
|
||||
protected function hasBlockConfig(array $settings, string $blockPrefix): bool
|
||||
{
|
||||
return array_key_exists($blockPrefix, array_filter($settings, fn($key) => str_starts_with($key, $blockPrefix), ARRAY_FILTER_USE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Construye la configuración de un servicio (Facebook, Google, etc.).
|
||||
*/
|
||||
protected function buildServiceConfig(array $settings, string $blockPrefix, string $defaultConfigKey): array
|
||||
{
|
||||
if (!$this->hasBlockConfig($settings, $blockPrefix)) {
|
||||
return config($defaultConfigKey);
|
||||
}
|
||||
|
||||
return [
|
||||
'client_id' => $settings["{$blockPrefix}client_id"] ?? '',
|
||||
'client_secret' => $settings["{$blockPrefix}client_secret"] ?? '',
|
||||
'redirect' => $settings["{$blockPrefix}redirect"] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Construye la configuración personalizada de Vuexy.
|
||||
*/
|
||||
protected function buildVuexyCustomConfig(array $settings): array
|
||||
{
|
||||
// Configuración predeterminada del sistema
|
||||
$defaultCustomConfig = config('custom', []);
|
||||
|
||||
// Convertimos las claves planas a un array multidimensional
|
||||
$settingsNested = Arr::undot($settings);
|
||||
|
||||
// Navegamos hasta la parte relevante del array desanidado
|
||||
$customSettings = $settingsNested['config']['custom'] ?? [];
|
||||
|
||||
// Fusionamos la configuración predeterminada con los valores del sistema
|
||||
$mergedConfig = array_replace_recursive($defaultCustomConfig, $customSettings);
|
||||
|
||||
// Normalizamos los valores booleanos
|
||||
return $this->normalizeBooleanFields($mergedConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normaliza los campos booleanos.
|
||||
*/
|
||||
protected function normalizeBooleanFields(array $config): array
|
||||
{
|
||||
$booleanFields = [
|
||||
'myRTLSupport',
|
||||
'myRTLMode',
|
||||
'hasCustomizer',
|
||||
'displayCustomizer',
|
||||
'footerFixed',
|
||||
'menuFixed',
|
||||
'menuCollapsed',
|
||||
'showDropdownOnHover',
|
||||
];
|
||||
|
||||
foreach ($booleanFields as $field) {
|
||||
if (isset($config['custom'][$field])) {
|
||||
$config['custom'][$field] = (bool) $config['custom'][$field];
|
||||
}
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpia el caché de la configuración del sistema.
|
||||
*/
|
||||
public static function clearSystemConfigCache(): void
|
||||
{
|
||||
Cache::forget('global_system_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Elimina las claves config.custom.* y limpia global_system_config
|
||||
*/
|
||||
public static function clearVuexyCustomConfig(): void
|
||||
{
|
||||
Setting::where('key', 'LIKE', 'config.custom.%')->delete();
|
||||
Cache::forget('global_system_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtiene y sobrescribe la configuración de correo electrónico.
|
||||
*/
|
||||
public function getMailSystemConfig(): array
|
||||
{
|
||||
return Cache::remember('mail_system_config', $this->cacheTTL, function () {
|
||||
$settings = Setting::global()
|
||||
->where('key', 'LIKE', 'mail.%')
|
||||
->pluck('value', 'key')
|
||||
->toArray();
|
||||
|
||||
$defaultMailersSmtpVars = config('mail.mailers.smtp');
|
||||
|
||||
return [
|
||||
'mailers' => [
|
||||
'smtp' => array_merge($defaultMailersSmtpVars, [
|
||||
'url' => $settings['mail.mailers.smtp.url'] ?? $defaultMailersSmtpVars['url'],
|
||||
'host' => $settings['mail.mailers.smtp.host'] ?? $defaultMailersSmtpVars['host'],
|
||||
'port' => $settings['mail.mailers.smtp.port'] ?? $defaultMailersSmtpVars['port'],
|
||||
'encryption' => $settings['mail.mailers.smtp.encryption'] ?? $defaultMailersSmtpVars['encryption'],
|
||||
'username' => $settings['mail.mailers.smtp.username'] ?? $defaultMailersSmtpVars['username'],
|
||||
'password' => isset($settings['mail.mailers.smtp.password']) && !empty($settings['mail.mailers.smtp.password'])
|
||||
? Crypt::decryptString($settings['mail.mailers.smtp.password'])
|
||||
: $defaultMailersSmtpVars['password'],
|
||||
'timeout' => $settings['mail.mailers.smtp.timeout'] ?? $defaultMailersSmtpVars['timeout'],
|
||||
]),
|
||||
],
|
||||
'from' => [
|
||||
'address' => $settings['mail.from.address'] ?? config('mail.from.address'),
|
||||
'name' => $settings['mail.from.name'] ?? config('mail.from.name'),
|
||||
],
|
||||
'reply_to' => [
|
||||
'method' => $settings['mail.reply_to.method'] ?? config('mail.reply_to.method'),
|
||||
'email' => $settings['mail.reply_to.email'] ?? config('mail.reply_to.email'),
|
||||
'name' => $settings['mail.reply_to.name'] ?? config('mail.reply_to.name'),
|
||||
],
|
||||
];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpia el caché de la configuración de correo electrónico.
|
||||
*/
|
||||
public static function clearMailSystemConfigCache(): void
|
||||
{
|
||||
Cache::forget('mail_system_config');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
protected function buildFortifyFeatures(array $settings): array
|
||||
{
|
||||
return array_filter([
|
||||
!empty($settings['config.fortify.features.registration']) && $settings['config.fortify.features.registration'] == 1
|
||||
? \Laravel\Fortify\Features::registration()
|
||||
: null,
|
||||
|
||||
!empty($settings['config.fortify.features.resetPasswords']) && $settings['config.fortify.features.resetPasswords'] == 1
|
||||
? \Laravel\Fortify\Features::resetPasswords()
|
||||
: null,
|
||||
|
||||
!empty($settings['config.fortify.features.emailVerification']) && $settings['config.fortify.features.emailVerification'] == 1
|
||||
? \Laravel\Fortify\Features::emailVerification()
|
||||
: null,
|
||||
|
||||
!empty($settings['config.fortify.features.updateProfileInformation']) && $settings['config.fortify.features.updateProfileInformation'] == 1
|
||||
? \Laravel\Fortify\Features::updateProfileInformation()
|
||||
: null,
|
||||
|
||||
!empty($settings['config.fortify.features.updatePasswords']) && $settings['config.fortify.features.updatePasswords'] == 1
|
||||
? \Laravel\Fortify\Features::updatePasswords()
|
||||
: null,
|
||||
|
||||
!empty($settings['config.fortify.features.twoFactorAuthentication.confirm']) && $settings['config.fortify.features.twoFactorAuthentication.confirm'] == 1
|
||||
? \Laravel\Fortify\Features::twoFactorAuthentication([
|
||||
'confirm' => true,
|
||||
'confirmPassword' => !empty($settings['config.fortify.features.twoFactorAuthentication.confirmPassword'])
|
||||
&& $settings['config.fortify.features.twoFactorAuthentication.confirmPassword'] == 1,
|
||||
'window' => $settings['config.fortify.features.twoFactorAuthentication.window'] ?? 1,
|
||||
])
|
||||
: null,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function loadUserSettings()
|
||||
{
|
||||
if (Auth::check()) {
|
||||
$userId = Auth::id();
|
||||
// Cargar configuraciones del usuario desde la caché
|
||||
return Cache::remember("user_settings_{$userId}", $this->cacheTTL, function () use ($userId) {
|
||||
return \App\Models\Setting::forUser($userId)->pluck('value', 'key')->toArray();
|
||||
});
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
*/
|
||||
}
|
153
src/modules/App/Services/SessionManagerService.php
Normal file
153
src/modules/App/Services/SessionManagerService.php
Normal file
@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Redis;
|
||||
|
||||
class SessionManagerService
|
||||
{
|
||||
private string $driver;
|
||||
|
||||
public function __construct(string $driver = null)
|
||||
{
|
||||
$this->driver = $driver ?? config('session.driver');
|
||||
}
|
||||
|
||||
public function getSessionStats(string $driver = null): array
|
||||
{
|
||||
$driver = $driver ?? $this->driver;
|
||||
|
||||
if (!$this->isSupportedDriver($driver))
|
||||
return $this->response('warning', 'Driver no soportado o no configurado.', ['session_count' => 0]);
|
||||
|
||||
try {
|
||||
switch ($driver) {
|
||||
case 'redis':
|
||||
return $this->getRedisStats();
|
||||
|
||||
case 'database':
|
||||
return $this->getDatabaseStats();
|
||||
|
||||
case 'file':
|
||||
return $this->getFileStats();
|
||||
|
||||
default:
|
||||
return $this->response('warning', 'Driver no reconocido.', ['session_count' => 0]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al obtener estadísticas: ' . $e->getMessage(), ['session_count' => 0]);
|
||||
}
|
||||
}
|
||||
|
||||
public function clearSessions(string $driver = null): array
|
||||
{
|
||||
$driver = $driver ?? $this->driver;
|
||||
|
||||
if (!$this->isSupportedDriver($driver)) {
|
||||
return $this->response('warning', 'Driver no soportado o no configurado.');
|
||||
}
|
||||
|
||||
try {
|
||||
switch ($driver) {
|
||||
case 'redis':
|
||||
return $this->clearRedisSessions();
|
||||
|
||||
case 'memcached':
|
||||
Cache::getStore()->flush();
|
||||
return $this->response('success', 'Se eliminó la memoria caché de sesiones en Memcached.');
|
||||
|
||||
case 'database':
|
||||
DB::table('sessions')->truncate();
|
||||
return $this->response('success', 'Se eliminó la memoria caché de sesiones en la base de datos.');
|
||||
|
||||
case 'file':
|
||||
return $this->clearFileSessions();
|
||||
|
||||
default:
|
||||
return $this->response('warning', 'Driver no reconocido.');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return $this->response('danger', 'Error al limpiar las sesiones: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private function getRedisStats()
|
||||
{
|
||||
$prefix = config('cache.prefix'); // Asegúrate de agregar el sufijo correcto si es necesario
|
||||
$keys = Redis::connection('sessions')->keys($prefix . '*');
|
||||
|
||||
return $this->response('success', 'Se ha recargado la información de la caché de Redis.', ['session_count' => count($keys)]);
|
||||
}
|
||||
|
||||
private function getDatabaseStats(): array
|
||||
{
|
||||
$sessionCount = DB::table('sessions')->count();
|
||||
|
||||
return $this->response('success', 'Se ha recargado la información de la base de datos.', ['session_count' => $sessionCount]);
|
||||
}
|
||||
|
||||
private function getFileStats(): array
|
||||
{
|
||||
$cachePath = config('session.files');
|
||||
$files = glob($cachePath . '/*');
|
||||
|
||||
return $this->response('success', 'Se ha recargado la información de sesiones de archivos.', ['session_count' => count($files)]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Limpia sesiones en Redis.
|
||||
*/
|
||||
private function clearRedisSessions(): array
|
||||
{
|
||||
$prefix = config('cache.prefix', '');
|
||||
$keys = Redis::connection('sessions')->keys($prefix . '*');
|
||||
|
||||
if (!empty($keys)) {
|
||||
Redis::connection('sessions')->flushdb();
|
||||
|
||||
// Simulate cache clearing delay
|
||||
sleep(1);
|
||||
|
||||
return $this->response('success', 'Se eliminó la memoria caché de sesiones en Redis.');
|
||||
}
|
||||
|
||||
return $this->response('info', 'No se encontraron claves para eliminar en Redis.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Limpia sesiones en archivos.
|
||||
*/
|
||||
private function clearFileSessions(): array
|
||||
{
|
||||
$cachePath = config('session.files');
|
||||
$files = glob($cachePath . '/*');
|
||||
|
||||
if (!empty($files)) {
|
||||
foreach ($files as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
return $this->response('success', 'Se eliminó la memoria caché de sesiones en archivos.');
|
||||
}
|
||||
|
||||
return $this->response('info', 'No se encontraron sesiones en archivos para eliminar.');
|
||||
}
|
||||
|
||||
|
||||
private function isSupportedDriver(string $driver): bool
|
||||
{
|
||||
return in_array($driver, ['redis', 'memcached', 'database', 'file']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Genera una respuesta estandarizada.
|
||||
*/
|
||||
private function response(string $status, string $message, array $data = []): array
|
||||
{
|
||||
return array_merge(compact('status', 'message'), $data);
|
||||
}
|
||||
}
|
1198
src/modules/App/Services/VuexyAdminService.php
Normal file
1198
src/modules/App/Services/VuexyAdminService.php
Normal file
File diff suppressed because it is too large
Load Diff
211
src/modules/App/Services/WebsiteSettingsService.php
Normal file
211
src/modules/App/Services/WebsiteSettingsService.php
Normal file
@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Admin\App\Services;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Modules\Admin\App\Models\Setting;
|
||||
|
||||
class WebsiteSettingsService
|
||||
{
|
||||
private $driver;
|
||||
private $imageDisk = 'public';
|
||||
private $favicon_basePath = 'favicon/';
|
||||
private $image_logo_basePath = 'images/logo/';
|
||||
|
||||
private $faviconsSizes = [
|
||||
'180x180' => [180, 180],
|
||||
'192x192' => [192, 192],
|
||||
'152x152' => [152, 152],
|
||||
'120x120' => [120, 120],
|
||||
'76x76' => [76, 76],
|
||||
'16x16' => [16, 16],
|
||||
];
|
||||
|
||||
private $imageLogoMaxPixels1 = 22500; // Primera versión (px^2)
|
||||
private $imageLogoMaxPixels2 = 75625; // Segunda versión (px^2) en Base64
|
||||
private $imageLogoMaxPixels3 = 230400; // Tercera versión (px^2)
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->driver = config('image.driver', 'gd');
|
||||
}
|
||||
|
||||
public function updateSetting(string $key, string $value): bool
|
||||
{
|
||||
$setting = Setting::updateOrCreate(
|
||||
['key' => $key],
|
||||
['value' => trim($value)]
|
||||
);
|
||||
|
||||
return $setting->save();
|
||||
}
|
||||
|
||||
public function processAndSaveFavicon($image): void
|
||||
{
|
||||
Storage::makeDirectory($this->imageDisk . '/' . $this->favicon_basePath);
|
||||
|
||||
// Eliminar favicons antiguos
|
||||
$this->deleteOldFavicons();
|
||||
|
||||
// Guardar imagen original
|
||||
$imageManager = new ImageManager($this->driver);
|
||||
|
||||
$imageName = uniqid('website_favicon_');
|
||||
|
||||
$image = $imageManager->read($image->getRealPath());
|
||||
|
||||
foreach ($this->faviconsSizes as $size => [$width, $height]) {
|
||||
$resizedPath = $this->favicon_basePath . $imageName . "_{$size}.png";
|
||||
|
||||
$image->cover($width, $height);
|
||||
|
||||
Storage::disk($this->imageDisk)->put($resizedPath, $image->toPng(indexed: true));
|
||||
}
|
||||
|
||||
$this->updateSetting('website_favicon_ns', $this->favicon_basePath . $imageName);
|
||||
}
|
||||
|
||||
protected function deleteOldFavicons(): void
|
||||
{
|
||||
// Obtener el favicon actual desde la base de datos
|
||||
$currentFavicon = Setting::where('key', 'website_favicon')->value('value');
|
||||
|
||||
if ($currentFavicon) {
|
||||
$filePaths = [
|
||||
$this->imageDisk . '/' . $currentFavicon,
|
||||
$this->imageDisk . '/' . $currentFavicon . '_16x16.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_192x192.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_76x76.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_120x120.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_152x152.png',
|
||||
$this->imageDisk . '/' . $currentFavicon . '_180x180.png',
|
||||
];
|
||||
|
||||
foreach ($filePaths as $filePath) {
|
||||
if (Storage::exists($filePath)) {
|
||||
Storage::delete($filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function processAndSaveImageLogo($image, string $type = ''): void
|
||||
{
|
||||
// Crear directorio si no existe
|
||||
Storage::makeDirectory($this->imageDisk . '/' . $this->image_logo_basePath);
|
||||
|
||||
// Eliminar imágenes antiguas
|
||||
$this->deleteOldImageWebapp($type);
|
||||
|
||||
// Leer imagen original
|
||||
$imageManager = new ImageManager($this->driver);
|
||||
$image = $imageManager->read($image->getRealPath());
|
||||
|
||||
// Generar tres versiones con diferentes áreas máximas
|
||||
$this->generateAndSaveImage($image, $type, $this->imageLogoMaxPixels1, 'small'); // Versión 1
|
||||
$this->generateAndSaveImage($image, $type, $this->imageLogoMaxPixels2, 'medium'); // Versión 2
|
||||
$this->generateAndSaveImage($image, $type, $this->imageLogoMaxPixels3); // Versión 3
|
||||
$this->generateAndSaveImageAsBase64($image, $type, $this->imageLogoMaxPixels3); // Versión 3
|
||||
}
|
||||
|
||||
private function generateAndSaveImage($image, string $type, int $maxPixels, string $suffix = ''): void
|
||||
{
|
||||
$imageClone = clone $image;
|
||||
|
||||
// Escalar imagen conservando aspecto
|
||||
$this->resizeImageToMaxPixels($imageClone, $maxPixels);
|
||||
|
||||
$imageName = 'website_image_logo' . ($suffix ? '_' . $suffix : '') . ($type == 'dark' ? '_dark' : '');
|
||||
|
||||
// Generar nombre y ruta
|
||||
$imageNameUid = uniqid($imageName . '_', ".png");
|
||||
$resizedPath = $this->image_logo_basePath . $imageNameUid;
|
||||
|
||||
// Guardar imagen en PNG
|
||||
Storage::disk($this->imageDisk)->put($resizedPath, $imageClone->toPng(indexed: true));
|
||||
|
||||
// Actualizar configuración
|
||||
$this->updateSetting($imageName, $resizedPath);
|
||||
}
|
||||
|
||||
private function resizeImageToMaxPixels($image, int $maxPixels)
|
||||
{
|
||||
// Obtener dimensiones originales de la imagen
|
||||
$originalWidth = $image->width(); // Método para obtener el ancho
|
||||
$originalHeight = $image->height(); // Método para obtener el alto
|
||||
|
||||
// Calcular el aspecto
|
||||
$aspectRatio = $originalWidth / $originalHeight;
|
||||
|
||||
// Calcular dimensiones redimensionadas conservando aspecto
|
||||
if ($aspectRatio > 1) { // Ancho es dominante
|
||||
$newWidth = sqrt($maxPixels * $aspectRatio);
|
||||
$newHeight = $newWidth / $aspectRatio;
|
||||
} else { // Alto es dominante
|
||||
$newHeight = sqrt($maxPixels / $aspectRatio);
|
||||
$newWidth = $newHeight * $aspectRatio;
|
||||
}
|
||||
|
||||
// Redimensionar la imagen
|
||||
$image->resize(
|
||||
round($newWidth), // Redondear para evitar problemas con números decimales
|
||||
round($newHeight),
|
||||
function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
}
|
||||
);
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
|
||||
private function generateAndSaveImageAsBase64($image, string $type, int $maxPixels): void
|
||||
{
|
||||
$imageClone = clone $image;
|
||||
|
||||
// Redimensionar imagen conservando el aspecto
|
||||
$this->resizeImageToMaxPixels($imageClone, $maxPixels);
|
||||
|
||||
// Convertir a Base64
|
||||
$base64Image = (string) $imageClone->toJpg(40)->toDataUri();
|
||||
|
||||
// Guardar como configuración
|
||||
$this->updateSetting(
|
||||
"website_image_logo_base64" . ($type === 'dark' ? '_dark' : ''),
|
||||
$base64Image // Ya incluye "data:image/png;base64,"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
protected function deleteOldImageWebapp(string $type = ''): void
|
||||
{
|
||||
// Determinar prefijo según el tipo (normal o dark)
|
||||
$suffix = $type === 'dark' ? '_dark' : '';
|
||||
|
||||
// Claves relacionadas con las imágenes que queremos limpiar
|
||||
$imageKeys = [
|
||||
"website_image_logo{$suffix}",
|
||||
"website_image_logo_small{$suffix}",
|
||||
"website_image_logo_medium{$suffix}",
|
||||
"website_image_logo_base64{$suffix}",
|
||||
];
|
||||
|
||||
foreach ($imageKeys as $key) {
|
||||
// Obtener la ruta de la imagen actual desde la base de datos
|
||||
$currentImage = Setting::where('key', $key)->value('value');
|
||||
|
||||
// Si es una imagen en disco, eliminarla
|
||||
if ($currentImage && !str_starts_with($currentImage, 'data:image')) {
|
||||
$filePath = $this->imageDisk . '/' . $currentImage;
|
||||
if (Storage::exists($filePath)) {
|
||||
Storage::delete($filePath);
|
||||
}
|
||||
}
|
||||
|
||||
// Opcional: Eliminar la configuración de la base de datos
|
||||
Setting::where('key', $key)->delete();
|
||||
}
|
||||
}
|
||||
}
|
112
src/modules/BaseServiceProvider.php
Normal file
112
src/modules/BaseServiceProvider.php
Normal file
@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
namespace Koneko\VuexyAdminModule;
|
||||
|
||||
use Illuminate\Auth\Events\Login;
|
||||
use Illuminate\Auth\Events\Logout;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\PermissionServiceProvider;
|
||||
use Modules\Admin\App\Http\Middleware\AdminTemplateMiddleware;
|
||||
use Modules\Admin\App\Listeners\ClearUserCache;
|
||||
use Modules\Admin\App\Listeners\HandleUserLogin;
|
||||
use Modules\Admin\App\Livewire\Cache\CacheFunctions;
|
||||
use Modules\Admin\App\Livewire\Users\UserCount;
|
||||
use Modules\Admin\App\Livewire\Users\UserTable;
|
||||
use Modules\Admin\App\Livewire\Rbac\RoleCards;
|
||||
use Modules\Admin\App\Livewire\Rbac\PermissionsIndex;
|
||||
use Modules\Admin\App\Livewire\Cache\CacheStats;
|
||||
use Modules\Admin\App\Livewire\Cache\SessionStats;
|
||||
use Modules\Admin\App\Livewire\Cache\MemcachedStats;
|
||||
use Modules\Admin\App\Livewire\Cache\RedisStats;
|
||||
use Modules\Admin\App\Livewire\AdminSettings\ApplicationSettings;
|
||||
use Modules\Admin\App\Livewire\AdminSettings\GeneralSettings;
|
||||
use Modules\Admin\App\Livewire\AdminSettings\InterfaceSettings;
|
||||
use Modules\Admin\App\Livewire\AdminSettings\MailSmtpSettings;
|
||||
use Modules\Admin\App\Livewire\AdminSettings\MailSenderResponseSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\AnalyticsSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\ChatSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\ContactFormSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\ContactInfoSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\FaviconSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\ImageLogoSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\LocationSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\SocialSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\TemplateSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\WebsiteSettings;
|
||||
use Modules\Admin\App\Livewire\WebsiteSettings\LegalSettings;
|
||||
use Modules\Admin\App\Models\User;
|
||||
use Modules\Admin\App\Providers\FortifyServiceProvider;
|
||||
use Modules\Admin\App\Providers\GlobalSettingsProvider;
|
||||
use Modules\Admin\App\Providers\VuexyAdminProvider;
|
||||
use OwenIt\Auditing\AuditableObserver;
|
||||
|
||||
class BaseServiceProvider extends ServiceProvider
|
||||
{
|
||||
public static $prefixRoute = 'admin';
|
||||
|
||||
public function register()
|
||||
{
|
||||
// Register the module's services and providers
|
||||
$this->app->register(FortifyServiceProvider::class);
|
||||
$this->app->register(PermissionServiceProvider::class);
|
||||
$this->app->register(GlobalSettingsProvider::class);
|
||||
$this->app->register(VuexyAdminProvider::class);
|
||||
}
|
||||
|
||||
|
||||
public function boot()
|
||||
{
|
||||
// Registrar alias del middleware
|
||||
$this->app['router']->aliasMiddleware('admin.settings', AdminTemplateMiddleware::class);
|
||||
|
||||
// Register the module's routes
|
||||
Route::middleware(['web'])->group(__DIR__ . '/routes.php');
|
||||
|
||||
// Register the module's views and resources
|
||||
$this->loadViewsFrom(__DIR__ . '/Resources/views', 'admin');
|
||||
|
||||
// Register the migrations
|
||||
$this->loadMigrationsFrom(__DIR__ . '/Database/migrations');
|
||||
|
||||
// Registrar manualmente listeners
|
||||
Event::listen(Login::class, HandleUserLogin::class);
|
||||
Event::listen(Logout::class, ClearUserCache::class);
|
||||
|
||||
// Register the module's Livewire components
|
||||
Livewire::component('user-count', UserCount::class);
|
||||
Livewire::component('user-table', UserTable::class);
|
||||
Livewire::component('role-card', RoleCards::class);
|
||||
Livewire::component('permissions-index', PermissionsIndex::class);
|
||||
|
||||
Livewire::component('general-settings', GeneralSettings::class);
|
||||
Livewire::component('application-settings', ApplicationSettings::class);
|
||||
Livewire::component('interface-settings', InterfaceSettings::class);
|
||||
|
||||
Livewire::component('cache-stats', CacheStats::class);
|
||||
Livewire::component('session-stats', SessionStats::class);
|
||||
Livewire::component('redis-stats', RedisStats::class);
|
||||
Livewire::component('memcached-stats', MemcachedStats::class);
|
||||
Livewire::component('cache-functions', CacheFunctions::class);
|
||||
|
||||
Livewire::component('mail-smtp-settings', MailSmtpSettings::class);
|
||||
Livewire::component('mail-sender-response-settings', MailSenderResponseSettings::class);
|
||||
|
||||
Livewire::component('website-settings', WebsiteSettings::class);
|
||||
Livewire::component('website-favicon-settings', FaviconSettings::class);
|
||||
Livewire::component('website-image-logo-settings', ImageLogoSettings::class);
|
||||
Livewire::component('website-social-settings', SocialSettings::class);
|
||||
Livewire::component('website-contact-form-settings', ContactFormSettings::class);
|
||||
Livewire::component('website-contact-info-settings', ContactInfoSettings::class);
|
||||
Livewire::component('website-location-settings', LocationSettings::class);
|
||||
Livewire::component('website-chat-settings', ChatSettings::class);
|
||||
Livewire::component('website-analytics-settings', AnalyticsSettings::class);
|
||||
Livewire::component('website-template-settings', TemplateSettings::class);
|
||||
Livewire::component('website-legal-settings', LegalSettings::class);
|
||||
|
||||
// Enable auditing
|
||||
User::observe(AuditableObserver::class);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user