CURSO DE LARAVEL 8

PROGRAMAS A UTILIZAR
  1. Composer Nos permite declarar las bibliotecas que necesitaremos en nuestros proyectos y de cuales libreras depende y Composer nos ayudara a (instalar / actualizar) de una manera sencilla y practica.
  2. Git Es un programa que nos permite lo siguiente:
    • ejecutar comandos en la terminal.
    • subir nuestro proyecto a un repositorio.
    • etc.
  3. NodeJs Node.js es un entorno en tiempo de ejecución que nos permite ejecutar comandos en el servidor.
  4. Visual Studio Code Visual Studio Code es un editor de código fuente desarrollado por Microsoft.
  5. Mysql (My Structured Query Language->Lenguaje de Consulta) es un gestor de base de datos, lo cual nos permite almacenar y administrar información.
  6. Xampp es un acrónimo, sus siglas significan: X: para cualquier sistema operativo. A: Apache, MariaDB/MySQL, PHP, Perl, es un servidor HTTP en software libre para cualquier plataforma.
  7. Navicat Es un programa lo cual nos facilita la administracion de nuestra base de datos
REQUISITOS BÁSICOS
  1. Conocimiento en Php
  2. Conocimiento en Html
  3. Conocimiento en Css
  4. Conocimiento en JavaScript básico
  5. LARAVEL 8 : PHP >= 7.3
  6. LARAVEL 9 : PHP >= 8
CONCEPTOS BÁSICOS
* Laravel es un framework de código abierto para desarrollar aplicaciones web en PHP. Laravel maneja una estructura de diseño MVC.
* Blade es un motor de plantillas, Blade es simple pero potente.
INSTALACION DE LARAVEL
                    
                     composer global require laravel/installer                            
                    
                    
Ver las versiones de nuestros programas
                     
                    php artisan --version /* ejecutar dentro del proyecto para saber la version de nuestro proyecto laravel */                          
                    node -v /* version de node */
                    php -v /* version de php */
                    laravel -v /* version de laravel */
                    npm -v /* version de npm */
                    
                    
ESTRUCTURA DE CARPETAS
IMG-estructura PHP
IMPRIMIR
                    
                    <h1>{{$mensaje}}</h1>
                    <!-- VUE agrega el @ -->
                    <h1>@{{mensaje}}</h1>
                    
                    
COMO CREAR DOMINIO LOCAL
En C:\Windows\System32\drivers\etc\hosts agregar lo siguiente
                    
                    127.0.0.1		     ejemplo.pe
                    
                    
En C:\XAMPP\apache\conf\extra\httpd-vhosts.conf agregar lo siguiente
                                               
                        <VirtualHost *:8080>
                            DocumentRoot "C:\xampp\htdocs\PROYECTOS-LARAVEL\computacion\public"
                            ServerName ejemplo.pe
                            <Directory "C:\xampp\htdocs\PROYECTOS-LARAVEL\computacion\public">
                                Options All
                                AllowOverride All
                                Require all granted
                            </Directory>
                        </VirtualHost>
                    
                    
* Reiniciar servidor APACHE
CREAR UN PROYECTO
                                               
                    laravel new blog    //método1 (debes tener instalado laravel)
                    composer create-project --prefer-dist laravel/laravel:^7.0 blog //método2(via composer)
                    
                    
Configurar para desarrollar un proyecto
                                               
                    debug=TRUE
                    'timezone' => 'America/Lima'
                    'timezone' => 'locale' => 'es'
                    descargar idioma español
                    COPIAR EL IDIOMA EN: \resources\lang\
                    
                    
Instalar bootstrap
                    
                    composer require laravel/ui
                    php artisan ui bootstrap  //sin autentificación
                    php artisan ui bootstrap --auth  //con autentificación
                    npm install
                    npm run dev
                    # ojo el servidor debe estar apagado
                    # se ejecuta laravel mix
                    
                    
CORRER EL SERVIDOR
                    
                    php artisan serve
                    
                    
Extension para Visual Studio Code
                    
                    Ayu
                    html tag wrapper
                    intellisense for css class names in html
                    Laravel Blade
                    Laravel Blade formatter
                    Laravel Blade Snippets
                    Laravel Snippets
                    Live Server
                    open in browser
                    PHP Intelephense
                    PHP IntelliSense
                    Prettier-Code formatter
                    px to rem
                    
                    
CREAR UN PROYECTO CON INFYOM
Descargar la plantilla en: PLANTILLA
CONFIGURACIONES EN LA PLANTILLA
                                               
                    copiar el archivo .envconf y renombrar como .env
                    <!--composer install(debes reiniciar VSC OJO: esto es opcional)-->
                    composer update
                    php artisan key:generate                       
                    
                    
CRUD AUTOMATICO
                                               
                    php artisan migrate *opcional
                    php artisan infyom:scaffold Producto --fromTable --tableName= producto
                    
                    
EN EL MODELO
                    
                    <?php
                    //use SoftDeletes;
                    protected $table = "usuario";
                    protected $primaryKey = 'id_usuario';
                    public $timestamps = false;
                    ?>
                    
                    
EN LAS VISTAS
                    
                    Edit.blade.php /* modificar el campo id */
                    Table.blade.php /* modificar el campo id */
                    
                    
MODELOS
*Los modelos son o se usan para interactuar con nuestra base de datos de esta manera podemos hacer cualquier clase de consulta a nuestra base de datos por ejemplo: insertar, borrar, modificar, mostrar.
*Los modelos se encuentran en app/Models.
                                                
                    php artisan make:model Usuario
CONFIGURAR EL MODELO.
                                                
                    <?php
                    public $table = "usuario";
                    public $primaryKey = "id_usuario";
                    public $timestamps = false;
                    protected $fillable = [
                       'nombre',
                       'apellido',
                       'password',
                       'correo',
                    ];
                    ?>
                    
                    
VISTAS
*Las vistas son la parte pública que se van a mostrar. Las vistas deben tener un formato .php o .blade.php
*Los vistas se encuentran en resources/views.
CONTROLADORES
*Los controladores son un mecanismo que nos permite agrupar la lógica de peticiones HTTP relacionadas y de esta forma organizar mejor nuestro código.
*Los controladores se encuentran en app/Http/Controllers.
                                                
                    php artisan make:controller UsuarioController
                    php artisan make:controller UsuarioController -r
                    
                    
REQUEST
*Los request en laravel se utilizan para poder validar los campos del formulario.
*Los request se encuentran en app/Http/Requests.
                                                        
                                php artisan make:request UsuarioCrearRequest
                            
                        
EL METODO
                                                        
                                <?php
                                public function store(RegistrarUsuarioRequest $request)
                                {                                            
                                }
                                ?>
                            
                        
REQUEST EN EL MISMO CONTROLADOR
                                                        
                                <?php
                                $request->validate([
                                'title' => 'required',
                                'content' => 'required',
                                ]);
                                ?>
                            
                        
CONFIGURACION
                                                        
                                <?php
                                public function authorize()
                                {
                                return true;
                                }
                                ?>
                            
                        
METODOS EN REQUEST
                            
                                public function rules()
                                {
                                    return [
                                    'nombre' => 'required',
                                    'foto'=>'image:jpg'
                                    ];
                                }
                    
                                public function attributes()
                                {
                                    return [
                                    'nombre'=>'nombre completo'
                                    ];
                                }
                    
                                public function messages()
                                {
                                    return [
                                    'nombre.required' => 'nombre del producto',
                                    'proveedor.required' => 'proveedor',
                                    ];
                                }
                            
                        
VALIDACIONES DE FORMULARIOS.
                            
                                1-> required    // requerido
                                2-> max:10  // maximo 10 caracteres
                                3-> min:2   // minimo 2 caracteres
                                4-> accepted    // aceptado
                                5-> date    // fecha
                                6-> file    // archivos
                                7-> email   // correo
                                8-> alpha   // solo letras
                                9-> alpha_dash  // letras y numeros, guiones y guiones bajos
                                10-> alpha_num  // letras y numeros
                                11-> numeric    // solo numero y decimales
                                11.1-> numeric|gt:0  // numeros mayor a CERO > 0
                                12-> digits:2   // numero de 2 digitos
                                13-> digits_between:2,5     // numero entre 2 y 5 digitos
                                14-> email:rfc,dns  // correo valido
                                15-> ends_with:com,isai     // el campo debe terminar en "com" o en "isai"
                                16-> image  // imagen(jpeg-png-bmp-gif-svg-webp)
                                17-> integer    // numero entero
                                18-> size   // debe ser de 10 caracteres
                                19-> string     // cadena de cualquier caracter
                                20 INGRESAR SOLO VALORES QUE ESTEN REGISTRADOS EN LA BD DEL CAMPO NOMBRE
                                20-> exists     // App\Models\producto,nombre
                                21 INGRESAR SOLO VALORES UNICOS
                                21-> unique     // App\Models\producto,correo
                                22-> mimes:jpg,png  // el archivo debe ser tipo "jpg" o "png"
                                23-> starts_with:A-,COM     // el campo debe comenzar con "A-" o "COM"
                            
                        
