Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reflect changes in the search service for OC 16. #22

Merged
merged 4 commits into from
Jun 13, 2024
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
5 changes: 5 additions & 0 deletions src/OpencastApi/Opencast.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class Opencast
'connect_timeout' => 0 // The API connection timeout. In seconds (default 0 to wait indefinitely) (optional)
'version' => null // The API Version. (Default null). (optional)
'handler' => null // The callable Handler or HandlerStack. (Default null). (optional)
'features' => null // A set of additional features [e.g. lucene search]. (Default null). (optional)
]

$engageConfig = [
Expand All @@ -91,6 +92,7 @@ class Opencast
'connect_timeout' => 0 // The API connection timeout. In seconds (default 0 to wait indefinitely) (optional)
'version' => null // The API Version. (Default null). (optional)
'handler' => null // The callable Handler or HandlerStack. (Default null). (optional)
'features' => null // A set of additional features [e.g. lucene search]. (Default null). (optional)
]
*/
/**
Expand Down Expand Up @@ -171,6 +173,9 @@ private function setEngageRestClient($config, $engageConfig)
if (!isset($engageConfig['handler']) && isset($config['handler'])) {
$engageConfig['handler'] = $config['handler'];
}
if (!isset($engageConfig['features']) && isset($config['features'])) {
$engageConfig['features'] = $config['features'];
}
$this->engageRestClient = new OcRestClient($engageConfig);
}

Expand Down
22 changes: 20 additions & 2 deletions src/OpencastApi/Rest/OcRestClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ class OcRestClient extends Client
private $additionalHeaders = [];
private $noHeader = false;
private $origin;
private $features = [];
/*
$config = [
'url' => 'https://develop.opencast.org/', // The API url of the opencast instance (required)
'username' => 'admin', // The API username. (required)
'password' => 'opencast', // The API password. (required)
'timeout' => 0, // The API timeout. In seconds (default 0 to wait indefinitely). (optional)
'connect_timeout' => 0, // The API connection timeout. In seconds (default 0 to wait indefinitely) (optional)
'version' => null // The API Version. (Default null). (optional)
'handler' => null // The callable Handler or HandlerStack. (Default null). (optional)
'version' => null, // The API Version. (Default null). (optional)
'handler' => null, // The callable Handler or HandlerStack. (Default null). (optional)
'features' => null // A set of additional features [e.g. lucene search]. (Default null). (optional)
]
*/
public function __construct($config)
Expand All @@ -51,9 +53,25 @@ public function __construct($config)
if (isset($config['handler']) && is_callable($config['handler'])) {
$parentConstructorConfig['handler'] = $config['handler'];
}

if (isset($config['features'])) {
$this->features = $config['features'];
}

parent::__construct($parentConstructorConfig);
}

public function readFeatures($key = null) {
if (empty($key)) {
return $this->features;
}

if (isset($this->features[$key])) {
return $this->features[$key];
}
return false;
}

public function registerHeaderException($header, $path) {
$path = ltrim($path, '/');
if (!isset($this->headerExceptions[$header]) || !in_array($path, $this->headerExceptions[$header])) {
Expand Down
144 changes: 102 additions & 42 deletions src/OpencastApi/Rest/OcSearch.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
<?php
<?php
namespace OpencastApi\Rest;

class OcSearch extends OcRest
{
const URI = '/search';
public $lucene = false; // By default false, main support for OC 16.

public function __construct($restClient)
{
$restClient->registerHeaderException('Accept', self::URI);
parent::__construct($restClient);
if ($restClient->readFeatures('lucene')) {
$this->lucene = true;
}
}


/**
* Search for episodes matching the query parameters as object (JSON) by default or XML (text) on demand.
*
* @param array $params the params to pass to the call: it must cointain the following:
*
* @param array $params the params to pass to the call: it must cointain the following:
* $params = [
* 'id' => '{The ID of the single episode to be returned, if it exists}',
* 'q' => '{Any episode that matches this free-text query.}',
Expand All @@ -28,7 +32,7 @@ public function __construct($restClient)
* 'sign' => '{If results are to be signed (Default value=true)}',
* ]
* @param string $format The output format (json or xml) of the response body. (Default value = 'json')
*
*
* @return array the response result ['code' => 200, 'body' => '{The search results, formatted as xml or json}']
*/
public function getEpisodes($params = [], $format = '')
Expand Down Expand Up @@ -64,30 +68,58 @@ public function getEpisodes($params = [], $format = '')
$query['sign'] = $params['sign'];
}

$sortsASC = [
'DATE_CREATED', 'DATE_MODIFIED', 'TITLE', 'SERIES_ID',
'MEDIA_PACKAGE_ID', 'CREATOR', 'CONTRIBUTOR', 'LANGUAGE',
'LICENSE','SUBJECT','DESCRIPTION','PUBLISHER',
];
$sortsDESC = array_map(function ($sort) {
return "{$sort}_DESC";
}, $sortsASC);

$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
// OC <= 15
if ($this->lucene) {
$sortsASC = [
'DATE_CREATED', 'DATE_MODIFIED', 'TITLE', 'SERIES_ID',
'MEDIA_PACKAGE_ID', 'CREATOR', 'CONTRIBUTOR', 'LANGUAGE',
'LICENSE','SUBJECT','DESCRIPTION','PUBLISHER',
];
$sortsDESC = array_map(function ($sort) {
return "{$sort}_DESC";
}, $sortsASC);

$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
}

// OC >= 16
} else {
$sorts = [
'modified', 'title', 'creator', 'contributor'
];

$sortsASC = array_map(function ($sort) {
return "{$sort} asc";
}, $sorts);

$sortsDESC = array_map(function ($sort) {
return "{$sort} desc";
}, $sorts);

$sorts_list = array_merge($sorts, $sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array(strtolower($params['sort']), $sorts_list)) {
$query['sort'] = strtolower($params['sort']);
}
}

$options = $this->restClient->getQueryParams($query);
return $this->restClient->performGet($uri, $options);
}


