Pré-requisitos

  1. Instalar compositor
  2. Configure seu servidor local (xampp, wamp)
  3. Verifique se você possui um editor de código instalado (texto sublime, vs código, átomo etc)
  4. Instalar Git (permite controle de origem e controle de versão)

Começando

Com o Git instalado, você tem acesso ao Git bash. Com o bash aberto, você pode trabalhar com o terminal para executar comandos que permitem instalar e usar o Laravel e seus pacotes facilmente.

Instale o Laravel via compositor

Depois de atender a todas as condições acima, usaremos o comando abaixo para configurar o instalador do Laravel:

composer global require laravel/installer

O comando acima permite fazer o download do instalador do Laravel usando o compositor que instalamos anteriormente.

laravel new project_name

Esse processo de instalação demora um pouco, então seja paciente. Nota que a instalação será feita no diretório que você especificar em seu terminal bash ou em qualquer terminal que você escolher usar.

Gerando um andaime de autenticação básica

Depois de instalar uma cópia do aplicativo Laravel, devemos gerar um andaime de autenticação básico.

cd project_namecomposer require laravel/uiphp artisan ui vue --auth

O comando acima instalará a exibição de layout, exibição de registro e exibição de login, bem como rotas para toda a autenticação do usuário.

Configurando variáveis ​​de ambiente no arquivo .env

Em seguida, precisamos configurar nossas variáveis ​​de ambiente e estabelecer uma conexão com nosso banco de dados (Neste artigo, usaremos um endereço IP fictício compartilhado)

DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=your_database_nameDB_USERNAME=server_usernameDB_PASSWORD=server_passwordMAIL_DRIVER=smtpMAIL_HOST=domain.comMAIL_PORT=465MAIL_USERNAME=noreply@domain.comMAIL_PASSWORD=domain_passwordMAIL_ENCRYPTION=sslMAIL_FROM_ADDRESS=noreply@domain.comMAIL_FROM_NAME="${APP_NAME}"

Agora terminamos de configurar a conexão com o banco de dados. No meu caso, trabalho com o Xampp, onde tenho DB_USERNAME=root e DB_PASSWORD=. Também não se esqueça de iniciar o servidor local, como mostrado abaixo.

Imagem do servidor xampp

Versionando o Banco de Dados e Iniciando o Servidor de Desenvolvimento

Antes de poder executar migrações no Laravel, você precisa estabelecer uma conexão com seu banco de dados. Desde que eu especifiquei your_database_name na configuração .env acima, posso clicar em “criar” e o phpMyAdmin criará um banco de dados vazio.

your database name
Adicionando um nome de banco de dados

No Git bash, navegue ou faça o CD no diretório project_name diretório e execute o comando abaixo:

cd project_namephp artisan migrate 

Isso executará todas as migrações padrão do Laravel em nosso aplicativo, desde que você tenha criado uma correspondência DB_DATABASE que criamos acima.

php artisan serve

Agora podemos iniciar nosso servidor de desenvolvimento:

php artisan serve
Iniciando servidor de desenvolvimento

Configure uma página de contato no pasta recursos> visualizações como isso:

@extends('layouts.client.app')@section('content')<!-- contact section -->    <div class="contact">        <div class="container">            <div class="row justify-content-center">                <div class="col-xl-7 col-lg-8 col-md-8">                    <div class="section-title">                        <h2>Contact Us</h2>                    </div>                </div>            </div>            @if(session('status'))            <div class="row justify-content-center">                <div class="col-xl-8 col-lg-8 col-md-8">                    <div class="alert alert-success alert-dismissible fade show" role="alert">                        <strong>Success ! </strong>  &nbsp; {{ session('status') }}                        <button type="button" class="close" data-dismiss="alert" aria-label="Close">                            <span aria-hidden="true">&times;</span>                        </button>                    </div>                </div>            </div>            @endif        </div>    </div>@endsection

O trecho de código acima estenderá um arquivo de layouts contendo a seção do cabeçalho. Ele também contém o título da seção “Entre em contato”, juntamente com uma mensagem retornada e exibida ao usuário se e somente se a mensagem de email foi enviada com êxito.

O foco principal aqui está na seção de formulário que você pode ver no próximo snippet de código:

