Score:5

การขยายคลาสบริการ filelog ของโมดูล contrib แสดงข้อผิดพลาดในการใช้งาน PSR

ธง nl

ฉันต้องการแทนที่บริการ logger.filelog จาก ไฟล์ล็อก โมดูลเพื่อใช้ parser ของฉันเอง

เกิดข้อผิดพลาดผ่าน ซิม และ ดรัช cr เมื่อเปิดใช้งานโมดูลแบบกำหนดเองใหม่ที่แทนที่บริการ

เว็บไซต์พบข้อผิดพลาดที่ไม่คาดคิด กรุณาลองใหม่อีกครั้งในภายหลัง.
Symfony\Component\DependencyInjection\Exception\LogicException: บริการ 'logger.filelog' สำหรับผู้บริโภค 'logger.factory' ไม่ได้ใช้ Psr\Log\LoggerInterface ใน Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass->processServiceCollectorPass() (บรรทัดที่ 182 ของ /app/docroot/core/lib/Drupal/Core/DependencyInjection/Compiler/TaggedHandlersPass.php)

โครงสร้างโมดูลที่กำหนดเองของฉันมีลักษณะดังนี้

custom_module
  - src
    - คนตัดไม้
      - TestFilelog.php
    CustomModuleServiceProvider.php
  custom_module.info.yml
  custom_module.module

ขณะนี้มีการใช้งานคลาสผู้ให้บริการ ServiceModifierInterface และแก้ไขบริการ logger.filelog ดั้งเดิมโดยตั้งค่าคลาสเป็น Drupal\custom_module\Logger\TestFilelog.

/**
 * คลาสที่จะแทนที่บริการโมดูล logger.filelog ที่สนับสนุน
 */
คลาส CustomModuleServiceProvider ใช้ ServiceModifierInterface {

  /**
   * {@inheritdoc}
   */
  ฟังก์ชั่นสาธารณะแก้ไข (ContainerBuilder $container) {
    ถ้า ($container->has('logger.filelog')) {
      $definition = $container->getDefinition('logger.filelog');
      $definition->setClass('Drupal\custom_module\Logger\TestFilelog');
    }
  }

}

TestFilelog.php

เนมสเปซ Drupal\custom_module\Logger;

ใช้ Drupal\filelog\Logger\FileLog;

/**
 * ตัวบันทึกไฟล์ตาม
 */
คลาส TestFileLog ขยาย FileLog {

  /**
   * แสดงข้อความเป็นสตริง
   *
   * @param ผสม $level
   * ระดับความรุนแรงของข้อความบันทึก
   * @param สตริง $ข้อความ
   * เนื้อหาของข้อความบันทึก
   * @param อาร์เรย์ $context
   * บริบทของข้อความบันทึก
   *
   * @return สตริง
   * ข้อความที่จัดรูปแบบ
   */
  ฟังก์ชันที่ได้รับการป้องกันแสดงผล ($level, $message, อาร์เรย์ $context = []): สตริง {

    $plainString = parent::render($level, $message, $context);

    $custom_channel = [
      'filter_custom_channel'
    ];

    ถ้า (in_array($context['channel'], $custom_channel)) {
      $plainString = $this->parseStrMasking($plainString);
    }
    ส่งคืน $plainString;
  }

  /**
   * ปกปิดรายละเอียดส่วนบุคคลตั้งแต่สตริงจนถึงบันทึก
   *
   * @param สตริง $pureString
   * สตริงที่จะแยกวิเคราะห์
   *
   * @return สตริง
   * สตริงที่ถูกปิดบัง
   */
  ฟังก์ชันที่ได้รับการป้องกัน parseStrMasking (string $pureString) {
    // ค่าเริ่มต้นเพื่อส่งคืน FinalString
    $finalString = $pureString;
    
    // การแยกวิเคราะห์แบบกำหนดเองไปที่นี่
    
    ส่งคืน $finalString;
  }

}

ฉันเห็นว่า Drupal\filelog\Logger\FileLog; มี ใช้ RfcLoggerTrait; ซึ่งดำเนินการ Psr\Log\LoggerInterface, นี่ฉันพลาดอะไรไป??

