View source
<?php
namespace Drupal\brightcove\Entity;
use Brightcove\Item\Playlist;
use Drupal\brightcove\BrightcoveUtil;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\brightcove\BrightcovePlaylistInterface;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\taxonomy\Entity\Term;
class BrightcovePlaylist extends BrightcoveVideoPlaylistCmsEntity implements BrightcovePlaylistInterface {
const TYPE_MANUAL = 0;
const TYPE_SMART = 1;
const TAG_SEARCH_CONTAINS_ONE_OR_MORE = 'contains_one_or_more';
const TAG_SEARCH_CONTAINS_ALL = 'contains_all';
public static function getTypes($type = NULL) {
$manual = [
'EXPLICIT' => t('Manual: Add videos manually'),
];
$smart_label = t('Smart: Add videos automatically based on tags')
->render();
$smart = [
$smart_label => [
'ACTIVATED_OLDEST_TO_NEWEST' => t('Smart: Activated Date (Oldest First)'),
'ACTIVATED_NEWEST_TO_OLDEST' => t('Smart: Activated Date (Newest First)'),
'ALPHABETICAL' => t('Smart: Video Name (A-Z)'),
'PLAYS_TOTAL' => t('Smart: Total Plays'),
'PLAYS_TRAILING_WEEK' => t('Smart: Trailing Week Plays'),
'START_DATE_OLDEST_TO_NEWEST' => t('Smart: Start Date (Oldest First)'),
'START_DATE_NEWEST_TO_OLDEST' => t('Smart: Start Date (Newest First)'),
],
];
if (!is_null($type)) {
switch ($type) {
case self::TYPE_MANUAL:
return $manual;
case self::TYPE_SMART:
return reset($smart);
default:
throw new \Exception('The type must be either TYPE_MANUAL or TYPE_SMART');
}
}
return $manual + $smart;
}
public static function typeAllowedValues(FieldStorageDefinitionInterface $definition, FieldableEntityInterface $entity = NULL, &$cacheable = TRUE) {
return self::getTypes();
}
public function getType() {
return $this
->get('type')->value;
}
public function setType($type) {
return $this
->set('type', $type);
}
public function isFavorite() {
return (bool) $this
->get('favorite')->value;
}
public function getBrightcoveId() {
return $this
->get('playlist_id')->value;
}
public function setBrightcoveId($id) {
$this
->set('playlist_id', $id);
return $this;
}
public function getTagsSearchCondition() {
return $this
->get('tags_search_condition')->value;
}
public function setTagsSearchCondition($condition) {
return $this
->set('tags_search_condition', $condition);
}
public function getVideos() {
return $this
->get('videos')
->getValue();
}
public function setVideos(array $videos) {
$this
->set('videos', $videos);
return $this;
}
public function save($upload = FALSE) {
$status = $this
->id() ? SAVED_UPDATED : SAVED_NEW;
$saved = parent::save();
if ($upload) {
$cms = BrightcoveUtil::getCmsApi($this
->getApiClient());
$playlist = new Playlist();
$playlist
->setName($this
->getName());
if ($this
->isFieldChanged('type')) {
$playlist
->setType($this
->getType());
if ($playlist
->getType() == 'EXPLICIT') {
$playlist
->setSearch('');
$this
->setTags([]);
}
else {
$playlist
->setVideoIds([]);
$this
->setVideos([]);
}
}
if ($this
->isFieldChanged('description')) {
$playlist
->setDescription($this
->getDescription());
}
if ($this
->isFieldChanged('reference_id')) {
$playlist
->setReferenceId($this
->getReferenceId());
}
if ($this
->isFieldChanged('tags') || $this
->isFieldChanged('tags_search_condition')) {
$condition = '';
if ($this
->getTagsSearchCondition() == self::TAG_SEARCH_CONTAINS_ALL) {
$condition = '+';
}
$tags = '';
if (!empty($tag_items = $this
->getTags())) {
if (count($tag_items) == 1) {
$this
->setTagsSearchCondition(self::TAG_SEARCH_CONTAINS_ALL);
}
$tags .= $condition . 'tags:"';
$first = TRUE;
foreach ($tag_items as $tag) {
$tag_term = Term::load($tag['target_id']);
$tags .= ($first ? '' : '","') . $tag_term
->getName();
if ($first) {
$first = FALSE;
}
}
$tags .= '"';
}
$playlist
->setSearch($tags);
}
if ($this
->isFieldChanged('videos')) {
$video_entities = $this
->getVideos();
$videos = [];
foreach ($video_entities as $video) {
$videos[] = BrightcoveVideo::load($video['target_id'])
->getBrightcoveId();
}
$playlist
->setVideoIds($videos);
}
switch ($status) {
case SAVED_NEW:
$saved_playlist = $cms
->createPlaylist($playlist);
$this
->setBrightcoveId($saved_playlist
->getId());
$this
->setCreatedTime(strtotime($saved_playlist
->getCreatedAt()));
break;
case SAVED_UPDATED:
$playlist
->setId($this
->getBrightcoveId());
$saved_playlist = $cms
->updatePlaylist($playlist);
break;
}
if (isset($saved_playlist)) {
$this
->setChangedTime(strtotime($saved_playlist
->getUpdatedAt()));
parent::save();
}
}
return $saved;
}
public function delete($local_only = FALSE) {
if (!$this
->isNew() && !$local_only) {
$cms = BrightcoveUtil::getCmsApi($this
->getApiClient());
$cms
->deletePlaylist($this
->getBrightcoveId());
}
parent::delete();
}
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$weight = -30;
$fields['bcplid'] = BaseFieldDefinition::create('integer')
->setLabel(t('ID'))
->setDescription(t('The Drupal entity ID of the Brightcove Playlist.'))
->setReadOnly(TRUE);
$fields['uuid'] = BaseFieldDefinition::create('uuid')
->setLabel(t('UUID'))
->setDescription(t('The Brightcove Playlist UUID.'))
->setReadOnly(TRUE);
$fields['api_client'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('API Client'))
->setDescription(t('Brightcove API credentials (account) to use.'))
->setRequired(TRUE)
->setSetting('target_type', 'brightcove_api_client')
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => ++$weight,
])
->setDisplayOptions('view', [
'type' => 'hidden',
'label' => 'inline',
'weight' => $weight,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['player'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Player'))
->setDescription(t('Brightcove Player to be used for playback.'))
->setSetting('target_type', 'brightcove_player')
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => ++$weight,
])
->setDisplayOptions('view', [
'type' => 'hidden',
'label' => 'inline',
'weight' => $weight,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['type'] = BaseFieldDefinition::create('list_string')
->setLabel(t('Playlist Type'))
->setRequired(TRUE)
->setDefaultValue('EXPLICIT')
->setSetting('allowed_values_function', [
self::class,
'typeAllowedValues',
])
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => ++$weight,
])
->setDisplayOptions('view', [
'type' => 'list_default',
'label' => 'inline',
'weight' => $weight,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Playlist name'))
->setDescription(t('Title of the playlist.'))
->setRequired(TRUE)
->setSettings([
'max_length' => 250,
'text_processing' => 0,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => ++$weight,
])
->setDisplayOptions('view', [
'type' => 'string',
'label' => 'hidden',
'weight' => $weight,
])
->setDisplayConfigurable('form', TRUE);
$fields['langcode'] = BaseFieldDefinition::create('language')
->setLabel(t('Language code'))
->setDescription(t('The language code for the Brightcove Video.'))
->setDisplayOptions('form', [
'type' => 'language_select',
'weight' => ++$weight,
])
->setDisplayConfigurable('form', TRUE);
$fields['favorite'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Show Playlist in Sidebar'))
->setDescription(t('Whether playlist is in favorites list'))
->setDefaultValue(FALSE)
->setDisplayOptions('view', [
'type' => 'string',
'label' => 'inline',
'weight' => ++$weight,
])
->setDisplayConfigurable('view', TRUE);
$fields['playlist_id'] = BaseFieldDefinition::create('string')
->setLabel(t('Playlist ID'))
->setDescription(t('Unique Playlist ID assigned by Brightcove.'))
->setReadOnly(TRUE)
->setDisplayOptions('view', [
'type' => 'string',
'label' => 'inline',
'weight' => ++$weight,
])
->setDisplayConfigurable('view', TRUE);
$fields['reference_id'] = BaseFieldDefinition::create('string')
->setLabel(t('Reference ID'))
->addConstraint('UniqueField')
->setDescription(t('Value specified must be unique'))
->setSettings([
'max_length' => 150,
'text_processing' => 0,
])
->setDisplayOptions('form', [
'type' => 'string_textfield',
'weight' => ++$weight,
])
->setDisplayOptions('view', [
'type' => 'string',
'label' => 'inline',
'weight' => $weight,
])
->setDefaultValueCallback(static::class . '::getDefaultReferenceId')
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['description'] = BaseFieldDefinition::create('string_long')
->setLabel(t('Short description'))
->setDisplayOptions('form', [
'type' => 'string_textarea',
'weight' => ++$weight,
])
->setDisplayOptions('view', [
'type' => 'basic_string',
'label' => 'above',
'weight' => $weight,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE)
->addPropertyConstraints('value', [
'Length' => [
'max' => 250,
],
]);
$fields['tags_search_condition'] = BaseFieldDefinition::create('list_string')
->setLabel(t('Tags search condition'))
->setRequired(TRUE)
->setDefaultValue(self::TAG_SEARCH_CONTAINS_ONE_OR_MORE)
->setSetting('allowed_values', [
self::TAG_SEARCH_CONTAINS_ONE_OR_MORE => t('contains one or more'),
self::TAG_SEARCH_CONTAINS_ALL => t('contains all'),
])
->setDisplayOptions('form', [
'type' => 'options_select',
'weight' => ++$weight,
])
->setDisplayConfigurable('form', TRUE);
$fields['tags'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Tags'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setSettings([
'target_type' => 'taxonomy_term',
'handler_settings' => [
'target_bundles' => [
BrightcoveVideo::TAGS_VID => BrightcoveVideo::TAGS_VID,
],
'auto_create' => TRUE,
],
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => ++$weight,
'settings' => [
'autocomplete_type' => 'tags',
],
])
->setDisplayOptions('view', [
'type' => 'entity_reference_label',
'label' => 'above',
'weight' => $weight,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['videos'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Videos'))
->setDescription(t('Videos in the playlist.'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setSettings([
'target_type' => 'brightcove_video',
'handler' => 'views',
'handler_settings' => [
'view' => [
'view_name' => 'brightcove_videos_by_api_client',
'display_name' => 'videos_entity_reference',
'arguments' => [],
],
],
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => ++$weight,
])
->setDisplayOptions('view', [
'type' => 'string',
'label' => 'above',
'weight' => $weight,
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['uid'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Authored by'))
->setDescription(t('The username of the Brightcove Playlist author.'))
->setSetting('target_type', 'user')
->setDefaultValueCallback('Drupal\\brightcove\\Entity\\BrightcovePlaylist::getCurrentUserId')
->setTranslatable(TRUE)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'author',
'weight' => ++$weight,
])
->setDisplayOptions('form', [
'type' => 'entity_reference_autocomplete',
'weight' => $weight,
'settings' => [
'match_operator' => 'CONTAINS',
'size' => '60',
'autocomplete_type' => 'tags',
'placeholder' => '',
],
])
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$fields['status'] = BaseFieldDefinition::create('boolean')
->setLabel(t('Publishing status'))
->setDescription(t('A boolean indicating whether the Brightcove Playlist is published.'))
->setDefaultValue(TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created'))
->setDescription(t('The time that the Brightcove Playlist was created.'))
->setTranslatable(TRUE)
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'timestamp',
'weight' => ++$weight,
])
->setDisplayConfigurable('view', TRUE);
$fields['changed'] = BaseFieldDefinition::create('changed')
->setLabel(t('Changed'))
->setDescription(t('The time that the Brightcove Playlist was last edited.'))
->setTranslatable(TRUE);
return $fields;
}
protected static function extractVideosArray(Playlist $playlist, EntityStorageInterface $video_storage) {
$videos = $playlist
->getVideoIds();
if (!$videos) {
return NULL;
}
$return = [];
foreach ($playlist
->getVideoIds() as $video_id) {
$bcvid = $video_storage
->getQuery()
->condition('video_id', $video_id)
->execute();
if ($bcvid) {
$bcvid = reset($bcvid);
$return[] = [
'target_id' => $bcvid,
];
}
else {
throw new \Exception(t('Playlist contains a video that is not (yet) available on the Drupal site'));
}
}
return $return;
}
public static function createOrUpdate(Playlist $playlist, EntityStorageInterface $playlist_storage, EntityStorageInterface $video_storage, $api_client_id = NULL) {
$videos = self::extractVideosArray($playlist, $video_storage);
$needs_save = FALSE;
$existing_playlist = $playlist_storage
->getQuery()
->condition('playlist_id', $playlist
->getId())
->execute();
if (!empty($existing_playlist)) {
$playlist_entity_id = reset($existing_playlist);
$playlist_entity = BrightcovePlaylist::load($playlist_entity_id);
if ($playlist_entity
->getChangedTime() < ($updated_at = strtotime($playlist
->getUpdatedAt()))) {
$needs_save = TRUE;
$playlist_entity
->setChangedTime($updated_at);
}
}
else {
$needs_save = TRUE;
$playlist_entity = BrightcovePlaylist::create([
'api_client' => [
'target_id' => $api_client_id,
],
'playlist_id' => $playlist
->getId(),
'created' => strtotime($playlist
->getCreatedAt()),
'changed' => strtotime($playlist
->getUpdatedAt()),
]);
}
if ($needs_save) {
if ($playlist_entity
->getType() != ($type = $playlist
->getType())) {
$playlist_entity
->setType($type);
}
if ($playlist_entity
->getName() != ($name = $playlist
->getName())) {
$playlist_entity
->setName($name);
}
if ($playlist_entity
->isFavorite() != ($favorite = $playlist
->isFavorite())) {
$playlist_entity
->set('favorite', $favorite);
}
if ($playlist_entity
->getReferenceId() != ($reference_id = $playlist
->getReferenceId())) {
$playlist_entity
->setReferenceId($reference_id);
}
if ($playlist_entity
->getDescription() != ($description = $playlist
->getDescription())) {
$playlist_entity
->setDescription($description);
}
$playlist_search = $playlist
->getSearch();
preg_match('/^(\\+?)([^\\+].*):(?:,?"(.*?[^"])")$/i', $playlist_search, $matches);
if (count($matches) == 4 && $matches[2] == 'tags') {
$playlist_tags = explode('","', $matches[3]);
$playlist_search_condition = $matches[1] == '+' ? self::TAG_SEARCH_CONTAINS_ALL : self::TAG_SEARCH_CONTAINS_ONE_OR_MORE;
if ($playlist_entity
->getTagsSearchCondition() != $playlist_search_condition) {
$playlist_entity
->setTagsSearchCondition($playlist_search_condition);
}
BrightcoveUtil::saveOrUpdateTags($playlist_entity, $api_client_id, $playlist_tags);
}
if ($playlist_entity
->getVideos() != $videos) {
$playlist_entity
->setVideos($videos);
}
$playlist_entity
->save();
}
}
}