<div class="row justify-content-center">    <div class="col-xl-8 col-lg-8">        <div class="login-form">            <form method="POST" action="{{ route('addContact') }}" enctype="multipart/form-data">                @csrf                <div class="row">                    <div class="col-6">                        <div class="form-group">                            <label for="name" class="col-form-label text-md-right">{{ __('Full Name') }}</label>                            <input type="text" class="form-control @error('fullname') is-invalid @enderror" name="fullname" value="{{ isset(Auth::user()->firstname) ? Auth::user()->firstname : '' }} {{ isset(Auth::user()->lastname) ? Auth::user()->lastname : '' }}" required autocomplete="Fullname" autofocus>                            @error('fullname')                                <span class="invalid-feedback" role="alert">                                    <strong>{{ $message }}</strong>                                </span>                            @enderror                        </div>                    </div>                                        <div class="col-6">                        <div class="form-group">                            <label for="email" class="col-form-label text-md-right">{{ __('Email Address') }}</label>                            <input type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ isset(Auth::user()->email) ? Auth::user()->email : '' }}" required autocomplete="email" autofocus>                            @error('email')                                <span class="invalid-feedback" role="alert">                                    <strong>{{ $message }}</strong>                                </span>                            @enderror                        </div>                                        </div>                    <div class="col-6">                                                <div class="form-group">                            <label for="name" class="col-form-label text-md-right">{{ __('Phone Number') }}</label>                            <input type="text" class="form-control @error('phone_number') is-invalid @enderror" name="phone_number" value="{{ isset(Auth::user()->phone_number) ? Auth::user()->phone_number : '' }}" required autocomplete="phone_number" autofocus>                            @error('phone_number')                                <span class="invalid-feedback" role="alert">                                    <strong>{{ $message }}</strong>                                </span>                            @enderror                        </div>                    </div>                    <div class="col-6">                                                            <div class="form-group">                            <label for="name" class="col-form-label text-md-right">{{ __('Subject') }}</label>                            <input type="text" class="form-control @error('subject') is-invalid @enderror" name="subject" required autofocus>                            @error('subject')                                <span class="invalid-feedback" role="alert">                                    <strong>{{ $message }}</strong>                                </span>                            @enderror                        </div>                    </div>                    <div class="col-6">                        <div class="form-group">                            <label for="password" class="col-form-label text-md-right">{{ __('Message') }}</label>                            <textarea class="form-control @error('message') is-invalid @enderror" name="message" required></textarea>                            @error('message')                                <span class="invalid-feedback" role="alert">                                    <strong>{{ $message }}</strong>                                </span>                            @enderror                        </div>                    </div>                    <div class="col-6">                                        <div class="form-group">                            <label for="name" class="col-form-label text-md-right">{{ __('Attach Screenshot') }}</label>                            <input type="file" accept="image/*" class="form-control @error('screenshot') is-invalid @enderror" name="screenshot" autofocus>                        </div>                    </div>                </div>                <div class="form-group row mb-0">                    <div class="col-md-6 offset-md-4">                        <button type="submit" class="btn btn-primary">                            {{ __('Send Message') }}                        </button>                    </div>                </div>            </form>        </div>    </div></div>

O trecho acima contém os vários campos de entrada que usaremos no processamento de informações do usuário. Os campos incluem NOME COMPLETO, ENDEREÇO ​​DE E-MAIL, NÚMERO DE TELEFONE, ASSUNTO ou OBJETIVO, MENSAGEM, CARGA DE IMAGEM (se houver) e finalmente um botão ENVIAR MENSAGEM para processar o envio do formulário.

Em seguida, mesclaremos os dois trechos de código para torná-los muito mais significativos.

@extends('layouts.client.app')@section('content')<div class="contact">    <div class="container">        <div class="row justify-content-center">            <div class="col-xl-7 col-lg-8 col-md-8">                <div class="section-title">                    <h2>Contact Us</h2>                </div>            </div>        </div>        @if(session('status'))        <div class="row justify-content-center">            <div class="col-xl-8 col-lg-8 col-md-8">                <div class="alert alert-success alert-dismissible fade show" role="alert">                    <strong>Success ! </strong>  &nbsp; {{ session('status') }}                    <button type="button" class="close" data-dismiss="alert" aria-label="Close">                        <span aria-hidden="true">&times;</span>                    </button>                </div>            </div>        </div>        @endif        <div class="row justify-content-center">                <div class="col-xl-8 col-lg-8">                    <div class="login-form">                        <form method="POST" action="{{ route('addContact') }}" enctype="multipart/form-data">                            @csrf                            <div class="row">                                <div class="col-6">                                    <div class="form-group">                                        <label for="name" class="col-form-label text-md-right">{{ __('Full Name') }}</label>                                        <input type="text" class="form-control @error('fullname') is-invalid @enderror" name="fullname" value="{{ isset(Auth::user()->firstname) ? Auth::user()->firstname : '' }} {{ isset(Auth::user()->lastname) ? Auth::user()->lastname : '' }}" required autocomplete="Fullname" autofocus>                                        @error('fullname')                                            <span class="invalid-feedback" role="alert">                                                <strong>{{ $message }}</strong>                                            </span>                                        @enderror                                    </div>                                </div>                                                                <div class="col-6">                                    <div class="form-group">                                        <label for="email" class="col-form-label text-md-right">{{ __('Email Address') }}</label>                                        <input type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ isset(Auth::user()->email) ? Auth::user()->email : '' }}" required autocomplete="email" autofocus>                                        @error('email')                                            <span class="invalid-feedback" role="alert">                                                <strong>{{ $message }}</strong>                                            </span>                                        @enderror                                    </div>                                                                </div>                                <div class="col-6">                                                                        <div class="form-group">                                        <label for="name" class="col-form-label text-md-right">{{ __('Phone Number') }}</label>                                        <input type="text" class="form-control @error('phone_number') is-invalid @enderror" name="phone_number" value="{{ isset(Auth::user()->phone_number) ? Auth::user()->phone_number : '' }}" required autocomplete="phone_number" autofocus>                                        @error('phone_number')                                            <span class="invalid-feedback" role="alert">                                                <strong>{{ $message }}</strong>                                            </span>                                        @enderror                                    </div>                                </div>                                <div class="col-6">                                                                                                <div class="form-group">                                        <label for="name" class="col-form-label text-md-right">{{ __('Subject') }}</label>                                        <input type="text" class="form-control @error('subject') is-invalid @enderror" name="subject" required autofocus>                                        @error('subject')                                            <span class="invalid-feedback" role="alert">                                                <strong>{{ $message }}</strong>                                            </span>                                        @enderror                                    </div>                                </div>                                <div class="col-6">                                    <div class="form-group">                                        <label for="password" class="col-form-label text-md-right">{{ __('Message') }}</label>                                        <textarea class="form-control @error('message') is-invalid @enderror" name="message" required></textarea>                                        @error('message')                                            <span class="invalid-feedback" role="alert">                                                <strong>{{ $message }}</strong>                                            </span>                                        @enderror                                    </div>                                </div>                                <div class="col-6">                                                                <div class="form-group">                                        <label for="name" class="col-form-label text-md-right">{{ __('Attach Screenshot') }}</label>                                        <input type="file" accept="image/*" class="form-control @error('screenshot') is-invalid @enderror" name="screenshot" autofocus>                                    </div>                                </div>                            </div>                            <div class="form-group row mb-0">                                <div class="col-md-6 offset-md-4">                                    <button type="submit" class="btn btn-primary">                                        {{ __('Send Message') }}                                    </button>                                </div>                            </div>                        </form>                    </div>                </div>        </div>    </div></div>@endsection

A imagem abaixo é um layout simples da aparência da página de contato no momento.

Contact us 2
Página de contato

Adicione rotas para ativar solicitações GET & POST

Primeiro, configuraremos as rotas em rotas> web.php para renderizar a página de contato por meio de um OBTER solicitar e enviar e-mails através do POSTAR request (que foi especificado no atributo de formulário acima).

Route::get('/contact', 'HomeController@index')->name('contact');Route::post('/contact', 'HomeController@send_mail')->name('addContact');

Adicionando lógica no HomeController

No app> Http> controladores, O andaime do Laravel gerou um HomeController.

<?phpnamespace AppHttpControllers;use IlluminateHttpRequest;class HomeController extends Controller{	public function index()    {        return view('template.client.contact'); //renders the contact page    }   }

O arquivo do controlador é onde reside a lógica do aplicativo. O Laravel Scaffold já gerou o HomeController padrão. Então, vamos nos contentar com isso e criar uma função chamada index. Nós o usaremos para renderizar a página de contato sempre que o usuário visitar a rota ou URL no aplicativo.

<?phpuse IlluminateSupportFacadesMail;use AppMailContactFormMail;class HomeController extends Controller{    public function send_mail(Request $request)    {        $this->validate($request, [            'fullname' => ['required', 'string', 'max:255' ],             'email' => ['required', 'string', 'email', 'max:255' ],            'phone_number' => ['string', 'max:255'],            'subject' => ['required', 'string', 'max:255'],            'message' => ['required', 'string', 'max:255']        ]);        $contact = [            'fullname' => $request['fullname'],             'email' => $request['email'],            'phone_number' => $request['phone_number'],            'subject' => $request['subject'],            'message' => $request['message'],            'screenshot' => $request->file('screenshot')->store('contact', 'public')        ];            Mail::to('[email protected]')->send(new ContactFormMail($contact));                return redirect()->route('contact')->with('status', 'Your Mail has been received');    }}

No mesmo HomeController, precisamos criar outra função chamada send_mail . A função validará todas as entradas do usuário e verificará se os campos não são deixados em branco e se os dados corretos são analisados.

Em seguida, crie uma variável chamada $create para armazenar os valores da matriz de todos os dados do usuário, incluindo upload de imagens.

O Laravel é fornecido com um sistema de arquivos que nos permite trabalhar com imagens facilmente. o Mail::to(....)e send enviado com Illuminate Support Facade que eu incluí na parte superior do snippet. Também incluí um Mailable, que explicarei em breve.

Agora precisamos alertar os usuários quando a mensagem foi despachada e redirecioná-los.

Reunir os trechos de código agora fará com que o HomeController tenha a seguinte aparência:

<?phpnamespace AppHttpControllers;use IlluminateHttpRequest;use IlluminateSupportFacadesMail;use AppMailContactFormMail;class HomeController extends Controller{	public function index()    {        return view('template.client.contact'); //renders the contact page    }        public function send_mail(Request $request)    {        $this->validate($request, [            'fullname' => ['required', 'string', 'max:255' ],             'email' => ['required', 'string', 'email', 'max:255' ],            'phone_number' => ['string', 'max:255'],            'subject' => ['required', 'string', 'max:255'],            'message' => ['required', 'string', 'max:255']        ]);        $contact = [            'fullname' => $request['fullname'],             'email' => $request['email'],            'phone_number' => $request['phone_number'],            'subject' => $request['subject'],            'message' => $request['message'],            'screenshot' => $request->file('screenshot')->store('contact', 'public')        ];            Mail::to('[email protected]')->send(new ContactFormMail($contact));                return redirect()->route('contact')->with('status', ' Your Mail has been received');    }}

Depois de mesclar as duas funções acima, terminamos a lógica do HomeController. Agora vamos prosseguir para o próximo passo.

Cada e-mail enviado no aplicativo Laravel é representado como “enviável”, caso você esteja se perguntando sobre o nome. Vamos criar uma remarcação para envio para informações de contato que queremos processar:

php artisan make:mail ContactFormMail --markdown=template.client.contactform

O comando acima irá gerar um arquivo de descontos no diretório recursos> visualizações> modelo> cliente diretório e também crie um arquivo para envio em app> Mail> ContactFormMail.php.

No ContactFormMail.php, temos o seguinte trecho de código que nos permite enviar e-mails sem um anexo:

<?phpnamespace AppMail;use AppUser;use IlluminateBusQueueable;use IlluminateContractsQueueShouldQueue;use IlluminateMailMailable;use IlluminateQueueSerializesModels;class ContactFormMail extends Mailable{    use Queueable, SerializesModels;    /**    * Create a new message instance.    *    * @return void    */    public function __construct($data)    {        $this->user = $data;    }    /**     * Build the message.     *     * @return $this     */    public function build()    {        return $this->from('[email protected]')                ->markdown('template.client.contactform')                ->with([                        'subject' => $this->user['subject'],                        'message' => $this->user['message'],                        'email' => $this->user['email'],                        'phone_number' => $this->user['phone_number'],                        'fullname' => $this->user['fullname'],                    ]);    }}

