This module extends standard entity autocomplete. It allows users to see autocomplete match by entity id and not only by entity label. Provides form element, entity reference field widget and allows to be enabled globally for all existing autocompletes.

Project link

https://www.drupal.org/project/autocomplete_id

Git instructions

git clone --branch 8.x-1.x https://git.drupalcode.org/project/autocomplete_id.git

PAReview checklist

https://pareview.sh/pareview/https-git.drupal.org-project-autocomplete_i...

Comments

mostepaniukvm created an issue. See original summary.

vernit’s picture

Thank you for the contribution!
Please see on the "Automated testing" page.

vernit’s picture

Status: Needs review » Needs work
avpaderno’s picture

Status: Needs work » Needs review

Is there anything that need to be fixed? That page just says automated tests aren't enabled.

avpaderno’s picture

Status: Needs review » Needs work
  • What follows is a quick review of the project; it doesn't mean to be complete
  • For every point, I didn't make a complete list of where the code should be fixed, but an example of what is wrong in the code
  • Not all the points are application stoppers; some of them describe changes that would be preferable to make
namespace Drupal\autocomplete_id\Controller;

use Drupal\system\Controller\EntityAutocompleteController;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Extends default system route controller. Replace matcher service.
 */
class EntityIdAutocompleteController extends EntityAutocompleteController {

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('autocomplete_id.matcher'),
      $container->get('keyvalue')->get('entity_autocomplete')
    );
  }

}

Drupal core controllers, among other classes, are considered internal, and they should not be extended.

mostepaniukvm’s picture

Hi @kiamlaluno,

Thanks, for your time,
I didn't know that controller classes shouldn't be extended.
I will check and work on this problem soon.

avpaderno’s picture

It's documented in Drupal 8 backwards compatibility and internal API policy (backend).

@internal

The following parts of the code base should always be treated as internal and are not guaranteed to not change between minor versions. For patch versions we will aim to avoid any breaking changes even to @internal code unless required to fix a serious bug:

Controllers and Form classes

Core modules contain many route controllers that are bound to individual routes, as well as form classes. These controllers are not part of the API of the module unless specifically marked with an @api tag on the method or class.

Plugins

Particular plugins, whether class based or yaml based, should not be considered part of the public API. References to plugin IDs and settings in default configuration can be relied upon however.

Entity handlers

Particular entity handlers should not be considered part of the public API. The interfaces which define those entity handlers though are part of the supported API.

PHP and JavaScript classes

In general, only interfaces can be relied on as the public API.
With the exception of base classes, developers should generally assume that implementations of classes will change, and that they should not inherit from classes in the system, or be prepared to update code for changes if they do.

avpaderno’s picture

(I forgot the more explicit point.)

mostepaniukvm’s picture

Status: Needs work » Needs review

I've read carefully Drupal 8 backwards compatibility and internal API policy article.

My module violates described principles multiple times. Controller, render element class, field widget class are extending core classes.

I decorated the core's service instead of replacing it with ServiceProvider with the hope that this is acceptable for contrib module. But it looks like a violation too because I extend core service class.

I really don't sure what to do next with this module. This is not an option to duplicate a lot of code to prevent extending of classes. But I can't find any elegant solution to implement the idea of this module and not break the rules of internal API policy. Could anyone give me any recommendations for this case?

In any case, it was a useful experience for me and I will take it into consideration in designing the next solutions.

avpaderno’s picture

It would help if there were a hook to alter the autocomplete, or the label for the autocompleted entity, but (at first sight) I didn't find a hook for that.

avpaderno’s picture

Status: Needs review » Needs work

Actually, the only method that would need to be added to the controller used from project is just the following one.

  public function handleAutocomplete(Request $request, $target_type, $selection_handler, $selection_settings_key) {
    $matches = [];

    // Get the typed string from the URL, if it exists.
    if ($input = $request->query->get('q')) {
      $typed_string = Tags::explode($input);
      $typed_string = mb_strtolower(array_pop($typed_string));

      // Selection settings are passed in as a hashed key of a serialized array
      // stored in the key/value store.
      $selection_settings = $this->keyValue->get($selection_settings_key, FALSE);
      if ($selection_settings !== FALSE) {
        $selection_settings_hash = Crypt::hmacBase64(serialize($selection_settings) . $target_type . $selection_handler, Settings::getHashSalt());
        if (!hash_equals($selection_settings_hash, $selection_settings_key)) {
          // Disallow access when the selection settings hash does not match the
          // passed-in key.
          throw new AccessDeniedHttpException('Invalid selection settings key.');
        }
      }
      else {
        // Disallow access when the selection settings key is not found in the
        // key/value store.
        throw new AccessDeniedHttpException();
      }
      $matches = $this->matcher->getMatches($target_type, $selection_handler, $selection_settings, $typed_string);
    }
    return new JsonResponse($matches);
  }

Those are just 14 lines of code.

mostepaniukvm’s picture

Status: Needs work » Needs review

Added method to controller class to prevent extending core controller class.

avpaderno’s picture

Assigned: Unassigned » avpaderno
Status: Needs review » Fixed

Thank you for your contribution! I am going to update your account.

These are some recommended readings to help with excellent maintainership:

You can find more contributors chatting on the IRC #drupal-contribute channel. So, come hang out and stay involved.
Thank you, also, for your patience with the review process.
Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.

I thank all the dedicated reviewers as well.

mostepaniukvm’s picture

Thank you for your time! I will read articles and definitely will stay involved.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.