I have tried all sorts of things and I'm not getting anywhere. Please would someone show me how to get the name and id of all available product attribute sets? One will be 'Default'...
I'm building a custom quoting system and need to pull in the attribute sets so that users can select that first then load up the products that are assigned to that set.
Many thanks for your help.
You can load the attribute sets with:
$attributeSetCollection = Mage::getResourceModel('eav/entity_attribute_set_collection') ->load();
Iterate:
foreach ($attributeSetCollection as $id=>$attributeSet) {
$entityTypeId = $attributeSet->getEntityTypeId();
$name = $attributeSet->getAttributeSetName();
Mage::log("ATTRIBUTE SET :".$name." - ".$id);
}
You can then load your collection by attribute set.
So As you are trying to get the attributeSets which are showing in manage attribute set section of admin you can follow the below coding:
<?php
require_once('app/Mage.php');
umask(0);
Mage::app();//->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$entityType = Mage::getModel('catalog/product')->getResource()->getTypeId();
$collection = Mage::getResourceModel('eav/entity_attribute_set_collection')->setEntityTypeFilter($entityType);
$allSet = array();
foreach($collection as $coll){
$attributeSet['name'] = $coll->getAttributeSetName();
$attributeSet['id'] = $coll->getAttributeSetId();
$allSet[] = $attributeSet;
}
echo "<pre>";
print_r($allSet);
echo "</pre>";
?>
Click here! For more reference.
If you want to get an Attribute set selector in your Magento Admin System > Configuration this class will be useful:
class CompanyName_ModuleName_Model_System_Config_Source_Catalog_Product_Attributeset
{
protected $_options = array();
public function toOptionArray()
{
if (!count($this->_options)) {
$entityTypeId = Mage::getResourceModel('catalog/product')->getTypeId();
$attributeSetCollection = Mage::getResourceModel('eav/entity_attribute_set_collection')
->setEntityTypeFilter($entityTypeId);
foreach ($attributeSetCollection as $_attributeSet) {
$this->_options[] = array(
'value' => $_attributeSet->getId(),
'label' => $_attributeSet->getAttributeSetName()
);
}
}
return $this->_options;
}
}
These attribute sets are limited by catalog_product entity type.
Indeed you will need the field in your system.xml like this:
<select_attribute_set translate="label">
<label>Default Attribute Set for new importing products</label>
<frontend_type>select</frontend_type>
<source_model>companyname_modulename/system_config_source_catalog_product_attributeset</source_model>
<sort_order>30</sort_order>
<show_in_default>1</show_in_default>
</select_attribute_set>
Related
This is magento code that i have used to get attribute.
echo $_product->getResource()->getAttribute('attrcode')->getFrontend()->getValue($_product);
This code is working fine in view.phtml it return to attribute code value.
when i write same code in list.phtml file this code is return blank.
where i do mistake. please help.
<?php echo $_product->getAttributeText('attrcode');?>
please use that code on list page and also check attribute setting in ('Used in Product Listing': "Yes")
Here is the code get attribute name and value that that doesn't belongs to any product
$attributeCode = 'YOUR_ATTRIBUTE_CODE';
$product = Mage::getModel('catalog/product');
$productCollection = Mage::getResourceModel('eav/entity_attribute_collection')
->setEntityTypeFilter($product->getResource()->getTypeId())
->addFieldToFilter('attribute_code', $attributeCode);
$attribute = $productCollection->getFirstItem()->setEntity($product->getResource());
print_r($attribute->getData()); // print out the available attributes
$options = $attribute->getSource()->getAllOptions(false);
print_r($options);
If you want to display all the values of a specific attribute in Magento 2 phtml file, then use following code
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$eavConfig = $objectManager->get('\Magento\Eav\Model\Config');
$attribute = $eavConfig->getAttribute('catalog_product','attribute_code');
$values = $attribute->getSource()->getAllOptions();
I have lot of products with custom options, now I have requirement to update only custom options through csv file. so how we can do this programatically?
i found one solution for updating custom options programatically here is the solution
$product = Mage::getModel('catalog/product')->load($product_id);
$values = array();
foreach ($product->getOptions() as $o) {
$p = $o->getValues();
}
}
foreach($p as $v)
{
$values[$v->getId()]['option_type_id']= $v->getId();
$values[$v->getId()]['title']= 'test';
$values[$v->getId()]['price']= 23;
$values[$v->getId()]['price_type']= 'fixed';
$values[$v->getId()]['sku']= $value1;
}
$v->setValues($values);
$v->saveValues();
$product->save();
hope this help someone
this only update custom options value
I think this is also useful...
If you are customize the products .
<?php
$magePath = 'app/Mage.php';
require_once $magePath;
Varien_Profiler::enable();
Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
umask(0);
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
$product_ids = array(1,2,167);
$productmodel = Mage::getModel('catalog/product');
foreach ($product_ids as $product_id) {
/**i use this two arrays for collecte value because i uses inside setData of
current option*/
$cos=array();
$co=array();
$product = $productmodel->load($product_id);
$options = $product->getProductOptionsCollection();
if (isset($options)) {
foreach ($options as $o) {
$title = $o->getTitle();
/**
this block is for changing information of specific option from collection options inside
current product
the save method for this option in end of code
*/
if ($title == "Line 1/Front") {
$o->setProduct($product);
$o->setTitle("Line 1/Ftont");
$o->setType("drop_down");
$o->setIsRequire(1);
$o->setSortOrder(0);
}
/**
this block for update or add information of specific value inside current option
*/
$optionType = $o->getType();
//test type
if ($optionType == "drop_down") {
//getting collection of value related to current option
$values = $o->getValuesCollection();
$found = false;
foreach ($values as $k => $v) {
//test existing of value for update
if (1 == preg_match("/said$/i", $v->getTitle())) {
//update and save
$v->setTitle("morad")
->setSku("kk")
->setPriceType("fixed")
->setSortOrder(0)
->setPrice(floatval(13.0000));
$v->setOption($o)->save();
/**
this ligne is important i collecte all value required for normalize save function
related to current option
*/
$cos[]=$v->toArray($co);
}
}
/**
create new value object you can use $option->getValueInstance() for working with
getSingleton
*/
$value = Mage::getModel('catalog/product_option_value');
$value->setOption($o)
->setTitle('valueiwant')
->setSku("nn")
->setPriceType("fixed")
->setSortOrder(1)
->setPrice(12)
/**
this ligne is important (relation forigien key) for related this new value
to specific option
*/
->setOptionId($o->getId());
$value->save();
/**
this ligne is important i collecte all value required for normalize save function
related to current option
*/
$cos[]=$value->toArray($co);
}
$o->setData("values",$cos)->save();
//var_dump($cos);
}
}
}
Do you create a module to do that ? If you do, you must use the cron system of Magento and call a method of a custom model :
<config>
<!--...-->
<crontab>
<jobs>
<company_test>
<schedule>
<cron_expr>0,15,30,45 * * * *</cron_expr>
</schedule>
<run>
<model>test/testmodel::testMethod</model>
</run>
</company_module>
</jobs>
</crontab>
</config>
When this is done, you can update the option of a specific product by using the model Mage_Catalog_Model_Product_Option. I don't know how the CSV is made, but the algorithm can be something like that :
// foreach option
/** #var $opt Mage_Catalog_Model_Product_Option */
$opt = Mage::getModel('catalog/product_option');
$opt->setProduct($product);
$optionArray = array(
'is_delete' => 0,
'title' => 'Blabla',
'previous_group' => '',
'previous_type' => '',
'type' => 'field', //can be radio, drop_down, file, area...
'is_require' => 0,
'sort_order' => 42,
'values' => array()
);
$opt->addOption($optionArray);
$opt->saveOptions();
// end foreach
Also check this link : http://subesh.com.np/2009/12/adding-custom-options-product-magento/
My client is requesting that each simple product within a bundled product they are selling (Clothing Top and Bottom) be added as a separate line item in the cart whenever a user adds it. Can anyone direct me in how to accomplish this? I am fairly good with MVC and the Zend Framework, but I need a bit of help finding the exact files that control adding bundled products to the cart, or an alternate method for getting these items added separately. Please assume that the only possible product type for this clothing is the Bundled product type.
You will need an observer:
<checkout_cart_product_add_after>
<observers>
<reporting>
<type>singleton</type>
<class>Yourcompany_yourmodelname_Model_Observer</class>
<method>onCartProductAdd</method>
</reporting>
</observers>
</checkout_cart_product_add_after>
Then do the observer:
class ourcompany_yourmodelname_Model_Observer extends Mage_Core_Model_Abstract
{
/**
* Binds to the checkout_cart_product_add_after Event and passes control to the helper function to process the quote
*
* #param Varien_Event_Observer $observer
* #return void
*/
public function onCartProductAdd($observer){
$product = $observer->getProduct();
$isProductBundle = ($product->getTypeId() == 'bundle');
$items_to_add = array();
$oTypeInstance = $oProduct->getTypeInstance(true);
$aSelections = $oTypeInstance->getSelectionsCollection($aOptionIds, $product );
$aOptions = $oTypeInstance->getOptionsByIds($aOptionIds, $product);
$bundleOptions = $aOptions->appendSelections($aSelections, true);
foreach ($bundleOptions as $bundleOption) {
if ($bundleOption->getSelections()) {
$bundleSelections = $bundleOption->getSelections();
foreach ($bundleSelections as $bundleSelection) {
$items_to_add[] = $bundleSelection.getID();
}
}
}
insertExtractedProducts($items_to_add);
}
/**
* Add extracted products into quote
*
* #param array $items_to_add
*/
public function insertExtractedProducts($items_to_add){
/**#var $cart Mage_Checkout_Model_Cart**/
$cart = Mage::helper('checkout/cart')->getCart();
$ids_to_add = array();
foreach($items_to_add as $item_to_be_added){
$ids_to_add[] = $item_to_be_added->getProductId();
}
$cart->addProductsByIDs($ids_to_add);
$cart->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
}
}
Just a simple sample, but it might help.
Bundled products can be complicated to understand, when working with it via code:
Here is a sample image:
Each Bundled product, have one to many options, which in the end will be links to products to be added to the bundle in the Shopping Cart.
Each Option consists of one to many Selections, which will be the linked products that will end up in the Shopping cart, under this bundled product. One Selection, can typically be set as the default, and will already be selected on the product page. More information can be found at this link on how to create and configure bundled products, because in this document, we will only discuss the programming side of it.
The bundled product’s display page, will look like this:
It could look like this in the shopping cart, once you clicked on “Add to Cart”:
Bundle Sample
Sample Shampoo
1 x Moisturiser-125ml $29.95
Default Conditioner
1 x Moisturiser-60g $99.95
When interrogating this product through code, you load it like any normal product:
$oProduct->load($vProductId);
Once it is loaded, you need to get a product type instance, so that you can load the options for this product type.
$oTypeInstance = $oProduct->getTypeInstance(true);
Now we can get the list of option ID’s for this product in this manner:
$oTypeInstance = $oProduct->getTypeInstance(true);
To interrogate the Selections, we will add the list of options to a collection, then get the Options collection, as well as their respective Selections:
$aSelections = $oTypeInstance->getSelectionsCollection($aOptionIds, $oProduct );
$aOptions = $oTypeInstance->getOptionsByIds($aOptionIds, $oProduct);
$bundleOptions = $aOptions->appendSelections($aSelections, true);
Now we have a Collection of Options, and each Option will have a collection of Selections. We can now loop through the options, and look at their Selctions.
foreach ($bundleOptions as $bundleOption) {
if ($bundleOption->getSelections()) {
$bundleSelections = $bundleOption->getSelections();
foreach ($bundleSelections as $bundleSelection) {
// get some data here
$vName = $bundleOption->getTitle();
}
}
}
To get a list of the Required Selection Products for the Bundled product, you can use the following code:
$requiredChildren = $this->getChildrenIds($product->getId(),$required=true);
You can then loop through the array of ID’s and load the products by their ID’s to get more information regarding those products.
Bundled products in the shopping cart
In order to loop through the selected options of a Bundled product in the shopping card, you can use something like this:
/**
* #var Mage_Bundle_Model_Product_Type
*/
$typeInstance = $this->getProduct()->getTypeInstance(true);
// get bundle options
$optionsQuoteItemOption = $this->getItem()->getOptionByCode('bundle_option_ids');
$bundleOptionsIds = unserialize($optionsQuoteItemOption->getValue());
if ($bundleOptionsIds) {
/**
* #var Mage_Bundle_Model_Mysql4_Option_Collection
*/
$optionsCollection = $typeInstance->getOptionsByIds($bundleOptionsIds, $this->getProduct());
// get and add bundle selections collection
$selectionsQuoteItemOption = $this->getItem()->getOptionByCode('bundle_selection_ids');
$selectionsCollection = $typeInstance->getSelectionsByIds(
unserialize($selectionsQuoteItemOption->getValue()),
$this->getProduct()
);
$bundleOptions = $optionsCollection->appendSelections($selectionsCollection, true);
foreach ($bundleOptions as $bundleOption) {
if ($bundleOption->getSelections()) {
$label = $bundleOption->getTitle()
$bundleSelections = $bundleOption->getSelections();
foreach ($bundleSelections as $bundleSelection) {
$sName = $bundleSelection->getName();
}
// some more code here to do stuff
}
}
}
This code gets the Options from the Quote Item Bundled Product, and then gets the Options for that product in a collection, and then finds the “Selected” Option Selection.
hth,
Shaun
Here's how you can do this in Magento 2.3 via an "around" plugin (interceptor) for the Magento\Checkout\Model\Cart->addProduct() method.
The addProduct() method is called when the customer adds a product to the cart. By adding code to this method via a plugin, you can alter the way the bundle product is added to the cart.
Define the plugin in Vendor/Module/etc/frontend/di.xml:
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="\Magento\Checkout\Model\Cart">
<plugin name="add-bundle-products-separate" type="Vendor\Module\Plugin\Checkout\Model\CartPlugin" sortOrder="1"/>
</type>
</config>
This is what tells Magento a plugin exists for this particular method.
Reference:
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html
Create the plugin's class.
In Vendor/Module/Plugin/Checkout/Model/CartPlugin.php:
<?php
namespace Vendor\Module\Plugin\Checkout\Model;
use \Magento\Catalog\Model\Product;
use \Magento\Framework\DataObject;
use \Magento\Checkout\Model\Cart;
/**
* Class CartPlugin
*
* #package Ppwd\CrossSell\Plugin\Checkout\Model
*
*/
class CartPlugin {
/**
* #param Cart $subject
* #param \Closure $proceed
* #param Product $productInfo
* #param DataObject|int|array $requestInfo
* #return Cart $subject
* #SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function aroundAddProduct(
$subject,
$proceed,
$productInfo,
$requestInfo = null
) {
// Detect if we are adding a bundle product to cart
if (!is_numeric($productInfo) && $productInfo->getTypeId() == 'bundle') {
$buyRequest = new DataObject($requestInfo);
// List of products selected as part of the bundle
$cartCandidates = $productInfo->getTypeInstance()->prepareForCartAdvanced($buyRequest, $productInfo);
$productIds = [];
// Add each item in bundle as if it were separately added to cart
/** #var Product $cartCandidate */
foreach ($cartCandidates as $cartCandidate) {
if ($cartCandidate->getTypeId() != 'bundle') {
for ($i = 0; $i < $cartCandidate->getCartQty(); $i++) {
$productIds[] = $cartCandidate->getId();
}
}
}
$subject->addProductsByIds($productIds);
return $subject;
}
// Return original result from addProduct() as if plugin didn't exist
$result = $proceed($productInfo, $requestInfo);
return $result;
}
}
When done, if you add the bundle to the cart the line items will appear separately instead of grouped together like a bundle product normally is.
I did this to solve the customer request to add bundle content as separate items in the cart. Just replace
$cart->addProduct($product, $params)
with
if ($product->getTypeId() == 'bundle') {
$request = new Varien_Object($params);
$cartCandidates = $product->getTypeInstance(true)->prepareForCartAdvanced($request, $product, Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_FULL);
$idstoadd = array();
foreach ($cartCandidates as $cartCandidate) {
if ($cartCandidate->getTypeId() == 'simple') {
for ($i = 0; $i < $cartCandidate->getCartQty(); $i++) {
$idstoadd[] = $cartCandidate->getId();
}
}
}
$cart->addProductsByIds($idstoadd);
} else {
$cart->addProduct($product, $params);
}
in the file cartController.
I have created a custom tab in admin which I need to manage customer attributes.
I would like to load all customer attributes in that section and keep a check box against each attribute.
Such that when ever a check box is checked or unchecked, based on the selection, the columns will be displayed/hidden in Manage Customer Grid.
I would like to know how do I get to display all customer attributes in that section with a checkbox each?
You can use getAttributes() which returns an array of Mage_Eav_Model_Entity_Attribute.
<?php
$attributes = Mage::getModel('customer/customer')->getAttributes();
foreach ($attributes as $attr) :
?>
<input type="checkbox" name="attributes[]" value="<?php echo $attr->getId() ?>" id="attribute-<?php echo $attr->getId() ?>" />
<label for="attribute-<?php echo $attr->getId() ?>"><?php echo $attr->getStoreLabel() ?></label>
<?php endforeach; ?>
Much improved technique for config:
First we need to create a source model in your module, in the following you obviously have to rename it to match your actual module.
class Your_Module_Model_Source_Customer_Attribute
{
public function toOptionArray()
{
$attributes = Mage::getModel('customer/entity_attribute_collection')
// remove filter to allow default address ID, etc.
->addVisibleFilter();
$result = array();
foreach ($attributes as $attribute) {
if (($label = $attribute->getFrontendLabel()))
$result[$attribute->getId()] = $label;
}
return $result;
}
}
Then we need a single new field in your module's system.xml.
<fieldname translate="label">
<label>Customer Attributes</label>
<frontend_type>checkboxes</frontend_type>
<source_model>yourmodule/source_customer_attribute</source_model>
<show_in_default>1</show_in_default>
</fieldname>
This works surprisingly well, surprising because these classes are not used in the core. Instead of checkboxes the type can also be radios, that works too.
Figured it out!
That's the final code. Obviously BIG thanks to you for your help with the code at the first place.
$attributes = Mage::getModel('customer/entity_address_attribute_collection');
$result = array();
foreach ($attributes as $attribute)
{
if (($label = $attribute->getFrontendLabel()))
$result[$attribute->getId()] = $label;
}
$attributes1 = Mage::getModel('customer/entity_attribute_collection');
$result1 = array();
foreach ($attributes1 as $attribute1)
{
if (($label1 = $attribute1->getFrontendLabel()))
$result1[$attribute1->getId()] = $label1;
}
$final = array_merge($result, $result1);
return $final;
I know that in Magento 1.4.2.0 one gets parent id's like so
list( $parentId ) = Mage::getModel('catalog/product_type_configurable')
->getParentIdsByChild( $product->getId() );
My question is: if I don't know what the parent is, how do I know to use the 'catalog/product_type_configurable' vs 'catalog/product_type_grouped' model to get the id?
You can just call both and offer a fall-back as it should be one or the other:
if($product->getTypeId() == "simple"){
$parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
if(!$parentIds)
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
if(isset($parentIds[0])){
$parent = Mage::getModel('catalog/product')->load($parentIds[0]);
// do stuff here
}
}
You may use:
$product->getTypeInstance();
Which will return the type object of your product
Then you can perform your:
->getParentIdsByChild()
Giving finally:
$product->getTypeInstance()->getParentIdsByChild($child->getId());
Here is another solution for magento 1.7.2
$parentIds = Mage::getSingleton('catalog/product_type_configurable')->getParentIdsByChild($mageProduct->getId());
we can use in block file,magento 2,
protected $_catalogProductTypeConfigurable;
public function __construct(
\Magento\Catalog\Block\Product\Context $context,
//for getting parent id of simple
\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable $catalogProductTypeConfigurable,
array $data = []
) {
//for getting parent id of simple
$this->_catalogProductTypeConfigurable = $catalogProductTypeConfigurable;
parent::__construct($context, $data);
}
public function getProductData($id){
$parentByChild = $this->_catalogProductTypeConfigurable->getParentIdsByChild($id);
if(isset($parentByChild[0])){
//set id as parent product id...
$id = $parentByChild[0];
}
return $id;
}
You could check the type of the product with $_product->getTypeId(); and if this returns 'configurable', take the configurable model and if it returns 'grouped' take the grouped model.
Hope this helps.