/**
* Search a lucene query as object (JSON) by default or XML (text) on demand.
*
* @param array $params the params to pass to the call: it must cointain the following:
*
* INFO: This endpoint is removed in Opencast 16.
*
* @param array $params the params to pass to the call: it must cointain the following:
* $params = [
* 'q' => '{ The lucene query. }',
* 'series' => '{ Include series in the search result. (Default value=false)}',
Expand All @@ -98,11 +130,15 @@ public function getEpisodes($params = [], $format = '')
* 'sign' => '{If results are to be signed (Default value=true)}',
* ]
* @param string $format The output format (json or xml) of the response body. (Default value = 'json')
*
*
* @return array the response result ['code' => 200, 'body' => '{The search results, formatted as xml or json}']
*/
public function getLucene($params = [], $format = '')
{
if (!$this->lucene) {
return ['code' => 410, 'reason' => 'Lucene search endpoint is not available!'];
}

$uri = self::URI . "/lucene.json";
if (!empty($format) && strtolower($format) == 'xml') {
$uri = str_replace('json', 'xml', $uri);
Expand Down Expand Up @@ -138,20 +174,20 @@ public function getLucene($params = [], $format = '')
}, $sortsASC);

$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
}

$options = $this->restClient->getQueryParams($query);
return $this->restClient->performGet($uri, $options);
}

/**
* Search for series matching the query parameters and returns JSON (object) by default or XML (text) on demand
*
* @param array $params the params to pass to the call: it must cointain the following:
*
* @param array $params the params to pass to the call: it must cointain the following:
* $params = [
* 'id' = '{The series ID. If the additional boolean parameter "episodes" is "true", the result set will include this series episodes.}'
* 'q' => '{Any series that matches this free-text query. If the additional boolean parameter "episodes" is "true", the result set will include this series episodes.}',
Expand All @@ -163,7 +199,7 @@ public function getLucene($params = [], $format = '')
* 'sign' => '{If results are to be signed (Default value=true)}',
* ]
* @param string $format The output format (json or xml) of the response body. (Default value = 'json')
*
*
* @return array the response result ['code' => 200, 'body' => '{The search results, formatted as xml or json}']
*/
public function getSeries($params = [], $format = '')
Expand Down Expand Up @@ -196,24 +232,48 @@ public function getSeries($params = [], $format = '')
$query['sign'] = $params['sign'];
}

