Laravel Forge is a Great Tool for Deploying your Application

Access all tutorials in sprocket icon.

October 24, 2015 from author Bill Keck.

Laravel Forge

One of the truly amazing things about the Laravel Framework is the amount of supporting products that are out there in addition to the wonderful free Laravel php framework. I had some interesting insight and discovery with Laravel Forge that I would like to share.

So, I developed my first production app with Laravel, KeyComicBooks.com, which is a fairly simple tool for finding “key” comic books, those worth investing in. Yes, people invest in comic books, but let’s not get into that, you can check out the site if you want to know more about that. It’s actually a fun little site.

Now to deploy it, I had some choices available to me that a lot of people don’t have. I went to our company’s network specialist, the one in charge of provisioning servers, and asked him if he could allocate the necessary resources and show me how to deploy my site. He told me he could do it, but that it would have to wait behind some other priorities. Another programmer at work chimed in and suggested I try Digital Ocean in combination with Forge.

I said, “You want me to do it myself?”

It’s one of those moments when you realize you are about to jump into the deep end, without really knowing how to swim. I think that’s an appropriate metaphor considering the name of the hosting company, Digital Ocean.

So just to be clear, Digital Ocean is a cloud hosting platform and Forge is Laravel’s deployment tool. I didn’t have any prior hands-on experience working with production environments, so this just seemed like it was going to be a grind. On the other hand, I could see the wisdom in jumping in full force, there really is no better way to learn. So that time had come.

I created my Digital Ocean account within about 2 minutes, there wasn’t much to it. I went for the $20 per month plan, which was sufficient for my needs, probably more than sufficient, but I always like to leave room in the resources. So getting that setup was a snap, but then the idea of provisioning everything I needed, PHP, MySql, Composer, Apache (in this case ngnix), node and whatever else just seemed way over my head.

So I opted to try Laravel Forge, which builds and helps you manage your server. Just a quick note, I’m going more in the review direction with this post as opposed to a step by step tutorial. I’m not authoritative enough at this point to give you that. But I can describe the process and tell you how it went for me, and I have to say up front, it was fairly smooth and I love Forge. It is well worth the $10 per month in saved time.

Once you signup for Forge, you link it to your Digital Ocean account, which is fairly simple. It’s a few fields in a form with placeholders that make it intuitive. Then you push a button and it configures your server. This is just awesome.

Next you have to link it to your repository, which again is very simple, but to get it to work, you do have to provide a public key for access from your terminal. I had no idea how to do this, but a little Googling got me on the right path. I was able to generate a public key from my mac and provide that to Forge.

In reality, as a complete newbie, this took about 20 minutes, the most time being spent away from Forge and working on the public key generation, and making the typical mistakes, like copying the private key instead of the public one. But once I cleared that hurdle, I was able to deploy my code to the server.

Did the site function out of the box? No. I had to run the migrations. This means you have to ssh into your server and get into the correct directory and run php artisan migrate. So it took me a few minutes to figure out how to do that the first time.

Then that failed because I didn’t have my server environment file set, so no DB connection. Your .env file does not get uploaded into your repository, so the application has no knowledge of the DB. Luckily, the .env file on the server is really easy to edit via Forge, and it only took a minute to update the DB info.

So then I tried my site and of course uncovered a few bugs I didn’t anticipate. I had an error in my navigation bar that was testing for the presence of a profile, but of course while I was coding I had a profile, but now, with a fresh install, I did not, so this was an untested and overlooked problem. It was a simple fix, and again, pulling in the latest code via Forge is a one click prospect. It’s an awesome flow.

But I still had another problem. I ran into the dreaded token mismatch error. This happens when inside the session.php file, which is in the config directory, the domain is not set to the current url. It took me a while to track that down. I felt really dumb because I had run into this before and forgot about it. So I was covering ground I should have already been aware of. This is one reason why I document so much, I just can’t remember everything, and chasing down bugs like that can consume a lot of time.

I also ran into problems where I had to clear my cache for my routes. So once I got all that done, I had a working site. But there was just one more problem. I did not have access to the backend, and since I could only sign up as a regular user, there was no way for me to create an admin user. One way to handle that might be to create a migration that creates the user with admin status.

But I figured I needed to understand how to interact via Mysql directly on the server anyway, so I updated the user record directly from my terminal. So I had to learn how to access MySql from the command line as opposed to using PhpMyAdmin, which is how I typically work with it. None of that has anything to do with Forge. I’m only mentioning these things because you need to have realistic expectations when deploying. You will probably have to do some refining with your app as well.

After getting my install operating correctly, I started reviewing the site and found things that weren’t right. So now I was changing code, pushing it to the repository, then deploying via Forge. Well Forge had one more feature that made this even easier. It can listen for changes to your repository and automatically push them for you. So I switched that on and it works beautifully.

