Zirkuläre Abhängigkeit: Magento \ Kunde \ Modell \ Sitzung hängt von Firma \ Modulname \ Plugin \ Config \ Share ab und umgekehrt


8

So überschreiben oder verwenden Sie das Plugin für isWebsiteScope()Funktionen aus der Datei Magento \ Customer \ Model \ Config \ Share.php .

Ich habe das Plugin für die unten stehende Funktion verwendet, möchte aber die aktuelle Kundensitzung in der unten stehenden Funktion abrufen. Überprüfen Sie hauptsächlich, ob custoemr angemeldet ist oder nicht .

Verwenden Sie einfach das Plugin und setzen Sie di.xml,

<!-- Override Share.php to set value of website scope -->
<type name="Magento\Customer\Model\Config\Share">
    <plugin name="Company_Modulename::Share" type="\Company\Modulename\Plugin\Config\Share\Proxy" sortOrder="1"/>
</type>

In der Share.php-Datei

<?php
namespace Company\Modulename\Plugin\Config;

class Share
{    
    public function __construct(
        \Magento\Customer\Model\Session $customerSession
    ) {
        $this->session = $customerSession;
    }
    /**
     * Check whether current customers sharing scope is website
     *
     * @return bool
     */
    public function afterIsWebsiteScope(\Magento\Customer\Model\Config\Share $subject)
    {
        if(!$this->session->isLoggedIn()){
            return 1;
        } else {
            return 0;
        }

    }
}

So erhalten Sie die aktuelle Kundensitzung in der obigen Funktion:

Wenn ich die aktuelle Kundensitzung mit dem Kundensitzungsmodell-Browser verwendet habe, wird ein kreisförmiger Abhängigkeitsfehler ausgegeben.


Wo kann dieses Problem Frontend oder Admin dupliziert werden?
Zed Blackbeard

Sie können die Kundensitzung nicht mit dem obigen Muster abrufen, da Magento\Customer\Model\Config\Sharees sich um eine Abhängigkeit von handelt Magento\Customer\Model\Session, daher der zirkuläre Abhängigkeitsfehler. Ich sehe, was Sie versuchen (dh den Umfang der Website ändern, wenn der Kunde angemeldet ist), konnte dies jedoch nicht herausfinden ein nicht-hackiger Weg auch.
Phil Birnie

@zedBlackbeard, Für Frontend.
Rakesh Jesadiya

1
@ RakeshJesadiya, Zuletzt habe ich den Objektmanager verwendet, um dieses Problem zu lösen. Auch ich bin offen für bessere Antworten
Murtuza Zabuawala

1
Ja als @MurtuzaZabuawala Für dieses Problem müssen Sie den Objektmanager verwenden. Aber verwenden Sie den Objektmanager als Abhängigkeit\Magento\Framework\ObjectManagerInterface
Prince Patel

Antworten:


4

Der einfachste Weg, zirkuläre Abhängigkeiten aufzulösen (obwohl nicht immer der beste), ist die Verwendung von Proxies.

Der Proxy für eine Klasse ist eine automatisch generierte Klasse (dh Magento erstellt sie automatisch, wenn sie nicht über den Auto-Loader gefunden wird), die vom Objektmanager abhängig ist und dieselbe Schnittstelle wie die ursprüngliche Klasse hat.

Die Implementierung einer beliebigen Methode des Proxys ist nur ein Aufruf derselben Methode der ursprünglichen Klasse. Im Konstruktor ist keine Originalklasse erforderlich, stattdessen wird das Objekt der Originalklasse über den Objektmanager erstellt, wenn zum ersten Mal eine Methode des Proxys aufgerufen wird.

Hier ist ein Beispiel für den Proxy aus dem Core ( \Magento\Backend\Model\Auth\Proxy):

/**
 * Get proxied instance
 *
 * @return \Magento\Backend\Model\Auth
 */
protected function _getSubject()
{
    if (!$this->_subject) {
        $this->_subject = true === $this->_isShared
            ? $this->_objectManager->get($this->_instanceName)
            : $this->_objectManager->create($this->_instanceName);
    }
    return $this->_subject;
}

