create attribute set in Magento setup script - php

Creating attributes and assigning them to existing attribute sets is a solved problem but we are running into an issue trying to create an attribute set and populate it with default and specific attributes is failing. This is the code in use:
$setup->addAttributeSet('catalog_product', 'women_sizing_denim');
$oAttributeSetModel = Mage::getModel("eav/entity_attribute_set")
->load($setup->getAttributeSetId('catalog_product', 'women_sizing_denim'))
->initFromSkeleton($setup->getAttributeSetId('catalog_product', 'default'))
->save();
I can verify by debugging through that the initfromSkeleton method does load the attributes from the default attribute_set as advertised, however after the save(), the new set is empty.
Adding new attributes to the set is possible, so it does exist and is created correctly, but the missing default attributes make it unusable since SKU, price, name, etc are all required.

I remember that the issue with creating attribute sets based on the default attribute set was, that you need to save the attribute set twice, once before calling initSkeleton() and once after it.
I don't remember the exact reason anymore, it's too long ago. Anyway, here's what worked for me:
// Mage_Eav_Model_Entity_Setup
$oEntitySetup = $this;
$oEntitySetup->startSetup();
$sNewSetName = 'myset';
$iCatalogProductEntityTypeId = (int) $oEntitySetup->getEntityTypeId('catalog_product');
$oAttributeset = Mage::getModel('eav/entity_attribute_set')
->setEntityTypeId($iCatalogProductEntityTypeId)
->setAttributeSetName($sNewSetName);
if ($oAttributeset->validate()) {
$oAttributeset
->save()
->initFromSkeleton($iCatalogProductEntityTypeId)
->save();
}
else {
die('Attributeset with name ' . $sNewSetName . ' already exists.');
}
$oEntitySetup->endSetup();

Please notice that setup class needs to extend
Mage_Catalog_Model_Resource_Eav_Mysql4_Setup
so that
$oEntitySetup->getEntityTypeId('catalog_product');
can be called.

I used Jürgen Thelen answer which worked.
But I found the new attribute set did not have default options and options group such as general and invoice etc.
So to get round this include $installer->getAttributeSetId('catalog_product', 'default') in the initFromSkeleton()
if($attributeSet->validate()) {
$attributeSet
->save()
->initFromSkeleton($installer->getAttributeSetId('catalog_product', 'default'))
->save();
} else {
die('Attributeset with name ' . $setName . ' already exists.');
}

Related

Magento duplicate attriubte set new attributes not showing in front end

Duplicated attriubte set for new product line.
Attributes set show in backend and front end.
Created new attribute and added to attribute set.
New attribute show's in back end but not front end.
If I add the new attribute to the origonal set that was duplicated the new attribute will now show on the front end for the product assoiated with the duplicated attribute group.
So basicly A new attribute added to a duplicate set won't show on the front end until its added to the attribute set that was duplicated.
I've checked to make sure the attribute is visable on front end etc and tried it several times checking the settings.
The goal is to be able to duplicate a attribute set and add new attributes for different product types. Then call the folder by id and display the assoiated attributes.
I've called the attribute group by ID (spec's). This code is working.
<?php
require_once 'app/Mage.php';
Mage::app();
$attributeGroupCollection = Mage::getResourceModel('eav/entity_attribute_group_collection');
$product = $this->getProduct();
foreach ($attributeGroupCollection as $attributeGroup) {
$attributeGroup->getAttributeGroupId();
$attributeSpecs = Mage::getResourceModel('eav/entity_attribute_collection')
->setAttributeGroupFilter(41);
}
?>
Help is appreciated, thanks
Duplicating an attribute set is duplicating at a time (the moment when you click the button). If you want to add an attribute in both attribute sets, you need to create it in both, for that, you just need to create your attribute and drop it in the section you want to have it linked to (what you call "folder"). If you want to do it programmatically. You need to create an observer that will be fired after the attribute set is saved and that will add the attribute to the duplicated attribute set. I would not advise to do so because it means that you need to enter the ID of the attribute set duplicated and it can be tricky thing when it comes to pushing the development to the production. I am sure there is a workaround for what you want to achieve.
The problem was is magento creates a new id for each new group folder in the new duplicated attribute set (makes sense). I was calling by ID for the group and as a result will only show attributes in the origional folder (weird) even if the product was assoicated with the new attribute set. What I did was get the current attribute set id and then sort out the attribute groups by name so even if the attribute sets are coppied as long as the folde has the name it will display in the custom loop displaying the attributes. Here is my working code:
$attributeSetModel = Mage::getModel("eav/entity_attribute_set");
$attributeSetModel->load($product->getAttributeSetId());
$attributeSetName = $attributeSetModel->getAttributeSetName();
$attributeSetID = $attributeSetModel->getAttributeSetID();
$groups = Mage::getModel('eav/entity_attribute_group')
->getResourceCollection()
->setAttributeSetFilter($attributeSetID)
->setSortOrder()
->load();
$attributeCodes = array();
foreach ($groups as $group) {
echo $groupName = $group->getAttributeGroupName();
$groupId = $group->getAttributeGroupId();
if (strpos($groupName , 'Specifications') !== false) {
echo 'true';
$specificationsNum = $groupId;
};
if (strpos($groupName , 'eatures') !== false) {
echo 'true';
$prodfeaturesNum = $groupId;
};
}
//echo $specifications;
$specifications = Mage::getResourceModel('eav/entity_attribute_collection')
->setAttributeGroupFilter($specificationsNum);
$prodfeatures = Mage::getResourceModel('eav/entity_attribute_collection')
->setAttributeGroupFilter($prodfeatures);