MOSTRAR ERRORES DE VALIDACION
                                                        
                                <input type="text" name="title" id="title">
                                @error('title')
                                    <p class="error-message">{{ $message }}</p>
                                @enderror
                            
                        
CONSERVAR ERRORES DE VALIDACION
                                                        
                                <form>
                                    <input name="title" value="{{ old('title') }}">
                                    <textarea name="content">{{ old('content',$valor) }}</textarea>  <!-- es utilizado en una actualizacion-->
                                    <select class="input input__select" name="tipo">
                                        <option value="">Seleccionar tipo de usuario...</option>
                                        @foreach ($sql as $item)
                                        <option {{old('tipo') == $item->id_tipo ? 'selected' : ''}} value="{{$item->id_tipo}}">{{$item->tipo}}</option>
                                        @endforeach
                                    </select>
                            
                        
RULES
*Los rules en laravel se utilizan para poder personalizar las validaciones REQUEST.
*Los rules se encuentran en app/Rules.
                                                        
                                php artisan make:rule usuario/registrar/duplicidadUsuario
                            
                        
EL METODO EN RULE
                                                        
                                <?php
                                public function passes($attribute, $value)
                                {
                                    /* validando duplicidad de usuario */
                                    $valUsuario = DB::select("select count(*) as total from usuario where usuario=? and estado=1", [
                                        $value
                                    ]);
                                    if ($valUsuario[0]->total > 0) {
                                        return false;
                                    }else{
                                        return true;
                                    }
                                }
                    
                                public function message()
                                {
                                    return 'Este usuario ya existe';
                                }
                                ?>
                            
                        
MODIFICAR ESTO EN EL REQUEST
                                                    
                            <?php
                            use App\Rules\usuario\registrar\duplicidadUsuario;
                    
                            public function rules()
                            {
                                return [
                                    "tipo" => "required",
                                    "usuario" => ["required","alpha_num",new duplicidadUsuario()],
                                ];
                            }
                            ?>
                        
                    
RULES CON PARAMETROS
                                                        
                                php artisan make:rule usuario/registrar/duplicidadUsuario
                            
                        
MODIFICAR ESTO EN EL REQUEST
                                                        
                                <?php
                                use App\Rules\usuario\registrar\duplicidadUsuario;
                    
                                public function rules()
                                {
                                    return [
                                        "tipo" => "required",
                                        "usuario" => ["required","alpha_num",new verificarUsuario(request()->id,request()->usuario)],
                                    ];
                                }
                                ?>
                            
                        
EL METODO EN RULE
                                                    
                            <?php
                            public function __construct($id = 0, $usuario="")
                            {
                                $this->id = $id;
                                $this->usuario=$usuario;
                            }
                    
                            public function passes($attribute, $value)
                            {
                                $verificarUsuario = DB::select("select count(*) as total from usuario where usuario=? and id_usuario!=? and estado=1", [
                                    $value,
                                    $this->id
                                ]);
                                if ($verificarUsuario[0]->total > 0) {
                                    return false;
                                } else {
                                    return true;
                                }
                            }
                    
                            public function message()
                            {
                                return "El usuario $this->usuario ya existe.";
                            }
                            ?>
                        
                    
ROUTES
Los Routes o Rutas es un sistema que se encargan de manejar el flujo de solicitudes y respuestas, desde y hacia el cliente.
                            
                                <?php
                                GET-POST-PUT-DELETE-PATCH
                                Route::get('curso-de-php',[PhpController::class,'index'])->name('php.index')->middleware('verified');
                                Route::get('curso-de-php-{id}',[PhpController::class,'index'])->name('php.index')->middleware('verified');

                                /* Comandos para ver la lista de Rutas creadas */
                                php artisan route:list                  // muestra la lista general de rutas creadas
                                php artisan route:list -v               // muestra las rutas creadas y el Middleware que se encarga de proteger
                                php artisan route:list --path=posts     // muestra solo las rutas que tiene la URI "posts"
                                php artisan route:list --except-vendor  // muestra solo las rutas creadas por el usuario(programador)
                                php artisan route:list --only-vendor    // muestra solo las rutas creadas por el propio sistema



                                //ruta con parametros opcionales
                                Route::get("/curso-{curso?}", function($curso="vacio"){
                                    return "Bienvenido al Curso $curso";
                                });

                                //ruta con expresiones regulares
                                Route::get("/suma/{a}/{b}", function ($a, $b) {
                                    return "La suma es: " . $a + $b;
                                })->where(["a" => "[0-9]+", "b" => "[0-9]+"]);
                                //tambien se puede usar 
                                //->whereAlpha(["a", "b"]); acepta solo letras
                                //->whereNumber(["a", "b"]); acepta solo numeros
                                //->whereAlphaNumeric(["a", "b"]); acepta letras y numeros

                                /* expresiones regulares GLOBALES
                                dentro de app/Providers/RouteServiceProvider */
                                public function boot()
                                {
                                    Route::pattern("id","[0-9]+");
                                    Route::pattern("id2","[0-9]+");
                                }

                                                                
                                ?>
                            
                        
MIDDLEWARE PERSONALIZADO
Nos van a ser útiles para validar las rutas(tener un control de ROLES Y PERMISOS)
Como crear un nuevo middleware
                                
                                    <?php
                                    php artisan make:middleware ClienteMiddleware
                                    ?>
                                
                            
Configurar la ruta
                                
                                    <?php                                    
                                    Route::resource("pagos", PagoController::class)->middleware(['verified', 'cliente']);
                                    ?>
                                
                            
Configurar Kernel.php en app/http/kernel.php
                                
                                    <?php                                    
                                    public function handle(Request $request, Closure $next)
                                    {
                                        'cliente' => \App\Http\Middleware\ClienteMiddleware::class,

                                        //ASI TIENE QUE VER
                                        protected $routeMiddleware = [
                                            'auth' => \App\Http\Middleware\Authenticate::class,
                                            'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
                                            'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
                                            'can' => \Illuminate\Auth\Middleware\Authorize::class,
                                            'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
                                            'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
                                            'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
                                            'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
                                            'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
                                            'cliente' => \App\Http\Middleware\ClienteMiddleware::class,
                                        ];
                                    }
                                    ?>
                                
                            
Configurar el Middleware
                                
                                    <?php                                    
                                    public function handle(Request $request, Closure $next)
                                    {
                                        if ($request->user()->tipo_usuario == 'administrador') {
                                            return $next($request);
                                        }
                                        if ($request->user()->tipo_usuario == 'cliente') {
                                            return redirect()->route("homeCliente");
                                        }
                                        return redirect()->route("home");
                                    }
                                    ?>
                                
                            
EXPRESIONES REGULARES
                            
                                <?php
                                usuario: "^[a-zA-Z0-9\_\-]{4,16}$", // Letras, numeros, guion y guion_bajo
                                nombre: "^[a-zA-ZÀ-ÿ\s]{1,40}$", // Letras y espacios, pueden llevar acentos.
                                password: "^.{4,12}$", // 4 a 12 digitos.
                                correo: "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$",
                                telefono: "^\d{7,14}$" // 7 a 14 numeros.

                                Coincidencias Basicas
                                    .       - Cualquier Caracter, excepto nueva linea
                                    \d      - Cualquier Digitos (0-9)
                                    \D      - No es un Digito (0-9)
                                    \w      - Caracter de Palabra (a-z, A-Z, 0-9, _)
                                    \W      - No es un Caracter de Palabra.
                                    \s      - Espacios de cualquier tipo. (espacio, tab, nueva linea)
                                    \S      - No es un Espacio, Tab o nueva linea.

                                    Limites
                                    \b      - Limite de Palabra
                                    \B      - No es un Limite de Palabra
                                    ^       - Inicio de una cadena de texto
                                    $       - Final de una cadena de texto

                                    Cuantificadores:
                                    *       - 0 o Más
                                    +       - 1 o Más
                                    ?       - 0 o Uno
                                    {3}     - Numero Exacto
                                    {3,4}   - Rango de Numeros (Minimo, Maximo)

                                    Conjuntos de Caracteres
                                    []      - Caracteres dentro de los brackets
                                    [^ ]    - Caracteres que NO ESTAN dentro de los brackets

                                    Grupos
                                    ( )     - Grupo
                                    |       - Uno u otro

                                ?>
                            
                        
