모든 자동 완성 제한을 무시하고 살 수 있다면 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이 아니라 확장 버전을 사용하고 있음을 기억해야합니다. 떠난 후 프로젝트에 참여하는 다른 개발자는 왜 서비스가 비표준 방식으로 작동하는지 파악하기가 어려울 수 있습니다.
이것이 해킹 핵심입니까?
당신이 그것을 어떻게 보는가에 달려 있습니다. 핵심 모듈로 들어 가지 않고 코드를 변경하지 않습니다. 패치를 작성하여 적용하지 않고 composer와 같은 패키지 관리자로 추적하지도 않습니다. ALTER 후크와 유사하게 사이트 핵심 동작을 변경하는 일회성 사용자 정의에 가깝습니다. 핵심 해킹은 사이트의 자체 사용자 정의 모듈 내에 있기 때문에 자체적으로 포함되어 있습니다. 따라서 원래 서비스 코드를 패치하거나 해킹 한 것과 같은 방식으로 원래 서비스에 대한 핵심 업데이트는 영향을받지 않습니다.
그러나 위에서 언급했듯이 해킹 코어와 동일한 위험이 있습니다.
원래 질문에서 문제는 노드 제목이 고유하지 않다는 것입니다. 드롭 다운에서 전체적으로 한계를 변경하는 것 이외의 더 나은 솔루션은 고유성 문제를 해결하는 것입니다.
내가 제안하는 것은 새로운 field_display_title 필드를 추가하고 페이지에서 사용하고, 필요한 경우 더 짧은 제목이 필요한 목록 페이지에 표시하기 위해 field_teaser_title 다른 필드를 사용하는 것입니다. 그런 다음 엔터티 참조 선택 드롭 다운으로 가져 오는 실제 제목은 편집자에게 유용 할 수 있으며 문제가 각 페이지의 제목이 동일한 경우 "내 기사 (페이지 1)"와 같이 고유 할 수 있습니다. 그런 다음 핵심 서비스를 재정의 할 필요가 없습니다.
Drupal에 문제가 발생하면 최소한의 사용자 정의 코드가 필요한 솔루션을 찾으십시오. 이를 통해 사이트를보다 안정적이고 유지 관리하기 쉽고 시간을 절약 할 수 있습니다.