Serializable Campi in Magento Collezioni
-
16-10-2019 - |
Domanda
Nel mio modello di risorse che ho definito un campo come serializzabile (vedere la proprietà $_serializableFields
in Mage_Core_Model_Resource_Db_Abstract
):. Manici Magento automaticamente la serializzazione / deserializzazione dei contenuti, quando il caricamento dei dati dal database e prima di salvare l'oggetto
Questo funziona perfettamente, ma quando ho iterare su una collezione di questi oggetti, il contenuto del campo non sono deserializzate automaticamente. Ho provato con $collection->walk('afterLoad')
ma presto resi conto che unserializeFields()
viene attivato nel modello di risorse load()
, e non in afterLoad()
come ho primo pensiero. Qual è la migliore pratica in questo caso? Come faccio a questo campo deserializzate automaticamente? Posso naturalmente ricaricare l'oggetto nel mio ciclo, facendo qualcosa di simile $object = $object->load($object->getId())
, ma mi chiedevo se esiste un modo più intelligente per raggiungere questo obiettivo.
Soluzione
I può naturalmente ricaricare l'oggetto nel mio ciclo, facendo qualcosa di simile
$object = $object->load($object->getId())
Questo è non una ricarica - questo è un carico . Articoli (istanze di modello) in collezioni non sono caricato. Essi semplicemente dovuto un array associativo dei dati di riga risultato applicati. Si tratta di un importante e un po 'di confusione differenza tra queste istanze modello di raccolta di proprietà e di quelli che sono i dati di auto-carico attraverso il loro modello di risorse.
In _afterLoad()
della vostra collezione, un'iterazione sulle _items
e unserialize()
campo appropriato:
protected function _afterLoad()
{
parent::_afterLoad();
foreach ($this->getItems() as $item) {
$item->setData('field',unserialize($item->getData('field')));
$item->setDataChanges(false);
//The above sets items as not dirty.
//Value will be serialized on save via resource model.
}
return $this;
}
Altri suggerimenti
Per fare questo per collezioni di prodotti ho aggiunto un listener di eventi per catalog_product_collection_load_after
e per iterare su tutti i prodotti.
/**
* Apply backend manipulations of attributes to collection items.
* Listens to catalog_product_collection_load_after.
*
* @param Varien_Event_Observer $observer
* @return Mage_Catalog_Model_Observer
*/
public function loadCollectionAttributes(Varien_Event_Observer $observer)
{
$collection = $observer->getCollection();
/* @var $collection Mage_Catalog_Model_Resource_Product_Collection */
foreach ($collection as $product) {
/* @var $product Limora_Catalog_Model_Product */
foreach ($product->getAttributes() as $attribute) {
/* @var $attribute Mage_Eav_Model_Attribute */
$attribute->getBackend()->afterLoad($product);
}
}
}
O più semplicemente, nella vostra collezione modello di risorse: -
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection { protected function _afterLoad() { parent::_afterLoad(); foreach ($this->getItems() as $item) { $this->getResource()->unserializeFields($item); $item->setDataChanges(false); } return $this; } }