METODOS
                                
                                    <?php
                                    METODOS DE ENVIO
                                    GET -> INDEX-CREATE-SHOW-EDIT
                                    POST -> STORE
                                    PUT o PATCH -> UPDATE
                                    DELETE -> DESTROY
                                    
                                    INDEX   //PARA MOSTRAR LA PAGINA DE INCIO "TABLA"
                                    CREATE  //PARA MOSTRAR LA PAGINA DE CREAR UN PRODUCTO
                                    STORE   //PARA EJECUTAR EL PROCESO DE INSERTAR PRODUCTO
                                    SHOW    //PARA MOSTRAR LA PAGINA DE VER DETALLES DEL PRODUCTO
                                    EDIT    //PARA MOSTRAR LA PAGINA DE EDICION DEL PRODUCTO
                                    UPDATE  //PARA EJECUTAR EL PROCESO DE ACTUALIZAR PRODUCTO
                                    DESTROY  //PARA EJECUTAR EL PROCESO DE ELIMINAR PRODUCTO
                                    
                                    public function index($id){
                                        return view('php.inicio');
                                    }
                                    ?>
                                
                            
COMO FUNCIONA BLADE
Blade es una herramienta que nos brinda laravel a la hora de crear interfaces de usuario.
Con blade creamos una interfaz(componente o layouts) y podemos utilizarlo desde otra pagina.
                            
                                <!DOCTYPE html>
                                <html lang="en">
                                <head>                            
                                    <title>@yield('titulo')</title>
                                </head>
                                <body>
                                    <header>...</header>
                                    <section class="content">
                                        @yield('contenido')
                                    </section>
                                    <footer>...</footer>
                                </body>
                                </html>
                            
                        
COMO LLAMAR Y UTILIZAR UNA PLANTILLA BLADE
                            
                                @extends('layouts/app')//INSTANCIANDO PARA UTILIZAR
                                @section('titulo', 'Curso Laravel')
                                @section('contenido')
                                    # aqui va el contenido
                                @endsection
                            
                        
FACTORY
Los factory son un modelo que nos proporciona laravel para poder ingresar(registrar) datos de prueba en nuestra base de datos.
                            
                                php artisan migrate     //REALIZAMOS LA MIGRACION
                                php artisan tinker      //INICIAMOS TINKER
                                >>> User::factory(20)->create()     //REGISTRAMOS 20 DATOS EN LA TABLA MODELO User
                            
                        
COMPARTIR DATOS ENTRE VISTAS
Nos ubicamos en App \Providers \AppServiceProvider
                            
                                use Illuminate\Support\Facades\View;//ES IMPRTANTE IMPORTAR ESTO
                                public function boot()
                                {
                                    $compartido = "Hola mundo";
                                    View::share('compartido', $compartido);
                                    // try {
                                    //     $sql = DB::select('select * from empresa');
                                    //     foreach ($sql as $value) {
                                    //         View::share('empresa', $value->nombre);
                                    //     }
                                    // } catch (\Throwable $th) {
                                    //     //throw $th;
                                    // }


                                    $usuario=DB::select(" select count(*) as 'total' from usuario where estado=1 ");
                                    View::share('usuario', $usuario[0]->total);

                                    $usuario=DB::select(" select count(*) as 'total' from cliente ");
                                    View::share('cliente', $usuario[0]->total);
                                }
                                
                            
                        
En la vista
                            
                                <h4 class="nombre-curso">{{$compartido}}</h4>
                            
                        
PERSONALIZAR LOGIN
CAMBIAR TABLA DEL LOGIN
  1. #crear un nuevo modelo
  2. php artisan make:model Usuario
  3. Por recomendacion es importante poner el campo USER Y PASSWORD en la tabla
  4. POR OBLIGACION LA TABLA DEBE CONTENER UN CAMPO "PASSWORD"
  5. Tenga mucho cuidado en el nuevo modelo class Usuario "extends Authenticatable"
En el modelo
                                                   
                                <?php
                                namespace App\Models;
                    
                                use Illuminate\Database\Eloquent\Factories\HasFactory;
                                use Illuminate\Foundation\Auth\User as Authenticatable;
                    
                                class Usuario extends Authenticatable
                                {
                                    use HasFactory;
                    
                                    public $table = "usuario";
                                    public $primaryKey = "id_usuario";
                                    //public $timestamps=false;
                                    protected $fillable = [
                                        'usuario', 'clave', 'nombre', 'apellido'
                                    ];
                                }
                                ?>
                            
                        
CREANDO UN NUEVO MODELO PARA LOGIN
                                                   
                                <?php
                                namespace App\models;
                                use Illuminate\Database\Eloquent\Model;
                                use Illuminate\Foundation\Auth\User as Authenticatable;
                                use Illuminate\Notifications\Notifiable;
                    
                                class Usuario extends Authenticatable
                                {
                                    use Notifiable;
                                    protected $table = 'usuario';
                                    protected $primaryKey = 'id';
                                    public $timestamps = false;
                                    protected $fillable = [
                                        'dni',
                                        'name',
                                        'apellido',
                                        'email',
                                        'password',
                                        'tipo',
                                        'telefono',
                                        'grado',
                                        'direccion',
                                        'estado',
                                        'foto',
                                        
                                    ];
                                }
                                ?>
                            
                        
CAMBIAR MODELO EN CONFIG/AUTH.PHP
                            
                                'providers' => [
                                    'users' => [
                                        'driver' => 'eloquent',
                                        'model' => App\Models\Usuario::class,
                                    ],
                    
                                    // 'users' => [
                                    //     'driver' => 'database',
                                    //     'table' => 'users',
                                    // ],
                                ],
                            
                        
CAMBIAR A MD5 LARAVEL EN vendor \laravel \framework \src \Illuminate \Auth EloquentUserProvider.php
                            
                                public function validateCredentials(UserContract $user, array $credentials)
                                {
                                    $plain = $credentials['password'];
                                    if (md5($plain) == $user->getAuthPassword()) {
                                        return true;
                                    } else {
                                        return false;
                                    }
                                    //return $this->hasher->check($plain, $user->getAuthPassword());
                                }
                            
                        
AGREGAMOS LO SIGUIENTE APP /HTTP /CONTROLLERS /AUTH /LOGINCONTROLLER
                            
                                public function username(){
                                    return 'usuario';//este es el nombre del campo de la tabla
                                }

                                //PARA VALIDAR INPUTS DEL LOGIN
                                use Illuminate\Http\Request;
                                protected function validateLogin(Request $request)
                                {
                                    $request->validate([
                                        $this->username() => 'required',
                                        'password' => 'required',
                                        'tipo' => 'required',
                                    ]);
                                }

                            
                        
CAMBIAMOS EL NAME DE LA VISTA LOGIN
                            
                                //cambiar el IDIOMA
                                <form action="{{ route('login') }}" method="POST">
                                    @csrf
                    
                                    <input name="usuario"
                                        value="{{ old('usuario') }}">
                                    <input name="password"
                                        value="{{ old('password') }}">
                                        
                                    @error('usuario')
                                        <small>{{ $errors->first('usuario') }}</small><br>
                                    @enderror
                                    @error('password')
                                        <small>{{ $errors->first('password') }}</small>
                                    @enderror
                    
                                    <button type="submit">Ingresar</button>
                                </form>
                            
                        
MENSAJE DE ERROR Y BOTON ENTRAR
                              
                                 //MENSAJE DE ERROR
                                 @error('usuario')
                                 <div class="alert alert-danger alert-dismissible fade show mb-1" role="alert">
                                       <small>{{ $errors->first('usuario') }}</small>
                                       <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                          <span aria-hidden="true">×</span>
                                       </button>
                                 </div>
                                 @enderror
      
                                 @if (session('mensaje'))
                                 <div class="alert alert-warning alert-dismissible fade show mb-0" role="alert">
                                    <small>{{ session('mensaje') }}</small>
                                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">
                                          <span aria-hidden="true">×</span>
                                    </button>
                                 </div>
                                 @endif
      
                                 //BOTON DE INICIAR SESION
                                 <form method="POST" action="{{ route('login') }}">
                                 </form>
      
                                 //BOTON DE CERRAR SESION
                                 <div class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
                                    <a class="dropdown-item" href="{{ route('logout') }}"
                                       onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                        {{ __('Logout') }}
                                    </a>
      
                                    <form id="logout-form" action="{{ route('logout') }}" method="POST" class="d-none">
                                        @csrf
                                    </form>
                                </div>
                              
                                      
BORRAR VERIFICACION DE EMAIL EN ROUTES/WEB.PHP
                            
                                Auth::routes(['verify' => true]);
                            
                        
COMENTAR EN controller /VerificationController
                            
                                //use VerifiesEmails;
                            
                        
CORREGIR EN VENDOR /LARAVEL /FRAMEWORK /SRC /ILUMINATE /ROUTING /CONTROLLER.PHP
                            
                                public function __call($method, $parameters)
                                {
                                    // throw new BadMethodCallException(sprintf(
                                    //     'Method %s::%s does not exist.', static::class, $method
                                    // ));
                                    return redirect()->route('home');
                                }
                            
                        
RESOLVER RESTRICCIONES DE CONSULTAS SQL
IR A config/database.php
                        
                            strict=>false //LINEA 59
                        
                    
LOGIN CON VARIOS TABLAS
PASO 1 Enviar datos de la BD a la vista Login
                                    
                                        public function showLoginForm()
                                        {
                                            $data = TipoUsuario::all();
                                            return view('auth.login', compact("data"));
                                        }
                                    
                                
