How Do I Output Multiselect Attribute Values In Magento 2.3.x? - magento

In a Magento 2.3.3 store I am trying to ouput the values of a multiselect custom attribute on a category page, but not having any luck.
I have set the attribute to be used in product listing and tried to output it on catalog/product/listing.phtml template page in my custom theme.
I am using the using the following code:
<?php /* #escapeNotVerified */ echo $_product->getResource()->getAttribute('custom_attribute')->getFrontend()->getValue($_product); ?>
This is working for dropdown attributes but not multi select attributes.
Kind of stuck on this...

You can use the below code to get MultiSelect Attribute value
create block in "catalog_product_view.xml"
<referenceBlock name="product.info.main">
<block class="Magento\Catalog\Block\Product\View" name="attribue.name" template="Magento_Catalog::product/view/attribute_name.phtml" after="-" />
</referenceBlock>
create "phtml" file under "Magento_Catalog::product/view/attribute_name.phtml"
<?php $product = $block->getProduct(); ?>
<div>
<?php
$data = explode(',',$product->getData('attribute_code'));
foreach($data as $value):
?>
<?php
$attr = $product->getResource()->getAttribute('attribute_code');
if ($attr->usesSource()):
?>
<?php
$option_value = $attr->getSource()->getOptionText($value);
?>
<p><?php echo $option_value; ?></p>
<?php endif;?>
<?php endforeach;?>
</div>

Here is an example of a code that returns "Multiselect Attribute Values". The attribute belongs to product entity. As it isn't a good idea to get ProductResource model from ProductModel and taking into account that probably you need to get it inside some template, just create a ViewModel and use this example there.
use Magento\Catalog\Model\ResourceModel\Product as ProductResource;
...
public function __construct(
...
ProductResource $productResource
)
{
...
$this->productResource = $productResource;
}
public function prepareProductAttributeOptions($product, $attributeCode)
{
$result = [];
$data = $product->getData($attributeCode);
$optionsIds = [];
if ($data) {
$optionsIds = explode(',', $data);
}
foreach ($optionsIds as $optionId) {
$attr = $this->productResource->getAttribute($attributeCode);
if ($attr->usesSource()) {
$option_value = $attr->getSource()->getOptionText($optionId);
$result[] = $option_value;
}
}
return implode(',', $result);
}

Related

magento how to get Json Config by product id

I am in need to get the Json Config by product id or sku in the product listing page for a particular category.
I can see that getJsonConfig is decalred in Product options block where only one particular product is showing thats why it can show Json Config without saying the product id. But I am in product list page.
Is there any way to get it like below?
$this->getJsonConfig($productId);
$this->getJsonConfig()
The method is part of
class Mage_Catalog_Block_Product_View
and it calls
/* #var $product Mage_Catalog_Model_Product */
$product = $this->getProduct();
public function getProduct()
{
if (!Mage::registry('product') && $this->getProductId()) {
$product = Mage::getModel('catalog/product')->load($this->getProductId());
Mage::register('product', $product);
}
return Mage::registry('product');
}
So to use it ( in any other page ) you have to set product in the block instance as below :
Mage::register('product', $_product); // add the product object in the registry
$block = Mage::getBlockSingleton('Mage_Catalog_Block_Product_View'); // Instantiate the product view block
echo $block->getJsonConfig();
I found a simple solution for configurable product view page.
Hope that will help.
if ($_product->isConfigurable())
{ $block1 = Mage::app()->getLayout()->createBlock('catalog/product_view');
$block1->setProduct($_product);
$configPrice = $block1->getJsonConfig(); //var_dump( $config = $block->getJsonConfig`enter code here`() );
$block2 = Mage::app()->getLayout()->createBlock('catalog/product_view_type_configurable');
$block2->setProduct($_product);
$config = $block2->getJsonConfig();
}
<?php if ($_product->isConfigurable()): ?>
<script type="text/javascript">
var optionsPrice = new Product.OptionsPrice(<?php echo $configPrice ?>);
</script>
<script type="text/javascript">
var spConfig = new Product.Config(<?php echo $config ?>);
</script>
<?php endif; ?>