What does isDirty() mean in Laravel?

First of all, I am not familiar with Laravel so much (or with the term "dirty" for that matter).
I stumbled upon this line of code -
if ($this->isDirty('status')) {
if (Notification::has('website-status-' . strtolower($this->status))) {
Notification::set($this->account, 'website-status-' . strtolower($this->status), $this->emailAttributes())
->email();
}
}
And I couldn't understand what that means exactly. I tried to find out on the internet but the Laravel site only says this
"Determine if a given attribute is dirty"
which doesn't really help...
When you want to know if the model has been edited since it was queried from the database, or isn't saved at all, then you use the ->isDirty() function.
The isDirty method determines if any attributes have been changed since the model was loaded. You may pass a specific attribute name to determine if a particular attribute is dirty.
$user = User::create([
'first_name' => 'Amir',
'last_name' => 'Kaftari',
'title' => 'Developer',
]);
$user->title = 'Jafar';
$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false
Eloquent provides the isDirty, isClean, and wasChanged methods to examine the internal state of your model and determine how its attributes have changed from when they were originally loaded.
You can find complete description and examples of these three methods here in the official document:
https://laravel.com/docs/9.x/eloquent#examining-attribute-changes
As support for the accepted answer:
$model = Model::find(1);
$model->first_column = $request->first_value;
$model->second_column = $request->second_value;
$model->third_column = $request->third_value;
if($model->isDirty()){
// the model has been edited, else codes here will not be executed
}
$model->save();

setting persistent plugin parameters in Joomla 3

I'm developing a Joomla 3.x plugin, and want to be able to change the plugin parameter set in the plugin's manifest file programmatically. I believe I need to use a JRegistry object, but I'm not sure about the syntax.
Here's the issue:
// token A is set in plugin params as defined in plugin's XML manifest
var_dump($this->params->get('token')); // prints token "A" as expected
// do some stuff to get a fresh access token, called token "B"
$tokenB = $function_to_get_fresh_token();
// set the new token
if ($tokenB) $this->params->set('token', $tokenB);
var_dump($this->params->get('apptoken')); // prints token "B" as expected
the problem is that on subsequent page reloads, the token reverts to tokenA rather than what I assumed would be the stored value of tokenB.
How do I store the tokenB value in the plugin's parameters in the database?
This is a working example of how to change plugin params from within the plugin (J! 3.4):
// Load plugin called 'plugin_name'
$table = new JTableExtension(JFactory::getDbo());
$table->load(array('element' => 'plugin_name'));
// Params can be changed like this
$this->params->set('new_param', 'new value'); // if you are doing change from a plugin
$table->set('params', $this->params->toString());
// Save the change
$table->store();
Note: If new params are added by plugin dynamically and the plugin is saved afterwards, these new params gets deleted. So one way to deal with it is to add those params as hidden fields to plugin's config XML.
This is just an outline, but something along these lines
$extensionTable = new JtableExtension();
$pluginId = $extensionTable->find('element', 'my_plugin');
$pluginRow = $extensionTable->load($pluginId);
// Do the jregistry work that is needed
// do some stuff to get a fresh access token, called token "B"
$tokenB = $function_to_get_fresh_token();
// set the new token
if ($tokenB) $this->params->set('token', $tokenB);
// more stuff
$extensionTable->save($pluginRow);
I spent a lot of time googling and reading and found no real answer to this. Oddly enough this doesn't seem to have been provided for in Joomla. So here's what I ended up doing:
1) build a function to get your plugin ID, since it will change from one installation to another
private function getPlgId(){
// stupid hack since there doesn't seem to be another way to get plugin id
$db = JFactory::getDBO();
$sql = 'SELECT `extension_id` FROM `#__extensions` WHERE `element` = "my_plugin" AND `folder` = "my_plugin_folder"'; // check the #__extensions table if you don't know your element / folder
$db->setQuery($sql);
if( !($plg = $db->loadObject()) ){
return false;
} else {
return (int) $plg->extension_id;
}
}
2) use the plugin id to load the table object:
$extension = new JTableExtension($db);
$ext_id = $this->getPlgId();
// get the existing extension data
$extension->load($ext_id);
3) when you're ready to store the value, add it to the params, then store it:
$this->params->set('myvalue', $newvalue);
$extension->bind( array('params' => $this->params->toString()) );
// check and store
if (!$extension->check()) {
$this->setError($extension->getError());
return false;
}
if (!$extension->store()) {
$this->setError($extension->getError());
return false;
}
If anyone knows a better way to do this please let me know!

