Browse Source

Clean up module and install files. Implement hook_help(), hook_requirements().

Frederic G. MARAND 7 years ago
parent
commit
be9aa158c1

+ 65 - 7
src/Plugin/Filter/UrlReplaceFilter.php

@@ -8,6 +8,7 @@ use Drupal\Core\Messenger\MessengerInterface;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Routing\CurrentRouteMatch;
 use Drupal\Core\Url;
+use Drupal\filter\Entity\FilterFormat;
 use Drupal\filter\FilterProcessResult;
 use Drupal\filter\Plugin\FilterBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -28,6 +29,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  */
 class UrlReplaceFilter extends FilterBase implements ContainerFactoryPluginInterface {
 
+  const ID = 'url_replace_filter';
   const SETTING_NAME = 'replacements';
 
   /**
@@ -54,16 +56,17 @@ class UrlReplaceFilter extends FilterBase implements ContainerFactoryPluginInter
    * @param array $plugin_definition
    *   The plugin definition.
    * @param \Drupal\Core\Routing\CurrentRouteMatch $currentRouteMatch
-   *   The current_route_match service.
+   *   Optional: the current_route_match service. Only used by the settings
+   *   form.
    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
-   *   The messenger service.
+   *   Optional: the messenger service. Only used by the settings form.
    */
   public function __construct(
     array $configuration,
     $plugin_id,
     array $plugin_definition,
-    CurrentRouteMatch $currentRouteMatch,
-    MessengerInterface $messenger
+    CurrentRouteMatch $currentRouteMatch = NULL,
+    MessengerInterface $messenger = NULL
   ) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->currentRouteMatch = $currentRouteMatch;
@@ -114,6 +117,45 @@ class UrlReplaceFilter extends FilterBase implements ContainerFactoryPluginInter
     return $form;
   }
 
