title: Decorators and method chaining
body: <p><strong>Goal</strong>: I want to "decorate" Laravel's Query Builder with additional functionality (without directly modifying it). </p>
  
  <p><strong>Example Problem</strong>: I'll try to keep this very brief. I have implemented a <code>get</code> method on my decorator:</p>
  
  <pre><code>public function get($columns = ['*'])
  {
      return $this-&gt;cache-&gt;get(implode('.', $columns), function () use ($columns) {
          return $this-&gt;queryBuilder-&gt;get($columns);
      });
  }
  </code></pre>
  
  <p>I'm also delegating all calls to methods not implemented on the decorator to the Query Builder.</p>
  
  <pre><code>public function __call($method, $parameters)
  {
      return call_user_func_array([$this-&gt;queryBuilder, $method], $parameters);
  }
  </code></pre>
  
  <p>Works fine when calling directly on the decorator, as you would expect. But almost everyone is used to chaining methods together when using the Query Builder.</p>
  
  <pre><code>$queryBuilder = (new CachingDecorator( new QueryBuilder , $app['cache.store'] ));
  
  // get all users
  $queryBuilder-&gt;from('users')-&gt;get();
  
  // get one user
  $queryBuilder-&gt;from('users')-&gt;first(); // &lt;-- delegates to get() internally
  </code></pre>
  
  <p><strong>Problem</strong>: The results from the call directly above are not being cached. Obviously because the <code>from</code> method returns an instance of the Laravel Query Builder and not my decorator.</p>
  
  <p><strong>Question</strong>: Is there some helpful pattern that will help solve this? Or is this a limitation of the decorator pattern?</p>
  
  <p>My first thought was to try to bind $this to another object, like you can in Javascript. I don't think PHP allows this.</p>
  
  <p>The best solution I can come up with involves a class to map the query builder object to its decorator(s), and/or some sort of base decorator that re-implements almost every method in the query builder object (not a fan of this one as it totally throws the DRY principle out the window).</p>
  
  <p><strong>Additional Notes</strong>: I know I could side-step the issue by just not chaining method calls together. No brainer right? Except it is not reasonable to ask every developer on the team to avoid chaining their calls together. I would much rather <strong>solve</strong> this problem than side-step it.</p>