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
14 changes: 14 additions & 0 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ class Client
*/
public NLSearchModels $nlSearchModels;

/**
* @var SynonymSets
*/
public SynonymSets $synonymSets;

/**
* @var ApiCall
*/
Expand Down Expand Up @@ -121,6 +126,7 @@ public function __construct(array $config)
$this->stemming = new Stemming($this->apiCall);
$this->conversations = new Conversations($this->apiCall);
$this->nlSearchModels = new NLSearchModels($this->apiCall);
$this->synonymSets = new SynonymSets($this->apiCall);
}

/**
Expand Down Expand Up @@ -234,4 +240,12 @@ public function getNLSearchModels(): NLSearchModels
{
return $this->nlSearchModels;
}

/**
* @return SynonymSets
*/
public function getSynonymSets(): SynonymSets
{
return $this->synonymSets;
}
}
77 changes: 77 additions & 0 deletions src/SynonymSet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Typesense;

use Http\Client\Exception as HttpClientException;
use Typesense\Exceptions\TypesenseClientError;

/**
* Class SynonymSet
*
* @package \Typesense
*/
class SynonymSet
{
/**
* @var string
*/
private string $synonymSetName;

/**
* @var ApiCall
*/
private ApiCall $apiCall;

/**
* SynonymSet constructor.
*
* @param string $synonymSetName
* @param ApiCall $apiCall
*/
public function __construct(string $synonymSetName, ApiCall $apiCall)
{
$this->synonymSetName = $synonymSetName;
$this->apiCall = $apiCall;
}

/**
* @return string
*/
private function endPointPath(): string
{
return sprintf(
'%s/%s',
SynonymSets::RESOURCE_PATH,
encodeURIComponent($this->synonymSetName)
);
}

/**
* @param array $params
*
* @return array
* @throws TypesenseClientError|HttpClientException
*/
public function upsert(array $params): array
{
return $this->apiCall->put($this->endPointPath(), $params);
}

/**
* @return array
* @throws TypesenseClientError|HttpClientException
*/
public function retrieve(): array
{
return $this->apiCall->get($this->endPointPath(), []);
}

/**
* @return array
* @throws TypesenseClientError|HttpClientException
*/
public function delete(): array
{
return $this->apiCall->delete($this->endPointPath());
}
}
93 changes: 93 additions & 0 deletions src/SynonymSets.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace Typesense;

use Http\Client\Exception as HttpClientException;
use Typesense\Exceptions\TypesenseClientError;

/**
* Class SynonymSets
*
* @package \Typesense
*/
class SynonymSets implements \ArrayAccess
{
public const RESOURCE_PATH = '/synonym_sets';

/**
* @var ApiCall
*/
private ApiCall $apiCall;

/**
* @var array
*/
private array $synonymSets = [];

/**
* SynonymSets constructor.
*
* @param ApiCall $apiCall
*/
public function __construct(ApiCall $apiCall)
{
$this->apiCall = $apiCall;
}

/**
* @param string $synonymSetName
* @param array $config
*
* @return array
* @throws TypesenseClientError|HttpClientException
*/
public function upsert(string $synonymSetName, array $config): array
{
return $this->apiCall->put(sprintf('%s/%s', static::RESOURCE_PATH, encodeURIComponent($synonymSetName)), $config);
}

/**
* @return array
* @throws TypesenseClientError|HttpClientException
*/
public function retrieve(): array
{
return $this->apiCall->get(static::RESOURCE_PATH, []);
}

/**
* @inheritDoc
*/
public function offsetExists($synonymSetName): bool
{
return isset($this->synonymSets[$synonymSetName]);
}

/**
* @inheritDoc
*/
public function offsetGet($synonymSetName): SynonymSet
{
if (!isset($this->synonymSets[$synonymSetName])) {
$this->synonymSets[$synonymSetName] = new SynonymSet($synonymSetName, $this->apiCall);
}

return $this->synonymSets[$synonymSetName];
}

/**
* @inheritDoc
*/
public function offsetSet($synonymSetName, $value): void
{
$this->synonymSets[$synonymSetName] = $value;
}

/**
* @inheritDoc
*/
public function offsetUnset($synonymSetName): void
{
unset($this->synonymSets[$synonymSetName]);
}
}
14 changes: 13 additions & 1 deletion tests/Feature/AnalyticsEventsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Feature;

use Tests\TestCase;
use Exception;