The automatic update did fail for a period, and I imagine behind the scenes that either BitBucket was having problems, which would not surprise me because that has happened before or Forge’s node server quit or something. Anyway, the problem was temporary and I love how it pulls the code automatically. I just push from my IDE, which is PHP Storm, and in less than a minute the code is both in the repository and live on the server. Very cool.

From my personal experience with Forge, I can say it has been extremely positive. I would be hopelessly lost without it, and at a minimum, it would take a lot of work to learn how to provision manually. There’s wisdom in learning how to do it manually, but my focus is not on environments, and I just don’t have the time now to commit to it. For beginner to intermediate programmers, Forge is just a great tool to work with. Eventually I’ll get some feedback from advanced environment guys to see what they think of it as well.

There’s an indicator button in Forge that shows you the status of deployment. Sometimes deployment can take a few minutes, so it’s really cool to be able to see the progress. I love watching it kick over and show me that my changes are live. It’s a good feeling.

In conclusion, I’m giving Laravel Forge the highest possible recommendation. I don’t feel like I’m drowning any more. I’m actually having fun deploying the application. It doesn’t get any better than that.

Advertisements

Simple Dropdown list from Eloquent List Method Laravel 5.1

Access all tutorials in sprocket icon.

October 4, 2015 from author Bill Keck.

Laravel makes creating a dynamic dropdown list incredibly simple. Let’s say for example, you have a Category model, which holds the categories you want to use in a dropdown list. You can just use the lists method pull out the values you want for the dropdown list:



$categories = Category::lists('category_name', 'id');

This assumes you have id and category_name columns in your categories table. Obviously if you are just calling it ‘name’, then use that.

Then you just need to pass $categories to your view:



return view('yourview.create', compact('categories'));

That returns an array with the values you need, which you can just pop into your dropdown list in your view. I’m using the Collective Form Helper package for my select:



{!! Form::select('category_id', $categories) !!}

And that’s it, you get your dropdown list. Little helpers like this make Laravel a pleasure to work with.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials. Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.

Eventing in Laravel 5.1

Access all tutorials in sprocket icon.

September 30, 2015 from author Bill Keck.

Eventing in Laravel 5.1.

Background.

One of the things that can be intimidating when you are a beginner is the idea of eventing. What is it? When to use it?

Probably the easiest way to get it is through a simple example. Think of an email message that gets sent out upon registration of a new user. In the old procedural way of doing it, you would just hardcode some kind of send command directly in the controller.

That does work, however if your application grows, you might have all kinds of messages that need to go out to users, things like support request responses, upgrade messages, and of course the previously mentioned signup responder.

When you put it in that context, it makes a lot of sense to have a clean and extensible way to handle these situations. Events are perfect for this. Laravel events are not limited to email, but this is an excellent way to look at how they work.

Mailhelper.

In my project, I decided to do a fairly robust mail helper class that handles many types of email responses. I haven’t built the system response for registration, so I’m using a class I built to handle support messages. I think if I try to go through that whole process, it would make the tutorial too long, so I’m not going to go through that entire class. Instead, I’ll just show you how I’m calling it:



$contactMailhelper = new ContactMailHelper('supportMessage', $request);

So what that does is it hands in the type of message we want, a support message, and also an instance of the request, which tells it which pre-formatted response we want to send, based on form input. I also did a token replace for username. It’s a fairly involved class, so don’t worry if it doesn’t make sense in a glance. All you need to know is that when it returns, the $contactMailerhelper holds the sendto email address, the subject, the body, and view that’s needed for the message.

If you don’t know how to send email from Laravel, this tutorial will help you with that too. After getting our instance of $contactMailhelper, we are then going to fire our event:



$contactMailhelper = new ContactMailHelper('supportMessage', $request);

event(new RespondedToSupportRequest($contactMailhelper));

Bind the Event to a Listener.

Ok, I’m getting ahead here by showing how it’s called, I’m going to come back to this because we have not yet created our event to handle it. So how do we that? Fortunately, Laravel makes this incredibly easy.

In your Providers folder, you will see a file named EventServiceProvider.php. Inside of that, we will put the following in the $listen array:



protected $listen = [
        'App\Events\RespondedToSupportRequest' => [
            'App\Listeners\MailUserSupportResponse',
        ],
    ];

This binds the event RespondedToSupportRequest to the listener MailUserSupportResponse. Neither of those two classes exist yet either.

Generate the event classes.

We can quickly get both of those classes up and running by using the following artisan command on the command line:



php artisan event:generate

So that command looks for any bindings that don’t currently have classes and creates them for you. If you run that coommand, you now have RespondedToSupportRequest.php in the events folder. You will also have MailUserSupportResponse.php in your listeners folder. Both files are stubbed out and namespaced and in the correct folders. This is just awesome workflow.

