Skip to content

Commit

Permalink
cakephp 5 version. prepare for release
Browse files Browse the repository at this point in the history
  • Loading branch information
skie committed Sep 12, 2024
1 parent 3cf4eeb commit 5018846
Show file tree
Hide file tree
Showing 24 changed files with 487 additions and 71 deletions.
19 changes: 14 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ CakeDC SearchFilter Plugin for CakePHP
[![Downloads](https://poser.pugx.org/CakeDC/search-filter/d/total.png)](https://packagist.org/packages/CakeDC/search-filter)
[![License](https://poser.pugx.org/CakeDC/search-filter/license.svg)](https://packagist.org/packages/CakeDC/search-filter)

Versions and branches
---------------------

| CakePHP | CakeDC Users Plugin | Tag | Notes |
| :-------------: | :------------------------: | :--: | :---- |
| ^5.0 | [2.0](https://github.com/cakedc/users/tree/2.next-cake5) | 2.0.0 | stable |
| ^4.5 | [1.0](https://github.com/cakedc/search-filter/tree/1.next-cake4) | 1.0.0 | stable |


## Overview

The SearchFilter plugin is a powerful and flexible solution for implementing advanced search functionality in CakePHP applications. It provides a robust set of tools for creating dynamic, user-friendly search interfaces with minimal effort.
Expand Down Expand Up @@ -59,17 +68,17 @@ class PostsController extends AppController

// Add a general search filter
$collection->add('search', $manager->filters()
->getNew('string')
->new('string')
->setConditions(new \stdClass())
->setLabel('Search...')
);

// Add a complex name filter that searches across multiple fields
$collection->add('name', $manager->filters()
->getNew('string')
->new('string')
->setLabel('Name')
->setCriterion(
new OrCriterion([
$manager->criterion()->or([
$manager->buildCriterion('title', 'string', $this->Posts),
$manager->buildCriterion('body', 'string', $this->Posts),
$manager->buildCriterion('author', 'string', $this->Posts),
Expand All @@ -79,7 +88,7 @@ class PostsController extends AppController

// Add a datetime filter for the 'created' field
$collection->add('created', $manager->filters()
->getNew('datetime')
->new('datetime')
->setLabel('Created')
->setCriterion($manager->buildCriterion('created', 'datetime', $this->Posts))
);
Expand All @@ -103,7 +112,7 @@ class PostsController extends AppController
]);

$filters = $manager->formatFinders($search);
$query = $query->find('filters', $filters);
$query = $query->find('filters', params: $filters);
}

// Paginate the results
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"autoload-dev": {
"psr-4": {
"CakeDC\\SearchFilter\\Test\\": "tests/",
"CakeDC\\SearchFilter\\Test\\App\\": "tests/test_app/App/",
"Cake\\Test\\": "vendor/cakephp/cakephp/tests/"
}
},
Expand Down
6 changes: 0 additions & 6 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,17 @@
<ini name="apc.enable_cli" value="1"/>
<env name="FIXTURE_SCHEMA_METADATA" value="./tests/schema.php"/>
</php>

<!-- Add any additional test suites you want to run here -->
<testsuites>
<testsuite name="SearchFilter">
<directory>./tests/</directory>
</testsuite>
</testsuites>

<!-- Setup fixture extension -->
<extensions>
<bootstrap class="Cake\TestSuite\Fixture\Extension\PHPUnitExtension"/>
</extensions>

<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>

</phpunit>
7 changes: 0 additions & 7 deletions src/Model/Filter/Criterion/BaseCriterion.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ abstract class BaseCriterion implements CriterionInterface
*/
protected string|ExpressionInterface $field;

/**
* Table name used for field condition
*
* @var string
*/
protected string $alias;

/**
* Extract single value or array by value name
*
Expand Down
1 change: 0 additions & 1 deletion src/Model/Filter/Criterion/DateTimeCriterion.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class DateTimeCriterion extends DateCriterion
* DateCriterion constructor.
*
* @param string|\Cake\Database\ExpressionInterface $field
// * @param string $alias
* @param string $format
*/
public function __construct(string|ExpressionInterface $field, string $format = 'Y-m-d\TH:i')
Expand Down
71 changes: 71 additions & 0 deletions tests/TestCase/Controller/ArticlesControllerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
declare(strict_types=1);

namespace CakeDC\SearchFilter\Test\TestCase\Controller;

use Cake\TestSuite\IntegrationTestTrait;
use Cake\TestSuite\TestCase;

class ArticlesControllerTest extends TestCase
{
use IntegrationTestTrait;

protected array $fixtures = [
'plugin.CakeDC/SearchFilter.Articles',
'plugin.CakeDC/SearchFilter.Authors',
];

public function setUp(): void
{
parent::setUp();
}

public function testIndex(): void
{
$this->get('/articles');
$this->assertResponseOk();
$this->assertResponseContains('Articles');
}

public function testString(): void
{
$this->get('/articles?f[0]=title&c[0]=like&v[0][value][]=First');
$this->assertResponseOk();
$this->assertResponseContains('First Article');
$this->assertResponseNotContains('Second Article');
}

public function testAuthorLike(): void
{
$this->get('/articles?f[0]=author_id&c[0]=like&v[0][value][]=larry');
$this->assertResponseOk();
$this->assertResponseContains('Second Article');
$this->assertResponseNotContains('First Article');
}

public function testAuthorEqual(): void
{
$this->get('/articles?f[0]=author_id&c[0]=%3D&v[0][id][]=1');
// debug($this->_getBodyAsString());
$this->assertResponseOk();
$this->assertResponseContains('First Article');
$this->assertResponseNotContains('Second Article');
}

public function testCreatedDate(): void
{
$this->get('/articles?f[0]=created&c[0]=between&v[0][from]=2023-01-01T00:00&v[0][to]=2023-12-31T00:00');
$this->assertResponseOk();
$this->assertResponseContains('First Article');
$this->assertResponseNotContains('Old Article');
}

public function testCombinedFilters(): void
{
$this->get('/articles?f[0]=title&c[0]=like&v[0][value][]=First&f[1]=created&c[1]=greaterOrEqual&v[1][value][]=2023-01-01T00:00');
$this->assertResponseOk();
$this->assertResponseContains('First Article');
$this->assertResponseNotContains('Second Article');
$this->assertResponseNotContains('Old Article');
}
}
106 changes: 58 additions & 48 deletions tests/bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,50 +1,63 @@
<?php
declare(strict_types=1);

$findRoot = function () {
$root = dirname(__DIR__);
if (is_dir($root . '/vendor/cakephp/cakephp')) {
return $root;
}

$root = dirname(__DIR__, 2);
if (is_dir($root . '/vendor/cakephp/cakephp')) {
return $root;
}

$root = dirname(__DIR__, 3);
if (is_dir($root . '/vendor/cakephp/cakephp')) {
return $root;
}
use Cake\Cache\Cache;
use Cake\Core\Configure;
use Cake\Datasource\ConnectionManager;
use Cake\TestSuite\Fixture\SchemaLoader;

/**
* Test suite bootstrap
*
* This function is used to find the location of CakePHP whether CakePHP
* has been installed as a dependency of the plugin, or the plugin is itself
* installed as a dependency of an application.
*/
$findRoot = function ($root) {
do {
$lastRoot = $root;
$root = dirname($root);
if (is_dir($root . '/vendor/cakephp/cakephp')) {
return $root;
}
} while ($root !== $lastRoot);

throw new Exception('Cannot find the root of the application, unable to run tests');
};
$root = $findRoot(__FILE__);
unset($findRoot);

if (!defined('DS')) {
define('DS', DIRECTORY_SEPARATOR);
}
define('ROOT', $findRoot());
define('APP_DIR', 'App');
define('WEBROOT_DIR', 'webroot');
define('APP', ROOT . '/tests/App/');
define('CONFIG', ROOT . '/tests/Config/');
define('WWW_ROOT', ROOT . DS . WEBROOT_DIR . DS);
define('TESTS', ROOT . DS . 'tests' . DS);
define('TMP', ROOT . DS . 'tmp' . DS);
define('LOGS', TMP . 'logs' . DS);
define('CACHE', TMP . 'cache' . DS);
define('CAKE_CORE_INCLUDE_PATH', ROOT . '/vendor/cakephp/cakephp');
chdir($root);

require $root . '/vendor/cakephp/cakephp/src/functions.php';
require_once $root . '/vendor/autoload.php';
// require_once $root . '/vendor/cakephp/cakephp/tests/bootstrap.php';

define('ROOT', $root . DS . 'tests' . DS . 'test_app' . DS);
define('APP', ROOT . 'App' . DS);
define('CONFIG', ROOT . 'config' . DS);
define('WWW_ROOT', ROOT . 'webroot' . DS);
define('TESTS', $root . DS . 'tests' . DS);
define('CAKE_CORE_INCLUDE_PATH', $root . '/vendor/cakephp/cakephp');
define('CORE_PATH', CAKE_CORE_INCLUDE_PATH . DS);
define('CAKE', CORE_PATH . 'src' . DS);
define('TMP', $root . DS . 'tmp' . DS);
define('LOGS', TMP . 'logs' . DS);
define('CACHE', TMP . 'cache' . DS);

require ROOT . '/vendor/cakephp/cakephp/src/functions.php';
require ROOT . '/vendor/autoload.php';
Configure::write('debug', true);

use Cake\Cache\Cache;
use Cake\Core\Configure;
use Cake\Datasource\ConnectionManager;
use Cake\Error\ErrorTrap;
use Cake\TestSuite\Fixture\SchemaLoader;
Configure::write('App', [
'namespace' => 'CakeDC\SearchFilter\Test\App',
'encoding' => 'UTF-8',
'debug' => true,
'paths' => [
// 'plugins' => [ROOT . 'Plugin' . DS],
'templates' => [ROOT . 'templates' . DS],
],
]);

Configure::write('App', ['namespace' => 'CakeDC\SearchFilter\Test\App']);
Configure::write('App.encoding', 'utf8');
Configure::write('debug', true);

@mkdir(TMP . 'cache/models', 0777);
Expand Down Expand Up @@ -76,8 +89,6 @@
'defaults' => 'php',
]);

Configure::write('App.encoding', 'utf8');

// Ensure default test connection is defined
if (!getenv('db_dsn')) {
putenv('db_dsn=sqlite:///:memory:');
Expand All @@ -88,17 +99,16 @@
'timezone' => 'UTC',
]);

// Create test database schema
// Load routes
// require CONFIG . 'routes.php';

// Load schema
if (env('FIXTURE_SCHEMA_METADATA')) {
$loader = new SchemaLoader();
$loader->loadInternalFile(env('FIXTURE_SCHEMA_METADATA'));
}

$error = [
'errorLevel' => E_ALL,
'skipLog' => [],
'log' => true,
'trace' => true,
'ignoredDeprecationPaths' => [],
];
(new ErrorTrap($error))->register();
// Ensure The Plugins are loaded
Configure::write('Plugin.CakeDC/SearchFilter', [
'path' => dirname(dirname(__FILE__)) . DS,
]);
22 changes: 19 additions & 3 deletions tests/App/Application.php → tests/test_app/App/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@

namespace CakeDC\SearchFilter\Test\App;

use Cake\Error\Middleware\ErrorHandlerMiddleware;
use Cake\Http\BaseApplication;
use Cake\Http\MiddlewareQueue;
use Cake\Routing\Middleware\AssetMiddleware;
use Cake\Routing\Middleware\RoutingMiddleware;
use Cake\Routing\Route\DashedRoute;
use Cake\Routing\RouteBuilder;
use Cake\Routing\Router;

/**
* Application setup class.
Expand All @@ -28,9 +32,9 @@ public function bootstrap(): void
{
parent::bootstrap();

$this->addPlugin('SearchFilter', [
'path' => ROOT . DS,
'autoload' => true,
$this->addPlugin('CakeDC/SearchFilter', [
// 'path' => ROOT . DS,
// 'autoload' => true,
]);
}

Expand All @@ -42,10 +46,22 @@ public function bootstrap(): void
*/
public function middleware(MiddlewareQueue $middleware): MiddlewareQueue
{
Router::reload();
$middleware
->add(new ErrorHandlerMiddleware())
->add(new AssetMiddleware())
->add(new RoutingMiddleware($this));

return $middleware;
}

public function routes(RouteBuilder $routes): void
{
$routes->setRouteClass(DashedRoute::class);
$routes->scope('/', function (RouteBuilder $builder) {
$builder->fallbacks();
});

parent::routes($routes);
}
}
22 changes: 22 additions & 0 deletions tests/test_app/App/Controller/AppController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php
declare(strict_types=1);

/**
* Copyright 2019 Cake Development Corporation, Las Vegas, Nevada (702) 425-5085 www.cakedc.com use and restrictions are governed by Section 8.5 of The Professional Services Agreement.
* Redistribution is prohibited. All Rights Reserved.
*/

namespace CakeDC\SearchFilter\Test\App\Controller;

use Cake\Controller\Controller;

/**
* This is a placeholder class.
* Create the same file in app/Controller/AppController.php
*
* Add your application-wide methods in the class below, your controllers
* will inherit them.
*/
class AppController extends Controller
{
}
Loading

0 comments on commit 5018846

Please sign in to comment.