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.

Rakesh Jesadiya
quelle
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).

Eugene Tulika
quelle
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;
    }

}
Murtuza Zabuawala
quelle
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