We’re not really building a working example, but you should get enough out of this tutorial to be able to setup your own events. So don’t worry if you would rather have a UserSignedUp event with an EmailWelcomeNewUser, just make the changes to the EventServiceProvider $listen array and generate your own events.

I’m going to continue on, because there are few more things that you should know that are really helpful.

Let’s tackle the listener first. All we have to do is modify the handle method:



public function handle(RespondedToSupportRequest $event)
{
        $data = ['body'         => $event->contactMailHelper->emailBody,
                 'emailAddress' => $event->contactMailHelper->emailAddress,
                 'emailSubject' => $event->contactMailHelper->emailSubject,
                 'emailView'    => $event->contactMailHelper->emailView,
        ];

        Mail::queue($data['emailView'],$data , function($message) use($data)
        {
            $message->to($data['emailAddress'])->subject($data['emailSubject']);
        });
}

In the signature of the handle method, we hand in an instance of the event. Then I’ve set up an array for the $data that we need to send an email. In my case, I’m receiving the configuration through the contactMailHelper object that I’m handing in.

If you want to simplify and hardcode in values for a signup email, for example, just replace that code with your own values. You can see that $data is just an array and we are simply using the array keys to hand in the appropriate values at the right places.

I’m also going to show you how to pass along an object, so you will be able to hand in the user instance if you want and you can use something like $event->user->email if you wish. Hopefully that will be clear.

Sending the mail.

The part that actually sends the mail is the following:



Mail::queue($data['emailView'],$data , function($message) use($data)
        {
            $message->to($data['emailAddress'])->subject($data['emailSubject']);
        });

I should mention that Laravel is going to look for view in the emails folder that is in the view folder. The second parameter is $data, so we have So your $data[’emailView’] key should hold that value. Inside the view itself, the array key is a variable you can call:



{{ $body }}

That will display whatever is in the email if you have set that in your $data array. You can reference the Laravel Docs on this as well.

Also, if you want to use Mail, you need to include the use statement:



use Illuminate\Support\Facades\Mail;

Also notice, I’m using the queue method as opposed to the send method. What this does is allow you to push the message to the queue, so you don’t have to stop the user experience to wait for it to process. Instead it gets pushed onto the queue, where it goes out asynchronously from the browser.

The Event.

Let’s go to the RespondedToSupportRequest.php and modify the constructor:



public function __construct($contactMailhelper)
    {
        $this->contactMailHelper = $contactMailhelper;
    }

We also need to set a property:



public $contactMailHelper;

So in my implementation, I’m handing in my instance of $contactMailHelper, which sets all the email properties I’m going to need. If you are doing a simple autoresponder on registration, you might just want to pass along the user id, so you can get the rest of what you need in the handle method of the listener. Like I said, this is not a working example for you, just trying to help you understand how it works.

At any rate, the constructor sets the property, which will be passed along to the listener when the event fires.

So, putting it all together, we call the event in your controller like so:



event(new RespondedToSupportRequest($contactMailhelper));

Don’t forget the use statement:



use App\Events\RespondedToSupportRequest;

That’s just one line you can pop into your controller(don’t forget the use statement), so you don’t end up with mail code in your controller that doesn’t really belong there.

So the $contactMailerhelper object is passed into the event and we know that is set through the constructor of the event for us to use in the listener. The handle method of the listener does the bulk of the work:



public function handle(RespondedToSupportRequest $event)
{
        $data = ['body'         => $event->contactMailHelper->emailBody,
                 'emailAddress' => $event->contactMailHelper->emailAddress,
                 'emailSubject' => $event->contactMailHelper->emailSubject,
                 'emailView'    => $event->contactMailHelper->emailView,
        ];

        Mail::queue($data['emailView'],$data , function($message) use($data)
        {
            $message->to($data['emailAddress'])->subject($data['emailSubject']);
        });
}

This tutorial might seem complicated if you are reading along, but in reality this is very simple. Here are the 4 simple steps to implementation:

1. Bind your event to listener in the EventServiceProvider file.
2. Use the artisan command to generate the necessary classes, php artisan event:generate
3. Modify the constructor of your event class if you need to pass in an $id variable or other object and set the property.
4. Code your handler in your listener class to do act on the event, in our example, it’s sending an email.

Tip: Remember your use statements.

Once you get this, you can see how wonderful and easy Laravel eventing really is. It’s a beautiful part of the laravel architecture, with simple syntax and many advanced features that you can read up on in the docs.

I hope you have enjoyed this tutorial and found it useful. Click on the sprocket icon at the top of the page to see all tutorials. Please comment, share, and like if you can, thanks!

I don’t have a donate button, but If you would like to support my work and learn more about Laravel, you can do so by buying one of my books, Laraboot: laravel 5* For Beginners, I really appreciate it.