podcast_publisher-1.0.0-alpha3/modules/podcast_publisher_analytics/src/Plugin/Block/DownloadIntentCountPodcast.php
modules/podcast_publisher_analytics/src/Plugin/Block/DownloadIntentCountPodcast.php
<?php
namespace Drupal\podcast_publisher_analytics\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a 'Download Intent Count Podcast' block.
*
* @Block(
* id = "download_intent_count_podcast",
* admin_label = @Translation("Download Intent Count Podcast"),
* category = @Translation("Podcast Publisher Analytics"),
* )
*/
class DownloadIntentCountPodcast extends BlockBase implements ContainerFactoryPluginInterface {
/**
* The database.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The current route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $routeMatch;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Image Factory.
*
* @var \Drupal\Core\Image\ImageFactory
*/
protected $imageFactory;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = new static(
$configuration,
$plugin_id,
$plugin_definition,
);
$instance->database = $container->get('database');
$instance->routeMatch = $container->get('current_route_match');
$instance->entityTypeManager = $container->get('entity_type.manager');
$instance->imageFactory = $container->get('image.factory');
return $instance;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$options = [];
$image_styles = $this->entityTypeManager
->getStorage('image_style')
->loadMultiple();
/** @var \Drupal\image\Entity\ImageStyle $image_style */
foreach ($image_styles as $image_style) {
$options[$image_style->id()] = $image_style->label();
}
$form['image_style'] = [
'#type' => 'select',
'#title' => $this->t('Image Style'),
'#description' => $this->t("Select the image style that should be used to display the podcast's image in the block."),
'#options' => $options,
'#default_value' => $this->configuration['image_style'],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
$this->configuration['image_style'] = $form_state->getValue('image_style');
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
$configuration = parent::defaultConfiguration();
return $configuration + [
'image_style' => '',
];
}
/**
* {@inheritdoc}
*/
public function build() {
$metadata = new BubbleableMetadata();
$metadata->addCacheableDependency($this);
$build = [
'#theme' => 'download_intent_count_podcast',
'#attached' => [
'library' => [
'podcast_publisher_analytics/block',
],
],
];
$podcast_id = $this->routeMatch->getParameter('arg_0')
?? $this->routeMatch->getParameter('podcast');
if (!$podcast_id) {
return $build;
}
$podcast = $this->entityTypeManager->getStorage('podcast')
->load($podcast_id);
$metadata->addCacheableDependency($podcast);
$metadata->addCacheTags(['podcast_download_intent']);
$build += [
'#title' => $podcast->label(),
'#subtitle' => $podcast->get('subtitle')->value,
'#episode_count' => $this->countEpisodesOfPodcast($podcast_id),
];
$build['#download_intent_count'] = $podcast_id ? $this->countDownloadsOfPodcast($podcast_id) : 0;
if ($image_file = $podcast->get('image')->entity) {
if (!$image_style = $this->configuration['image_style']) {
// Just use the first image style that query returns as fallback.
$image_style = $this->entityTypeManager
->getStorage('image_style')
->getQuery()
->accessCheck(FALSE)
->range(0, 1)
->execute();
}
$image = $this->imageFactory->get($image_file->getFileUri());
$build['#image'] = [
'#theme' => 'image_style',
'#width' => $image->getWidth(),
'#height' => $image->getHeight(),
'#style_name' => $image_style,
'#uri' => $image_file->getFileUri(),
];
}
return $build + [
'#cache' => [
'tags' => $metadata->getCacheTags(),
'contexts' => $metadata->getCacheContexts(),
],
];
}
/**
* Returns the count of all episode download intents of given podcast.
*/
protected function countDownloadsOfPodcast(int $podcast_id): int {
$query = $this->database
->select('podcast_download_intent', 'pdi');
$query->addExpression('COUNT(pdi.id)');
$query->join('podcast_episode', 'pe', 'pe.id = pdi.episode');
$query->join('podcast_user_agent', 'pua', 'pdi.user_agent = pua.id');
$bot_condition = $query->orConditionGroup()
->condition('pua.bot', 0)
->isNull('pua.bot');
$query->condition($bot_condition)
->condition('pe.podcast', $podcast_id)
->condition('pdi.original_intent', NULL, 'IS NULL');
return $query->execute()->fetchField();
}
/**
* Returns the count of all episodes of given podcast.
*/
protected function countEpisodesOfPodcast(int $podcast_id): int {
return $this->entityTypeManager->getStorage('podcast_episode')
->getQuery()
->count()
->accessCheck(FALSE)
->condition('podcast', $podcast_id)
->execute();
}
}
