You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
3.9 KiB
162 lines
3.9 KiB
<?php |
|
|
|
namespace Drupal\islandora; |
|
|
|
use Drupal\Core\Entity\EntityInterface; |
|
use Drupal\islandora\MediaSource\MediaSourceService; |
|
use Drupal\jwt\Authentication\Provider\JwtAuth; |
|
use GuzzleHttp\Psr7; |
|
use GuzzleHttp\Client; |
|
use GuzzleHttp\Exception\RequestException; |
|
use Islandora\Crayfish\Commons\Client\GeminiClient; |
|
use Psr\Log\LoggerInterface; |
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; |
|
|
|
/** |
|
* Locates the matching Fedora URI from the Gemini database. |
|
* |
|
* @package Drupal\islandora |
|
*/ |
|
class GeminiLookup { |
|
|
|
/** |
|
* A GeminiClient. |
|
* |
|
* @var \Islandora\Crayfish\Commons\Client\GeminiClient |
|
*/ |
|
private $geminiClient; |
|
|
|
/** |
|
* A JWT Provider service. |
|
* |
|
* @var \Drupal\jwt\Authentication\Provider\JwtAuth |
|
*/ |
|
private $jwtProvider; |
|
|
|
/** |
|
* A MediaSourceService. |
|
* |
|
* @var \Drupal\islandora\MediaSource\MediaSourceService |
|
*/ |
|
private $mediaSource; |
|
|
|
/** |
|
* An http client. |
|
* |
|
* @var \GuzzleHttp\Client |
|
*/ |
|
private $guzzle; |
|
|
|
/** |
|
* The islandora logger channel. |
|
* |
|
* @var \Psr\Log\LoggerInterface |
|
*/ |
|
private $logger; |
|
|
|
/** |
|
* GeminiField constructor. |
|
* |
|
* @param \Islandora\Crayfish\Commons\Client\GeminiClient $client |
|
* The Gemini client. |
|
* @param \Drupal\jwt\Authentication\Provider\JwtAuth $jwt_auth |
|
* The JWT provider. |
|
* @param \Drupal\islandora\MediaSource\MediaSourceService $media_source |
|
* Media source service. |
|
* @param \GuzzleHttp\Client $guzzle |
|
* Guzzle client. |
|
* @param \Psr\Log\LoggerInterface $logger |
|
* The Islandora logger. |
|
*/ |
|
public function __construct( |
|
GeminiClient $client, |
|
JwtAuth $jwt_auth, |
|
MediaSourceService $media_source, |
|
Client $guzzle, |
|
LoggerInterface $logger |
|
) { |
|
$this->geminiClient = $client; |
|
$this->jwtProvider = $jwt_auth; |
|
$this->mediaSource = $media_source; |
|
$this->guzzle = $guzzle; |
|
$this->logger = $logger; |
|
} |
|
|
|
/** |
|
* Lookup this entity's URI in the Gemini db and return the other URI. |
|
* |
|
* @param \Drupal\Core\Entity\EntityInterface $entity |
|
* The entity to look for. |
|
* |
|
* @return string|null |
|
* Return the URI or null |
|
*/ |
|
public function lookup(EntityInterface $entity) { |
|
// Exit early if the entity hasn't been saved yet. |
|
if ($entity->id() == NULL) { |
|
return NULL; |
|
} |
|
|
|
$is_media = $entity->getEntityTypeId() == 'media'; |
|
|
|
// Use the entity's uuid unless it's a media, |
|
// use its file's uuid instead. |
|
if ($is_media) { |
|
try { |
|
$file = $this->mediaSource->getSourceFile($entity); |
|
$uuid = $file->uuid(); |
|
} |
|
// If the media has no source file, exit early. |
|
catch (NotFoundHttpException $e) { |
|
return NULL; |
|
} |
|
} |
|
else { |
|
$uuid = $entity->uuid(); |
|
} |
|
|
|
// Look it up in Gemini. |
|
$token = "Bearer " . $this->jwtProvider->generateToken(); |
|
$urls = $this->geminiClient->getUrls($uuid, $token); |
|
|
|
// Exit early if there's no results from Gemini. |
|
if (empty($urls)) { |
|
return NULL; |
|
} |
|
|
|
// If it's not a media, just return the url from Gemini;. |
|
if (!$is_media) { |
|
return $urls['fedora']; |
|
} |
|
|
|
// If it's a media, perform a HEAD request against |
|
// the file in Fedora and get its 'describedy' link header. |
|
try { |
|
$head = $this->guzzle->head( |
|
$urls['fedora'], |
|
['allow_redirects' => FALSE, 'headers' => ['Authorization' => $token]] |
|
); |
|
$links = Psr7\parse_header($head->getHeader("Link")); |
|
foreach ($links as $link) { |
|
if ($link['rel'] == 'describedby') { |
|
return trim($link[0], '<>'); |
|
} |
|
} |
|
} |
|
catch (RequestException $e) { |
|
$this->logger->warning( |
|
"Error performing Gemini lookup for media. Fedora HEAD to @url returned @status => @message", |
|
[ |
|
'@url' => $urls['fedora'], |
|
'@status' => $e->getCode(), |
|
'@message' => $e->getMessage, |
|
] |
|
); |
|
return NULL; |
|
} |
|
|
|
// Return null if no link header is found. |
|
return NULL; |
|
} |
|
|
|
}
|
|
|