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

Added ability to list broadcasts #288

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
79 changes: 79 additions & 0 deletions src/OpenTok/BroadcastList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace OpenTok;

use OpenTok\Util\Client;
use OpenTok\Util\Validators;

/**
* A class for accessing an array of Archive objects.
*/
class BroadcastList
{
/**
* @internal
*/
private $data;
/**
* @internal
*/
private $client;
/**
* @internal
*/
private $items;

/**
* @internal
*/
public function __construct($broadcastListData, $options = array())
{
// unpack optional arguments (merging with default values) into named variables
$defaults = array(
'apiKey' => null,
'apiSecret' => null,
'apiUrl' => 'https://api.opentok.com',
'client' => null
);
$options = array_merge($defaults, array_intersect_key($options, $defaults));
list($apiKey, $apiSecret, $apiUrl, $client) = array_values($options);

// validate params
Validators::validateBroadcastListData($broadcastListData);
Validators::validateClient($client);

$this->data = $broadcastListData;

$this->client = isset($client) ? $client : new Client();
if (!$this->client->isConfigured()) {
Validators::validateApiKey($apiKey);
Validators::validateApiSecret($apiSecret);
Validators::validateApiUrl($apiUrl);

$this->client->configure($apiKey, $apiSecret, $apiUrl);
}
}

/**
* Returns the number of total archives for the API key.
*/
public function totalCount()
{
return $this->data['count'];
}

/**
* Returns an array of Archive objects.
*/
public function getItems()
{
if (!$this->items) {
$items = array();
foreach ($this->data['items'] as $broadcastData) {
$items[] = new Broadcast($broadcastData, array( 'client' => $this->client ));
}
$this->items = $items;
}
return $this->items;
}
}
28 changes: 28 additions & 0 deletions src/OpenTok/OpenTok.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use OpenTok\Layout;
use OpenTok\Util\Client;
use OpenTok\BroadcastList;
use OpenTok\Util\Validators;
use OpenTok\Exception\InvalidArgumentException;
use OpenTok\Exception\UnexpectedValueException;
Expand Down Expand Up @@ -478,6 +479,33 @@ public function forceDisconnect($sessionId, $connectionId)
return $this->client->forceDisconnect($sessionId, $connectionId);
}

/**
* Returns an BroadcastList. The <code>items()</code> method of this object returns a list of
* broadcasts that are completed and in-progress, for your API key.
*
* @param integer $offset Optional. The index offset of the first broadcast. 0 is offset of the
* most recently started broadcast. 1 is the offset of the broadcast that started prior to the most
* recent broadcast. If you do not specify an offset, 0 is used.
* @param integer $count Optional. The number of broadcasts to be returned. The maximum number of
* broadcasts returned is 1000.
* @param string $sessionId Optional. The OpenTok session Id for which you want to retrieve broadcasts for. If no session Id
* is specified, the method will return archives from all sessions created with the API key.
*
* @return BroadcastList An ArchiveList object. Call the items() method of the ArchiveList object
* to return an array of Archive objects.
*/
public function listBroadcasts($offset = 0, $count = null, $sessionId = null)
{
// validate params
Validators::validateOffsetAndCount($offset, $count);
if (!is_null($sessionId)) {
Validators::validateSessionIdBelongsToKey($sessionId, $this->apiKey);
}

$broadcastListData = $this->client->listBroadcasts($offset, $count, $sessionId);
return new BroadcastList($broadcastListData, array( 'client' => $this->client ));
}

