Skip to content

Commit

Permalink
feat: provide trait to query flagged enums with Eloquent
Browse files Browse the repository at this point in the history
  • Loading branch information
obennaci committed Oct 2, 2020
1 parent 7a43af5 commit 70164a5
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased](https://github.com/BenSampo/laravel-enum/compare/v3.0.0...master)

### Added

- Provide trait to query flagged enums using Eloquent

## [3.0.0](https://github.com/BenSampo/laravel-enum/compare/v2.2.0...v3.0.0) - 2020-08-07

### Added
Expand Down
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,19 @@ UserPermissions::Admin()->getBitmask(); // 1111;
UserPermissions::DeleteComments()->getBitmask(); // 1000;
```

### Flagged enum in Eloquent queries
To use flagged enums directly in your Eloquent queries, you may use the `FlaggedEnumQueries` trait on your model which provides you with the following methods:

#### hasFlag($column, $flag): Builder
```php
User::hasFlag('permissions', UserPermissions::DeleteComments())->get();
```
#### doesntHaveFlag($column, $flag): Builder
```php
User::doesntHaveFlag('permissions', UserPermissions::DeleteComments())->get();
```


## Attribute Casting

You may cast model attributes to enums using Laravel 7.x's built in custom casting. This will cast the attribute to an enum instance when getting and back to the enum value when setting.
Expand Down
4 changes: 4 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,8 @@
<directory suffix="Test.php">./tests/</directory>
</testsuite>
</testsuites>
<php>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
</php>
</phpunit>
30 changes: 30 additions & 0 deletions src/Traits/FlaggedEnumQueries.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace BenSampo\Enum\Traits;

use BenSampo\Enum\FlaggedEnum;

trait FlaggedEnumQueries
{
/**
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $column
* @param int $flag
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeHasFlag($query, $column, $flag)
{
return $query->whereRaw("$column & ? > 0", [$flag]);
}

/**
* @param \Illuminate\Database\Eloquent\Builder $query
* @param string $column
* @param int $flag
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeNotHasFlag($query, $column, $flag)
{
return $query->whereRaw("not $column & ? > 0", [$flag]);
}
}
51 changes: 51 additions & 0 deletions tests/FlaggedEnumQueriesTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

namespace BenSampo\Enum\Tests;

use BenSampo\Enum\Tests\Enums\SuperPowers;
use BenSampo\Enum\Tests\Models\ModelWithFlaggedQueries;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Orchestra\Testbench\TestCase;

class FlaggedEnumQueriesTest extends TestCase
{
use RefreshDatabase;

protected function setUp(): void
{
parent::setUp();

$this->setUpDatabase($this->app);
}

protected function setUpDatabase(Application $app)
{
$app['db']->connection()->getSchemaBuilder()->create('test_models', function (Blueprint $table) {
$table->increments('id');
$table->integer('superpowers');
$table->timestamps();
});
}

/** @test */
public function it_can_constrain_query_by_flagged_enum()
{
ModelWithFlaggedQueries::create([
'superpowers' => SuperPowers::flags([SuperPowers::Flight, SuperPowers::Immortality])
]);

ModelWithFlaggedQueries::create([
'superpowers' => SuperPowers::flags([SuperPowers::Strength, SuperPowers::Immortality])
]);

$this->assertEquals(2, ModelWithFlaggedQueries::query()->hasFlag('superpowers', SuperPowers::Immortality)->count());
$this->assertEquals(1, ModelWithFlaggedQueries::query()->hasFlag('superpowers', SuperPowers::Flight)->count());
$this->assertEquals(0, ModelWithFlaggedQueries::query()->hasFlag('superpowers', SuperPowers::Invisibility)->count());

$this->assertEquals(0, ModelWithFlaggedQueries::query()->notHasFlag('superpowers', SuperPowers::Immortality)->count());
$this->assertEquals(1, ModelWithFlaggedQueries::query()->notHasFlag('superpowers', SuperPowers::Flight)->count());
$this->assertEquals(2, ModelWithFlaggedQueries::query()->notHasFlag('superpowers', SuperPowers::Invisibility)->count());
}
}
15 changes: 15 additions & 0 deletions tests/Models/ModelWithFlaggedQueries.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace BenSampo\Enum\Tests\Models;

use BenSampo\Enum\Traits\FlaggedEnumQueries;
use Illuminate\Database\Eloquent\Model;

class ModelWithFlaggedQueries extends Model
{
use FlaggedEnumQueries;

public $table = 'test_models';

protected $guarded = [];
}

0 comments on commit 70164a5

Please sign in to comment.