Puncte:5

Extinderea clasei de serviciu filelog al modulului contrib afișează o eroare de implementare a PSR

drapel nl

Am vrut să înlocuiesc serviciul logger.filelog de la jurnal de fișiere modul pentru a folosi propriul meu parser.

A apărut o eroare prin drush cim și drush cr când noul modul personalizat care suprascrie serviciul este activat.

Site-ul web a întâmpinat o eroare neașteptată. Vă rugăm să încercați din nou mai târziu.
Symfony\Component\DependencyInjection\Exception\LogicException: Serviciul „logger.filelog” pentru consumator „logger.factory” nu implementează Psr\Log\LoggerInterface. în Drupal\Core\DependencyInjection\Compiler\TaggedHandlersPass->processServiceCollectorPass() (linia 182 din /app/docroot/core/lib/Drupal/Core/DependencyInjection/Compiler/TaggedHandlersPass.php).

Structura modulelor mele personalizate arată astfel

modul_personalizat
  - src
    - Logger
      - TestFilelog.php
    CustomModuleServiceProvider.php
  custom_module.info.yml
  modul_personalizat.modul

În prezent, clasa de furnizor de servicii a fost implementată ServiceModifierInterface și a modificat serviciul original logger.filelog setându-i clasa la Drupal\modul_personalizat\Logger\TestFilelog.

/**
 * Clasă pentru a suprascrie modulul contrib serviciul logger.filelog.
 */
clasa CustomModuleServiceProvider implementează ServiceModifierInterface {

  /**
   * {@inheritdoc}
   */
  funcția publică alter(ContainerBuilder $container) {
    if ($container->has('logger.filelog')) {
      $definition = $container->getDefinition('logger.filelog');
      $definition->setClass('Drupal\custom_module\Logger\TestFilelog');
    }
  }

}

TestFilelog.php

spațiu de nume Drupal\modul_personalizat\Logger;

utilizați Drupal\filelog\Logger\FileLog;

/**
 * Logger bazat pe fișiere.
 */
clasa TestFileLog extinde FileLog {

  /**
   * Redă un mesaj într-un șir.
   *
   * @param mixed $level
   * Nivelul de severitate al mesajului de jurnal.
   * @param șir $mesaj
   * Conținutul mesajului de jurnal.
   * @param array $context
   * Contextul mesajului de jurnal.
   *
   * @return șir
   * Mesajul formatat.
   */
  funcția protejată randare($nivel, $mesaj, matrice $context = []): șir {

    $plainString = parent::render($nivel, $mesaj, $context);

    $canal_personalizat = [
      „filter_custom_channel”
    ];

    dacă (în_array($context['canal'], $canal_personalizat)) {
      $plainString = $this->parseStrMasking($plainString);
    }
    returnează $plainString;
  }

  /**
   * Mascați detaliile personale de la șiruri la jurnal.
   *
   * @param șir $pureString
   * Șirul care trebuie analizat.
   *
   * @return șir
   * Șirul care a fost mascat.
   */
  funcția protejată parseStrMasking(șir $pureString) {
    // Implicit pentru a returna finalString.
    $finalString = $pureString;
    
    // Analiza personalizată merge aici.
    
    returnează $finalString;
  }

}

Vad asta Drupal\filelog\Logger\FileLog; are utilizați RfcLoggerTrait; care implementează Psr\Log\LoggerInterface, ce imi lipseste aici??

drapel cn
Codul dvs. funcționează bine pentru mine - ați încercat să reporniți Apache/PHP-FPM?
drapel cn
Totuși, aveți o mică discrepanță - amestecați majusculele lui `TestFileLog` (este `Testfilelog` în numele fișierului și modificarea serviciului). S-ar putea să facă diferența dacă sunteți pe un sistem de fișiere sensibil la majuscule și minuscule
Michael Chen avatar
drapel nl
OMG @Clive ai perfecta dreptate! Felicitari pentru tine prietene!
Michael Chen avatar
drapel nl
FYI, în timp ce mă luptam aseară, am descoperit o altă modalitate de a suprascrie serviciul modulului contrib prin custom_module.services.yml. Funcționează, așa că l-am folosit în schimb. Vă mulțumim pentru efortul de a testa și citi, mulțumesc!
Puncte:2
drapel nl

După cum a subliniat @Clive în comentariul de mai sus, am avut o discrepanță în carcasa lui TestFilelog și TestFileLog. Multumesc din nou!

Acest lucru ar trebui să facă o diferență asupra motivului pentru care implementarea interfeței nu a fost citită de Drupal cu privire la gestionarea serviciului.

Pe de altă parte, am descoperit o altă abordare a depășirii jurnal de fișiere serviciul modulelor, pe care l-am luat în schimb.

  1. Am șters CustomModuleServiceProvider.php fişier
  2. Creată custom_module.services.yml
  3. numele mașinii de serviciu ar trebui să fie același cu serviciul suprascris. (de exemplu, logger.filelog)
    Verifica docroot/modules/contrib/filelog/filelog.services.yml

Conținutul custom_module.services.yml

Servicii:
  logger.filelog:
    clasa: Drupal\custom_module\Logger\TestFileLog
    argumente:
      - „@config.factory”
      - '@stat'
      - „@token”
      - „@datetime.time”
      - „@logger.log_message_parser”
      - „@filelog.file_manager”
    Etichete:
      - { nume: logger }

Ref:

  1. Cum să decorezi Servicii - Symfony
  2. Modificarea serviciilor existente - Drupal
  3. Suplimentarea serviciilor în Drupal - PreviousNext
drapel fr
Redefinirea serviciului astfel ar fi ultima mea alegere. Alegerile mai bune sunt felul în care ați făcut-o în întrebarea inițială, sau prin decor. Motivul este că definirea propriului dvs. logger.filelog în fișierul services.yml nu indică nimic că acesta este un serviciu suprascris - intenția programatorului este ascunsă (a fost doar o greșeală că a fost folosit un serviciu numit anterior?) . De asemenea, ce se întâmplă dacă modulul Filelog este încărcat *după* modulul tău - care serviciu este definit de fapt, al tău sau serviciul Filelog? Și ce se întâmplă dacă un alt modul suprascrie logger.filelog?
Michael Chen avatar
drapel nl
Aoleu! Îngrijorarea dvs. are un motiv, poate ar trebui să o rafinam înapoi la formatul original și să verific dacă funcționează.Pe de altă parte, există alte resurse la care pot face referire în decorarea serviciului? Am citit doar că decorarea extinde serviciul original, dar în timp ce îl implementez, de fapt nu știu cum ar trebui să înlocuiesc serviciul original cu un serviciu de decorare. Noroc!
drapel fr
Acesta este un articol destul de bun care ar trebui să vă ajute: https://www.phase2technology.com/blog/using-symfony-service-decorators-drupal-8
Michael Chen avatar
drapel nl
Vă mulțumim pentru informații, acest articol a fost cu adevărat util, deoarece a scris fiecare detaliu al procesului lor de considerare și gândire.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.