Meandering Soul

This day is done, I'm going home.
eFranes Penguin Avatar

Dependency Injection with inherited Controllers in Laravel 5

20
Apr 2015

Usually, when setting up my controllers in a Laravel 5 application, I end up creating one or several base controllers for different entry points (e.g. APIController, FrontendController, …) While I deem this a good practice, it can lead to problems with Laravel’s otherwise fantastic Dependency Injection. To illustrate, take a look at the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// FrontendController.php

class FrontendController extends Controller
{
  public function __construct(\Illuminate\Contracts\Events\Dispatcher $dispatcher)
  {
    $dispatcher->listen('composing: frontend.base', function ()
      {
        // handle root view compose
      }
    );
  }
}

// BlogController.php

class BlogController extends FrontendController
{
  protected $repo = null;

  public function __construct(TextRepository $repo)
  {
    $this->repo = $repo;
  }
}

As some IDEs and testing tools would say: There are multiple problems!

  1. The BlogController’s constructor does not call the parent.
  2. The constructors do neither match nor can all required parameters be handed down.
  3. Actually there is no number three but lists with two points always seem awkward.

Look at the mess I made!

Not calling the parent constructor which probably does important things? Bad idea. Could be fixed with changing the constructor of BlogController to:

1
2
3
4
5
public function __construct(TextRepository $repo)
{
  $this->repo = $repo;
  parent::__construct();
}

But then again that’s not quite right too, is it? It should be more along the lines of this:

1
2
3
4
5
public function __construct(\Illuminate\Contracts\Events\Dispatcher $dispatcher, TextRepository $repo)
{
  $this->repo = $repo;
  parent::__construct($dispatcher);
}

Which is ugly as hell. Let alone remembering that for all of the other descendants of the FrontendController.

Let’s make that pretty

Right around the time I realized that I didn’t want to write that second version even once, I thought “hey, Eloquent models have this boot() method. That could be a way to go.”

Said and done. I refactored my code to this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// FrontendController.php

...
  public function __construct(\Illuminate\Contracts\Events\Dispatcher $dispatcher)
  {
    // the dispatcher stuff

    if (method_exists($this, 'boot')) $this->boot();
  }

// BlogController.php

public class BlogController extends FrontendController
{
  public function boot(TextRepository $repo)
  {
    $this->repo = $repo;
  }
}

Which, of course, did not work. And - as too often is the case - the error was all too obvious to me once I had committed the crime. So, after a while, I figured that if Laravel can resolve class names to inject from type hints, why shouldn’t I. Thus followed some research on method reflection and I ended up with this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// FrontendController.php

...
  public function __construct(\Illuminate\Contracts\Events\Dispatcher $dispatcher)
  {
    // the dispatcher stuff

    if (method_exists($this, 'boot'))
    {
      // resolve the boot dependencies
      $reflect = new \ReflectionMethod($this, 'boot');
      $reflectedParameters = $reflect->getParameters();

      $bootArguments = [];

      foreach ($reflectedParameters as $reflectedParameter)
      {
        preg_match("/.*<required> (.+) \${$reflectedParameter->getName()}/", $reflectedParameter, $typeHint);

        if (count($typeHint) == 2)
        {
          $className = $typeHint[1];
          $resolved = app()->make($className);

          array_push($bootArguments, $resolved);
        } 
      }

      call_user_func_array([&$this, 'boot'], $bootArguments);
    }
  }

And this, finally, works just as expected. One thing to note though: Bad things will happen if you have anything but type-hinted to-be-resolved classes as attributes to the boot() method.

  • Published on April 20, 2015
  • 486 words

Deep Linking in Eloquent Models

13
Apr 2015

Sometimes, when designing data models, it turns out that access to a property of a related model might be handy from the current model. For the case of one-to-many relations, Laravel’s Eloquent already comes with the hasManyThrough()-method. But what if it’s a one-to-one relation? And what if the attribute one wants to have access to is up a few levels in the model hierarchy? Well, turns out that can be pretty easily done, too.

Assuming, three models A, B, C all related, e.g. B has a_id, C has b_id and C would benefit from direct access to A, that can be achieved through Eloquent with the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class C extends Model
{
    ...

    public function b()
    {
        return $this->belongsTo('B');
    }

    public function a()
    {
        return $this->belongsTo('A');
    }

    public function getAIDAttribute()
    {
        return $this->b->a_id;
    }

    ...
}

Of course, one might also use this to fetch a specific attribute instead of creating a complete relation. Keep in mind though, that this may cause serious performance issues since the ORM has to fetch all referenced entities before it can return anything.

  • Published on April 13, 2015
  • 182 words

Lightweight links for Prism.js

09
Apr 2015

Although Prism.js provides a very good autolinker plugin, it did not quite fit my needs for a recent project. Here’s what I came up with as a stupidly simple replacement that’s not as sophisticated (i.e. does not do links in Markdown and such stuff) but works perfectly well with to-be-highlighted JSON.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
Prism.hooks.add('wrap', function(env) {
    if (env.type == 'string', env.content.match(/http/))
    {
        env.content = "<a href=\\"" 
                    + env.content.replace('"', '') 
                    + "\\">" 
                    + env.content 
                    + "</a>";
    }
});

