Ben Lobaugh Online

I think, therefore I am. I am, therefore I sail

Tag: Laravel

Lock attached to door

How to Force SSL (HTTPS) in Laravel

Out of the box, Laravel will allow both HTTPS and HTTP requests to your website or application. Ideally all requests are served via SSL. There are several ways to accomplish this, some of which require access to server configs. I am going to show you how you can easily force SSL in your Laravel application to ensure HTTPS will be on no matter where you application is deployed. Of course the server still requires a valid SSL certificate to run- that is outside the scope of this tutorial.

Assumptions

  • Working server with the SSL certificate already installed
  • Laravel app running
  • Requests being fulfilled on both HTTP and HTTPS
  • Basic Laravel knowledge

Time to complete in your app

30 minutes or less!

How it works

Laravel provides a mechanism for filtering HTTP requests called Middleware. Middleware has many use cases, a few of which include: user verification, CORS headers, logging requests, etc. Only after all Middleware conditions have been met is the app able to fulfill the visitor’s request. This is the perfect place for us to enforce SSL.

Read more about Middleware in the on the official Laravel docs https://laravel.com/docs/master/middleware

Step One: Create the Middleware Base

Middleware can be generated automatically with artisan with the following command:

php artisan make:middleware ForceSSL

The new file will be created in app/Http/Middleware/ForceSSL.php

namespace App\Http\Middleware;

use Closure;

class ForceSSL
{

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

Step Two: Update the handler

All we have to do now is look at the request and if it is not secure redirect to the secure version of the url!

Update the handle method like so

    public function handle($request, Closure $next)
    {

        // If the request is not secure, redirect to the HTTPS url.
        if( !$request->secure() ) {
            return redirect()->secure( $request->getRequestUri() );
        }

        // Otherwise carry on.
        return $next($request);
    }

Step Three: Test

That is it. 

Really.

Go test it.

Step Four: Enjoy a nice scotch

‘nuff said

Photo by Anita Jankovic on Unsplash

Man reading newspaper

Add a Mailchimp email subscription form in Laravel – double opt in!

With several fantastic extension out there, integrating a Mailchimp email subscription form in Laravel has never been easier!

I am going to show you an example integration that collects an email address in a simple form. We will be using the laravel-newsletter package by spatie.

Assumptions

  • You have a Laravel application already running
  • You have a Mailchimp account
  • You have a basic understanding of Laravel

Step One: Include the spatie/laravel-newsletter package

Include the spatie/laravel-newsletter package in your project with

composer require spatie/laravel-newsletter

This package contains a very easy to use set of methods to control all aspects of your subscribers and user management. In this tutorial we will only be using the subscribe functionality.

Step Two: Configuration

The default configuration file will be generated with

php artisan vendor:publish --provider="Spatie\Newsletter\NewsletterServiceProvider"

A file will be created at config/newsletter.php. In this file are a set of variables that will be needed in the .env file.

Step Three: Create the Controller

A Controller will be used to send off the subscriber’s email to the Mailchimp service. Other tutorials on form submission will also include a Model and Migration here. I am choosing to skip that since we are not putting data into a database, but rather are acting as a passthrough.

php artisan make:controller Subscriber 

The controller file will be created at app/Http/Controllers/Subscriber.php

Add a method called addSubscriber