+  /**
+   * Return the list of input formats containing the active URL Replace filter.
+   *
+   * @return array
+   *   The list of input format names, keyed by format_id.
+   */
+  public static function getFormats() {
+    $formats = FilterFormat::loadMultiple();
+
+    $ret = [];
+    /** @var \Drupal\filter\FilterFormatInterface $format */
+    foreach ($formats as $format_id => $format) {
+      /** @var \Drupal\filter\FilterPluginCollection $filterCollection */
+      $filterCollection = $format->filters();
+      if (!$filterCollection->has(static::ID)) {
+        continue;
+      }
+
+      /** @var \Drupal\filter\Plugin\FilterInterface $filter */
+      $filter = $filterCollection->get(static::ID);
+      if ($filter->getConfiguration()['status'] ?? FALSE) {
+        $ret[$format_id] = $format->label();
+      }
+    }
+
+    return $ret;
+  }
+
+  /**
+   * Implements hook_help().
+   */
+  public static function help(string $routeName) {
+    if ($routeName !== 'filter.admin_overview') {
+      return;
+    }
+
+    return t('To configure url_replace_filter, enable its checkbox in each text format where you want it, then configure its rewriting rules in the vertical tab which will appear at the bottom of the format configuration page. The module does not contain any global configuration.');
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -122,6 +164,22 @@ class UrlReplaceFilter extends FilterBase implements ContainerFactoryPluginInter
     $empty = 0;
     $form[self::SETTING_NAME] = [
       '#type' => 'details',
+      '#description' => $this->t("
+<p>Enter original base URLs and their replacements. Matching not case-sensitive. 
+  You may use <em>%baseurl</em> in the replacement string to insert your site's 
+  base URL (without the trailing slash).</p>
+
+<p><strong>Warning</strong>: To avoid unexpected results, you must include
+  trailing slashes in both the original and replacement strings.</p>
+ 
+<p><strong>Warning</strong>: Replacements are executed in the order you give 
+  them. Place the most specific URLs first. For example, 
+  <em>http://example.com/somepath/</em> should be replaced before 
+  <em>http://example.com/</em>.</p>
+  
+<p>If you need more replacement rules, more fields will be added after saving 
+  the settings.</p>"),
+
       '#title' => $this->t('URL Replace Filter'),
       '#open' => TRUE,
       '#theme' => 'url_replace_filter_settings_form',
@@ -150,14 +208,14 @@ class UrlReplaceFilter extends FilterBase implements ContainerFactoryPluginInter
   }
 
   /**
-   * Submit handler for _url_replace_filter_settings() form.
+   * Element_validate handler for settingsForm().
    *
    * Remove useless empty settings to keep variable as small as possible.
    *
    * Needs to be public to be usable as a #element_validate callback.
    */
   public function settingsFormValidate(array $form, FormStateInterface &$form_state) {
-    $settings = $form_state->getValue('filters')['url_replace_filter']['settings'][self::SETTING_NAME];
+    $settings = $form_state->getValue('filters')[self::ID]['settings'][self::SETTING_NAME];
 
     $validSettings = array_filter($settings, function (array $setting) {
       return !(empty($setting['original']) && empty($setting['replacement']));
@@ -166,7 +224,7 @@ class UrlReplaceFilter extends FilterBase implements ContainerFactoryPluginInter
     $result = serialize(array_values($validSettings));
     $form_state->setValue([
       'filters',
-      'url_replace_filter',
+      self::ID,
       'settings',
       self::SETTING_NAME,
     ], $result);

File diff suppressed because it is too large
+ 0 - 51
src/Tests/UrlReplaceFilterTest.php


+ 97 - 0
test/src/Unit/UrlReplaceFilterTest.php

@@ -0,0 +1,97 @@
+<?php
+
+namespace Drupal\Tests\filter\Unit;
+
+use Drupal\Tests\UnitTestCase;
+use Drupal\url_replace_filter\Plugin\Filter\UrlReplaceFilter;
+
+/**
+ * @coversDefaultClass \Drupal\url_replace_filter\Plugin\Filter\UrlReplaceFilter
+ * @group filter
+ */
+class UrlReplaceFilterTest extends UnitTestCase {
+
+  /**
+   * @var \Drupal\url_replace_filter\Plugin\Filter\UrlReplaceFilter
+   */
+  protected $filter;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $configuration['settings'] = [
+      UrlReplaceFilter::SETTING_NAME => serialize([
+        'original' => '',
+        'replacement' => '',
+      ]),
+    ];
+    $this->filter = new UrlReplaceFilter($configuration, UrlReplaceFilter::ID, ['provider' => 'test']);
+    $this->filter->setStringTranslation($this->getStringTranslationStub());
+  }
+
+  /**
+   * @covers ::filterAttributes
+   *
+   * @dataProvider providerFilterAttributes
+   *
+   * @param string $html
+   *   Input HTML.
+   * @param array $expected
+   *   The expected output string.
+   */
+  public function testfilterAttributes($html, $expected) {
+    $this->assertSame($expected, $this->filter->filterAttributes($html));
+  }
+
+  /**
+   * Provides data for testfilterAttributes.
+   *
+   * @return array
+   *   An array of test data.
+   */
+  public function providerFilterAttributes() {
+    return [
+      ['<a href="/blog" title="Blog">Blog</a>', '<a href="/blog">Blog</a>'],
+      ['<p dir="rtl" />', '<p dir="rtl"></p>'],
+      ['<p dir="bogus" />', '<p></p>'],
+      ['<p id="first" />', '<p></p>'],
+      // The addition of xml:lang isn't especially desired, but is still valid
+      // HTML5. See https://www.drupal.org/node/1333730.
+      ['<p id="first" lang="en">text</p>', '<p lang="en" xml:lang="en">text</p>'],
+      ['<p style="display: none;" />', '<p></p>'],
+      ['<code class="pretty invalid">foreach ($a as $b) {}</code>', '<code class="pretty">foreach ($a as $b) {}</code>'],
+      ['<code class="boring pretty">foreach ($a as $b) {}</code>', '<code class="boring pretty">foreach ($a as $b) {}</code>'],
+      ['<code class="boring    pretty ">foreach ($a as $b) {}</code>', '<code class="boring pretty">foreach ($a as $b) {}</code>'],
+      ['<code class="invalid alpaca">foreach ($a as $b) {}</code>', '<code>foreach ($a as $b) {}</code>'],
+      ['<h3 class="big">a heading</h3>', '<h3>a heading</h3>'],
+      ['<h3 id="first">a heading</h3>', '<h3 id="first">a heading</h3>'],
+      // Wilcard value. Case matters, so upper case doesn't match.
+      ['<code class="align-left bold">foreach ($a as $b) {}</code>', '<code class="align-left">foreach ($a as $b) {}</code>'],
+      ['<code class="align-right ">foreach ($a as $b) {}</code>', '<code class="align-right">foreach ($a as $b) {}</code>'],
+      ['<code class="Align-right ">foreach ($a as $b) {}</code>', '<code>foreach ($a as $b) {}</code>'],
+      // Wilcard name, case is ignored.
+      ['<ol style="display: none;" llama-wim="noble majestic"></ol>', '<ol llama-wim="noble majestic"></ol>'],
+      ['<ol style="display: none;" LlamA-Wim="majestic"></ol>', '<ol llama-wim="majestic"></ol>'],
+      ['<ol style="display: none;" llama-="noble majestic"></ol>', '<ol llama-="noble majestic"></ol>'],
+      // Both wildcard names and values.
+      ['<ul style="display: none;" alpaca-wool="wooly-warm strong majestic"></ul>', '<ul alpaca-wool="wooly-warm strong"></ul>'],
+    ];
+  }
+
+  /**
+   * @covers ::setConfiguration
+   */
+  public function testSetConfiguration() {
+    $configuration['settings'] = [
+      // New lines and spaces are replaced with a single space.
+      'allowed_html' => "<a>  <br>\r\n  <p>",
+      'filter_html_help' => 1,
+      'filter_html_nofollow' => 0,
+    ];
+    $filter = new FilterHtml($configuration, 'filter_html', ['provider' => 'test']);
+    $this->assertSame('<a> <br> <p>', $filter->getConfiguration()['settings']['allowed_html']);
+  }
+
+}

+ 17 - 50
url_replace_filter.install

@@ -1,74 +1,41 @@
 <?php
+
 /**
  * @file
  * Install file for URL Replace filter.
  *
- * @author: Frédéric G. MARAND <fgm@osinet.fr>
- *
  * @license General Public License version 2.0 or later
  */
 
+use Drupal\url_replace_filter\Plugin\Filter\UrlReplaceFilter;
+
 /**
- * Implementation of hook_requirements().
+ * Implements hook_requirements().
  *
  * Ensure the module is actually used in at least one filter.
  */
-function Zurl_replace_filter_requirements($phase) {
+function url_replace_filter_requirements($phase) {
+  // Only run in runtime phase, to ensure autoloading is available.
   if ($phase != 'runtime') {
-    return array();
+    return [];
   }
 
-  $formats = _url_replace_filter_get_formats();
-  $filter_id = 'url_replace_filter/0';
-  $count = 0;
-  foreach ($formats as $format) {
-    if (!empty($format->{$filter_id})) {
-      $count++;
-    }
-  }
-  $req = array(
+  $formats = UrlReplaceFilter::getFormats();
+  $count = count($formats);
+  $req = [
     'title' => t('URL replace filter'),
-  );
+  ];
   if ($count) {
-    $req['value'] = format_plural($count, "Used in 1 format.", "Used in @count formats.");
+    $req['value'] = \Drupal::translation()->formatPlural($count,
+      'Used in 1 format.',
+      'Used in @count formats.'
+    );
     $req['severity'] = REQUIREMENT_OK;
   }
   else {
     $req['value'] = t('Module is enabled but no format uses its filter. You should disable the module or use the filter in at least one format.');
-    $req['severity'] = REQUIREMENT_INFO;
+    $req['severity'] = REQUIREMENT_WARNING;
   }
 
-  return array('url_replace_filter' => $req);
-}
-
-/**
- * Implementation of hook_disable().
- *
- * - Flush filter cache to remove content cached with this filter.
- */
-function url_replace_filter_disabled() {
-  cache_clear_all('*', 'cache_filter', TRUE);
-}
-
-/**
- * Implementation of hook_uninstall().
- *
- * - Remove all configuration variables for the module.
- * - Remove instances of the filter in all input formats.
- * - Flush filter cache to remove content cached with this filter.
- */
-function url_replace_filter_uninstall() {
-  // Delete configuration variables.
-  foreach (array_keys($GLOBALS['conf']) as $name ) {
-    if (strpos($name, 'url_replace_filter_') === 0) {
-      variable_del($name);
-    }
-  }
-
-  // Remove filter from input formats.
-  $formats = _url_replace_filter_get_formats();
-  foreach ($formats as $format) {
-    db_query("DELETE FROM {filters} WHERE module = 'url_replace_filter'");
-  }
-  cache_clear_all('*', 'cache_filter', TRUE);
+  return [UrlReplaceFilter::ID => $req];
 }

File diff suppressed because it is too large
+ 1 - 42
url_replace_filter.module


Some files were not shown because too many files changed in this diff