diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 681124be..57e5d6ec 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -4,6 +4,7 @@ on:
push:
branches:
- 5.x
+ - 6.x
pull_request:
branches:
- '*'
@@ -18,10 +19,10 @@ jobs:
strategy:
fail-fast: false
matrix:
- php-version: ['8.1', '8.2', '8.3', '8.4', '8.5']
+ php-version: ['8.4', '8.5']
prefer-lowest: ['']
include:
- - php-version: '8.1'
+ - php-version: '8.4'
prefer-lowest: 'prefer-lowest'
services:
diff --git a/.github/workflows/deploy_docs_6x.yml b/.github/workflows/deploy_docs_6x.yml
new file mode 100644
index 00000000..9280ba8e
--- /dev/null
+++ b/.github/workflows/deploy_docs_6x.yml
@@ -0,0 +1,28 @@
+---
+name: 'deploy_docs_6x'
+
+on:
+ push:
+ branches:
+ - 6.x
+ workflow_dispatch:
+
+permissions:
+ contents: read
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Cloning repo
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+
+ - name: Push to dokku
+ uses: dokku/github-action@cc7dec1d2b9fed249a14ae462bc953bba436f78c # v1.10.0
+ with:
+ git_remote_url: 'ssh://dokku@apps.cakephp.org:22/elasticsearch-docs-6'
+ git_push_flags: '-f'
+ ssh_private_key: ${{ secrets.DOKKU_SSH_PRIVATE_KEY }}
+ branch: '6.x'
diff --git a/.github/workflows/docs-validation.yml b/.github/workflows/docs-validation.yml
index 439a52c1..6043b1f6 100644
--- a/.github/workflows/docs-validation.yml
+++ b/.github/workflows/docs-validation.yml
@@ -3,7 +3,7 @@ name: Documentation Validation
on:
push:
branches:
- - 5.x
+ - 6.x
paths:
- 'docs/**'
- '.github/**'
@@ -14,7 +14,7 @@ on:
jobs:
validate:
- uses: cakephp/.github/.github/workflows/docs-validation.yml@5.x
+ uses: cakephp/.github/.github/workflows/docs-validation.yml@6.x
with:
docs-path: 'docs'
vitepress-path: 'docs/.vitepress'
@@ -24,4 +24,4 @@ jobs:
enable-spell-check: true
enable-markdown-lint: true
enable-link-check: true
- tools-ref: '5.x'
+ tools-ref: '6.x'
diff --git a/README.md b/README.md
index 22c57819..d5653953 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,13 @@
# Elasticsearch Datasource for CakePHP
-
+
[](https://packagist.org/packages/cakephp/elastic-search)
[](https://packagist.org/packages/cakephp/elastic-search/stats)
-[](https://app.codecov.io/gh/cakephp/elastic-search/tree/5.x)
+[](https://app.codecov.io/gh/cakephp/elastic-search/tree/6.x)
[](https://phpstan.org/)
[](LICENSE)
-Use [Elastic Search](https://www.elastic.co/) as an alternative ORM backend in CakePHP 5.2+.
+Use [Elastic Search](https://www.elastic.co/) as an alternative ORM backend in CakePHP 6.0+.
You can [find the documentation for the plugin in the Cake Book](https://book.cakephp.org/elasticsearch).
@@ -17,7 +17,7 @@ You can install Elasticsearch into your project using
[composer](https://getcomposer.org). For existing applications you can run:
```bash
-composer require cakephp/elastic-search:^5.0
+composer require cakephp/elastic-search:^6.0
```
### Versions Table
@@ -30,8 +30,9 @@ composer require cakephp/elastic-search:^5.0
| [>=3.4.0](https://github.com/cakephp/elastic-search/tree/3.x) | 4.0+ | 7.x | 7.x |
| [4.x](https://github.com/cakephp/elastic-search/tree/4.x) | 5.0+ | 7.x | 7.x |
| [5.x](https://github.com/cakephp/elastic-search/tree/5.x) | 5.2+ | 9.x | 9.x |
+| [6.x](https://github.com/cakephp/elastic-search/tree/6.x) | 6.0+ | 9.x | 9.x |
-You are seeing the 5.x version.
+You are seeing the 6.x version.
## Connecting the Plugin to your Application
@@ -42,7 +43,7 @@ use Cake\ElasticSearch\Plugin as ElasticSearchPlugin;
class Application extends BaseApplication
{
- public function bootstrap()
+ public function bootstrap(): void
{
$this->addPlugin(ElasticSearchPlugin::class);
diff --git a/composer.json b/composer.json
index 5b1e6bf2..307e2aea 100644
--- a/composer.json
+++ b/composer.json
@@ -18,12 +18,13 @@
"source": "https://github.com/cakephp/elastic-search"
},
"require": {
- "cakephp/cakephp": "^5.2.0",
+ "php": ">=8.4",
+ "cakephp/cakephp": "^6.0",
"ruflin/elastica": "^9.0"
},
"require-dev": {
- "cakephp/cakephp-codesniffer": "^5.0",
- "phpunit/phpunit": "^10.5.5 || ^11.5.3 || ^12.1.3",
+ "cakephp/cakephp-codesniffer": "^6.0",
+ "phpunit/phpunit": "^13.0",
"nyholm/psr7": "^1.8"
},
"autoload": {
@@ -56,8 +57,10 @@
"test-coverage": "phpunit --coverage-clover=clover.xml",
"phpstan": "vendor/bin/phpstan analyse",
"phpstan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^2.0 --no-update && composer update && mv composer.backup composer.json",
- "rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"^2.2\" && mv composer.backup composer.json",
+ "rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"~2.6.0\" && mv composer.backup composer.json",
"rector-check": "vendor/bin/rector process --dry-run",
"rector-fix": "vendor/bin/rector process"
- }
+ },
+ "minimum-stability": "dev",
+ "prefer-stable": true
}
diff --git a/docs/.vitepress/toc_en.json b/docs/.vitepress/toc_en.json
index 3915b418..847157b4 100644
--- a/docs/.vitepress/toc_en.json
+++ b/docs/.vitepress/toc_en.json
@@ -21,6 +21,7 @@
"text": "Migration",
"collapsed": false,
"items": [
+ { "text": "6.0 Upgrade Guide", "link": "/6-0-upgrade-guide" },
{ "text": "5.0 Upgrade Guide", "link": "/5-0-upgrade-guide" },
{ "text": "4.0 Upgrade Guide", "link": "/4-0-upgrade-guide" },
{ "text": "3.0 Upgrade Guide", "link": "/3-0-upgrade-guide" }
diff --git a/docs/en/6-0-upgrade-guide.md b/docs/en/6-0-upgrade-guide.md
new file mode 100644
index 00000000..c1a2dcfe
--- /dev/null
+++ b/docs/en/6-0-upgrade-guide.md
@@ -0,0 +1,114 @@
+# 6.0 Upgrade Guide
+
+::: warning Requirements
+CakePHP ElasticSearch `6.x` requires CakePHP `6.0+`, Elasticsearch `9.x`, Elastica `9.x`, and PHP `8.4+`.
+:::
+
+## Requirements
+
+- CakePHP `6.0+`
+- Elasticsearch `9.x`
+- Elastica `9.x`
+- PHP `8.4+`
+
+## Breaking Changes
+
+Version `6.x` requires CakePHP `6.x`.
+The Elasticsearch, Elastica and PHP version requirements are unchanged from `5.x`,
+apart from the PHP version bump required by CakePHP `6`.
+
+### Updated dependencies
+
+Update your application requirements:
+
+```bash
+composer require cakephp/elastic-search:^6.0
+```
+
+- `cakephp/cakephp` is now `^6.0`.
+- `php` is now `>=8.4`.
+
+### Entity access rules
+
+`Cake\Datasource\EntityTrait` renamed its access control API:
+
+| CakePHP 5.x | CakePHP 6.x |
+| ------------------------------- | ------------------------------- |
+| `$entity->setAccess(...)` | `$entity->setPatchable(...)` |
+| `$entity->getAccessible()` | `$entity->getPatchable()` |
+| `$entity->isAccessible(...)` | `$entity->isPatchable(...)` |
+| `'accessibleFields' => [...]` | `'patchableFields' => [...]` |
+
+The `Marshaller` options array follows the same rename:
+
+```php
+// Before (5.x)
+$entity = $this->Articles->marshallOne($data, ['accessibleFields' => ['title' => false]]);
+
+// After (6.x)
+$entity = $this->Articles->marshallOne($data, ['patchableFields' => ['title' => false]]);
+```
+
+### Query changes
+
+- `Query::order()` has been removed. Use `Query::orderBy()` instead.
+- Finders no longer accept a positional options array. Pass finder options as
+ named arguments; passing an array now throws an `InvalidArgumentException`:
+
+```php
+// Before (5.x, deprecated)
+$this->Articles->find('all', ['limit' => 10]);
+
+// After (6.x)
+$this->Articles->find('all', limit: 10);
+```
+
+- Fluent query methods (`select()`, `where()`, `limit()`, `offset()`, `page()`,
+ `orderBy()`, `applyOptions()`, `setRepository()`, ...) now declare a `static`
+ return type, as required by `Cake\Datasource\QueryInterface`.
+
+### Fixtures
+
+`Cake\Datasource\FixtureInterface::insert()` and `truncate()` now return `void`.
+If you have custom fixtures that implement or extend `Cake\ElasticSearch\TestSuite\TestFixture`,
+update their signatures accordingly:
+
+```php
+public function insert(ConnectionInterface $connection): void
+{
+}
+```
+
+### Subclassing `Cake\ElasticSearch\Document`
+
+CakePHP `6` removed the underscore prefix convention. Plugin classes follow the
+same rule, so protected members that custom subclasses may rely on were renamed:
+
+| 5.x | 6.x |
+| -------------------- | ---------------- |
+| `Document::$_result` | `Document::$searchResult` |
+
+`$searchResult` holds the `Elastica\Result` the document was hydrated from and
+backs `index()`, `version()`, `highlights()` and `explanation()`.
+
+The same convention applies to `Query`, `Index`, `Connection`, `Marshaller` and
+friends - for example `Query::$_queryParts` is now `Query::$queryParts`.
+
+### Test suite
+
+- `Index` and `Connection` fluent setters (`setConnection()`, `setName()`,
+ `setEntityClass()`, `setCacher()`, `setLogger()`, `enableQueryLogging()`, ...)
+ now declare a `static` return type.
+
+## Recommended Migration Steps
+
+1. Update `composer.json` to require `cakephp/elastic-search:^6.0` and run `composer update`.
+2. Upgrade your application to CakePHP `6.0` and PHP `8.4` by following the
+ [CakePHP 6 migration guide](https://book.cakephp.org/6.x/appendices/6-0-migration-guide.html).
+3. Replace `setAccess()`/`getAccessible()`/`isAccessible()` calls with their
+ `setPatchable()`/`getPatchable()`/`isPatchable()` equivalents.
+4. Rename the `accessibleFields` marshaller option to `patchableFields`.
+5. Replace `Query::order()` with `Query::orderBy()` and convert finder option
+ arrays to named arguments.
+6. Update custom fixture `insert()`/`truncate()` signatures to `void`.
+7. Re-run your test suite against Elasticsearch `9.x`.
diff --git a/docs/en/index.md b/docs/en/index.md
index 5c56f874..f618f8cb 100644
--- a/docs/en/index.md
+++ b/docs/en/index.md
@@ -2,7 +2,7 @@
The ElasticSearch plugin provides an ORM-like abstraction for working with [Elasticsearch](https://www.elastic.co/products/elasticsearch) indexes in CakePHP. It helps with indexing, searching, validation, embedded documents, and fixture-backed tests.
-Version `5.x` targets CakePHP `5.2+`, Elasticsearch `9.x`, Elastica `9.x`, and PHP `8.1+`.
+Version `6.x` targets CakePHP `6.0+`, Elasticsearch `9.x`, Elastica `9.x`, and PHP `8.4+`.
## Documentation Map
@@ -11,4 +11,4 @@ Version `5.x` targets CakePHP `5.2+`, Elasticsearch `9.x`, Elastica `9.x`, and P
- [Searching and Saving](/searching-and-saving) covers finding, validating, saving, updating, bulk operations, and deleting documents.
- [Embedded Documents](/embedded-documents) explains `embedOne()` and `embedMany()` for nested document objects.
- [Testing](/testing) shows how to load mappings and fixtures for integration tests.
-- [3.0 Upgrade Guide](/3-0-upgrade-guide), [4.0 Upgrade Guide](/4-0-upgrade-guide), and [5.0 Upgrade Guide](/5-0-upgrade-guide) describe version-specific migration changes.
+- [6.0 Upgrade Guide](/6-0-upgrade-guide), [5.0 Upgrade Guide](/5-0-upgrade-guide), [4.0 Upgrade Guide](/4-0-upgrade-guide), and [3.0 Upgrade Guide](/3-0-upgrade-guide) describe version-specific migration changes.
diff --git a/docs/en/installation.md b/docs/en/installation.md
index 55ec6afe..11b7f2df 100644
--- a/docs/en/installation.md
+++ b/docs/en/installation.md
@@ -3,7 +3,7 @@
Install the plugin with Composer from your application's root directory:
```bash
-composer require cakephp/elastic-search:^5.0
+composer require cakephp/elastic-search:^6.0
```
Load the plugin in your application bootstrap:
diff --git a/docs/ja/index.md b/docs/ja/index.md
index b1fae161..624778d8 100644
--- a/docs/ja/index.md
+++ b/docs/ja/index.md
@@ -7,7 +7,7 @@ ElasticSearch プラグインは、[Elasticsearch](https://www.elastic.co/produc
アプリケーションのルートディレクトリーで Composer を使ってインストールします。
```bash
-composer require cakephp/elastic-search:^5.0
+composer require cakephp/elastic-search:^6.0
```
`src/Application.php` でプラグインを読み込みます。
diff --git a/phpcs.xml b/phpcs.xml
index abf9ae9f..4434c0a8 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -4,13 +4,8 @@
tests/
-
+
-
-
-
- 0
-
diff --git a/rector.php b/rector.php
index e728216d..f2b3d594 100644
--- a/rector.php
+++ b/rector.php
@@ -1,24 +1,28 @@
withPhpVersion(PhpVersion::PHP_83)
+ ->withPhpVersion(PhpVersion::PHP_84)
->withPaths([
__DIR__ . '/src',
__DIR__ . '/tests',
])
->withSkip([
- // CakePHP coding standards compatibility
- DisallowedEmptyRuleFixerRector::class,
- SimplifyIfElseToTernaryRector::class,
// Skip visibility changes that might break inheritance
MakeInheritedMethodVisibilitySameAsParentRector::class,
+ // Docblock removal rules added in rector 2.5/2.6. They are skipped to keep
+ // the diff behavior-neutral, and because `@return $this` is still needed for
+ // PHPStan to track the fluent interfaces declared by CakePHP interfaces.
+ RemoveDuplicatedReturnSelfDocblockRector::class,
+ RemoveUselessReturnTagRector::class,
+ RemoveUselessUnionReturnDocblockRector::class,
])
->withParallel()
->withPreparedSets(
diff --git a/src/Association/Embedded.php b/src/Association/Embedded.php
index 6dd80929..d6599145 100644
--- a/src/Association/Embedded.php
+++ b/src/Association/Embedded.php
@@ -101,7 +101,7 @@ public function getProperty(): string
* @param string|null $name The property name to set.
* @return $this
*/
- public function setProperty(?string $name = null)
+ public function setProperty(?string $name = null): static
{
if ($name !== null) {
$this->property = $name;
@@ -149,7 +149,7 @@ public function getEntityClass(): string
* @param string $name The name of the class to use
* @return $this
*/
- public function setEntityClass(string $name)
+ public function setEntityClass(string $name): static
{
$class = App::className($name, 'Model/Document');
$this->entityClass = $class ?? Document::class;
@@ -186,7 +186,7 @@ public function getIndexClass(): string
* @throws \InvalidArgumentException In case the class name is set after the target index has been
* resolved, and it doesn't match the target index's class name.
*/
- public function setIndexClass(string|Index|null $className)
+ public function setIndexClass(string|Index|null $className): static
{
if ($className instanceof Index) {
$this->index = $className;
@@ -219,7 +219,7 @@ public function setIndexClass(string|Index|null $className)
* @param \Cake\ElasticSearch\Index $index the instance to be assigned as target side
* @return $this
*/
- public function setIndex(Index $index)
+ public function setIndex(Index $index): static
{
$this->index = $index;
diff --git a/src/Datasource/Connection.php b/src/Datasource/Connection.php
index 6a289222..dce22d88 100644
--- a/src/Datasource/Connection.php
+++ b/src/Datasource/Connection.php
@@ -35,12 +35,12 @@
*/
class Connection implements ConnectionInterface
{
- protected array $_config;
+ protected array $config;
/**
* Compatibility shim for ConnectionInterface
*/
- public const ROLE_WRITE = 'write';
+ public const string ROLE_WRITE = 'write';
/**
* Whether or not query logging is enabled.
@@ -60,17 +60,17 @@ class Connection implements ConnectionInterface
/**
* Elastica client instance
*/
- protected ElasticaClient $_client;
+ protected ElasticaClient $client;
/**
* Logger object instance.
*/
- protected QueryLogger|LoggerInterface $_logger;
+ protected QueryLogger|LoggerInterface $logger;
/**
* Instance of ElasticLogger
*/
- protected ElasticLogger $_esLogger;
+ protected ElasticLogger $esLogger;
protected CacheInterface $cacher;
@@ -104,9 +104,9 @@ public function __construct(array $config = [])
);
}
- $this->_config = $config;
+ $this->config = $config;
$logger = $this->logQueries ? $this->getEsLogger() : null;
- $this->_client = new ElasticaClient($config, $logger);
+ $this->client = new ElasticaClient($config, $logger);
}
/**
@@ -118,8 +118,8 @@ public function __construct(array $config = [])
*/
public function __call(string $name, array $attributes): mixed
{
- if (method_exists($this->_client, $name)) {
- $callback = [$this->_client, $name];
+ if (method_exists($this->client, $name)) {
+ $callback = [$this->client, $name];
assert(is_callable($callback));
return call_user_func_array($callback, $attributes);
@@ -151,7 +151,7 @@ public function configName(): string
* @param bool $enable Enable/disable query logging
* @return $this
*/
- public function enableQueryLogging(bool $enable = true)
+ public function enableQueryLogging(bool $enable = true): static
{
$this->logQueries = $enable;
@@ -160,10 +160,8 @@ public function enableQueryLogging(bool $enable = true)
/**
* Disable query logging
- *
- * @return $this
*/
- public function disableQueryLogging()
+ public function disableQueryLogging(): static
{
$this->logQueries = false;
@@ -199,7 +197,7 @@ public function disableConstraints(callable $operation)
*/
public function config(): array
{
- return $this->_config;
+ return $this->config;
}
/**
@@ -208,9 +206,9 @@ public function config(): array
* @param \Cake\Database\Log\QueryLogger|\Psr\Log\LoggerInterface $logger Logger instance
* @return $this
*/
- public function setLogger(QueryLogger|LoggerInterface $logger)
+ public function setLogger(QueryLogger|LoggerInterface $logger): static
{
- $this->_logger = $logger;
+ $this->logger = $logger;
$this->getEsLogger()->setLogger($logger);
return $this;
@@ -225,7 +223,7 @@ public function setLogger(QueryLogger|LoggerInterface $logger)
*/
public function getLogger(): LoggerInterface
{
- if (!isset($this->_logger)) {
+ if (!isset($this->logger)) {
$loggerName = $this->loggerName;
$engine = Log::engine($loggerName) ?: Log::engine('debug');
@@ -236,7 +234,7 @@ public function getLogger(): LoggerInterface
$this->setLogger($engine);
}
- return $this->_logger;
+ return $this->logger;
}
/**
@@ -244,17 +242,17 @@ public function getLogger(): LoggerInterface
*/
public function getEsLogger(): ElasticLogger
{
- if (!isset($this->_esLogger)) {
- $this->_esLogger = new ElasticLogger($this->getLogger(), $this);
+ if (!isset($this->esLogger)) {
+ $this->esLogger = new ElasticLogger($this->getLogger(), $this);
}
- return $this->_esLogger;
+ return $this->esLogger;
}
/**
* @inheritDoc
*/
- public function setCacher(CacheInterface $cacher)
+ public function setCacher(CacheInterface $cacher): static
{
$this->cacher = $cacher;
@@ -270,7 +268,7 @@ public function getCacher(): CacheInterface
return $this->cacher;
}
- $configName = $this->_config['cacheMetadata'] ?? '_cake_model_';
+ $configName = $this->config['cacheMetadata'] ?? '_cake_model_';
if (!is_string($configName)) {
$configName = '_cake_model_';
}
@@ -292,7 +290,7 @@ public function getCacher(): CacheInterface
*/
public function getDriver(string $role = self::ROLE_WRITE): ElasticaClient
{
- return $this->_client;
+ return $this->client;
}
/**
@@ -306,6 +304,6 @@ public function getIndex(?string $name = null): Index
{
$defaultIndex = $this->config()['index'] ?? $this->configName;
- return $this->_client->getIndex($name ?: $defaultIndex);
+ return $this->client->getIndex($name ?: $defaultIndex);
}
}
diff --git a/src/Datasource/IndexLocator.php b/src/Datasource/IndexLocator.php
index 6981ecf9..2524284e 100644
--- a/src/Datasource/IndexLocator.php
+++ b/src/Datasource/IndexLocator.php
@@ -53,7 +53,7 @@ class IndexLocator extends AbstractLocator
* @return $this
* @psalm-param class-string<\Cake\ElasticSearch\Index> $className
*/
- public function setFallbackClassName(string $className)
+ public function setFallbackClassName(string $className): static
{
$this->fallbackClassName = $className;
@@ -69,7 +69,7 @@ public function setFallbackClassName(string $className)
* @param bool $allow Flag to enable or disable fallback
* @return $this
*/
- public function allowFallbackClass(bool $allow = true)
+ public function allowFallbackClass(bool $allow = true): static
{
$this->allowFallbackClass = $allow;
diff --git a/src/Datasource/IndexLocatorAwareTrait.php b/src/Datasource/IndexLocatorAwareTrait.php
index 58f69a81..f337b17e 100644
--- a/src/Datasource/IndexLocatorAwareTrait.php
+++ b/src/Datasource/IndexLocatorAwareTrait.php
@@ -34,7 +34,7 @@ trait IndexLocatorAwareTrait
/**
* Index locator instance
*/
- protected ?LocatorInterface $_indexLocator = null;
+ protected ?LocatorInterface $indexLocator = null;
/**
* Sets the index locator.
@@ -42,9 +42,9 @@ trait IndexLocatorAwareTrait
* @param \Cake\Datasource\Locator\LocatorInterface $indexLocator LocatorInterface instance.
* @return $this
*/
- public function setIndexLocator(LocatorInterface $indexLocator)
+ public function setIndexLocator(LocatorInterface $indexLocator): static
{
- $this->_indexLocator = $indexLocator;
+ $this->indexLocator = $indexLocator;
return $this;
}
@@ -54,8 +54,8 @@ public function setIndexLocator(LocatorInterface $indexLocator)
*/
public function getIndexLocator(): LocatorInterface
{
- if ($this->_indexLocator !== null) {
- return $this->_indexLocator;
+ if ($this->indexLocator !== null) {
+ return $this->indexLocator;
}
$locator = FactoryLocator::get('Elastic');
@@ -64,7 +64,7 @@ public function getIndexLocator(): LocatorInterface
'`FactoryLocator` must return an instance of Cake\Datasource\Locator\LocatorInterface for type `Elastic`.',
);
- return $this->_indexLocator = $locator;
+ return $this->indexLocator = $locator;
}
/**
diff --git a/src/Datasource/Log/ElasticLogger.php b/src/Datasource/Log/ElasticLogger.php
index 373f484a..c0f5242b 100644
--- a/src/Datasource/Log/ElasticLogger.php
+++ b/src/Datasource/Log/ElasticLogger.php
@@ -34,12 +34,12 @@ class ElasticLogger extends AbstractLogger
/**
* Holds the logger instance
*/
- protected QueryLogger|LoggerInterface $_logger;
+ protected QueryLogger|LoggerInterface $logger;
/**
* Holds the connection instance
*/
- protected Connection $_connection;
+ protected Connection $connection;
/**
* Constructor, set the QueryLogger instance
@@ -50,7 +50,7 @@ class ElasticLogger extends AbstractLogger
public function __construct(QueryLogger|LoggerInterface $logger, Connection $connection)
{
$this->setLogger($logger);
- $this->_connection = $connection;
+ $this->connection = $connection;
}
/**
@@ -59,9 +59,9 @@ public function __construct(QueryLogger|LoggerInterface $logger, Connection $con
* @param \Cake\Database\Log\QueryLogger|\Psr\Log\LoggerInterface $logger Set logger instance to pass logging data to
* @return $this
*/
- public function setLogger(QueryLogger|LoggerInterface $logger)
+ public function setLogger(QueryLogger|LoggerInterface $logger): static
{
- $this->_logger = $logger;
+ $this->logger = $logger;
return $this;
}
@@ -71,7 +71,7 @@ public function setLogger(QueryLogger|LoggerInterface $logger)
*/
public function getLogger(): QueryLogger|LoggerInterface
{
- return $this->_logger;
+ return $this->logger;
}
/**
@@ -85,8 +85,8 @@ public function getLogger(): QueryLogger|LoggerInterface
*/
public function log(mixed $level, Stringable|string $message, array $context = []): void
{
- if ($this->_connection->isQueryLoggingEnabled() && $level === LogLevel::DEBUG) {
- $this->_log($level, (string)$message, $context);
+ if ($this->connection->isQueryLoggingEnabled() && $level === LogLevel::DEBUG) {
+ $this->logQuery($level, (string)$message, $context);
}
}
@@ -107,7 +107,7 @@ public function log(mixed $level, Stringable|string $message, array $context = [
* @param string $message The log message
* @param array $context log context
*/
- protected function _log(string $level, string $message, array $context = []): void
+ protected function logQuery(string $level, string $message, array $context = []): void
{
// Only process if we have request data
if (!isset($context['request']) || !is_array($context['request'])) {
diff --git a/src/Document.php b/src/Document.php
index 8b567a88..6de969c6 100644
--- a/src/Document.php
+++ b/src/Document.php
@@ -35,7 +35,7 @@ class Document implements EntityInterface, InvalidPropertyInterface
* from a search query. It can contain extra information about this document
* concerning the search operation, such as highlights, score and version.
*/
- protected Result $_result;
+ protected Result $searchResult;
/**
* Takes either an array or a Result object form a search and constructs
@@ -75,14 +75,20 @@ public function __construct(Result|array $data = [], array $options = [])
}
if ($options['result'] !== null) {
- $this->_result = $options['result'];
+ $this->searchResult = $options['result'];
}
if (count($data) > 0) {
$this->setOriginalField(array_keys($data));
if ($options['markClean'] && !$options['useSetters']) {
- $this->_fields = $data;
+ foreach ($data as $field => $value) {
+ $field = (string)$field;
+ $this->setRawValue($field, $value);
+ if (!array_key_exists($field, $this->dynamicFields)) {
+ $this->assignedProps[$field] = true;
+ }
+ }
return;
}
@@ -106,8 +112,8 @@ public function __construct(Result|array $data = [], array $options = [])
*/
public function index(): ?string
{
- if (isset($this->_result)) {
- return $this->_result->getIndex();
+ if (isset($this->searchResult)) {
+ return $this->searchResult->getIndex();
}
return null;
@@ -120,8 +126,8 @@ public function index(): ?string
*/
public function version(): int
{
- if (isset($this->_result)) {
- return intval($this->_result->getVersion());
+ if (isset($this->searchResult)) {
+ return intval($this->searchResult->getVersion());
}
return 1;
@@ -136,8 +142,8 @@ public function version(): int
*/
public function highlights(): array
{
- if (isset($this->_result)) {
- return $this->_result->getHighlights();
+ if (isset($this->searchResult)) {
+ return $this->searchResult->getHighlights();
}
return [];
@@ -151,8 +157,8 @@ public function highlights(): array
*/
public function explanation(): array
{
- if (isset($this->_result)) {
- return $this->_result->getExplanation();
+ if (isset($this->searchResult)) {
+ return $this->searchResult->getExplanation();
}
return [];
diff --git a/src/Exception/MissingDocumentException.php b/src/Exception/MissingDocumentException.php
index 1412c971..758a8af8 100644
--- a/src/Exception/MissingDocumentException.php
+++ b/src/Exception/MissingDocumentException.php
@@ -25,5 +25,5 @@
*/
class MissingDocumentException extends MissingEntityException
{
- protected string $_messageTemplate = 'Document class %s could not be found.';
+ protected string $messageTemplate = 'Document class %s could not be found.';
}
diff --git a/src/Exception/MissingIndexClassException.php b/src/Exception/MissingIndexClassException.php
index ea7cf53a..f0b65712 100644
--- a/src/Exception/MissingIndexClassException.php
+++ b/src/Exception/MissingIndexClassException.php
@@ -25,5 +25,5 @@
*/
class MissingIndexClassException extends CakeException
{
- protected string $_messageTemplate = 'Index class %s could not be found.';
+ protected string $messageTemplate = 'Index class %s could not be found.';
}
diff --git a/src/Exception/NotImplementedException.php b/src/Exception/NotImplementedException.php
index 5e34c21e..a1f7c79f 100644
--- a/src/Exception/NotImplementedException.php
+++ b/src/Exception/NotImplementedException.php
@@ -25,5 +25,5 @@
*/
class NotImplementedException extends CakeException
{
- protected string $_messageTemplate = 'Method %s has not been implemented in this context.';
+ protected string $messageTemplate = 'Method %s has not been implemented in this context.';
}
diff --git a/src/Index.php b/src/Index.php
index a0e44e3a..db28f60f 100644
--- a/src/Index.php
+++ b/src/Index.php
@@ -32,7 +32,6 @@
use Cake\Event\EventDispatcherTrait;
use Cake\Event\EventListenerInterface;
use Cake\Event\EventManager;
-use Cake\Event\EventManagerInterface;
use Cake\Utility\Inflector;
use Cake\Validation\ValidatorAwareTrait;
use Closure;
@@ -40,7 +39,6 @@
use InvalidArgumentException;
use Psr\SimpleCache\CacheInterface;
use RuntimeException;
-use function Cake\Core\deprecationWarning;
use function Cake\Core\namespaceSplit;
/**
@@ -48,14 +46,9 @@
*
* A index in elastic search is approximately equivalent to a table or collection
* in a relational datastore. This ODM maps each index to a class.
- *
- * @implements \Cake\Event\EventDispatcherInterface<\Cake\ORM\Table>
*/
class Index implements RepositoryInterface, EventListenerInterface, EventDispatcherInterface
{
- /**
- * @use \Cake\Event\EventDispatcherTrait<\Cake\ElasticSearch\Index>
- */
use EventDispatcherTrait;
use RulesAwareTrait;
use ValidatorAwareTrait;
@@ -84,24 +77,24 @@ class Index implements RepositoryInterface, EventListenerInterface, EventDispatc
/**
* Connection instance
*/
- protected Connection $_connection;
+ protected Connection $connection;
/**
* The name of the Elasticsearch index this class represents
*/
- protected string $_name;
+ protected string $name;
/**
* Registry key used to create this index object
*/
- protected string $_registryAlias;
+ protected string $registryAlias;
/**
* The name of the class that represent a single document for this type
*
* @var class-string<\Cake\ElasticSearch\Document>
*/
- protected string $_documentClass;
+ protected string $documentClass;
/**
* Collection of Embedded sub documents this type has.
@@ -146,11 +139,9 @@ public function __construct(array $config = [])
$eventManager = $config['eventManager'];
}
- $this->_eventManager = $eventManager ?: new EventManager();
+ $this->eventManager = $eventManager ?: new EventManager();
$this->initialize($config);
- if ($this->_eventManager instanceof EventManagerInterface) {
- $this->_eventManager->on($this);
- }
+ $this->eventManager->on($this);
$this->dispatchEvent('Model.initialize');
}
@@ -218,9 +209,9 @@ public function embedded(): array
* @param \Cake\ElasticSearch\Datasource\Connection $conn the new connection instance
* @return $this
*/
- public function setConnection(Connection $conn)
+ public function setConnection(Connection $conn): static
{
- $this->_connection = $conn;
+ $this->connection = $conn;
return $this;
}
@@ -230,7 +221,7 @@ public function setConnection(Connection $conn)
*/
public function getConnection(): Connection
{
- return $this->_connection;
+ return $this->connection;
}
/**
@@ -239,9 +230,9 @@ public function getConnection(): Connection
* @param string $registryAlias The key used to access this object.
* @return $this
*/
- public function setRegistryAlias(string $registryAlias)
+ public function setRegistryAlias(string $registryAlias): static
{
- $this->_registryAlias = $registryAlias;
+ $this->registryAlias = $registryAlias;
return $this;
}
@@ -251,11 +242,11 @@ public function setRegistryAlias(string $registryAlias)
*/
public function getRegistryAlias(): string
{
- if (!isset($this->_registryAlias)) {
- $this->_registryAlias = $this->getAlias();
+ if (!isset($this->registryAlias)) {
+ $this->registryAlias = $this->getAlias();
}
- return $this->_registryAlias;
+ return $this->registryAlias;
}
/**
@@ -264,9 +255,9 @@ public function getRegistryAlias(): string
* @param string $name Index name
* @return $this
*/
- public function setName(string $name)
+ public function setName(string $name): static
{
- $this->_name = $name;
+ $this->name = $name;
return $this;
}
@@ -278,13 +269,13 @@ public function setName(string $name)
*/
public function getName(): string
{
- if (!isset($this->_name)) {
+ if (!isset($this->name)) {
$name = namespaceSplit(static::class);
$name = substr(end($name), 0, -5);
- $this->_name = Inflector::underscore($name);
+ $this->name = Inflector::underscore($name);
}
- return $this->_name;
+ return $this->name;
}
/**
@@ -303,7 +294,7 @@ public function getTable(): string
* @param string $alias Index alias
* @return $this
*/
- public function setAlias(string $alias)
+ public function setAlias(string $alias): static
{
return $this->setName($alias);
}
@@ -364,18 +355,15 @@ public function callFinder(string $type, Query $query, mixed ...$args): Query
);
}
- // Handle backward compatibility for array-based options
- if (count($args) === 1 && isset($args[0]) && is_array($args[0])) {
- deprecationWarning(
- '5.0.0',
- 'Calling finder methods with options arrays is deprecated. ' .
- 'Use named arguments instead.',
- );
- $options = $args[0];
- $query->applyOptions($options);
- $options = $query->getOptions();
-
- return $this->{$finder}($query, $options);
+ // A single positional array used to be the legacy options array,
+ // removed in 6.0 in favor of named arguments.
+ if (count($args) === 1 && array_key_exists(0, $args) && is_array($args[0])) {
+ throw new InvalidArgumentException(sprintf(
+ 'Passing an options array to the "%s" finder is not supported. ' .
+ "Use named arguments instead, for example find('%s', limit: 10).",
+ $type,
+ $type,
+ ));
}
// Convert named arguments to options array for the finder method
@@ -593,8 +581,8 @@ public function saveMany(array $entities, array $options = []): bool
$esIndex->addDocuments($documents, $requestParams);
foreach ($documents as $key => $doc) {
- $entities[$key]->id = $doc->getId();
- $entities[$key]->_version = $doc->getVersion();
+ $entities[$key]->set('id', $doc->getId());
+ $entities[$key]->set('_version', $doc->getVersion());
$entities[$key]->setNew(false);
$entities[$key]->setSource($this->getRegistryAlias());
$entities[$key]->clean();
@@ -806,19 +794,19 @@ public function newEntities(array $data, array $options = []): array
*/
public function getEntityClass(): string
{
- if (!isset($this->_documentClass)) {
+ if (!isset($this->documentClass)) {
$default = Document::class;
$self = static::class;
$parts = explode('\\', $self);
if ($self === self::class || count($parts) < 3) {
- return $this->_documentClass = $default;
+ return $this->documentClass = $default;
}
$alias = Inflector::classify(Inflector::underscore(substr(array_pop($parts), 0, -5)));
$name = implode('\\', array_slice($parts, 0, -1)) . '\\Document\\' . $alias;
if (!class_exists($name)) {
- return $this->_documentClass = $default;
+ return $this->documentClass = $default;
}
/** @var class-string<\Cake\ElasticSearch\Document>|null $class */
@@ -828,10 +816,10 @@ public function getEntityClass(): string
}
/** @var class-string<\Cake\ElasticSearch\Document> $class */
- return $this->_documentClass = $class;
+ return $this->documentClass = $class;
}
- return $this->_documentClass;
+ return $this->documentClass;
}
/**
@@ -841,7 +829,7 @@ public function getEntityClass(): string
* @throws \Cake\ElasticSearch\Exception\MissingDocumentException when the entity class cannot be found
* @return $this
*/
- public function setEntityClass(string $name)
+ public function setEntityClass(string $name): static
{
$class = App::className($name, 'Model/Document');
if (!$class) {
@@ -849,7 +837,7 @@ public function setEntityClass(string $name)
}
/** @var class-string<\Cake\ElasticSearch\Document> $class */
- $this->_documentClass = $class;
+ $this->documentClass = $class;
return $this;
}
diff --git a/src/Marshaller.php b/src/Marshaller.php
index 6023508c..2445cdab 100644
--- a/src/Marshaller.php
+++ b/src/Marshaller.php
@@ -53,7 +53,7 @@ public function __construct(Index $index)
*
* - fieldList: A whitelist of fields to be assigned to the entity. If not present,
* the accessible fields list in the entity will be used.
- * - accessibleFields: A list of fields to allow or deny in entity accessible fields.
+ * - patchableFields: A list of fields to allow or deny in entity accessible fields.
* - associated: A list of embedded documents you want to marshal.
*
* @param array $data The data to hydrate.
@@ -63,17 +63,17 @@ public function one(array $data, array $options = []): Document
{
$options += ['associated' => []];
- [$data, $options] = $this->_prepareDataAndOptions($data, $options);
+ [$data, $options] = $this->prepareDataAndOptions($data, $options);
$entity = $this->index->newEmptyEntity();
assert($entity instanceof Document);
- if (isset($options['accessibleFields'])) {
- foreach ((array)$options['accessibleFields'] as $key => $value) {
- $entity->setAccess($key, $value);
+ if (isset($options['patchableFields'])) {
+ foreach ((array)$options['patchableFields'] as $key => $value) {
+ $entity->setPatchable($key, $value);
}
}
- $errors = $this->_validate($data, $options, true);
+ $errors = $this->validate($data, $options, true);
$entity->setErrors($errors);
$properties = [];
@@ -180,30 +180,30 @@ protected function mergeNested(Embedded $embed, Document|array|null $existing, a
$existing->patch($data);
return $existing;
- } else {
- if (!is_array($existing)) {
- $existing = [];
- }
+ }
- foreach ($existing as $i => $row) {
- if (isset($data[$i])) {
- $row->patch($data[$i]);
- }
+ if (!is_array($existing)) {
+ $existing = [];
+ }
- unset($data[$i]);
+ foreach ($existing as $i => $row) {
+ if (isset($data[$i])) {
+ $row->patch($data[$i]);
}
- foreach ($data as $row) {
- if (is_array($row)) {
- $new = $index->newEmptyEntity();
- assert($new instanceof Document);
- $new->patch($row);
- $existing[] = $new;
- }
- }
+ unset($data[$i]);
+ }
- return $existing;
+ foreach ($data as $row) {
+ if (is_array($row)) {
+ $new = $index->newEmptyEntity();
+ assert($new instanceof Document);
+ $new->patch($row);
+ $existing[] = $new;
+ }
}
+
+ return $existing;
}
/**
@@ -213,7 +213,7 @@ protected function mergeNested(Embedded $embed, Document|array|null $existing, a
*
* - fieldList: A whitelist of fields to be assigned to the entity. If not present,
* the accessible fields list in the entity will be used.
- * - accessibleFields: A list of fields to allow or deny in entity accessible fields.
+ * - patchableFields: A list of fields to allow or deny in entity accessible fields.
*
* @param array $data The data to hydrate.
* @param array $options List of options
@@ -250,10 +250,10 @@ public function many(array $data, array $options = []): array
public function merge(EntityInterface $entity, array $data, array $options = []): EntityInterface
{
$options += ['associated' => []];
- [$data, $options] = $this->_prepareDataAndOptions($data, $options);
+ [$data, $options] = $this->prepareDataAndOptions($data, $options);
$isNew = $entity->isNew();
- $errors = $this->_validate($data, $options, $isNew);
+ $errors = $this->validate($data, $options, $isNew);
$entity->setErrors($errors);
// Handle invalid fields
@@ -357,7 +357,7 @@ public function mergeMany(iterable $entities, array $data, array $options = []):
* @return array The list of validation errors.
* @throws \RuntimeException If no validator can be created.
*/
- protected function _validate(array $data, array $options, bool $isNew): array
+ protected function validate(array $data, array $options, bool $isNew): array
{
if (!$options['validate']) {
return [];
@@ -390,7 +390,7 @@ protected function _validate(array $data, array $options, bool $isNew): array
* @param array $options The options passed to this marshaller.
* @return array An array containing prepared data and options.
*/
- protected function _prepareDataAndOptions(array $data, array $options): array
+ protected function prepareDataAndOptions(array $data, array $options): array
{
$options += ['validate' => true];
$data = new ArrayObject($data);
diff --git a/src/Query.php b/src/Query.php
index acebfe78..0100e054 100644
--- a/src/Query.php
+++ b/src/Query.php
@@ -28,6 +28,7 @@
use Elastica\Collapse;
use Elastica\Query as ElasticaQuery;
use Elastica\Query\AbstractQuery;
+use Elastica\Query\BoolQuery;
use InvalidArgumentException;
use IteratorAggregate;
use Psr\SimpleCache\CacheInterface;
@@ -67,13 +68,13 @@ class Query implements IteratorAggregate, QueryInterface
*
* @var \Elastica\Query
*/
- protected ElasticaQuery $_elasticQuery;
+ protected ElasticaQuery $elasticQuery;
/**
* The various query builder parts that will
* be transferred to the elastica query.
*/
- protected array $_queryParts = [
+ protected array $queryParts = [
'fields' => [],
'limit' => null,
'offset' => null,
@@ -90,19 +91,19 @@ class Query implements IteratorAggregate, QueryInterface
/**
* Internal state to track whether or not the query has been modified.
*/
- protected bool $_dirty = false;
+ protected bool $dirty = false;
/**
* Additional options for Elastica\Index::search()
*
* @see \Elastica\Search::OPTION_SEARCH_* constants
*/
- protected array $_searchOptions = [];
+ protected array $searchOptions = [];
/**
* Instance of a repository object this query is bound to.
*/
- protected Index $_repository;
+ protected Index $repository;
/**
* A ResultSet.
@@ -111,13 +112,13 @@ class Query implements IteratorAggregate, QueryInterface
*
* @see \Cake\Datasource\QueryTrait::setResult()
*/
- protected ?iterable $_results = null;
+ protected ?iterable $results = null;
/**
* List of map-reduce routines that should be applied over the query
* result
*/
- protected array $_mapReduce = [];
+ protected array $mapReduce = [];
/**
* List of formatter classes or callbacks that will post-process the
@@ -125,18 +126,18 @@ class Query implements IteratorAggregate, QueryInterface
*
* @var array<\Closure>
*/
- protected array $_formatters = [];
+ protected array $formatters = [];
/**
* A query cacher instance if this query has caching enabled.
*/
- protected ?QueryCacher $_cache = null;
+ protected ?QueryCacher $cache = null;
/**
* Holds any custom options passed using applyOptions that could not be processed
* by any method in this class.
*/
- protected array $_options = [];
+ protected array $options = [];
/**
* Query constructor
@@ -146,7 +147,7 @@ class Query implements IteratorAggregate, QueryInterface
public function __construct(Index $repository)
{
$this->setRepository($repository);
- $this->_elasticQuery = new ElasticaQuery();
+ $this->elasticQuery = new ElasticaQuery();
}
/**
@@ -162,10 +163,10 @@ public function __construct(Index $repository)
* @param bool $overwrite Whether or not to replace previous selections.
* @return $this
*/
- public function select(Closure|array|string|int|float $fields, bool $overwrite = false)
+ public function select(Closure|array|string|int|float $fields, bool $overwrite = false): static
{
if (!$overwrite) {
- $currentFields = $this->_queryParts['fields'];
+ $currentFields = $this->queryParts['fields'];
if (!is_array($currentFields)) {
$currentFields = [];
}
@@ -177,7 +178,7 @@ public function select(Closure|array|string|int|float $fields, bool $overwrite =
$fields = array_merge($currentFields, $fields);
}
- $this->_queryParts['fields'] = $fields;
+ $this->queryParts['fields'] = $fields;
return $this;
}
@@ -189,9 +190,9 @@ public function select(Closure|array|string|int|float $fields, bool $overwrite =
* @param ?int $limit The number of documents to return.
* @return $this
*/
- public function limit(?int $limit)
+ public function limit(?int $limit): static
{
- $this->_queryParts['limit'] = (int)$limit;
+ $this->queryParts['limit'] = (int)$limit;
return $this;
}
@@ -203,9 +204,9 @@ public function limit(?int $limit)
* @param ?int $offset The number of records to be skipped
* @return $this
*/
- public function offset(?int $offset)
+ public function offset(?int $offset): static
{
- $this->_queryParts['offset'] = (int)$offset;
+ $this->queryParts['offset'] = (int)$offset;
return $this;
}
@@ -224,7 +225,7 @@ public function offset(?int $offset)
* the current limit clause will be used.
* @return $this
*/
- public function page(int $num, ?int $limit = null)
+ public function page(int $num, ?int $limit = null): static
{
if ($limit !== null) {
$this->limit($limit);
@@ -268,7 +269,7 @@ public function page(int $num, ?int $limit = null)
*/
public function clause(string $name): mixed
{
- return $this->_queryParts[$name];
+ return $this->queryParts[$name];
}
/**
@@ -283,36 +284,17 @@ public function clause(string $name): mixed
* @param \Closure|array|string $fields The sorting order to use.
* @param bool $overwrite Whether or not to replace previous sorting.
* @return $this
- * @deprecated 5.0.0 Use orderBy() instead now that CollectionInterface methods are no longer proxied.
*/
- public function order(Closure|array|string $fields, bool $overwrite = false)
- {
- return $this->orderBy($fields, $overwrite);
- }
-
- /**
- * Sets the sorting options for the result set.
- *
- * The accepted format for the $order parameter is:
- *
- * - [['name' => ['order'=> 'asc', ...]], ['price' => ['order'=> 'asc', ...]]]
- * - ['name' => 'asc', 'price' => 'desc']
- * - 'field1' (defaults to order => 'desc')
- *
- * @param \Closure|array|string $fields The sorting order to use.
- * @param bool $overwrite Whether or not to replace previous sorting.
- * @return $this
- */
- public function orderBy(array|Closure|string $fields, bool $overwrite = false)
+ public function orderBy(array|Closure|string $fields, bool $overwrite = false): static
{
if (is_array($fields) && is_numeric(key($fields))) {
if ($overwrite) {
- $this->_queryParts['order'] = $fields;
+ $this->queryParts['order'] = $fields;
return $this;
}
- $this->_queryParts['order'] = array_merge($fields, $this->_queryParts['order']);
+ $this->queryParts['order'] = array_merge($fields, $this->queryParts['order']);
return $this;
}
@@ -337,10 +319,10 @@ public function orderBy(array|Closure|string $fields, bool $overwrite = false)
$fields = collection($fields)->map($normalizer)->toList();
if (!$overwrite) {
- $fields = array_merge($this->_queryParts['order'], $fields);
+ $fields = array_merge($this->queryParts['order'], $fields);
}
- $this->_queryParts['order'] = $fields;
+ $this->queryParts['order'] = $fields;
return $this; // [['field' => [...]], ['field2' => [...]]]
}
@@ -355,7 +337,7 @@ public function orderBy(array|Closure|string $fields, bool $overwrite = false)
*/
public function find(string $finder, mixed ...$args): static
{
- return $this->_repository->callFinder($finder, $this, ...$args);
+ return $this->repository->callFinder($finder, $this, ...$args);
}
/**
@@ -408,13 +390,13 @@ public function where(
Closure|array|string|null $conditions = null,
array $types = [],
bool $overwrite = false,
- ) {
+ ): static {
// Convert string conditions to proper format for _buildBoolQuery
if (is_string($conditions)) {
$conditions = [$conditions];
}
- return $this->_buildBoolQuery('filter', $conditions, $overwrite);
+ return $this->buildBoolQuery('filter', $conditions, $overwrite);
}
/**
@@ -467,15 +449,19 @@ public function where(
*
* `WHERE (title = 'Foo') AND (author_id = 1 OR author_id = 2)`
*
- * @param \Elastica\Query\AbstractQuery|callable|array|null $conditions The list of conditions.
+ * @param \Elastica\Query\AbstractQuery|\Closure|array|string|null $conditions The list of conditions.
* @param array $types Not used, required to comply with QueryInterface.
* @see \Cake\ElasticSearch\Query::where()
* @see \Cake\ElasticSearch\QueryBuilder
* @return $this
*/
- public function andWhere(array|callable|AbstractQuery|null $conditions, array $types = [])
+ public function andWhere(array|Closure|AbstractQuery|string|null $conditions, array $types = []): static
{
- return $this->_buildBoolQuery('filter', $conditions, false, 'addMust');
+ if (is_string($conditions)) {
+ $conditions = [$conditions];
+ }
+
+ return $this->buildBoolQuery('filter', $conditions, false, 'addMust');
}
/**
@@ -485,13 +471,13 @@ public function andWhere(array|callable|AbstractQuery|null $conditions, array $t
* This method can be used in the same way the `where()` method is used. Please refer to
* its documentation for more details.
*
- * @param \Elastica\Query\AbstractQuery|callable|array $conditions The list of conditions
+ * @param \Elastica\Query\AbstractQuery|\Closure|array $conditions The list of conditions
* @param bool $overwrite Whether or not to replace previous queries.
* @return $this
*/
- public function queryMust(array|callable|AbstractQuery $conditions, bool $overwrite = false)
+ public function queryMust(array|Closure|AbstractQuery $conditions, bool $overwrite = false): static
{
- return $this->_buildBoolQuery('query', $conditions, $overwrite);
+ return $this->buildBoolQuery('query', $conditions, $overwrite);
}
/**
@@ -501,13 +487,13 @@ public function queryMust(array|callable|AbstractQuery $conditions, bool $overwr
* This method can be used in the same way the `where()` method is used. Please refer to
* its documentation for more details.
*
- * @param \Elastica\Query\AbstractQuery|callable|array $conditions The list of conditions
+ * @param \Elastica\Query\AbstractQuery|\Closure|array $conditions The list of conditions
* @param bool $overwrite Whether or not to replace previous queries.
* @return $this
*/
- public function queryShould(array|callable|AbstractQuery $conditions, bool $overwrite = false)
+ public function queryShould(array|Closure|AbstractQuery $conditions, bool $overwrite = false): static
{
- return $this->_buildBoolQuery('query', $conditions, $overwrite, 'addShould');
+ return $this->buildBoolQuery('query', $conditions, $overwrite, 'addShould');
}
/**
@@ -517,14 +503,14 @@ public function queryShould(array|callable|AbstractQuery $conditions, bool $over
* This method can be used in the same way the `where()` method is used. Please refer to
* its documentation for more details.
*
- * @param \Elastica\Query\AbstractQuery|callable|array $conditions The list of conditions.
+ * @param \Elastica\Query\AbstractQuery|\Closure|array $conditions The list of conditions.
* @param bool $overwrite Whether or not to replace previous filters.
* @return $this
* @see \Cake\ElasticSearch\Query::where()
*/
- public function postFilter(array|callable|AbstractQuery $conditions, bool $overwrite = false)
+ public function postFilter(array|Closure|AbstractQuery $conditions, bool $overwrite = false): static
{
- return $this->_buildBoolQuery('postFilter', $conditions, $overwrite);
+ return $this->buildBoolQuery('postFilter', $conditions, $overwrite);
}
/**
@@ -533,9 +519,9 @@ public function postFilter(array|callable|AbstractQuery $conditions, bool $overw
* @param \Elastica\Query\AbstractQuery $query Set the query
* @return $this
*/
- public function setFullQuery(AbstractQuery $query)
+ public function setFullQuery(AbstractQuery $query): static
{
- $this->_queryParts['query'] = $query;
+ $this->queryParts['query'] = $query;
return $this;
}
@@ -546,13 +532,13 @@ public function setFullQuery(AbstractQuery $query)
* @param \Elastica\Collapse|string $collapse Collapse field or elastic collapse object
* @return $this
*/
- public function collapse(Collapse|string $collapse)
+ public function collapse(Collapse|string $collapse): static
{
if (is_string($collapse)) {
$collapse = (new Collapse())->setFieldname($collapse);
}
- $this->_queryParts['collapse'] = $collapse;
+ $this->queryParts['collapse'] = $collapse;
return $this;
}
@@ -563,14 +549,14 @@ public function collapse(Collapse|string $collapse)
* @param \Elastica\Aggregation\AbstractAggregation|array $aggregation One or multiple facets
* @return $this
*/
- public function aggregate(AbstractAggregation|array $aggregation)
+ public function aggregate(AbstractAggregation|array $aggregation): static
{
if (is_array($aggregation)) {
foreach ($aggregation as $aggregationItem) {
$this->aggregate($aggregationItem);
}
} else {
- $this->_queryParts['aggregations'][] = $aggregation;
+ $this->queryParts['aggregations'][] = $aggregation;
}
return $this;
@@ -584,10 +570,10 @@ public function aggregate(AbstractAggregation|array $aggregation)
public function searchOptions(?array $options = null): array|self
{
if ($options === null) {
- return $this->_searchOptions;
+ return $this->searchOptions;
}
- $this->_searchOptions = $options;
+ $this->searchOptions = $options;
return $this;
}
@@ -597,19 +583,19 @@ public function searchOptions(?array $options = null): array|self
* variable.
*
* @param string $partType The name of the part in which the bool query will be stored
- * @param \Elastica\Query\AbstractQuery|callable|array $conditions The list of conditions.
+ * @param \Elastica\Query\AbstractQuery|\Closure|array $conditions The list of conditions.
* @param bool $overwrite Whether or not to replace previous query.
* @param string $type The method to use for appending the conditions to the Query
* @return $this
*/
- protected function _buildBoolQuery(
+ protected function buildBoolQuery(
string $partType,
- AbstractQuery|callable|array|null $conditions,
+ AbstractQuery|Closure|array|null $conditions,
bool $overwrite,
string $type = 'addMust',
- ) {
- if (!isset($this->_queryParts[$partType]) || $overwrite) {
- $this->_queryParts[$partType] = new ElasticaQuery\BoolQuery();
+ ): static {
+ if (!isset($this->queryParts[$partType]) || $overwrite) {
+ $this->queryParts[$partType] = new BoolQuery();
}
if ($conditions === null) {
@@ -617,13 +603,13 @@ protected function _buildBoolQuery(
}
if ($conditions instanceof AbstractQuery) {
- $this->_queryParts[$partType]->{$type}($conditions);
+ $this->queryParts[$partType]->{$type}($conditions);
return $this;
}
- if (is_callable($conditions)) {
- $conditions = $conditions(new QueryBuilder(), $this->_queryParts[$partType], $this);
+ if ($conditions instanceof Closure) {
+ $conditions = $conditions(new QueryBuilder(), $this->queryParts[$partType], $this);
}
if ($conditions === null) {
@@ -634,14 +620,14 @@ protected function _buildBoolQuery(
$conditions = (new QueryBuilder())->parse($conditions);
if (is_array($conditions)) {
foreach ($conditions as $condition) {
- $this->_queryParts[$partType]->{$type}($condition);
+ $this->queryParts[$partType]->{$type}($condition);
}
}
return $this;
}
- $this->_queryParts[$partType]->{$type}($conditions);
+ $this->queryParts[$partType]->{$type}($conditions);
return $this;
}
@@ -652,7 +638,7 @@ protected function _buildBoolQuery(
*
* - fields: Maps to the select method
* - conditions: Maps to the where method
- * - order: Maps to the order method
+ * - order: Maps to the orderBy method
* - limit: Maps to the limit method
* - offset: Maps to the offset method
* - page: Maps to the page method
@@ -681,12 +667,12 @@ protected function _buildBoolQuery(
* @param array $options list of query clauses to apply new parts to.
* @return $this
*/
- public function applyOptions(array $options)
+ public function applyOptions(array $options): static
{
$valid = [
'fields' => 'select',
'conditions' => 'where',
- 'order' => 'order',
+ 'order' => 'orderBy',
'limit' => 'limit',
'offset' => 'offset',
'page' => 'page',
@@ -697,7 +683,7 @@ public function applyOptions(array $options)
if (isset($valid[$option]) && isset($values)) {
$this->{$valid[$option]}($values);
} else {
- $this->_options[$option] = $values;
+ $this->options[$option] = $values;
}
}
@@ -710,9 +696,9 @@ public function applyOptions(array $options)
* @param array $highlight The highlight options to use.
* @return $this
*/
- public function highlight(array $highlight)
+ public function highlight(array $highlight): static
{
- $this->_queryParts['highlight'] = $highlight;
+ $this->queryParts['highlight'] = $highlight;
return $this;
}
@@ -724,9 +710,9 @@ public function highlight(array $highlight)
* @param float $score The minimum score to observe
* @return $this
*/
- public function withMinScore(float $score)
+ public function withMinScore(float $score): static
{
- $this->_elasticQuery->setMinScore($score);
+ $this->elasticQuery->setMinScore($score);
return $this;
}
@@ -745,7 +731,7 @@ public function withMinScore(float $score)
* @throws \InvalidArgumentException When a negative integer value is provided
* @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-body.html#request-body-search-track-total-hits
*/
- public function trackTotalHits(int|bool|null $trackTotalHits)
+ public function trackTotalHits(int|bool|null $trackTotalHits): static
{
if (is_int($trackTotalHits) && $trackTotalHits < 0) {
throw new InvalidArgumentException(
@@ -753,8 +739,8 @@ public function trackTotalHits(int|bool|null $trackTotalHits)
);
}
- $this->_queryParts['trackTotalHits'] = $trackTotalHits;
- $this->_dirty = true;
+ $this->queryParts['trackTotalHits'] = $trackTotalHits;
+ $this->dirty = true;
return $this;
}
@@ -764,15 +750,15 @@ public function trackTotalHits(int|bool|null $trackTotalHits)
*
* @return \Cake\ElasticSearch\ResultSet The results of the query
*/
- protected function _execute(): ResultSetInterface
+ protected function execute(): ResultSetInterface
{
- $connection = $this->_repository->getConnection();
- $index = $this->_repository->getName();
+ $connection = $this->repository->getConnection();
+ $index = $this->repository->getName();
$esIndex = $connection->getIndex($index);
$query = $this->compileQuery();
- return new ResultSet($esIndex->search($query, $this->_searchOptions), $this);
+ return new ResultSet($esIndex->search($query, $this->searchOptions), $this);
}
/**
@@ -782,58 +768,58 @@ protected function _execute(): ResultSetInterface
*/
public function compileQuery(): ElasticaQuery
{
- if ($this->_queryParts['fields']) {
- $this->_elasticQuery->setSource($this->_queryParts['fields']);
+ if ($this->queryParts['fields']) {
+ $this->elasticQuery->setSource($this->queryParts['fields']);
}
- if (isset($this->_queryParts['limit'])) {
- $this->_elasticQuery->setSize($this->_queryParts['limit']);
+ if (isset($this->queryParts['limit'])) {
+ $this->elasticQuery->setSize($this->queryParts['limit']);
}
- if (isset($this->_queryParts['offset'])) {
- $this->_elasticQuery->setFrom($this->_queryParts['offset']);
+ if (isset($this->queryParts['offset'])) {
+ $this->elasticQuery->setFrom($this->queryParts['offset']);
}
- if ($this->_queryParts['order']) {
- $this->_elasticQuery->setSort($this->_queryParts['order']);
+ if ($this->queryParts['order']) {
+ $this->elasticQuery->setSort($this->queryParts['order']);
}
- if ($this->_queryParts['highlight']) {
- $this->_elasticQuery->setHighlight($this->_queryParts['highlight']);
+ if ($this->queryParts['highlight']) {
+ $this->elasticQuery->setHighlight($this->queryParts['highlight']);
}
- if ($this->_queryParts['collapse']) {
- $this->_elasticQuery->setCollapse($this->_queryParts['collapse']);
+ if ($this->queryParts['collapse']) {
+ $this->elasticQuery->setCollapse($this->queryParts['collapse']);
}
- if ($this->_queryParts['aggregations']) {
- foreach ($this->_queryParts['aggregations'] as $aggregation) {
- $this->_elasticQuery->addAggregation($aggregation);
+ if ($this->queryParts['aggregations']) {
+ foreach ($this->queryParts['aggregations'] as $aggregation) {
+ $this->elasticQuery->addAggregation($aggregation);
}
}
- if ($this->_queryParts['trackTotalHits'] !== null) {
- $this->_elasticQuery->setTrackTotalHits($this->_queryParts['trackTotalHits']);
+ if ($this->queryParts['trackTotalHits'] !== null) {
+ $this->elasticQuery->setTrackTotalHits($this->queryParts['trackTotalHits']);
}
- if (!isset($this->_queryParts['query'])) {
- $this->_queryParts['query'] = new ElasticaQuery\BoolQuery();
+ if (!isset($this->queryParts['query'])) {
+ $this->queryParts['query'] = new BoolQuery();
}
/** @var \Elastica\Query\AbstractQuery $query */
- $query = clone $this->_queryParts['query'];
+ $query = clone $this->queryParts['query'];
- if ($query instanceof ElasticaQuery\BoolQuery && isset($this->_queryParts['filter'])) {
- $query->addFilter($this->_queryParts['filter']);
+ if ($query instanceof BoolQuery && isset($this->queryParts['filter'])) {
+ $query->addFilter($this->queryParts['filter']);
}
- if (isset($this->_queryParts['postFilter'])) {
- $this->_elasticQuery->setPostFilter($this->_queryParts['postFilter']);
+ if (isset($this->queryParts['postFilter'])) {
+ $this->elasticQuery->setPostFilter($this->queryParts['postFilter']);
}
- $this->_elasticQuery->setQuery($query);
+ $this->elasticQuery->setQuery($query);
- return $this->_elasticQuery;
+ return $this->elasticQuery;
}
/**
@@ -867,8 +853,8 @@ public function aliasFields(array $fields, ?string $defaultAlias = null): array
*/
public function count(): int
{
- $connection = $this->_repository->getConnection();
- $index = $this->_repository->getName();
+ $connection = $this->repository->getConnection();
+ $index = $this->repository->getName();
$esIndex = $connection->getIndex($index);
$query = clone $this->compileQuery();
@@ -884,10 +870,10 @@ public function count(): int
* @param \Cake\Datasource\RepositoryInterface $repository The default repository object to use.
* @return $this
*/
- public function setRepository(RepositoryInterface $repository)
+ public function setRepository(RepositoryInterface $repository): static
{
assert($repository instanceof Index, 'ElasticSearch\Query requires an Index subclass');
- $this->_repository = $repository;
+ $this->repository = $repository;
return $this;
}
@@ -898,7 +884,7 @@ public function setRepository(RepositoryInterface $repository)
*/
public function getRepository(): Index
{
- return $this->_repository;
+ return $this->repository;
}
/**
@@ -948,15 +934,15 @@ public function getIterator(): Traversable
* a cache engine instance.
* @return $this
*/
- public function cache(Closure|string|false $key, CacheInterface|string $config = 'default')
+ public function cache(Closure|string|false $key, CacheInterface|string $config = 'default'): static
{
if ($key === false) {
- $this->_cache = null;
+ $this->cache = null;
return $this;
}
- $this->_cache = new QueryCacher($key, $config);
+ $this->cache = new QueryCacher($key, $config);
return $this;
}
@@ -976,29 +962,29 @@ public function cache(Closure|string|false $key, CacheInterface|string $config =
*/
public function all(): ResultSetInterface
{
- if ($this->_results !== null) {
- if (!($this->_results instanceof ResultSetInterface)) {
- $this->_results = $this->decorateResults($this->_results);
+ if ($this->results !== null) {
+ if (!($this->results instanceof ResultSetInterface)) {
+ $this->results = $this->decorateResults($this->results);
}
- return $this->_results;
+ return $this->results;
}
$results = null;
- if ($this->_cache instanceof QueryCacher) {
- $results = $this->_cache->fetch($this);
+ if ($this->cache instanceof QueryCacher) {
+ $results = $this->cache->fetch($this);
}
if ($results === null) {
- $results = $this->decorateResults($this->_execute());
- if ($this->_cache instanceof QueryCacher) {
- $this->_cache->store($this, $results);
+ $results = $this->decorateResults($this->execute());
+ if ($this->cache instanceof QueryCacher) {
+ $this->cache->store($this, $results);
}
}
- $this->_results = $results;
+ $this->results = $results;
- return $this->_results;
+ return $this->results;
}
/**
@@ -1024,10 +1010,10 @@ public function toArray(): array
* @return $this
* @see \Cake\Collection\Iterator\MapReduce for details on how to use emit data to the map reducer.
*/
- public function mapReduce(?Closure $mapper = null, ?Closure $reducer = null, bool $overwrite = false)
+ public function mapReduce(?Closure $mapper = null, ?Closure $reducer = null, bool $overwrite = false): static
{
if ($overwrite) {
- $this->_mapReduce = [];
+ $this->mapReduce = [];
}
if (!$mapper instanceof Closure) {
@@ -1038,7 +1024,7 @@ public function mapReduce(?Closure $mapper = null, ?Closure $reducer = null, boo
return $this;
}
- $this->_mapReduce[] = ['mapper' => $mapper, 'reducer' => $reducer];
+ $this->mapReduce[] = ['mapper' => $mapper, 'reducer' => $reducer];
return $this;
}
@@ -1048,7 +1034,7 @@ public function mapReduce(?Closure $mapper = null, ?Closure $reducer = null, boo
*/
public function getMapReducers(): array
{
- return $this->_mapReduce;
+ return $this->mapReduce;
}
/**
@@ -1094,10 +1080,10 @@ public function getMapReducers(): array
* @return $this
* @throws \InvalidArgumentException
*/
- public function formatResults(?Closure $formatter = null, int|bool $mode = self::APPEND)
+ public function formatResults(?Closure $formatter = null, int|bool $mode = self::APPEND): static
{
if ($mode === self::OVERWRITE) {
- $this->_formatters = [];
+ $this->formatters = [];
}
if (!$formatter instanceof Closure) {
@@ -1109,12 +1095,12 @@ public function formatResults(?Closure $formatter = null, int|bool $mode = self:
}
if ($mode === self::PREPEND) {
- array_unshift($this->_formatters, $formatter);
+ array_unshift($this->formatters, $formatter);
return $this;
}
- $this->_formatters[] = $formatter;
+ $this->formatters[] = $formatter;
return $this;
}
@@ -1126,7 +1112,7 @@ public function formatResults(?Closure $formatter = null, int|bool $mode = self:
*/
public function getResultFormatters(): array
{
- return $this->_formatters;
+ return $this->formatters;
}
/**
@@ -1143,7 +1129,7 @@ public function getResultFormatters(): array
*/
public function first(): mixed
{
- if ($this->_dirty) {
+ if ($this->dirty) {
$this->limit(1);
}
@@ -1187,7 +1173,7 @@ public function firstOrFail(): mixed
*/
public function getOptions(): array
{
- return $this->_options;
+ return $this->options;
}
/**
@@ -1199,8 +1185,8 @@ protected function decorateResults(iterable $result): ResultSetInterface
{
$decorator = $this->decoratorClass();
- if ($this->_mapReduce !== []) {
- foreach ($this->_mapReduce as $functions) {
+ if ($this->mapReduce !== []) {
+ foreach ($this->mapReduce as $functions) {
$result = new MapReduce($result, $functions['mapper'], $functions['reducer']);
}
@@ -1211,8 +1197,8 @@ protected function decorateResults(iterable $result): ResultSetInterface
$result = new $decorator($result);
}
- if ($this->_formatters !== []) {
- foreach ($this->_formatters as $formatter) {
+ if ($this->formatters !== []) {
+ foreach ($this->formatters as $formatter) {
$result = $formatter($result, $this);
}
diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php
index e5c636e2..36460c99 100644
--- a/src/QueryBuilder.php
+++ b/src/QueryBuilder.php
@@ -3,7 +3,6 @@
namespace Cake\ElasticSearch;
-use Elastica;
use Elastica\Query;
use Elastica\Query\AbstractQuery;
use Elastica\Query\BoolQuery;
@@ -56,7 +55,7 @@ public function between(string $field, mixed $from, mixed $to): Range
*/
public function bool(): BoolQuery
{
- return new Elastica\Query\BoolQuery();
+ return new BoolQuery();
}
/**
@@ -68,7 +67,7 @@ public function bool(): BoolQuery
*/
public function exists(string $field): Exists
{
- return new Elastica\Query\Exists($field);
+ return new Exists($field);
}
/**
@@ -96,7 +95,7 @@ public function exists(string $field): Exists
*/
public function geoBoundingBox(string $field, array|string $topLeft, array|string $bottomRight): GeoBoundingBox
{
- return new Elastica\Query\GeoBoundingBox($field, [$topLeft, $bottomRight]);
+ return new GeoBoundingBox($field, [$topLeft, $bottomRight]);
}
/**
@@ -118,7 +117,7 @@ public function geoBoundingBox(string $field, array|string $topLeft, array|strin
*/
public function geoDistance(string $field, array|string $location, string $distance): GeoDistance
{
- return new Elastica\Query\GeoDistance($field, $location, $distance);
+ return new GeoDistance($field, $location, $distance);
}
/**
@@ -147,7 +146,7 @@ public function geoDistance(string $field, array|string $location, string $dista
*/
public function geoPolygon(string $field, array $geoPoints): GeoPolygon
{
- return new Elastica\Query\GeoPolygon($field, $geoPoints);
+ return new GeoPolygon($field, $geoPoints);
}
/**
@@ -176,9 +175,9 @@ public function geoPolygon(string $field, array $geoPoints): GeoPolygon
public function geoShape(
string $field,
array $geoPoints,
- string $type = Elastica\Query\GeoShapeProvided::TYPE_ENVELOPE,
+ string $type = GeoShapeProvided::TYPE_ENVELOPE,
): GeoShapeProvided {
- return new Elastica\Query\GeoShapeProvided($field, $geoPoints, $type);
+ return new GeoShapeProvided($field, $geoPoints, $type);
}
/**
@@ -203,7 +202,7 @@ public function geoShapeIndex(
string $index = 'shapes',
string $path = 'shape',
): GeoShapePreIndexed {
- return new Elastica\Query\GeoShapePreIndexed($field, $id, $index, $path);
+ return new GeoShapePreIndexed($field, $id, $index, $path);
}
/**
@@ -242,7 +241,7 @@ public function gte(string $field, mixed $value): Range
*/
public function hasChild(Query|AbstractQuery|string $query, string $type): HasChild
{
- return new Elastica\Query\HasChild($query, $type);
+ return new HasChild($query, $type);
}
/**
@@ -254,7 +253,7 @@ public function hasChild(Query|AbstractQuery|string $query, string $type): HasCh
*/
public function hasParent(Query|AbstractQuery|string $query, string $type): HasParent
{
- return new Elastica\Query\HasParent($query, $type);
+ return new HasParent($query, $type);
}
/**
@@ -265,7 +264,7 @@ public function hasParent(Query|AbstractQuery|string $query, string $type): HasP
*/
public function ids(array $ids = []): Ids
{
- return new Elastica\Query\Ids($ids);
+ return new Ids($ids);
}
/**
@@ -276,7 +275,7 @@ public function ids(array $ids = []): Ids
*/
public function limit(int $limit): Limit
{
- return new Elastica\Query\Limit($limit);
+ return new Limit($limit);
}
/**
@@ -286,7 +285,7 @@ public function limit(int $limit): Limit
*/
public function matchAll(): MatchAll
{
- return new Elastica\Query\MatchAll();
+ return new MatchAll();
}
/**
@@ -330,7 +329,7 @@ public function lte(string $field, mixed $value): Range
*/
public function nested(string $path, AbstractQuery $query): Nested
{
- $nested = new Elastica\Query\Nested();
+ $nested = new Nested();
$nested->setPath($path);
$nested->setQuery($query);
@@ -346,7 +345,7 @@ public function nested(string $path, AbstractQuery $query): Nested
*/
public function not(AbstractQuery|array $query): BoolQuery
{
- $boolQuery = new Elastica\Query\BoolQuery();
+ $boolQuery = new BoolQuery();
$boolQuery->addMustNot($query);
return $boolQuery;
@@ -363,7 +362,7 @@ public function not(AbstractQuery|array $query): BoolQuery
*/
public function prefix(string $field, string $prefix, float $boost = 1.0): Prefix
{
- $prefixQuery = new Elastica\Query\Prefix();
+ $prefixQuery = new Prefix();
$prefixQuery->setPrefix($field, $prefix, $boost);
return $prefixQuery;
@@ -386,7 +385,7 @@ public function prefix(string $field, string $prefix, float $boost = 1.0): Prefi
*/
public function range(string $field, array $args): Range
{
- return new Elastica\Query\Range($field, $args);
+ return new Range($field, $args);
}
/**
@@ -405,7 +404,7 @@ public function range(string $field, array $args): Range
*/
public function regexp(string $field, string $regexp, float $boost = 1.0): Regexp
{
- return new Elastica\Query\Regexp($field, $regexp, $boost);
+ return new Regexp($field, $regexp, $boost);
}
/**
@@ -422,7 +421,7 @@ public function regexp(string $field, string $regexp, float $boost = 1.0): Regex
*/
public function script(AbstractScript|array|string $script): Script
{
- return new Elastica\Query\Script($script);
+ return new Script($script);
}
/**
@@ -440,7 +439,7 @@ public function script(AbstractScript|array|string $script): Script
*/
public function simpleQueryString(array|string $fields, string $string): SimpleQueryString
{
- return new Elastica\Query\SimpleQueryString($string, (array)$fields);
+ return new SimpleQueryString($string, (array)$fields);
}
/**
@@ -458,7 +457,7 @@ public function simpleQueryString(array|string $fields, string $string): SimpleQ
*/
public function match(string $field, string $value): MatchQuery
{
- return new Elastica\Query\MatchQuery($field, $value);
+ return new MatchQuery($field, $value);
}
/**
@@ -476,7 +475,7 @@ public function match(string $field, string $value): MatchQuery
*/
public function term(string $field, string|float|int|bool $value): Term
{
- return new Elastica\Query\Term([$field => $value]);
+ return new Term([$field => $value]);
}
/**
@@ -502,7 +501,7 @@ public function terms(string $field, array $values): Terms
}
}
- return new Elastica\Query\Terms($field, $scalarValues);
+ return new Terms($field, $scalarValues);
}
/**
@@ -701,7 +700,7 @@ public function parse(array|AbstractQuery $conditions): AbstractQuery|array
continue;
}
- $result[] = $this->_parseQuery($k, $c);
+ $result[] = $this->parseQuery($k, $c);
}
return $result;
@@ -713,7 +712,7 @@ public function parse(array|AbstractQuery $conditions): AbstractQuery|array
* @param string $field The filed name containing the operator
* @param mixed $value The value to pass to the query
*/
- protected function _parseQuery(string $field, mixed $value): AbstractQuery
+ protected function parseQuery(string $field, mixed $value): AbstractQuery
{
$operator = '=';
$parts = explode(' ', trim($field), 2);
@@ -740,7 +739,7 @@ protected function _parseQuery(string $field, mixed $value): AbstractQuery
return $this->lte($field, $value);
}
- if (in_array($operator, ['in', 'not in'])) {
+ if (in_array($operator, ['in', 'not in'], true)) {
$value = (array)$value;
}
diff --git a/src/Rule/IsUnique.php b/src/Rule/IsUnique.php
index 9f8406af..94f97520 100644
--- a/src/Rule/IsUnique.php
+++ b/src/Rule/IsUnique.php
@@ -31,7 +31,7 @@ class IsUnique
/**
* The list of fields to check
*/
- protected array $_fields;
+ protected array $fields;
/**
* Constructor.
@@ -45,7 +45,7 @@ class IsUnique
*/
public function __construct(array $fields)
{
- $this->_fields = $fields;
+ $this->fields = $fields;
}
/**
@@ -62,11 +62,11 @@ public function __construct(array $fields)
*/
public function __invoke(EntityInterface $entity, array $options): bool
{
- if (!$entity->extract($this->_fields, true)) {
+ if (!$entity->extract($this->fields, true)) {
return true;
}
- $fields = $entity->extract($this->_fields);
+ $fields = $entity->extract($this->fields);
$conditions = [];
foreach ($fields as $field => $value) {
diff --git a/src/TestSuite/TestFixture.php b/src/TestSuite/TestFixture.php
index f6b98414..65656070 100644
--- a/src/TestSuite/TestFixture.php
+++ b/src/TestSuite/TestFixture.php
@@ -161,11 +161,11 @@ public function create(ConnectionInterface $db): bool
*
* @param \Cake\Datasource\ConnectionInterface $connection The Elasticsearch connection
*/
- public function insert(ConnectionInterface $connection): bool
+ public function insert(ConnectionInterface $connection): void
{
assert($connection instanceof Connection, 'Requires an elasticsearch connection');
if ($this->records === []) {
- return false;
+ return;
}
$documents = [];
@@ -183,8 +183,6 @@ public function insert(ConnectionInterface $connection): bool
$esIndex->addDocuments($documents);
$esIndex->refresh();
-
- return true;
}
/**
@@ -211,7 +209,7 @@ public function drop(ConnectionInterface $db): bool
*
* @param \Cake\Datasource\ConnectionInterface $connection The Elasticsearch connection
*/
- public function truncate(ConnectionInterface $connection): bool
+ public function truncate(ConnectionInterface $connection): void
{
$query = new MatchAll();
assert($connection instanceof Connection, 'Requires an elasticsearch connection');
@@ -219,8 +217,6 @@ public function truncate(ConnectionInterface $connection): bool
$esIndex = $connection->getIndex($this->getIndex()->getName());
$esIndex->deleteByQuery($query);
$esIndex->refresh();
-
- return true;
}
/**
diff --git a/src/View/Form/DocumentContext.php b/src/View/Form/DocumentContext.php
index 7f8cf71f..7b9c60ea 100644
--- a/src/View/Form/DocumentContext.php
+++ b/src/View/Form/DocumentContext.php
@@ -37,23 +37,23 @@ class DocumentContext implements ContextInterface
/**
* The request object.
*/
- protected ServerRequest $_request;
+ protected ServerRequest $request;
/**
* The context data
*/
- protected array $_context;
+ protected array $context;
/**
* The name of the top level entity/index object.
*/
- protected string $_rootName;
+ protected string $rootName;
/**
* Boolean to track whether or not the entity is a
* collection.
*/
- protected bool $_isCollection = false;
+ protected bool $isCollection = false;
/**
* Constructor.
@@ -63,14 +63,14 @@ class DocumentContext implements ContextInterface
*/
public function __construct(ServerRequest $request, array $context)
{
- $this->_request = $request;
+ $this->request = $request;
$context += [
'entity' => null,
'index' => null,
'validator' => 'default',
];
- $this->_context = $context;
- $this->_prepare();
+ $this->context = $context;
+ $this->prepare();
}
/**
@@ -87,10 +87,10 @@ public function __construct(ServerRequest $request, array $context)
*
* @throws \RuntimeException When a table object cannot be located/inferred.
*/
- protected function _prepare(): void
+ protected function prepare(): void
{
- $index = $this->_context['index'];
- $entity = $this->_context['entity'];
+ $index = $this->context['index'];
+ $entity = $this->context['entity'];
if (empty($index)) {
if (is_array($entity) || $entity instanceof Traversable) {
$entity = (new Collection($entity))->first();
@@ -118,13 +118,13 @@ protected function _prepare(): void
);
}
- $this->_isCollection = (
+ $this->isCollection = (
is_array($entity) ||
$entity instanceof Traversable
);
assert($index instanceof Index);
- $this->_rootName = $index->getName();
- $this->_context['index'] = $index;
+ $this->rootName = $index->getName();
+ $this->context['index'] = $index;
}
/**
@@ -150,7 +150,7 @@ public function isPrimaryKey(string $field): bool
*/
public function isCreate(): bool
{
- $entity = $this->_context['entity'];
+ $entity = $this->context['entity'];
if (is_array($entity) || $entity instanceof Traversable) {
$entity = (new Collection($entity))->first();
}
@@ -167,12 +167,12 @@ public function isCreate(): bool
*/
public function val(string $field, array $options = []): mixed
{
- $val = $this->_request->getData($field);
+ $val = $this->request->getData($field);
if ($val !== null) {
return $val;
}
- if (empty($this->_context['entity'])) {
+ if (empty($this->context['entity'])) {
return null;
}
@@ -183,8 +183,8 @@ public function val(string $field, array $options = []): mixed
return $entity->get(array_pop($parts));
}
- if ($this->_context['entity'] instanceof Document) {
- return Hash::get($this->_context['entity'], $field);
+ if ($this->context['entity'] instanceof Document) {
+ return Hash::get($this->context['entity'], $field);
}
return null;
@@ -200,16 +200,16 @@ public function val(string $field, array $options = []): mixed
protected function entity(array $path): object|array|false
{
$oneElement = count($path) === 1;
- if ($oneElement && $this->_isCollection) {
+ if ($oneElement && $this->isCollection) {
return false;
}
- $entity = $this->_context['entity'];
+ $entity = $this->context['entity'];
if ($oneElement) {
return $entity;
}
- if ($path[0] === $this->_rootName) {
+ if ($path[0] === $this->rootName) {
$path = array_slice($path, 1);
}
@@ -349,8 +349,8 @@ public function getMaxLength(string $field): ?int
}
foreach ($validator->field($fieldName)->rules() as $rule) {
- if ($rule->get('rule') === 'maxLength') {
- return $rule->get('pass')[0];
+ if ($rule->name === 'maxLength' && isset($rule->pass[0])) {
+ return $rule->pass[0];
}
}
@@ -364,7 +364,7 @@ public function getMaxLength(string $field): ?int
*/
protected function getValidator(): Validator
{
- return $this->_context['index']->getValidator($this->_context['validator']);
+ return $this->context['index']->getValidator($this->context['validator']);
}
/**
@@ -372,7 +372,7 @@ protected function getValidator(): Validator
*/
public function fieldNames(): array
{
- $schema = $this->_context['index']->schema();
+ $schema = $this->context['index']->schema();
return $schema->fields();
}
@@ -382,7 +382,7 @@ public function fieldNames(): array
*/
public function type(string $field): ?string
{
- $schema = $this->_context['index']->schema();
+ $schema = $this->context['index']->schema();
return $schema->fieldType($field);
}
@@ -413,8 +413,8 @@ public function error(string $field): array
$entityErrors = [];
$errors = [];
- if ($this->_context['entity'] instanceof Document) {
- $entityErrors = $this->_context['entity']->getErrors();
+ if ($this->context['entity'] instanceof Document) {
+ $entityErrors = $this->context['entity']->getErrors();
}
$tailField = array_pop($parts);
diff --git a/tests/Fixture/ArticlesFixture.php b/tests/Fixture/ArticlesFixture.php
index 1a16f358..d75cbfc8 100644
--- a/tests/Fixture/ArticlesFixture.php
+++ b/tests/Fixture/ArticlesFixture.php
@@ -1,4 +1,7 @@
_indexLocator instanceof LocatorInterface) {
- return $this->_indexLocator;
+ if ($this->indexLocator instanceof LocatorInterface) {
+ return $this->indexLocator;
}
// Return a mock IndexLocator instead of using FactoryLocator
- return $this->_indexLocator = new IndexLocator();
+ return $this->indexLocator = new IndexLocator();
}
};
diff --git a/tests/TestCase/MarshallerTest.php b/tests/TestCase/MarshallerTest.php
index 29a8cf1e..765c9878 100644
--- a/tests/TestCase/MarshallerTest.php
+++ b/tests/TestCase/MarshallerTest.php
@@ -140,7 +140,7 @@ public function testOneFieldList(): void
}
/**
- * test marshalling with accessibleFields
+ * test marshalling with patchableFields
*/
public function testOneAccessibleFields(): void
{
@@ -158,7 +158,7 @@ public function testOneAccessibleFields(): void
$this->assertNull($result->body);
$this->assertNull($result->user_id);
- $result = $marshaller->one($data, ['accessibleFields' => ['body' => true]]);
+ $result = $marshaller->one($data, ['patchableFields' => ['body' => true]]);
$this->assertSame($data['title'], $result->title);
$this->assertSame($data['body'], $result->body);
@@ -475,7 +475,7 @@ public function testMergeValidationErrorsPreserveInvalidFields(): void
public function testMergeFieldList(): void
{
$doc = $this->index->get(1);
- $doc->setAccess('*', false);
+ $doc->setPatchable('*', false);
$data = [
'title' => 'New title',
@@ -866,13 +866,13 @@ public function testMarshallOneMultiLevelEmbedWithAccessibleFields(): void
],
];
$options = [
- 'accessibleFields' => ['remove_this' => false],
+ 'patchableFields' => ['remove_this' => false],
'associated' => [
'User' => [
- 'accessibleFields' => ['last_name' => false],
+ 'patchableFields' => ['last_name' => false],
'associated' => [
'UserType' => [
- 'accessibleFields' => ['level' => false],
+ 'patchableFields' => ['level' => false],
],
],
],
@@ -1235,7 +1235,6 @@ public function testFieldValueWithExistingField(): void
$reflection = new ReflectionClass($marshaller);
$method = $reflection->getMethod('fieldValue');
- $method->setAccessible(true);
$result = $method->invoke($marshaller, $entity, 'title');
$this->assertSame('Test', $result);
@@ -1254,7 +1253,6 @@ public function testFieldValueWithMissingField(): void
$reflection = new ReflectionClass($marshaller);
$method = $reflection->getMethod('fieldValue');
- $method->setAccessible(true);
$result = $method->invoke($marshaller, $entity, 'nonexistent');
$this->assertNull($result, 'Should return null for missing fields');
@@ -1270,7 +1268,6 @@ public function testFieldValueWithNullValue(): void
$reflection = new ReflectionClass($marshaller);
$method = $reflection->getMethod('fieldValue');
- $method->setAccessible(true);
$result = $method->invoke($marshaller, $entity, 'title');
$this->assertNull($result);
diff --git a/tests/TestCase/ResultSetTest.php b/tests/TestCase/ResultSetTest.php
index d061f5d3..709d6367 100644
--- a/tests/TestCase/ResultSetTest.php
+++ b/tests/TestCase/ResultSetTest.php
@@ -107,7 +107,6 @@ public function testDecoratedMethods(): void
// Read the wrapped results so we can compare method outputs.
// This is not ideal but better than using mocks.
$reflect = new ReflectionProperty($results, 'resultSet');
- $reflect->setAccessible(true);
$elasticResult = $reflect->getValue($results);
diff --git a/tests/TestCase/Rule/IsUniqueTest.php b/tests/TestCase/Rule/IsUniqueTest.php
index 00e4c18e..ec4fa620 100644
--- a/tests/TestCase/Rule/IsUniqueTest.php
+++ b/tests/TestCase/Rule/IsUniqueTest.php
@@ -46,8 +46,7 @@ public function testConstructor(): void
// Use reflection to verify fields were stored correctly
$reflection = new ReflectionClass($rule);
- $fieldsProperty = $reflection->getProperty('_fields');
- $fieldsProperty->setAccessible(true);
+ $fieldsProperty = $reflection->getProperty('fields');
$storedFields = $fieldsProperty->getValue($rule);
@@ -62,8 +61,7 @@ public function testConstructorWithEmptyArray(): void
$rule = new IsUnique([]);
$reflection = new ReflectionClass($rule);
- $fieldsProperty = $reflection->getProperty('_fields');
- $fieldsProperty->setAccessible(true);
+ $fieldsProperty = $reflection->getProperty('fields');
$storedFields = $fieldsProperty->getValue($rule);
@@ -80,8 +78,7 @@ public function testConstructorWithSingleField(): void
$rule = new IsUnique([$field]);
$reflection = new ReflectionClass($rule);
- $fieldsProperty = $reflection->getProperty('_fields');
- $fieldsProperty->setAccessible(true);
+ $fieldsProperty = $reflection->getProperty('fields');
$storedFields = $fieldsProperty->getValue($rule);
diff --git a/tests/TestCase/TestSuite/Fixture/DeleteQueryStrategyTest.php b/tests/TestCase/TestSuite/Fixture/DeleteQueryStrategyTest.php
index acbefe96..e7aff552 100644
--- a/tests/TestCase/TestSuite/Fixture/DeleteQueryStrategyTest.php
+++ b/tests/TestCase/TestSuite/Fixture/DeleteQueryStrategyTest.php
@@ -40,7 +40,6 @@ public function testConstructor(): void
// Use reflection to verify helper was initialized
$reflection = new ReflectionClass($strategy);
$helperProperty = $reflection->getProperty('helper');
- $helperProperty->setAccessible(true);
$helper = $helperProperty->getValue($strategy);
@@ -48,7 +47,6 @@ public function testConstructor(): void
// Test that fixtures array is initialized empty
$fixturesProperty = $reflection->getProperty('fixtures');
- $fixturesProperty->setAccessible(true);
$fixtures = $fixturesProperty->getValue($strategy);
@@ -76,7 +74,6 @@ public function testSetupTest(): void
// Verify fixtures are stored internally
$reflection = new ReflectionClass($strategy);
$fixturesProperty = $reflection->getProperty('fixtures');
- $fixturesProperty->setAccessible(true);
$fixtures = $fixturesProperty->getValue($strategy);
@@ -96,7 +93,6 @@ public function testSetupTestWithEmptyArray(): void
// Verify fixtures array remains empty
$reflection = new ReflectionClass($strategy);
$fixturesProperty = $reflection->getProperty('fixtures');
- $fixturesProperty->setAccessible(true);
$fixtures = $fixturesProperty->getValue($strategy);
@@ -132,7 +128,6 @@ public function testMultipleSetupTestCalls(): void
// Verify it doesn't crash and fixtures are updated
$reflection = new ReflectionClass($strategy);
$fixturesProperty = $reflection->getProperty('fixtures');
- $fixturesProperty->setAccessible(true);
$fixtures = $fixturesProperty->getValue($strategy);
@@ -173,7 +168,6 @@ public function testTeardownTestWithoutSetup(): void
// Verify fixtures array is still empty
$reflection = new ReflectionClass($strategy);
$fixturesProperty = $reflection->getProperty('fixtures');
- $fixturesProperty->setAccessible(true);
$fixtures = $fixturesProperty->getValue($strategy);
@@ -294,7 +288,6 @@ public function testSetupTestMethodCoverage(): void
// Verify fixtures are loaded
$reflection = new ReflectionClass($strategy);
$fixturesProperty = $reflection->getProperty('fixtures');
- $fixturesProperty->setAccessible(true);
$fixtures = $fixturesProperty->getValue($strategy);
$this->assertNotEmpty($fixtures);
@@ -319,7 +312,6 @@ public function testTeardownTestMethodCoverage(): void
// Verify fixtures were cleared
$reflection = new ReflectionClass($strategy);
$fixturesProperty = $reflection->getProperty('fixtures');
- $fixturesProperty->setAccessible(true);
$fixtures = $fixturesProperty->getValue($strategy);
$this->assertEmpty($fixtures, 'Fixtures should be cleared after teardown');
diff --git a/tests/TestCase/TestSuite/TestFixtureTest.php b/tests/TestCase/TestSuite/TestFixtureTest.php
index d3eaeb94..69de7dd0 100644
--- a/tests/TestCase/TestSuite/TestFixtureTest.php
+++ b/tests/TestCase/TestSuite/TestFixtureTest.php
@@ -175,11 +175,12 @@ public function testCreateWithEmptySchema(): void
}
/**
- * Test insert method with empty records returns false
+ * Test insert method with empty records does not touch the connection
*/
public function testInsertWithEmptyRecords(): void
{
$connection = $this->createMock(Connection::class);
+ $connection->expects($this->never())->method('getIndex');
$fixture = new class extends TestFixture {
public string $connection = 'test_empty';
@@ -187,8 +188,7 @@ public function testInsertWithEmptyRecords(): void
public array $records = [];
};
- $result = $fixture->insert($connection);
- $this->assertFalse($result);
+ $fixture->insert($connection);
}
/**
@@ -581,12 +581,12 @@ public function testInsertWithRealConnectionAndRecords(): void
// Create the index first
$fixture->create($connection);
- $result = $fixture->insert($connection);
- $this->assertTrue($result);
+ $fixture->insert($connection);
// Verify documents were inserted
$esIndex = $connection->getIndex($fixture->getIndex()->getName());
$esIndex->refresh();
+ $this->assertSame(2, $fixture->getIndex()->find()->count());
// Clean up
$esIndex->delete();
@@ -618,8 +618,8 @@ public function testInsertWithRecordsWithoutIds(): void
// Create the index first
$fixture->create($connection);
- $result = $fixture->insert($connection);
- $this->assertTrue($result);
+ $fixture->insert($connection);
+ $this->assertSame(2, $fixture->getIndex()->find()->count());
// Clean up
$esIndex = $connection->getIndex($fixture->getIndex()->getName());
@@ -709,8 +709,8 @@ public function testTruncate(): void
$fixture->create($connection);
$fixture->insert($connection);
- $result = $fixture->truncate($connection);
- $this->assertTrue($result);
+ $fixture->truncate($connection);
+ $this->assertSame(0, $fixture->getIndex()->find()->count());
// Verify index still exists but is empty
$esIndex = $connection->getIndex($fixture->getIndex()->getName());
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index b0b5201f..ee8635d9 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -14,9 +14,9 @@
* @since 0.0.1
* @license https://www.opensource.org/licenses/mit-license.php MIT License
*/
-require dirname(__DIR__) . '/vendor/autoload.php';
+require __DIR__ . '/../vendor/autoload.php';
-define('CAKE', dirname(__DIR__) . '/vendor/cakephp/cakephp/src/');
+define('CAKE', __DIR__ . '/../vendor/cakephp/cakephp/src/');
define('ROOT', dirname(__DIR__));
if (!defined('DS')) {
diff --git a/tests/testapp/Plugin/TestPlugin/src/TestPluginPlugin.php b/tests/testapp/Plugin/TestPlugin/src/TestPluginPlugin.php
new file mode 100644
index 00000000..e2f2dba5
--- /dev/null
+++ b/tests/testapp/Plugin/TestPlugin/src/TestPluginPlugin.php
@@ -0,0 +1,26 @@
+ true,
];
}
diff --git a/tests/testapp/TestApp/src/Model/Index/MyUsersIndex.php b/tests/testapp/TestApp/src/Model/Index/MyUsersIndex.php
index b3dc8b52..8a0dce59 100644
--- a/tests/testapp/TestApp/src/Model/Index/MyUsersIndex.php
+++ b/tests/testapp/TestApp/src/Model/Index/MyUsersIndex.php
@@ -26,5 +26,5 @@ class MyUsersIndex extends Index
/**
* Overrides default table name
*/
- protected string $_name = 'users';
+ protected string $name = 'users';
}