/**
 * {@inheritdoc}
 */
public function setAuthStorage($storage)
{
    return $this->_getSubject()->setAuthStorage($storage);
}

Um einen Proxy zu verwenden, verweisen Sie anstelle des Verweises auf die Klasse (irgendwo in di.xml oder in der Konstruktorabhängigkeit) auf den Proxy, indem Sie den Namen der Klasse anhängen \Proxy, dh:

<type name="Magento\Customer\Model\Config\Share">
<plugin name="Company_Modulename::Share" type="\Company\Modulename\Plugin\Config\Share\Proxy" sortOrder="1"/>

Es lohnt sich immer zu analysieren, ob es Möglichkeiten gibt, die Geschäftslogik neu zu schreiben, um zirkuläre Abhängigkeiten zu vermeiden, bevor Proxies verwendet werden (oder aus dem gleichen Grund ein Objektmanager im Konstruktor).


Wie bekomme ich eine Kundensitzung in der Datei proxy.php auf die oben beschriebene Weise? Immer noch der gleiche Fehler kommt
Rakesh Jesadiya

@RakeshJesadiya Behalte das Plugin einfach so bei, wie du es geschrieben hast, aber ändere di.xml und gib den Plugin-Typ mit dem \ProxySuffix an (wie in meinem obigen Beispiel). Erstellen Sie die Proxy-Klasse nicht manuell.
Eugene Tulika

Geben Sie den gleichen Fehler erneut auf die oben beschriebene Weise. Zirkuläre Abhängigkeit: Magento \ Kunde \ Modell \ Sitzung hängt von Firma \ Modulname \ Plugin \ Config \ Share ab und umgekehrt.
Rakesh Jesadiya

Ich habe meine Fragen basierend auf Ihrem Kommentar aktualisiert, aber nicht funktioniert
Rakesh Jesadiya

Ich sehe, das Problem ist, dass die Methode isWebsiteScope vom Konstruktor des aufgerufen wird. Magento\Customer\Model\Session\StorageDeshalb muss das Objekt zum Zeitpunkt der Erstellung noch erstellt werden, obwohl wir Proxy verwendet haben. Ich sehe auch nicht, wie Object Manager Ihnen hilft (funktioniert bei mir nicht). Ich werde mir genauer ansehen, welche Geschäftslogik Sie implementieren möchten, und sie auf einer anderen Ebene hinzufügen.
Eugene Tulika

1

Die einzige Möglichkeit, die zirkuläre Abhängigkeit zu entfernen, besteht darin, sie objectManagerdirekt zu verwenden .

Ich weiß, dass dies ein hässlicher Weg ist, aber ich denke, dies ist der einzige Weg,

Wenn jemand eine bessere Lösung hat, bin ich auch offen für Lösungen

Aber mein Weg unten ist die Lösung:

protected $_objectManager;

public function __construct( 
    \Magento\Framework\ObjectManagerInterface $objectManager
)
{
    $this->_objectManager = $objectManager;
}

public function afterIsWebsiteScope(\Magento\Customer\Model\Config\Share $subject)
{
    $customerSession = $this->_objectManager->get('Magento\Customer\Model\Session');
    if(!$customerSession->isLoggedIn()){
        return 1;
    } else {
        return 0;
    }

}

1
Ja, ich denke auch, dass dies der einzige Weg zur Lösung ist, circular dependencyaber wir sollten den Objektmanager als Abhängigkeit in Klassendateien verwenden. +1 von mir :)
Prince Patel

Es funktioniert noch nicht und zeigt den gleichen Fehler.
Rakesh Jesadiya

@ RakeshJesadiya hast du Magento\Customer\Model\Sessionvom Konstruktor entfernt? und löschen var / Generation
Murtuza Zabuawala

Ja, ich habe es versucht. Entfernen Sie den generierten und var-Ordner aus dem Stammverzeichnis
Rakesh Jesadiya

Jetzt sieht der Fehler so aus: Ungefangener Fehler: Aufruf einer Mitgliedsfunktion get () auf null in /var/www/html/studentkare/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php:144
Rakesh Jesadiya
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.