Showing posts with label Laravel 5. Show all posts
Showing posts with label Laravel 5. Show all posts

Saturday, January 30, 2016

Creating live links in Whoops (Laravel 5.1 edition)

Whoops is "an error handler framework for PHP. Out-of-the-box, it provides a pretty error interface that helps you debug your web projects, but at heart it's a simple yet powerful stacked error handling system." I was introduced to it in Laravel 4, but then it was removed in Laravel 5. Matt Stauffer and then Ryan Winchester provided instructions on bringing Whoops back into Laravel 5.x and it's much nicer than the standard Laravel error message.

Out-of-the-box, it also provides 'live' links into your code, directly to the file and line on which the error occurred, and all the way through the stack trace. Pick a point in the stack, click on the file link, and if you've set the editor properly in the Whoops handler, you're instantly in the correct spot in your code!

That is unless the error occurs on a server, and that server has a different base path than the machine where your code resides. A server running on a Vagrant box for instance. Like many other things, the server path has to be mapped to a local path. In the Whoops error handler, it needs to map to the correct local-to-your-editor file location so Whoops can build the correct links.

Here's the way to do that:

First follow Ryan's excellent instructions for getting Whoops running in Laravel 5.1. Then modify this area of his code:


To this:


And add a 'vagrant home' variable to .env:


In the new callback in handler.php:
  • line 12 adds a $translations array that rewrites the source file location from 'remote' to 'local' directories
  • line 15 performs the 'translations' and urlencodes the resulting location
  • line 19 sets the editor. This doesn't have to be Phpstorm by any means. Whoops PrettyPageHandler contains a list of editor links. The path for Sublime would be "subl://open?url=file://$file&line=$line" or MacVim: "mvim://open/?url=file://$file&line=$line"

Also fix the CSS

I wasn't entirely happy with some of the new Whoops 2.0 css, so I overwrote some of it in an alternate whoops.base.css file which has to be registered with Whoops, so:
  • line 24 adds another local-to-the-app resource path
  • line 25 adds the custom css
Which is just this:

The original Whoops 2.0 css lives in {doc_root}/vendor/filp/whoops/src/Whoops/Resources/css/whoops.base.css

Tuesday, December 01, 2015

Switching database ports on-the-fly for Artisan, PHPUnit

One of the minor (really minor) annoyances of using Artisan in a Homestead/Vagrant environment is having to remember to run commands that interact with a database on the server, since that's where the database lives. It's possible to run them in the host environment, but you have to switch the host port to the correct forwarded port (from 3306 to 33060 for MySql).

A few extra properties in .env, and a wee bit of code in the not-often-used 'port' entry does that switching in the database configuration file based on the $_SERVER['HOME'] entry, which is completely passive and doesn't require any special setup on the server. Works for PHPUnit tests too:


This solution may be a little hacky, but it works reliably. If there's a better way (there probably is), please let me know in the comments.

Also note the change from the default 'utf8' in 'charset' and 'collation'. This has nothing to do with port switching but has everything to do with MySql's handling of UTF8. There's a good writeup about it here, the gist of which is:
MySQL’s utf8 encoding is awkwardly named, as it’s different from proper UTF-8 encoding. It doesn’t offer full Unicode support.
...
Luckily, MySQL 5.5.3 (released in early 2010) introduced a new encoding called utf8mb4 which maps to proper UTF-8 and thus fully supports Unicode...

So I (we) should have been using MySQL 5.5.3 with that charset for at least the last 5 years.

Tuesday, November 24, 2015

Testing a New Artisan command in Laravel 5.1

It took me quite a while to figure this out today (and for sure there may be a better way), but there didn't seem to be a well-documented way to test Laravel 5.1 Artisan commands. The main reason that I want to do this is to be able to run some simple commands directly in an Artisan command without writing another class just to essentially act as a test harness. In the case I was working on, I'm adding a field to a database table that needs to be populated with an initial attribute in every row for ElasticSearch. This will normally happen when a record is upserted, but initially it'll run once for each row in a loop as part of a multi-system update. I thought I'd run it as an Artisan command, although realistically it'd be better run as a queue-able job.

I spent some time with Laracasts but the TDD tests were 1) based on Codeception (nice, but not what I wanted) and 2) were for Laravel 4. Directly using the Symfony console test methodology doesn't work with Laravel's IoC container in Laravel 5.1. Even the Laravel foundation tests don't specifically test each of the Artisan console commands. At least I couldn't find anything, although ultimately it was the way that Laravel instantiates Artisan that gave me a clue.

You can run an Artisan command in your tests, but what I really wanted to do was check the output to the terminal, which means capturing stdout while running a command, which the test-native Artisan command doesn't support.

In any event, this works well, and displays both ways of running an Artisan command in a test:

A blog post every couple of years seems to be about the right frequency. No?