Se riesci a superare tutti i limiti di completamento automatico, puoi eseguire l' override di un servizio principale in Drupal 8;
Il servizio che devi sovrascrivere è qui in core.services.yml:
entity.autocomplete_matcher:
class: Drupal\Core\Entity\EntityAutocompleteMatcher
arguments: ['@plugin.manager.entity_reference_selection']
Nel modulo personalizzato, aggiungi una classe che implementa 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);
}
}
Quindi copia EntityAutocompleteMatcher.php nel tuo modulo su /src/Entity/EntityAutocompleteMatcherCustom.php
Quindi aggiorna il 10 hardcoded a 50 o qualsiasi limite desideri:
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;
}
}
Ovviamente ignorare i servizi di base comporta alcuni rischi, ma è bello poterlo fare.
Quali sono i rischi di ignorare un servizio principale?
1) Potresti perdere i vantaggi degli aggiornamenti quando aggiorni il core. Se nel servizio è presente una correzione di sicurezza critica e la copia modificata presenta un buco di sicurezza, non si trarrà vantaggio dall'aggiornamento della comunità da parte del codice.
2) Altri moduli installati possono avere dipendenze dal servizio originale con il set di funzionalità originale. Quindi supponiamo che ci sia del codice in un altro modulo che si interromperà se il numero di voci di completamento automatico è maggiore o minore di 10, non lo saprai, fino a quando non ti influenza.
3) Rende il tuo codebase più difficile da mantenere. Devi ricordare che non stai usando Drupal core, ma una versione estesa. Altri sviluppatori che si uniscono al tuo progetto dopo la tua partenza potrebbero avere difficoltà a capire perché un servizio si sta comportando in modo non standard.
Questo nucleo di hacking?
Dipende dal tuo punto di vista. Non entra nel modulo principale e non cambia il codice. Non sta nemmeno creando una patch, applicandola e monitorandola con un gestore di pacchetti come compositore. È più di una personalizzazione unica che altera il comportamento di base di un sito, simile a un hook ALTER. È più autonomo di un hack principale, perché è all'interno del tuo modulo personalizzato sul tuo sito. Pertanto, gli aggiornamenti di base al servizio originale non saranno interessati, allo stesso modo come se si correggesse o violasse il codice del servizio originale.
Ma presenta alcuni degli stessi rischi dell'hacking core, come menzionato sopra.
Nella domanda originale, il problema era che i titoli dei nodi non erano abbastanza unici. La soluzione migliore, oltre a modificare il limite a livello globale sui menu a discesa, sarebbe risolvere il problema dell'unicità.
Quello che suggerirei è di aggiungere un nuovo campo field_display_title e usarlo sulla pagina, e se ne hai bisogno un altro campo field_teaser_title per la visualizzazione su pagine di elenco in cui hai bisogno di un titolo più breve. Quindi il titolo effettivo che viene inserito nel menu a discesa Seleziona riferimento entità può essere utile per i tuoi editor ed essere unico, come "Il mio articolo (pagina 1)" se il problema è che ogni pagina ha lo stesso titolo. Quindi non è necessario eseguire l'override di un servizio principale.
Quando riscontri un problema con Drupal, prova a trovare la soluzione che richiede la minima quantità di codice personalizzato. Questo rende il tuo sito più stabile, più facile da mantenere e ti fa risparmiare tempo.