Skip to content

Commit

Permalink
Add the ability to auto-determine the presenter
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy committed Aug 16, 2023
1 parent cecab42 commit e1aefe0
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 8 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ If you want to change the directory, you have two options.
First options is to set the full namespace while you're creating the presenter class

```bash
php artisna presneter:make App\Models\Presenter\UserPresenter
php artisan presneter:make App\Models\Presenter\UserPresenter
```

Or change `presenter_namespace` from `config/laravel-presenter` file.
Expand Down
58 changes: 51 additions & 7 deletions src/Concerns/UsesPresenters.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,62 @@
*/
trait UsesPresenters
{
/*
|--------------------------------------------------------------------------
| Presenters
|--------------------------------------------------------------------------
|
| Presenters can be defined as a single item in $this->presenter or
| as an array of $this->presenters. If neither are set, then we will
| generate a default based on the Model and type (if set).
|
*/

/**
* Check the given presenters value exists or not
*
* @param string $type
* @return mixed
* @throws PresenterException
*/
public function present(string $type = 'default')
public function present(string $type = 'default'): mixed
{
if (array_key_exists($type, $this->presenters)) {
return new $this->presenters[$type]($this);
$presenter = $this->getDefaultPresenterName($type);

if (! is_null($this->presenters) && is_array($this->presenters)) {
if (array_key_exists($type, $this->presenters)) {
$presenter = $this->presenters[$type];
} else {
throw new PresenterException();
}

} elseif (isset($this->presenter) && is_string($this->presenter)) {
$presenter = $this->presenter;
}

if (class_exists($presenter)) {
return new $presenter($this);
}

throw new PresenterException();
}

/*
|--------------------------------------------------------------------------
| Default Presenter Names
|--------------------------------------------------------------------------
|
| By default, the presenter name is defined based on the name of the
| Model class. The default namespace is \App\Presenters. So, the Model
| Day has Presenter DayPresenter. However, if you supply a type, e.g. then it
| would be DayTypePresenter.
|
*/

private function getDefaultPresenterName($type)
{
$modelNameModifier = $type === 'default' ? '' : $type;

return str(get_class())
->replace('Models', 'Presenters')
->append(str($modelNameModifier)->ucfirst())
->append('Presenter')
->toString();
}
}
14 changes: 14 additions & 0 deletions tests/Models/Item.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

namespace Coderflex\LaravelPresenter\Tests\Models;

use Coderflex\LaravelPresenter\Concerns\CanPresent;
use Coderflex\LaravelPresenter\Concerns\UsesPresenters;
use Illuminate\Database\Eloquent\Model;

class Item extends Model implements CanPresent
{
use UsesPresenters;

protected $guarded = [];
}
15 changes: 15 additions & 0 deletions tests/Presenters/ItemPresenter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Coderflex\LaravelPresenter\Tests\Presenters;

;

use Coderflex\LaravelPresenter\Presenter;

class ItemPresenter extends Presenter
{
public function slug()
{
return str($this->model->title)->slug()->toString();
}
}
15 changes: 15 additions & 0 deletions tests/Presenters/ItemSubdomainPresenter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Coderflex\LaravelPresenter\Tests\Presenters;

;

use Coderflex\LaravelPresenter\Presenter;

class ItemSubdomainPresenter extends Presenter
{
public function caps()
{
return str($this->model->title)->upper()->toString();
}
}
19 changes: 19 additions & 0 deletions tests/PresentersTest.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use Coderflex\LaravelPresenter\Tests\Models\Item;
use Coderflex\LaravelPresenter\Tests\Models\Post;
use Coderflex\LaravelPresenter\Tests\Models\User;

Expand Down Expand Up @@ -74,3 +75,21 @@
Coderflex\LaravelPresenter\Exceptions\PresenterException::class,
'Coderflex\LaravelPresenter\Tests\Models\Post should implements \Coderflex\LaravelPresenter\Concerns\CanPresent interface'
)->group('Presenter Implementation');

it('can automatically load the presenter', function () {
$item = new Item([
'title' => 'An item title',
]);

expect($item->present()->slug)
->toEqual('an-item-title');
});

it('can automatically load a non-default presenter', function () {
$item = new Item([
'title' => 'An item title',
]);

expect($item->present('subdomain')->caps)
->toEqual('AN ITEM TITLE');
});
32 changes: 32 additions & 0 deletions tests/database/migrations/create_items_table.php.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};

0 comments on commit e1aefe0

Please sign in to comment.