ERROR acceso denegado 'forge'
Asegúrese de que en config/database.php su nombre de conexión predeterminado sea el mismo que en su .env.
                        
                            DB_CONNECTION=mysql
                            DB_HOST=127.0.0.1
                            DB_PORT=3306
                            DB_DATABASE=sisventa
                            DB_USERNAME=root
                            DB_PASSWORD=
                        
                    
                        
                            'mysql' => [
                                'driver' => 'mysql',
                                'url' => env('DATABASE_URL'),
                                'host' => env('DB_HOST', '127.0.0.1'),
                                'port' => env('DB_PORT', '3306'),
                                'database' => env('DB_DATABASE', 'sisventa'),
                                'username' => env('DB_USERNAME', 'root'),
                                'password' => env('DB_PASSWORD', ''),
                                'unix_socket' => env('DB_SOCKET', ''),
                                'charset' => 'utf8mb4',
                                'collation' => 'utf8mb4_unicode_ci',
                                'prefix' => '',
                                'prefix_indexes' => true,
                                'strict' => false,
                                'engine' => null,
                                'options' => extension_loaded('pdo_mysql') ? array_filter([
                                    PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
                                ]) : [],
                            ],
                        
                    
PERSONALIZAR REDIRECCION LOGIN
EDITAR APP /HTTP /CONTROLLERS /HOMECONTROLLER
                                
                                    
                                    public function index()
                                    {
                                        //return view('home');
                                        $estado = Auth::user()->estado;
                                        if ($estado == 1) {
                                            $sql = DB::select('select count(*) as total from usuario where tipo=1');
                                            return view('home')->with('sql', $sql);
                                        } else {
                                            session()->invalidate();
                                            session()->regenerateToken();
                                            return back()->with('mensaje', 'USUARIO SUSPENDIDO, consulte con el Administrador');
                                        }
                                    }



                                    //poner fecha de expiracion en HomeController
                                    // luego se recomienda ofuscar todo el codigo del archivo
                                    public function index()
                                    {
                                        $fecha = date("Y");
                                        $duracion = date("Y") + 2; //solo dura 2 años
                                        if ($fecha <= $duracion) {
                                            return view('home');
                                        } else {
                                            session()->invalidate();
                                            session()->regenerateToken();
                                            return back()->with('mensaje', "ACCESO DENEGADO, consulte con el desarrollador $duracion");
                                        }
                                    }

                                
                            
GENERAR GRÁFICOS
OJO
  1. Los saltos de linea y comentarios en el script de Chart js es muy importante
                        
                            <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
                        
                    
                        
                            <!-- Dentro de esta etiqueta se mostrará nuestra Gráfica -->
                            <canvas id="grafica" height="90" width="200px"></canvas>
                        
                    
MOSTRANDO DATOS DESDE CONTROLADOR
                        
                            <?php
                            //EN EL CONTROLADOR 
                            $venta=DB::select("");
                            $data=[0,0,0,0,0,0,0,0,0,0,0,0];//meses
                            foreach ($venta as $key => $value) {
                                $data[$value->fechaN-1]=$value->tot;//guardando los datos en cada mes correspondiente
                            }
                            View::share("datas", $data);//enviando los datos a la vista(GRAFICA)
                    
                            //EN EL CONTROLADOR OPCION 2
                            $data = [];
                            $data2 = [];
                            foreach ($sql4 as $key => $value) {
                                array_push($data, $value->nombre);
                                array_push($data2, $value->tot);
                            }
                            return view("vistas/reportes_ventas/hoy", compact("sql"))
                            ->with("data", $data)
                            ->with("data2", $data2);
                    
                            //DECODIFICANDO EL JSON QUE VIENE DESDE EL CONTROLADOR
                            let datas = <?php echo json_encode($datas); ?>
                    
                            //EN LA VISTA-GRAFICA 
                            const datosVentas2020 = {
                                data: datas,
                            };
                        
                    
GRAFICO DE LINEAS
                        
                            <script>
                                // Obtener una referencia al elemento canvas del DOM
                                const $grafica = document.querySelector("#grafica");
                                // Las etiquetas son las que van en el eje X. 
                                const etiquetas = ["Enero", "Febrero", "Marzo", "Abril"]
                                // Podemos tener varios conjuntos de datos. Comencemos con uno
                                const datosVentas2020 = {
                                    label: "Ventas por mes",
                                    data: [5000, 1500, 8000, 5102], // La data es un arreglo que debe tener la misma cantidad de valores que la cantidad de etiquetas
                                    backgroundColor: 'rgba(54, 162, 235, 0.2)', // Color de fondo
                                    borderColor: 'rgba(54, 162, 235, 1)', // Color del borde
                                    borderWidth: 1,// Ancho del borde
                                };
                                new Chart($grafica, {
                                    type: 'line',// Tipo de gráfica
                                    data: {
                                        labels: etiquetas,
                                        datasets: [
                                            datosVentas2020,
                                            // Aquí más datos...
                                        ]
                                    },
                                    options: {
                                        scales: {
                                            yAxes: [{
                                                ticks: {
                                                    beginAtZero: true
                                                }
                                            }],
                                        },
                                    }
                                });
                            </script>
                        
                    
GRAFICO DE BARRAS
                        
                            <script>
                                // Obtener una referencia al elemento canvas del DOM
                                const $grafica = document.querySelector("#grafica");
                                // Las etiquetas son las que van en el eje X. 
                                const etiquetas = ["Enero", "Febrero", "Marzo", "Abril"]
                                // Podemos tener varios conjuntos de datos. Comencemos con uno
                                const datosVentas2020 = {
                                    label: "Ventas por mes",
                                    data: [5000, 1500, 8000, 5102], // La data es un arreglo que debe tener la misma cantidad de valores que la cantidad de etiquetas
                                    backgroundColor: 'rgba(54, 162, 235, 0.2)', // Color de fondo
                                    borderColor: 'rgba(54, 162, 235, 1)', // Color del borde
                                    borderWidth: 1,// Ancho del borde
                                };
                                new Chart($grafica, {
                                    type: 'bar',// Tipo de gráfica
                                    data: {
                                        labels: etiquetas,
                                        datasets: [
                                            datosVentas2020,
                                            // Aquí más datos...
                                        ]
                                    },
                                    options: {
                                        scales: {
                                            yAxes: [{
                                                ticks: {
                                                    beginAtZero: true
                                                }
                                            }],
                                        },
                                    }
                                });
                            </script>
                        
                    
GRAFICO DE BARRAS CON 2 CONJUNTOS DE DATOS
                        
                            <script>
                                // Obtener una referencia al elemento canvas del DOM
                                const $grafica = document.querySelector("#grafica");
                                // Las etiquetas son las que van en el eje X. 
                                const etiquetas = ["Enero", "Febrero", "Marzo", "Abril"]
                                // Podemos tener varios conjuntos de datos
                                const datosVentas2020 = {
                                    label: "Ventas por mes - 2020",
                                    data: [5000, 1500, 8000, 5102], // La data es un arreglo que debe tener la misma cantidad de valores que la cantidad de etiquetas
                                    backgroundColor: 'rgba(54, 162, 235, 0.2)', // Color de fondo
                                    borderColor: 'rgba(54, 162, 235, 1)', // Color del borde
                                    borderWidth: 1,// Ancho del borde
                                };
                                const datosVentas2021 = {
                                    label: "Ventas por mes - 2021",
                                    data: [10000, 1700, 5000, 5989], // La data es un arreglo que debe tener la misma cantidad de valores que la cantidad de etiquetas
                                    backgroundColor: 'rgba(255, 159, 64, 0.2)',// Color de fondo
                                    borderColor: 'rgba(255, 159, 64, 1)',// Color del borde
                                    borderWidth: 1,// Ancho del borde
                                };
                                
                                new Chart($grafica, {
                                    type: 'bar',// Tipo de gráfica
                                    data: {
                                        labels: etiquetas,
                                        datasets: [
                                            datosVentas2020,
                                            datosVentas2021,
                                            // Aquí más datos...
                                        ]
                                    },
                                    options: {
                                        scales: {
                                            yAxes: [{
                                                ticks: {
                                                    beginAtZero: true
                                                }
                                            }],
                                        },
                                    }
                                });
                            </script>
                        
                    