Vamos quebrar um pouco esse código.

No _construct método Estou analisando todos os dados do usuário como parâmetro e reatribuindo-os. No build método, toda a configuração de classe enviável é feita.

o from Método especifica o remetente do correio, de quem é o correio (no meu caso [email protected])

o with Método permite que você escolha como as mensagens serão renderizadas na remarcação gerada. Neste artigo, atribuiremos todos os campos aos pares de chave e valor dentro da matriz para que, dentro da redução, possamos acessar cada valor com sua própria chave exclusiva.

o markdown Método aceita o nome do modelo de remarcação a ser renderizado com um parâmetro de dados opcional (se não estivéssemos usando o with método).

E por último, o to Método especifica o destinatário do email. No HomeController acima, altere ‘[email protected]‘para o endereço do destinatário real.

Adicionar dados ao arquivo Markdown

Agora precisamos configurar o arquivo de marcação no diretório recursos> visualizações> modelo> cliente diretório. Como já temos pares de valores-chave em vigor, é mais fácil fazer referência a chaves no arquivo de remarcação, como mostrado abaixo:

@component('mail::message')# {{$subject}}## {{$message}}Feel free to contact me via {{$phone}} or {{$email}}Thanks,<br>{{$fullname}}{{ config('app.name') }}@endcomponent