Just add this to your site’s scripts and everything will be better.

  • Published on April 09, 2015
  • 64 words

On showing tables

25
Feb 2015

Showing the existing tables in a database can be really handy. Unfortunately, MySQL’s SHOW TABLES; is not a standard sql command. Although it quite honestly should be. Thus, for quick reference, here goes:

  • MySQL: SHOW TABLES;
  • Postgres: SELECT name FROM pg_catalog.pg_tables;
  • SQLite: SELECT name FROM sqlite_master WHERE type = 'table';

There probably is a SELECT-Syntax for MySQL too, but who really cares? The one above is so much shorter in any case.

  • Published on February 25, 2015
  • 75 words

Speeding up test cycles

12
Jan 2015

Codeception supports several layers of selecting which tests to actually run when you invoke codecept run. This can - among other times - be extremely useful when you’re trying to fix a bug and you really only need that one single test method to run or when you’re just doing API development and don’t need to check all of your UI integration tests for the time being.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# run all tests in all test suites
$ ./codecept run 

# run all tests in a single test suite
$ ./codecept run <suite> 

# run a single test case in the given suite
$ ./codecept run <suite> <test>          

# run only the given method in the test case
$ ./codecept run <suite> <test>:<method>
  • Published on January 12, 2015
  • 119 words

Wrapping HTML in PHP

28
Dec 2014

Among other things, I am currently working on rewriting the text handling code of this website into something cleaner and more usable. In the current version, the text manipulation is a big non-deterministic ugly mess of regular expressions and other not-so-niceties. For the new version I decided on going with a modular approach and - more importantly - doing the actual replacements I want to apply to the Markdown before showing it with DOM manipulations.

One of the wonderful but often forgotten features of PHP’s DOM library is that it offers the DOMDocumentFragment not-quite-standard part of the DOM Level 1 spec. John Resig once wrote a wonderful piece on the JavaScript version of this. As John points out, working with fragments can lead to significant performance improvements. I have to admit that I did not conduct performance testing to conclusively say that this also applies to PHP but it at least feels faster. Additionally, these fragments don’t come with all the garbage of full blown HTML documents that the default DOMDocument tends to deliver.

In the case of having HTML stored in a string variable, wrapping things is almost too easy:

$html = "<p>I will be wrapped</p>"; $html = "<div>".$html."</div>";

I bet you wrote code like that at least once. Regardless of the programming language. But this is not good code. To me, the most obvious flaw is the possibility to miss things. What if you forget the slash in the second div. Happened to the best of us. Followed by hours of trying to find out why there’s suddenly this weird gap in the page.

When manipulating HTML inside the DOM classes, malformed output cannot happen. Exceptions can, but that’s the point. You’ll know when something goes wrong before you already shipped it to the client. Unfortunately, working with objects usually means a little more code than string manipulation. In return, the code allows for telling a better readable story.

The below code snippet is extracted from the above mentioned text manipulation library I am working on. Once finished (which hopefully happens in the coming days/weeks), this will be available on GitHub. There will of course be a Laravel integration. The presented method accepts a node (which technically already could contain children) in which the given fragment will be wrapped. Poof, magic. Requires PHP >=5.4, though.

1
2
3
4
5
6
7
8
protected function wrapFragment(DOMDocumentFragment $fragment, DOMNode $wrapNode)
{
    $newFragment = $this->doc->createDocumentFragment();
    $wrapNode->appendChild($fragment->cloneNode(true));
    $newFragment->appendChild($wrapNode);

    return $newFragment;
}
  • Published on December 28, 2014
  • 405 words

Grunt and Codeception

12
Dec 2014

Codeception is a great tool for testing PHP Applications in a variety of different ways. Grunt is a great tool for managing all kinds of deployment tasks from minifying CSS and JavaScript to moving compiled assets around. In terms of continuous integration and quick development cycles, I like to get the amount of commands I have to run to test any change in an application as close to zero as possible. Since this is not exactly a tutorial, I am going to assume that you know the basics of using the above tools, if not, I recommend you consult this Laracast for Codeception and Grunt’s very own getting started page on *drumroll* Grunt. And yes, I know that this Laracast is not free but trust me: Laracasts really are like Netflix for developers.

So far, I already had a Gruntfile and a Codeception configuration that reduced everything to:

1
2
$ grunt                   # run client side integration
$ vendor/bin/codecept run # run server side integration

This is not ideal though. Especially not for active development when I want this stuff to run after every relevant edit. Also, 2 is greater than 0. I figured that ideally, two things needed to happen:

  1. grunt starts codeception
  2. grunt tasks run automagically after file changes

The first requirement was easily achieved with grunt-run:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
run: {
// Gruntfile.js
...
    codeception: {
        cmd: 'vendor/bin/codecept',
        args: ['run'],
      }
    }
