Skip to content

Commit

Permalink
Implement applying default filters
Browse files Browse the repository at this point in the history
- #10
  • Loading branch information
Kyslik committed Sep 30, 2018
1 parent cc6d1df commit 1f80406
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 2 deletions.
21 changes: 20 additions & 1 deletion src/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,25 @@ public function apply(Builder $builder): Builder
}


public function default(array $defaults, int $code = 307)
{
if ($this->request->isMethod('GET') || ! empty($defaults)) {
$defaults = force_assoc_array($defaults, '');

$append = [];
foreach ($defaults as $filter => $default) {
if ( ! $this->request->has($filter)) {
$append[$filter] = $default;
}
}

if ( ! empty($append)) {
abort(redirect($this->request->fullUrlWithQuery($append), $code));
}
}
}


/**
* @return \Illuminate\Database\Eloquent\Builder
*/
Expand Down Expand Up @@ -107,7 +126,7 @@ private function filters(): array
foreach ($this->filterMap as $filter => $value) {
$method = (is_string($filter)) ? $filter : $value;

// head([]) === false, we check if head returns false and remove that item from array
// head([]) === false, we check if head returns false and remove that item from array, I am sorry
if (($filters[$method] = head($this->request->only($value))) === false) {
unset($filters[$method]);
}
Expand Down
17 changes: 17 additions & 0 deletions src/FilterContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,26 @@
interface FilterContract
{

/**
* Applies filters on a $builder instance.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
*
* @return \Illuminate\Database\Eloquent\Builder
*/
function apply(Builder $builder);


/**
* @param array $defaults
*
* @param int $code
*
* @return void
*/
function default(array $defaults, int $code = 307);


/**
* @return array ex: ['method-name', 'another-method' => 'alias', 'yet-another-method' => ['alias-one', 'alias-two]]
*/
Expand Down
24 changes: 24 additions & 0 deletions src/helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,27 @@ function remove_prefix($prefix, $subject, $check = true)
return $check ? str_replace_first($prefix, '', $subject) : substr($subject, strlen($prefix));
}
}

if ( ! function_exists('force_assoc_array')) {
/**
* Transforms array to be associative.
*
* @param array $array
* @param null $empty
*
* @return array
*/
function force_assoc_array(array $array, $empty = null)
{
$new = [];
foreach ($array as $key => $value) {
if (is_numeric($key)) {
$new[$value] = $empty;
} else {
$new[$key] = $value;
}
}

return $new;
}
}
45 changes: 45 additions & 0 deletions tests/DefaultFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Kyslik\LaravelFilterable\Test;

class DefaultFilterTest extends TestCase
{

function test_redirect_happens()
{
$this->expectException(\Illuminate\Http\Exceptions\HttpResponseException::class);
$filter = $this->buildCustomFilter('one=neo');

$filter->default(['trinity']);
}


function test_redirect_does_not_happen()
{
$filter = $this->buildCustomFilter('one=neo&side-kick=trinity');

$filter->default(['side-kick' => 'tank']);

$this->assertTrue(true, 'We are testing, that \Illuminate\Http\Exceptions\HttpResponseException is not thrown');
}


function test_defaults_redirect_with_correct_query()
{
$filter = $this->buildCustomFilter('one=neo');

try {
$code = 307;
$filter->default(['trinity', 'morpheus'], $code);
} catch (\Illuminate\Http\Exceptions\HttpResponseException $e) {
$response = $e->getResponse();

$this->assertEquals($response->getStatusCode(), $code);
$this->assertTrue($response->isRedirection());

$parameters = [];
parse_str(parse_url($response->headers->get('location'), PHP_URL_QUERY), $parameters);
$this->assertArraySubset($parameters, ['one' => 'neo', 'trinity' => '', 'morpheus' => '']);
}
}
}
5 changes: 4 additions & 1 deletion tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
use Illuminate\Http\Request;
use Kyslik\LaravelFilterable\FilterableServiceProvider;
use Kyslik\LaravelFilterable\Generic\Templater;
use Kyslik\LaravelFilterable\Test\Stubs\UserFilter;
use Kyslik\LaravelFilterable\Test\Stubs\RoleFilter;
use Kyslik\LaravelFilterable\Test\Stubs\UserFilter;
use Orchestra\Testbench\TestCase as Orchestra;

abstract class TestCase extends Orchestra
Expand Down Expand Up @@ -50,6 +50,7 @@ protected function buildFilter($requestQuery)

/** @var Request $request */
$request = resolve(Request::class)->create('http://test.dev?'.$requestQuery);
$this->app->instance(Request::class, $request);

return new UserFilter($request, resolve(Templater::class));
}
Expand All @@ -59,6 +60,8 @@ protected function buildCustomFilter($requestQuery)
{
/** @var Request $request */
$request = resolve(Request::class)->create('http://test.dev?'.$requestQuery);
$this->app->instance(Request::class, $request);

return new RoleFilter($request);
}

Expand Down

0 comments on commit 1f80406

Please sign in to comment.