    public function addSubscriber( Request $request ) {

        $validatedData = $request->validate([
            'email' => 'required|email',
        ]);

        // Do additional validation and security checks here....

        // Sign up the user!
        Newsletter::subscribePending( $validatedData['email'] );

        if( Newsletter::lastActionSucceeded() ) {
            $status = json_encode( [ 'success' => true, 'message' => 'You have been added to the list! Please check your email to confirm.' ] );
        } else {
            $status = json_encode( [ 'success' => false, 'message' => 'There was an issue adding you to the list! Please try again or contact the admin.', 'error' => Newsletter::getLastError() ] );
        }

        return $status;
    }

Step Four: Update routes

Next you will need to update your routes file to add the new endpoint. Do this in routes/web.php

Route::get('subscriber/add’, 'Subscriber@addSubscriber');

If you are building this into an API you can use the routes/api.php file.

Step Five: Wire up your form

This is the final step to world domination!…. or at least having your subscription form ready for prime time. Simply wire up your form to use this new endpoint. I am going to assume that you know how to handle html forms here 😉

Step Six: Final Testing

Because we set this up as a GET query, testing is as simple as passing the email query parameter. Submit an email and see it populate in your Mailchimp account!

Step Seven: Drink Scotch

The final and most important step!

How to use custom pivot tables in Laravel 6.x

Have you run into this before?

Your app’s database table structure is predefined and unalterable. There are lookup tables (called pivot table in Laravel) that create many to many relationships between tables using YOUR naming convention. It makes sense in the context of your application, but you quickly find out that Laravel’s relationship defaults do not match it well.

Lets take this scenario for example:

You have users who are part of organizations, and organizations can have groups in them, created by the users.

There are three primary tables:

  • users
  • organizations
  • groups

Additionally there is a lookup table called organization_groups. The lookup table contains not only the related id, but several other relevant data points, including a field called “created_by_user_id”.

This looks good in theory, however Laravel is going to require the pivot (lookup) table to be named groups_organizations out of the box. In your data structure it logically makes sense to have the table named organization_groups though. Luckily this is entirely possible, though the documentation on how to do it leaves a little to be desired.

Step One: The basic models

Let’s start out by creating the basic models. This can be easily done with Laravel’s artisan command

php artisan make:model Users
php artisan make:model Organizations
php artisan make:model Groups

It should be noted here that I used the build in Laravel users model that comes with the authentication mechanisms. I did not actually run the make:model command for that. You will not need to if you use Laravel’s users either.

Step Two: Related Groups to the Organizations model

This was the most annoying part to figure out, and the least well documented…..

When you load an organization you will be able to access all the groups via a class property. For example:

$org = Organization::find( $id );

$groups = $org->groups;

Laravel is doing some magic behind the scenes here- first, “groups” is not a property. When requested, Laravel checks to see if a corresponding method exists. In this case it looks for “public function groups()”. The method must return a relationship, such as “belongsToMany”.

By default, Laravel will use the “groups_organizations” table, but by messing with parameters I determined how to properly switch the table. Laravel does a lot of magic with parameters- depending on how many you use the meaning of the parameter changes. In our case it looks like

$this->belongsToMany( CLASS, TABLE, KEY-RELATING-THIS-MODEL, KEY-FOR-OTHER-MODEL )

which comes out to

$this->belongsToMany( Groups::class, ‘organization_groups’, ‘organization_id, ‘group_id’ )

Notice the keys are singular. Laravel is expecting them to be plural (like the table name I think) so have have to be explicitly specified here.

Here is the full code to create the relation. This code belongs in the Organizations model.

public function groups() {
   return $this->belongsToMany( Groups::class, ‘organization_groups’, ‘organization_id, ‘group_id’ );
}

Now we will be able to do things such as:

$org = Organizations::find( 42 );

foreach( $org->groups as $group ) {
    echo $group->name;
}

Step Three: Relate a User to the Group

Here each Group has a single User set in the “created_by_user_id” field.

Laravel’s many-to-one relationship used “hasOne”. In the Groups model class we add:

public function createdBy() {
    return $this->hasOne( User::class, 'id', 'created_by_user_id' );
}

Now we can find which user created a group with

$group->createdBy->name;

In the organizational context, we may have a list of all groups and who created them.

$org = Organizations::find( 42 );
foreach( $org->groups as $group ) {
    echo “Group: “ . $group->name . “ - Created by: “ . $group->createdBy->name ;
}

Hope that helps!

Powered by WordPress & Beards