GRAFICO CIRCULAR
                        
                            <script>
                                // Obtener una referencia al elemento canvas del DOM
                                const $grafica = document.querySelector("#grafica");
                                // Las etiquetas son las porciones de la gráfica
                                const etiquetas = ["Ventas", "Donaciones", "Trabajos", "Publicidad"]
                                // Podemos tener varios conjuntos de datos. Comencemos con uno
                                const datosIngresos = {
                                    data: [1500, 400, 2000, 7000], // La data es un arreglo que debe tener la misma cantidad de valores que la cantidad de etiquetas
                                    // Ahora debería haber tantos background colors como datos, es decir, para este ejemplo, 4
                                    backgroundColor: [
                                        'rgba(163,221,203,0.2)',
                                        'rgba(232,233,161,0.2)',
                                        'rgba(230,181,102,0.2)',
                                        'rgba(229,112,126,0.2)',
                                    ],// Color de fondo
                                    borderColor: [
                                        'rgba(163,221,203,1)',
                                        'rgba(232,233,161,1)',
                                        'rgba(230,181,102,1)',
                                        'rgba(229,112,126,1)',
                                    ],// Color del borde
                                    borderWidth: 1,// Ancho del borde
                                };
                                new Chart($grafica, {
                                    type: 'pie',// Tipo de gráfica. Puede ser dougnhut o pie
                                    data: {
                                        labels: etiquetas,
                                        datasets: [
                                            datosIngresos,
                                            // Aquí más datos...
                                        ]
                                    },
                                });
                            </script>
                        
                    
ENVIAR MAILS
PASO 1 : Crear un proyecto
                                
                                    <?php
                                        laravel new enviarEmail
                                    ?>
                                
                            
PASO 2 : Crear los controladores
                            
                                <?php
                                    php artisan make:mail ContactoMailable  //para configurar el envio de email
                                    php artisan make:controller ContactoController  
                                ?>
                            
                        
                            
                                <?php
                                    namespace App\Mail;
                                    use Illuminate\Bus\Queueable;
                                    use Illuminate\Mail\Mailable;
                                    use Illuminate\Queue\SerializesModels;
                                    
                                    class ContactoMailable extends Mailable
                                    {
                                        use Queueable, SerializesModels;
                                    
                                        public $subject = "INFORMACION DE CONTACTO"; //ESTO ES EL ASUNTO DEL CORREO
                                        public $contacto;//solo creamos para pasar variables a la vista y ENVIARSELOS
                                        /**
                                        * Create a new message instance.
                                        *
                                        * @return void
                                        */
                                        public function __construct($contacto)
                                        {
                                            $this->contacto = $contacto;//ALMACENAMOS LOS DATOS QUE SE RECIBEN PARA MOSTRAR EN LA VISTA
                                        }
                                    
                                        /**
                                        * Build the message.
                                        *
                                        * @return $this
                                        */
                                        public function build()
                                        {
                                            /* ESTO ES LA VISTA QUE SE VA A ENVIAR AL CORREO */
                                            return $this->view('mail.contactanos');
                                        }
                                    }
                                    
                                ?>
                            
                        
                            
                                <?php
                                    namespace App\Http\Controllers;
                                    use App\Mail\ContactoMailable;
                                    use Illuminate\Http\Request;
                                    use Illuminate\Support\Facades\Mail;
                                    
                                    class ContactoController extends Controller
                                    {
                                        public function index(Request $request)
                                        {
                                            $correo = new ContactoMailable($request->all());//enviamos estos datos al MAILABLE
                                            Mail::to($request->correo)->send($correo); //CORREO DEL RECEPTOR
                                            //return "mensaje enviado";
                                            //return redirect()->route('email.index')->with("mensaje", $request["correo"]);
                                            return redirect()->back()->with("mensaje", $request["correo"]);
                                        }
                                    }
                                                            
                                ?>
                            
                        
PASO 3 : Crear los rutas
                            
                                <?php
                                    Route::post('enviar-email', [ContactoController::class, 'index'])->name('email.index');
                                ?>
                            
                        
PASO 4 : Configurar .env
                                
                                    <?php
                                        /* OJO TENGA MUCHO CUIDADO CON LOS COMENTARIOS EN EL .env */
                                        MAIL_MAILER=smtp
                                        MAIL_HOST=smtp.gmail.com
                                        MAIL_PORT=587
                                        MAIL_USERNAME=isai.sandoval1999@gmail.com//correo del emisor
                                        MAIL_PASSWORD=isai74433542//correo del emisor
                                        MAIL_ENCRYPTION=TLS
                                        MAIL_FROM_ADDRESS=isai.sandoval1999@gmail.com//correo del emisor
                                        MAIL_FROM_NAME="ISAI SANDOVAL"//Nombre
                                    ?>
                                
                            
PASO 4 : Configurar .env en Servidor
  1. CONFIGURAR EN EL SERVIDOR
    1. Ingresar a tu CPanel
    2. Ir a la sección de Correo Electrónico o Cuentas de email
    3. Selecciona uno de los Dominio y click en conectar dispositivos
                                
                                    <?php
                                        /* OJO TENGA MUCHO CUIDADO CON LOS COMENTARIOS EN EL .env */
                                        MAIL_MAILER=smtp
                                        MAIL_HOST=mail.huracancito.com
                                        MAIL_PORT=587
                                        MAIL_USERNAME=_mainaccount@huracancito.com//este correo es del hosting
                                        MAIL_PASSWORD=zsrb3S82R8//esta clave es del login al hosting
                                        MAIL_ENCRYPTION=TLS
                                        MAIL_FROM_ADDRESS=_mainaccount@huracancito.com//este correo es del hosting
                                        MAIL_FROM_NAME="ISAI SANDOVAL"//Nombre
                                    ?>
                                
                            
PASO 5 : CREA LAS VISTAS
                            
                                    @if (session("mensaje"))
                                    <script>
                                        alert("se ha enviado un mensaje a {{session('mensaje')}}")
                                    </script>
                                    @endif
                    
                                    <form action="{{route('email.index')}}" method="post">
                                        @csrf
                                        <div>
                                            <input name="correo" type="email" placeholder="name@example.com">
                                            <textarea name="mensaje" rows="3"></textarea>
                                        </div>                                
                                        <button type="submit">Enviar</button>
                                    </form>                        
                            
                        
                            
                                <div>
                                    <h1>ESTE ES EL MENSAJE QUE SE VA A ENVIAR AL CORREO</h1>
                                    <h5>puede personalizarlo como quiera</h5>
                                    <section>
                                        <h1>{{$contacto['mensaje']}}</h1>
                                    </section>
                                </div>
                                

                                <!-- Un ejemplo -->
                                    <style>
                                        body {
                                            font-family: Arial, sans-serif;
                                            background-color: #f5f5f5;
                                            text-align: center;
                                        }
                                        h1 {
                                            margin-top: 50px;
                                            margin-bottom: 20px;
                                        }
                                        p {
                                            margin-bottom: 40px;
                                        }
                                        button {
                                            background-color: #007bff;
                                            color: #fff;
                                            border: none;
                                            padding: 10px 20px;
                                            border-radius: 5px;
                                            font-size: 18px;
                                            cursor: pointer;
                                            transition: background-color 0.3s;
                                        }
                                        button:hover {
                                            background-color: #0056b3;
                                        }
                                        a {
                                            color: white !important;
                                            text-decoration: none;
                                        }
                                    </style>
                                </head>

                                <body>
                                    <h1>Restablecer contraseña</h1>
                                    <p>Haga clic en el botón para restablecer su contraseña:</p>
                                    <button><a href="{{ route('recuperar.form', [$id_usuario, $codigo]) }}">Restablecer contraseña</a></button>
                                </body>


                            
                        
EN CASO DE ERROR ir a config/mail.php
                        
                            'smtp' => [
                                'transport' => 'smtp',
                                'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
                                'port' => env('MAIL_PORT', 587),
                                'encryption' => env('MAIL_ENCRYPTION', 'tls'),
                                'username' => env('MAIL_USERNAME'),
                                'password' => env('MAIL_PASSWORD'),
                                'timeout' => null,
                                'auth_mode' => null,
                                'stream' => [
                                    'ssl' => [
                                        'allow_self_signed' => true,
                                        'verify_peer' => false,
                                        'verify_peer_name' => false,
                                    ],
                                ],
                            ],
                            
                            //luego ejecuta esto
                            php artisan config:clear
                        
                    
GENERAR QR CON SIMPLE QRCODE
Ejemplo del controlador del SISTEMA DE APAFA
                            
                                <?php
                                use SimpleSoftwareIO\QrCode\Facades\QrCode;

                                foreach ($datosPadreFamilia as $key => $item) {
                                    //generar el qr
                                    QrCode::format('png')->size(500)->generate($item->padre_dni, public_path("qr/$id_padre.png"));
                                    //qr de historial padres
                                    QrCode::format('png')->size(500)->generate(route("historial.descargaPDF", $item->padre_dni), public_path("qr/historial/$id_padre.png"));
                                }
                                ?>
                            
                        
IMPORTAR DATOS DESDE EXCEL
Laravel excel es una de las herramientas que nos proporciona laravel para realizar exportanciones y incluso importaciones en formato EXCEL, CSV, PDF, ETC
                            
                                //OJO: si te sale un error al instalar el "maatwebsite/excel" -> prueba con esto
                                //1-> ve a xampp/php/php.ini->borra el ";" de "extension=gd"
                                //2-> intenta ejecutar nuevamente el comando
                                IMPORTANTE debes crear un modelo
                                CONFIGURAR TU MODELO
                                composer require maatwebsite/excel  //instalamos laravel excel
                                //creando un Import para importar datos del modelo User El archivo se puede encontrar en app/Exports
                                php artisan make:import UsersImport --model=User
                            
                        
