Skip to content

Commit

Permalink
Enable QueryBuilder to be resolved from the container
Browse files Browse the repository at this point in the history
  • Loading branch information
adamtomat committed Jun 14, 2018
1 parent 2667242 commit 56a48b2
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 19 deletions.
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,21 @@
![CI](https://travis-ci.org/Rareloop/lumberjack-querybuilder.svg?branch=master)
![Coveralls](https://coveralls.io/repos/github/Rareloop/lumberjack-querybuilder/badge.svg?branch=master)

Experimental QueryBuilder for Lumberjack Post objects.
Experimental QueryBuilder for Lumberjack Post objects.

## Install
```
composer require rareloop/lumberjack-querybuilder
```

Once installed, register the Service Provider in `config/app.php` within your theme:

```
'providers' => [
...
Rareloop\Lumberjack\QueryBuilder\QueryBuilderServiceProvider::class,
...
],
```
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "rareloop/lumberjack-querybuilder",
"require": {
"rareloop/lumberjack-core": "^3.0.0"
"rareloop/lumberjack-core": "^3.2.0",
"tightenco/collect": ">=5.5.33"
},
"require-dev": {
"phpunit/phpunit": "^6.0",
Expand Down
34 changes: 34 additions & 0 deletions src/Contracts/QueryBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Rareloop\Lumberjack\QueryBuilder\Contracts;

use Tightenco\Collect\Support\Collection;

interface QueryBuilder
{
public function getParameters() : array;

public function wherePostType($postType) : QueryBuilder;

public function limit($limit) : QueryBuilder;

public function offset($offset) : QueryBuilder;

public function orderBy($orderBy, string $order = QueryBuilder::ASC) : QueryBuilder;

public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string $type = null) : QueryBuilder;

public function whereIdIn(array $ids) : QueryBuilder;

public function whereIdNotIn(array $ids) : QueryBuilder;

public function whereStatus() : QueryBuilder;

public function whereMeta($key, $value, $compare = '=', $type = null) : QueryBuilder;

public function whereMetaRelationshipIs(string $relation) : QueryBuilder;

public function get() : Collection;

public function clone() : QueryBuilder;
}
30 changes: 16 additions & 14 deletions src/QueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

namespace Rareloop\Lumberjack\QueryBuilder;

use Rareloop\Lumberjack\QueryBuilder\Contracts\QueryBuilder as QueryBuilderContract;
use Rareloop\Lumberjack\QueryBuilder\Exceptions\InvalidMetaRelationshipException;
use Rareloop\Lumberjack\QueryBuilder\Post;
use Tightenco\Collect\Support\Collection;
use Timber\Timber;

class QueryBuilder
class QueryBuilder implements QueryBuilderContract
{
protected $postClass = Post::class;

Expand Down Expand Up @@ -39,7 +41,7 @@ class QueryBuilder
const OR = 'OR';
const AND = 'AND';

public function getParameters()
public function getParameters() : array
{
$params = [
'post_type' => $this->postType,
Expand Down Expand Up @@ -91,28 +93,28 @@ public function getParameters()
return $params;
}

public function wherePostType($postType)
public function wherePostType($postType) : QueryBuilderContract
{
$this->postType = $postType;

return $this;
}

public function limit($limit)
public function limit($limit) : QueryBuilderContract
{
$this->limit = $limit;

return $this;
}

public function offset($offset)
public function offset($offset) : QueryBuilderContract
{
$this->offset = $offset;

return $this;
}

public function orderBy($orderBy, string $order = QueryBuilder::ASC)
public function orderBy($orderBy, string $order = QueryBuilder::ASC) : QueryBuilderContract
{
$order = strtoupper($order);

Expand All @@ -122,7 +124,7 @@ public function orderBy($orderBy, string $order = QueryBuilder::ASC)
return $this;
}

public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string $type = null)
public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string $type = null) : QueryBuilderContract
{
$order = strtoupper($order);

Expand All @@ -133,21 +135,21 @@ public function orderByMeta($metaKey, string $order = QueryBuilder::ASC, string
return $this;
}

public function whereIdIn(array $ids)
public function whereIdIn(array $ids) : QueryBuilderContract
{
$this->whereIn = $ids;

return $this;
}

public function whereIdNotIn(array $ids)
public function whereIdNotIn(array $ids) : QueryBuilderContract
{
$this->whereNotIn = $ids;

return $this;
}

public function whereStatus()
public function whereStatus() : QueryBuilderContract
{
$args = func_get_args();

Expand All @@ -160,7 +162,7 @@ public function whereStatus()
return $this;
}

public function whereMeta($key, $value, $compare = '=', $type = null)
public function whereMeta($key, $value, $compare = '=', $type = null) : QueryBuilderContract
{
$params = [
'key' => $key,
Expand All @@ -177,7 +179,7 @@ public function whereMeta($key, $value, $compare = '=', $type = null)
return $this;
}

public function whereMetaRelationshipIs(string $relation)
public function whereMetaRelationshipIs(string $relation) : QueryBuilderContract
{
$relation = strtoupper($relation);

Expand All @@ -192,12 +194,12 @@ public function whereMetaRelationshipIs(string $relation)
return $this;
}

public function get()
public function get() : Collection
{
return collect(Timber::get_posts($this->getParameters(), $this->postClass));
}

public function clone()
public function clone() : QueryBuilderContract
{
$clone = clone $this;

Expand Down
15 changes: 15 additions & 0 deletions src/QueryBuilderServiceProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Rareloop\Lumberjack\QueryBuilder;

use Rareloop\Lumberjack\Providers\ServiceProvider;
use Rareloop\Lumberjack\QueryBuilder\Contracts\QueryBuilder as QueryBuilderContract;
use Rareloop\Lumberjack\QueryBuilder\QueryBuilder;

class QueryBuilderServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(QueryBuilderContract::class, QueryBuilder::class);
}
}
23 changes: 20 additions & 3 deletions src/ScopedQueryBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,32 @@

namespace Rareloop\Lumberjack\QueryBuilder;

use Rareloop\Lumberjack\Helpers;
use Rareloop\Lumberjack\QueryBuilder\Exceptions\CannotRedeclarePostTypeOnQueryException;
use Rareloop\Lumberjack\QueryBuilder\QueryBuilder;
use Rareloop\Lumberjack\QueryBuilder\Contracts\QueryBuilder as QueryBuilderContract;

class ScopedQueryBuilder extends QueryBuilder
class ScopedQueryBuilder
{
public function __construct($postClass)
{
$this->postClass = $postClass;

$this->queryBuilder = Helpers::app(QueryBuilderContract::class);
}

public function __call($name, $arguments)
{
// Proxy QueryBuilder methods
if (method_exists($this->queryBuilder, $name)) {
$response = call_user_func_array([$this->queryBuilder, $name], $arguments);

// We want to make sure that chaining continues through this proxy object so we
// must only return the response of the QueryBuilder if it isn't the QueryBuilder itself
return $response === $this->queryBuilder ? $this : $response;
}

// See if this is a scope function that needs calling
$scopeFunctionName = 'scope' . ucfirst($name);

$post = new $this->postClass(false, true);
Expand All @@ -27,14 +41,17 @@ public function __call($name, $arguments)

public function getParameters()
{
return array_merge(parent::getParameters(), ['post_type' => call_user_func([$this->postClass, 'getPostType'])]);
return array_merge(
$this->queryBuilder->getParameters(),
['post_type' => call_user_func([$this->postClass, 'getPostType'])]
);
}

public function wherePostType($postType)
{
throw new CannotRedeclarePostTypeOnQueryException;
}

public function get()
{
return $this->postClass::query($this->getParameters());
Expand Down
11 changes: 11 additions & 0 deletions tests/Unit/PostQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,24 @@

use Mockery;
use PHPUnit\Framework\TestCase;
use Rareloop\Lumberjack\Application;
use Rareloop\Lumberjack\QueryBuilder\Contracts\QueryBuilder as QueryBuilderContract;
use Rareloop\Lumberjack\QueryBuilder\Post;
use Rareloop\Lumberjack\QueryBuilder\QueryBuilder;
use Rareloop\Lumberjack\QueryBuilder\ScopedQueryBuilder;

class PostQueryBuilderTest extends TestCase
{
use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;

public function setUp()
{
$this->app = new Application;
$this->app->bind(QueryBuilderContract::class, QueryBuilder::class);

parent::setUp();
}

/** @test */
public function can_create_a_builder()
{
Expand Down
24 changes: 24 additions & 0 deletions tests/Unit/QueryBuilderServiceProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Rareloop\Lumberjack\QueryBuilder\Test\Providers;

use PHPUnit\Framework\TestCase;
use Rareloop\Lumberjack\Application;
use Rareloop\Lumberjack\Config;
use Rareloop\Lumberjack\Http\Lumberjack;
use Rareloop\Lumberjack\QueryBuilder\Contracts\QueryBuilder as QueryBuilderContract;
use Rareloop\Lumberjack\QueryBuilder\QueryBuilderServiceProvider;

class PostQueryBuilderTest extends TestCase
{
/** @test */
public function query_builder_is_registered_into_container()
{
$app = new Application;
$provider = new QueryBuilderServiceProvider($app);

$provider->register();

$this->assertTrue($app->has(QueryBuilderContract::class));
}
}
29 changes: 29 additions & 0 deletions tests/Unit/ScopedQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@
use Illuminate\Support\Collection;
use Mockery;
use PHPUnit\Framework\TestCase;
use Rareloop\Lumberjack\Application;
use Rareloop\Lumberjack\QueryBuilder\Contracts\QueryBuilder as QueryBuilderContract;
use Rareloop\Lumberjack\QueryBuilder\Post;
use Rareloop\Lumberjack\QueryBuilder\QueryBuilder;
use Rareloop\Lumberjack\QueryBuilder\ScopedQueryBuilder;
use Timber\Timber;

class ScopedQueryBuilderTest extends TestCase
{
use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;

public function setUp()
{
$this->app = new Application;
$this->app->bind(QueryBuilderContract::class, QueryBuilder::class);

parent::setUp();
}

/** @test */
public function correct_post_type_is_set()
{
Expand Down Expand Up @@ -82,6 +93,24 @@ public function missing_query_scope_throws_an_error()
$builder = new ScopedQueryBuilder(PostWithQueryScope::class);
$builder->nonExistentScope();
}

/** @test */
public function can_use_a_different_query_builder_implementation()
{
$this->app->bind(QueryBuilderContract::class, CustomQueryBuilder::class);

$builder = new ScopedQueryBuilder(Post::class);

$this->assertSame('it works', $builder->nonStandardMethod());
}
}

class CustomQueryBuilder extends QueryBuilder
{
public function nonStandardMethod()
{
return 'it works';
}
}

class PostWithQueryScope extends Post
Expand Down

0 comments on commit 56a48b2

Please sign in to comment.