Obtener atributo del producto en el carrito en Magento2

21

Estoy tratando de obtener un atributo de producto en la plantilla del carrito. Pero yo simplemente no funciona! El atributo se establece en Visible en las páginas del catálogo en Storefront = yes y se utiliza en el listado de productos = yes

Utilizo un módulo personalizado para anular la siguiente plantilla:

/vendor/magento/module-checkout/view/frontend/templates/cart/item/default.phtml

Tengo el producto:

$_item = $block->getItem();
$product = $_item->getProduct();

Normalmente esperaría que un atributo personalizado (de tipo área de texto en este caso) con un código de atributo 'sample_attr' esté disponible con uno de estos:

$product->getData('sample_attr');

o

$product->getSampleAttr();

Algunos atributos están disponibles usando esto (sku, peso, precio ...), pero para un atributo personalizado tampoco funciona. El ayudante incluido (\ Magento \ Msrp \ Helper \ Data) tampoco tiene método de atributo.

Puedo obtener todos los códigos de atributos usando:

   $attributes = $product->getAttributes();
   foreach($attributes as $a)
   {
     var_dump($a->getName());
   }

También he intentado:

    $attribute = $product->getResource()->getAttribute('sample_attr');
    var_dump($attribute->getFrontend()->getValue($product));

pero esto devuelve nulo.

Entonces, ¿cómo obtengo el valor del atributo?

He intentado estos: obtener un atributo específico para cada producto en la página del catálogo

Salida del atributo de texto personalizado en el catálogo list.phtml (Magento 2)

tecjam
fuente

Respuestas:

51

No hay necesidad de cambiar ningún código PHP para hacer esto.

Solo necesita crear {MODULE_NAME}/etc/catalog_attributes.xmlcon dicho contenido:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/catalog_attributes.xsd">
    <group name="quote_item">
        <attribute name="sample_attr"/>
    </group>
</config>
Igor Sydorenko
fuente
Interesante. No había pensado en eso. Lo intentaré más adelante.
tecjam
De
nada
2
¡Fantástico! Funciona para mi. Parecía que tenía que correr magento setup:di:compilepara que esto funcionara, pero eso tiene sentido. Estás cambiando el árbol de dependencias aquí.
psyklopz
Esta debería ser la respuesta aceptada en mi humilde opinión. Las otras respuestas sugieren cargar el modelo del producto para cada artículo del carrito, lo que no es una buena idea por razones de rendimiento, especialmente cuando los carritos de los usuarios son grandes.
Andrew Kett
Tengo crear un módulo TenX / checkoutex bajo etc He colocado por encima de código, pero no su trabajo me pueden ayudar
Sarvesh Tiwari
8

Así que encontré una manera de obtener la información que buscaba. ¡Tengo que cargar el producto completo del ProductRepository! Tenga en cuenta que si intenta cargarlo, \Magento\Catalog\Model\Productse comportará como un singleton, siempre le dará el mismo producto para cada bucle.

Utilicé la clase auxiliar de mis módulos, ya que define el siguiente método para cargar el producto desde el productId:

public function __construct(
  \Magento\Framework\App\Helper\Context $context,
  \Magento\Catalog\Model\ProductRepository $productRepo
) {
  $this->_productRepo = $productRepo;
  parent::__construct($context);
  }


/**
 * Load product from productId
 *
 * @param $id
 * @return $this
 */
public function getProductById($id)
{
    return $this->_productRepo
        ->getById($id);
}

Incluí el ayudante en la plantilla:

$customHelper = $this->helper('MyCompany\MyModule\Helper\Data');

Cargo el producto completo:

$custProd = $customHelper->getProductById($product->getId());

Y ahora puedo usar:

$custProd->getSampleAttr();

y

$custProd->getData('sample_attr');

para obtener los datos

tecjam
fuente
2

Para aquellos que aterrizaron aquí buscando una solución simple, así es como me funcionó

Agregué a mi default.phtml(en module-checkout/view/frontend/templates/cart/item) esto:

<?php
    $product_id = $product->getId();
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $customProduct = $objectManager->get('Magento\Catalog\Model\Product')->load($product_id);
 ?>

entonces puedes llamar $customProduct->getData('your_attribute');como siempre

Luca G
fuente
2
En la plantilla, Magento nos desalienta a usar ObjectManager directamente. Deberíamos agregar el bloque.
Khoa TruongDinh
2
No debe usar directamente el ObjectManager ni en la plantilla, ni en el bloque.
ocornu
Si simplemente no te importa cómo, este 100% funciona.
A. Lal
1

Con la configuración de administrador correcta, los atributos personalizados se cargan en el objeto del producto en la página Finalizar compra si el modelo de origen en la eav_attributetabla sql está configurado en NULL. Por lo tanto, puede acceder directamente $product->getSampleAttr()desde la página de pago.

Pero si el atributo tiene un modelo de origen como Magento\Eav\Model\Entity\Attribute\Source\Table, debe cargar el producto desde el repositorio.

Cree un nuevo ayudante y agregue el repositorio de productos en el constructor que aún funciona en 2.2.6 (como la solución de tecjam)

Tenga en cuenta que el problema es el mismo si intenta anular el procesador de elementos (llamado en la página de pago) y agregar el depósito del producto aquí.

ingrese la descripción de la imagen aquí

Jakk64
fuente
0

Los atributos personalizados no se incluyen en el objeto del producto que se encuentra en Quote / Cart, por lo que no puede obtenerlo a través de la función getData ('custom_attribute'). lo que debe hacer es obtener el Id. del producto devuelto por el objeto de Cotización del producto y cargar el producto utilizando el repositorio del producto, una vez que haya cargado el producto a través del repositorio, puede obtener todos los datos, incluidos los atributos personalizados asignados, más tarde puede usar la función getData ('custom_attribute') para obtenerlo.

Espero que tenga sentido.

Zeeshan Khuwaja
fuente