Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Keep modules compatible with multiple Drupal Core branches while using new services

Parent Feed: 

While working on making a module compatible with Drupal 9 I found that the module was using an obsolete function that had been replaced with a new service. It was something like this:


/**
 * My plugin.
 *
 * @SearchPlugin(
 *   id = "my_plugin",
 *   title = @Translation("My plugin")
 * )
 */
class MyPluginSearch extends SearchPluginBase implements AccessibleInterface, SearchIndexingInterface {

  /**
   * {@inheritdoc}
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition
  ) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition
    );
  }

  /** ... **/
  public function indexClear() {
    search_index_clear($this->getPluginId());
  }
}

The function search_index_clear is now part of the new search.index service that was added in Drupal 8.8. In order to keep this working on Drupal 8.8+ and Drupal 9 we need to inject the service in the create function. But if we do this unconditionally, we will get an error in Drupal 8.7 because that service was added on 8.8. What to do then?

Fortunately years ago I read an article that addressed a similar need. It talked about how to safely extends Drupal 8 plugin classes without fear of constructor changes. In my case I didn't want to change the constructor, so as to keep it compatible with Drupal 8.7 and below. At the same time, I wanted to inject the new service to use it in Drupal 8.8+ and Drupal 9. I just modified a bit my code to something like this:


/**
 * My plugin.
 *
 * @SearchPlugin(
 *   id = "my_plugin",
 *   title = @Translation("My plugin")
 * )
 */
class MyPluginSearch extends SearchPluginBase implements AccessibleInterface, SearchIndexingInterface {

  /** ... */
  protected $searchIndex;

  /**
   * {@inheritdoc}
   */
  public static function create(
    ContainerInterface $container,
    array $configuration,
    $plugin_id,
    $plugin_definition
  ) {
    $instance =  new static(
      $configuration,
      $plugin_id,
      $plugin_definition
    );

    // Only inject the service in Drupal 8.8 or newer.
    if (floatval(\Drupal::VERSION) >= 8.8) {
      $instance->searchIndex = $container->get('search.index');
    }

    return $instance;
  }

  /** ... **/
  public function indexClear() {
    if (floatval(\Drupal::VERSION) >= 8.8) {
      $this->searchIndex->clear($this->getPluginId());
    }
    else {
      search_index_clear($this->getPluginId());
    }
  }
}

And that's it, Drupal 8.8 and newer will take advantage of the new service while we keep this compatible with Drupal 8.7. This will give users more time to upgrade to Drupal 8.8+ or Drupal 9.

Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web