Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion docs/src/plugin/collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
8 changes: 4 additions & 4 deletions src/TypesenseCollectionIndex.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ class TypesenseCollectionIndex
/** @var string */
public $indexName;

/** @var string */
public $section;

/** @var array */
public $schema = [];

Expand All @@ -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
Expand Down
6 changes: 3 additions & 3 deletions src/config.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/**
* Typesense plugin for Craft CMS 5.x
*
Expand Down Expand Up @@ -28,7 +29,6 @@
\percipiolondon\typesense\TypesenseCollectionIndex::create(
[
'name' => 'schools',
'section' => 'schools.default', //section handle + entry type handle
'fields' => [
[
'name' => 'title',
Expand All @@ -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,
Expand All @@ -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');
}),
]
Expand Down
109 changes: 40 additions & 69 deletions src/controllers/DocumentsController.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

namespace percipiolondon\typesense\controllers;

use Craft;
Expand Down Expand Up @@ -60,7 +61,7 @@ function (ElementEvent $event) {
$this->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);
Expand Down Expand Up @@ -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']);
}
}
}
}
Expand All @@ -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']);
}
}
}
}
Expand Down
21 changes: 10 additions & 11 deletions src/helpers/CollectionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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) {
Expand Down