class AnalyticsEventsTest extends TestCase
{
Expand All @@ -11,6 +12,11 @@ class AnalyticsEventsTest extends TestCase
protected function setUp(): void
{
parent::setUp();

if ($this->isV30OrAbove()) {
$this->markTestSkipped('Analytics is deprecated in Typesense v30+');
}

$this->client()->collections->create([
"name" => "products",
"fields" => [
Expand Down Expand Up @@ -52,7 +58,13 @@ protected function setUp(): void
protected function tearDown(): void
{
parent::tearDown();
$this->client()->analytics->rules()->{'product_queries_aggregation'}->delete();

if (!$this->isV30OrAbove()) {
try {
$this->client()->analytics->rules()->{'product_queries_aggregation'}->delete();
} catch (Exception $e) {
}
}
}

public function testCanCreateAnEvent(): void
Expand Down
19 changes: 16 additions & 3 deletions tests/Feature/AnalyticsRulesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Tests\TestCase;
use Typesense\Exceptions\ObjectNotFound;
use Exception;

class AnalyticsRulesTest extends TestCase
{
Expand All @@ -26,14 +27,26 @@ class AnalyticsRulesTest extends TestCase
protected function setUp(): void
{
parent::setUp();

if ($this->isV30OrAbove()) {
$this->markTestSkipped('Analytics is deprecated in Typesense v30+');
}

$this->ruleUpsertResponse = $this->client()->analytics->rules()->upsert($this->ruleName, $this->ruleConfiguration);
}

protected function tearDown(): void
{
$rules = $this->client()->analytics->rules()->retrieve();
foreach ($rules['rules'] as $rule) {
$this->client()->analytics->rules()->{$rule['name']}->delete();
if (!$this->isV30OrAbove()) {
try {
$rules = $this->client()->analytics->rules()->retrieve();
if (is_array($rules) && isset($rules['rules'])) {
foreach ($rules['rules'] as $rule) {
$this->client()->analytics->rules()->{$rule['name']}->delete();
}
}
} catch (Exception $e) {
}
}
}

Expand Down
61 changes: 61 additions & 0 deletions tests/Feature/SynonymSetsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace Feature;

use Tests\TestCase;
use Typesense\Exceptions\ObjectNotFound;
use Exception;

class SynonymSetsTest extends TestCase
{
private $upsertResponse = null;
private $synonymSets = null;
private $synonymSetData = [
'synonyms' => [
[
'id' => 'dummy',
'synonyms' => ['foo', 'bar', 'baz'],
'root' => '',
],
],
];

protected function setUp(): void
{
parent::setUp();

if (!$this->isV30OrAbove()) {
$this->markTestSkipped('SynonymSets is only supported in Typesense v30+');
}

$this->synonymSets = $this->client()->synonymSets;
$this->upsertResponse = $this->synonymSets->upsert('test-synonym-set', $this->synonymSetData);
}


public function testCanUpsertASynonymSet(): void
{
$this->assertEquals($this->synonymSetData['synonyms'], $this->upsertResponse['synonyms']);
}

public function testCanRetrieveAllSynonymSets(): void
{
$returnData = $this->synonymSets->retrieve();
$this->assertCount(1, $returnData);
}

public function testCanRetrieveASpecificSynonymSet(): void
{
$returnData = $this->synonymSets['test-synonym-set']->retrieve();
$this->assertEquals($this->synonymSetData['synonyms'], $returnData['synonyms']);
}

public function testCanDeleteASynonymSet(): void
{
$returnData = $this->synonymSets['test-synonym-set']->delete();
$this->assertEquals('test-synonym-set', $returnData['name']);

$this->expectException(ObjectNotFound::class);
$this->synonymSets['test-synonym-set']->retrieve();
}
}
5 changes: 5 additions & 0 deletions tests/Feature/SynonymsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class SynonymsTest extends TestCase
protected function setUp(): void
{
parent::setUp();

if ($this->isV30OrAbove()) {
$this->markTestSkipped('Synonyms is deprecated in Typesense v30+, use SynonymSets instead');
}

$this->setUpCollection('books');

$this->synonyms = $this->client()->collections['books']->synonyms;
Expand Down
22 changes: 22 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Typesense\Client;
use Mockery;
use Typesense\ApiCall;
use Exception;

abstract class TestCase extends BaseTestCase
{
Expand Down Expand Up @@ -98,4 +99,25 @@ protected function tearDownTypesense(): void
$this->typesenseClient->collections[$collection['name']]->delete();
}
}

protected function isV30OrAbove(): bool
{
try {
$debug = $this->typesenseClient->debug->retrieve();
$version = $debug['version'];

if ($version === 'nightly') {
return true;
}

if (preg_match('/^v(\d+)/', $version, $matches)) {
$majorVersion = (int) $matches[1];
return $majorVersion >= 30;
}

return false;
} catch (Exception $e) {
return false;
}
}
}