$sortsASC = [
'DATE_CREATED', 'DATE_MODIFIED', 'TITLE', 'SERIES_ID',
'MEDIA_PACKAGE_ID', 'CREATOR', 'CONTRIBUTOR', 'LANGUAGE',
'LICENSE','SUBJECT','DESCRIPTION','PUBLISHER',
];
$sortsDESC = array_map(function ($sort) {
return "{$sort}_DESC";
}, $sortsASC);
// OC <= 15
if ($this->lucene) {
$sortsASC = [
'DATE_CREATED', 'DATE_MODIFIED', 'TITLE', 'SERIES_ID',
'MEDIA_PACKAGE_ID', 'CREATOR', 'CONTRIBUTOR', 'LANGUAGE',
'LICENSE','SUBJECT','DESCRIPTION','PUBLISHER',
];
$sortsDESC = array_map(function ($sort) {
return "{$sort}_DESC";
}, $sortsASC);

$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
$sorts = array_merge($sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array($params['sort'], $sorts)) {
$query['sort'] = $params['sort'];
}

// OC >= 16
} else {
$sorts = [
'modified', 'title', 'creator', 'contributor'
];

$sortsASC = array_map(function ($sort) {
return "{$sort} asc";
}, $sorts);

$sortsDESC = array_map(function ($sort) {
return "{$sort} desc";
}, $sorts);

$sorts_list = array_merge($sorts, $sortsASC, $sortsDESC);

if (array_key_exists('sort', $params) && !empty($params['sort']) &&
in_array(strtolower($params['sort']), $sorts_list)) {
$query['sort'] = strtolower($params['sort']);
}
}

$options = $this->restClient->getQueryParams($query);
return $this->restClient->performGet($uri, $options);
}
}
?>
?>
12 changes: 4 additions & 8 deletions tests/DataProvider/SearchDataProvider.php
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
<?php
<?php
namespace Tests\DataProvider;

class SearchDataProvider {

public static function getEpisodeQueryCases(): array
{
return [
[[], 'json'],
[[], 'xml'],
[[], 'XML'],
[['id' => 'fe0b45b0-7ed5-4944-8b0a-a0a283331791'], ''],
[['sid' => '8010876e-1dce-4d38-ab8d-24b956e3d8b7'], ''],
[['sname' => 'HUB_LOCAL_TEST'], ''],
[['sort' => 'DATE_CREATED_DESC'], ''],
[['sort' => 'modified asc'], ''],
[['offset' => 1], ''],
[['limit' => 1], ''],
[['admin' => true], ''],
Expand All @@ -39,11 +37,9 @@ public static function getSeriesQueryCases(): array
{
return [
[[], 'json'],
[[], 'xml'],
[[], 'XML'],
[['id' => '8010876e-1dce-4d38-ab8d-24b956e3d8b7'], ''],
[['episodes' => true], ''],
[['sort' => 'DATE_CREATED_DESC'], ''],
[['sort' => 'modified desc'], ''],
[['offset' => 1], ''],
[['limit' => 1], ''],
[['admin' => true], ''],
Expand Down
7 changes: 5 additions & 2 deletions tests/DataProvider/SetupDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ public static function getConfig($version = ''): array
'username' => $username,
'password' => $password,
'timeout' => $timeout,
'version' => '1.9.0',
'connect_timeout' => $connectTimeout
'version' => '1.11.0',
'connect_timeout' => $connectTimeout,
'features' => [
'lucene' => false
]
];
if (!empty($version)) {
$config['version'] = $version;
Expand Down
16 changes: 8 additions & 8 deletions tests/Unit/OcSearchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,22 @@ public function get_eposides($params, $format): void

/**
* @test
* @dataProvider \Tests\DataProvider\SearchDataProvider::getLuceneQueryCases()
* @dataProvider \Tests\DataProvider\SearchDataProvider::getSeriesQueryCases()
*/
public function get_lucenes($params, $format): void
public function get_series($params, $format): void
{
$response = $this->ocSearch->getLucene($params, $format);
$this->assertSame(200, $response['code'], 'Failure to search lucene');
$response = $this->ocSearch->getSeries($params, $format);
$this->assertSame(200, $response['code'], 'Failure to search series');
}

/**
* @test
* @dataProvider \Tests\DataProvider\SearchDataProvider::getSeriesQueryCases()
* @dataProvider \Tests\DataProvider\SearchDataProvider::getLuceneQueryCases()
*/
public function get_series($params, $format): void
public function get_lucenes($params, $format): void
{
$response = $this->ocSearch->getSeries($params, $format);
$this->assertSame(200, $response['code'], 'Failure to search series');
$response = $this->ocSearch->getLucene($params, $format);
$this->assertContains($response['code'], [200, 410], 'Failure to create an event');
}
}
?>
4 changes: 2 additions & 2 deletions tests/UnitMock/OcSearchTestMock.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ public function get_eposides(): void
* @test
*/
public function get_lucenes(): void
{
{
$params = ['series' => true];
$response = $this->ocSearch->getLucene($params);
$this->assertSame(200, $response['code'], 'Failure to search lucene');
$this->assertContains($response['code'], [200, 410], 'Failure to create an event');
}

/**
Expand Down
Loading