Laravel conditional for @extends in blade

I have a Laravel app that has multiple users.  Depending on the user I need to display a different blade template.  The problem is that it is not possible to use a regular

After much searching I found that @extends is required to be on the first line so it is possible to have a conditional if you do it this way.

Hope this saves you some time.

Laravel AWS s3 file storage – IAM users and Permissions

This seemed easy with Laravel 5.4 supporting s3 disks but it took a bit of setting up and a lot of trial and error so this is what is needed to get it working.

  1. Setting Laravel up to use s3

Ensure that you follow the docs and add flysystem to your composer.json.

Then update composer.

2. Sign up for AWS

3. Create your first bucket.

There are 4 steps to creating a bucket.

Add a unique bucket name and choose a region.

Nothing to change or add on this screen or up to step 4. Just click next on each.

Your bucket will now be added to the system.

4. Create a IAM user with the right permissions.

Click on services in the top bar and then click on IAM.

On the IAM screen click on users and then add user.

Add a user name and tick the programmatic access. Click next.

Click on the ‘Attach Policies’ and then ‘Create Policy’.

A new tab will open (remember that as we will be coming back to the above page shortly. Click on the select button for ‘Create your own policy’.

To add a policy copy the code below exactly and do not change the date for the version. Make sure you do change the ‘bucket-name’ in two locations to your buckets name which you just created.

Use Amazon S3 with Laravel 5

Check the policy and then click on create if all is good.

Go back to the previous tab we talked about earlier not to forget. Find the policy that you just made.  You should click on the refresh button first then you may need to use the search so just start typing the policy name.  Tick the checkbox next to the policy you just created and click next down the bottom right.

Create the user.

This is the newly created user.  It is VERY IMPORTANT to copy the key and secret key down here.  You will not be able to access it at any other time.

Done the bucket and the user has been added to AWS s3 now.  You can start to store files here now.

5. Adding Bucket to Laravel

IN you .env file add this to the bottom of the page.

In your config/filesystems.php

in disks change to refer to your .env file.  This keeps the access keys out of your version control.

You can also change the default disk to ‘s3’ if that suits you.

Why are my images not showing up?

In AWS s3 a buckets contents are private and cannot be accessed from a website or even with a direct url.  Laravel allows you to individually set permission for files which are saved to s3.  If you would like to allow all images to be visible from you bucket you can set permission for the bucket in AWS.  By doing this you will be able to show images on your website which are stored in your bucket.  This also means that you do not need to specify in your project for each file.

In AWS go to s3 and click on your bucket.

Click on permission on the top tab. Click on Bucket policy. Add the code snippet below and save.

This article helped and provided the code below. Of course change the ‘your bucket’ to the name of your bucket. Click on save.

Saving files.

However you have your upload set up here are a few tips.

I am using intervention to assist with my file uploads.  So in your code mine is a service class I use for uploads but yours might just be in your Model or controller.

This article helped

The important parts here are the stream() and then the __toString().

Dont forget to include Storage facade in your code e.g.

That is about it . You have all the elements to make this work.

If you are having problems getting this to work locally check out my trouble uploading to s3 from local

Trouble uploading images to AWS s3 and XAMPP

So I needed to get my local xampp development site working with AWS s3 to store images.  I had it set up and working on my development server but I needed my local development to work as well. Unfortunately I kept getting this error.

Aws\S3\Exception\S3Exception with message ‘Error executing “ListObjects” on “https://mybucket.s3-ap-southeast-2.amazonaws.com/?prefix=&delimiter=%2F&encoding-type=url”; AWS HTTP error: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)’

I Googled for a solution and everywhere I found that I needed to change my php.ini file to include a certificate. Unfortunately everywhere told me to get a clean cacert.pem and do the following in the php.ini file.

This did not work for me.  More searching and a bit of trial and error lead me to this.

And badda-bing badda-boom it works!

Hope this helps someone save some hours.

Laravel Dom PDF issues with font awesome and a Unicode work around

So I am using Laravel-DomPDF by Barryvdh in my Laravel 5.4 project, which makes it super easy to create PDF documents from Laravel Views.

Kudos to Barryvdh for providing a simple way to produce PDF documents from Laravel.

So, I wanted to pull Font Awesome into the blade view for a couple of icons I had on the page.  Problem was that it was not working.  I tried everything suggested from full url for the link, to adding a fonts folder to /storage/app.  None worked for me.

As I only need a tick and an exclamation on the page I decided to add the styles straight into the head of my blade file and use Unicode.

I found that Dom PDF already pulls in DeJaVu Fonts which is a project that is aiming for complete coverage of alphabetic scripts. The other thing is that it has a bunch of symbols.  Not as awesome as Font Awesome but enough for my needs.

In between the head tags I added this.

This is the check:

And this is the exclamation:

Neat hey! Where did I get the content:”\????” from?

Miscellaneous_Symbols

This was a quick and dirty solution to my issue and may help you.  While I agree it’s not ideal it is better than changing to another PDF project or spending more time trying to get this to work with Font Awesome at the moment.

Laravel event handler for last login

I recently needed to show on the admin side of an app the last login of all users and if they had logged in at all.  I also wanted to show the user the last time that they visited the site.  I used event handlers for both these tasks.

Update the Users Table

I have used the user model to store a timestamp for each event, so I added two new rows to my users table.  I will then be able to access these easily in my blade template.

On the user model I also added both timestamps to the proteced $dates array. By doing this I will be able to use ‘Carbon’ helpers like ‘diffForHumans’.

Creating the Event Handlers:

On the admin side I used the login event and for the user I used the logout event to record the current time and date to the users table.

In the EventServiceProvider service provider (app/Providers/EventServiceProvider.php) I added the following to the $listen array:

I then ran php artisan event:generate. This command then creates two event listeners located at app\Listeners\Users\LatestLogin and app\Listeners\Users\PreviousLogin.

Each event listener’s handle()method I added the following.  

I also added:

to each listener.

Now when a user logs in or logs out the event listener fires and updates the appropriate row of the users table for the user.

Blade

Finally for completeness in my blade file I can call:

And it will output something like – 1 hour ago – or however long it was since the user signed in.

For the user in the view I add:

It outputs something like: Last Visit: 2 days ago

That is about it. I hope this helps someone else out.

Laravel Raw Statements for Database Queries

Laravel has a powerful query builder but there are limitations when database queries become more complex.  Enter Raw queries.

The docs have an example  of a raw query which will get you going but sometimes there is a need to completely ditch the builder and and go it alone.

The following example is what I used create a query which is completely raw.

The important thing to notice here is that when using the raw query you can pass variables straight into the query which could be a security issue especially if the information is being passed from a from by a user.

To ensure that any values that need to be passed to the query are sanitized they can be passed in an array after the query.

Take a look at the query and the ‘And’ clauses.

The :companyId in the example is how you add your variables using the array.

In the array give the key and then the value to be added.

That is it.  Hope it helps with your complex Laravel queries.

cURL error 60: SSL certificate problem: unable to get local issuer certificate – Laravel Notifications error

In a new application I was adding in Slack notifications and while testing I got cURL error 60: SSL certificate problem: unable to get local issuer certificate...

I am working on a Windows 10 machine with xampp.  I found the solution on Laracast Forum with a little bit of effort so I thought I would outline the steps succinctly to save a little time in the future.

I am going to assume that you have a version of Guzzle which is 6.2 or around that.

Step 1.

Download a fresh PEM file from this link https://gist.github.com/VersatilityWerks/5719158/download

This is a zip file which you will save into xampp.

Step 2

Unzip this file and save the file cacert.pem in D:/xampp/php/extras/ssl.

Step 3

Update the php.ini file.  D:/xampp/php/php.ini

Alternatively to locate the php.ini file open the XAMPP control panel and click on Config adjacent to Apache.

Search and find curl.cainfo and add the full path to the the cacert.pem file you just added.
The new line should be something like this:
curl.cainfo = D:\xampp\php\extras\ssl\cacert.pem

Step 4

Restart Apache and try and fire off your notification again. It should just work now.

Bootstrap 4 open remote modal from select

In a recent project I have upgraded from Bootstrap 3+ to Bootstrap 4.  I am currently using Bootstrap Alpha 6.

If you used remote modals where you essentially injected content from another place into your modal and you port your code over to the new Bootstrap 4 this is not longer possible in the way that you are currently doing it. As of Bootstrap 3.3.7 ‘remote’ was depreciated and in Bootstrap 4 it has been completely removed. 🙁

It is possible to get things to work again but it has taken me a bit of time and effort to get what was working well, to work again, with the new framework.  So I hope that this will help.

The select.

Notice that data attributes are included for each option. The last one data-url can be whatever you want to call it.  I called it url as I am passing a url.  You can pass whatever value or page you want.

When an option is selected it will hit our jQuery which is as follows.

First it will hit #something when it detects that a selection has been made. It will then open the Modal with an id of 'myModal'.  See comments for further explanation in code below.

Oh, the bottom two lines reset the select after a selection has been made.  You may not need those.

The modal ‘myModal’.

Then the .load will load the ‘remote page’ from the url.  This could be just a html page or whatever you want but the ‘load‘ will pull it in and insert it into the .modal-body as we wanted.

That is it.

Laravel error – Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

When trying to migrate the Auth database tables on a fresh Laravel 5.4 install I got the following error.

Aftera bit of Google’ing I found a solution that workded for me.

Add the following line in the users migration file.

So the create_users_table should look like this.

Original solution was found here.