Creazione di istanze di aiutanti in Magento 2


26

Le ultime build di Magento 2 hanno eliminato la Mageclasse. Questo significa che abbiamo perso il Mage::helpermetodo.

Esiste una tecnica di sostituzione (helper factory?) Per creare un'istanza di helper in Magento 2? O ci si aspetta che usiamo la nuova classe del gestore degli oggetti e creiamo un'istanza dell'helper come oggetto singleton / memorizzato nella cache con get(vs. create)

Risposte:


31

Vedo che sei arrivato alla giusta soluzione, voglio solo riassumere.

L'iniezione del costruttore deve essere utilizzata per recuperare l'helper (o qualsiasi altra istanza) in qualunque classe sia necessaria:

class SomeClass
{
    public function __construct(\Magento\Core\Helper\Data $helper)
    {
        $this->helper = $helper;
    }

    public function doSmth()
    {
        $this->helper->someMethod();
    }
}

Nota che non sono richiesti commenti phpDoc , Magento leggerà direttamente la firma del costruttore per capire quali dipendenze sono richieste.

\ Magento \ Core \ Helper \ Factory dovrebbe essere usato solo in quei rari casi in cui devi chiamare molti helper multipli o non sai esattamente quale ti serve.

L'uso diretto di Object Manager è rigorosamente sconsigliato . Quindi, per favore, evita di usare:

\Magento\Core\Model\ObjectManager::getInstance()

È lì solo per serializzazione / deserializzazione.


non utilizzare statico in quanto non può essere testato con l'unità PHP e sì, è sconsigliato. Tutte le dipendenze M2 vengono eseguite tramite il costruttore e gestite internamente dall'Object Manager e verranno recuperate come Singleton. Inoltre, non utilizzare _ per indicare una visibilità della proprietà, tutti i nomi M2 devono utilizzare la camecase
PartySoft

@Anton Kril se usiamo helperin template, come $this->helper('Magento\Catalog\Helper\Image'), segue le migliori pratiche?
Khoa TruongDinh,

2
No non lo fa. I modelli devono solo fare riferimento a blocchi. Gli aiutanti dovrebbero essere evitati
Anton Kril,

10

Sembra che le persone incoraggianti di Magento usino il loro nuovo sistema di iniezione automatica delle dipendenze per ottenere aiutanti e modelli in oggetti tramite il costruttore dell'oggetto.

La versione corta? Se si dispone di un oggetto che è un'istanza da parte del gestore oggetti, e decorare un costruttore con un PHPDoc@param , ed i parametri ha una serie di tipo suggerimento corretto, il gestore oggetto si istanziare automaticamente l'helper (o, credo, altri oggetti) per voi.

Ad esempio, il costruttore seguente inietterebbe un helper di dati di base nell'oggetto.

/**
* @param \Magento\Core\Helper\Data $coreData
*/        
public function __construct(\Magento\Core\Helper\Data $coreData)
{
    $this->_coreHelper = $coreData;            
}

Questa è la risposta corretta - grande investigazione; non era del tutto ovvio per me, anche dopo aver scavato molto.
Philwinkle,

2
OK ... ora mi fa male la testa ... molto. Vuoi dire che dovremmo usare PHPDoc per "scrivere" il codice? Questa è una follia. Smetto.
Marius

@Marius hahaha non è così raro - il blog di Alan lo spiega in una certa misura.
Filwinkle

3
@philwinkle. Ho letto il suo articolo. Molto interessante, ma dico ancora che questa è follia. Chiamami vecchio stile, ma il codice "ai miei tempi" era codice e i commenti erano quelle cose che quasi nessuno si prendeva la briga di scrivere.
Marius

Oh ... e comunque. +1. Bella domanda e bella risposta.
Marius

7

A parte tutte le risposte sopra, se devi usare l'helper nel modello phtml puoi semplicemente fare così:

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]');

Spero sia utile se qualcuno non lo sapesse prima;)


6

Il modo in cui gli helper sono istanziati (almeno per il nuovo modulo Backend (~ dev50)) sono tramite una helperFactory:

/**
 * Return helper object
 *
 * @param string $name
 * @return \Magento\Core\Helper\AbstractHelper
 */
public function helper($name)
{
    return $this->_helperFactory->get($name);
}

Che è essenzialmente solo un tipo specializzato di una fabbrica di modelli. Ad esempio: Magento \ Core \ Block \ Context line 143 (dev50) come parte del costruttore:

\Magento\Core\Model\Factory\Helper $helperFactory

L'helper factory restituirà il modello richiesto in base al nome della classe e si assicurerà che sia una instanceofclasse astratta di helper:

/**
 * Get helper singleton
 *
 * @param string $className
 * @param array $arguments
 * @return \Magento\Core\Helper\AbstractHelper
 * @throws \LogicException
 */
public function get($className, array $arguments = array())
{
    $className = str_replace('_', '\\', $className);
    /* Default helper class for a module */
    if (strpos($className, '\Helper\\') === false) {
        $className .= '\Helper\Data';
    }

    $helper = $this->_objectManager->get($className, $arguments);

    if (false === ($helper instanceof \Magento\Core\Helper\AbstractHelper)) {
        throw new \LogicException(
            $className . ' doesn\'t extends Magento\App\Helper'
        );
    }

    return $helper;
}

Se dovessi implementarlo da solo, sembra che il core di Magento lo stia caricando in due modi:

Fai rotolare la tua fabbrica:

$objectManager = \Magento\Core\Model\ObjectManager::getInstance();

$helperFactory = $objectManager->get('\Magento\Core\Model\Factory\Helper');
$helper = $helperFactory->get('\PulseStorm\Commercebug\Helper\Data');

O prendilo direttamente:

$helper = \Magento\Core\Model\ObjectManager::getInstance()->get('Magento\Core\Helper\Data');

1
+1 per informazioni utili, ma vorresti creare un'istanza della fabbrica direttamente in quel modo? O dovrebbe essere istanziato un singolo helper factory con l'Object Manager come classe memorizzata nella cache con get?
Alan Storm,

Non è del tutto chiaro, perché la fabbrica di helper è ereditata da \ Mage \ Core \ Block \ Abstract - Penso che l'intenzione sia quella di fornire la tua propria fabbrica di helper. Essa non sembra che stanno intenzionalmente la creazione di un Singleton per la fabbrica, però.
Philwinkle,

Sembra che io abbia bisogno / la migliore fonte è quella di rintracciare il modo in cui _helperFactory viene iniettato in quegli oggetti e vedere come il team principale lo istanzia.
Alan Storm,

Il mio riepilogo di semplificazione non è corretto e il costruttore richiede un'istanza di ObjectManager. Modificherò momentaneamente.
Philwinkle,

Vedi modifica. Dovrebbe funzionare - difficile da determinare in questo momento perché il mio ambiente cli shell non sta caricando l'istanza di configurazione del negozio come previsto. Questo dovrebbe essere sufficiente per portarti sulla strada giusta, però.
Filwinkle

0

Prova in questo modo

$helper = \Magento\Framework\App\ObjectManager::getInstance()->get('Xx\Xx\Helper\Xx');

L'uso diretto di Object Manager è rigorosamente sconsigliato.
sv3n

@ sv3n potresti spiegare, qual è la ragione? Grazie.
Sohan

1
Meglio usare iniezioni di dipendenza invece ... ha risposto qui per esempio ... magento.stackexchange.com/questions/142352/…
sv3n
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.