Якщо ви можете жити з перевищенням усіх обмежень автозаповнення, ви можете змінити основну службу в Drupal 8;
Служба, яку потрібно перекрити, знаходиться тут у core.services.yml:
entity.autocomplete_matcher:
class: Drupal\Core\Entity\EntityAutocompleteMatcher
arguments: ['@plugin.manager.entity_reference_selection']
У свій спеціальний модуль додайте клас, який реалізує 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);
}
}
Потім скопіюйте EntityAutocompleteMatcher.php у свій модуль за адресою /src/Entity/EntityAutocompleteMatcherCustom.php
Потім оновіть жорстко закодовані 10 на 50 або будь-який обмеження, який ви хочете:
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;
}
}
Очевидно, що переосмислення основних сервісів має певні ризики, але здорово, що ви можете це зробити.
Які ризики перекриття базової послуги?
1) Ви можете втратити переваги оновлень під час оновлення ядра. Якщо в сервісі є критичне виправлення безпеки, і ваша змінена копія має отвір безпеки, ви не отримаєте користі від оновлення коду спільнотою.
2) Інші модулі, які ви встановлюєте, можуть залежати від оригінальної послуги з її оригінальним набором функцій. Тож скажімо, що в іншому модулі є якийсь код, який порушиться, якщо кількість записів автозаповнення буде більшою або меншою за 10, ви про це не дізнаєтесь, поки це не вплине на вас.
3) Це ускладнює підтримку вашої кодової бази. Ви повинні пам’ятати, що ви використовуєте не основний Drupal, а розширену версію. Іншим розробникам, які приєднаються до вашого проекту після того, як ви підете, можливо, важко з'ясувати, чому служба поводиться нестандартно.
Це хакерське ядро?
Залежить від того, як ти на це дивишся. Це не входить в основний модуль і змінюється код. Навіть не створити патч, а застосувати його та відстежити його за допомогою менеджера пакунків, наприклад композитора. Це більше разова настройка, яка змінює поведінку основних сайтів, аналогічну гачку ALTER. Це більш автономне, що ядро зламає, оскільки воно знаходиться у вашому власному користувальницькому модулі на вашому сайті. Таким чином, основні оновлення оригінальної послуги не впливатимуть так само, як якщо б ви виправили або зламали оригінальний код послуги.
Але це має деякі ті ж ризики, що і злом ядра, як згадувалося вище.
У первісному питанні проблема полягала у тому, що назви вузлів недостатньо унікальні. Кращим рішенням, крім зміни ліміту на глобальному рівні падіння, було б вирішити проблему унікальності.
Що я б запропонував, це додати нове поле field_display_title і використовувати його на сторінці, а якщо вам це потрібно, інше поле field_teaser_title для відображення на сторінках списку, де вам потрібно коротший заголовок. Тоді фактичний заголовок, який потрапляє у спадне меню вибору посилання на юридичну особу, може бути корисним вашим редакторам та бути унікальним, наприклад "Моя стаття (сторінка 1)", якщо випуск кожної сторінки має однаковий заголовок. Тоді вам не доведеться перекривати основну службу.
Якщо ви зіткнулися з проблемою з Drupal, спробуйте знайти рішення, яке вимагає найменшої кількості користувацького коду. Це робить ваш сайт більш стабільним, простішим в обслуговуванні та економить ваш час.