diff --git a/core/lib/Drupal/Component/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Component/Plugin/Discovery/AnnotatedClassDiscovery.php index 7e31231..377bf4a 100644 --- a/core/lib/Drupal/Component/Plugin/Discovery/AnnotatedClassDiscovery.php +++ b/core/lib/Drupal/Component/Plugin/Discovery/AnnotatedClassDiscovery.php @@ -45,6 +45,16 @@ class AnnotatedClassDiscovery implements DiscoveryInterface { /** * Constructs an AnnotatedClassDiscovery object. + * + * @param array $plugin_namespaces + * (optional) An array of namespace that may contain plugin implementations. + * Defaults to an empty array. + * @param array $annotation_namespaces + * (optional) The namespaces of classes that can be used as annotations. + * Defaults to an empty array. + * @param string $plugin_definition_annotation_name + * (optional) The name of the annotation that contains the plugin definition. + * Defaults to 'Drupal\Component\Annotation\Plugin'. */ function __construct($plugin_namespaces = array(), $annotation_namespaces = array(), $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') { $this->pluginNamespaces = $plugin_namespaces; diff --git a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php index 3c10366..8ed9440 100644 --- a/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php +++ b/core/lib/Drupal/Core/Plugin/Discovery/AnnotatedClassDiscovery.php @@ -22,9 +22,15 @@ class AnnotatedClassDiscovery extends ComponentAnnotatedClassDiscovery { * @param string $type * The plugin type, for example filter. * @param array $root_namespaces - * Array of root paths keyed by the corresponding namespace to look for - * plugin implementations, \Plugin\$owner\$type will be appended to each - * namespace. + * (optional) An array of root paths keyed by the corresponding namespace to + * look for plugin implementations. '\Plugin\$owner\$type' will be appended + * to each namespace. Defaults to an empty array. + * @param array $annotation_namespaces + * (optional) The namespaces of classes that can be used as annotations. + * Defaults to an empty array. + * @param string $plugin_definition_annotation_name + * (optional) The name of the annotation that contains the plugin definition. + * Defaults to 'Drupal\Component\Annotation\Plugin'. * * @todo Figure out how to make the following comment FALSE. * Drupal modules can be enabled (and therefore, namespaces registered) @@ -33,8 +39,8 @@ class AnnotatedClassDiscovery extends ComponentAnnotatedClassDiscovery { * until the next request. Additionally when a namespace is unregistered, * plugins will not be removed until the next request. */ - function __construct($owner, $type, array $root_namespaces = array()) { - $annotation_namespaces = array( + function __construct($owner, $type, array $root_namespaces = array(), $annotation_namespaces = array(), $plugin_definition_annotation_name = 'Drupal\Component\Annotation\Plugin') { + $annotation_namespaces += array( 'Drupal\Component\Annotation' => DRUPAL_ROOT . '/core/lib', 'Drupal\Core\Annotation' => DRUPAL_ROOT . '/core/lib', ); @@ -42,7 +48,7 @@ function __construct($owner, $type, array $root_namespaces = array()) { foreach ($root_namespaces as $namespace => $dir) { $plugin_namespaces["$namespace\\Plugin\\{$owner}\\{$type}"] = array($dir); } - parent::__construct($plugin_namespaces, $annotation_namespaces); + parent::__construct($plugin_namespaces, $annotation_namespaces, $plugin_definition_annotation_name); } } diff --git a/core/modules/ban/ban.admin.inc b/core/modules/ban/ban.admin.inc deleted file mode 100644 index 9f20a45..0000000 --- a/core/modules/ban/ban.admin.inc +++ /dev/null @@ -1,142 +0,0 @@ -ip; - $links = array(); - $links['delete'] = array( - 'title' => t('delete'), - 'href' => "admin/config/people/ban/delete/$ip->iid", - ); - $row[] = array( - 'data' => array( - '#type' => 'operations', - '#links' => $links, - ), - ); - $rows[] = $row; - } - - $build['ban_ip_form'] = drupal_get_form('ban_ip_form', $default_ip); - - $build['ban_ip_banning_table'] = array( - '#theme' => 'table', - '#header' => $header, - '#rows' => $rows, - '#empty' => t('No blocked IP addresses available.'), - ); - - return $build; -} - -/** - * Form constructor for banning an IP address. - * - * @param string $default_ip - * An IP address to ban, used as default value. - * - * @see ban_ip_form_validate() - * @see ban_ip_form_submit() - * @ingroup forms - */ -function ban_ip_form($form, &$form_state, $default_ip) { - $form['ip'] = array( - '#title' => t('IP address'), - '#type' => 'textfield', - '#size' => 48, - '#maxlength' => 40, - '#default_value' => $default_ip, - '#description' => t('Enter a valid IP address.'), - ); - $form['actions'] = array('#type' => 'actions'); - $form['actions']['submit'] = array( - '#type' => 'submit', - '#value' => t('Add'), - ); - return $form; -} - -/** - * Form validation handler for ban_ip_form(). - * - * @see ban_ip_form_submit() - */ -function ban_ip_form_validate($form, &$form_state) { - $ip = trim($form_state['values']['ip']); - if (db_query("SELECT * FROM {ban_ip} WHERE ip = :ip", array(':ip' => $ip))->fetchField()) { - form_set_error('ip', t('This IP address is already banned.')); - } - elseif ($ip == Drupal::request()->getClientIP()) { - form_set_error('ip', t('You may not ban your own IP address.')); - } - elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) == FALSE) { - form_set_error('ip', t('Enter a valid IP address.')); - } -} - -/** - * Form submission handler for ban_ip_form(). - * - * @see ban_ip_form_validate() - */ -function ban_ip_form_submit($form, &$form_state) { - $ip = trim($form_state['values']['ip']); - db_insert('ban_ip') - ->fields(array('ip' => $ip)) - ->execute(); - drupal_set_message(t('The IP address %ip has been banned.', array('%ip' => $ip))); - $form_state['redirect'] = 'admin/config/people/ban'; -} - -/** - * Form constructor to unban an IP address. - * - * @param array $ban_ip - * The IP address record to unban, as provided by ban_ip_load(). - * - * @see ban_ip_delete_submit() - */ -function ban_ip_delete_form($form, &$form_state, array $ban_ip) { - $form['ban_ip'] = array( - '#type' => 'value', - '#value' => $ban_ip, - ); - return confirm_form($form, - t('Are you sure you want to unblock %ip?', array('%ip' => $ban_ip['ip'])), - 'admin/config/people/ban', - NULL, - t('Delete') - ); -} - -/** - * Form submission handler for ban_ip_delete_form(). - */ -function ban_ip_delete_form_submit($form, &$form_state) { - $banned_ip = $form_state['values']['ban_ip']; - db_delete('ban_ip') - ->condition('iid', $banned_ip['iid']) - ->execute(); - watchdog('user', 'Deleted %ip', array('%ip' => $banned_ip['ip'])); - drupal_set_message(t('The IP address %ip was deleted.', array('%ip' => $banned_ip['ip']))); - $form_state['redirect'] = 'admin/config/people/ban'; -} diff --git a/core/modules/ban/ban.module b/core/modules/ban/ban.module index 9e9ed0f..29becf5 100644 --- a/core/modules/ban/ban.module +++ b/core/modules/ban/ban.module @@ -44,30 +44,12 @@ function ban_menu() { $items['admin/config/people/ban'] = array( 'title' => 'IP address bans', 'description' => 'Manage banned IP addresses.', - 'page callback' => 'ban_admin_page', - 'access arguments' => array('ban IP addresses'), - 'file' => 'ban.admin.inc', + 'route_name' => 'ban_admin_page', 'weight' => 10, ); $items['admin/config/people/ban/delete/%ban_ip'] = array( 'title' => 'Delete IP address', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('ban_ip_delete_form', 5), - 'access arguments' => array('ban IP addresses'), - 'file' => 'ban.admin.inc', + 'route_name' => 'ban_delete', ); return $items; } - -/** - * Loads a banned IP address record from the database. - * - * @param int $iid - * The ID of the banned IP address to retrieve. - * - * @return array - * The banned IP address record from the database as an array. - */ -function ban_ip_load($iid) { - return db_query("SELECT * FROM {ban_ip} WHERE iid = :iid", array(':iid' => $iid))->fetchAssoc(); -} diff --git a/core/modules/ban/ban.routing.yml b/core/modules/ban/ban.routing.yml new file mode 100644 index 0000000..366bd2e --- /dev/null +++ b/core/modules/ban/ban.routing.yml @@ -0,0 +1,14 @@ +ban_admin_page: + pattern: '/admin/config/people/ban/{default_ip}' + defaults: + _form: '\Drupal\ban\Form\BanAdmin' + default_ip: '' + requirements: + _permission: 'ban IP addresses' + +ban_delete: + pattern: '/admin/config/people/ban/delete/{ban_ip}' + defaults: + _form: '\Drupal\ban\Form\BanDelete' + requirements: + _permission: 'ban IP addresses' diff --git a/core/modules/ban/lib/Drupal/ban/Form/BanAdmin.php b/core/modules/ban/lib/Drupal/ban/Form/BanAdmin.php new file mode 100644 index 0000000..b2cd013 --- /dev/null +++ b/core/modules/ban/lib/Drupal/ban/Form/BanAdmin.php @@ -0,0 +1,145 @@ +request = $request; + $this->database = $database; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('request'), + $container->get('database') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'ban_ip_form'; + } + + /** + * {@inheritdoc} + * + * @param string $default_ip + * (optional) IP address to be passed on to drupal_get_form() for use as the + * default value of the IP address form field. + */ + public function buildForm(array $form, array &$form_state, $default_ip = '') { + $rows = array(); + $header = array(t('banned IP addresses'), t('Operations')); + $result = $this->database->query('SELECT * FROM {ban_ip}'); + foreach ($result as $ip) { + $row = array(); + $row[] = $ip->ip; + $links = array(); + $links['delete'] = array( + 'title' => t('delete'), + 'href' => "admin/config/people/ban/delete/$ip->iid", + ); + $row[] = array( + 'data' => array( + '#type' => 'operations', + '#links' => $links, + ), + ); + $rows[] = $row; + } + + $form['ip'] = array( + '#title' => t('IP address'), + '#type' => 'textfield', + '#size' => 48, + '#maxlength' => 40, + '#default_value' => $default_ip, + '#description' => t('Enter a valid IP address.'), + ); + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Add'), + ); + + $form['ban_ip_banning_table'] = array( + '#theme' => 'table', + '#header' => $header, + '#rows' => $rows, + '#empty' => t('No blocked IP addresses available.'), + '#weight' => 120, + ); + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, array &$form_state) { + $ip = trim($form_state['values']['ip']); + if ($this->database->query("SELECT * FROM {ban_ip} WHERE ip = :ip", array(':ip' => $ip))->fetchField()) { + form_set_error('ip', t('This IP address is already banned.')); + } + elseif ($ip == $this->request->getClientIP()) { + form_set_error('ip', t('You may not ban your own IP address.')); + } + elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) == FALSE) { + form_set_error('ip', t('Enter a valid IP address.')); + } + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $ip = trim($form_state['values']['ip']); + $this->database->insert('ban_ip') + ->fields(array('ip' => $ip)) + ->execute(); + drupal_set_message(t('The IP address %ip has been banned.', array('%ip' => $ip))); + $form_state['redirect'] = 'admin/config/people/ban'; + } + +} diff --git a/core/modules/ban/lib/Drupal/ban/Form/BanDelete.php b/core/modules/ban/lib/Drupal/ban/Form/BanDelete.php new file mode 100644 index 0000000..8017f9c --- /dev/null +++ b/core/modules/ban/lib/Drupal/ban/Form/BanDelete.php @@ -0,0 +1,104 @@ +database = $database; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('database') + ); + } + + /** + * {@inheritdoc} + */ + public function getFormID() { + return 'ban_ip_delete_form'; + } + + /** + * {@inheritdoc} + */ + protected function getQuestion() { + return t('Are you sure you want to unblock %ip?', array('%ip' => $this->banIP['ip'])); + } + + /** + * {@inheritdoc} + */ + protected function getConfirmText() { + return t('Delete'); + } + + /** + * {@inheritdoc} + */ + protected function getCancelPath() { + return 'admin/config/people/ban'; + } + + /** + * {@inheritdoc} + * + * @param int $ban_ip_id + * The IP address record ID to unban. + */ + public function buildForm(array $form, array &$form_state, $ban_ip = '') { + $this->banIP = $this->database->query("SELECT * FROM {ban_ip} WHERE iid = :iid", array(':iid' => $ban_ip))->fetchAssoc(); + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + $this->database->delete('ban_ip') + ->condition('iid', $this->banIP['iid']) + ->execute(); + watchdog('user', 'Deleted %ip', array('%ip' => $this->banIP['ip'])); + drupal_set_message(t('The IP address %ip was deleted.', array('%ip' => $this->banIP['ip']))); + $form_state['redirect'] = 'admin/config/people/ban'; + } + +} diff --git a/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php new file mode 100644 index 0000000..792f8a7 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Tests/Plugin/Discovery/CustomAnnotationClassDiscoveryTest.php @@ -0,0 +1,51 @@ + 'Custom annotation class discovery', + 'description' => 'Tests that a custom annotation class is used.', + 'group' => 'Plugin API', + ); + } + + protected function setUp() { + parent::setUp(); + + $this->expectedDefinitions = array( + 'example_1' => array( + 'id' => 'example_1', + 'custom' => 'John', + 'class' => 'Drupal\plugin_test\Plugin\plugin_test\custom_annotation\Example1', + ), + 'example_2' => array( + 'id' => 'example_2', + 'custom' => 'Paul', + 'class' => 'Drupal\plugin_test\Plugin\plugin_test\custom_annotation\Example2', + ), + ); + $root_namespaces = array('Drupal\plugin_test' => DRUPAL_ROOT . '/core/modules/system/tests/modules/plugin_test/lib'); + $annotation_namespaces = array( + 'Drupal\plugin_test\Plugin\Annotation' => DRUPAL_ROOT . '/core/modules/system/tests/modules/plugin_test/lib', + ); + + $this->discovery = new AnnotatedClassDiscovery('plugin_test', 'custom_annotation', $root_namespaces, $annotation_namespaces, 'Drupal\plugin_test\Plugin\Annotation\PluginExample'); + $this->emptyDiscovery = new AnnotatedClassDiscovery('non_existing_module', 'non_existing_plugin_type', $root_namespaces, $annotation_namespaces, 'Drupal\plugin_test\Plugin\Annotation\PluginExample'); + } + +} diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Annotation/PluginExample.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Annotation/PluginExample.php new file mode 100644 index 0000000..f830152 --- /dev/null +++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/Annotation/PluginExample.php @@ -0,0 +1,43 @@ + $this->id, + 'custom' => $this->custom, + ); + } + +} diff --git a/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/custom_annotation/Example1.php b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/custom_annotation/Example1.php new file mode 100644 index 0000000..269f3ed --- /dev/null +++ b/core/modules/system/tests/modules/plugin_test/lib/Drupal/plugin_test/Plugin/plugin_test/custom_annotation/Example1.php @@ -0,0 +1,20 @@ + empty($form_state['ok_button']) ? t('Cancel') : t('Ok'), '#submit' => array($cancel_submit), '#validate' => array(), + '#attributes' => array('formnovalidate' => ''), ); // Compatibility, to be removed later: // TODO: When is "later"?