diff --git a/.gitattributes b/.gitattributes
index 1185e15..47ea9b3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,7 +5,7 @@
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
-.php_cs export-ignore
.scrutinizer.yml export-ignore
-.travis.yml export-ignore
-phpunit.xml export-ignore
+.styleci.yml export-ignore
+phpstan.neon.dist export-ignore
+phpunit.xml.dist export-ignore
diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
new file mode 100644
index 0000000..a521b25
--- /dev/null
+++ b/.github/workflows/continuous-integration.yml
@@ -0,0 +1,48 @@
+name: "Continuous Integration"
+
+on:
+ push:
+ branches:
+ - master
+ - 11.x
+ pull_request:
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ phpunit:
+
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: true
+ matrix:
+ php: [8.2, 8.3, 8.4]
+ stability: [prefer-stable]
+
+ name: PHP ${{ matrix.php }} - ${{ matrix.stability }}
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, gd, memcached
+ tools: composer:v2
+ coverage: none
+
+ - name: Setup Memcached
+ uses: niden/actions-memcached@v7
+
+ - name: Install dependencies
+ uses: nick-invision/retry@v1
+ with:
+ timeout_minutes: 5
+ max_attempts: 5
+ command: COMPOSER_ROOT_VERSION=dev-master composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
+
+ - name: Execute tests
+ run: vendor/bin/phpunit
diff --git a/.github/workflows/lock-closed-issues.yml b/.github/workflows/lock-closed-issues.yml
new file mode 100644
index 0000000..6b89427
--- /dev/null
+++ b/.github/workflows/lock-closed-issues.yml
@@ -0,0 +1,21 @@
+name: Lock Closed Issues
+
+on:
+ schedule:
+ - cron: "0 0 * * *"
+
+permissions:
+ issues: write
+
+jobs:
+ action:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: dessant/lock-threads@v3
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ issue-inactive-days: "14"
+ #issue-comment: |
+ # This issue has been locked since it has been closed for more than 14 days.
+ issue-lock-reason: ""
+ process-only: "issues"
diff --git a/.github/workflows/pint.yml b/.github/workflows/pint.yml
new file mode 100644
index 0000000..bac3eab
--- /dev/null
+++ b/.github/workflows/pint.yml
@@ -0,0 +1,28 @@
+name: PHP Linting
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+jobs:
+ phplint:
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: write
+ pull-requests: write
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ github.head_ref }}
+
+ - name: "laravel-pint"
+ uses: aglipanci/laravel-pint-action@latest
+ with:
+ preset: laravel
+ verboseMode: true
+
+ - uses: stefanzweifel/git-auto-commit-action@v5
+ with:
+ commit_message: "fix: pint"
diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml
new file mode 100644
index 0000000..bdf913b
--- /dev/null
+++ b/.github/workflows/static-analysis.yml
@@ -0,0 +1,54 @@
+name: "Static Analysis"
+
+on:
+ push:
+ paths:
+ - .github/workflows/static-analysis.yml
+ - composer.*
+ - phpstan.neon.dist
+ - src/**
+ - tests/**
+
+ pull_request:
+ paths:
+ - .github/workflows/static-analysis.yml
+ - composer.*
+ - phpstan.neon.dist
+ - src/**
+ - tests/**
+
+ schedule:
+ - cron: '0 0 * * *'
+
+jobs:
+ static-analysis-phpstan:
+
+ name: "Static Analysis with PHPStan"
+ runs-on: ubuntu-latest
+
+ strategy:
+ fail-fast: true
+ matrix:
+ php: [8.2, 8.3, 8.4]
+ stability: [prefer-stable]
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ tools: composer:v2
+ coverage: none
+
+ - name: Install dependencies
+ uses: nick-invision/retry@v1
+ with:
+ timeout_minutes: 5
+ max_attempts: 5
+ command: COMPOSER_ROOT_VERSION=dev-master composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress
+
+ - name: "Run a static analysis with phpstan/phpstan"
+ run: "vendor/bin/phpstan --error-format=table"
diff --git a/.gitignore b/.gitignore
index df0e1ea..384d40a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
/vendor
/coverage
+/.phpunit.cache
composer.phar
composer.lock
diff --git a/.php_cs b/.php_cs
deleted file mode 100644
index e8c5a2a..0000000
--- a/.php_cs
+++ /dev/null
@@ -1,77 +0,0 @@
-finder(DefaultFinder::create()->in(__DIR__))
- ->fixers($fixers)
- ->level(FixerInterface::NONE_LEVEL)
- ->setUsingCache(true);
diff --git a/.styleci.yml b/.styleci.yml
deleted file mode 100644
index 35eca69..0000000
--- a/.styleci.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-preset: laravel
-
-enabled:
- - align_double_arrow
- - align_equals
-
-disabled:
- - concat_without_spaces
- - unalign_equals
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c0ece51..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-language: php
-
-php:
- - 7.0
- - 7.1
-
-env:
- global:
- - setup=basic
-
-sudo: false
-
-install:
- - if [[ $setup = 'basic' ]]; then travis_retry composer install --no-interaction --prefer-source; fi
- - if [[ $setup = 'stable' ]]; then travis_retry composer update --prefer-source --no-interaction --prefer-stable; fi
- - if [[ $setup = 'lowest' ]]; then travis_retry composer update --prefer-source --no-interaction --prefer-lowest --prefer-stable; fi
-
-script: vendor/bin/phpunit
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3c15cfe..5611df5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,44 +2,8 @@
## Changelog
-### v1.6.0 - 2020-06-07
+### v12.0.0 - 2025-02-26
--- Bump league/fractal to ^0.19.0. [#25](https://github.com/yajra/laravel-datatables-fractal/pull/25), credits to @sheriffmarley.
-
-### v1.5.0 - 2019-06-12
-
-- Bump league/fractal to ^0.18.0. [#21](https://github.com/yajra/laravel-datatables-fractal/pull/21), credits to @abdullah-abunada.
-
-### v1.4.0 - 2019-03-05
-
-- Add support for Laravel 5.8 [#20](https://github.com/yajra/laravel-datatables-fractal/pull/20).
-
-### v1.3.0 - 2018-11-15
-
-- Allow using closures as transformer. [#17](https://github.com/yajra/laravel-datatables-fractal/pull/17) credits to [@c00p3r](https://github.com/c00p3r)
-- Fix [#1863](https://github.com/yajra/laravel-datatables/issues/1863).
-
-### v1.2.1 - 2018-06-12
-
-- TransformerMakeCommand namespace typo [#14](https://github.com/yajra/laravel-datatables-fractal/pull/14)
-
-### v1.2.0 - 2018-03-28
-
-- Add make:transformer command [#13](https://github.com/yajra/laravel-datatables-fractal/pull/13)
-
-### v1.1.1 - 2017-12-26
-
-- Use collection if data key is not set. [#11](https://github.com/yajra/laravel-datatables-fractal/pull/11)
-
-### v1.1.0 - 2017-12-12
-
-- Fix typo issue [#7](https://github.com/yajra/laravel-datatables-fractal/issues/7). [#8](https://github.com/yajra/laravel-datatables-fractal/pull/8)
-- Add multi transformer ability [#6](https://github.com/yajra/laravel-datatables-fractal/pull/6)
-
-### v1.0.1 - 2017-08-31
-
-- Update fractal to 0.17.0.
-
-### v1.0.0 - 2017-08-31
-
-- First stable release.
+- Add support for Laravel 12
+- Add Laravel Pint
+- Add Rector
diff --git a/README.md b/README.md
index ce7c5f3..73f6dc1 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,8 @@
# Laravel DataTables Fractal Plugin
-[](http://laravel.com)
+[](http://laravel.com)
[](https://packagist.org/packages/yajra/laravel-datatables-fractal)
-[](https://travis-ci.org/yajra/laravel-datatables-fractal)
+[](https://github.com/yajra/laravel-datatables-fractal/actions/workflows/continuous-integration.yml)
[](https://scrutinizer-ci.com/g/yajra/laravel-datatables-fractal/?branch=master)
[](https://packagist.org/packages/yajra/laravel-datatables-fractal)
[](https://packagist.org/packages/yajra/laravel-datatables-fractal)
@@ -11,17 +11,27 @@ This package is a plugin of [Laravel DataTables](https://github.com/yajra/larave
## Requirements
-- [PHP >=7.0](http://php.net/)
-- [Laravel 5.4+](https://github.com/laravel/framework)
-- [Laravel DataTables v8.x](https://github.com/yajra/laravel-datatables)
+- [PHP >= 8.2](http://php.net/)
+- [Laravel 12.x](https://github.com/laravel/framework)
+- [Laravel DataTables](https://github.com/yajra/laravel-datatables)
## Documentations
- [Laravel DataTables Fractal Documentation](https://yajrabox.com/docs/laravel-datatables/master/response-fractal)
+## Laravel Version Compatibility
+
+| Laravel | Package |
+|:--------------|:--------|
+| 8.x and below | 1.x |
+| 9.x | 9.x |
+| 10.x | 10.x |
+| 11.x | 11.x |
+| 12.x | 12.x |
+
## Quick Installation
-`composer require yajra/laravel-datatables-fractal`
+`composer require yajra/laravel-datatables-fractal:^12.0`
### Register Service Provider (Optional on Laravel 5.5+)
@@ -49,8 +59,3 @@ If you discover any security related issues, please email [aqangeles@gmail.com](
## License
The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables-fractal/blob/master/LICENSE.md) for more information.
-
-## Buy me a coffee
-
-[](https://www.paypal.me/yajra)
-
diff --git a/composer.json b/composer.json
index 28c3f14..4b516df 100644
--- a/composer.json
+++ b/composer.json
@@ -1,48 +1,62 @@
{
- "name": "yajra/laravel-datatables-fractal",
- "description": "Laravel DataTables Fractal Plugin.",
- "keywords": [
- "laravel",
- "datatables",
- "fractal",
- "api"
- ],
- "license": "MIT",
- "authors": [
- {
- "name": "Arjay Angeles",
- "email": "aqangeles@gmail.com"
- }
- ],
- "require": {
- "php": ">=7.0",
- "yajra/laravel-datatables-oracle": "8.*|9.*",
- "league/fractal": "^0.19.0"
- },
- "require-dev": {
- "mockery/mockery": "0.9.*",
- "phpunit/phpunit": "~6.0"
- },
- "autoload": {
- "psr-4": {
- "Yajra\\DataTables\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "Yajra\\DataTables\\Tests\\": "tests/"
- }
- },
- "extra": {
- "branch-alias": {
- "dev-master": "1.0-dev"
+ "name": "yajra/laravel-datatables-fractal",
+ "description": "Laravel DataTables Fractal Plugin.",
+ "keywords": [
+ "laravel",
+ "datatables",
+ "fractal",
+ "api"
+ ],
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Arjay Angeles",
+ "email": "aqangeles@gmail.com"
+ }
+ ],
+ "require": {
+ "php": "^8.2",
+ "yajra/laravel-datatables-oracle": "^12",
+ "league/fractal": "^0.20.1"
},
- "laravel": {
- "providers": [
- "Yajra\\DataTables\\FractalServiceProvider"
- ]
- }
- },
- "minimum-stability": "dev",
- "prefer-stable": true
+ "require-dev": {
+ "larastan/larastan": "^3.1",
+ "orchestra/testbench": "^10",
+ "laravel/pint": "^1.21",
+ "rector/rector": "^2.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "Yajra\\DataTables\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Yajra\\DataTables\\Fractal\\Tests\\": "tests/"
+ }
+ },
+ "extra": {
+ "branch-alias": {
+ "dev-master": "12.x-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Yajra\\DataTables\\FractalServiceProvider"
+ ]
+ }
+ },
+ "scripts": {
+ "test": "./vendor/bin/phpunit",
+ "pint": "./vendor/bin/pint",
+ "rector": "./vendor/bin/rector",
+ "stan": "./vendor/bin/phpstan analyse --memory-limit=2G --ansi --no-progress --no-interaction --configuration=phpstan.neon.dist",
+ "pr": [
+ "@pint",
+ "@rector",
+ "@stan",
+ "@test"
+ ]
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true
}
diff --git a/config/datatables-fractal.php b/config/datatables-fractal.php
index 25f547a..39250f1 100644
--- a/config/datatables-fractal.php
+++ b/config/datatables-fractal.php
@@ -4,7 +4,7 @@
/*
* Request key name to parse includes on fractal.
*/
- 'includes' => 'include',
+ 'includes' => 'include',
/*
* Default fractal serializer.
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..ccac0c6
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,15 @@
+includes:
+ - ./vendor/larastan/larastan/extension.neon
+
+parameters:
+
+ paths:
+ - src
+
+ level: 5
+
+ ignoreErrors:
+ - identifier: function.alreadyNarrowedType
+
+ excludePaths:
+
diff --git a/phpunit.xml b/phpunit.xml
deleted file mode 100644
index 3366726..0000000
--- a/phpunit.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
- ./tests/
-
-
-
-
- ./vendor
-
-
-
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..2cb7512
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,8 @@
+
+
+
+
+ ./tests/
+
+
+
diff --git a/rector.php b/rector.php
new file mode 100644
index 0000000..74003ed
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,22 @@
+paths([
+ __DIR__.'/config',
+ __DIR__.'/src',
+ ]);
+
+ // register a single rule
+ $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);
+
+ // define sets of rules
+ $rectorConfig->sets([
+ LevelSetList::UP_TO_PHP_82,
+ ]);
+};
diff --git a/src/Commands/TransformerMakeCommand.php b/src/Commands/TransformerMakeCommand.php
index 4e4fe39..a86a5ce 100644
--- a/src/Commands/TransformerMakeCommand.php
+++ b/src/Commands/TransformerMakeCommand.php
@@ -33,14 +33,12 @@ class TransformerMakeCommand extends GeneratorCommand
/**
* Replace the class name for the given stub.
*
- * @param string $stub Contents of the stub
- * @param string $name The class name
- *
- * @return string
+ * @param string $stub Contents of the stub
+ * @param string $name The class name
*/
- protected function replaceClass($stub, $name)
+ protected function replaceClass($stub, $name): string
{
- $stub = parent::replaceClass($stub, $name . 'Transformer');
+ $stub = parent::replaceClass($stub, $name.'Transformer');
$stub = str_replace('Dummy', ucfirst($this->argument('name')), $stub);
$stub = str_replace('dummy', lcfirst($this->argument('name')), $stub);
@@ -54,24 +52,20 @@ protected function replaceClass($stub, $name)
/**
* Get the stub file for the generator.
- *
- * @return string
*/
- protected function getStub()
+ protected function getStub(): string
{
return $this->argument('include') ?
- __DIR__ . '/stubs/transformer.inc.stub' :
- __DIR__ . '/stubs/transformer.stub';
+ __DIR__.'/stubs/transformer.inc.stub' :
+ __DIR__.'/stubs/transformer.stub';
}
/**
* Get the default namespace for the class.
*
- * @param string $rootNamespace The root namespace
- *
- * @return string
+ * @param string $rootNamespace The root namespace
*/
- protected function getDefaultNamespace($rootNamespace)
+ protected function getDefaultNamespace($rootNamespace): string
{
return $rootNamespace.'\Transformers';
}
@@ -79,11 +73,9 @@ protected function getDefaultNamespace($rootNamespace)
/**
* Get the destination class path.
*
- * @param string $name Name of the class with namespace
- *
- * @return string
+ * @param string $name Name of the class with namespace
*/
- protected function getPath($name)
+ protected function getPath($name): string
{
$name = Str::replaceFirst($this->rootNamespace(), '', $name);
diff --git a/src/Commands/stubs/transformer.inc.stub b/src/Commands/stubs/transformer.inc.stub
index 8690ec5..0b2874e 100644
--- a/src/Commands/stubs/transformer.inc.stub
+++ b/src/Commands/stubs/transformer.inc.stub
@@ -14,7 +14,7 @@ class DummyClass extends TransformerAbstract
* @param \App\Dummy $dummy
* @return array
*/
- public function transform(Dummy $dummy)
+ public function transform(Dummy $dummy): array
{
return [
'id' => (int) $dummy->id,
diff --git a/src/Commands/stubs/transformer.stub b/src/Commands/stubs/transformer.stub
index 82cd7b1..5ffe2ec 100644
--- a/src/Commands/stubs/transformer.stub
+++ b/src/Commands/stubs/transformer.stub
@@ -11,7 +11,7 @@ class DummyClass extends TransformerAbstract
* @param \App\Dummy $dummy
* @return array
*/
- public function transform(Dummy $dummy)
+ public function transform(Dummy $dummy): array
{
return [
'id' => (int) $dummy->id,
diff --git a/src/FractalServiceProvider.php b/src/FractalServiceProvider.php
index e966455..41c0492 100644
--- a/src/FractalServiceProvider.php
+++ b/src/FractalServiceProvider.php
@@ -10,21 +10,12 @@
class FractalServiceProvider extends ServiceProvider
{
- /**
- * Indicates if loading of the provider is deferred.
- *
- * @var bool
- */
- protected $defer = false;
-
/**
* Bootstrap the application events.
- *
- * @return void
*/
- public function boot()
+ public function boot(): void
{
- $this->mergeConfigFrom(__DIR__ . '/../config/datatables-fractal.php', 'datatables-fractal');
+ $this->mergeConfigFrom(__DIR__.'/../config/datatables-fractal.php', 'datatables-fractal');
$this->publishAssets();
$this->registerMacro();
@@ -32,94 +23,72 @@ public function boot()
/**
* Publish datatables assets.
- *
- * @return void
*/
- protected function publishAssets()
+ protected function publishAssets(): void
{
$this->publishes(
[
- __DIR__ . '/../config/datatables-fractal.php' => config_path('datatables-fractal.php'),
+ __DIR__.'/../config/datatables-fractal.php' => config_path('datatables-fractal.php'),
], 'datatables-fractal'
);
}
/**
* Register DataTables macro methods.
- *
- * @return void
*/
- protected function registerMacro()
+ protected function registerMacro(): void
{
- DataTableAbstract::macro(
- 'setTransformer', function ($transformer) {
- $this->transformer = [$transformer];
+ DataTableAbstract::macro('setTransformer', function ($transformer) {
+ $this->transformer = [$transformer];
- return $this;
- }
- );
+ return $this;
+ });
- DataTableAbstract::macro(
- 'addTransformer', function ($transformer) {
- $this->transformer[] = $transformer;
+ DataTableAbstract::macro('addTransformer', function ($transformer) {
+ $this->transformer[] = $transformer;
- return $this;
- }
- );
+ return $this;
+ });
- DataTableAbstract::macro(
- 'setSerializer', function ($serializer) {
- $this->serializer = $serializer;
+ DataTableAbstract::macro('setSerializer', function ($serializer) {
+ $this->serializer = $serializer;
- return $this;
- }
- );
+ return $this;
+ });
}
/**
* Register the service provider.
- *
- * @return void
*/
- public function register()
+ public function register(): void
{
- $this->app->singleton(
- 'datatables.fractal', function () {
- $fractal = new Manager;
- $config = $this->app['config'];
- $request = $this->app['request'];
-
- $includesKey = $config->get('datatables-fractal.includes', 'include');
- if ($request->get($includesKey)) {
- $fractal->parseIncludes($request->get($includesKey));
- }
+ $this->app->singleton('datatables.fractal', function () {
+ $fractal = new Manager;
+ $config = $this->app['config'];
+ $request = $this->app['request'];
+
+ $includesKey = $config->get('datatables-fractal.includes', 'include');
+ if ($request->get($includesKey)) {
+ $fractal->parseIncludes($request->get($includesKey));
+ }
- $serializer = $config->get('datatables-fractal.serializer', DataArraySerializer::class);
- $fractal->setSerializer(new $serializer);
+ $serializer = $config->get('datatables-fractal.serializer', DataArraySerializer::class);
+ $fractal->setSerializer(new $serializer);
- return $fractal;
- }
- );
+ return $fractal;
+ });
- $this->app->singleton(
- 'datatables.transformer', function () {
- return new FractalTransformer($this->app->make('datatables.fractal'));
- }
- );
+ $this->app->singleton('datatables.transformer', fn () => new FractalTransformer($this->app->make('datatables.fractal')));
- $this->commands(
- [
- TransformerMakeCommand::class,
- ]
- );
+ $this->commands([
+ TransformerMakeCommand::class,
+ ]);
}
/**
* Get the services provided by the provider.
- *
- * @return array
*/
- public function provides()
+ public function provides(): array
{
return [
'datatables.fractal',
diff --git a/src/Transformers/FractalTransformer.php b/src/Transformers/FractalTransformer.php
index 3a2f7e0..3748367 100644
--- a/src/Transformers/FractalTransformer.php
+++ b/src/Transformers/FractalTransformer.php
@@ -2,6 +2,8 @@
namespace Yajra\DataTables\Transformers;
+use Closure;
+use Illuminate\Support\Collection as LaravelCollection;
use League\Fractal\Manager;
use League\Fractal\Resource\Collection;
use League\Fractal\Serializer\SerializerAbstract;
@@ -9,31 +11,19 @@
class FractalTransformer
{
- /**
- * @var \League\Fractal\Manager
- */
- protected $fractal;
-
/**
* FractalTransformer constructor.
- *
- * @param \League\Fractal\Manager $fractal
*/
- public function __construct(Manager $fractal)
- {
- $this->fractal = $fractal;
- }
+ public function __construct(protected Manager $fractal) {}
/**
* Transform output using the given transformer and serializer.
- *
- * @param mixed $output
- * @param mixed $transformer
- * @param mixed $serializer
- * @return array
*/
- public function transform($output, $transformer, $serializer = null)
- {
+ public function transform(
+ array|LaravelCollection $output,
+ iterable $transformer,
+ ?SerializerAbstract $serializer = null
+ ): array {
if ($serializer !== null) {
$this->fractal->setSerializer($this->createSerializer($serializer));
}
@@ -41,12 +31,12 @@ public function transform($output, $transformer, $serializer = null)
$collector = [];
foreach ($transformer as $transform) {
if ($transform != null) {
- $resource = new Collection($output, $this->createTransformer($transform));
- $collection = $this->fractal->createData($resource)->toArray();
- $transformed = $collection['data'] ?? $collection;
- $collector = array_map(
+ $resource = new Collection($output, $this->createTransformer($transform));
+ $collection = $this->fractal->createData($resource)->toArray();
+ $transformed = $collection['data'] ?? $collection;
+ $collector = array_map(
function ($item_collector, $item_transformed) {
- if ($item_collector === null) {
+ if (! is_array($item_collector)) {
$item_collector = [];
}
@@ -62,30 +52,28 @@ function ($item_collector, $item_transformed) {
/**
* Get or create transformer serializer instance.
*
- * @param mixed $serializer
- * @return \League\Fractal\Serializer\SerializerAbstract
+ * @param class-string|SerializerAbstract $serializer
*/
- protected function createSerializer($serializer)
+ protected function createSerializer(SerializerAbstract|string $serializer): SerializerAbstract
{
if ($serializer instanceof SerializerAbstract) {
return $serializer;
}
- return new $serializer();
+ return new $serializer;
}
/**
* Get or create transformer instance.
*
- * @param mixed $transformer
- * @return \League\Fractal\TransformerAbstract
+ * @param \Closure|class-string|TransformerAbstract $transformer
*/
- protected function createTransformer($transformer)
+ protected function createTransformer(Closure|string|TransformerAbstract $transformer): Closure|TransformerAbstract
{
- if ($transformer instanceof TransformerAbstract || $transformer instanceof \Closure) {
+ if ($transformer instanceof TransformerAbstract || $transformer instanceof Closure) {
return $transformer;
}
- return new $transformer();
+ return new $transformer;
}
}
diff --git a/tests/.gitkeep b/tests/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/FractalTest.php b/tests/FractalTest.php
new file mode 100644
index 0000000..cd75fa4
--- /dev/null
+++ b/tests/FractalTest.php
@@ -0,0 +1,66 @@
+getAjax('/users');
+
+ $json->assertJson([
+ 'draw' => 0,
+ 'recordsTotal' => 20,
+ 'recordsFiltered' => 20,
+ ]);
+
+ $this->assertIsInt($json['data'][0]['id']);
+ $this->assertIsString($json['data'][0]['name']);
+ }
+
+ #[Test]
+ public function it_works_with_closure()
+ {
+ $json = $this->getAjax('/closure');
+
+ $json->assertJson([
+ 'draw' => 0,
+ 'recordsTotal' => 20,
+ 'recordsFiltered' => 20,
+ ]);
+
+ $this->assertIsInt($json['data'][0]['id']);
+ $this->assertIsString($json['data'][0]['name']);
+ }
+
+ protected function setUp(): void
+ {
+ parent::setUp();
+
+ $this->app['router']->get('/users', function () {
+ return DataTables::eloquent(User::query())
+ ->setTransformer(UserTransformer::class)
+ ->toJson();
+ });
+
+ $this->app['router']->get('/closure', function () {
+ return DataTables::eloquent(User::query())
+ ->setTransformer(function (User $user) {
+ return [
+ 'id' => (int) $user->id,
+ 'name' => $user->name,
+ ];
+ })
+ ->toJson();
+ });
+ }
+}
diff --git a/tests/Models/Post.php b/tests/Models/Post.php
new file mode 100644
index 0000000..eab0305
--- /dev/null
+++ b/tests/Models/Post.php
@@ -0,0 +1,21 @@
+belongsTo(User::class);
+ }
+}
diff --git a/tests/Models/Role.php b/tests/Models/Role.php
new file mode 100644
index 0000000..1a7eef5
--- /dev/null
+++ b/tests/Models/Role.php
@@ -0,0 +1,16 @@
+belongsToMany(User::class);
+ }
+}
diff --git a/tests/Models/User.php b/tests/Models/User.php
new file mode 100644
index 0000000..4099137
--- /dev/null
+++ b/tests/Models/User.php
@@ -0,0 +1,28 @@
+hasMany(Post::class);
+ }
+
+ public function roles(): BelongsToMany
+ {
+ return $this->belongsToMany(Role::class);
+ }
+
+ public function user(): MorphTo
+ {
+ return $this->morphTo();
+ }
+}
diff --git a/tests/TestCase.php b/tests/TestCase.php
new file mode 100644
index 0000000..d7dc86e
--- /dev/null
+++ b/tests/TestCase.php
@@ -0,0 +1,119 @@
+migrateDatabase();
+ $this->seedDatabase();
+ }
+
+ protected function migrateDatabase()
+ {
+ /** @var \Illuminate\Database\Schema\Builder $schemaBuilder */
+ $schemaBuilder = $this->app['db']->connection()->getSchemaBuilder();
+ if (! $schemaBuilder->hasTable('users')) {
+ $schemaBuilder->create('users', function (Blueprint $table) {
+ $table->increments('id');
+ $table->string('name');
+ $table->string('email');
+ $table->string('user_type')->nullable();
+ $table->unsignedInteger('user_id')->nullable();
+ $table->timestamps();
+ });
+ }
+ if (! $schemaBuilder->hasTable('posts')) {
+ $schemaBuilder->create('posts', function (Blueprint $table) {
+ $table->increments('id');
+ $table->string('title');
+ $table->unsignedInteger('user_id');
+ $table->timestamps();
+ $table->softDeletes();
+ });
+ }
+ if (! $schemaBuilder->hasTable('roles')) {
+ $schemaBuilder->create('roles', function (Blueprint $table) {
+ $table->increments('id');
+ $table->string('role');
+ $table->timestamps();
+ });
+ }
+ if (! $schemaBuilder->hasTable('role_user')) {
+ $schemaBuilder->create('role_user', function (Blueprint $table) {
+ $table->unsignedInteger('role_id');
+ $table->unsignedInteger('user_id');
+ $table->timestamps();
+ });
+ }
+ }
+
+ protected function seedDatabase()
+ {
+ $adminRole = Role::create(['role' => 'Administrator']);
+ $userRole = Role::create(['role' => 'User']);
+
+ collect(range(1, 20))->each(function ($i) use ($userRole) {
+ /** @var User $user */
+ $user = User::query()->create([
+ 'name' => 'Record-'.$i,
+ 'email' => 'Email-'.$i.'@example.com',
+ ]);
+
+ collect(range(1, 3))->each(function ($i) use ($user) {
+ $user->posts()->create([
+ 'title' => "User-{$user->id} Post-{$i}",
+ ]);
+ });
+
+ if ($i % 2) {
+ $user->roles()->attach(Role::all());
+ } else {
+ $user->roles()->attach($userRole);
+ }
+ });
+ }
+
+ /**
+ * Set up the environment.
+ *
+ * @param \Illuminate\Foundation\Application $app
+ */
+ protected function getEnvironmentSetUp($app)
+ {
+ $app['config']->set('app.debug', true);
+ $app['config']->set('database.default', 'sqlite');
+ $app['config']->set('database.connections.sqlite', [
+ 'driver' => 'sqlite',
+ 'database' => ':memory:',
+ 'prefix' => '',
+ ]);
+ }
+
+ protected function getPackageProviders($app): array
+ {
+ return [
+ \Yajra\DataTables\DataTablesServiceProvider::class,
+ \Yajra\DataTables\FractalServiceProvider::class,
+ ];
+ }
+
+ public function getAjax($uri, array $headers = []): TestResponse
+ {
+ return $this->getJson($uri, array_merge(['X-Requested-With' => 'XMLHttpRequest'], $headers));
+ }
+
+ public function postAjax($uri, array $headers = []): TestResponse
+ {
+ return $this->postJson($uri, array_merge(['X-Requested-With' => 'XMLHttpRequest'], $headers));
+ }
+}
diff --git a/tests/Transformers/UserTransformer.php b/tests/Transformers/UserTransformer.php
new file mode 100644
index 0000000..806b5f2
--- /dev/null
+++ b/tests/Transformers/UserTransformer.php
@@ -0,0 +1,17 @@
+ (int) $user->id,
+ 'name' => $user->name,
+ ];
+ }
+}