Neste ponto, estamos quase terminando 😊😊😊. Parabéns por acompanhar o processo até agora. Agora você aprendeu como enviar um email sem anexo. Agora vamos ver como fazer isso com um anexo.

Enviando correios com um anexo

O Laravel já vem com um poderoso sistema de arquivo, portanto, enviar e-mails com um anexo não é muito difícil. Aproveitaremos esse recurso e criaremos armazenamento para os usuários onde armazenaremos os arquivos anexados no aplicativo.

php artisan storage:link

NOTA : No HomeController acima, eu já especifiquei um diretório de armazenamento para os uploads. Você deve fazer o mesmo criando uma pasta (chamada contato) no armazenamento> aplicativo> público> contato .

Também no config> filesystems.php verifique e verifique se o disco padrão do sistema de arquivos está definido como return ['default' => 'public'].

Agora o ContactFormMail.php se parece com isso. Agora podemos usar o attachFromStorage método que faz referência ao caminho do arquivo.

<?phpnamespace AppMail;use AppUser;use IlluminateBusQueueable;use IlluminateContractsQueueShouldQueue;use IlluminateMailMailable;use IlluminateQueueSerializesModels;class ContactFormMail extends Mailable{    use Queueable, SerializesModels;    /**    * Create a new message instance.    *    * @return void    */    public $user;    public function __construct($data)    {        $this->user = $data;    }    /**     * Build the message.     *     * @return $this     */    public function build()    {        return $this->from('[email protected]')                ->markdown('template.client.contactform')                ->attachFromStorage($this->user['screenshot'])                ->with([                        'subject' => $this->user['subject'],                        'message' => $this->user['message'],                        'email' => $this->user['email'],                        'phone_number' => $this->user['phone_number'],                        'fullname' => $this->user['fullname']                    ]);    }}

A única adição aqui será attachFromStorage. É usado para processar os arquivos anexados (imagem ou pdf) durante todo o processo de correspondência.

No arquivo de remarcação que usamos anteriormente, podemos retrabalhá-lo levemente para se parecer com o que é mostrado abaixo:

<div class="row">	<h1 class="text-dark">{{$subject}}</h1>	<h3>{{$message}}</h3> 	<h4>You can reach me via mail or telephone : {{$email}} or {{$phone_number}}<br/>	Thanks	</h4></div>
Correio com anexo sem remarcação

Screenshot 20200724 180046
Captura de tela da mensagem de email bem-sucedida

Yaaay agora podemos fazer uma dança feliz porque finalmente terminamos 🎉🎉🎉🎉🎉

via GIPHY

Agora que você concluiu o artigo inteiro, poderá implementar um recurso de email semelhante em seus aplicativos Laravel.

Para saber mais, confira o site oficial Documentação do Laravel aqui.