lightning_scheduler-8.x-1.x-dev/lightning_scheduler.module
lightning_scheduler.module
<?php
use Drupal\content_moderation\Plugin\WorkflowType\ContentModeration;
use Drupal\Core\Cache\CacheCollectorInterface;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Extension\Extension;
use Drupal\Core\Update\UpdateKernel;
use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
use Drupal\lightning_scheduler\Plugin\Field\FieldWidget\ModerationStateWidget;
use Drupal\workflows\WorkflowInterface;
use Drupal\lightning_scheduler\BaseFields;
/**
* Implements hook_library_info_alter().
*/
function lightning_scheduler_library_info_alter(array &$libraries, $extension) {
if ($extension === 'seven') {
$dir = \Drupal::service('extension.list.module')->getPath('lightning_scheduler');
$libraries['lightning_scheduler.widget'] = [
'css' => [
'theme' => [
// @TODO This will break if the site is running in a subdirectory.
"/$dir/css/component.seven.css" => [],
],
],
];
}
}
/**
* Implements hook_system_info_alter().
*/
function lightning_scheduler_system_info_alter(array &$info, Extension $extension, $type) {
if ($type === 'theme' && $extension->getName() === 'seven') {
$info['libraries-extend']['lightning_scheduler/widget'][] = 'seven/lightning_scheduler.widget';
}
}
/**
* Implements hook_cron().
*/
function lightning_scheduler_cron() {
// Do not execute during database updates. This hook could be invoked if, for
// example, Automated Cron is triggered at the end of one of the many HTTP
// requests that are made during an update.php process.
if (Drupal::service('kernel') instanceof UpdateKernel) {
return;
}
$field_manager = Drupal::service('entity_field.manager');
// Retrieve all entity types with the 'schedule_transition_state' and
// 'scheduled_transition_date' fields in active field storage.
$entity_types = array_filter(array_keys($field_manager->getFieldMap()), function ($entity_type_id) use ($field_manager) {
$fields = $field_manager->getActiveFieldStorageDefinitions($entity_type_id);
return isset($fields['scheduled_transition_state'], $fields['scheduled_transition_date']);
});
/** @var \Drupal\lightning_scheduler\TransitionManager $transition_manager */
$transition_manager = Drupal::service('lightning_scheduler.transition_manager');
$start = new DrupalDateTime('now', DateTimeItemInterface::STORAGE_TIMEZONE);
$now = Drupal::time()->getRequestTime();
$start->setTimestamp($now);
foreach ($entity_types as $entity_type_id) {
$transition_manager->process($entity_type_id, $start);
}
// At some point, core started caching state values, both statically and
// persistently. Unfortunately, the cron service does not explicitly persist
// the system.cron_last variable, which means that subsequent reads of
// system.cron_last might return an outdated value, thus breaking any code
// which is sensitive to the last cron run time (e.g., this module). This
// should be fixed in core at some point, but for now we can work around it by
// ensuring the state cache is cleared during cron, ensuring that all of its
// values are persisted.
$state = Drupal::state();
if ($state instanceof CacheCollectorInterface) {
$state->resetCache();
}
}
/**
* Implements hook_entity_base_field_info().
*/
function lightning_scheduler_entity_base_field_info(EntityTypeInterface $entity_type) {
$fields = [];
/** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_info */
$moderation_info = Drupal::service('content_moderation.moderation_information');
if ($moderation_info->isModeratedEntityType($entity_type)) {
$fields += BaseFields::getLightningSchedulerBaseFieldDefinitions();
}
return $fields;
}
/**
* Implements hook_field_widget_info_alter().
*/
function lightning_scheduler_field_widget_info_alter(array &$info) {
// Make the moderation state basefield widget use our plugin class.
if (!empty($info['moderation_state_default'])) {
$info['moderation_state_default']['class'] = ModerationStateWidget::class;
}
}
/**
* Implements hook_local_tasks_alter().
*/
function lightning_scheduler_local_tasks_alter(array &$local_tasks) {
// This makes our test code simpler, and should be harmless.
$local_tasks['entity.node.edit_form']['options']['attributes']['rel'] = 'edit-form';
}
/**
* Implements hook_ENTITY_TYPE_insert().
*/
function lightning_scheduler_workflow_insert(WorkflowInterface $entity) {
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$workflow_plugin = $entity->getTypePlugin();
if ($workflow_plugin instanceof ContentModeration) {
// Install our base field definitions for every moderated entity type.
foreach ($workflow_plugin->getEntityTypes() as $entity_type_id) {
foreach (BaseFields::getLightningSchedulerBaseFieldDefinitions() as $field_name => $field_storage_definition) {
if (!$entity_definition_update_manager->getFieldStorageDefinition($field_name, $entity_type_id)) {
$entity_definition_update_manager->installFieldStorageDefinition($field_name, $entity_type_id, 'lightning_scheduler', $field_storage_definition);
}
}
}
}
}
/**
* Implements hook_ENTITY_TYPE_update().
*/
function lightning_scheduler_workflow_update(WorkflowInterface $entity) {
$entity_type_manager = \Drupal::entityTypeManager();
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
/** @var \Drupal\content_moderation\ModerationInformationInterface $moderation_information */
$moderation_information = \Drupal::service('content_moderation.moderation_information');
// Either install our base field definitions for entity types that are now
// moderated, or remove them for those that are not moderated anymore.
foreach ($entity_type_manager->getDefinitions() as $entity_type_id => $entity_type) {
if ($moderation_information->isModeratedEntityType($entity_type)) {
foreach (BaseFields::getLightningSchedulerBaseFieldDefinitions() as $field_name => $field_storage_definition) {
if (!$entity_definition_update_manager->getFieldStorageDefinition($field_name, $entity_type_id)) {
$entity_definition_update_manager->installFieldStorageDefinition($field_name, $entity_type_id, 'lightning_scheduler', $field_storage_definition);
}
}
}
else {
foreach (array_keys(BaseFields::getLightningSchedulerBaseFieldDefinitions()) as $field_name) {
if ($field_storage_definition = $entity_definition_update_manager->getFieldStorageDefinition($field_name, $entity_type_id)) {
$entity_definition_update_manager->uninstallFieldStorageDefinition($field_storage_definition);
}
}
}
}
}
/**
* Implements hook_ENTITY_TYPE_delete().
*/
function lightning_scheduler_workflow_delete(WorkflowInterface $entity) {
$entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager();
$workflow_plugin = $entity->getTypePlugin();
if ($workflow_plugin instanceof ContentModeration) {
// Remove our base field definitions for every entity type that was
// moderated.
foreach ($workflow_plugin->getEntityTypes() as $entity_type_id) {
foreach (array_keys(BaseFields::getLightningSchedulerBaseFieldDefinitions()) as $field_name) {
if ($field_storage_definition = $entity_definition_update_manager->getFieldStorageDefinition($field_name, $entity_type_id)) {
$entity_definition_update_manager->uninstallFieldStorageDefinition($field_storage_definition);
}
}
}
}
}