cn flag
รหัสของคุณทำงานได้ดีสำหรับฉัน - คุณลองรีสตาร์ท Apache/PHP-FPM แล้วหรือยัง
cn flag
คุณมีความคลาดเคลื่อนเล็กน้อย - คุณกำลังผสม `TestFileLog` (ซึ่งก็คือ `Testfilelog` ในชื่อไฟล์และบริการที่เปลี่ยนแปลง) อาจสร้างความแตกต่างหากคุณอยู่ในระบบไฟล์ที่คำนึงถึงตัวพิมพ์เล็กและใหญ่
Michael Chen avatar
nl flag
OMG @Clive คุณพูดถูก! ความรุ่งโรจน์สำหรับคุณเพื่อน!
Michael Chen avatar
nl flag
FYI ในขณะที่กำลังดิ้นรนเมื่อคืนนี้ ฉันได้ค้นพบวิธีอื่นในการแทนที่บริการของโมดูลการสนับสนุนผ่าน custom_module.services.yml มันใช้งานได้ดังนั้นฉันจึงใช้มันแทน ขอบคุณสำหรับความพยายามของคุณในการทดสอบและการอ่าน ขอบคุณ!
Score:2
ธง nl

ตามที่ @Clive ชี้ให้เห็นในความคิดเห็นด้านบน ฉันมีความคลาดเคลื่อนในกรณีของ ทดสอบไฟล์ล็อก และ ทดสอบไฟล์บันทึก. ขอบคุณอีกครั้ง!

สิ่งนี้ควรสร้างความแตกต่างว่าทำไม Drupal จึงไม่อ่านการใช้งานอินเทอร์เฟซในการจัดการบริการ

ในทางกลับกัน ฉันค้นพบวิธีอื่นในการแทนที่ ไฟล์ล็อก บริการของโมดูลที่ฉันใช้แทน

  1. ฉันลบ CustomModuleServiceProvider.php ไฟล์
  2. สร้าง custom_module.services.yml
  3. ชื่อเครื่องบริการควรเหมือนกับบริการที่ถูกแทนที่ (เช่น logger.filelog)
    ตรวจสอบ docroot/modules/contrib/filelog/filelog.services.yml

เนื้อหาของ custom_module.services.yml

บริการ:
  logger.filelog:
    คลาส: Drupal\custom_module\Logger\TestFileLog
    ข้อโต้แย้ง:
      - '@config.factory'
      - '@สถานะ'
      - '@โทเค็น'
      - '@datetime.time'
      - '@logger.log_message_parser'
      - '@filelog.file_manager'
    แท็ก:
      - { ชื่อ: คนตัดไม้ }

อ้างอิง:

  1. วิธีตกแต่งบริการ - Symfony
  2. การเปลี่ยนแปลงบริการที่มีอยู่ - Drupal
  3. แทนที่บริการใน Drupal - PreviousNext
fr flag
การกำหนดบริการใหม่เช่นนั้นจะเป็นทางเลือกสุดท้ายของฉัน ตัวเลือกที่ดีกว่าคือวิธีที่คุณทำในคำถามเดิมหรือโดยการตกแต่ง เหตุผลก็คือ การกำหนด logger.filelog ของคุณเองในไฟล์ services.yml นั้นไม่ได้บ่งบอกว่านี่เป็นบริการที่ถูกแทนที่ - ความตั้งใจของโปรแกรมเมอร์นั้นถูกบดบัง (เป็นเพียงความผิดพลาดที่ใช้บริการชื่อก่อนหน้านี้หรือไม่) . นอกจากนี้ จะเกิดอะไรขึ้นหากโมดูล Filelog ถูกโหลด *หลังจาก* โมดูลของคุณ - บริการใดที่ได้รับการกำหนดไว้จริง ๆ แล้ว บริการของคุณหรือ Filelog และจะเกิดอะไรขึ้นหากโมดูลอื่นแทนที่ logger.filelog
Michael Chen avatar
nl flag
โอ้ที่รัก! ข้อกังวลของคุณมีเหตุผล บางทีฉันควรปรับแต่งกลับเป็นรูปแบบเดิมและตรวจสอบว่าใช้งานได้ในทางกลับกัน มีแหล่งข้อมูลอื่นอีกไหมที่ฉันอาจใช้อ้างอิงในการตกแต่งบริการ ฉันอ่านแค่ว่าการตกแต่งขยายบริการดั้งเดิม แต่ในขณะที่ใช้งานจริง ฉันไม่รู้ว่าฉันควรแทนที่บริการดั้งเดิมด้วยบริการตกแต่งอย่างไร ไชโย!
fr flag
นี่เป็นบทความที่ค่อนข้างดีซึ่งน่าจะช่วยได้: https://www.phase2technology.com/blog/using-symfony-service-decorators-drupal-8
Michael Chen avatar
nl flag
ขอบคุณสำหรับข้อมูล บทความนี้มีประโยชน์จริง ๆ เพราะเขียนรายละเอียดการพิจารณาและกระบวนการคิดทุกอย่าง

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา