Se você pode substituir todos os limites de preenchimento automático, pode substituir um serviço principal no Drupal 8;
O serviço que você precisa substituir está aqui em core.services.yml:
entity.autocomplete_matcher:
class: Drupal\Core\Entity\EntityAutocompleteMatcher
arguments: ['@plugin.manager.entity_reference_selection']
No seu módulo personalizado, adicione uma classe que implemente ServiceModifierInterface
namespace Drupal\mymodule;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceModifierInterface;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class MyModuleServiceProvider implements ServiceModifierInterface {
/**
* Modifies existing service definitions.
*
* @param ContainerBuilder $container
* The ContainerBuilder whose service definitions can be altered.
*/
public function alter(ContainerBuilder $container) {
for ($id = 'entity.autocomplete_matcher'; $container->hasAlias($id); $id = (string) $container->getAlias($id));
$definition = $container->getDefinition($id);
$definition->setClass('Drupal\mymodule\Entity\EntityAutocompleteMatcherCustom');
$container->setDefinition($id, $definition);
}
}
Em seguida, copie EntityAutocompleteMatcher.php no seu módulo em /src/Entity/EntityAutocompleteMatcherCustom.php
Em seguida, atualize os 10 codificados para 50, ou o limite que desejar:
namespace Drupal\mymodule\Entity;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\Tags;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginManagerInterface;
use Drupal\Core\Entity\EntityAutocompleteMatcher;
/**
* Matcher class to get autocompletion results for entity reference.
*/
class EntityAutocompleteMatcherCustom extends EntityAutocompleteMatcher {
/*
* {@inheritdoc]
*/
public function getMatches($target_type, $selection_handler, $selection_settings, $string = '') {
$matches = array();
$options = array(
'target_type' => $target_type,
'handler' => $selection_handler,
'handler_settings' => $selection_settings,
);
$handler = $this->selectionManager->getInstance($options);
if (isset($string)) {
// Get an array of matching entities.
$match_operator = !empty($selection_settings['match_operator']) ? $selection_settings['match_operator'] : 'CONTAINS';
// Changing limit from 10 to 50.
$entity_labels = $handler->getReferenceableEntities($string, $match_operator, 50);
// Loop through the entities and convert them into autocomplete output.
foreach ($entity_labels as $values) {
foreach ($values as $entity_id => $label) {
$key = "$label ($entity_id)";
// Strip things like starting/trailing white spaces, line breaks and
// tags.
$key = preg_replace('/\s\s+/', ' ', str_replace("\n", '', trim(Html::decodeEntities(strip_tags($key)))));
// Names containing commas or quotes must be wrapped in quotes.
$key = Tags::encode($key);
$matches[] = array('value' => $key, 'label' => $label);
}
}
}
return $matches;
}
}
Obviamente, substituir os serviços principais tem alguns riscos, mas é legal que você possa fazer isso.
Quais são os riscos de substituir um serviço principal?
1) Você pode perder os benefícios das atualizações ao atualizar o núcleo. Se houver uma correção crítica de segurança no serviço e sua cópia alterada tiver uma falha de segurança, você não se beneficiará com a atualização da comunidade por esse código.
2) Outros módulos instalados podem ter dependências para o serviço original com seu conjunto de recursos original. Então, digamos que exista algum código em outro módulo que será interrompido se o número de entradas de preenchimento automático for maior ou menor que 10, você não saberá disso até que isso o afete.
3) Torna sua base de código mais difícil de manter. Você deve se lembrar que não está usando o Drupal principal, mas uma versão estendida. Outros desenvolvedores que ingressam no seu projeto depois que você saiu podem ter dificuldade em descobrir por que um serviço está se comportando de maneira não-padrão.
Esse é o núcleo do hacking?
Depende de como você olha para isso. Não está entrando no módulo principal e mudando o código. Não é nem mesmo criar um patch e aplicá-lo e rastreá-lo com um gerenciador de pacotes, como o compositor. É mais uma personalização única que altera o comportamento principal de um site, semelhante a um gancho ALTER. É mais independente do que um hack principal, porque está dentro do seu próprio módulo personalizado em seu site. Portanto, as atualizações principais do serviço original não serão afetadas, da mesma forma como se você corrigisse ou hackeasse o código do serviço original.
Mas tem alguns dos mesmos riscos que o núcleo de hackers, como mencionado acima.
Na pergunta original, o problema era que os títulos dos nós não são exclusivos o suficiente. A melhor solução, além de alterar o limite globalmente nos drop-downs, seria resolver o problema de exclusividade.
O que eu sugeriria é adicionar um novo campo field_display_title e usá-lo na página, e se você precisar dele outro campo field_teaser_title para exibição nas páginas da lista em que você precisa de um título mais curto. Em seguida, o título real que é puxado para a lista suspensa de seleção de referência de entidade pode ser útil para seus editores e ser exclusivo, como "Meu artigo (página 1)" se o problema é que cada página tem o mesmo título. Então você não precisa substituir um serviço principal.
Quando você se deparar com um problema com o Drupal, tente encontrar a solução que requer a menor quantidade de código personalizado. Isso torna seu site mais estável, mais fácil de manter e economiza seu tempo.