reverted: --- b/config/optional/system.action.node_break_lock.yml +++ /dev/null @@ -1,10 +0,0 @@ -langcode: en -status: true -dependencies: - module: - - node -id: node_break_lock -label: 'Break Lock' -type: node -plugin: entity:break_lock:node -configuration: { } diff -u b/src/Plugin/Action/BreakLock.php b/src/Plugin/Action/BreakLock.php --- b/src/Plugin/Action/BreakLock.php +++ b/src/Plugin/Action/BreakLock.php @@ -14,7 +14,7 @@ * * @Action( * id = "entity:break_lock", - * label = @Translation("Break Lock"), + * action_label = @Translation("Break Lock"), * deriver = "Drupal\content_lock\Plugin\Action\BreakLockDeriver", * ) */ @@ -60,7 +60,7 @@ * {@inheritdoc} */ public function execute(ContentEntityInterface $entity = NULL) { - $this->lockService->release($entity->id(), $entity->language()->getId(), NULL, $entity->getEntityTypeId()); + $this->lockService->release($entity->id(), $entity->language()); } /** diff -u b/src/Plugin/Action/BreakLockDeriver.php b/src/Plugin/Action/BreakLockDeriver.php --- b/src/Plugin/Action/BreakLockDeriver.php +++ b/src/Plugin/Action/BreakLockDeriver.php @@ -2,14 +2,89 @@ namespace Drupal\content_lock\Plugin\Action; -use Drupal\Core\Action\Plugin\Action\Derivative\EntityActionDeriverBase; +use Drupal\Component\Plugin\Derivative\DeriverBase; use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; +use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\Core\StringTranslation\TranslationInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides an action deriver that finds content entity types. */ -class BreakLockDeriver extends EntityActionDeriverBase { +class BreakLockDeriver extends DeriverBase implements ContainerDeriverInterface { + + use StringTranslationTrait; + + /** + * The entity type manager. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected $entityTypeManager; + + /** + * Constructs a new EntityActionDeriverBase object. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager + * The entity type manager. + * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation + * The string translation service. + */ + public function __construct(EntityTypeManagerInterface $entity_type_manager, TranslationInterface $string_translation) { + $this->entityTypeManager = $entity_type_manager; + $this->stringTranslation = $string_translation; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( + $container->get('entity_type.manager'), + $container->get('string_translation') + ); + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions($base_plugin_definition) { + if (empty($this->derivatives)) { + $definitions = []; + foreach ($this->getApplicableEntityTypes() as $entity_type_id => $entity_type) { + $definition = $base_plugin_definition; + $definition['type'] = $entity_type_id; + $definition['label'] = sprintf('%s %s', $base_plugin_definition['action_label'], $entity_type->getSingularLabel()); + $definitions[$entity_type_id] = $definition; + } + $this->derivatives = $definitions; + } + + return parent::getDerivativeDefinitions($base_plugin_definition); + } + + /** + * Gets a list of applicable entity types. + * + * The list consists of all entity types which match the conditions for the + * given deriver. + * For example, if the action applies to entities that are publishable, + * this method will find all entity types that are publishable. + * + * @return \Drupal\Core\Entity\EntityTypeInterface[] + * The applicable entity types, keyed by entity type ID. + */ + protected function getApplicableEntityTypes() { + $entity_types = $this->entityTypeManager->getDefinitions(); + $entity_types = array_filter($entity_types, function (EntityTypeInterface $entity_type) { + return $this->isApplicable($entity_type); + }); + + return $entity_types; + } /** * {@inheritdoc} only in patch2: unchanged: --- a/content_lock.services.yml +++ b/content_lock.services.yml @@ -2,3 +2,9 @@ services: content_lock: class: Drupal\content_lock\ContentLock\ContentLock arguments: ['@database', '@module_handler', '@csrf_token', '@date.formatter', '@current_user', '@config.factory', '@request_stack', '@entity_type.manager'] + + settings_save_event_subscriber: + class: '\Drupal\content_lock\EventSubscriber\SettingsSaveEventSubscriber' + arguments: ['@entity_type.manager'] + tags: + - { name: 'event_subscriber' } only in patch2: unchanged: --- /dev/null +++ b/src/EventSubscriber/SettingsSaveEventSubscriber.php @@ -0,0 +1,62 @@ +entityTypeManager = $entity_type_manager; + } + + /** + * On config save. + * + * @param \Drupal\Core\Config\ConfigCrudEvent $event + * The save event. + */ + public function onSave(ConfigCrudEvent $event) { + + if ($event->getConfig()->getName() == 'content_lock.settings') { + + foreach (array_filter($event->getConfig()->get('types')) as $type => $value) { + $action = $this->entityTypeManager->getStorage('action')->loadByProperties([ + 'plugin' => 'entity:break_lock:' . $type, + ]); + if (empty($action)) { + $action = $this->entityTypeManager->getStorage('action')->create([ + 'id' => $type . '_break_lock_action', + 'label' => 'Break lock ' . $type, + 'plugin' => 'entity:break_lock:' . $type, + 'type' => $type, + ]); + $action->save(); + } + } + } + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[ConfigEvents::SAVE][] = ['onSave']; + return $events; + } + +}