EN EL PARTICIPANTEIMPORT
                            
                                <?php
                                //CON PARAMETROS
                                namespace App\Imports;

                                use App\Models\Participante;
                                use Maatwebsite\Excel\Concerns\ToModel;
                                use Maatwebsite\Excel\Concerns\WithBatchInserts;
                                use Maatwebsite\Excel\Concerns\WithChunkReading;
                                use Maatwebsite\Excel\Concerns\WithHeadingRow;

                                class ParticipanteImport implements ToModel, WithHeadingRow, WithBatchInserts, WithChunkReading
                                {

                                    private $idCurso;

                                    public function __construct($curso)
                                    {
                                        $this->idCurso = $curso;
                                    }

                                    public function model(array $row)
                                    {
                                        //aqui todos los encabezados del excel van en MINUSCULAS(si el encabezado tiene un espacio agregar el simbolo "_" )
                                        return new Participante([
                                            "id_curso" => $this->idCurso,
                                            "dni" => $row["dni_del_participante"],
                                            "nombre" => $row["nombres_del_participante"],
                                            "apellido" => $row["apellidos_del_participante"],
                                            "correo" => $row["correo_del_participante"],
                                        ]);
                                    }

                                    public function batchSize(): int
                                    {
                                        return 4000;
                                    }

                                    public function chunkSize(): int
                                    {
                                        return 4000;
                                    }
                                }
                                
                            
                            
EN LA RUTA
                            
                                //IMPORTANTE: la ruta debe ser de tipo POST
                                Route::POST('importParticipante', [ParticipanteController::class, 'importParticipante'])->name('importParticipante.index');
                            
                            
EN EL CONTROLADOR
                            
                                namespace App\Http\Controllers;
                    
                                use App\Exports\ModeloParticipanteExport;
                                use App\Exports\ParticipanteExport;
                                use App\Imports\ParticipanteImport;
                                use Illuminate\Http\Request;
                                use Illuminate\Support\Facades\DB;
                                use Maatwebsite\Excel\Facades\Excel;
                    
                                class ParticipanteController extends Controller
                                {
                                    public function importParticipante(Request $request)
                                    {
                                        $request->validate([
                                            "dato" => "required|file|mimes:xlsx,xls,csv",
                                            "curso" => "required"
                                        ]);
                                        $file = $request->file("dato"); //dato es el name
                                        Excel::import(new ParticipanteImport($request->curso), $file);
                                        return back()->with("CORRECTO", "Los datos se han cargado exitosamente");
                                    }
                                }
                            
                            
EN MI FORMULARIO
                            
                                <form action="" enctype="multipart/form-data" method="POST">
                                @csrf
                                    <div class="mb-4 mt-2 col-12 d-flex justify-content-between">
                                        <input type="file" name="dato" class="input input__text" value="{{ old('dato') }}">
                                        @error('dato')
                                            <small class="error error__text">{{ $message }}</small>
                                        @enderror
                                        <button type="submit" class="btn btn-primary px-5"><i class="fas fa-upload"></i> Cargar
                                            Datos</button>
                                    </div>
                                </form>
                            
                            
GENERAR EXCEL
Laravel excel es una de las herramientas que nos proporciona laravel para realizar exportanciones y incluso importaciones en formato EXCEL, CSV, PDF, ETC
                            
                                //OJO: si te sale un error al instalar el "maatwebsite/excel" -> prueba con esto
                                //1-> ve a xampp/php/php.ini->borra el ";" de "extension=gd"
                                //2-> intenta ejecutar nuevamente el comando
                                composer require maatwebsite/excel  //instalamos laravel excel
                                //creando un Export para exportar datos del modelo User El archivo se puede encontrar en app/Exports
                                php artisan make:export UsersExport --model=User    
                            
                        
EN EL USERSEXPORT
                            
                                namespace App\Exports;
                    
                                use Illuminate\Contracts\View\View;
                                use Illuminate\Support\Facades\DB;
                                use Maatwebsite\Excel\Concerns\FromView;
                    
                                class UsersExport implements FromView
                                {
                                    public function view(): View {
                                        $sql = DB::select('select *from users');
                                        return view('datos.index', [
                                            'usuarios' => $sql
                                        ]);
                                    }                            
                                }
                    
                    
                    
                                //CON PARAMETROS ENVIADOS DESDE EL CONTROLADOR
                                class NotasExport implements FromView
                                {
                                    private $anio;
                                    
                                    public function __construct($anio)
                                    {
                                        $this->anio = $anio;
                                    }
                    
                                    public function view(): View {
                                        $sql = $this->anio;
                                        return view('exportaciones.notas', [
                                            'sql' => $sql
                                        ]);
                                    }
                                }
                            
                            
EN LA RUTA
                            
                                Route::get('ver-excel', [UsuarioController::class, 'export'])->name('excel.index');
                            
                            
EN EL CONTROLADOR
                            
                                namespace App\Http\Controllers;
                    
                                use App\Exports\UsersExport;
                                use Maatwebsite\Excel\Facades\Excel;
                    
                                class UsuarioController extends Controller
                                {
                                    public function export()
                                    {
                                        return Excel::download(new UsersExport, 'usuarios.xlsx'); //csv
                                    }
                                }
                            
                            
EN VISTA PREVIA
                            
                                <table>
                                    <thead>
                                        <tr>
                                            <th>USUARIO</th>
                                            <th>CORREO</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        @foreach($usuarios as $user)
                                        <tr>
                                            <td>{{ $user->name }}</td>
                                            <td>{{ $user->email }}</td>
                                        </tr>
                                        @endforeach
                                    </tbody>
                                </table>
                            
                            
CONEXION BD
                                
                                    <?php
                                        DB_CONNECTION=mysql
                                        DB_HOST=127.0.0.1
                                        DB_PORT=3306
                                        DB_DATABASE=Nombre de la BD
                                        DB_USERNAME=Usuario
                                        DB_PASSWORD=Contraseña
                                    ?>
                                
                            
