Skip to content

Commit

Permalink
feat: add trait AllowToExecute
Browse files Browse the repository at this point in the history
  • Loading branch information
efureev committed Nov 13, 2021
1 parent ec7b694 commit 0fda4d0
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Check MD [online][check-online].

## [unreleased]

## [1.10.0] - 2021-11-14

### Added

- Add trait `AllowToExecute`

## [1.9.0] - 2021-10-16

### Added
Expand Down
55 changes: 55 additions & 0 deletions src/Traits/Models/AllowToExecute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

namespace Php\Support\Laravel\Traits\Models;

use Illuminate\Database\Eloquent\Model;
use Php\Support\Exceptions\MethodNotAllowedException;

/**
* @mixin Model
*/
trait AllowToExecute
{
protected static array $disallowMethodsMap = [];
protected array $allowList = [];

public function addMethodToAllowList(string $method): void
{
$this->allowList[$method] = true;
}

private function rejectMethodFromAllowList(string $method): void
{
unset($this->allowList[$method]);
}

protected function isAllowToExecute(string $method): bool
{
return !array_key_exists($method, static::$disallowMethodsMap) || isset($this->allowList[$method]);
}

protected function checkPossibilityAndExecute(string $method, ...$arguments): mixed
{
if ($this->isAllowToExecute($method)) {
return parent::$method(...$arguments);
}
$hint = static::$disallowMethodsMap[$method];

if ($hint instanceof \Closure) {
return $hint($this);
}

if (is_string($hint)) {
$text = "You should call this method like this: $hint";
}

throw new MethodNotAllowedException($text ?? 'You don\'t allow to execute this method!');
}

protected static function addMethodToDisallowMap(string $method, string|\Closure $hint = null): void
{
static::$disallowMethodsMap[$method] = $hint;
}
}
91 changes: 91 additions & 0 deletions tests/Traits/Models/AllowToExecuteTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php

declare(strict_types=1);

namespace Php\Support\Laravel\Tests\Traits\Models;

use Illuminate\Database\Eloquent\Model;
use Php\Support\Exceptions\MethodNotAllowedException;
use Php\Support\Laravel\Tests\AbstractTestCase;
use Php\Support\Laravel\Traits\Models\AllowToExecute;

class AllowToExecuteTest extends AbstractTestCase
{

/** @test */
public function callBase()
{
$class = $this->buildClass();

$this->expectException(MethodNotAllowedException::class);
$this->expectExceptionMessage(
'Method Not Allowed: You should call this method like this: Remover::exec($model)'
);

$class->delete();
}

/** @test */
public function callWithDisablePossibility()
{
$class = $this->buildClass();

$this->expectException(MethodNotAllowedException::class);
$this->expectExceptionMessage('Method Not Allowed: You should call this method like this: new Query($model)');

$class->newQuery();
}

/** @test */
public function callWithPossibility()
{
$class = $this->buildClass();
$class->addMethodToAllowList('newQuery');

$class->newQuery();

static::assertNotNull($class);
}

/** @test */
public function callFn()
{
$class = $this->buildClass();

$this->expectException(MethodNotAllowedException::class);
$this->expectExceptionMessage("QQ");
$class->handle(1, 2);
}

private function buildClass(): Model
{
return new class extends Model {
use AllowToExecute;

protected static function booting(): void
{
static::addMethodToDisallowMap('delete', 'Remover::exec($model)');
static::addMethodToDisallowMap('newQuery', 'new Query($model)');
static::addMethodToDisallowMap(
'handle',
static fn() => throw new MethodNotAllowedException("QQ")
);
}

public function delete()
{
return $this->checkPossibilityAndExecute(__FUNCTION__);
}

public function handle($value, $value2)
{
return $this->checkPossibilityAndExecute(__FUNCTION__, $value, $value2);
}

public function newQuery()
{
return $this->checkPossibilityAndExecute(__FUNCTION__);
}
};
}
}

0 comments on commit 0fda4d0

Please sign in to comment.