digital_signage_framework-2.3.x-dev/src/Drush/Commands/DeviceCommands.php
src/Drush/Commands/DeviceCommands.php
<?php
namespace Drupal\digital_signage_framework\Drush\Commands;
use Consolidation\OutputFormatters\StructuredData\RowsOfFields;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\digital_signage_framework\DeviceInterface;
use Drupal\digital_signage_framework\Emergency;
use Drupal\digital_signage_framework\Entity\Device;
use Drupal\digital_signage_framework\PlatformPluginManager;
use Drush\Attributes\Argument;
use Drush\Attributes\Command;
use Drush\Attributes\DefaultTableFields;
use Drush\Attributes\FieldLabels;
use Drush\Attributes\Option;
use Drush\Attributes\Usage;
use Drush\Commands\DrushCommands;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* A Drush command file for digital signage devices.
*/
class DeviceCommands extends DrushCommands {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* The platform plugin manager.
*
* @var \Drupal\digital_signage_framework\PlatformPluginManager
*/
protected PlatformPluginManager $pluginManager;
/**
* The emergency services.
*
* @var \Drupal\digital_signage_framework\Emergency
*/
protected Emergency $emergency;
/**
* Constructs the device commands.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
* @param \Drupal\digital_signage_framework\PlatformPluginManager $plugin_manager
* The platform plugin manager.
* @param \Drupal\digital_signage_framework\Emergency $emergency
* The emergency services.
*/
public function __construct(EntityTypeManagerInterface $entityTypeManager, PlatformPluginManager $plugin_manager, Emergency $emergency) {
parent::__construct();
$this->entityTypeManager = $entityTypeManager;
$this->pluginManager = $plugin_manager;
$this->emergency = $emergency;
}
/**
* Return an instance of these Drush commands.
*
* @param \Symfony\Component\DependencyInjection\ContainerInterface $container
* The container.
*
* @return \Drupal\digital_signage_framework\Drush\Commands\DeviceCommands
* The instance of Drush commands.
*/
public static function create(ContainerInterface $container): DeviceCommands {
return new DeviceCommands(
$container->get('entity_type.manager'),
$container->get('plugin.manager.digital_signage_platform'),
$container->get('digital_signage_content_setting.emergency'),
);
}
/**
* Synchronize devices with all platforms.
*/
#[Command(name: 'digital-signage-device:sync', aliases: ['dsds'])]
#[Option(name: 'platform', description: 'Platform ID if only one should be synchronized, defaults to all.')]
#[Usage(name: 'digital-signage-device:sync', description: 'Synchronizes all devices with all enabled platforms.')]
public function syncDevices(array $options = ['platform' => NULL]): void {
$this->pluginManager->syncDevices($this->input->getOption('platform'));
}
/**
* List devices.
*
* @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
* The rows with fields.
*/
#[Command(name: 'digital-signage-device:list', aliases: ['dsdl'])]
#[FieldLabels(labels: [
'id' => 'ID',
'label' => 'Name',
'platform' => 'Platform',
'extid' => 'External ID',
'status' => 'Status',
'slides' => 'No of slides',
])]
#[DefaultTableFields(fields: ['id', 'label', 'platform', 'extid', 'status', 'slides'])]
#[Usage(name: 'digital-signage-device:list', description: 'List all devices.')]
public function listDevices(array $options = ['all' => FALSE, 'platform' => NULL, 'format' => 'table']): RowsOfFields {
$devices = [];
/** @var \Drupal\digital_signage_framework\DeviceInterface $device */
foreach (Device::loadMultiple() as $device) {
if ($this->input->getOption('all') || $device->isEnabled()) {
if ($this->input->getOption('platform') === NULL || $device->bundle() === $this->input->getOption('platform')) {
$schedule = $device->getSchedule();
$devices[] = [
'id' => $device->id(),
'label' => $device->label(),
'extid' => $device->extId(),
'platform' => $device->bundle(),
'status' => $device->isEnabled(),
'slides' => ($schedule === NULL) ? 0 : count($schedule->getItems()),
];
}
}
}
return new RowsOfFields($devices);
}
/**
* Show debug log.
*
* @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields|null
* The rows with fields, if no records is requested.
*
* @throws \JsonException
*/
#[Command(name: 'digital-signage-device:log:debug', aliases: ['dsdld'])]
#[Argument(name: 'deviceId', description: 'The id of the device from which to get the logs.')]
#[Option(name: 'record', description: 'The id of the log record which should be shown with details.')]
#[FieldLabels(labels: [
'time' => 'Date / Time',
'message' => 'Message',
])]
#[DefaultTableFields(fields: ['time', 'message'])]
#[Usage(name: 'digital-signage-device:log:debug 17', description: 'Show debug logs from device with id 17.')]
public function showDebugLogs(int $deviceId, array $options = ['record' => NULL, 'format' => 'table']): ?RowsOfFields {
$device = $this->loadDevice($deviceId);
if ($this->input->getOption('record') !== NULL) {
$record = $device->getPlugin()->getRecord($this->input->getOption('record')) ?? '';
if (!is_scalar($record)) {
$record = json_encode($record, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT);
}
$this->io()->block($record);
}
else {
$rows = $device->getPlugin()->showDebugLog($device);
return new RowsOfFields($rows);
}
return NULL;
}
/**
* Show error log.
*
* @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields|null
* The rows with fields, if no records is requested.
*
* @throws \JsonException
*/
#[Command(name: 'digital-signage-device:log:error', aliases: ['dsdle'])]
#[Argument(name: 'deviceId', description: 'The id of the device from which to get the logs.')]
#[Option(name: 'record', description: 'The id of the error record which should be shown with details.')]
#[FieldLabels(labels: [
'time' => 'Date / Time',
'message' => 'Message',
])]
#[DefaultTableFields(fields: ['time', 'message'])]
#[Usage(name: 'digital-signage-device:log:error 17', description: 'Show error logs from device with id 17.')]
public function showErrorLogs(int $deviceId, array $options = ['record' => NULL, 'format' => 'table']): ?RowsOfFields {
$device = $this->loadDevice($deviceId);
if ($this->input->getOption('record') !== NULL) {
$record = $device->getPlugin()->getRecord($this->input->getOption('record')) ?? '';
if (!is_scalar($record)) {
$record = json_encode($record, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT);
}
$this->io()->block($record);
}
else {
$rows = $device->getPlugin()->showErrorLog($device);
return new RowsOfFields($rows);
}
return NULL;
}
/**
* Show slide change report.
*
* @return \Consolidation\OutputFormatters\StructuredData\RowsOfFields
* The rows with fields, if no records is requested.
*/
#[Command(name: 'digital-signage-device:report:slide', aliases: ['dsdrs'])]
#[Argument(name: 'deviceId', description: 'The id of the device from which to get the report.')]
#[FieldLabels(labels: [
'time' => 'Date / Time',
'message' => 'Message',
])]
#[DefaultTableFields(fields: ['time', 'message'])]
#[Usage(name: 'digital-signage-device:report:slide 17', description: 'Show slide change report from device with id 17.')]
public function showSlideChangeReport(int $deviceId, array $options = ['format' => 'table']): RowsOfFields {
$device = $this->loadDevice($deviceId);
$rows = $device->getPlugin()->showSlideReport($device);
return new RowsOfFields($rows);
}
/**
* Turn on debugging for the given device.
*/
#[Command(name: 'digital-signage-device:debug', aliases: ['dsdd'])]
#[Argument(name: 'deviceId', description: 'The id of the device for which to enable debugging.')]
#[Usage(name: 'digital-signage-device:debug 17', description: 'Turn on debugging on device with id 17.')]
public function debug(int $deviceId): void {
$device = $this->loadDevice($deviceId);
$device->getPlugin()->debugDevice($device);
}
/**
* Set emergency mode for the given device.
*/
#[Command(name: 'digital-signage-device:emergencymode:set', aliases: ['dsdes'])]
#[Argument(name: 'deviceId', description: 'The id of the device for which to enable emergency mode.')]
#[Usage(name: 'digital-signage-device:emergencymode:set 17', description: 'Set emergency mode for device with id 17.')]
public function setEmergencyMode(int $deviceId): void {
$device = $this->loadDevice($deviceId);
if ($entities = $this->emergency->allForSelect()) {
$choice = $this->io()->choice('Select the content for emergency mode', $entities);
[$type, $id] = explode('/', $choice);
/** @var \Drupal\Core\Entity\ContentEntityInterface|null $entity */
$entity = $this->entityTypeManager->getStorage($type)->load($id);
if ($entity) {
$device
->set('emergency_entity', $entity->get('digital_signage')->getValue()[0]['target_id'])
->save();
}
}
else {
$this->io()->warning('No emergency content available.');
}
}
/**
* Disable emergency mode on the given device.
*/
#[Command(name: 'digital-signage-device:emergencymode:disable', aliases: ['dsded'])]
#[Argument(name: 'deviceId', description: 'The id of the device for which to enable emergency mode.')]
#[Usage(name: 'digital-signage-device:emergencymode:disable 17', description: 'Disable emergency mode for device with id 17.')]
public function disableEmergencyMode(int $deviceId): void {
$device = $this->loadDevice($deviceId);
$device
->set('emergency_entity', NULL)
->save();
}
/**
* Helper function to load a device entity.
*
* @param int $deviceId
* The device ID.
* @param string|null $bundle
* The optional bundle.
*
* @return \Drupal\digital_signage_framework\DeviceInterface
* The device entity.
*/
protected function loadDevice(int $deviceId, ?string $bundle = NULL): DeviceInterface {
/** @var \Drupal\digital_signage_framework\DeviceInterface|null $device */
$device = Device::load($deviceId);
if ($device === NULL) {
throw new \InvalidArgumentException('Incorrect device ID');
}
if ($bundle !== NULL && $bundle !== $device->bundle()) {
throw new \InvalidArgumentException('Device is not the correct type: ' . $bundle);
}
return $device;
}
}
