diff --git a/composer.json b/composer.json
index 3ab58cae..3700e7fb 100644
--- a/composer.json
+++ b/composer.json
@@ -1,69 +1,75 @@
{
- "name": "meilisearch/search-bundle",
- "description": "Seamless integration of Meilisearch into your Symfony project.",
- "keywords": [
- "meilisearch",
- "instant",
- "search",
- "api",
- "symfony",
- "bundle"
- ],
- "type": "symfony-bundle",
- "license": "MIT",
- "authors": [
- {
- "name": "David Sanchez",
- "email": "david38sanchez@gmail.com"
- }
- ],
- "require": {
- "php": "^7.4|^8.0",
- "ext-json": "*",
- "doctrine/doctrine-bundle": "^2.4",
- "illuminate/collections": "^8.47",
- "meilisearch/meilisearch-php": "^0.24.0",
- "symfony/filesystem": "^4.4 || ^5.0 || ^6.0",
- "symfony/property-access": "^4.4 || ^5.0 || ^6.0",
- "symfony/serializer": "^4.4 || ^5.0 || ^6.0"
- },
- "require-dev": {
- "doctrine/orm": "^2.9",
- "friendsofphp/php-cs-fixer": "^3.0",
- "nyholm/psr7": "^1.3",
- "phpstan/extension-installer": "^1.1",
- "phpstan/phpstan": "^0.12.90",
- "phpstan/phpstan-doctrine": "^0.12.39",
- "phpstan/phpstan-phpunit": "^0.12.20",
- "phpstan/phpstan-symfony": "^0.12.37",
- "phpunit/php-code-coverage": "^9.2",
- "phpunit/phpunit": "^9.5",
- "symfony/doctrine-bridge": "^4.4 || ^5.0 || ^6.0",
- "symfony/http-client": "^4.4 || ^5.0 || ^6.0",
- "symfony/phpunit-bridge": "^4.4 || ^5.0 || ^6.0",
- "symfony/yaml": "^4.4 || ^5.0 || ^6.0"
- },
- "autoload": {
- "psr-4": {
- "MeiliSearch\\Bundle\\": "src/"
- }
- },
- "autoload-dev": {
- "psr-4": {
- "MeiliSearch\\Bundle\\Test\\": "tests/"
- }
- },
- "config": {
- "sort-packages": true,
- "allow-plugins": {
- "phpstan/extension-installer": true
- }
- },
- "scripts": {
- "phpstan": "./vendor/bin/phpstan --memory-limit=1G --ansi",
- "test:unit": "./vendor/bin/phpunit --colors=always --verbose",
- "test:unit:coverage": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --colors=always --coverage-html=tests/coverage",
- "lint:check": "./vendor/bin/php-cs-fixer fix -v --using-cache=no --dry-run",
- "lint:fix": "./vendor/bin/php-cs-fixer fix -v --using-cache=no"
+ "name": "meilisearch/search-bundle",
+ "description": "Seamless integration of Meilisearch into your Symfony project.",
+ "keywords": [
+ "meilisearch",
+ "instant",
+ "search",
+ "api",
+ "symfony",
+ "bundle"
+ ],
+ "type": "symfony-bundle",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "David Sanchez",
+ "email": "david38sanchez@gmail.com"
}
+ ],
+ "repositories": {
+ "meilisearch/meilisearch-php": {
+ "type": "git",
+ "url": "https://github.com/meilisearch/meilisearch-php"
+ }
+ },
+ "require": {
+ "php": "^7.4|^8.0",
+ "ext-json": "*",
+ "doctrine/doctrine-bundle": "^2.4",
+ "illuminate/collections": "^8.47",
+ "meilisearch/meilisearch-php": "dev-bump-meilisearch-v0.28.0 as 1.2.3",
+ "symfony/filesystem": "^4.4 || ^5.0 || ^6.0",
+ "symfony/property-access": "^4.4 || ^5.0 || ^6.0",
+ "symfony/serializer": "^4.4 || ^5.0 || ^6.0"
+ },
+ "require-dev": {
+ "doctrine/orm": "^2.9",
+ "friendsofphp/php-cs-fixer": "^3.0",
+ "nyholm/psr7": "^1.3",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^0.12.90",
+ "phpstan/phpstan-doctrine": "^0.12.39",
+ "phpstan/phpstan-phpunit": "^0.12.20",
+ "phpstan/phpstan-symfony": "^0.12.37",
+ "phpunit/php-code-coverage": "^9.2",
+ "phpunit/phpunit": "^9.5",
+ "symfony/doctrine-bridge": "^4.4 || ^5.0 || ^6.0",
+ "symfony/http-client": "^4.4 || ^5.0 || ^6.0",
+ "symfony/phpunit-bridge": "^4.4 || ^5.0 || ^6.0",
+ "symfony/yaml": "^4.4 || ^5.0 || ^6.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "MeiliSearch\\Bundle\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "MeiliSearch\\Bundle\\Test\\": "tests/"
+ }
+ },
+ "config": {
+ "sort-packages": true,
+ "allow-plugins": {
+ "phpstan/extension-installer": true
+ }
+ },
+ "scripts": {
+ "phpstan": "./vendor/bin/phpstan --memory-limit=1G --ansi",
+ "test:unit": "./vendor/bin/phpunit --colors=always --verbose",
+ "test:unit:coverage": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --colors=always --coverage-html=tests/coverage",
+ "lint:check": "./vendor/bin/php-cs-fixer fix -v --using-cache=no --dry-run",
+ "lint:fix": "./vendor/bin/php-cs-fixer fix -v --using-cache=no"
+ }
}
diff --git a/src/CollectionXX.php b/src/CollectionXX.php
new file mode 100644
index 00000000..46793e6e
--- /dev/null
+++ b/src/CollectionXX.php
@@ -0,0 +1,146 @@
+items;
+ }
+
+ /**
+ * Get the collection of items as a plain array.
+ *
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->items;
+ }
+
+ /**
+ * The items contained in the collection.
+ *
+ * @var array
+ */
+ protected $items = [];
+
+ /**
+ * Create a new collection.
+ *
+ * @param mixed $items
+ * @return void
+ */
+ public function __construct($items = [])
+ {
+ $this->items = $items;
+ }
+
+ /**
+ * Get an item from the collection by key.
+ *
+ * @param mixed $key
+ * @param mixed $default
+ * @return mixed
+ */
+ public function get($key, $default = null)
+ {
+ if ($this->offsetExists($key)) {
+ return $this->items[$key];
+ }
+
+ return $default;
+ }
+
+ /**
+ * Transform each item in the collection using a callback.
+ *
+ * @param callable $callback
+ * @return $this
+ */
+ public function transform(callable $callback)
+ {
+ $this->items = $this->map($callback)->all();
+
+ return $this;
+ }
+
+ /**
+ * Run a map over each of the items.
+ *
+ * @param callable $callback
+ * @return static
+ */
+ public function map(callable $callback)
+ {
+ $keys = array_keys($this->items);
+
+ $items = array_map($callback, $this->items, $keys);
+
+ return new static(array_combine($keys, $items));
+ }
+
+ /**
+ * Count the number of items in the collection.
+ *
+ * @return int
+ */
+ #[\ReturnTypeWillChange]
+ public function count()
+ {
+ return count($this->items);
+ }
+
+ /**
+ * Get all of the items in the collection.
+ *
+ * @return array
+ */
+ public function all()
+ {
+ return $this->items;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function offsetSet($offset, $value): void
+ {
+ $this->items[$offset] = $value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function offsetExists($offset): bool
+ {
+ return isset($this->items[$offset]) || \array_key_exists($offset, $this->items);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function offsetUnset($offset): void
+ {
+ unset($this->items[$offset]);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($offset)
+ {
+ if (isset($this->items[$offset])) {
+ return $this->items[$offset];
+ }
+
+ return null;
+ }
+}
diff --git a/src/Command/IndexCommand.php b/src/Command/IndexCommand.php
index 6b6ceb9f..acc6d198 100644
--- a/src/Command/IndexCommand.php
+++ b/src/Command/IndexCommand.php
@@ -4,7 +4,7 @@
namespace MeiliSearch\Bundle\Command;
-use Illuminate\Support\Collection;
+use MeiliSearch\Bundle\CollectionXX;
use MeiliSearch\Bundle\SearchService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
@@ -26,24 +26,23 @@ public function __construct(SearchService $searchService)
parent::__construct();
}
- protected function getIndices(): Collection
+ protected function getIndices(): CollectionXX
{
- return collect($this->searchService->getConfiguration()->get('indices'))
- ->transform(function (array $item) {
+ return (new CollectionXX($this->searchService->getConfiguration()->get('indices')))->transform(function (array $item) {
$item['name'] = $this->prefix.$item['name'];
return $item;
});
}
- protected function getEntitiesFromArgs(InputInterface $input, OutputInterface $output): Collection
+ protected function getEntitiesFromArgs(InputInterface $input, OutputInterface $output): CollectionXX
{
$indices = $this->getIndices();
- $indexNames = collect();
+ $indexNames = new CollectionXX();
if ($indexList = $input->getOption('indices')) {
$list = \explode(',', $indexList);
- $indexNames = collect($list)->transform(function (string $item): string {
+ $indexNames = (new CollectionXX($list))->transform(function (string $item): string {
// Check if the given index name already contains the prefix
if (!str_contains($item, $this->prefix)) {
return $this->prefix.$item;
@@ -58,11 +57,15 @@ protected function getEntitiesFromArgs(InputInterface $input, OutputInterface $o
'No indices specified. Please either specify indices using the cli option or YAML configuration.'
);
- return collect();
+ return new CollectionXX();
}
if (count($indexNames) > 0) {
- return $indices->reject(fn (array $item) => !in_array($item['name'], $indexNames->toArray(), true));
+ foreach ($indices->getItems() as $key => $value) {
+ if (!in_array($value['name'], $indexNames->toArray(), true)) {
+ unset($indices[$key]);
+ }
+ }
}
return $indices;
diff --git a/src/Command/MeiliSearchCreateCommand.php b/src/Command/MeiliSearchCreateCommand.php
index 0afc6a81..a95a83ba 100644
--- a/src/Command/MeiliSearchCreateCommand.php
+++ b/src/Command/MeiliSearchCreateCommand.php
@@ -4,6 +4,7 @@
namespace MeiliSearch\Bundle\Command;
+use MeiliSearch\Bundle\CollectionXX;
use MeiliSearch\Bundle\Exception\InvalidSettingName;
use MeiliSearch\Bundle\Exception\TaskException;
use MeiliSearch\Bundle\Model\Aggregator;
@@ -50,7 +51,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if (is_subclass_of($entityClassName, Aggregator::class)) {
$indexes->forget($key);
- $indexes = collect(array_merge(
+ $indexes = new CollectionXX(array_merge(
$indexes->toArray(),
array_map(
static fn ($entity) => ['name' => $index['name'], 'class' => $entity],
@@ -85,6 +86,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
$task = $indexInstance->{$method}($value);
+
+ $indexInstance->waitForTask($task['taskUid']);
$task = $indexInstance->getTask($task['taskUid']);
if ('failed' === $task['status']) {
diff --git a/src/Command/MeiliSearchDeleteCommand.php b/src/Command/MeiliSearchDeleteCommand.php
index b1a9a636..5ccd8cbf 100644
--- a/src/Command/MeiliSearchDeleteCommand.php
+++ b/src/Command/MeiliSearchDeleteCommand.php
@@ -4,6 +4,7 @@
namespace MeiliSearch\Bundle\Command;
+use MeiliSearch\Bundle\CollectionXX;
use MeiliSearch\Exceptions\ApiException;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -33,10 +34,17 @@ protected function configure(): void
protected function execute(InputInterface $input, OutputInterface $output): int
{
- $indexToDelete = collect($this->getEntitiesFromArgs($input, $output))->unique('name');
+ $list = $this->getEntitiesFromArgs($input, $output);
+
+ $indexesToDelete = [];
+ foreach($list as $element) {
+ $hash = $element['name'];
+ $indexesToDelete[$hash] = $element;
+ }
+ $indexesToDelete = new CollectionXX(array_values($indexesToDelete));
/** @var array $index */
- foreach ($indexToDelete as $index) {
+ foreach ($indexesToDelete as $index) {
$indexName = $index['name'];
try {
$this->searchService->deleteByIndexName($indexName);
@@ -47,7 +55,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$output->writeln('Deleted '.$indexName.'');
}
- if (0 === count($indexToDelete)) {
+ if (0 === count($indexesToDelete)) {
$output->writeln('Cannot delete index. Not found.');
}
diff --git a/src/Command/MeiliSearchImportCommand.php b/src/Command/MeiliSearchImportCommand.php
index 30b23af3..bb935336 100644
--- a/src/Command/MeiliSearchImportCommand.php
+++ b/src/Command/MeiliSearchImportCommand.php
@@ -9,6 +9,7 @@
use MeiliSearch\Bundle\Exception\TaskException;
use MeiliSearch\Bundle\Model\Aggregator;
use MeiliSearch\Bundle\SearchService;
+// use MeiliSearch\Bundle\CollectionXX;
use MeiliSearch\Client;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@@ -74,7 +75,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if (is_subclass_of($entityClassName, Aggregator::class)) {
$indexes->forget($key);
- $indexes = collect(array_merge(
+ $indexes = new CollectionXX(array_merge(
$indexes->toArray(),
array_map(
fn ($entity) => ['class' => $entity],
diff --git a/src/SearchService.php b/src/SearchService.php
index 03f0741b..07a520a8 100644
--- a/src/SearchService.php
+++ b/src/SearchService.php
@@ -5,7 +5,7 @@
namespace MeiliSearch\Bundle;
use Doctrine\Persistence\ObjectManager;
-use Illuminate\Support\Collection;
+use MeiliSearch\Bundle\CollectionXX;
/**
* Interface SearchService.
@@ -22,7 +22,7 @@ public function isSearchable($className): bool;
public function getSearchable(): array;
- public function getConfiguration(): Collection;
+ public function getConfiguration(): CollectionXX;
/**
* Get the index name for the given `$className`.
diff --git a/src/Services/MeiliSearchService.php b/src/Services/MeiliSearchService.php
index be2e7154..2edba069 100644
--- a/src/Services/MeiliSearchService.php
+++ b/src/Services/MeiliSearchService.php
@@ -6,7 +6,7 @@
use Doctrine\Common\Util\ClassUtils;
use Doctrine\Persistence\ObjectManager;
-use Illuminate\Support\Collection;
+use MeiliSearch\Bundle\CollectionXX;
use MeiliSearch\Bundle\Engine;
use MeiliSearch\Bundle\Entity\Aggregator;
use MeiliSearch\Bundle\Exception\ObjectIdNotFoundException;
@@ -25,7 +25,7 @@ final class MeiliSearchService implements SearchService
{
private SerializerInterface $normalizer;
private Engine $engine;
- private Collection $configuration;
+ private CollectionXX $configuration;
private PropertyAccessor $propertyAccessor;
private array $searchableEntities;
private array $entitiesAggregators;
@@ -37,7 +37,7 @@ public function __construct(SerializerInterface $normalizer, Engine $engine, arr
{
$this->normalizer = $normalizer;
$this->engine = $engine;
- $this->configuration = new Collection($configuration);
+ $this->configuration = new CollectionXX($configuration);
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
$this->setSearchableEntities();
@@ -63,7 +63,7 @@ public function getSearchable(): array
return $this->searchableEntities;
}
- public function getConfiguration(): Collection
+ public function getConfiguration(): CollectionXX
{
return $this->configuration;
}
@@ -73,8 +73,9 @@ public function getConfiguration(): Collection
*/
public function searchableAs(string $className): string
{
- $indexes = Collection::wrap($this->getConfiguration()->get('indices'));
- $index = $indexes->firstWhere('class', $className);
+ $indexes = $this->getConfiguration()->get('indices');
+ $indexes = array_filter($indexes, fn ($item) => $item['class'] == $className);
+ $index = reset($indexes);
return $this->getConfiguration()->get('prefix').$index['name'];
}
diff --git a/tests/BaseKernelTestCase.php b/tests/BaseKernelTestCase.php
index 1eb39228..0f08084f 100644
--- a/tests/BaseKernelTestCase.php
+++ b/tests/BaseKernelTestCase.php
@@ -186,12 +186,11 @@ protected function getFileName(string $indexName, string $type): string
private function cleanUp(): void
{
- collect($this->searchService->getConfiguration()->get('indices'))
- ->each(function ($item): bool {
- $this->cleanupIndex($this->getPrefix().$item['name']);
+ $indexes = $this->searchService->getConfiguration()->get('indices');
- return true;
- });
+ foreach ($indexes as $item) {
+ $this->cleanupIndex($this->getPrefix().$item['name']);
+ }
$this->cleanupIndex($this->getPrefix().'indexA');
$this->cleanupIndex($this->getPrefix().'indexB');
diff --git a/tests/Integration/SearchTest.php b/tests/Integration/SearchTest.php
index abff7ea6..c01f688e 100644
--- a/tests/Integration/SearchTest.php
+++ b/tests/Integration/SearchTest.php
@@ -63,7 +63,9 @@ public function testSearchImportAggregator(): void
$commandTester = new CommandTester($command);
$commandTester->execute([
'--indices' => $this->index->getUid(),
- ]);
+ ], ['verbosity' => true, 'capture_stderr_separately' => true]);
+
+ var_dump($commandTester->getOutput()->__toString());
$output = $commandTester->getDisplay();