Si puede vivir anulando todos los límites de autocompletar, puede anular un servicio central en Drupal 8;
El servicio que necesita anular está aquí en core.services.yml:
entity.autocomplete_matcher:
class: Drupal\Core\Entity\EntityAutocompleteMatcher
arguments: ['@plugin.manager.entity_reference_selection']
En su módulo personalizado, agregue una clase 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);
}
}
Luego copie EntityAutocompleteMatcher.php en su módulo en /src/Entity/EntityAutocompleteMatcherCustom.php
Luego actualice el 10 codificado a 50, o el límite que desee:
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, anular los servicios centrales tiene algunos riesgos, pero es genial que puedas hacer esto.
¿Cuáles son los riesgos de anular un servicio central?
1) Puede perder los beneficios de las actualizaciones cuando actualiza Core. Si hay una solución de seguridad crítica en el servicio, y su copia alterada tiene el agujero de seguridad, no se beneficiará de la comunidad que actualiza ese código.
2) Otros módulos que instale pueden tener dependencias del servicio original con su conjunto de características original. Entonces, digamos que hay algún código en otro módulo que se romperá si el número de entradas de autocompletar es mayor o menor que 10, no lo sabrá hasta que lo afecte.
3) Hace que su base de código sea más difícil de mantener. Debe recordar que no está utilizando Drupal principal, sino una versión extendida. Otros desarrolladores que se unen a su proyecto después de su partida pueden tener dificultades para descubrir por qué un servicio se comporta de una manera no estándar.
¿Es este núcleo de piratería?
Depende de cómo lo mires. No está entrando en el módulo central y cambiando el código. Ni siquiera es crear un parche y aplicarlo y rastrearlo con un administrador de paquetes como el compositor. Es más una personalización única que altera el comportamiento central de un sitio, similar a un gancho ALTER. Es más autónomo que un hack core, porque está dentro de su propio módulo personalizado en su sitio. Por lo tanto, las actualizaciones principales del servicio original no se verán afectadas, de la misma manera que si parcheara o pirateara el código de servicio original.
Pero tiene algunos de los mismos riesgos que hackear el núcleo, como se mencionó anteriormente.
En la pregunta original, el problema era que los títulos de los nodos no son lo suficientemente únicos. La mejor solución, además de cambiar el límite global de los menús desplegables, sería resolver el problema de la unicidad.
Lo que sugeriría es agregar un nuevo campo field_display_title y usarlo en la página, y si lo necesita, otro field field_teaser_title para mostrar en las páginas de la lista donde necesita un título más corto. Luego, el título real que aparece en el menú desplegable de selección de referencia de entidad puede ser útil para sus editores y puede ser único, como "Mi artículo (página 1)" si el problema es que cada página tiene el mismo título. Entonces no tiene que anular un servicio central.
Cuando encuentre un problema con Drupal, intente encontrar la solución que requiera la menor cantidad de código personalizado. Esto hace que su sitio sea más estable, más fácil de mantener y le ahorra tiempo.