Skip to content
Merged
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
34 changes: 34 additions & 0 deletions _config/synonyms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
Name: forager-bifrost-synonyms
Only:
envvarset: 'BIFROST_MANAGEMENT_API_KEY'
After:
- 'silverstripe-forager-elastic-enterprise-synonyms'
- 'silverstripe-forager-synonyms'
---
SilverStripe\Core\Injector\Injector:
# Adaptors provided by this module
SilverStripe\Forager\Interfaces\Requests\CreateSynonymRuleAdaptor:
class: SilverStripe\ForagerBifrost\Adaptors\Requests\CreateSynonymRuleAdaptor
SilverStripe\Forager\Interfaces\Requests\GetSynonymRuleAdaptor:
class: SilverStripe\ForagerBifrost\Adaptors\Requests\GetSynonymRuleAdaptor
SilverStripe\Forager\Interfaces\Requests\GetSynonymRulesAdaptor:
class: SilverStripe\ForagerBifrost\Adaptors\Requests\GetSynonymRulesAdaptor
SilverStripe\Forager\Interfaces\Requests\UpdateSynonymRuleAdaptor:
class: SilverStripe\ForagerBifrost\Adaptors\Requests\UpdateSynonymRuleAdaptor
SilverStripe\Forager\Interfaces\Requests\DeleteSynonymRuleAdaptor:
class: SilverStripe\ForagerBifrost\Adaptors\Requests\DeleteSynonymRuleAdaptor
# Adaptors provided by the ElasticEnterprise dependency
SilverStripe\Forager\Interfaces\Requests\GetSynonymCollectionsAdaptor:
Comment thread
blueo marked this conversation as resolved.
class: SilverStripe\ForagerElasticEnterprise\Adaptors\Requests\GetSynonymCollectionsAdaptor
# Request overrides to work with the Bifröst API
Elastic\EnterpriseSearch\AppSearch\Request\DeleteSynonymSet:
class: SilverStripe\ForagerBifrost\Service\Requests\DeleteSynonymRule
Elastic\EnterpriseSearch\AppSearch\Request\GetSynonymSet:
class: SilverStripe\ForagerBifrost\Service\Requests\GetSynonymRule
Elastic\EnterpriseSearch\AppSearch\Request\ListSynonymSets:
class: SilverStripe\ForagerBifrost\Service\Requests\GetSynonymRules
Elastic\EnterpriseSearch\AppSearch\Request\CreateSynonymSet:
class: SilverStripe\ForagerBifrost\Service\Requests\CreateSynonymRule
Elastic\EnterpriseSearch\AppSearch\Request\PutSynonymSet:
class: SilverStripe\ForagerBifrost\Service\Requests\UpdateSynonymRule
3 changes: 1 addition & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
"php": "^8.1",
"silverstripe/framework": "^5",
"silverstripe/reports": "^5",
"silverstripe/silverstripe-forager-elastic-enterprise": "^1",
"silverstripe/silverstripe-forager": "^1.1.0",
"silverstripe/silverstripe-forager-elastic-enterprise": "^1.1",
"guzzlehttp/guzzle": "^7"
},
"require-dev": {
Expand Down
41 changes: 41 additions & 0 deletions src/Adaptors/Requests/CreateSynonymRuleAdaptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace SilverStripe\ForagerBifrost\Adaptors\Requests;

use Elastic\EnterpriseSearch\Client;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forager\Interfaces\Requests\CreateSynonymRuleAdaptor as PostSynonymRuleAdaptorInterface;
use SilverStripe\Forager\Service\Query\SynonymRule as SynonymRuleQuery;
use SilverStripe\Forager\Service\Results\SynonymRule as SynonymRuleResult;
use SilverStripe\ForagerBifrost\Processors\SynonymRuleProcessor;
use SilverStripe\ForagerBifrost\Service\Requests\CreateSynonymRule;

class CreateSynonymRuleAdaptor implements PostSynonymRuleAdaptorInterface
{

private ?Client $client = null;

private static array $dependencies = [
'client' => '%$' . Client::class . '.managementClient',
];

public function setClient(?Client $client): void
{
$this->client = $client;
}

public function process(int|string $synonymCollectionId, SynonymRuleQuery $synonymRule): SynonymRuleResult
{
$request = Injector::inst()->create(CreateSynonymRule::class, $synonymCollectionId, $synonymRule);

// Should either be successful or throw an exception, which we'll let fly
$body = $this->client->appSearch()->createSynonymSet($request)->asString();
$body = json_decode($body, true);

$synonymRuleResult = SynonymRuleResult::create($body['id']);
SynonymRuleProcessor::applyStringToResult($synonymRuleResult, $body['synonyms']);

return $synonymRuleResult;
}

}
35 changes: 35 additions & 0 deletions src/Adaptors/Requests/DeleteSynonymRuleAdaptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace SilverStripe\ForagerBifrost\Adaptors\Requests;

use Elastic\EnterpriseSearch\AppSearch\Request\DeleteSynonymSet;
use Elastic\EnterpriseSearch\Client;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forager\Interfaces\Requests\DeleteSynonymRuleAdaptor as DeleteSynonymRuleAdaptorInterface;

class DeleteSynonymRuleAdaptor implements DeleteSynonymRuleAdaptorInterface
{

private ?Client $client = null;

private static array $dependencies = [
'client' => '%$' . Client::class . '.managementClient',
];

public function setClient(?Client $client): void
{
$this->client = $client;
}

public function process(int|string $synonymCollectionId, int|string $synonymRuleId): bool
{
$request = Injector::inst()->create(DeleteSynonymSet::class, $synonymCollectionId, $synonymRuleId);

// Should either be successful or throw an exception, which we'll let fly
$body = $this->client->appSearch()->deleteSynonymSet($request)->asString();
$body = json_decode($body, true);

return $body['success'];
}

}
40 changes: 40 additions & 0 deletions src/Adaptors/Requests/GetSynonymRuleAdaptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace SilverStripe\ForagerBifrost\Adaptors\Requests;

use Elastic\EnterpriseSearch\AppSearch\Request\GetSynonymSet;
use Elastic\EnterpriseSearch\Client;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forager\Interfaces\Requests\GetSynonymRuleAdaptor as GetSynonymRuleAdaptorInterface;
use SilverStripe\Forager\Service\Results\SynonymRule;
use SilverStripe\ForagerBifrost\Processors\SynonymRuleProcessor;

class GetSynonymRuleAdaptor implements GetSynonymRuleAdaptorInterface
{

private ?Client $client = null;

private static array $dependencies = [
'client' => '%$' . Client::class . '.managementClient',
];

public function setClient(?Client $client): void
{
$this->client = $client;
}

public function process(int|string $synonymCollectionId, int|string $synonymRuleId): SynonymRule
{
$request = Injector::inst()->create(GetSynonymSet::class, $synonymCollectionId, $synonymRuleId);

// Should either be successful or throw an exception, which we'll let fly
$body = $this->client->appSearch()->getSynonymSet($request)->asString();
$body = json_decode($body, true);

$synonymRule = SynonymRule::create($body['id']);
SynonymRuleProcessor::applyStringToResult($synonymRule, $body['synonyms']);

return $synonymRule;
}

}
47 changes: 47 additions & 0 deletions src/Adaptors/Requests/GetSynonymRulesAdaptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace SilverStripe\ForagerBifrost\Adaptors\Requests;

use Elastic\EnterpriseSearch\AppSearch\Request\ListSynonymSets;
use Elastic\EnterpriseSearch\Client;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forager\Interfaces\Requests\GetSynonymRulesAdaptor as GetSynonymRulesAdaptorInterface;
use SilverStripe\Forager\Service\Results\SynonymRule;
use SilverStripe\Forager\Service\Results\SynonymRules;
use SilverStripe\ForagerBifrost\Processors\SynonymRuleProcessor;

class GetSynonymRulesAdaptor implements GetSynonymRulesAdaptorInterface
{

private ?Client $client = null;

private static array $dependencies = [
'client' => '%$' . Client::class . '.managementClient',
];

public function setClient(?Client $client): void
{
$this->client = $client;
}

public function process(int|string $synonymCollectionId): SynonymRules
{
$request = Injector::inst()->create(ListSynonymSets::class, $synonymCollectionId);

// Should either be successful or throw an exception, which we'll let fly
$body = $this->client->appSearch()->listSynonymSets($request)->asString();
$body = json_decode($body, true);

$synonymRules = SynonymRules::create();

foreach ($body as $result) {
$synonymRule = SynonymRule::create($result['id']);
SynonymRuleProcessor::applyStringToResult($synonymRule, $result['synonyms']);

$synonymRules->add($synonymRule);
}

return $synonymRules;
}

}
49 changes: 49 additions & 0 deletions src/Adaptors/Requests/UpdateSynonymRuleAdaptor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace SilverStripe\ForagerBifrost\Adaptors\Requests;

use Elastic\EnterpriseSearch\Client;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Forager\Interfaces\Requests\UpdateSynonymRuleAdaptor as PatchSynonymRuleAdaptorInterface;
use SilverStripe\Forager\Service\Query\SynonymRule as SynonymRuleQuery;
use SilverStripe\Forager\Service\Results\SynonymRule as SynonymRuleResult;
use SilverStripe\ForagerBifrost\Processors\SynonymRuleProcessor;
use SilverStripe\ForagerBifrost\Service\Requests\UpdateSynonymRule;

class UpdateSynonymRuleAdaptor implements PatchSynonymRuleAdaptorInterface
{

private ?Client $client = null;

private static array $dependencies = [
'client' => '%$' . Client::class . '.managementClient',
];

public function setClient(?Client $client): void
{
$this->client = $client;
}

public function process(
int|string $synonymCollectionId,
int|string $synonymRuleId,
SynonymRuleQuery $synonymRule
): SynonymRuleResult {
$request = Injector::inst()->create(
UpdateSynonymRule::class,
$synonymCollectionId,
$synonymRuleId,
$synonymRule
);

// Should either be successful or throw an exception, which we'll let fly
$body = $this->client->appSearch()->createSynonymSet($request)->asString();
$body = json_decode($body, true);

$synonymRuleResult = SynonymRuleResult::create($body['id']);
SynonymRuleProcessor::applyStringToResult($synonymRuleResult, $body['synonyms']);

return $synonymRuleResult;
}

}
48 changes: 48 additions & 0 deletions src/Processors/SynonymRuleProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace SilverStripe\ForagerBifrost\Processors;

use SilverStripe\Core\Injector\Injectable;
use SilverStripe\Forager\Service\Query\SynonymRule as SynonymRuleQuery;
use SilverStripe\Forager\Service\Results\SynonymRule as SynonymRuleResult;

class SynonymRuleProcessor
{

use Injectable;

public static function getStringFromQuery(SynonymRuleQuery $synonymRule): string
{
if ($synonymRule->getType() === SynonymRuleResult::TYPE_EQUIVALENT) {
return implode(', ', $synonymRule->getSynonyms());
}

return sprintf(
'%s => %s',
implode(', ', $synonymRule->getRoot()),
implode(', ', $synonymRule->getSynonyms())
);
}

public static function applyStringToResult(SynonymRuleResult $synonymRule, string $synonymsString): void
{
$type = str_contains($synonymsString, '=>')
? SynonymRuleResult::TYPE_DIRECTIONAL
: SynonymRuleResult::TYPE_EQUIVALENT;

$synonymRule->setType($type);

if ($synonymRule->getType() === SynonymRuleResult::TYPE_DIRECTIONAL) {
$split = explode('=>', $synonymsString);
// We'd expect there to always be 2 items
$root = trim($split[0]);
$synonyms = trim($split[1]);

$synonymRule->setRoot(array_map('trim', explode(',', $root)));
$synonymRule->setSynonyms(array_map('trim', explode(',', $synonyms)));
} else {
$synonymRule->setSynonyms(array_map('trim', explode(',', $synonymsString)));
}
}

}
24 changes: 24 additions & 0 deletions src/Service/Requests/CreateSynonymRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace SilverStripe\ForagerBifrost\Service\Requests;

use Elastic\EnterpriseSearch\AppSearch\Request\CreateSynonymSet;
use SilverStripe\Forager\Service\Query\SynonymRule as SynonymRuleQuery;
use SilverStripe\ForagerBifrost\Processors\SynonymRuleProcessor;
use stdClass;

class CreateSynonymRule extends CreateSynonymSet
{

public function __construct(string $synonymCollectionId, SynonymRuleQuery $synonymRule)
{
$body = new stdClass();
$body->synonyms = SynonymRuleProcessor::singleton()->getStringFromQuery($synonymRule);

$this->method = 'POST';
$this->headers['Content-Type'] = 'application/json';
$this->path = sprintf('/api/v1/%s/synonyms', $synonymCollectionId);
$this->body = $body;
}

}
17 changes: 17 additions & 0 deletions src/Service/Requests/DeleteSynonymRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace SilverStripe\ForagerBifrost\Service\Requests;

use Elastic\EnterpriseSearch\AppSearch\Request\DeleteSynonymSet;

class DeleteSynonymRule extends DeleteSynonymSet
{

public function __construct(string $synonymCollectionId, string $synonymRuleId)
{
parent::__construct($synonymCollectionId, $synonymRuleId);

$this->path = sprintf('/api/v1/%s/synonyms/%s', $synonymCollectionId, $synonymRuleId);
}

}
17 changes: 17 additions & 0 deletions src/Service/Requests/GetSynonymRule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace SilverStripe\ForagerBifrost\Service\Requests;

use Elastic\EnterpriseSearch\AppSearch\Request\GetSynonymSet;

class GetSynonymRule extends GetSynonymSet
{

public function __construct(string $synonymCollectionId, string $synonymRuleId)
{
parent::__construct($synonymCollectionId, $synonymRuleId);

$this->path = sprintf('/api/v1/%s/synonyms/%s', $synonymCollectionId, $synonymRuleId);
}

}
17 changes: 17 additions & 0 deletions src/Service/Requests/GetSynonymRules.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace SilverStripe\ForagerBifrost\Service\Requests;

use Elastic\EnterpriseSearch\AppSearch\Request\ListSynonymSets;

class GetSynonymRules extends ListSynonymSets
{

public function __construct(string $synonymCollectionId)
{
parent::__construct($synonymCollectionId);

$this->path = sprintf('/api/v1/%s/synonyms', $synonymCollectionId);
}

}
Loading