commands-1.x-dev/src/Entity/Command.php
src/Entity/Command.php
<?php
namespace Drupal\commands\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityChangedTrait;
use Drupal\Core\Entity\EntityStorageInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\RevisionableContentEntityBase;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\commands\CommandInterface;
use Drupal\user\EntityOwnerTrait;
/**
* Defines the command entity class.
*
* @ContentEntityType(
* id = "command",
* label = @Translation("Command run"),
* label_collection = @Translation("Command runs"),
* label_singular = @Translation("command run"),
* label_plural = @Translation("command runs"),
* label_count = @PluralTranslation(
* singular = "@count command run",
* plural = "@count command runs",
* ),
* bundle_label = @Translation("Command type"),
* handlers = {
* "list_builder" = "Drupal\commands\CommandListBuilder",
* "views_data" = "Drupal\views\EntityViewsData",
* "access" = "Drupal\commands\CommandAccessControlHandler",
* "form" = {
* "add" = "Drupal\commands\Form\CommandForm",
* "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm",
* },
* "route_provider" = {
* "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
* }
* },
* base_table = "operations_command",
* data_table = "operations_command_data",
* revision_table = "operations_command_revision",
* revision_data_table = "operations_command_revision_data",
* show_revision_ui = TRUE,
* admin_permission = "administer command types",
* entity_keys = {
* "id" = "id",
* "bundle" = "command_type",
* "label" = "id",
* "revision" = "vid",
* "uuid" = "uuid",
* "owner" = "uid",
* },
* links = {
* "collection" = "/admin/content/command",
* "add-form" = "/command/run/{command_type}",
* "add-page" = "/command/run",
* "canonical" = "/command/{command}",
* "delete-form" = "/command/{command}/delete",
* "version_history" = "/command/{command}/history",
* "revision" = "/command/{command}/history/{command_revision}/view",
* },
* revision_metadata_keys = {
* "revision_user" = "revision_uid",
* "revision_created" = "revision_timestamp",
* "revision_log_message" = "revision_log",
* },
* bundle_entity_type = "command_type",
* field_ui_base_route = "entity.command_type.edit_form",
* )
*/
class Command extends RevisionableContentEntityBase {
use EntityChangedTrait;
use EntityOwnerTrait;
/**
* A command is queued.
*/
const COMMAND_QUEUED = -1;
/**
* A command process is running.
*/
const COMMAND_PROCESSING = 3;
/**
* The command ended with an error.
*/
const COMMAND_ERROR = 2;
/**
* The command ended successfully.
*/
const COMMAND_OK = 0;
/**
* The command ended but a warning was detected.
*/
const COMMAND_WARN = 1;
/**
* Human-readable strings for state.
*
* @var string
*/
const STATE_NAMES = [
self::COMMAND_OK => 'OK',
self::COMMAND_WARN => 'Warning',
self::COMMAND_ERROR => 'Error',
self::COMMAND_PROCESSING => 'Processing',
self::COMMAND_QUEUED => 'Queued',
];
/**
* {@inheritdoc}
*/
public function preSave(EntityStorageInterface $storage) {
parent::preSave($storage);
if (!$this->getOwnerId()) {
// If no owner has been set explicitly, make the anonymous user the owner.
$this->setOwnerId(0);
}
// Apply params to command.
$params = $this->parameters->get(0)? $this->parameters->get(0)->getValue(): [];
$this->set('command', $this->getBundleEntity()->commandPlugin()->command($params));
// If "finished" time is set, save duration field.
if ($this->finished->value) {
$this->duration->setValue($this->finished->value - $this->executed->value);
}
}
/**
* Returns the bundle entity of the entity, or NULL if there is none.
*
* @return \Drupal\Core\Entity\EntityInterface|null
* The bundle entity.
*/
protected function getBundleEntity() {
if ($bundle_entity_type = $this->getEntityType()->getBundleEntityType()) {
return \Drupal::entityTypeManager()->getStorage($bundle_entity_type)->load($this->bundle());
}
return NULL;
}
/**
* {@inheritdoc}
*/
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
$fields['uid'] = BaseFieldDefinition::create('entity_reference')
->setLabel(t('Created by'))
->setSetting('target_type', 'user')
->setDefaultValueCallback(static::class . '::getDefaultEntityOwner')
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'author',
'weight' => 15,
])
->setDisplayConfigurable('view', TRUE);
$fields['created'] = BaseFieldDefinition::create('created')
->setLabel(t('Created on'))
->setDescription(t('The time that the command entity was created.'))
->setDisplayOptions('view', [
'label' => 'inline',
'type' => 'timestamp',
'weight' => 20,
])
->setDisplayConfigurable('view', TRUE);
$fields['state'] = BaseFieldDefinition::create('list_integer')
->setSetting('allowed_values', [
static::STATE_NAMES
])
->setLabel(t('Command State'))
->setDescription(t('The latest state of a command.'))
->setDefaultValue(static::COMMAND_QUEUED)
->setRequired(TRUE)
->setRevisionable(TRUE)
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'hidden',
'type' => 'list_default',
'weight' => -15,
])
;
$fields['command'] = BaseFieldDefinition::create('string')
->setLabel(t('Command'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setRequired(TRUE)
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'string',
'weight' => -5,
])
;
$fields['parameters'] = BaseFieldDefinition::create('map')
->setRevisionable(TRUE)
->setLabel(t('Command parameters'))
->setDescription(t('Key value pairs to be used in generating this command.'))
->setRequired(FALSE)
// @TODO: "map" fields need a widget.
// ->setDisplayConfigurable('view', TRUE)
// ->setDisplayOptions('view', [
// 'label' => 'visible',
// 'type' => 'table',
// 'weight' => -5,
// ])
;
$fields['working_directory'] = BaseFieldDefinition::create('string')
->setLabel(t('Working Directory'))
->setDescription(t('The directory to run the command in.'))
->setDefaultValueCallback('\Drupal\commands\Entity\Command::defaultWorkingDirectory')
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'string',
'weight' => -5,
])
;
$fields['output'] = BaseFieldDefinition::create('output')
->setLabel(t('Output'))
->setDescription(t('Output from the command.'))
->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
->setRequired(FALSE)
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'output_ansi',
'weight' => -5,
])
;
$fields['executed'] = BaseFieldDefinition::create('timestamp')
->setLabel(t('Start Time'))
->setDescription(t('The time that the command was started.'))
->setRequired(FALSE)
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'timestamp',
'weight' => -5,
])
;
$fields['finished'] = BaseFieldDefinition::create('timestamp')
->setLabel(t('End Time'))
->setDescription(t('The time that the command ended.'))
->setRequired(FALSE)
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'timestamp',
'weight' => -5,
])
;
$fields['duration'] = BaseFieldDefinition::create('integer')
->setLabel(t('Duration'))
->setDescription(t('The amount of time that a command took to run.'))
->setRequired(FALSE)
->setSetting('suffix', t(' seconds'))
->setDisplayConfigurable('view', TRUE)
->setDisplayOptions('view', [
'label' => 'visible',
'type' => 'number_integer',
'weight' => -5,
])
;
return $fields;
}
/**
* Default value for working_directory field.
* @return false|string
*/
public static function defaultWorkingDirectory() {
return getcwd();
}
/**
* Create a more user friendly label.
* @return array|\Drupal\Core\StringTranslation\TranslatableMarkup|mixed|string|void|null
*/
public function label() {
$label = t(':type #:id', [
':type' => $this->getBundleEntity() ? $this->getBundleEntity()->label(): parent::label(),
':id' => parent::label(),
]);
return $label;
}
}