Get product atribute value in magento

Hi i have got the maximum elements of products using below code but it doesn't show the size attribute of my product, the size attribute is visible on front-end but i cant understand why it is not printing with this code
<?php
ob_start();
session_start();
ini_set('display_errors', 1);
//for order update
include '../../../../app/Mage.php';
Mage::app('default');
echo '<pre>';
if(isset($_REQUEST['productid'])){
$productId = $_REQUEST['productid'];
}else{
$productId = '12402'; // product ID 10 is an actual product, and used here for a test
}
$product = Mage::getModel('catalog/product')->load($productId); //load the product
//$product_id = $product->getId();
//$created_at = $product->getcreated_at();
//$description = $product->getdescription();
//$short_description = $product->getshort_description();
//$sku = $product->getsku();
//$size_fit = $product->getsize_fit();
//$style_ideas = $product->getstyle_ideas();
//$name = $product->getname();
//$price = $product->getprice();
//$stocklevel = (int)Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty();
If its the size_fit attribute (i'm guessing that because its the only size attempt in your code..) use $product->getSizeFit(). For just size use $product->getSize(). When this is not returning anything, please post the attribute installer if you have one. Mufadall his answer is also correct but judging your code you are just using wrong syntax.
Basicly according to the magic get method the first letter is turned into a capital and all other letters after an underscore.
Ex.: To fetch my_sample_attribute use getMySampleAttribute().
getData('my_sample_attribute') would also be an option but you shouldn't make a habbit of doing that because in some cases, for some attributes getData('attribute') returns a different value then getAttribute()....
$product->getData($attribute_code);
will return you the actual attribute value. For attribute with type dropdown it will return option id
$product->getResource()->getAttribute($attribute_code)->getFrontend()->getValue($product);
will return actual value
You can use this:
$product->getData('Your Attribute ID');
Go to Size attribute and check for Drop Down used in product listing if it set to No then set it to Yes, after that you can get your size attribute with other product attribute
You can use the getters, or getData();
The getter is set in magento with the magic __get() method, and you can use it in the following way:
$product->getDescription() // ( to get description attribute)
$product->getShortDescription() // (to get short_description attribute)
So basically you explode the attribute with underscores, and capitalize the words, and you will get what you need to put after "get".
Here is something very useful I use all the time
Zend_Debug::dump($product->getData());
This gets you all the data you have to work with. If you are missing data, it means it's not loaded.
Good luck!

Add attributeSet but based on an existing set - Magento

Ok, its possible to add a new attribute set in magento using something like the following:
$entitySetup = new Mage_Eav_Model_Entity_Setup;
$entitySetup->addAttributeSet('catalog_product', $setName);
But how can i base the set on an existing set like the default. This option is available in the admin section so its possible.
I did this 6 months ago, I do not have the code anymore, but I know you have to use the initFromSkeleton() method on your attribute set. You can search Magento's code for calls to this function, there are very few calls (just one perhaps). It will show you its usage.
EDIT: I remember I had the very same problem you are talking about, and I mailed about it. Here is the usage I was advised:
$attrSet = Mage::getModel('eav/entity_attribute_set');
$attrSet->setAttributeSetName('MyAttributeSet');
$attrSet->setEntityTypeId(4);//You can look into the db what '4' corresponds to, I think it is for products.
$attrSet->initFromSkeleton($attrSetId);
$attrSet->save();
The initialization is done before the save.
// create attribute set
$entityTypeId = Mage::getModel('eav/entity')
->setType('catalog_product')
->getTypeId(); // 4 - Default
$newSet = Mage::getModel('eav/entity_attribute_set');
$newSet->setEntityTypeId($entityTypeId);
$newSet->setAttributeSetName(self::ATTRIBUTE_SET_NAME);
$newSet->save();
$newSet->initFromSkeleton($entityTypeId);
$newSet->save();
This is what worked for me.
$i_duplicate_attribut_set_id = 10; // ID of Attribut-Set you want to duplicate
$object = new Mage_Catalog_Model_Product_Attribute_Set_Api();
$object->create('YOUR_ATTRIBUT_SET_NAME', $i_duplicate_attribut_set_id);
Alex
Here you can find useful information about working with attribute sets.
Here:
$entityTypeId = Mage::getModel('eav/entity')
->setType('catalog_product') // This can be any eav_entity_type code
->getTypeId();
$attrSet = Mage::getModel('eav/entity_attribute_set');
$attrSetCollection = $attrSet->getCollection();
$attrSetCollection
->addFieldToFilter('entity_type_id', array('eq' => $entityTypeId))
->addFieldToFilter('attribute_set_name', array('eq' => 'Default')); // This can be any attribute set you might want to clone
$defaultAttrSet = $attrSetCollection->getFirstItem();
$defaultAttrSetId = $defaultAttrSet->getAttributeSetId();
$attrSet->setAttributeSetName('Assinaturas'); // This is the new attribute set name
$attrSet->setEntityTypeId($entityTypeId);
$attrSet->initFromSkeleton($defaultAttrSetId);
$attrSet->save();

Categories