diff --git a/ctools.routing.yml b/ctools.routing.yml new file mode 100644 index 0000000..a8eecb1 --- /dev/null +++ b/ctools.routing.yml @@ -0,0 +1,7 @@ +ctools.user_permission_autocomplete: + path: '/ctools/user-permission-autocomplete' + defaults: + _controller: '\Drupal\ctools\Controller\CtoolsAutocomplete::autocompletePermission' + requirements: + # @todo What permission do we use? + _permission: 'administer blocks' diff --git a/src/Controller/CtoolsAutocomplete.php b/src/Controller/CtoolsAutocomplete.php new file mode 100644 index 0000000..b947a09 --- /dev/null +++ b/src/Controller/CtoolsAutocomplete.php @@ -0,0 +1,61 @@ +permissionHandler = $permission_handler; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('user.permissions') + ); + } + + /** + * @param \Symfony\Component\HttpFoundation\Request $request + * + * @return \Symfony\Component\HttpFoundation\JsonResponse + */ + public function autocompletePermission(Request $request) { + $typed_permission = $request->query->get('q'); + $matches = []; + foreach ($this->permissionHandler->getPermissions() as $key => $permission) { + if (stripos($key, $typed_permission) === 0 || stripos($permission['title'], $typed_permission) === 0) { + $key = $permission['title'] . "($key)"; + $matches[] = ['value' => $key, 'label' => $permission['title']]; + } + } + return new JsonResponse($matches); + } + +} diff --git a/src/Plugin/Condition/Permission.php b/src/Plugin/Condition/Permission.php index 5a1edad..65e087a 100644 --- a/src/Plugin/Condition/Permission.php +++ b/src/Plugin/Condition/Permission.php @@ -9,6 +9,8 @@ use Drupal\Core\Condition\ConditionPluginBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides a 'User Permission' condition. @@ -22,7 +24,32 @@ * ) * */ -class Permission extends ConditionPluginBase { +class Permission extends ConditionPluginBase implements ContainerFactoryPluginInterface { + + /** + * @var \Drupal\user\PermissionHandlerInterface + */ + protected $permissionHandler; + + /** + * Permission constructor. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, \Drupal\user\PermissionHandlerInterface $permission_handler) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + $this->permissionHandler = $permission_handler; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('user.permissions') + ); + } /** * {@inheritdoc} @@ -31,13 +58,41 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta $form['permission'] = array( '#type' => 'textfield', '#title' => $this->t('When the user has the following permission'), - '#default_value' => $this->configuration['permission'], + '#default_value' => $this->getPermissionString(), '#description' => $this->t('If you specify no permission, the condition will evaluate to TRUE for all users.'), + '#autocomplete_route_name' => 'ctools.user_permission_autocomplete', + '#element_validate' => [[static::class, 'validateAutocomplete']], ); return parent::buildConfigurationForm($form, $form_state); } /** + * @todo. + */ + protected function getPermissionString() { + $permission_string = $this->configuration['permission']; + $permissions = $this->permissionHandler->getPermissions(); + if (!empty($permissions[$permission_string])) { + $permission_string = $permissions[$permission_string]['title'] . ' (' . $permission_string . ')'; + } + return $permission_string; + } + + /** + * @todo. + */ + public static function validateAutocomplete(array &$element, FormStateInterface $form_state, array &$complete_form) { + if (!empty($element['#value'])) { + if (preg_match("/.+\s\(([\w\s]+)\)/", $element['#value'], $matches)) { + $form_state->setValueForElement($element, $matches[1]); + } + else { + $form_state->setError($element, '@todo'); + } + } + } + + /** * {@inheritdoc} */ public function defaultConfiguration() { diff --git a/tests/src/Unit/PermissionTest.php b/tests/src/Unit/PermissionTest.php new file mode 100644 index 0000000..e61c731 --- /dev/null +++ b/tests/src/Unit/PermissionTest.php @@ -0,0 +1,55 @@ +assertSame($expected, $form_state->getValue($form['#parents'])); + $this->assertSame($expected_errors, $form_state->getErrors()); + } + + public function providerTestValidateAutocomplete() { + $data = []; + $data['null'] = [ + NULL, + NULL, + [], + ]; + $data['no_match'] = [ + 'some_value', + NULL, + ['the_parents' => 'Nope'], + ]; + $data['match'] = [ + 'Human readable (machine readable)', + 'machine readable', + [], + ]; + return $data; + } + +}