Martin Carlin


These are all of my blog posts, where possible/applicable, I'll include an embedded CodePen demo or a gist, I hope you find them useful.

I recently had to deal with migrating legacy systems to a Laravel 5.4 app, as you might have guessed, the legacy app was using sha1 and not bcrypt.

Here is how I managed to silently update sha1 passwords to the more secure bcrypt version:


namespace App\Listeners;

use Illuminate\Auth\Events\Attempting;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

use App\User;

use Hash;

class CheckOldHashedPassword
     * Create the event listener.
     * @return void
    public function __construct()

     * Handle the event.
     * @param  Login  $event
     * @return void
    public function handle(Attempting $event)
        $user = User::where('email', $event->credentials['username'])->first();

        if (!empty($user) && $user->password === sha1($event->credentials['password'])) {
            // update password
            $user->password = Hash::make($event->credentials['password']);

Just created the above file in app\Listeners.

Depending on the name of your login field, you might need to change the array key being used in $event->credentials, possibly username or email.

If you are using md5 or something else, then you can easily add in the checks that you need.

Save yourself the time, if you are trying to submit a form via ajax using FormData, it doesn't work with put requests, change the request type to post and it should be fine.

Just a quick post about how to use Laravel Echo without the npm package.

The way I did it was to add it to my local project as per the docs:

npm install --save laravel-echo pusher-js

Then I copied the node_modules/laravel-echo/dist/echo.js file to my public/vendor directory.

Then I just updated my scripts partial to include the Echo js file and the Pusher library:

<!-- Echo -->
  var module = { };

<script src="{{ cached_asset('vendor/echo.js', true) }}"></script>

<!-- Pusher -->
<script src="{{ cached_asset('vendor/pusher.min.js', true) }}"></script>

  window.Echo = new Echo({
    broadcaster: 'pusher',
    key: '{{ config('broadcasting.connections.pusher.key') }}',
    cluster: 'eu',
    encrypted: true

The var module = { }; is needed because how it's meant to be used with webpack I think, I picked that up from a Stack Overflow answer.

I've been trying to figure this out for a while before I cracked it:

Users Controller

use Illuminate\Foundation\Auth\SendsPasswordResetEmails;

class Users extends Controller

    use SendsPasswordResetEmails;

    public function resetPassword(Request $request, $id)

        // your response

The form I used in my view is

<form id="password-reset-form" action="/users/{{ $user->id }}/reset-password" method="put">
   {{ csrf_field() }}
   <input type="hidden" name="_method" value="put">
   <input type="hidden" name="email" value="{{ $user->email }}">
   <button type="submit">Reset Password</button>

Then all you need is a route

Route::put('users/{id}/reset-password', '[email protected]');

Apologies if this is obvious, but thought it could possibly help others. I had this link on a product detail page to redirect back to the results page:

<a href="{{ URL::previous() }}">Search Results</a>

but after the page reload triggered by adding the item to the basket, that link would go 'back' to the same page (not to mention the possibility of navigating to the page from somewhere other than the results page). I couldn't think of any way around it but managed to fix it by updating the controller method for the search results page. The items are fetched using the inbuilt paginator:

/* query logic */

$items = $items->paginate(15);

$url = $items->url($items->currentPage()); // e.g. /some-url?page=1

// then append all the get params to the string from above
foreach ($request->all() as $key => $value) {
    $url .= '&' . $key . '=' . $value;

$request->session()->put('results-route', $url);

then use <a href="{{ Session::get('results-route') }}">Search Results</a> instead.

Not sure if there's a neater way but chuffed I managed to come up with a solution, had no idea how I was going to fix that.

I was using the excellent slick Carousel and needed to implement next and previous buttons to move the carousel in the desired direction, but also had to show and hide these buttons depending on the current slide as I didn't want to use the infinite functionality in this scenario.

First off, initialise the plugin using your desired options, I'd say that these are the minimum requirement but in this case I also had arrows set to false, dots set to true and was also using the lazyLoad option:

    infinite: false,
    slidesToShow: 1,
    slidesToScroll: 1

Then use the slick api to move the carousel when buttons are clicked:

$('.next').click(function() {

$('.previous').click(function() {

and, finally:

$('.steps').on('beforeChange', function(event, slick, currentSlide, nextSlide) {

    if (nextSlide == slick.slideCount - 1) {
    } else if (nextSlide != slick.slideCount - 1 && nextSlide != 0) {
    } else if (currentSlide == 0 || nextSlide == 0) {


I used beforeChange because using the afterChange meant the showing and hiding didn't happen until what felt like to be too late, since the new slide has to be in place before that code is executed.


After writing the first version of the post, I wanted to go back to have another look at it as I wasn't quite happy.

I was running php vendor/bin/dep for deploys since I installed Deployer as a local package.

I changed that by installing globally composer global require deployer/deployer.

Then I could use dep instead of php vendor/bin/dep.

I then removed all of the tasks that were already defined in the Deployer Laravel recipe from my script to avoid cluttering. I didn't even notice that include before so I'm glad I went back to have another look at this.

After that I setup some variables at the top to avoid any confusion over what needed updating for individual use cases.

I also followed the Laravel recipe and included the .env in the shared_files array.

The biggest change after that was to simply upload the public/build directory and its contents over having to do npm install and then gulp --production.

This makes the deploy significantly quicker and it also saves you having to install node and npm on production, as well as not having a node_modules directory for every release which would take up a significant amount of room.

I was still having issues with the bootstrap/cache folder after my re-shuffle, so I removed that line from the top level .gitignore (can't remember if it was me that added that or not, but looking at Laravel's .gitignore it must have been me) and that helped and saved needing a further task in the deploy. There is already a .gitignore in the bootstrap/cache directory so that nothing in there will be version controlled, but just having the empty directory saved endless amounts of pain.

The final piece of the puzzle was to run chmod g+s <directory> to make files inherit group to make files inherit the group from the parent directory (my parent directory had martin:nginx as the owner and group). Without that, all the newly deployed files were martin:martin which didn't work for my configuration since nginx is running as .... nginx.

New gist:

I recently tried using Deployer for the first time to setup a deployment process for a Laravel 5 project, rather than using something like Capistrano that would require installing ruby and gems rather than just adding a Composer package.

This gist represents hours of heartbreaking errors trying to figure out why things weren't working, the main one being the first task:

 * Create cache folder in bootstrap directory
task('deploy:cache_folder', function() {
  run('mkdir {{release_path}}/bootstrap/cache');
})->desc('Manually create cache folder');

I was getting an error saying that bootstrap/cache/services.php didn't exist when trying to run php artisan optimize. The solution seems to be creating the bootstrap/cache directory but of all the tutorials and blog posts I read, none mentioned it so I'm not sure if this is a recent change since the .gitignore file has /bootstrap/cache in it but a 5.1 project I have doesn't.

I think the rest is fairly self-explanatory, just replace the placeholders in the square brackets, the curly brackets are actually used by Deployer so don't change those!

This example is made a bit more complicated due to using elixir for assets, so that's why we have to have a task that runs npm install.

I also wasn't sure what to do with the .env file since it's not in source control and obviously your local one will be based on a local environment, not production, so I decided just to create a .env.production file that gets uploaded and renamed to .env. The only problem I can see there is that if you are part of a team then you'd need to communicate any changes somehow since it's not meant to be version controlled.

To deploy, run dep deploy.

If you have any suggested improvements then I'd love to hear them.

Rails Tips

Use helper functions in models and controllers

Sometimes you just need to use ActionView functions in your models or controllers.

A way to achieve this is to include them like so:

include ActionView::Helpers::TextHelper

but a nicer approach seems to be to use the function directly like so:

ActionController::Base.helpers.[FUNCTION_NAME] (arguments)

Better pagination - avoid multiple queries

First, do your query as normal but with one difference.

results ='SQL_CALC_FOUND_ROWS model.*')

and then immediately after, run the following:

total = ModelName.connection.execute('SELECT FOUND_ROWS()')

To get the actual total number, you can use .first on the total object.

This works even when using limit and offset in the original query.


These are my personal notes about git which might help others, most are self explanatory.


To create a new git repo in the current directory:
git init

Check the status of the repository, helpful for seeing what has changed:
git status

See last five commits:
git log

Add a new file to the repo:
git add <filename>

Show changes to a file between commits:
git diff <filename>

Commit changes to staging area:
git commit -m <message>

See latest commit:
git show HEAD

Discard changes to file in working directory:
git checkout HEAD <filename>

Unstage changes to file in working directory:
git reset HEAD <filename>

Revert to previous commit identified by the SHA:
git reset <sha>

List local branches:
git branch

Create local copy of remote repo:
git clone <remote repo url>

List remote repos:
git remote -v

Pull changes from remote repo into local copy:
git fetch

Merge remote origin into local branch:
git merge origin/master

Push branch to remote origin:
git push origin <branch name>

List modified files:
git diff --name-only

Everyday Workflow for Branching

Create a new branch:
git branch <new branch name>

Checkout the new branch:
git checkout <new branch name>

Commit changes to the new branch:
git commit -a -m <message>

Switch back to master:
git checkout master

Merge branch to master:
git merge <new branch name> master

Delete branch:
git branch -d <new branch name>

Push changes to origin:
git push origin

Tagging (optional)

Add a tag to the branch:
git tag -a <tag name> -m "message"

Push tag to remote repo:
git push origin <tag name>

Markdown Tips

Markdown us usually pretty straightforward but I was struggling to think of a way to use a link in code blocks but thanks to this answer on StackOverflow you can do this:

[`this is code`](https://this_is_url/)

Tools, Software and Uses

This is just a post to keep track of things I use.

Thanks to wesbos, I use the Cobalt2 themes for Sublime Text as well as iTerm.

There is also a Cobalt2 theme for SequelPro made by Adam Tuttle.

The pieces of software I use daily are:

and less often:

Sublime Text extensions


Apple TV Screensavers

I recently went through the trials and tribulations of upgrading PHP on my VM running CentOS 7 so I thought I'd document how I did it.

The key to it is the Remi RPM Repository but I made the dumb mistake of adding the repos for the CentOS 6 version of the 5.6 upgrade so to fix that I removed all of the repos I just added:

rm -rf /etc/yum.repos.d/remi*

and then I just added what I needed manually:

cat > /etc/yum.repos.d/remi-php56.repo << EOF

Then you need to clear the cache:

yum clean expire-cache

and re-run the update

yum update

You might get some errors like so:

Error: Package: php-gd-5.6.22-1.el7.remi.x86_64 (remi-php56)
Error: Package: php-gd-5.6.22-1.el7.remi.x86_64 (remi-php56)
       Requires: gd-last(x86-64) >= 2.1.1
Error: Package: php-pecl-zip-1.13.2-1.el7.remi.5.6.x86_64 (remi-php56)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

To fix these:


yum localinstall gd-last-*.rpm


yum localinstall libzip-last-*.rpm

yum update

That should have worked, so try running php -v.

You might have some warnings like I did:

PHP Warning:  PHP Startup: newrelic: Unable to initialize module
Module compiled with module API=20100525
PHP    compiled with module API=20131226
These options need to match
in Unknown on line 0
PHP Warning:  PHP Startup: ssh2: Unable to initialize module
Module compiled with module API=20100525
PHP    compiled with module API=20131226
These options need to match
in Unknown on line 0
PHP 5.6.22 (cli) (built: May 26 2016 15:36:45)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

New Relic is easy to fix:

newrelic-install install

and for ssh2, I just removed it:

rm -rf /etc/php.d/ssh2.ini

re-reun php -v to confirm that the warnings are gone.

Hope it helps.


I recently spent a productive weekend eventually learning gulp and after reading countless blog posts and tutorials, I finally managed to get a workflow together that worked perfectly for me - spinning up a local web server, SASS compilation, asset minification and js uglifying, as well as (cached) image optimisation, and last but not least, deploying.

If I remember correctly, the vast majority of this came from one source but I cannot remember where, so apologies for that.

The changes I made included using gulp-connect-php and figuring out how to get it to point to the app directory and how to run the watching and SASS compilation tasks upon starting the server.

After that, it just needed a teak to also compile the SASS before trying to minify the CSS.

Finally, the last bit of pain was trying to figure out the deployment - it worked fine but everything was under the dist directory which I didn't want, the rsyncConf.root = 'dist'; sorts that issue out.

This post is a follow-on from How to Use Capistrano 3 for Ghost Theme Deployment, so please read that first.

The aim of this post is to introduce SASS to the workflow instead of vanilla CSS.

I followed this excellent blog post here but I will describe what specific changes I made to my local project.

First off, as the post points out, you need to install the SASS gem both to your local machine and your production server.

gem install sass

When installing on production, the main thing to watch out for is to install it as the deploy_user and not root.

The problem I had is that my specific deploy user didn't have permission to write to the location where rbenv installs its gems so if you are using rbenv or rvm then that is something to watch out for.

I simply did

sudo gem install sass

and that solved the problem.

The next thing was to follow the steps from the blog post to create the .scss files and also untracking the existing screen.css and deleting the local copy once we have everything we need in the sass stylesheets.

The problem we will have now is that git doesn't track empty directories so we will need to update the deploy.rb to create the assets/css directory when we deploy.

To build it locally if you are doing local development you can do the following from your theme root directory:

sass assets/sass/input.scss:assets/css/screen.css --style compressed

You can add the --watch option to continually monitor for changes.

We then need to update the .gitignore file so that .css and .map files can't accidentally be committed:


The last thing to do is then update the execute statements in deploy.rb

# symlink REVISION file
execute 'sudo ln -sf /var/www/path_to_ghost_install/content/themes/theme_name/current/REVISION /var/www/path_to_ghost_install/content/themes/theme_name/REVISION'
 # create css directory for our compiled stylesheet to go in
execute 'sudo mkdir /var/www/path_to_ghost_install/content/themes/theme_name/current/assets/css'
# symlink all the files from the current release to the theme root
execute 'sudo ln -sf /var/www/path_to_ghost_install/content/themes/theme_name/current/* /var/www/path_to_ghost_install/content/themes/theme_name'
# chown everything to be owned by our ghost user and not the deploy user
execute 'sudo chown -R ghost_user:ghost_user /var/www/path_to_ghost_install/content/themes/theme_name'
# compile the css stylesheet from our sass files
execute 'sudo sass /var/www/path_to_ghost_install/content/themes/theme_name/current/assets/sass/input.scss:/var/www/path_to_ghost_install/content/themes/theme_name/current/assets/css/screen.css --style compressed'
# restart the forever process
execute 'sudo forever restart /var/www/path_to_ghost_install/index.js'

Don't forget to push your changes to your git repo before deploying.

As you may know, I am using the Bulma flexbox css framework for my personal Ghost theme.

As part of the framework, there are notifications and the framework also provides the ability to include a delete button for the notification, but it is completely static and doesn't do anything - yet.

I also had to add some CSS to fix the button for the notification:

.notification > button.delete {
  border: none;

which is strange as it seems fine on the Bulma site.

In addition to this, I added a new modifier class in the naming convention of the existing classes:

.is-hidden {
  display: none;

This class is then applied to the notification when the delete button is clicked.

To achieve that in jQuery, you can simply use this:

$(document).on('click', '.notification > button.delete', function() {
    return false;

You could optionally remove the element from the DOM completely by chaining the .remove() method, e.g.


See the Pen Bulma CSS Framework - Add Functionality to Dismiss Notifications by Martin Carlin (@martincarlin87) on CodePen.