/**
* Starts a live streaming broadcast of an OpenTok session.
*
Expand Down
26 changes: 26 additions & 0 deletions src/OpenTok/Util/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,32 @@ public function listArchives($offset, $count, $sessionId)
return $archiveListJson;
}

public function listBroadcasts($offset, $count, $sessionId)
{
$request = new Request('GET', '/v2/project/' . $this->apiKey . '/broadcast');
$queryParams = [];
if ($offset != 0) {
$queryParams['offset'] = $offset;
}
if (!empty($count)) {
$queryParams['count'] = $count;
}
if (!empty($sessionId)) {
$queryParams['sessionId'] = $sessionId;
}
try {
$response = $this->client->send($request, [
'debug' => $this->isDebug(),
'query' => $queryParams
]);
$broadcastListJson = json_decode($response->getBody(), true);
} catch (\Exception $e) {
$this->handleException($e);
return;
}
return $broadcastListJson;
}

public function startBroadcast(string $sessionId, array $options): array
{
$request = new Request(
Expand Down
19 changes: 19 additions & 0 deletions src/OpenTok/Util/Validators.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Validators
public static $guidRegEx = '/^\[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}\$/';
public static $archiveSchemaUri;
public static $broadcastSchemaUri;
public static $broadcastListSchemaUri;

public static function validateApiKey($apiKey)
{
Expand Down Expand Up @@ -195,6 +196,24 @@ public static function validateArchiveListData($archiveListData)
);
}
}

public static function validateBroadcastListData($broadcastListData)
{
if (!self::$broadcastListSchemaUri) {
self::$broadcastListSchemaUri = __DIR__ . '/broadcast-list-schema.json';
}
$document = new Document();
// have to do a encode+decode so that json objects decoded as arrays from Guzzle
// are re-encoded as objects instead
$document->loadData(json_decode(json_encode($broadcastListData)));
$document->loadSchema(self::$broadcastListSchemaUri);
if (!$document->validate()) {
throw new InvalidArgumentException(
'The broadcast data provided is not valid. Errors:' . $document->lastError . ' broadcastListData:' . print_r($broadcastListData, true)
);
}
}

public static function validateOffsetAndCount($offset, $count)
{
if (
Expand Down
56 changes: 56 additions & 0 deletions src/OpenTok/Util/broadcast-list-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"$schema": "http://json-schema.org/draft-06/schema#",
"type":"object",
"properties": {
"count": {
"description": "Total number of broadcasts of the query",
"type": "integer"
},
"items": {
"type": "array",
"items": {
"title": "Broadcast",
"description": "An OpenTok Broadcast",
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}$"
},
"sessionId": {
"type": "string"
},
"projectId": {
"type": "integer"
},
"createdAt": {
"type" : "integer"
},
"updatedAt": {
"type" : "integer"
},
"resolution": {
"type": "string"
},
"broadcastUrls": {
"oneOf": [
{
"type": "null"
},
{
"type": "object",
"properties": {
"hls": {
"type": "string"
}
}
}
]
}
},
"required": ["id", "sessionId", "projectId", "createdAt", "updatedAt"]
}
}
},
"required": ["count", "items"]
}
7 changes: 5 additions & 2 deletions src/OpenTok/Util/broadcast-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"sessionId": {
"type": "string"
},
"partnerId": {
"projectId": {
"type": "integer"
},
"createdAt": {
Expand All @@ -20,6 +20,9 @@
"updatedAt": {
"type" : "integer"
},
"resolution": {
"type": "string"
},
"broadcastUrls": {
"oneOf": [
{
Expand All @@ -36,5 +39,5 @@
]
}
},
"required": ["id", "sessionId", "partnerId", "createdAt", "updatedAt"]
"required": ["id", "sessionId", "projectId", "createdAt", "updatedAt"]
}
114 changes: 114 additions & 0 deletions tests/OpenTokTest/OpenTokTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
use PHPUnit\Framework\TestCase;
use GuzzleHttp\Handler\MockHandler;
use InvalidArgumentException as GlobalInvalidArgumentException;
use OpenTok\BroadcastList;
use OpenTok\Exception\AuthenticationException;
use OpenTok\Exception\DomainException as ExceptionDomainException;
use OpenTok\Exception\InvalidArgumentException;
Expand Down Expand Up @@ -1161,6 +1162,119 @@ public function testForceDisconnectConnectionException()

}

public function testListsBroadcasts()
{
// Arrange
$this->setupOTWithMocks([[
'code' => 200,
'headers' => [
'Content-Type' => 'application/json'
],
'path' => 'v2/project/APIKEY/broadcast/index'
]]);

// Act
$broadcastList = $this->opentok->listBroadcasts();

// Assert
$this->assertCount(1, $this->historyContainer);

$request = $this->historyContainer[0]['request'];
$this->assertEquals('GET', strtoupper($request->getMethod()));
$this->assertEquals('/v2/project/'.$this->API_KEY.'/broadcast', $request->getUri()->getPath());
$this->assertEquals('api.opentok.com', $request->getUri()->getHost());
$this->assertEquals('https', $request->getUri()->getScheme());

$authString = $request->getHeaderLine('X-OPENTOK-AUTH');
$this->assertEquals(true, TestHelpers::validateOpenTokAuthHeader($this->API_KEY, $this->API_SECRET, $authString));

$userAgent = $request->getHeaderLine('User-Agent');
$this->assertNotEmpty($userAgent);
$this->assertStringStartsWith('OpenTok-PHP-SDK/4.9.0', $userAgent);

$this->assertInstanceOf(BroadcastList::class, $broadcastList);
}

public function testListsBroadcastsWithOffsetAndCount()
{
// Arrange
$this->setupOTWithMocks([[
'code' => 200,
'headers' => [
'Content-Type' => 'application/json'
],
'path' => 'v2/project/APIKEY/broadcast/index-page-2'
]]);

// Act
$broadcastList = $this->opentok->listBroadcasts(1, 1);

// Assert
$this->assertCount(1, $this->historyContainer);

$request = $this->historyContainer[0]['request'];
$this->assertEquals('GET', strtoupper($request->getMethod()));
$this->assertEquals('/v2/project/'.$this->API_KEY.'/broadcast', $request->getUri()->getPath());
$this->assertEquals('api.opentok.com', $request->getUri()->getHost());
$this->assertEquals('https', $request->getUri()->getScheme());

$authString = $request->getHeaderLine('X-OPENTOK-AUTH');
$this->assertEquals(true, TestHelpers::validateOpenTokAuthHeader($this->API_KEY, $this->API_SECRET, $authString));

// TODO: test the dynamically built User Agent string
$userAgent = $request->getHeaderLine('User-Agent');
$this->assertNotEmpty($userAgent);
$this->assertStringStartsWith('OpenTok-PHP-SDK/4.9.0', $userAgent);

$this->assertInstanceOf(BroadcastList::class, $broadcastList);
$this->assertEquals(1, $broadcastList->totalCount());
$this->assertEquals('1c46ad10-0a81-464c-9759-748b707d3734', $broadcastList->getItems()[0]->id);
}

public function testListsBroadcastsWithSessionId()
{
// Arrange
$this->setupOTWithMocks([[
'code' => 200,
'headers' => [
'Content-Type' => 'application/json'
],
'path' => 'v2/project/APIKEY/broadcast/index'
]]);

$sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI';
$bogusApiKey = '12345678';
$bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789';
$opentok = new OpenTok($bogusApiKey, $bogusApiSecret);

// Act
$broadcastList = $this->opentok->listBroadcasts(0, null, $sessionId);

// Assert
$this->assertCount(1, $this->historyContainer);

$request = $this->historyContainer[0]['request'];
$this->assertEquals('GET', strtoupper($request->getMethod()));
$this->assertEquals('/v2/project/'.$this->API_KEY.'/broadcast', $request->getUri()->getPath());
$this->assertEquals('api.opentok.com', $request->getUri()->getHost());
$this->assertEquals('https', $request->getUri()->getScheme());

$authString = $request->getHeaderLine('X-OPENTOK-AUTH');
$this->assertEquals(true, TestHelpers::validateOpenTokAuthHeader($this->API_KEY, $this->API_SECRET, $authString));

// TODO: test the dynamically built User Agent string
$userAgent = $request->getHeaderLine('User-Agent');
$this->assertNotEmpty($userAgent);
$this->assertStringStartsWith('OpenTok-PHP-SDK/4.9.0', $userAgent);

$this->assertInstanceOf(BroadcastList::class, $broadcastList);
$this->assertEquals(2, $broadcastList->totalCount());
$this->assertEquals($sessionId, $broadcastList->getItems()[0]->sessionId);
$this->assertEquals($sessionId, $broadcastList->getItems()[1]->sessionId);
$this->assertEquals('1748b707-0a81-464c-9759-c46ad10d3734', $broadcastList->getItems()[0]->id);
$this->assertEquals('1c46ad10-0a81-464c-9759-748b707d3734', $broadcastList->getItems()[1]->id);
}

public function testStartsBroadcast()
{
// Arrange
Expand Down
Loading