CONSULTAS SQL
                                
                                    <?php
                                    try {
                                        $sql = DB::update('update usuario set dni=?, name=?, apellido=?, email=?,telefono=?,
                                        direccion=? where id=?', [$dni, $nombre, $apellido, $email, $telefono, $direccion, $id]);
                                        if ($sql == 0) {
                                            $sql = 1;
                                        }
                                    } catch (\Throwable $th) {
                                    }
                                    if ($sql == 1) {
                                        return back()->with('correcto', 'Datos modificados correctamente');
                                    } else {
                                        return back()->with('incorrecto', 'Error al modificar los datos');
                                    }
                                    ?>
                                
                            
RETURN
                                
                                    <?php
                                    return view('ver-perfil/perfil', compact('sql'))->with('sql2', $sql2);//RETORNA UNA VISTA
                                    return view('notas/table')
                                    ->with('sql', [])                            
                                    ->with('grado', $grado)
                                    ->with('anio', $anio);
                    
                                    return redirect()->route('perfil.index', ['id' => 1]);//RETORNA UNA RUTA EN EPECIFICO
                    
                                    return back()->with("mensaje", "Notas eliminado Correctamente");//RETORNA A LA MISMA PAGINA
                    
                                    return response()->json(['dato' => $sql, 200]);//RETORNA UN JSON
                                    ?>
                                
                            
AJAX EN LARAVEL
                        
                            OPCIONAL
                            <!--<meta name="csrf-token" content="{{ csrf_token() }}">
                            $.ajaxSetup({
                                headers: {
                                    'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                                }
                            });-->
                    
                            <select name="consulta" id="consulta">
                                <option value="">seleccionar consulta...</option>
                                @foreach ($sql2 as $item)
                                <option value="{{$item->id_consulta}}">{{$item->descripcion}}</option>
                                @endforeach
                            </select>
                    
                            <script>
                                function buscar() {
                                    let valor=document.getElementById("consulta").value;
                                           
                                    var ruta = "{{ url('busqueda-por-lista/') }}/" + valor + "";
                                    //var ruta = "{{ route('busqueda.busqueda',['valor']) }}";
                                    $.ajax({
                                        url: ruta,
                                        type: "get",
                                        success: function(data) {
                                            let tr=document.createElement("tr");
                                            let tbody=document.querySelector("tbody");
                                            let fragmento=document.createDocumentFragment();
                                            let td="";
                                            data.dato.forEach(function(item,index){
                                                td+=`<tr><td>${item.paciente}</td><td>${item.fecha_cita}</td><td>${item.ape_nom}</td><td>${item.descripcion}</td></tr>`;
                                                //tr.innerHTML=td;
                                                tbody.innerHTML=td
                                                console.log(item)
                                            })
                                        },
                                        error: function(data) {
                                            $("#prom").html(data.error);
                                            let tbody=document.querySelector("tbody");
                                            //let tr=document.querySelector("tr");
                                            tbody.innerHTML=""
                                            // if ($.isEmptyObject(errors) == false) {
                                            //     $.each(errors.errors, function(key, value) {
                                            //         var errorId = '#' + key + 'Error';
                                            //         $(errorId).removeClass("d-none");
                                            //         $(errorId).text(value);
                                            //     })
                                            // }
                                        }
                                    })
                                }
                            
                            </script>
                            
                            <script>
                                let desc=document.getElementById("consulta");
                                desc.addEventListener("change",buscar)
                                console.log(desc.value)
                            </script>
                    
                            RETORNANDO UN JSON
                            <!--return response()->json(['dato' => $sql, 200]);-->
                        

                    
                                                            
                                    //UN EJEMPLO EN EL CONTROLADOR
                                    public function buscarProvincia($id)
                                    {
                                        $consulta = DB::select("select * from provincias where idDepa = $id");
                                        if (count($consulta) > 0) {
                                            return response()->json([
                                                'success' => true,
                                                'data' => $consulta
                                            ], 200);
                                        } else {
                                            return response()->json([
                                                'error' => true,
                                                'message' => 'No se encontraron resultados para la consulta'
                                            ], 400);
                                        }
                                    }
                                
                            
AJAX EN LARAVEL PARTE 2
                        
                            EN EL APP
                            <!--<meta name="csrf-token" content="{{ csrf_token() }}">-->
                    
                            <script>
                                function vender(){
                                    let cliente=document.getElementById("cliente").value;
                                    let id=document.getElementById("id").value;
                                    let total=document.getElementById("pagoTotal").innerHTML;
                            
                                    let tr2=document.querySelectorAll(".tr2")
                                    let datos=[];
                                    tr2.forEach(function(el,index){
                                        datos.push(
                                            {
                                                "cliente":cliente,
                                                "usuario":id,
                                                "producto":el.children[0].children[0].value,
                                                "precio":el.children[1].children[0].value,
                                                "cantidad":el.children[2].children[0].value,
                                                "subtotal":el.children[3].children[0].value,
                                                "total":total
                                            }
                                        )
                                    });
                                    
                                    console.log(datos)
                                    
                                    
                                    var ruta = "{{ url('registrar-salida') }}";
                                    $.ajax({
                                        url: ruta,
                                        type: "post",
                                        data:{valores : JSON.stringify(datos)},
                                        headers: {
                                            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                                        },
                                        success: function(data) {},
                                        error: function(data) {}
                                    })
                                }
                            </script>
                        
                    
                        
                            EN LA RUTA
                            Route::post("/registrar-salida", [SalidaController::class, "registrarVenta"]);
                    
                            EN EL CONTROLADOR
                            public function registrarVenta(Request $request)
                            {
                                $valores = $request->valores;
                                $valores = json_decode($valores);
                    
                                return response()->json(['dato2' => $valores, 200]);
                            }
                        
                    
ENVIAR IMAGEN A LA BD DESDE UN FORMULARIO
PASO 01: el formulario debe debe llevar el atributo enctype
                                
                                    <form method="POST" action="{{route('perfil.store')}}" enctype="multipart/form-data">
                                    @csrf
                                        <input type="file" class="form-control" name="foto">
                                        <input type="submit">
                                    </form>
                                
                            
PASO 02: Recibir la imagen enviada desde el controlador
                                
                                    <?php
                                    $foto = file_get_contents($_FILES['foto']['tmp_name']);
                                    ?>
                                
                        
PASO 03: Mostrar en pantalla la imagen
                                
                                    <img src="data:image/jpg;base64,<?= base64_encode($item->foto) ?>" alt="">
                                
                            
OTROS COMANDOS
LLAMAR RUTA CON PARAMETROS
                        
                           <a href="{{ route('comunicado.show', ["$i->id1", "$i->id2", "$i->id3"]) }}"></a>
                        
                     
SELECT AUTOMATICO
                        
                            <select name="grado" id="grado">
                                <option value="">Grado y seccion...</option>
                                @foreach ($sql2 as $item)
                                <option {{ $item->id_grado == $i->id_grado ? 'selected' : '' }}
                                    value="{{ $item->id_grado }}">
                                    {{ $item->grado . ' ' . $item->seccion1 }}
                                </option>
                                @endforeach
                            </select>
                        
                    
DAR FORMATO A MENUS DE NAVEGACION
                        
                            <li class="treeview {{ Request::is('usuarios*', 'estudiantes*', 'docentes*', 'directors*', 'tipo-usuarios*') ? 'menu-open' : '' }}"></li>
                            <a style="{{ Request::is('usuarios*', 'estudiantes*', 'docentes*', 'directors*', 'tipo-usuarios*') ? 'border-left:solid 2px #00C4FD!important' : '' }}"></a>
                        
                    
PWA
                            
                               SI HAY ERROR CONFIGURAR LO SIGUIENTE
                               ubicate en public/serviceworker.js
                    
                               var staticCacheName = "pwa-v" + new Date().getTime();//intenta eliminar esta linea
                                var filesToCache = [
                                    '/offline',
                                    '/css/app.css',//corrige esta linea
                                    '/js/app.js',//corrige esta linea
                                    '/images/icons/icon-72x72.png',
                                    '/images/icons/icon-96x96.png',
                                    '/images/icons/icon-128x128.png',
                                    '/images/icons/icon-144x144.png',
                                    '/images/icons/icon-152x152.png',
                                    '/images/icons/icon-192x192.png',
                                    '/images/icons/icon-384x384.png',
                                    '/images/icons/icon-512x512.png',
                                ];
                    
                            
                        
                        
                            # link de ayuda
                            https://omarbarbosa.com/posts/convertir-aplicacion-laravel-en-una-pwa
                            #correr el servidor
                            php artisan serve
                            #instalar
                            composer require silviolleite/laravelpwa
                            #publicar
                            php artisan vendor:publish --provider="LaravelPWA\Providers\LaravelPWAServiceProvider"
                            /*En la carpeta config encontraremos el archivo laravelpwa.php y 
                            haremos la modificaciones necesarias como el nombre, corto y largo, 
                            que la aplicación tendrá, también los colores que apliquen de 
                            acuerdo a la paleta de colores del diseño. En mi caso, el archivo quedó así:*/
                    
                            /*Reemplazo de imágenes En el archivo de configuración anterior 
                            hay dos array que relacionan las imágenes (iconos, splash) 
                            que requiere toda aplicación web progresiva para su normal 
                            funcionamiento; debes reemplazarlas con tus iconos y personalizar 
                            los splash, los cuales se verán de primera mano mientras se carga 
                            la aplicación. Estas imágenes fueron publicadas en la carpeta pública,
                            en la ruta public/images/icons.*/
                    
                            /*
                            Incluir directiva de Blade Para que los assets estén disponibles
                             en el navegador, debemos incluir la directiva @laravelPWA de Blade 
                             en el layout, el cual es la vista padre. Es importante que sea 
                             antes de cerrar el head.
                    
                            <html>
                            <head>
                                <title>Aplicación</title>
                                ...
                                @laravelPWA
                            </head>
                            <body>
                                ...
                                @yield('content')
                                ...
                            </body>
                            </html>
                            */
                        
                    
WHATSAPP API
                                
                                    <?php
                                    //Primero debes crear y configurar tu api aqui https://developers.facebook.com/docs/whatsapp/

                                    //Instalamos guzzlehttp
                                    composer require guzzlehttp/guzzle

                                    //En la ruta
                                    Route::get("/enviar-mensaje", [EnviarController::class, "enviar"]);

                                    //En el controlador
                                    public function enviar()
                                    {
                                        try {
                                            $token = 'EAATiSXnyZBRwBAL5VaQZC9PVE9ltUySuJqjvRQVTlDqZCkrNmML1QSJUCDcU7vnkZCJqNDCM64Y3zdKQzKBZARjAl2jo8j0M5PP5cOpY68tI2HpZA9SNzcv5epqYVUg4k986gWeje5x3eXtz9kpm85CD6LbZBPRMmBsoQG6RxJ4hWiVSyRM3QcO11ParAGix8bsxImI0cog6ojJESZAmOgHk';
                                            $phoneId = '101091292888818';
                                            $version = 'v15.0';
                                            $payload = [
                                                'messaging_product' => 'whatsapp',
                                                'to' => '51973698935',
                                                'type' => 'template',
                                                'template' => [
                                                    'name' => 'hello_world',
                                                    'language' => [
                                                        'code' => 'en_US'
                                                    ]
                                                ]
                                            ];

                                            $mensaje = Http::withToken($token)->post('https://graph.facebook.com/' . $version . '/' . $phoneId . '/messages', $payload)->throw()->json();
                                            return response()->json([
                                                'success' => true,
                                                'data' => $mensaje
                                            ], 200);
                                        } catch (\Throwable $e) {
                                            return response()->json([
                                                'success' => false,
                                                'error' => $e->getMessage(),
                                            ], 500);
                                        }
                                    }


                                    ?>
                                
                            
PAGINACION EN LARAVEL
Paso 1: Debes tener creado tu Modelo
                                
                                    <?php

                                    namespace App\Models;

                                    use Illuminate\Database\Eloquent\Factories\HasFactory;
                                    use Illuminate\Database\Eloquent\Model;

                                    class Estudiante extends Model
                                    {
                                        use HasFactory;
                                        protected $table = "estudiante";
                                        protected $primaryKey = "id_estudiante";
                                        public $timestamps = false;
                                        protected $fillable = [
                                            "dni", "nombre", "apellido_paterno", "apellido_materno", "estado_voto", "grado"
                                        ];
                                    }

                                
                            
Paso 2: En el controlador
                                
                                    public function index()
                                    {
                                        $sql = Estudiante::paginate(5);
                                        return view("vistas/estudiante")
                                            ->with("estudiante", $sql);
                                    }
                                
                            
Paso 3: En la vista
                                
                                    @foreach ($estudiantes as $estudiante)
                                        // mostrar datos del estudiante
                                    @endforeach

                                    <div class="text-right">
                                        {{ $estudiante->links('pagination::bootstrap-4') }}
                                        Mostrando {{ $estudiante->firstItem() }} - {{ $estudiante->lastItem() }} de {{ $estudiante->total() }}
                                        resultados
                                    </div>
                                
                            
OBTENER EL ID ASIGNADO A UN REGISTRO
                                
                                    <?php
                                    $id = DB::table('usuario')->insertGetId([
                                        'nombre' => $nombre,
                                        'apellido_paterno' => $ape_pat,
                                        'apellido_materno' => $ape_mat,
                                        'usuario' => $usuario,
                                        'password' => $clave,
                                        'correo' => $correo,
                                        'foto' => $foto,
                                        'estado' => 1,
                                    ]);

                                    // $id contiene el ID asignado al nuevo registro en la tabla "usuario"


                                
                            
GUARDAR ARCHIVOS EN SERVIDOR
                                
                                    <?php
                                    //guardando la foto en servidor
                                    try {
                                        $file = $request->file("txtfoto");
                                        $nombreFile = "usuario-" . $usuario . "." . $file->guessExtension();
                                        $ruta = public_path("foto/usuario/" . $nombreFile);
                                        copy($file, $ruta);
                                    } catch (\Throwable $th) {
                                        $ruta = "";
                                    }

                                    if (file_exists($ruta)) {
                                    } else {
                                        return back()->with("INCORRECTO", "Hubo un error al subir la foto ");
                                    }


                                    //eliminamos la img anterior
                                    //OJO: si vas a reemplazar una imagen por otra con el mismo nombre NO es necesario eliminar, porque solo lo reemplazará
                                    $rutaAn = public_path("foto/usuario/" . $request->txtid);
                                    if (unlink("$rutaAn")) {
                                        // El archivo se eliminó correctamente
                                    } else {
                                        // No se pudo eliminar el archivo
                                    }
                                
                            
CONFIGURAR SWEET ALERT
                                
                                    <form action="{{ route('estudiante.delete', $item->id_estudiante) }}" method="get"
                                        class="d-inline formulario-eliminar">
                                    </form>
                                    <a href="#" class="btn btn-sm btn-danger eliminar"
                                        data-id="{{ $item->id_estudiante }}">
                                        <i class="fas fa-trash-alt"></i>
                                    </a>
                                
                            
                                
                                    $(document).on("click", "a.eliminar", function (event) {
                                        event.preventDefault(); // Evita que se siga el enlace
                                        var form = $(this).prev(".formulario-eliminar"); // Obtiene el formulario anterior al botón
                                        var url = form.attr("action"); // Obtiene la URL de la ruta de eliminación
                                        var csrf_token = $('meta[name="csrf-token"]').attr("content"); // Obtiene el token CSRF
                                    
                                        Swal.fire({
                                            title: "¿Está seguro?",
                                            text: "¡ No podrá recuperar este registro !",
                                            icon: "warning",
                                            showCancelButton: true,
                                            confirmButtonColor: "#2CB073",
                                            cancelButtonColor: "#d33",
                                            confirmButtonText: "Si, Eliminar",
                                            cancelButtonText: "No, Salir",
                                            reverseButtons: true,
                                            padding: "20px",
                                            backdrop: true,
                                            position: "top",
                                            allowOutsideClick: true,
                                            allowEscapeKey: true,
                                            allowEnterKey: false,
                                        }).then((confirm) => {
                                            if (confirm.isConfirmed) {
                                                // Agrega el token CSRF al formulario
                                                form.append(
                                                    ''
                                                );
                                                form.submit(); // Envía el formulario
                                            }
                                        });
                                    });
                                        
                                
                            
DESCARGAR SQL DE BD (BACKUP)
                                
                                    Route::get('backup', function () {
                                        $dbname = 'trabajo_sistema_nota3';
                                        $dbuser = 'root';
                                        $dbpass = '';
                                        $dbhost = 'localhost';
                                    
                                        $backupFile = $dbname . date("Y-m-d-H-i-s") . '.sql';
                                        $command = "mysqldump --user=$dbuser --password=$dbpass --host=$dbhost $dbname > $backupFile";
                                    
                                        system($command, $output);
                                    
                                        header('Content-Description: File Transfer');
                                        header('Content-Type: application/octet-stream');
                                        header('Content-Disposition: attachment; filename=' . basename($backupFile));
                                        header('Expires: 0');
                                        header('Cache-Control: must-revalidate');
                                        header('Pragma: public');
                                        header('Content-Length: ' . filesize($backupFile));
                                        readfile($backupFile);
                                    })->name('backup')->middleware('verified');                                    
                                
                            
QUICKCHART
Sirve para imprimir Graficos en archivos PDF. Lo que este complemento hace es convertir tu grafico ChartJS en IMG y mostrarlo en el pDF
API REST
CREA TU CONEXION A LA BD
CREA TU CONTROLADOR
                        
                            <?php
                            public function index()
                            {
                                $sql = DB::select("select * from producto");
                                return response()->json($sql, 200);
                            }
                    
                    
                            public function store(Request $request)
                            {
                                $request->validate([
                                    "nombre" => "required",
                                    "cantidad" => "required",
                                    "total" => "required"
                                ]);
                                $sql = DB::insert("insert into producto(nombre,cantidad,total)values(?,?,?)", [
                                    $request->nombre,
                                    $request->cantidad,
                                    $request->total
                                ]);
                                if ($sql == 1) {
                                    return response()->json(["mensaje" => "producto registrado"], 200);
                                } else {
                                    return response()->json(["error" => "error al registrar"], 201);
                                }
                            }
                    
                            
                            public function show($id)
                            {
                                $sql = DB::select("select * from producto where id_producto=?", [
                                    $id
                                ]);
                                return response()->json($sql, 200);
                            }
                    
                    
                            public function update(Request $request, $id)
                            {
                                $request->validate([
                                    "nombre" => "required",
                                    "cantidad" => "required",
                                    "total" => "required"
                                ]);
                    
                                try {
                                    $sql = DB::update("update producto set nombre=?, cantidad=?, total=? where id_producto=$id", [
                                        $request->nombre,
                                        $request->cantidad,
                                        $request->total
                                    ]);
                                    if ($sql == 0) {
                                        $sql = 1;
                                    }
                                } catch (\Throwable $th) {
                                    $sql = 0;
                                }
                    
                                if ($sql == 1) {
                                    return response()->json(["mensaje" => "producto actualizado"], 200);
                                } else {
                                    return response()->json(["error" => "error al actualizar"], 201);
                                }
                            }
                    
                    
                            public function destroy($id)
                            {
                                $sql = DB::delete("delete from producto where id_producto=?", [
                                    $id
                                ]);
                                if ($sql == 1) {
                                    return response()->json(["mensaje" => "producto eliminado"], 200);
                                } else {
                                    return response()->json(["error" => "error al eliminar"], 201);
                                }
                            }
                            ?>
                        
                    
CREA TU RUTA
                        
                            <?php
                            Route::get("listar-productos", [ProductoController::class, "index"]);
                            Route::get("lista-productos-id-{id}", [ProductoController::class, "show"]);
                            Route::post("crear-producto", [ProductoController::class, "store"]);
                            Route::post("actualizar-producto-{id}", [ProductoController::class, "update"]);
                            Route::get("eliminar-producto-{id}", [ProductoController::class, "destroy"]);
                            ?>
                        
                    
URL
                        
                            http://127.0.0.1:8000/api/lista-productos
                            
                            http://127.0.0.1:8000/api/crear-producto
                            en header:
                            Accept  application/json
                    
                            en  body raw:
                            {
                                "nombre":"mouse",
                                "cantidad":"20",
                                "total":"150"
                            }
                        
                    
VITE
Pasos para correr proyecto con Vite
  1. npm install
  2. npm run dev
Pasos para correr proyecto con Vite en Producción
  1. npm run build
  2. asegurate de que .GitIgnore no lo tenga en cuenta