Meandering Soul

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

Using Git Hooks for code style fixes

16
Oct 2015

Pretty much every modern language has an established Coding Style Guide. For PHP, this is PSR-2. As with other style guides of this sort, there is a tool for automatically applying the appropriate fixes to one’s code

I only recently finally switched to using PSR-2 and to make sure I wouldn’t accidentally miss running the style fixer, I added this little snipped to my .git/hooks/pre-commit-Hook:

1
2
3
4
5
6
modified_php=$(git ls-files --modified | grep "\.php$")

for f in $modified
do
    php-cs-fixer fix --level psr2 $f
done
  • Published on October 16, 2015
  • 84 words

Redirecting in Laravel Form Requests

08
May 2015

While Form Request Validation in Laravel 5 usually does exactly what it’s supposed to do, I recently had to append a location hash to the redirect URL. Turns out that’s as simple as overwriting the FormRequest’s getRedirectUrl()-method:

1
2
3
4
5
protected function getRedirectUrl()
{
  $url = $this->redirector->getUrlGenerator();
  return $url->previous().'#hash';
}
  • Published on May 08, 2015
  • 49 words

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