From bbc25d9af09ac2f57c133489823cf3c703f9d1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maik=20Mu=CC=88ller?= Date: Sun, 19 Sep 2021 03:47:34 +0200 Subject: [PATCH] basically working --- .github/FUNDING.yml | 2 +- CHANGELOG.md | 2 +- LICENSE.md | 2 +- README.md | 16 +- composer.json | 24 +-- config/column-multi-filter.php | 15 ++ config/skeleton.php | 5 - configure.php | 30 +-- database/factories/ModelFactory.php | 2 +- .../migrations/create_skeleton_table.php.stub | 2 +- src/Classes/Filter.php | 17 ++ src/ColumnMultiFilter.php | 203 ++++++++++++++++++ src/ColumnMultiFilterFacade.php | 16 ++ ...p => ColumnMultiFilterServiceProvider.php} | 14 +- ...mmand.php => ColumnMultiFilterCommand.php} | 6 +- src/Exceptions/ColumnMultiFilterException.php | 30 +++ src/Skeleton.php | 7 - src/SkeletonFacade.php | 16 -- tests/Pest.php | 2 +- tests/TestCase.php | 10 +- 20 files changed, 337 insertions(+), 84 deletions(-) create mode 100644 config/column-multi-filter.php delete mode 100644 config/skeleton.php create mode 100644 src/Classes/Filter.php create mode 100644 src/ColumnMultiFilter.php create mode 100644 src/ColumnMultiFilterFacade.php rename src/{SkeletonServiceProvider.php => ColumnMultiFilterServiceProvider.php} (55%) rename src/Commands/{SkeletonCommand.php => ColumnMultiFilterCommand.php} (54%) create mode 100644 src/Exceptions/ColumnMultiFilterException.php delete mode 100755 src/Skeleton.php delete mode 100644 src/SkeletonFacade.php diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index c68765b..c817eb0 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: :vendor_name +github: moltox diff --git a/CHANGELOG.md b/CHANGELOG.md index 767365d..18bf926 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -All notable changes to `:package_name` will be documented in this file. +All notable changes to `column-multi-filter` will be documented in this file. ## 1.0.0 - 202X-XX-XX diff --git a/LICENSE.md b/LICENSE.md index 58c9ad4..2e54d79 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) :vendor_name +Copyright (c) moltox Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index bf84262..eec39b7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# :package_description +# Filters multiple columns [![Latest Version on Packagist](https://img.shields.io/packagist/v/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug) [![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/:vendor_slug/:package_slug/run-tests?label=tests)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3Arun-tests+branch%3Amain) @@ -8,7 +8,7 @@ --- This repo can be used to scaffold a Laravel package. Follow these steps to get started: -1. Press the "Use template" button at the top of this repo to create a new repo with the contents of this skeleton +1. Press the "Use template" button at the top of this repo to create a new repo with the contents of this column-multi-filter 2. Run "php ./configure.php" to run a script that will replace all placeholders throughout all the files 3. Remove this block of text. 4. Have fun creating your package. @@ -19,7 +19,7 @@ This is where your description should go. Limit it to a paragraph or two. Consid ## Support us -[](https://spatie.be/github-ad-click/:package_name) +[](https://spatie.be/github-ad-click/column-multi-filter) We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). @@ -36,13 +36,13 @@ composer require :vendor_slug/:package_slug You can publish and run the migrations with: ```bash -php artisan vendor:publish --provider="VendorName\Skeleton\SkeletonServiceProvider" --tag=":package_slug-migrations" +php artisan vendor:publish --provider="VendorName\ColumnMultiFilter\ColumnMultiFilterServiceProvider" --tag=":package_slug-migrations" php artisan migrate ``` You can publish the config file with: ```bash -php artisan vendor:publish --provider="VendorName\Skeleton\SkeletonServiceProvider" --tag=":package_slug-config" +php artisan vendor:publish --provider="VendorName\ColumnMultiFilter\ColumnMultiFilterServiceProvider" --tag=":package_slug-config" ``` This is the contents of the published config file: @@ -55,8 +55,8 @@ return [ ## Usage ```php -$skeleton = new VendorName\Skeleton(); -echo $skeleton->echoPhrase('Hello, VendorName!'); +$column-multi-filter = new VendorName\ColumnMultiFilter(); +echo $column-multi-filter->echoPhrase('Hello, VendorName!'); ``` ## Testing @@ -79,7 +79,7 @@ Please review [our security policy](../../security/policy) on how to report secu ## Credits -- [:author_name](https://github.com/:author_username) +- [Maik Mueller](https://github.com/moltox) - [All Contributors](../../contributors) ## License diff --git a/composer.json b/composer.json index 55a4e6e..3a9465e 100644 --- a/composer.json +++ b/composer.json @@ -1,17 +1,17 @@ { - "name": ":vendor_slug/:package_slug", - "description": ":package_description", + "name": "moltox/column-multi-filter", + "description": "Filters multiple columns", "keywords": [ - ":vendor_name", + "moltox", "laravel", - ":package_slug" + "column-multi-filter" ], - "homepage": "https://github.com/:vendor_slug/:package_slug", + "homepage": "https://github.com/moltox/column-multi-filter", "license": "MIT", "authors": [ { - "name": ":author_name", - "email": "author@domain.com", + "name": "Maik Mueller", + "email": "maik@muelleronline.org", "role": "Developer" } ], @@ -30,13 +30,13 @@ }, "autoload": { "psr-4": { - "VendorName\\Skeleton\\": "src", - "VendorName\\Skeleton\\Database\\Factories\\": "database/factories" + "Moltox\\ColumnMultiFilter\\": "src", + "Moltox\\ColumnMultiFilter\\Database\\Factories\\": "database/factories" } }, "autoload-dev": { "psr-4": { - "VendorName\\Skeleton\\Tests\\": "tests" + "Moltox\\ColumnMultiFilter\\Tests\\": "tests" } }, "scripts": { @@ -49,10 +49,10 @@ "extra": { "laravel": { "providers": [ - "VendorName\\Skeleton\\SkeletonServiceProvider" + "Moltox\\ColumnMultiFilter\\ColumnMultiFilterServiceProvider" ], "aliases": { - "Skeleton": "VendorName\\Skeleton\\SkeletonFacade" + "ColumnMultiFilter": "Moltox\\ColumnMultiFilter\\ColumnMultiFilterFacade" } } }, diff --git a/config/column-multi-filter.php b/config/column-multi-filter.php new file mode 100644 index 0000000..82c7545 --- /dev/null +++ b/config/column-multi-filter.php @@ -0,0 +1,15 @@ + [ + 'type' => Filter::LIKE, + 'logic' => Filter::LOGIC_VALUE + ], + 'uri_relation_column_separator' => '.', + 'log_enabled' => true, + 'log_channel' => 'default', + + +]; diff --git a/config/skeleton.php b/config/skeleton.php deleted file mode 100644 index fbb0e4c..0000000 --- a/config/skeleton.php +++ /dev/null @@ -1,5 +0,0 @@ - $authorName, - ':author_username' => $authorUsername, + 'Maik Mueller' => $authorName, + 'moltox' => $authorUsername, 'author@domain.com' => $authorEmail, - ':vendor_name' => $vendorName, + 'moltox' => $vendorName, ':vendor_slug' => $vendorSlug, 'VendorName' => $vendorNamespace, - ':package_name' => $packageName, + 'column-multi-filter' => $packageName, ':package_slug' => $packageSlug, - 'Skeleton' => $className, - 'skeleton' => $packageSlug, - ':package_description' => $description, + 'ColumnMultiFilter' => $className, + 'column-multi-filter' => $packageSlug, + 'Filters multiple columns' => $description, ]); match (true) { - str_contains($file, 'src/Skeleton.php') => rename($file, './src/' . $className . '.php'), - str_contains($file, 'src/SkeletonServiceProvider.php') => rename($file, './src/' . $className . 'ServiceProvider.php'), - str_contains($file, 'src/SkeletonFacade.php') => rename($file, './src/' . $className . 'Facade.php'), - str_contains($file, 'src/Commands/SkeletonCommand.php') => rename($file, './src/Commands/' . $className . 'Command.php'), - str_contains($file, 'database/migrations/create_skeleton_table.php.stub') => rename($file, './database/migrations/create_' . $packageSlugWithoutPrefix . '_table.php.stub'), - str_contains($file, 'config/skeleton.php') => rename($file, './config/' . $packageSlugWithoutPrefix . '.php'), + str_contains($file, 'src/ColumnMultiFilter.php') => rename($file, './src/' . $className . '.php'), + str_contains($file, 'src/ColumnMultiFilterServiceProvider.php') => rename($file, './src/' . $className . 'ServiceProvider.php'), + str_contains($file, 'src/ColumnMultiFilterFacade.php') => rename($file, './src/' . $className . 'Facade.php'), + str_contains($file, 'src/Commands/ColumnMultiFilterCommand.php') => rename($file, './src/Commands/' . $className . 'Command.php'), + str_contains($file, 'database/migrations/create_column_multi_filter_table.php.stub') => rename($file, './database/migrations/create_' . $packageSlugWithoutPrefix . '_table.php.stub'), + str_contains($file, 'config/column-multi-filter.php') => rename($file, './config/' . $packageSlugWithoutPrefix . '.php'), default => [], }; } diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index c51604f..10159a4 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -1,6 +1,6 @@ id(); // add fields diff --git a/src/Classes/Filter.php b/src/Classes/Filter.php new file mode 100644 index 0000000..8a1cda7 --- /dev/null +++ b/src/Classes/Filter.php @@ -0,0 +1,17 @@ +has('filter')) { + + $filters = request()->get('filter'); + + $this->log('Filter found: ' . print_r($filters, true)); + + return $this->filterQueryBuilder($query, $filters); + + } + + return $query; + + } + + protected function filterQueryBuilder(Builder $query, array $filters) + { + + foreach ($filters as $column => $value) { + + if ($this->isColumnFilterable($column)) { + + $this->log(sprintf('Filterable column found: %30s with value: %s', $column, $value)); + + $filterType = $this->getFilterType($column); + $logic = $this->getLogic($column); + $operator = $this->getOperator($filterType); + $value = trim($value); + + $this->addFilter($query, $column, $operator, $value, $logic); + + } + } + + return $query; + + } + + protected function isColumnFilterable(string $column) + { + + return Arr::has($this->multiFilter, $column); + + } + + protected function getFilterType($column) + { + + $type = config('column-multi-filter.default.type', Filter::LIKE); + + if (Arr::has($this->multiFilter[$column], 'type')) { + + $type = $this->multiFilter[$column]['type']; + + } + + return $type; + + } + + + /** + * + * Returns the where logic for the given column + * + * @param $column + * + * @return \Illuminate\Config\Repository|\Illuminate\Contracts\Foundation\Application|mixed + */ + protected function getLogic($column) + { + + $logic = config('column-multi-filter.default.logic', Filter::LIKE); + + if (Arr::has($this->multiFilter[$column], 'logic')) { + + $logic = $this->multiFilter[$column]['logic']; + + } + + return $logic; + + } + + protected function getOperator($type) + { + + return match ($type) { + Filter::LIKE => "like", + default => "=", + }; + + } + + /** + * + * @throws ColumnMultiFilterException + */ + protected function addFilter(Builder $query, string $column, string $operator, mixed $value, mixed $logic) + { + + if ($this->isColumnRelational($column)) { + + $exp = explode(config('column-multi-filter.seperator', '.'), $column); + + if (count($exp) > 2) { + throw new ColumnMultiFilterException($column, 3); + } else { + + if (count($exp) === 2) { + + list ($relation, $column) = $exp; + + + $query->whereHas(Str::camel($relation), function ($qb) use ($column, $operator, $value, $logic) { + + /** + * @var Builder $qb + */ + $qb = $this->addWhereIfValid($qb, $column, $operator, $value, $logic); + }); + + } + } + + } else { + Log::debug('where ..'.print_r([$column, $operator, $value, $logic], true)); + $query = $this->addWhereIfValid($query, $column, $operator, $value, $logic); + + } + + return $query; + + } + + /** + * @param string $column + * + * @return bool + */ + private function isColumnRelational(string $column): bool + { + + return count($this->splitRelatedColumn($column)) > 1; + + } + + private function splitRelatedColumn($relationColumn): array + { + + return explode(config('column-multi-sort.uri_relation_column_separator', '.'), $relationColumn); + + } + + private function addWhereIfValid(Builder $query, string $column, string $operator, string $value, string $logic) + { + + if (trim($operator) === 'like' && trim($value) === '') { + return $query; + } + + Log::debug('add where now'); + $query->where($column, $operator, $value, $logic); + + return $query; + + } + + + private function log(string $message, $logLevel = 'info', $force = false) + { + + if (config('column-multi-filter.log_enabled', false) || $force) { + + Log::channel(env('LOG_CHANNEL', 'stack'))->log($logLevel, '[MultiSort] '.$message); + + } + + } + +} diff --git a/src/ColumnMultiFilterFacade.php b/src/ColumnMultiFilterFacade.php new file mode 100644 index 0000000..b095e76 --- /dev/null +++ b/src/ColumnMultiFilterFacade.php @@ -0,0 +1,16 @@ +name('skeleton') + ->name('column-multi-filter') ->hasConfigFile() - ->hasViews() - ->hasMigration('create_skeleton_table') - ->hasCommand(SkeletonCommand::class); + // ->hasViews() + // ->hasMigration('create_column_multi_filter_table') + // ->hasCommand(ColumnMultiFilterCommand::class) + ; } } diff --git a/src/Commands/SkeletonCommand.php b/src/Commands/ColumnMultiFilterCommand.php similarity index 54% rename from src/Commands/SkeletonCommand.php rename to src/Commands/ColumnMultiFilterCommand.php index 4ce4c84..2831b95 100644 --- a/src/Commands/SkeletonCommand.php +++ b/src/Commands/ColumnMultiFilterCommand.php @@ -1,12 +1,12 @@ in(__DIR__); diff --git a/tests/TestCase.php b/tests/TestCase.php index d04fb0c..4652df1 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,10 +1,10 @@ 'VendorName\\Skeleton\\Database\\Factories\\'.class_basename($modelName).'Factory' + fn (string $modelName) => 'VendorName\\ColumnMultiFilter\\Database\\Factories\\'.class_basename($modelName).'Factory' ); } protected function getPackageProviders($app) { return [ - SkeletonServiceProvider::class, + ColumnMultiFilterServiceProvider::class, ]; } @@ -29,7 +29,7 @@ class TestCase extends Orchestra config()->set('database.default', 'testing'); /* - $migration = include __DIR__.'/../database/migrations/create_skeleton_table.php.stub'; + $migration = include __DIR__.'/../database/migrations/create_column_multi_filter_table.php.stub'; $migration->up(); */ }