diff --git a/README.md b/README.md index 5c24807..eb8791b 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/src/Concerns/UsesPresenters.php b/src/Concerns/UsesPresenters.php index 4b1c3a5..066d214 100644 --- a/src/Concerns/UsesPresenters.php +++ b/src/Concerns/UsesPresenters.php @@ -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(); + } } diff --git a/tests/Models/Item.php b/tests/Models/Item.php new file mode 100644 index 0000000..064978b --- /dev/null +++ b/tests/Models/Item.php @@ -0,0 +1,14 @@ +model->title)->slug()->toString(); + } +} diff --git a/tests/Presenters/ItemSubdomainPresenter.php b/tests/Presenters/ItemSubdomainPresenter.php new file mode 100644 index 0000000..f467b04 --- /dev/null +++ b/tests/Presenters/ItemSubdomainPresenter.php @@ -0,0 +1,15 @@ +model->title)->upper()->toString(); + } +} diff --git a/tests/PresentersTest.php b/tests/PresentersTest.php index 06d511b..379745a 100644 --- a/tests/PresentersTest.php +++ b/tests/PresentersTest.php @@ -1,5 +1,6 @@ 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'); +}); diff --git a/tests/database/migrations/create_items_table.php.stub b/tests/database/migrations/create_items_table.php.stub new file mode 100644 index 0000000..12adbd4 --- /dev/null +++ b/tests/database/migrations/create_items_table.php.stub @@ -0,0 +1,32 @@ +id(); + $table->string('title'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('users'); + } +};