หากคุณสามารถอยู่กับการเอาชนะขีด จำกัด การเติมข้อความอัตโนมัติทั้งหมดคุณสามารถแทนที่บริการหลักใน 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
จากนั้นอัปเดต hardcoded 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) มันทำให้ codebase ของคุณยากขึ้น คุณต้องจำไว้ว่าคุณไม่ได้ใช้ core Drupal แต่เป็นเวอร์ชั่นเพิ่มเติม นักพัฒนารายอื่นที่เข้าร่วมโครงการของคุณหลังจากที่คุณออกอาจมีปัญหาในการหาสาเหตุที่ทำให้บริการทำงานในลักษณะที่ไม่ได้มาตรฐาน
นี่คือแฮ็คหลักหรือไม่
ขึ้นอยู่กับว่าคุณจะมองอย่างไร มันจะไม่เข้าสู่โมดูลหลักและการเปลี่ยนรหัส มันไม่ได้แม้แต่จะสร้างแพตช์และใช้มันและติดตามมันด้วยผู้จัดการแพ็คเกจเช่นนักแต่งเพลง มันเป็นมากกว่าการปรับแต่งแบบครั้งเดียวที่จะปรับเปลี่ยนพฤติกรรมของไซต์หลักคล้ายกับ hook ALTER มีแฮ็คหลักในตัวเองมากขึ้นเพราะอยู่ในโมดูลที่คุณกำหนดเองในเว็บไซต์ของคุณ ดังนั้นการอัปเดตหลักของบริการดั้งเดิมจะไม่ได้รับผลกระทบเช่นเดียวกับถ้าคุณแก้ไขหรือแฮ็กรหัสบริการเดิม
แต่มันมีความเสี่ยงเช่นเดียวกับการแฮ็คหลักตามที่กล่าวไว้ข้างต้น
ในคำถามเดิมปัญหาคือชื่อโหนดนั้นไม่ซ้ำกันมากพอ ทางออกที่ดีกว่านอกเหนือจากการเปลี่ยนขีด จำกัด ทั่วโลกเมื่อเลื่อนลงจะเป็นการแก้ปัญหาที่เป็นเอกลักษณ์
สิ่งที่ฉันอยากจะแนะนำคือการเพิ่มฟิลด์ใหม่ field_display_title และใช้มันในหน้าและถ้าคุณต้องการมันอีกฟิลด์ field_teaser_title เพื่อแสดงในหน้ารายการที่คุณต้องการชื่อที่สั้นกว่า จากนั้นชื่อจริงที่ถูกดึงเข้าสู่การอ้างอิงแบบเลือกรายการอ้างอิงนั้นจะมีประโยชน์สำหรับผู้แก้ไขของคุณและไม่ซ้ำกันเช่น "บทความของฉัน (หน้า 1)" หากปัญหาคือแต่ละหน้ามีชื่อเรื่องเดียวกัน จากนั้นคุณไม่จำเป็นต้องยกเลิกบริการหลัก
เมื่อคุณเจอปัญหากับ Drupal ลองค้นหาวิธีแก้ปัญหาที่ต้องใช้รหัสกำหนดเองจำนวนน้อยที่สุด ทำให้ไซต์ของคุณมีเสถียรภาพมากขึ้นง่ายต่อการดูแลรักษาและประหยัดเวลา