Magento: list all values of a single attribute

I'm trying to list up all the existing values of a newly created attribute in magento 1.7.0.2.
(and make them clickable links, so that on click they list up all of the items with the specific attribute value, but that's not a priority right now)
The attribute code is "artist"
So far i created the file Artist.php in app/code/core/Mage/Catalog/Block/ with the following code:
public function getAllArtists()
{
$product = Mage::getModel('catalog/product');
$attributes = Mage::getResourceModel('eav/entity_attribute_collection')
->setEntityTypeFilter($product->getResource()->getTypeId())
->addFieldToFilter('attribute_code', 'artist');
$attribute = $attributes->getFirstItem()->setEntity($product->getResource());
$artists = $attribute->getSource()->getAllOptions(false);
return $artists;
}
and the file artist.phtml in /app/design/frontend/default/template-name/template/catalog/product with this code:
<ul id="artist_list">
<?php foreach ($this->getAllArtists() as $artist): ?>
<li><?php echo $artist['label'] ?></li>
<?php endforeach; ?>
</ul>
which i then call in a static block with
{{block type="core/template" template="catalog/product/artist.phtml"}}
but nothing appears...
i used the code from this thread: http://www.magentocommerce.com/boards/viewthread/19982/P0/
the attribute is set "Visible on Product View Page on Front-end"
and i call the attribute value of each item in the ../template/product/view.phtml with
<?php echo $_product->getData('artist') ?>
and it correctly displays the value.
any ideas?
$name='whatever_your_attribute_name';
$attributeInfo = Mage::getResourceModel('eav/entity_attribute_collection')->setCodeFilter($name)->getFirstItem();
$attributeId = $attributeInfo->getAttributeId();
$attribute = Mage::getModel('catalog/resource_eav_attribute')->load($attributeId);
$attributeOptions = $attribute ->getSource()->getAllOptions(false);
print_r($attributeOptions);
Ref: Magento - get all attribute value
it will be just
$attribute = Mage::getModel('eav/config')->getAttribute(4,'artist');
if($attribute->usesSource()) {
$options = $attribute->getSource()->getAllOptions(false);
foreach($options as $key=>$value) {
if(count($value)==2) {
$artists[] = $value['label'];
}
}
}

How to make second root category navigation in magento?

Other than the normal navigation I get when I add subcategories to the main root category, I want to be able to make a new root category, assign subcategories to it and have it display as a separate menu.
Is this possible?
May this can help you :Link 1Link 2
To retrieve another root category
<?php
echo '<pre>';
$id=9;
$catagory_model = Mage::getModel('catalog/category');
$categories = $catagory_model->load($id); // where $id will be the known category id
if(!empty($categories))
{
echo 'category name->'.$categories->getName(); //get category name
echo '<br>';
echo 'category image url->'.$categories->getImageUrl(); //get category image url
echo '<br>';
echo 'category url path->'.$categories->getUrlPath(); //get category url path
echo '<br>';
}
?>
now $id=9; is my new root category id.
To retrieve sub categories of these new root category ($id=9;) below is the following reference code.Customize it according to your requirements.
<?php $helper = $this->helper('catalog/category') ?>
<?php $categories = $this->getStoreCategories() ?>
<?php foreach($categories as $category): ?>
<?php $subcategories = $category->getChildren() ?>
<?php foreach($subcategories as $subcategory): ?>
<?php $subsubcategories = $subcategory->getChildren() ?>
<?php foreach($subsubcategories as $subsubcategory): ?>
<?php endforeach; ?><!-- end foreach subsubcategories -->
<?php endforeach; ?><!-- end foreach subcategories -->
<?php endforeach; ?><!-- end foreach categories -->
In an ideal world you would have found the answer by now, but in case you didn't I modified Nikhil's answer to work for me to basically do what you describe, minus any convenience at all...
$id=9;
$catagory_model = Mage::getModel('catalog/category');
$categories = $catagory_model->load($id);
if(!empty($categories))
{
$cats = explode(",", $categories->getChildren());
foreach($cats AS $c)
{
$cat = $catagory_model->load(trim($c));
echo ''.$cat->getName().'';
}
}
I'm just pasting what I used. The reality is you will have to build the html to make this do whatever you want it to do. If you have subcategories within your loop, you will have to run another fetch in the foreach part.
I am not familiar with magento enough to know what methods you can run on the $cat object. I did a print_r($cat) to examine the object and made a lucky guess that getUrlKey would be available.
Magento... pfft! you'd think ebay would have higher standards than this.

Flash messanger in zf2

How can i use flash messenger in zend freamwork 2? Session documentation is not yet. Anyone know it? But session libraries are there.
Update :
Zend Framework new release added FlashMessenger View Helper , found in path /library/Zend/View/Helper/FlashMessenger.php
FlashMessenger.php
Old answer :
I have written a custom view helper, for printing flash messages
In /module/Application/Module.php
public function getViewHelperConfig()
{
return array(
'factories' => array(
'flashMessage' => function($sm) {
$flashmessenger = $sm->getServiceLocator()
->get('ControllerPluginManager')
->get('flashmessenger');
$message = new \My\View\Helper\FlashMessages( ) ;
$message->setFlashMessenger( $flashmessenger );
return $message ;
}
),
);
}
Create a custom view helper in /library/My/View/Helper/FlashMessages.php
namespace My\View\Helper;
use Zend\View\Helper\AbstractHelper;
class FlashMessages extends AbstractHelper
{
protected $flashMessenger;
public function setFlashMessenger( $flashMessenger )
{
$this->flashMessenger = $flashMessenger ;
}
public function __invoke( )
{
$namespaces = array(
'error' ,'success',
'info','warning'
);
// messages as string
$messageString = '';
foreach ( $namespaces as $ns ) {
$this->flashMessenger->setNamespace( $ns );
$messages = array_merge(
$this->flashMessenger->getMessages(),
$this->flashMessenger->getCurrentMessages()
);
if ( ! $messages ) continue;
$messageString .= "<div class='$ns'>"
. implode( '<br />', $messages )
.'</div>';
}
return $messageString ;
}
}
then simple call from layout.phtml , or your view.phtml
echo $this->flashMessage();
Let me show example of controller action
public function testFlashAction()
{
//set flash message
$this->flashMessenger()->setNamespace('warning')
->addMessage('Mail sending failed!');
//set flash message
$this->flashMessenger()->setNamespace('success')
->addMessage('Data added successfully');
// redirect to home page
return $this->redirect()->toUrl('/');
}
In home page, it prints
<div class="success">Data added successfully</div>
<div class="warning">Mail sending failed!</div>
Hope this will helps !
i have written a post about this some time ago. You can find it right here
Basically you use it just the same like earlier.
<?php
public function commentAction()
{
// ... display Form
// ... validate the Form
if ($form->isValid()) {
// try-catch passing data to database
$this->flashMessenger()->addMessage('Thank you for your comment!');
return $this->redirect()->toRoute('blog-details'); //id, blabla
}
}
public function detailsAction()
{
// Grab the Blog with given ID
// Grab all Comments for this blog
// Assign the view Variables
return array(
'blog' => $blog,
'comments' => $comments,
'flashMessages' => $this->flashMessenger()->getMessages()
);
}
Then in your .phtml file you do it like this:
// details.phtml
<?php if(count($flashMessages)) : ?>
<ul>
<?php foreach ($flashMessages as $msg) : ?>
<li><?php echo $msg; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
Obviously this isn't all too handy, as you have to do this for every single .phtml file. Therefore doing it within the layout you have to do it at best like the following:
<?php
// layout.phtml
// First get the viewmodel and all its children (ie the actions viewmodel)
$children = $this->viewModel()
->getCurrent()
->getChildren();
$ourView = $children[0];
if (isset($ourView->flashMessages) && count($ourView->flashMessages)) : ?>
<ul class="flashMessages">
<?php foreach ($ourView->flashMessages as $fMessage) : ?>
<li><?php echo $fMessage; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
If you need further description, please see my blog, but i guess the code itself is pretty clear (apart frmo the layout.phtml example). Alternatively you're always free to write your own view helper to have it look a little cleaner inside your view-templates.
How to grab Flashmessenger’s messages in a View Helper – sharing code as requested by Sam.
The View helper should implement the ServiceManagerAwareInterface interface and related methods. The plugin will now have access to a Service Manager which we can use to get the Service Locator and ultimately access to the Flash Messenger.
I’ve not touched this code since I initially wrote it – so there may be a more elegant way of doing this.
protected function getMessages()
{
$serviceLocator = $this->getServiceManager()->getServiceLocator();
$plugin = $serviceLocator->get('ControllerPluginManager');
$flashMessenger = $plugin->get('flashmessenger');
$messages = $flashMessenger->getMessages();
// Check for any recently added messages
if ($flashMessenger->hasCurrentMessages())
{
$messages += $flashMessenger->getCurrentMessages();
$flashMessenger->clearCurrentMessages();
}
return $messages;
}
And calling getMessages() from within the plugin should return an array of messages that can be passed to a partial and rendered.
Add code below to the view to render error messages:
<?php echo $this->flashmessenger()
->setMessageOpenFormat('<div class="alert alert-danger"><ul%s><li>')
->setMessageCloseString('</li></ul></div>')
->render('error')
; ?>
In previous request, make sure you created an error message by running code below in your controller:
$this->flashmessenger()->addErrorMessage('Whops, something went wrong...');

Magento - Product Collection with the current user's Wishlist

Within a Magento php Controller, how can I get a Product Collection containing the products listed in the logged in user's (ie current user's) Wishlist.
I am getting the Wishlist using:
$wishList = Mage::getModel('wishlist/wishlist')->loadByCustomer(Mage::getSingleton('customer/session')->getCustomer());
and this contains the correct number of items.
But I would like to get a Product Collection. I have tried:
$productCollection = $wishList->getProductCollection();
and
$productCollection = $wishList->getProductCollection()->addAttributeToSelect('id')->load();
but the Product Collection I get has a length of 0.
How do I get the Product Collection?
You can use the getWishlistItemCollection (see link for more details) off the wishlist helper to return a collection of items, you then need to get the product from the item.
I have been using the following code to create an associative array of the products, which I then use to determine if a product I am displaying in the list page is in the wishlist...hopefully this will help:
public function getWishList() {
$_itemCollection = Mage::helper('wishlist')->getWishlistItemCollection();
$_itemsInWishList = array();
foreach ($_itemCollection as $_item) {
$_product = $_item->getProduct();
$_itemsInWishList[$_product->getId()] = $_item;
}
return $_itemsInWishList;
}
Try this with product all details like name, images etc...
<?php
$customer = Mage::getSingleton('customer/session')->getCustomer();
if($customer->getId())
{
$wishlist = Mage::getModel('wishlist/wishlist')->loadByCustomer($customer, true);
$wishListItemCollection = $wishlist->getItemCollection();
foreach ($wishListItemCollection as $item)
{
echo $item->getName()."</br>";
echo $item->getId()."</br>";
echo $item->getPrice()."</br>";
echo $item->getQty()."</br>";
$item = Mage::getModel('catalog/product')->setStoreId($item->getStoreId())->load($item->getProductId());
if ($item->getId()) :
?>
<img src="<?php echo Mage::helper('catalog/image')->init($item, 'small_image')->resize(113, 113); ?>" width="113" height="113" />
<?php endif; } } ?>
$customer = Mage::getSingleton('customer/session')->getCustomer();
$wishlist = Mage::getModel('wishlist/wishlist')->loadByCustomer($customer, true);
$wishListItemCollection = $wishlist->getItemCollection();
foreach ($wishListItemCollection as $item)
{
// do things
}

Resources