You are here

class BrightcoveVideoController in Brightcove Video Connect 3.x

Same name and namespace in other branches
  1. 8.2 src/Controller/BrightcoveVideoController.php \Drupal\brightcove\Controller\BrightcoveVideoController
  2. 8 src/Controller/BrightcoveVideoController.php \Drupal\brightcove\Controller\BrightcoveVideoController

Provides controller for video related callbacks.

Hierarchy

Expanded class hierarchy of BrightcoveVideoController

File

src/Controller/BrightcoveVideoController.php, line 24

Namespace

Drupal\brightcove\Controller
View source
class BrightcoveVideoController extends ControllerBase {

  /**
   * Database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $connection;

  /**
   * The brightcove_video storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $videoStorage;

  /**
   * The brightcove_text_track storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $textTrackStorage;

  /**
   * The video queue object.
   *
   * @var \Drupal\Core\Queue\QueueInterface
   */
  protected $videoQueue;

  /**
   * Key-value expirable store.
   *
   * @var \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface
   */
  protected $keyValueExpirable;

  /**
   * Lock backend.
   *
   * @var \Drupal\Core\Lock\LockBackendInterface
   */
  protected $lock;

  /**
   * Controller constructor.
   *
   * @param \Drupal\Core\Database\Connection $connection
   *   Database connection.
   * @param \Drupal\Core\Entity\EntityStorageInterface $video_storage
   *   Brightcove Video entity storage.
   * @param \Drupal\Core\Entity\EntityStorageInterface $text_track_storage
   *   Brightcove Text Track entity storage.
   * @param \Drupal\Core\Queue\QueueInterface $video_queue
   *   The Video queue object.
   * @param \Drupal\Core\KeyValueStore\KeyValueExpirableFactoryInterface $key_value_expirable
   *   Key-value expirable store.
   * @param \Drupal\Core\Lock\LockBackendInterface $lock
   *   Lock backend.
   */
  public function __construct(Connection $connection, EntityStorageInterface $video_storage, EntityStorageInterface $text_track_storage, QueueInterface $video_queue, KeyValueExpirableFactoryInterface $key_value_expirable, LockBackendInterface $lock) {
    $this->connection = $connection;
    $this->videoStorage = $video_storage;
    $this->textTrackStorage = $text_track_storage;
    $this->videoQueue = $video_queue;
    $this->keyValueExpirable = $key_value_expirable;
    $this->lock = $lock;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('database'), $container
      ->get('entity_type.manager')
      ->getStorage('brightcove_video'), $container
      ->get('entity_type.manager')
      ->getStorage('brightcove_text_track'), $container
      ->get('queue')
      ->get('brightcove_video_queue_worker'), $container
      ->get('keyvalue.expirable'), $container
      ->get('lock'));
  }

  /**
   * Menu callback to update the existing Video with the latest version.
   *
   * @param int $entity_id
   *   The ID of the video in Drupal.
   *
   * @return \Symfony\Component\HttpFoundation\RedirectResponse
   *   Redirection response.
   */
  public function update($entity_id) {

    /** @var \Drupal\brightcove\Entity\BrightcoveVideo $video_entity */
    $video_entity = BrightcoveVideo::load($entity_id);

    /** @var \Brightcove\API\CMS $cms */
    $cms = BrightcoveUtil::getCmsApi($video_entity
      ->getApiClient());

    // Update video.
    $video = $cms
      ->getVideo($video_entity
      ->getBrightcoveId());
    $this->videoQueue
      ->createItem([
      'api_client_id' => $video_entity
        ->getApiClient(),
      'video' => $video,
    ]);

    // Run batch.
    batch_set([
      'operations' => [
        [
          [
            BrightcoveUtil::class,
            'runQueue',
          ],
          [
            'brightcove_video_queue_worker',
          ],
        ],
        [
          [
            BrightcoveUtil::class,
            'runQueue',
          ],
          [
            'brightcove_text_track_queue_worker',
          ],
        ],
        [
          [
            BrightcoveUtil::class,
            'runQueue',
          ],
          [
            'brightcove_text_track_delete_queue_worker',
          ],
        ],
      ],
    ]);

    // Run batch and redirect back to the video edit form.
    return batch_process(Url::fromRoute('entity.brightcove_video.edit_form', [
      'brightcove_video' => $entity_id,
    ]));
  }

  /**
   * Ingestion callback for Brightcove.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Request object.
   * @param int $token
   *   The token which matches the video ID.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   *   An empty Response object.
   */
  public function ingestionCallback(Request $request, $token) {
    $status = BrightcoveUtil::runWithSemaphore(function () use ($request, $token) {
      $content = Json::decode($request
        ->getContent());
      if (json_last_error() !== JSON_ERROR_NONE) {
        throw new \Exception('Failed to decode JSON from response: ' . json_last_error_msg());
      }
      if (is_array($content) && $content['status'] == 'SUCCESS' && $content['version'] == 1 && $content['action'] == 'CREATE') {
        $video_id = $this->keyValueExpirable
          ->get('brightcove_callback')
          ->get($token);
        if (!empty($video_id)) {

          /** @var \Drupal\brightcove\Entity\BrightcoveVideo $video_entity */
          $video_entity = BrightcoveVideo::load($video_id);
          if (!is_null($video_entity)) {
            $cms = BrightcoveUtil::getCmsApi($video_entity
              ->getApiClient());
            switch ($content['entityType']) {

              // Video.
              case 'TITLE':

                // Delete video file from the entity.
                $video_entity
                  ->setVideoFile(NULL);
                $video_entity
                  ->save();
                break;

              // Assets.
              case 'ASSET':

                // Check for Text Track ID format. There is no other way to
                // determine whether the asset is a text track or something
                // else...
                if (preg_match('/^\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}$/i', $content['entity'])) {
                  $text_tracks = $video_entity
                    ->getTextTracks();
                  foreach ($text_tracks as $key => $text_track) {
                    if (!empty($text_track['target_id'])) {

                      /** @var \Drupal\brightcove\Entity\BrightcoveTextTrack $text_track_entity */
                      $text_track_entity = BrightcoveTextTrack::load($text_track['target_id']);
                      if (!is_null($text_track_entity) && empty($text_track_entity
                        ->getTextTrackId())) {

                        // Remove text track without Brightcove ID.
                        $text_track_entity
                          ->delete();

                        // Try to find the ingested text track on the video
                        // object and recreate it.
                        $cms = BrightcoveUtil::getCmsApi($video_entity
                          ->getApiClient());
                        $video = $cms
                          ->getVideo($video_entity
                          ->getBrightcoveId());
                        $api_text_tracks = $video
                          ->getTextTracks();
                        $found_api_text_track = NULL;
                        foreach ($api_text_tracks as $api_text_track) {
                          if ($api_text_track
                            ->getId() == $content['entity']) {
                            $found_api_text_track = $api_text_track;
                            break;
                          }
                        }

                        // Create new text track.
                        if (!is_null($found_api_text_track)) {
                          BrightcoveTextTrack::createOrUpdate($found_api_text_track, $this->textTrackStorage, $video_entity
                            ->id());
                        }

                        // We need to process only one per request.
                        break;
                      }
                    }
                  }
                }
                else {
                  $client = BrightcoveUtil::getClient($video_entity
                    ->getApiClient());
                  $api_client = BrightcoveUtil::getApiClient($video_entity
                    ->getApiClient());

                  // Check for each asset type by try-and-error, currently there
                  // is no other way to determine which asset is what...
                  $asset_types = [
                    BrightcoveVideo::IMAGE_TYPE_THUMBNAIL,
                    BrightcoveVideo::IMAGE_TYPE_POSTER,
                  ];
                  foreach ($asset_types as $type) {
                    try {
                      $client
                        ->request('GET', 1, 'cms', $api_client
                        ->getAccountId(), '/videos/' . $video_entity
                        ->getBrightcoveId() . '/assets/' . $type . '/' . $content['entity'], NULL);
                      switch ($type) {
                        case BrightcoveVideo::IMAGE_TYPE_THUMBNAIL:
                        case BrightcoveVideo::IMAGE_TYPE_POSTER:
                          $images = $cms
                            ->getVideoImages($video_entity
                            ->getBrightcoveId());
                          $function = ucfirst($type);

                          // @TODO: Download the image only if truly different.
                          // But this may not be possible without downloading
                          // the image.
                          $video_entity
                            ->saveImage($type, $images
                            ->{"get{$function}"}());
                          break 2;
                      }
                    } catch (APIException $e) {

                      // Do nothing here, just catch the exception to not
                      // generate an error.
                    }
                  }
                }

                // @TODO: Do we have to do anything with the rest of the assets?
                break;

              // Don't do anything if we got something else.
              default:
                return NULL;
            }

            // Update video entity with the latest update date.
            $video = $cms
              ->getVideo($video_entity
              ->getBrightcoveId());
            $video_entity
              ->setChangedTime(strtotime($video
              ->getUpdatedAt()));
            $video_entity
              ->save();
          }
        }
      }
      return TRUE;
    }, $this->lock);
    return new Response('', $status === FALSE ? 409 : 200);
  }

  /**
   * Destructor.
   */
  public function __destruct() {

    // Make sure that the semaphore gets released.
    if ($this
      ->state()
      ->get('brightcove_video_semaphore', FALSE) == TRUE) {
      $this
        ->state()
        ->set('brightcove_video_semaphore', FALSE);
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
BrightcoveVideoController::$connection protected property Database connection.
BrightcoveVideoController::$keyValueExpirable protected property Key-value expirable store.
BrightcoveVideoController::$lock protected property Lock backend.
BrightcoveVideoController::$textTrackStorage protected property The brightcove_text_track storage.
BrightcoveVideoController::$videoQueue protected property The video queue object.
BrightcoveVideoController::$videoStorage protected property The brightcove_video storage.
BrightcoveVideoController::create public static function Instantiates a new instance of this class. Overrides ControllerBase::create
BrightcoveVideoController::ingestionCallback public function Ingestion callback for Brightcove.
BrightcoveVideoController::update public function Menu callback to update the existing Video with the latest version.
BrightcoveVideoController::__construct public function Controller constructor.
BrightcoveVideoController::__destruct public function Destructor.
ControllerBase::$configFactory protected property The configuration factory.
ControllerBase::$currentUser protected property The current user service. 1
ControllerBase::$entityFormBuilder protected property The entity form builder.
ControllerBase::$entityTypeManager protected property The entity type manager.
ControllerBase::$formBuilder protected property The form builder. 2
ControllerBase::$keyValue protected property The key-value storage. 1
ControllerBase::$languageManager protected property The language manager. 1
ControllerBase::$moduleHandler protected property The module handler. 2
ControllerBase::$stateService protected property The state service.
ControllerBase::cache protected function Returns the requested cache bin.
ControllerBase::config protected function Retrieves a configuration object.
ControllerBase::container private function Returns the service container.
ControllerBase::currentUser protected function Returns the current user. 1
ControllerBase::entityFormBuilder protected function Retrieves the entity form builder.
ControllerBase::entityTypeManager protected function Retrieves the entity type manager.
ControllerBase::formBuilder protected function Returns the form builder service. 2
ControllerBase::keyValue protected function Returns a key/value storage collection. 1
ControllerBase::languageManager protected function Returns the language manager service. 1
ControllerBase::moduleHandler protected function Returns the module handler. 2
ControllerBase::redirect protected function Returns a redirect response object for the specified route.
ControllerBase::state protected function Returns the state storage service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.