...
grunt.registerTask('default', ['run:codeception', ...]);

The second requirement can be solved using grunt-contrib-watch (Hint: I use Sass):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Gruntfile.js
...

watch: {
      js: {
        files: 'client/js/**/*.js',
        tasks: ['concat']
      },

      css: {
        files: 'client/sass/**/*.scss',
        tasks: ['sass', 'autoprefixer']
      },

      php: {
        files: [
          'app/**/*.php', 
          'tests/**/*.php'
        ],
        tasks: ['run:codeception']
      }
    },

Obviously, your watched directories might look a little bit different. This one here is for this website which currently is a strange hybrid between Laravel 4.2 and 5.

After these changes, for local development, I can just run grunt watch in a Terminal tab and leave that open, while on the CI server, I have the build script simply start grunt to have everything done for me.

Bonus: Desktop notifications

Desktop notifications are cool, right? I mean, at least when they actually contain useful information. Like for instance telling you that one of your tests failed. That would save you the time and effort to open up that grunt-watch terminal window after every change. So, the question is, can that be done?

While I did not stumble upon a perfect solution yet, I managed to at least get something that kind of tells me ‘Yay’ or ‘Nay’ with grunt-notify.

Setting up the notify plugin is ridiculously easy. The only thing I added in addition to enabling the plugin, is the option to extend the notification display duration and bam!, notifications appeared:

1
2
3
4
5
6
7
// Gruntfile.js
...
    notify_hooks: {
      options: {
        duration: 5
      }
    }
  • Published on December 12, 2014
  • 480 words

Tags

22
Nov 2014

A long time ago, I wrote that tags are obsolete (translated version) because search engines are better than ever at figuring our content out. And I am still convinced of that. This is one of the reasons why this website does not even have the functionality for tagging things. I did not need it, thus I did not code it. Apart from this mere technical aspect, there’s also the human factor of tags being another layer of complexity. In redesigning this website - and still constantly thinking about improvements - I made an effort not to add features I don’t want. I deliberately chose to leave Wordpress behind once and for all for the single purpose of having complete control over what this website does when and why. Admittedly, there are still a lot of things that could be done differently and better but to that end I am currently waiting on the release of Laravel 5 in order to save myself some work of the “doing things twice” nature.

But - and this is a big one - in the meantime I realized that there are indeed applications where the presence and use of tags can be beneficial. For me, this insight came with my rediscovery of Evernote. For the uninitiated, Evernote is a multi-purpose note-taking tool of general awesomeness, but to go into more detail on that would probably be worth a separate article. I do read a lot of things on the internet. My basic workflow for that is somewhat inspired by this wonderful article about learning workflows: Finding things, saving them in Pocket and – if the content seems worth keeping around – moving it over to Evernote. When I started that, I did not ever do anything more than push the „Share to Evernote“ button. The first major change occured when I created a special notebook for all the things I share via Pocket (or clip directly from a website). This simplified things in the Evernote UI quite a bit since all the articles were no longer mingled up between my personal notes and blog post drafts and all that stuff. Later, at first just as a little experiment for myself I took to applying tags on the things I share to Evernote. The idea was to summarize what I just read in three to five keywords and use these as tags.

This is where something unexpected happened. After applying this technique for a few weeks now and increasingly finding myself looking at the Tags section of the interface instead of just bluntly searching. Oftentimes, when I’m working on some programming problem or in a discussion in some project, my subconscious tells me that I read something about that topic that could be of value. Before, I had to force myself to exactly remember what I read in order to find it. Now, I am able to just take a quick glance and find the keywords that correspond to the situation. Additionally, this sometimes leads to making new connections between things because it’s easier to connect words than whole articles.

I am thus taking my previous harsh statement back. Keywords/Tags are not completely obsolete. I still believe that they are mostly useless for things like search engine optimization or rather any machine-processed content. They can though play an important role in reclaiming an overview or diving deeper into collections for humans. I currently add 10-20 web shares to Evernote per month. This may not sound very much, but do this over a few months or years and the amount of things to remember that they exist quickly exceeds the amount of things we are able to have present because of all the other stuff life requires us to know on a day-to-day basis. Ever since I first read about the pensieve in the Harry Potter novels, I wanted to have one. I wanted to store the information and thoughts I did not need „right now“ somewhere where I could easily find them when I needed them. However, back in late 2009, when I first used Evernote (or at least that’s what my oldest notes are dated at), I did not see it’s power to be just that – my pensieve. Back then though, access to the internet was not as ubiquitous as it is nowadays. Therefore and because the kind of devices we used to carry around just wasn’t powerful enough yet, it simple wasn’t possible to carry around this kind of brain extension.

Evernote has already become part of my pensieve in the cloud and yet still I wonder what features I have not yet discovered, what haven’t I yet thought about maybe using in a different way. We live in a world where having a good storage system is more important then ever and yet I too often find myself struggling to retrieve the right piece of content in the right situation with as little effort as possible. But tagging things seems to help.

  • Published on November 22, 2014
  • 835 words