archivesspace-8.x-1.x-dev/src/ArchivesSpaceSession.php
src/ArchivesSpaceSession.php
<?php
namespace Drupal\archivesspace;
use Drupal\Core\Site\Settings;
use Drupal\Core\Logger\LoggerChannelTrait;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ServerException;
/**
* An ArchivesSpace authenticated session object.
*/
class ArchivesSpaceSession {
use LoggerChannelTrait;
/**
* The logger factory.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected $logger;
/**
* Connection Information.
*
* @var array
*/
protected $connectionInfo = [
'base_uri' => 'http://localhost:8089',
'api_path' => '',
'username' => 'admin',
'password' => 'admin',
];
/**
* Session ID.
*
* @var string
*/
protected $session = '';
/**
* {@inheritdoc}
*/
public function __construct() {
$this->logger = $this->getLogger('archivesspace');
}
/**
* Create a session with connection information.
*
* @param string $base_uri
* The host (and port) for the ArchivesSpace API.
* @param string $api_path
* The optional path for the API endpoint.
* @param string $username
* The username to use for authentication.
* @param string $password
* The password to use for authentication.
*/
public static function withConnectionInfo($base_uri, $api_path, $username, $password) {
if (!preg_match("@^https?://@", $base_uri)) {
throw new \InvalidArgumentException('Could not connect with invalid base URI: ' . $base_uri);
}
if (empty($username) || empty($password)) {
throw new \InvalidArgumentException('Could not connect. Either the username or password was missing.');
}
$instance = new self();
$instance->connectionInfo = [
'base_uri' => $base_uri,
'api_path' => $api_path,
'username' => $username,
'password' => $password,
];
return $instance;
}
/**
* Either logs in or returns the current session.
*
* @return ArchivesSpaceSession
* The ArchivesSpace session object
*/
public function getSession() {
if (empty($this->session)) {
$this->login();
}
return $this->session;
}
/**
* Issues an ArchivesSpace request.
*
* @param string $type
* The type of Request to issue (usually GET or POST)
* @param string $path
* The API path to use for the request.
* @param array $parameters
* Either GET query parameters or array to POST as JSON.
* @param bool $binary
* Expect a binary response instead of json.
*
* @return mixed
* Either an array of response data OR
* a GuzzleHttp\Psr7\Stream if $binary is true.
*/
public function request(string $type, string $path, array $parameters = [], $binary = FALSE) {
if (!in_array($type, ['GET', 'POST'])) {
throw new \InvalidArgumentException('Cant\'t make an ArchivesSpace request with type: ' . $type);
}
if (empty($this->session)) {
$this->login();
}
$client = new Client(['base_uri' => $this->connectionInfo['base_uri']]);
$request_data = [
'headers' => [
'X-ArchivesSpace-Session' => $this->session,
],
];
switch ($type) {
case 'GET':
$request_data['query'] = $parameters;
break;
case 'POST':
$request_data['json'] = $parameters;
}
try {
$response = $client->request($type, $this->connectionInfo['api_path'] . $path, $request_data);
}
catch (ServerException $e) {
$this->logger->error('Could not complete request due to system error: ' . $e->getMessage());
return FALSE;
}
return ($binary) ? $response->getBody() : json_decode($response->getBody(), TRUE);
}
/**
* Login to ArchivesSpace.
*/
protected function login() {
$state_config = [];
foreach (\Drupal::state()->getMultiple(['archivesspace.base_uri',
'archivesspace.api_path',
'archivesspace.username',
'archivesspace.password',
]
) as $key => $value) {
$new_key = substr($key, 14);
if (!empty($value)) {
$state_config[$new_key] = $value;
}
}
$this->connectionInfo = array_replace($this->connectionInfo, $state_config);
// If the base_uri or api_path are set in Drupal Settings, use that.
if (Settings::get('archivespace.base_uri')) {
$this->connectionInfo['base_uri'] = Settings::get('archivespace.base_uri');
}
if (Settings::get('archivespace.api_path')) {
$this->connectionInfo['api_path'] = Settings::get('archivespace.api_path');
}
// Setup the client.
$client = new Client([
'base_uri' => $this->connectionInfo['base_uri'],
]);
// Form the query string and make the call.
$login_url = '/users/' .
rawurlencode($this->connectionInfo['username']) .
'/login?password=' .
rawurlencode($this->connectionInfo['password']);
$response = $client->post($this->connectionInfo['api_path'] . $login_url);
// Return the Session ID from the response.
$login_response = json_decode($response->getBody(), TRUE);
$this->session = $login_response['session'];
}
}
