diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 399ef82..1a13177 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.1.1 + uses: dependabot/fetch-metadata@v2.4.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/php-cs-fixer.yml b/.github/workflows/php-cs-fixer.yml index f55d1fa..fb20cf1 100644 --- a/.github/workflows/php-cs-fixer.yml +++ b/.github/workflows/php-cs-fixer.yml @@ -8,7 +8,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4.2.2 with: ref: ${{ github.head_ref }} @@ -18,6 +18,6 @@ jobs: args: --config=.php_cs.dist.php --allow-risky=yes - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Fix styling diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 19d6402..566d8aa 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -11,7 +11,7 @@ jobs: name: phpstan runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4.2.2 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -20,7 +20,7 @@ jobs: coverage: none - name: Install composer dependencies - uses: ramsey/composer-install@v1 + uses: ramsey/composer-install@v3 - name: Run PHPStan run: ./vendor/bin/phpstan --error-format=github diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 041bf5d..a203f78 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -2,9 +2,11 @@ name: run-tests on: push: - branches: [main] + branches: + - main pull_request: - branches: [main] + branches: + - main jobs: test: @@ -13,18 +15,23 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest, windows-latest] - php: [8.0] - laravel: [8.*] + php: [8.1, 8.2, 8.3] + laravel: [10.*, 11.*] stability: [prefer-lowest, prefer-stable] include: - - laravel: 8.* - testbench: ^6.23 + - laravel: 10.* + testbench: ^8.0.0 + - laravel: 11.* + testbench: ^9.0 + exclude: + - laravel: 11.* + php: 8.1 name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4.2.2 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index fa56639..6d54b94 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4.2.2 with: ref: main @@ -21,7 +21,7 @@ jobs: release-notes: ${{ github.event.release.body }} - name: Commit updated CHANGELOG - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 with: branch: main commit_message: Update CHANGELOG diff --git a/CHANGELOG.md b/CHANGELOG.md index be52967..eed8f75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,64 @@ All notable changes to `laravel-presenter` will be documented in this file. +## v1.2.1 - 2022-10-22 + +### What's Changed + +- Bump dependabot/fetch-metadata from 1.3.3 to 1.3.4 by @dependabot in https://github.com/coderflexx/laravel-presenter/pull/8 +- update README.md by @ousid in https://github.com/coderflexx/laravel-presenter/pull/10 +- Bump actions/checkout from 2 to 3.1.0 by @dependabot in https://github.com/coderflexx/laravel-presenter/pull/9 + +### New Contributors + +- @ousid made their first contribution in https://github.com/coderflexx/laravel-presenter/pull/10 + +**Full Changelog**: https://github.com/coderflexx/laravel-presenter/compare/v1.2.0...v1.2.1 + +## V1.2.0 - 2022-08-14 + +### What's Changed + +- Change Command Name and fix Typo by @syntafin in https://github.com/coderflexx/laravel-presenter/pull/6 + +### New Contributors + +- @syntafin made their first contribution in https://github.com/coderflexx/laravel-presenter/pull/6 + +**Full Changelog**: https://github.com/coderflexx/laravel-presenter/compare/v1.1.1...v1.2.0 + +## v1.1.1 - 2022-02-13 + +## Add + +- Add `interfaceNotImplemented` method + +**Full Changelog**: https://github.com/coderflexx/laravel-presenter/compare/v1.1.0...v1.1.1 + +## v1.1.0 - 2022-02-12 + +## Add + +- Adding Laravel 9 Support + +## v1.0.5 - 2022-02-12 + +## Update + +- update `README.md` + +## v1.0.4 - 2022-02-12 + +# Update + +- Update `README.md` + +## v1.0.3 - 2022-02-12 + +# Update + +- update `composer.json` + ## v1.0.2 - 2022-02-12 ## Fixes diff --git a/README.md b/README.md index 77536f6..019681a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,28 @@ # Laravel Presenter [![The Latest Version on Packagist](https://img.shields.io/packagist/v/coderflexx/laravel-presenter.svg?style=flat-square)](https://packagist.org/packages/coderflexx/laravel-presenter) -[![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/coderflexx/laravel-presenter/run-tests?label=tests)](https://github.com/coderflexx/laravel-presenter/actions?query=workflow%3Arun-tests+branch%3Amain) -[![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/coderflexx/laravel-presenter/Check%20&%20fix%20styling?label=code%20style)](https://github.com/coderflexx/laravel-presenter/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) +[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/coderflexx/laravel-presenter/run-tests.yml?branch=main&label=tests)](https://github.com/coderflexx/laravel-presenter/actions?query=workflow%3Arun-tests+branch%3Amain) +[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/coderflexx/laravel-presenter/phpstan.yml?branch=main&label=code%20style)](https://github.com/coderflexx/laravel-presenter/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) +[![Total Downloads](https://img.shields.io/packagist/dt/coderflexx/laravel-presenter.svg?style=flat-square)](https://packagist.org/packages/coderflexx/laravel-presenter) A clean way to present your model attributes without putting them in the wrong file. + +- [Laravel Presenter](#laravel-presenter) + - [Installation](#installation) + - [Usage](#usage) + - [Model Implementation](#model-implementation) + - [Create New Model Presenter class](#create-new-model-presenter-class) + - [Using the `Presenter` Generated Class](#using-the-presenter-generated-class) + - [Example](#example) + - [Adding Another Presenter Type](#adding-another-presenter-type) + - [Testing](#testing) + - [Changelog](#changelog) + - [Contributing](#contributing) + - [Security Vulnerabilities](#security-vulnerabilities) + - [Credits](#credits) + - [License](#license) + ## Installation You can install the package via composer: @@ -17,7 +34,7 @@ composer require coderflexx/laravel-presenter You can publish the config file with: ```bash -vendor:publish --provider="Coderflex\LaravelPresenter\LaravelPresenterServiceProvider" +php artisan vendor:publish --provider="Coderflex\LaravelPresenter\LaravelPresenterServiceProvider" ``` This is the contents of the published config file: @@ -67,7 +84,7 @@ class User extends Authenticatable implements CanPresent This package gives you an easy way to generate new `Presenter` class, all you need to do is to use `presenter:make` command. ```bash -php artisan presenter:make UserPresneter +php artisan presenter:make UserPresenter ``` `UserPresenter` in our case, leaves by default in `App\Presenters`. @@ -94,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 artisna presenter:make App\Models\Presenter\UserPresenter ``` Or change `presenter_namespace` from `config/laravel-presenter` file. @@ -130,7 +147,7 @@ class User extends Authenticatable implements CanPresent By default, the type of your presenter class is `default`, but you can use as many of presenters you want, just by identifying the type in `$presenters` property. ## Example -Now, after we generated the `presenter` class, and we implemented it successfully in our model, we can use it as so: +Now, after we generated the `presenter` class, and we implemented it successfully in our model, we can use it like so: In your `UserPresenter` class or any presenter class you generated. @@ -155,8 +172,8 @@ $user->present()->fullName ``` Your application will show the full name from the method you added. -## Adding Another Presenter Type: -Like I said above, by default the type will be `deafult` but, you can add more types as you need. +## Adding Another Presenter Type +Like I said above, by default the type will be `default` but, you can add more types as you need. Here is an example: @@ -225,7 +242,7 @@ Please review [our security policy](../../security/policy) on how to report secu ## Credits -- [Coderflex](https://github.com/coderflexxx) +- [Oussama Sid](https://github.com/ousid) - [All Contributors](../../contributors) ## License diff --git a/composer.json b/composer.json index 0251db6..23ef0a4 100644 --- a/composer.json +++ b/composer.json @@ -16,20 +16,21 @@ } ], "require": { - "php": "^8.0", + "php": "^8.0|^8.1", "spatie/laravel-package-tools": "^1.9.2", - "illuminate/contracts": "^8.73" + "illuminate/console": "^8.75|^9.0|^10.0|^11.0|^12.0", + "illuminate/contracts": "^8.0|^9.0|^10.0|^11.0|^12.0" }, "require-dev": { - "nunomaduro/collision": "^5.10", - "nunomaduro/larastan": "^1.0", - "orchestra/testbench": "^6.22", - "pestphp/pest": "^1.21", - "pestphp/pest-plugin-laravel": "^1.1", - "phpstan/extension-installer": "^1.1", + "nunomaduro/collision": "^5.10|^6.1|^7.0|^8.1", + "nunomaduro/larastan": "^1.0|^2.0", + "orchestra/testbench": "^8.0|^9.0", + "pestphp/pest": "^1.22|^2.34", + "pestphp/pest-plugin-laravel": "^1.3|^2.3", + "phpstan/extension-installer": "^1.2", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^9.5|^10.0" }, "autoload": { "psr-4": { @@ -47,7 +48,14 @@ "test-coverage": "vendor/bin/pest --coverage" }, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "pestphp/pest-plugin-laravel": true, + "pestphp/pest-plugin": true, + "phpstan/extension-installer": true, + "phpstan/phpstan-deprecation-rules": true, + "phpstan/phpstan-phpunit": true + } }, "extra": { "laravel": { diff --git a/src/Console/MakePresenterCommand.php b/src/Console/MakePresenterCommand.php new file mode 100644 index 0000000..fe1211c --- /dev/null +++ b/src/Console/MakePresenterCommand.php @@ -0,0 +1,69 @@ +files->exists($this->getPath($this->qualifyClass($rawName))); + } + + /** + * Get the stub file for the generator. + * + * @return string + */ + protected function getStub() + { + return $this->resolveStubPath('/stubs/presenter.stub'); + } + + /** + * Resolve the fully-qualified path to the stub. + * + * @param string $stub + * @return string + */ + protected function resolveStubPath($stub) + { + return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) + ? $customPath + : __DIR__ . $stub; + } + + /** + * Get the default namespace for the class. + * + * @param string $rootNamespace + * @return string + */ + protected function getDefaultNamespace($rootNamespace) + { + $configNamespace = config('laravel-presenter.presenter_namespace'); + + return is_null($configNamespace) + ? $rootNamespace . '\Presenters' + : $configNamespace; + } +} diff --git a/src/Console/PresenterMakeCommand.php b/src/Console/PresenterMakeCommand.php index df0ad88..fa9f2c8 100644 --- a/src/Console/PresenterMakeCommand.php +++ b/src/Console/PresenterMakeCommand.php @@ -2,68 +2,12 @@ namespace Coderflex\LaravelPresenter\Console; -use Illuminate\Console\GeneratorCommand; - -class PresenterMakeCommand extends GeneratorCommand +class PresenterMakeCommand extends MakePresenterCommand { public $name = 'presenter:make'; - public $description = 'create a new presenter class'; - - /** - * The type of class being generated. - * - * @var string - */ - protected $type = 'Presenter'; - - /** - * Determine if the class already exists. - * - * @param string $rawName - * @return bool - */ - protected function alreadyExists($rawName) + protected function configure() { - return class_exists($rawName) || - $this->files->exists($this->getPath($this->qualifyClass($rawName))); - } - - /** - * Get the stub file for the generator. - * - * @return string - */ - protected function getStub() - { - return $this->resolveStubPath('/stubs/presenter.stub'); - } - - /** - * Resolve the fully-qualified path to the stub. - * - * @param string $stub - * @return string - */ - protected function resolveStubPath($stub) - { - return file_exists($customPath = $this->laravel->basePath(trim($stub, '/'))) - ? $customPath - : __DIR__ . $stub; - } - - /** - * Get the default namespace for the class. - * - * @param string $rootNamespace - * @return string - */ - protected function getDefaultNamespace($rootNamespace) - { - $configNamespace = config('laravel-presenter.presenter_namespace'); - - return is_null($configNamespace) - ? $rootNamespace . '\Presenters' - : $configNamespace; + $this->setHidden(true); } } diff --git a/src/Exceptions/PresenterException.php b/src/Exceptions/PresenterException.php index bf0bbb4..db7dc3a 100644 --- a/src/Exceptions/PresenterException.php +++ b/src/Exceptions/PresenterException.php @@ -3,6 +3,7 @@ namespace Coderflex\LaravelPresenter\Exceptions; use Exception; +use Illuminate\Database\Eloquent\Model; class PresenterException extends Exception { @@ -19,4 +20,19 @@ class PresenterException extends Exception * @var int */ protected $code = 500; + + /** + * Method for Presenter Implementation absence on the model + * @param Model $model + * @return self + */ + public static function interfaceNotImplemented(Model $model): self + { + return new self(( + __(':model should implements :interface interface', [ + 'model' => get_class($model), + 'interface' => '\Coderflex\LaravelPresenter\Concerns\CanPresent', + ]) + )); + } } diff --git a/src/LaravelPresenterServiceProvider.php b/src/LaravelPresenterServiceProvider.php index e9582a4..d690f14 100644 --- a/src/LaravelPresenterServiceProvider.php +++ b/src/LaravelPresenterServiceProvider.php @@ -2,7 +2,10 @@ namespace Coderflex\LaravelPresenter; -use Coderflex\LaravelPresenter\Console\PresenterMakeCommand; +use Coderflex\LaravelPresenter\Console\{ + MakePresenterCommand, + PresenterMakeCommand +}; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -18,6 +21,7 @@ public function configurePackage(Package $package): void $package ->name('laravel-presenter') ->hasConfigFile('laravel-presenter') + ->hasCommand(MakePresenterCommand::class) ->hasCommand(PresenterMakeCommand::class); } } diff --git a/src/Presenter.php b/src/Presenter.php index 93b9491..b1926a5 100755 --- a/src/Presenter.php +++ b/src/Presenter.php @@ -17,12 +17,7 @@ abstract class Presenter public function __construct(Model $model) { if (! $model instanceof \Coderflex\LaravelPresenter\Concerns\CanPresent) { - throw new PresenterException( - __(':model should implements :interface interface', [ - 'model' => get_class($model), - 'interface' => '\Coderflex\LaravelPresenter\Concerns\CanPresent', - ]) - ); + throw PresenterException::interfaceNotImplemented($model); } $this->model = $model; diff --git a/tests/PresentersTest.php b/tests/PresentersTest.php index ef60cec..06d511b 100644 --- a/tests/PresentersTest.php +++ b/tests/PresentersTest.php @@ -4,6 +4,10 @@ use Coderflex\LaravelPresenter\Tests\Models\User; it('cannot create new presenter without a name argument', function () { + $this->markTestSkipped( + __('In laravel V9.*, and above versions, it can put a question for the name argument, if it\'s not presented.') + ); + $this->artisan('presenter:make ') ->assertExitCode(1); })->throws( @@ -16,6 +20,12 @@ ->assertExitCode(0); })->group('Presenter Command'); + +it('can create new presenter class with the alias command', function () { + $this->artisan('make:presenter UserPresenter') + ->assertExitCode(0); +})->group('Presenter Command'); + it('presents user full name', function () { $user = new User([ 'first_name' => 'John',