Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[5.5] Add whereIn and whereNotIn constraints to DatabaseRule #20691

Merged
merged 3 commits into from
Aug 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions src/Illuminate/Validation/Rules/DatabaseRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ trait DatabaseRule
protected $wheres = [];

/**
* The custom query callback.
* The array of custom query callbacks.
*
* @var \Closure|null
* @var array
*/
protected $using;
protected $using = [];

/**
* Create a new rule instance.
Expand Down Expand Up @@ -99,6 +99,34 @@ public function whereNotNull($column)
return $this->where($column, 'NOT_NULL');
}

/**
* Set a "where in" constraint on the query.
*
* @param string $column
* @param array $values
* @return $this
*/
public function whereIn($column, array $values)
{
return $this->where(function ($query) use ($column, $values) {
$query->whereIn($column, $values);
});
}

/**
* Set a "where not in" constraint on the query.
*
* @param string $column
* @param array $values
* @return $this
*/
public function whereNotIn($column, array $values)
{
return $this->where(function ($query) use ($column, $values) {
$query->whereNotIn($column, $values);
});
}

/**
* Register a custom query callback.
*
Expand All @@ -107,7 +135,7 @@ public function whereNotNull($column)
*/
public function using(Closure $callback)
{
$this->using = $callback;
$this->using[] = $callback;

return $this;
}
Expand All @@ -119,7 +147,7 @@ public function using(Closure $callback)
*/
public function queryCallbacks()
{
return $this->using ? [$this->using] : [];
return $this->using;
}

/**
Expand Down
166 changes: 164 additions & 2 deletions tests/Validation/ValidationExistsRuleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,179 @@
namespace Illuminate\Tests\Validation;

use PHPUnit\Framework\TestCase;
use Illuminate\Validation\Validator;
use Illuminate\Validation\Rules\Exists;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Validation\DatabasePresenceVerifier;

class ValidationExistsRuleTest extends TestCase
{
/**
* Setup the database schema.
*
* @return void
*/
public function setUp()
{
$db = new DB;

$db->addConnection([
'driver' => 'sqlite',
'database' => ':memory:',
]);

$db->bootEloquent();
$db->setAsGlobal();

$this->createSchema();
}

public function testItCorrectlyFormatsAStringVersionOfTheRule()
{
$rule = new \Illuminate\Validation\Rules\Exists('table');
$rule = new Exists('table');
$rule->where('foo', 'bar');
$this->assertEquals('exists:table,NULL,foo,bar', (string) $rule);

$rule = new \Illuminate\Validation\Rules\Exists('table', 'column');
$rule = new Exists('table', 'column');
$rule->where('foo', 'bar');
$this->assertEquals('exists:table,column,foo,bar', (string) $rule);
}

public function testItChoosesValidRecordsUsingWhereInRule()
{
$rule = new Exists('users', 'id');
$rule->whereIn('type', ['foo', 'bar']);

EloquentTestUser::create(['id' => '1', 'type' => 'foo']);
EloquentTestUser::create(['id' => '2', 'type' => 'bar']);
EloquentTestUser::create(['id' => '3', 'type' => 'baz']);
EloquentTestUser::create(['id' => '4', 'type' => 'other']);

$trans = $this->getIlluminateArrayTranslator();
$v = new Validator($trans, [], ['id' => $rule]);
$v->setPresenceVerifier(new DatabasePresenceVerifier(Eloquent::getConnectionResolver()));

$v->setData(['id' => 1]);
$this->assertTrue($v->passes());
$v->setData(['id' => 2]);
$this->assertTrue($v->passes());
$v->setData(['id' => 3]);
$this->assertFalse($v->passes());
$v->setData(['id' => 4]);
$this->assertFalse($v->passes());
}

public function testItChoosesValidRecordsUsingWhereNotInRule()
{
$rule = new Exists('users', 'id');
$rule->whereNotIn('type', ['foo', 'bar']);

EloquentTestUser::create(['id' => '1', 'type' => 'foo']);
EloquentTestUser::create(['id' => '2', 'type' => 'bar']);
EloquentTestUser::create(['id' => '3', 'type' => 'baz']);
EloquentTestUser::create(['id' => '4', 'type' => 'other']);

$trans = $this->getIlluminateArrayTranslator();
$v = new Validator($trans, [], ['id' => $rule]);
$v->setPresenceVerifier(new DatabasePresenceVerifier(Eloquent::getConnectionResolver()));

$v->setData(['id' => 1]);
$this->assertFalse($v->passes());
$v->setData(['id' => 2]);
$this->assertFalse($v->passes());
$v->setData(['id' => 3]);
$this->assertTrue($v->passes());
$v->setData(['id' => 4]);
$this->assertTrue($v->passes());
}

public function testItChoosesValidRecordsUsingWhereNotInAndWhereNotInRulesTogether()
{
$rule = new Exists('users', 'id');
$rule->whereIn('type', ['foo', 'bar', 'baz'])->whereNotIn('type', ['foo', 'bar']);

EloquentTestUser::create(['id' => '1', 'type' => 'foo']);
EloquentTestUser::create(['id' => '2', 'type' => 'bar']);
EloquentTestUser::create(['id' => '3', 'type' => 'baz']);
EloquentTestUser::create(['id' => '4', 'type' => 'other']);

$trans = $this->getIlluminateArrayTranslator();
$v = new Validator($trans, [], ['id' => $rule]);
$v->setPresenceVerifier(new DatabasePresenceVerifier(Eloquent::getConnectionResolver()));

$v->setData(['id' => 1]);
$this->assertFalse($v->passes());
$v->setData(['id' => 2]);
$this->assertFalse($v->passes());
$v->setData(['id' => 3]);
$this->assertTrue($v->passes());
$v->setData(['id' => 4]);
$this->assertFalse($v->passes());
}

protected function createSchema()
{
$this->schema('default')->create('users', function ($table) {
$table->unsignedInteger('id');
$table->string('type');
});
}

/**
* Get a schema builder instance.
*
* @return \Illuminate\Database\Schema\Builder
*/
protected function schema($connection = 'default')
{
return $this->connection($connection)->getSchemaBuilder();
}

/**
* Get a database connection instance.
*
* @return \Illuminate\Database\Connection
*/
protected function connection($connection = 'default')
{
return $this->getConnectionResolver()->connection($connection);
}

/**
* Get connection resolver.
*
* @return \Illuminate\Database\ConnectionResolverInterface
*/
protected function getConnectionResolver()
{
return Eloquent::getConnectionResolver();
}

/**
* Tear down the database schema.
*
* @return void
*/
public function tearDown()
{
$this->schema('default')->drop('users');
}

public function getIlluminateArrayTranslator()
{
return new \Illuminate\Translation\Translator(
new \Illuminate\Translation\ArrayLoader, 'en'
);
}
}

/**
* Eloquent Models.
*/
class EloquentTestUser extends Eloquent
{
protected $table = 'users';
protected $guarded = [];
public $timestamps = false;
}