diff --git a/docs/src/plugin/collections.md b/docs/src/plugin/collections.md index 9340b88..f939871 100644 --- a/docs/src/plugin/collections.md +++ b/docs/src/plugin/collections.md @@ -14,7 +14,6 @@ Per array item, you will create a `new TypesenseCollectionIndex`. Here's a basic \percipiolondon\typesense\TypesenseCollectionIndex::create( [ 'name' => 'schools', - 'section' => 'schools.default', //section handle + entry type handle 'fields' => [ [ 'name' => 'title', diff --git a/src/TypesenseCollectionIndex.php b/src/TypesenseCollectionIndex.php index 20eb2ac..a903bf3 100644 --- a/src/TypesenseCollectionIndex.php +++ b/src/TypesenseCollectionIndex.php @@ -13,9 +13,6 @@ class TypesenseCollectionIndex /** @var string */ public $indexName; - /** @var string */ - public $section; - /** @var array */ public $schema = []; @@ -31,9 +28,12 @@ class TypesenseCollectionIndex public function __construct(array $schema) { $this->indexName = $schema['name']; - $this->section = $schema['section']; $this->schema = $schema; $this->criteria = $this->elementType::find(); + + if (isset($schema['section'])) { + Craft::$app->getDeprecator()->log(__METHOD__, 'Setting section in the Typesense config no longer does anything, all corrosponding functionality now runs through the criteria parameter.'); + } } public static function create(array $schema): self diff --git a/src/config.php b/src/config.php index f40fb18..0fe4b53 100755 --- a/src/config.php +++ b/src/config.php @@ -1,4 +1,5 @@ 'schools', - 'section' => 'schools.default', //section handle + entry type handle 'fields' => [ [ 'name' => 'title', @@ -50,7 +50,7 @@ ], ], 'default_sorting_field' => 'post_date_timestamp', // can only be an integer, - 'resolver' => static function(\craft\elements\Entry $entry) { + 'resolver' => static function (\craft\elements\Entry $entry) { return [ 'id' => (string)$entry->id, 'title' => $entry->title, @@ -62,7 +62,7 @@ ] ) ->elementType(\craft\elements\Entry::class) - ->criteria(function(\craft\elements\db\EntryQuery $query) { + ->criteria(function (\craft\elements\db\EntryQuery $query) { return $query->section('schools'); }), ] diff --git a/src/controllers/DocumentsController.php b/src/controllers/DocumentsController.php index aaa41d5..8452ee4 100644 --- a/src/controllers/DocumentsController.php +++ b/src/controllers/DocumentsController.php @@ -1,4 +1,5 @@ handleSave($element); if ($event->name === Elements::EVENT_AFTER_RESTORE_ELEMENT || $event->name === Structures::EVENT_AFTER_MOVE_ELEMENT) { - foreach($element->getSupportedSites() as $site) { + foreach ($element->getSupportedSites() as $site) { if ($site['siteId'] ?? null) { $entry = Entry::find()->id($element->id)->siteId($site['siteId'])->one(); $this->handleSave($entry); @@ -137,66 +138,48 @@ public function triggerBeforeUpsert(string $index, string $id): void protected function handleSave(Entry $entry): void { - $sectionHande = $entry->section->handle ?? null; - $type = $entry->type->handle ?? null; - $collection = null; - $resolver = null; - - if ($sectionHande) { - $section = ''; + $collections = CollectionHelper::getAllCollectionsElementIsIndexedIn($entry); - if ($type) { - $section = $sectionHande . '.' . $type; - } - - $collection = CollectionHelper::getCollectionBySection($section); - - // get the generic type if specific doesn't exist - if (is_null($collection)) { - $section = $sectionHande . '.all'; - $collection = CollectionHelper::getCollectionBySection($section); - } + foreach ($collections as $collection) { //create collection if it doesn't exist if (!$collection instanceof \percipiolondon\typesense\TypesenseCollectionIndex) { Typesense::$plugin->getCollections()->saveCollections(); - $collection = CollectionHelper::getCollectionBySection($section); + $collection = CollectionHelper::getCollection($collection->name); } - } - if (is_null($collection)) return; + $resolver = $collection->schema['resolver']($entry); - $resolver = $collection->schema['resolver']($entry); + if (($entry->enabled && $entry->getEnabledForSite()) && $entry->getStatus() === 'live' && in_array($entry->id, $collection->criteria->ids())) { + // element is enabled --> save to Typesense + if ($resolver) { + // Trigger the before upsert event + $this->triggerBeforeUpsert($collection->indexName, $resolver['id']); - if (($entry->enabled && $entry->getEnabledForSite()) && $entry->getStatus() === 'live' && in_array($entry->id, $collection->criteria->ids())) { - // element is enabled --> save to Typesense - if ($resolver) { - // Trigger the before upsert event - $this->triggerBeforeUpsert($collection->indexName, $resolver['id']); + Craft::info('Typesense edit / add document based of: ' . $entry->title, __METHOD__); - Craft::info('Typesense edit / add document based of: ' . $entry->title, __METHOD__); + try { + Typesense::$plugin->getClient()->client()->collections[$collection->indexName]->documents->upsert($resolver); - try { - Typesense::$plugin->getClient()->client()->collections[$collection->indexName]->documents->upsert($resolver); - - // Trigger the after upsert event - $this->triggerAfterUpsert($collection->indexName, $resolver['id']); - } catch (ObjectNotFound | ServerError $e) { - Craft::$app->session->setFlash('error', Craft::t('typesense', 'There was an issue saving your action, check the logs for more info')); - Craft::error($e->getMessage(), __METHOD__); + // Trigger the after upsert event + $this->triggerAfterUpsert($collection->indexName, $resolver['id']); + } catch (ObjectNotFound | ServerError $e) { + Craft::$app->session->setFlash('error', Craft::t('typesense', 'There was an issue saving your action, check the logs for more info')); + Craft::error($e->getMessage(), __METHOD__); + } } - } - } else { - // element is disabled --> delete from Typesense - if ($resolver) { - // Trigger the before delete event - $this->triggerBeforeDelete($collection->indexName, $resolver['id']); + } else { + // element is disabled --> delete from Typesense + if ($resolver) { + // Trigger the before delete event + $this->triggerBeforeDelete($collection->indexName, $resolver['id']); - Craft::info('Typesense delete document based of: ' . $entry->title, __METHOD__); - Typesense::$plugin->getClient()->client()->collections[$collection->indexName]->documents->delete(['filter_by' => 'id: ' . $resolver['id']]); + Craft::info('Typesense delete document based of: ' . $entry->title, __METHOD__); + Typesense::$plugin->getClient()->client()->collections[$collection->indexName]->documents->delete(['filter_by' => 'id: ' . $resolver['id']]); - // Trigger the after delete event - $this->triggerAfterDelete($collection->indexName, $resolver['id']); + // Trigger the after delete event + $this->triggerAfterDelete($collection->indexName, $resolver['id']); + } } } } @@ -216,32 +199,20 @@ protected function handleDelete(ElementEvent $event) $entry = Entry::find()->id($element->id)->siteId($site['siteId'])->one(); if ($entry) { - $section = $entry->section->handle ?? null; - $type = $entry->type->handle ?? null; - $collection = null; - $resolver = null; - - if ($section) { - if ($type) { - $section = $section . '.' . $type; - } - - $collection = CollectionHelper::getCollectionBySection($section); - } - - if ($collection) { + $collections = CollectionHelper::getAllCollectionsElementIsIndexedIn($entry); + foreach ($collections as $collection) { $resolver = $collection->schema['resolver']($entry); - } - if ($resolver) { - // Trigger the before delete event - $this->triggerBeforeDelete($collection->indexName, $resolver['id']); + if ($resolver) { + // Trigger the before delete event + $this->triggerBeforeDelete($collection->indexName, $resolver['id']); - Craft::info('Typesense delete document based on: ' . $entry->title . ' - ' . $entry->getSite()->handle, __METHOD__); - Typesense::$plugin->getClient()->client()->collections[$collection->indexName]->documents->delete(['filter_by' => 'id: ' . $resolver['id']]); + Craft::info('Typesense delete document based on: ' . $entry->title . ' - ' . $entry->getSite()->handle, __METHOD__); + Typesense::$plugin->getClient()->client()->collections[$collection->indexName]->documents->delete(['filter_by' => 'id: ' . $resolver['id']]); - // Trigger the after delete event - $this->triggerAfterDelete($collection->indexName, $resolver['id']); + // Trigger the after delete event + $this->triggerAfterDelete($collection->indexName, $resolver['id']); + } } } } diff --git a/src/helpers/CollectionHelper.php b/src/helpers/CollectionHelper.php index 0ef32b7..a7e9a8c 100644 --- a/src/helpers/CollectionHelper.php +++ b/src/helpers/CollectionHelper.php @@ -2,12 +2,8 @@ namespace percipiolondon\typesense\helpers; -use Craft; - -use craft\helpers\DateTimeHelper; +use craft\base\Element; use craft\helpers\Json; - -use percipiolondon\typesense\models\CollectionModel as Collection; use percipiolondon\typesense\Typesense; use percipiolondon\typesense\TypesenseCollectionIndex; @@ -31,23 +27,26 @@ public static function getCollection(string $name): ?TypesenseCollectionIndex return null; } - public static function getCollectionBySection(string $name): ?TypesenseCollectionIndex + /** + * Find all collections that an element is included in by executing the collection element query with the element ID + */ + public static function getAllCollectionsElementIsIndexedIn(Element $element) { + $matchingCollections = []; $indexes = Typesense::$plugin->getSettings()->collections; foreach ($indexes as $index) { - if ($index->section === $name || (is_array($index->section) && in_array($name, $index->section))) { - return $index; + if ($index->criteria->id($element->id)->count() > 0) { + $matchingCollections[] = $index; } } - - return null; + return $matchingCollections; } public static function convertDocumentsToArray(string $index): array { $documents = Typesense::$plugin->getClient()->client()->collections[$index]->documents->export(); - $jsonDocs = explode("\n",$documents); + $jsonDocs = explode("\n", $documents); $documents = []; foreach ($jsonDocs as $document) {