إظهار المستخدم الحالي في السجل
-
26-12-2019 - |
سؤال
أحاول إنشاء معالج أحادي مخصص لإرفاق المستخدم الحالي برسالة خطأ.
عند الإعلان عن خدمة مثل ذلك:
monolog.processor.mail:
class: MyVendor\Monolog\Processor\MailProcessor
arguments:
- @mailer
- @security.context
tags:
- { name: monolog.processor, method: processRecord }
أحصل على مرجع دائري:
[Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException]
Circular reference detected for service "monolog.processor.mail",
path: "router -> monolog.logger.router -> monolog.processor.mail
-> security.context -> security.authentication.manager
-> fos_user.user_provider.username_email-> fos_user.user_manager
-> doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection
-> doctrine.dbal.logger -> monolog.logger.doctrine".
ماذا سيكون افضل تمرين الحل هنا؟
موضوع المنتدى ذو صلة:http://forum.symfony-project.org/viewtopic.php?t=40306&p=131081#p131143
وهذا الموضوع يبين أن:
- حقنة Setter لا تحل المشكلة (لقد جربت ذلك أيضًا)
- يؤدي حقن الحاوية إلى تكرار صيغة المصدر (لم أؤكد هذا)
كما حاولت هذا البرنامج النصي http://pastebin.com/AuvFgTY3 لإخراج المستخدم من الجلسة.
if ($this->session !== null) {
if ($this->session->has($this->securityKey)) {
$token = unserialize($this->session->get($this->securityKey));
$this->currentUser = $token->getUser();
}
}
أعطى هذا الخطأ التالي:
Warning: ini_set(): A session is active. You cannot change the session module's ini settings at this time in
C:\inetpub\symfony23\vendor\symfony\symfony\src\Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeFileSessionHandler.php
on line 56
أنا أفهم أن Security.context لم يتم إنشاؤه بعد للخدمات التي تطلب المسجل في وقت مبكر جدًا.بالنسبة لصفي، لا يمثل ذلك مشكلة لأنني سأقوم بتعيين المستخدم على ذلك undefined
.لذلك من الناحية المثالية security.context
سيتم حقن الواضع بعد security.context
تم إنشاء الخدمة.ومع ذلك، لا يمكنني تغيير الأولوية على المسجل الذي سيتم إنشاؤه في وقت متأخر جدًا لأنه مطلوب في وقت مبكر.لذلك ربما يتحول السؤال إلى:كيفية إعادة إنشاء الخدمة مرة أخرى بعد تهيئة Security.context؟لست متأكدًا مما إذا كان النموذج الأولي للنطاق سيساعد هنا؟؟
المحلول
إنشاء معالج بناءً على طلب kernel واستخراج المستخدم:
// src/AppBundle/Monolog/UserProcessor.php
namespace AppBundle\Monolog;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class UserProcessor
{
private $tokenStorage;
private $user;
public function __construct(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
public function __invoke(array $record)
{
if (null !== $this->user) {
$record['extra']['user'] = $this->user->getUsername();
}
return $record;
}
public function onKernelRequest(GetResponseEvent $event)
{
if (null === $token = $this->tokenStorage->getToken()) {
return;
}
if (!is_object($user = $token->getUser())) {
// e.g. anonymous authentication
return;
}
$this->user = $user;
}
}
تسجيل المعالج الجديد:
# app/config/services.yml
services:
monolog.processor.user:
class: AppBundle\Monolog\UserProcessor
arguments: ["@security.token_storage"]
tags:
- { name: monolog.processor }
- { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
توجد مشكلة في وثائق Symfony