How Magento2 add attribute option programmatically (not in setup)
I try to add options for size and color attributes in my importer modul but I don't how...:
private function addOption($attributeCode, $value)
{
$ob = $this->_objectManager;
/* @var $m MagentoEavModelEntityAttributeOptionManagement */
$m = $this->optionManagement;
/* @var $option MagentoEavModelEntityAttributeOption */
$option = $this->attributeOption;
$option->setLabel($value);
$option->setValue($value);
$m->add(MagentoCatalogApiDataProductAttributeInterface::ENTITY_TYPE_CODE,
$attributeCode,
$option);
This report an error (I modified exception reporting on OptionMaganger.php
to Exception->message)
Cannot save attribute size Notice: Undefined index: delete in /var/www/html/magento2/vendor/magento/module-swatches/Model/Plugin/EavAttribute.php on line 177
- The OptionManagement and Option come from
_contstructor
- With OptionManagement I can retrieve the existing items, so should be ok..
setLabel()
and setValue()
are default, but I tried setData, load option instance and pass by OptionManagement->getItems
to add(...) "again",
but error still exists...
Any idea, how can I append EAV Options (swatches?) during the import process? (not in modul setup)
Update :
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way :)
magento2 attributes
add a comment |
I try to add options for size and color attributes in my importer modul but I don't how...:
private function addOption($attributeCode, $value)
{
$ob = $this->_objectManager;
/* @var $m MagentoEavModelEntityAttributeOptionManagement */
$m = $this->optionManagement;
/* @var $option MagentoEavModelEntityAttributeOption */
$option = $this->attributeOption;
$option->setLabel($value);
$option->setValue($value);
$m->add(MagentoCatalogApiDataProductAttributeInterface::ENTITY_TYPE_CODE,
$attributeCode,
$option);
This report an error (I modified exception reporting on OptionMaganger.php
to Exception->message)
Cannot save attribute size Notice: Undefined index: delete in /var/www/html/magento2/vendor/magento/module-swatches/Model/Plugin/EavAttribute.php on line 177
- The OptionManagement and Option come from
_contstructor
- With OptionManagement I can retrieve the existing items, so should be ok..
setLabel()
and setValue()
are default, but I tried setData, load option instance and pass by OptionManagement->getItems
to add(...) "again",
but error still exists...
Any idea, how can I append EAV Options (swatches?) during the import process? (not in modul setup)
Update :
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way :)
magento2 attributes
option added any value as string not supported for integer
– Ajay Patel
Nov 22 '17 at 3:38
add a comment |
I try to add options for size and color attributes in my importer modul but I don't how...:
private function addOption($attributeCode, $value)
{
$ob = $this->_objectManager;
/* @var $m MagentoEavModelEntityAttributeOptionManagement */
$m = $this->optionManagement;
/* @var $option MagentoEavModelEntityAttributeOption */
$option = $this->attributeOption;
$option->setLabel($value);
$option->setValue($value);
$m->add(MagentoCatalogApiDataProductAttributeInterface::ENTITY_TYPE_CODE,
$attributeCode,
$option);
This report an error (I modified exception reporting on OptionMaganger.php
to Exception->message)
Cannot save attribute size Notice: Undefined index: delete in /var/www/html/magento2/vendor/magento/module-swatches/Model/Plugin/EavAttribute.php on line 177
- The OptionManagement and Option come from
_contstructor
- With OptionManagement I can retrieve the existing items, so should be ok..
setLabel()
and setValue()
are default, but I tried setData, load option instance and pass by OptionManagement->getItems
to add(...) "again",
but error still exists...
Any idea, how can I append EAV Options (swatches?) during the import process? (not in modul setup)
Update :
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way :)
magento2 attributes
I try to add options for size and color attributes in my importer modul but I don't how...:
private function addOption($attributeCode, $value)
{
$ob = $this->_objectManager;
/* @var $m MagentoEavModelEntityAttributeOptionManagement */
$m = $this->optionManagement;
/* @var $option MagentoEavModelEntityAttributeOption */
$option = $this->attributeOption;
$option->setLabel($value);
$option->setValue($value);
$m->add(MagentoCatalogApiDataProductAttributeInterface::ENTITY_TYPE_CODE,
$attributeCode,
$option);
This report an error (I modified exception reporting on OptionMaganger.php
to Exception->message)
Cannot save attribute size Notice: Undefined index: delete in /var/www/html/magento2/vendor/magento/module-swatches/Model/Plugin/EavAttribute.php on line 177
- The OptionManagement and Option come from
_contstructor
- With OptionManagement I can retrieve the existing items, so should be ok..
setLabel()
and setValue()
are default, but I tried setData, load option instance and pass by OptionManagement->getItems
to add(...) "again",
but error still exists...
Any idea, how can I append EAV Options (swatches?) during the import process? (not in modul setup)
Update :
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way :)
magento2 attributes
magento2 attributes
edited Dec 8 '16 at 12:46
Ronak Chauhan
4,12511448
4,12511448
asked Dec 27 '15 at 20:51
InterpigeonInterpigeon
8116
8116
option added any value as string not supported for integer
– Ajay Patel
Nov 22 '17 at 3:38
add a comment |
option added any value as string not supported for integer
– Ajay Patel
Nov 22 '17 at 3:38
option added any value as string not supported for integer
– Ajay Patel
Nov 22 '17 at 3:38
option added any value as string not supported for integer
– Ajay Patel
Nov 22 '17 at 3:38
add a comment |
6 Answers
6
active
oldest
votes
use MagentoEavSetupEavSetupFactory;
use MagentoStoreModelStoreManagerInterface;
declare:
protected $_eavSetupFactory;
constructor :
public function __construct(
MagentoEavSetupEavSetupFactory $eavSetupFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoCatalogModelResourceModelEavAttribute $attributeFactory,
MagentoFrameworkObjectManagerInterface $objectmanager,
ModuleDataSetupInterface $setup,
MagentoCatalogModelProductFactory $productloader
) {
$this->_eavSetupFactory = $eavSetupFactory;
$this->_storeManager = $storeManager;
$this->_attributeFactory = $attributeFactory;
$this->_objectManager = $objectmanager;
$this->setup = $setup;
$this->_productloader = $productloader;
}
execute methode :
public function execute(EventObserver $observer)
{
/** @var $brand KtplBrandModelBrand */
$brand = $observer->getEvent()->getBrand();
$option_id = "";
$data = ;
$attribute_arr = [$brand['brand_id'] => $brand['brand_title']];
$optionTable = $this->setup->getTable('eav_attribute_option');
$attributeInfo=$this->_attributeFactory->getCollection()
->addFieldToFilter('attribute_code',['eq'=>"shop_by_brand"])
->getFirstItem();
$attribute_id = $attributeInfo->getAttributeId();
$eavAttribute = $this->_objectManager->create('MagentoEavModelConfig');
$option=array();
$option['attribute_id'] = $attributeInfo->getAttributeId();
$option['value'] = array(0=>array()); // 0 means "new option_id", other values like "14" means "update option_id=14" - this array index is casted to integer
$storeManager = $this->_objectManager->get('MagentoStoreModelStoreManagerInterface');
$stores = $storeManager->getStores();
$storeArray[0] = "All Store Views";
foreach ($stores as $store) {
$storeArray[$store->getId()] = $store->getName();
}
if (empty($brand['optionId'])) {
foreach($attribute_arr as $key => $value){
$option['value'][0][0]=$value;
foreach($storeArray as $storeKey => $store){
$option['value'][0][$storeKey] = $value;
}
}
}
else
{
foreach($attribute_arr as $key => $value){
foreach($storeArray as $storeKey => $store){
$option['value'][$brand['optionId']][$storeKey] = $value;
}
}
}
$eavSetup = $this->_eavSetupFactory->create();
$eavSetup->addAttributeOption($option)
}
You have serious error in your code:$option['value'][$value][0] - it should not be $value but "option_id" - integer, for new one option set 0. This one is cast to integer, so if you have string with no numer, eg "black" it will be 0 correctly. But if your $value is something like "10 Black" it will cast to 10 and update database entity with option_id = 10 instead creating new one. This may cause serious mess in your shop database.
– A.Maksymiuk
Mar 15 '18 at 21:28
thanks to inform brother. If you found any error than you can update my answer @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 5:25
Did it. Please accept, then I'll revert my downvote.
– A.Maksymiuk
Mar 16 '18 at 8:41
Approved, but down-vote any answer is not the proper way bro, If you think that answer is not related or not as per asked then you can else don't down-vote anyone's answer. @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 9:12
I did it to warn anyone to use this code, because it would cause serious damage in data integrity. E.g. instead adding new option named "42" (size) your script updated option_id = 42 (which was existing option of completly different attribute). Luckily it happend to me on test server and fresh new database.
– A.Maksymiuk
Mar 16 '18 at 9:20
add a comment |
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way.
See my way. I believe it to be 'official'
– CarComp
Mar 31 '16 at 16:00
your solution is work but only when option are option not work for integer
– Ajay Patel
Nov 21 '17 at 14:05
add a comment |
Seems to be a validation issue.
The delete key in data comes from the form in the backend, so try to add an empty delete key that way:
$option->setData('delete','');
It could works.
Sadly no. The OptionManager add(..) reparse the $option parameter and leave the 'delete' key empty, I don't no why... But I found another way....
– Interpigeon
Jan 2 '16 at 15:50
Great, please add your solution as an answer to resolve the question.
– MauroNigrele
Jan 2 '16 at 15:59
I can't answer my own question, but i updated the question. I think my solution is a workaround...
– Interpigeon
Jan 2 '16 at 16:14
Hey, you can answer your question is pretty common.
– MauroNigrele
Jan 2 '16 at 16:16
add a comment |
I ended up rewriting this entire answer using ObjectFactory methods suggested by Ryan H.
It ended up being a Helper Class that utilized some attributes I created on the customer object, but the idea is there on how to utilize EAV + ObjectFactories to manipulate attribute options
<?php
namespace SttiHealthdayHelper {
use MagentoEavModelEntityAttributeFactory;
use MagentoEavModelEntityAttributeOptionFactory;
use MagentoEavModelEntityAttributeOptionManagementFactory;
use MagentoFrameworkAppHelperAbstractHelper;
use MagentoFrameworkAppHelperContext;
use MagentoEavModelEntityAttribute;
use SttiHealthdayModelRelationFactory;
/**
* Eav data helper
*/
class Data extends AbstractHelper {
protected $optionFactory;
protected $attributeFactory;
protected $relationFactory;
protected $optionManagementFactory;
public function __construct(Context $context, AttributeFactory $attributeFactory, OptionFactory $optionFactory,
RelationFactory $relationFactory,
OptionManagementFactory $optionManagementFactory) {
$this->optionFactory = $optionFactory;
$this->attributeFactory = $attributeFactory;
$this->optionFactory = $optionFactory;
$this->relationFactory = $relationFactory;
$this->optionManagementFactory = $optionManagementFactory;
parent::__construct($context);
}
public function addRelationsHelper($answerJson, $attributeCode) {
// IMPORTANT: READ THIS OR THE CODE BELOW WONT MAKE SENSE!!!!
// Since magento's attribute option model was never meant to
// hold guids, we'll be saving the guid as the label. An option_id will
// get created, which can then be saved to the relationship table. Then
// the label in the attribute_option table can be changed to the actual 'word'
// by looking up all of the options, matching on the guid, and doing a replace.
// At that point, there will be a 1:1 relation between guid, option_id, and the 'word'
// Get the attribute requested
$attribute = $this->attributeFactory->create();
$attribute = $attribute->loadByCode("customer", $attributeCode);
$answers = json_decode($answerJson, true);
// Prepare vars
//$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$prekeys = array();
$prevalues = array();
foreach ($answers as $answer) {
$prekeys = $answer['Key'];
$prevalues = $answer['Value'];
}
// load up all relations
// generate an array of matching indexes so we can remove
// them from the array to process
$collection = $this->relationFactory->create()->getCollection();
$removalIds = array();
foreach ($collection as $relation) {
// if the item is already in the magento relations,
// don't attempt to add it to the attribute options
for($cnt = 0; $cnt < sizeof($answers); $cnt++) {
if ($relation['stti_guid'] == $prekeys[$cnt]) {
$removalIds = $cnt;
}
}
}
// Remove the values from the arrays we are going to process
foreach($removalIds as $removalId) {
unset($prekeys[$removalId]);
unset($prevalues[$removalId]);
}
// "reindex" the arrays
$keys = array_values($prekeys);
$values = array_values($prevalues);
// prepare the array that will be sent into the attribute model to
// update its option values
$updates = array();
$updates['attribute_id'] = $attribute->getId();
// This section utilizes the DI generated OptionFactory and OptionManagementFactory
// to add the options to the customer attribute specified in the parameters.
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option = $this->optionFactory->create();
$option->setLabel($keys[$cnt]);
$this->optionManagementFactory->create()->add("customer", $attributeCode, $option);
}
// After save, pull all attribute options, compare to the 'keys' array
// and create healthday/relation models if needed
$relationIds = $attribute->getOptions();
$updatedAttributeCount = 0;
$options = array();
$options['value'] = array();
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option_id = 0;
foreach($relationIds as $relationId) {
if ($relationId->getLabel() == $keys[$cnt]) {
$option_id = $relationId['value'];
break;
}
}
if ($option_id > 0) {
// Create the healthday relation utilizing our custom models DI generated ObjectFactories
$relation = $this->relationFactory->create();
$relation->setAttributeId($attribute->getId());
$relation->setOptionId($option_id);
$relation->setSttiGuid($keys[$cnt]);
$relation->save();
// Rename the attribute option value to the 'word'
$options['value'][$option_id] = $values[$cnt];
$updatedAttributeCount++;
}
}
if ($updatedAttributeCount > 0) {
$attribute->setData('option', $options);
$attribute->save();
}
// Save the relationship to the guid
return $updatedAttributeCount;
}
}
}
1
You should be injecting ObjectFactory and create instances of Object from that, not injecting Object itself. ORM objects are not to be injected directly.
– Ryan Hoerr
Apr 1 '16 at 17:04
Which ObjectFactory? Theres like 50. I'm looking at MagentoFrameworkApiObjectFactory but it just looks like a wrapper for ObjectManager. I'm not sure why I wouldn't just implement the objectmanager itself. Theres SO many wrappers for wrappers of things in this new version.
– CarComp
Apr 8 '16 at 12:56
1
I was speaking in the abstract. Inject the Factory for your given object, not literally 'ObjectFactory'. You should inject the factory for each specific type you use, and create them as needed. Yes, it seems messy at first... but there are very good reasons for it. Beside, ECG code standards all but prohibit direct use of ObjectManager. See Alan Storm's article explaining the whole subject: alanstorm.com/magento_2_object_manager_instance_objects
– Ryan Hoerr
Apr 8 '16 at 13:05
What should I do when the objects I want to use do not have a factory? For instance, I can't find a way to 'factory' the options management stuff. MagentoEavModelAttributeFactory also uses a weird ->createAttribute(vars) instead of just ->create(). I'm just saying, when you don't work with a product, or a category built in stuff, things get a little weird.
– CarComp
Apr 8 '16 at 13:53
1
Not all objects will require a factory. For ones that do, the factory may not exist out-of-box -- any that don't exist will be created at runtime (with DI generation), or during compilation. Read the article I linked. Any way about it, you need to learn to work with Magento2, not against it. Yes, there is a learning curve. If you don't already, I strongly recommend picking up PhpStorm or a similar IDE.
– Ryan Hoerr
Apr 8 '16 at 14:03
|
show 1 more comment
UPDATE 2016-09-11: As quickshiftin pointed out, this solution does not work for M2.1+. Attempting to dependency-inject the CategorySetup
class outside of setup will give you a fatal error. See here for a more robust solution: https://magento.stackexchange.com/a/103951/1905
Use the MagentoCatalogSetupCategorySetup
class for this. It includes an addAttributeOption()
method, which works exactly the same way as eav/entity_setup::addAttributeOption()
in 1.x. There are some other attribute methods there that might be helpful as well.
You can use dependency injection to get this class at any time, even outside a setup process.
Specifically:
/**
* Constructor.
*
* @param MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository
* @param MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
*/
public function __construct(
MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository,
MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
) {
$this->attributeRepository = $attributeRepository;
$this->categorySetupFactory = $categorySetupFactory;
}
/**
* Create a matching attribute option
*
* @param string $attributeCode Attribute the option should exist in
* @param string $label Label to add
* @return void
*/
public function addOption($attributeCode, $label) {
$attribute = $this->attributeRepository->get($attributeCode);
$categorySetup = $this->categorySetupFactory->create();
$categorySetup->addAttributeOption(
[
'attribute_id' => $attribute->getAttributeId(),
'order' => [0],
'value' => [
[
0 => $label, // store_id => label
],
],
]
);
}
If desired, you could eliminate the attributeRepository
class and use getAttribute()
directly on categorySetup
. You'd just have to include the entity type ID each time.
Hi Ryan, I'm trying to use theCategorySetupFactory
to instantiate aCategorySetup
from aConsoleCommand
, however when I call$factory->setup()
a fatal error occurs:PHP Fatal error: Uncaught TypeError: Argument 1 passed to MagentoSetupModuleDataSetup::__construct() must be an instance of MagentoFrameworkModuleSetupContext, instance of MagentoFrameworkObjectManagerObjectManager given
– quickshiftin
Sep 10 '16 at 21:50
Ahh, I've now stumbled upon this thread in which you state this stopped working in Magento 2.1 (which I'm using). Revising my code now, but prob best to put a note on this answer to that effect as well...
– quickshiftin
Sep 10 '16 at 22:24
add a comment |
Magento 2 add Specific attribute option Value programmatically.
Run this Script in root directory of magento after url.
$objectManager = MagentoFrameworkAppObjectManager::getInstance(); // instance of object manager
try{
$entityType = 'catalog_product';
$attributeCode = 'manufacturer';
$attributeInfo = $objectManager->get(MagentoEavModelEntityAttribute::class)
->loadByCode($entityType, $attributeCode);
$attributeFactory = $objectManager->get('MagentoCatalogModelResourceModelEavAttribute');
$attributeId = $attributeInfo->getAttributeId();
//$manufacturer = $item->{'Manufacturer'};
$attribute_arr = ['aaa','bbb','ccc','ddd'];
$option = array();
$option['attribute_id'] = $attributeId;
foreach($attribute_arr as $key=>$value){
$option['value'][$value][0]=$value;
foreach($storeManager as $store){
$option['value'][$value][$store->getId()] = $value;
}
}
if ($option) {
$eavSetupFactory = $objectManager->create('MagentoEavSetupEavSetup');
print_r($eavSetupFactory->getAttributeOption());
die();
$eavSetupFactory->addAttributeOption($option);
}
}catch(Exception $e){
echo $e->getMessage();
}
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "479"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f95124%2fhow-magento2-add-attribute-option-programmatically-not-in-setup%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
use MagentoEavSetupEavSetupFactory;
use MagentoStoreModelStoreManagerInterface;
declare:
protected $_eavSetupFactory;
constructor :
public function __construct(
MagentoEavSetupEavSetupFactory $eavSetupFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoCatalogModelResourceModelEavAttribute $attributeFactory,
MagentoFrameworkObjectManagerInterface $objectmanager,
ModuleDataSetupInterface $setup,
MagentoCatalogModelProductFactory $productloader
) {
$this->_eavSetupFactory = $eavSetupFactory;
$this->_storeManager = $storeManager;
$this->_attributeFactory = $attributeFactory;
$this->_objectManager = $objectmanager;
$this->setup = $setup;
$this->_productloader = $productloader;
}
execute methode :
public function execute(EventObserver $observer)
{
/** @var $brand KtplBrandModelBrand */
$brand = $observer->getEvent()->getBrand();
$option_id = "";
$data = ;
$attribute_arr = [$brand['brand_id'] => $brand['brand_title']];
$optionTable = $this->setup->getTable('eav_attribute_option');
$attributeInfo=$this->_attributeFactory->getCollection()
->addFieldToFilter('attribute_code',['eq'=>"shop_by_brand"])
->getFirstItem();
$attribute_id = $attributeInfo->getAttributeId();
$eavAttribute = $this->_objectManager->create('MagentoEavModelConfig');
$option=array();
$option['attribute_id'] = $attributeInfo->getAttributeId();
$option['value'] = array(0=>array()); // 0 means "new option_id", other values like "14" means "update option_id=14" - this array index is casted to integer
$storeManager = $this->_objectManager->get('MagentoStoreModelStoreManagerInterface');
$stores = $storeManager->getStores();
$storeArray[0] = "All Store Views";
foreach ($stores as $store) {
$storeArray[$store->getId()] = $store->getName();
}
if (empty($brand['optionId'])) {
foreach($attribute_arr as $key => $value){
$option['value'][0][0]=$value;
foreach($storeArray as $storeKey => $store){
$option['value'][0][$storeKey] = $value;
}
}
}
else
{
foreach($attribute_arr as $key => $value){
foreach($storeArray as $storeKey => $store){
$option['value'][$brand['optionId']][$storeKey] = $value;
}
}
}
$eavSetup = $this->_eavSetupFactory->create();
$eavSetup->addAttributeOption($option)
}
You have serious error in your code:$option['value'][$value][0] - it should not be $value but "option_id" - integer, for new one option set 0. This one is cast to integer, so if you have string with no numer, eg "black" it will be 0 correctly. But if your $value is something like "10 Black" it will cast to 10 and update database entity with option_id = 10 instead creating new one. This may cause serious mess in your shop database.
– A.Maksymiuk
Mar 15 '18 at 21:28
thanks to inform brother. If you found any error than you can update my answer @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 5:25
Did it. Please accept, then I'll revert my downvote.
– A.Maksymiuk
Mar 16 '18 at 8:41
Approved, but down-vote any answer is not the proper way bro, If you think that answer is not related or not as per asked then you can else don't down-vote anyone's answer. @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 9:12
I did it to warn anyone to use this code, because it would cause serious damage in data integrity. E.g. instead adding new option named "42" (size) your script updated option_id = 42 (which was existing option of completly different attribute). Luckily it happend to me on test server and fresh new database.
– A.Maksymiuk
Mar 16 '18 at 9:20
add a comment |
use MagentoEavSetupEavSetupFactory;
use MagentoStoreModelStoreManagerInterface;
declare:
protected $_eavSetupFactory;
constructor :
public function __construct(
MagentoEavSetupEavSetupFactory $eavSetupFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoCatalogModelResourceModelEavAttribute $attributeFactory,
MagentoFrameworkObjectManagerInterface $objectmanager,
ModuleDataSetupInterface $setup,
MagentoCatalogModelProductFactory $productloader
) {
$this->_eavSetupFactory = $eavSetupFactory;
$this->_storeManager = $storeManager;
$this->_attributeFactory = $attributeFactory;
$this->_objectManager = $objectmanager;
$this->setup = $setup;
$this->_productloader = $productloader;
}
execute methode :
public function execute(EventObserver $observer)
{
/** @var $brand KtplBrandModelBrand */
$brand = $observer->getEvent()->getBrand();
$option_id = "";
$data = ;
$attribute_arr = [$brand['brand_id'] => $brand['brand_title']];
$optionTable = $this->setup->getTable('eav_attribute_option');
$attributeInfo=$this->_attributeFactory->getCollection()
->addFieldToFilter('attribute_code',['eq'=>"shop_by_brand"])
->getFirstItem();
$attribute_id = $attributeInfo->getAttributeId();
$eavAttribute = $this->_objectManager->create('MagentoEavModelConfig');
$option=array();
$option['attribute_id'] = $attributeInfo->getAttributeId();
$option['value'] = array(0=>array()); // 0 means "new option_id", other values like "14" means "update option_id=14" - this array index is casted to integer
$storeManager = $this->_objectManager->get('MagentoStoreModelStoreManagerInterface');
$stores = $storeManager->getStores();
$storeArray[0] = "All Store Views";
foreach ($stores as $store) {
$storeArray[$store->getId()] = $store->getName();
}
if (empty($brand['optionId'])) {
foreach($attribute_arr as $key => $value){
$option['value'][0][0]=$value;
foreach($storeArray as $storeKey => $store){
$option['value'][0][$storeKey] = $value;
}
}
}
else
{
foreach($attribute_arr as $key => $value){
foreach($storeArray as $storeKey => $store){
$option['value'][$brand['optionId']][$storeKey] = $value;
}
}
}
$eavSetup = $this->_eavSetupFactory->create();
$eavSetup->addAttributeOption($option)
}
You have serious error in your code:$option['value'][$value][0] - it should not be $value but "option_id" - integer, for new one option set 0. This one is cast to integer, so if you have string with no numer, eg "black" it will be 0 correctly. But if your $value is something like "10 Black" it will cast to 10 and update database entity with option_id = 10 instead creating new one. This may cause serious mess in your shop database.
– A.Maksymiuk
Mar 15 '18 at 21:28
thanks to inform brother. If you found any error than you can update my answer @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 5:25
Did it. Please accept, then I'll revert my downvote.
– A.Maksymiuk
Mar 16 '18 at 8:41
Approved, but down-vote any answer is not the proper way bro, If you think that answer is not related or not as per asked then you can else don't down-vote anyone's answer. @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 9:12
I did it to warn anyone to use this code, because it would cause serious damage in data integrity. E.g. instead adding new option named "42" (size) your script updated option_id = 42 (which was existing option of completly different attribute). Luckily it happend to me on test server and fresh new database.
– A.Maksymiuk
Mar 16 '18 at 9:20
add a comment |
use MagentoEavSetupEavSetupFactory;
use MagentoStoreModelStoreManagerInterface;
declare:
protected $_eavSetupFactory;
constructor :
public function __construct(
MagentoEavSetupEavSetupFactory $eavSetupFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoCatalogModelResourceModelEavAttribute $attributeFactory,
MagentoFrameworkObjectManagerInterface $objectmanager,
ModuleDataSetupInterface $setup,
MagentoCatalogModelProductFactory $productloader
) {
$this->_eavSetupFactory = $eavSetupFactory;
$this->_storeManager = $storeManager;
$this->_attributeFactory = $attributeFactory;
$this->_objectManager = $objectmanager;
$this->setup = $setup;
$this->_productloader = $productloader;
}
execute methode :
public function execute(EventObserver $observer)
{
/** @var $brand KtplBrandModelBrand */
$brand = $observer->getEvent()->getBrand();
$option_id = "";
$data = ;
$attribute_arr = [$brand['brand_id'] => $brand['brand_title']];
$optionTable = $this->setup->getTable('eav_attribute_option');
$attributeInfo=$this->_attributeFactory->getCollection()
->addFieldToFilter('attribute_code',['eq'=>"shop_by_brand"])
->getFirstItem();
$attribute_id = $attributeInfo->getAttributeId();
$eavAttribute = $this->_objectManager->create('MagentoEavModelConfig');
$option=array();
$option['attribute_id'] = $attributeInfo->getAttributeId();
$option['value'] = array(0=>array()); // 0 means "new option_id", other values like "14" means "update option_id=14" - this array index is casted to integer
$storeManager = $this->_objectManager->get('MagentoStoreModelStoreManagerInterface');
$stores = $storeManager->getStores();
$storeArray[0] = "All Store Views";
foreach ($stores as $store) {
$storeArray[$store->getId()] = $store->getName();
}
if (empty($brand['optionId'])) {
foreach($attribute_arr as $key => $value){
$option['value'][0][0]=$value;
foreach($storeArray as $storeKey => $store){
$option['value'][0][$storeKey] = $value;
}
}
}
else
{
foreach($attribute_arr as $key => $value){
foreach($storeArray as $storeKey => $store){
$option['value'][$brand['optionId']][$storeKey] = $value;
}
}
}
$eavSetup = $this->_eavSetupFactory->create();
$eavSetup->addAttributeOption($option)
}
use MagentoEavSetupEavSetupFactory;
use MagentoStoreModelStoreManagerInterface;
declare:
protected $_eavSetupFactory;
constructor :
public function __construct(
MagentoEavSetupEavSetupFactory $eavSetupFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoCatalogModelResourceModelEavAttribute $attributeFactory,
MagentoFrameworkObjectManagerInterface $objectmanager,
ModuleDataSetupInterface $setup,
MagentoCatalogModelProductFactory $productloader
) {
$this->_eavSetupFactory = $eavSetupFactory;
$this->_storeManager = $storeManager;
$this->_attributeFactory = $attributeFactory;
$this->_objectManager = $objectmanager;
$this->setup = $setup;
$this->_productloader = $productloader;
}
execute methode :
public function execute(EventObserver $observer)
{
/** @var $brand KtplBrandModelBrand */
$brand = $observer->getEvent()->getBrand();
$option_id = "";
$data = ;
$attribute_arr = [$brand['brand_id'] => $brand['brand_title']];
$optionTable = $this->setup->getTable('eav_attribute_option');
$attributeInfo=$this->_attributeFactory->getCollection()
->addFieldToFilter('attribute_code',['eq'=>"shop_by_brand"])
->getFirstItem();
$attribute_id = $attributeInfo->getAttributeId();
$eavAttribute = $this->_objectManager->create('MagentoEavModelConfig');
$option=array();
$option['attribute_id'] = $attributeInfo->getAttributeId();
$option['value'] = array(0=>array()); // 0 means "new option_id", other values like "14" means "update option_id=14" - this array index is casted to integer
$storeManager = $this->_objectManager->get('MagentoStoreModelStoreManagerInterface');
$stores = $storeManager->getStores();
$storeArray[0] = "All Store Views";
foreach ($stores as $store) {
$storeArray[$store->getId()] = $store->getName();
}
if (empty($brand['optionId'])) {
foreach($attribute_arr as $key => $value){
$option['value'][0][0]=$value;
foreach($storeArray as $storeKey => $store){
$option['value'][0][$storeKey] = $value;
}
}
}
else
{
foreach($attribute_arr as $key => $value){
foreach($storeArray as $storeKey => $store){
$option['value'][$brand['optionId']][$storeKey] = $value;
}
}
}
$eavSetup = $this->_eavSetupFactory->create();
$eavSetup->addAttributeOption($option)
}
edited Mar 16 '18 at 9:10
A.Maksymiuk
413512
413512
answered Oct 28 '16 at 12:00
Ronak ChauhanRonak Chauhan
4,12511448
4,12511448
You have serious error in your code:$option['value'][$value][0] - it should not be $value but "option_id" - integer, for new one option set 0. This one is cast to integer, so if you have string with no numer, eg "black" it will be 0 correctly. But if your $value is something like "10 Black" it will cast to 10 and update database entity with option_id = 10 instead creating new one. This may cause serious mess in your shop database.
– A.Maksymiuk
Mar 15 '18 at 21:28
thanks to inform brother. If you found any error than you can update my answer @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 5:25
Did it. Please accept, then I'll revert my downvote.
– A.Maksymiuk
Mar 16 '18 at 8:41
Approved, but down-vote any answer is not the proper way bro, If you think that answer is not related or not as per asked then you can else don't down-vote anyone's answer. @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 9:12
I did it to warn anyone to use this code, because it would cause serious damage in data integrity. E.g. instead adding new option named "42" (size) your script updated option_id = 42 (which was existing option of completly different attribute). Luckily it happend to me on test server and fresh new database.
– A.Maksymiuk
Mar 16 '18 at 9:20
add a comment |
You have serious error in your code:$option['value'][$value][0] - it should not be $value but "option_id" - integer, for new one option set 0. This one is cast to integer, so if you have string with no numer, eg "black" it will be 0 correctly. But if your $value is something like "10 Black" it will cast to 10 and update database entity with option_id = 10 instead creating new one. This may cause serious mess in your shop database.
– A.Maksymiuk
Mar 15 '18 at 21:28
thanks to inform brother. If you found any error than you can update my answer @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 5:25
Did it. Please accept, then I'll revert my downvote.
– A.Maksymiuk
Mar 16 '18 at 8:41
Approved, but down-vote any answer is not the proper way bro, If you think that answer is not related or not as per asked then you can else don't down-vote anyone's answer. @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 9:12
I did it to warn anyone to use this code, because it would cause serious damage in data integrity. E.g. instead adding new option named "42" (size) your script updated option_id = 42 (which was existing option of completly different attribute). Luckily it happend to me on test server and fresh new database.
– A.Maksymiuk
Mar 16 '18 at 9:20
You have serious error in your code:$option['value'][$value][0] - it should not be $value but "option_id" - integer, for new one option set 0. This one is cast to integer, so if you have string with no numer, eg "black" it will be 0 correctly. But if your $value is something like "10 Black" it will cast to 10 and update database entity with option_id = 10 instead creating new one. This may cause serious mess in your shop database.
– A.Maksymiuk
Mar 15 '18 at 21:28
You have serious error in your code:$option['value'][$value][0] - it should not be $value but "option_id" - integer, for new one option set 0. This one is cast to integer, so if you have string with no numer, eg "black" it will be 0 correctly. But if your $value is something like "10 Black" it will cast to 10 and update database entity with option_id = 10 instead creating new one. This may cause serious mess in your shop database.
– A.Maksymiuk
Mar 15 '18 at 21:28
thanks to inform brother. If you found any error than you can update my answer @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 5:25
thanks to inform brother. If you found any error than you can update my answer @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 5:25
Did it. Please accept, then I'll revert my downvote.
– A.Maksymiuk
Mar 16 '18 at 8:41
Did it. Please accept, then I'll revert my downvote.
– A.Maksymiuk
Mar 16 '18 at 8:41
Approved, but down-vote any answer is not the proper way bro, If you think that answer is not related or not as per asked then you can else don't down-vote anyone's answer. @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 9:12
Approved, but down-vote any answer is not the proper way bro, If you think that answer is not related or not as per asked then you can else don't down-vote anyone's answer. @A.Maksymiuk
– Ronak Chauhan
Mar 16 '18 at 9:12
I did it to warn anyone to use this code, because it would cause serious damage in data integrity. E.g. instead adding new option named "42" (size) your script updated option_id = 42 (which was existing option of completly different attribute). Luckily it happend to me on test server and fresh new database.
– A.Maksymiuk
Mar 16 '18 at 9:20
I did it to warn anyone to use this code, because it would cause serious damage in data integrity. E.g. instead adding new option named "42" (size) your script updated option_id = 42 (which was existing option of completly different attribute). Luckily it happend to me on test server and fresh new database.
– A.Maksymiuk
Mar 16 '18 at 9:20
add a comment |
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way.
See my way. I believe it to be 'official'
– CarComp
Mar 31 '16 at 16:00
your solution is work but only when option are option not work for integer
– Ajay Patel
Nov 21 '17 at 14:05
add a comment |
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way.
See my way. I believe it to be 'official'
– CarComp
Mar 31 '16 at 16:00
your solution is work but only when option are option not work for integer
– Ajay Patel
Nov 21 '17 at 14:05
add a comment |
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way.
Other way I can add option:
$attributeCode = 137; /* on size, 90 on color ... */
$languageValues[0]='Admin Label';
$languageValues[1]='Default Store Label - XXXXL';
$ob = $this->_objectManager;
private function addOption($attributeCode,$languageValues){
$ob = $this->_objectManager;
/* @var $attr MagentoEavModelEntityAttribute */
$attr = $ob->create('MagentoEavModelEntityAttribute');
$attr->load($attributeCode);
$option = ;
$option['value'][$languageValues[0]] = $languageValues;
$attr->addData(array('option' => $option));
$attr->save();
}
This way Magento2 can save an option to attribute, but I dont know what is the "official" way.
answered Jan 2 '16 at 16:36
InterpigeonInterpigeon
8116
8116
See my way. I believe it to be 'official'
– CarComp
Mar 31 '16 at 16:00
your solution is work but only when option are option not work for integer
– Ajay Patel
Nov 21 '17 at 14:05
add a comment |
See my way. I believe it to be 'official'
– CarComp
Mar 31 '16 at 16:00
your solution is work but only when option are option not work for integer
– Ajay Patel
Nov 21 '17 at 14:05
See my way. I believe it to be 'official'
– CarComp
Mar 31 '16 at 16:00
See my way. I believe it to be 'official'
– CarComp
Mar 31 '16 at 16:00
your solution is work but only when option are option not work for integer
– Ajay Patel
Nov 21 '17 at 14:05
your solution is work but only when option are option not work for integer
– Ajay Patel
Nov 21 '17 at 14:05
add a comment |
Seems to be a validation issue.
The delete key in data comes from the form in the backend, so try to add an empty delete key that way:
$option->setData('delete','');
It could works.
Sadly no. The OptionManager add(..) reparse the $option parameter and leave the 'delete' key empty, I don't no why... But I found another way....
– Interpigeon
Jan 2 '16 at 15:50
Great, please add your solution as an answer to resolve the question.
– MauroNigrele
Jan 2 '16 at 15:59
I can't answer my own question, but i updated the question. I think my solution is a workaround...
– Interpigeon
Jan 2 '16 at 16:14
Hey, you can answer your question is pretty common.
– MauroNigrele
Jan 2 '16 at 16:16
add a comment |
Seems to be a validation issue.
The delete key in data comes from the form in the backend, so try to add an empty delete key that way:
$option->setData('delete','');
It could works.
Sadly no. The OptionManager add(..) reparse the $option parameter and leave the 'delete' key empty, I don't no why... But I found another way....
– Interpigeon
Jan 2 '16 at 15:50
Great, please add your solution as an answer to resolve the question.
– MauroNigrele
Jan 2 '16 at 15:59
I can't answer my own question, but i updated the question. I think my solution is a workaround...
– Interpigeon
Jan 2 '16 at 16:14
Hey, you can answer your question is pretty common.
– MauroNigrele
Jan 2 '16 at 16:16
add a comment |
Seems to be a validation issue.
The delete key in data comes from the form in the backend, so try to add an empty delete key that way:
$option->setData('delete','');
It could works.
Seems to be a validation issue.
The delete key in data comes from the form in the backend, so try to add an empty delete key that way:
$option->setData('delete','');
It could works.
answered Dec 28 '15 at 4:16
MauroNigreleMauroNigrele
2,577926
2,577926
Sadly no. The OptionManager add(..) reparse the $option parameter and leave the 'delete' key empty, I don't no why... But I found another way....
– Interpigeon
Jan 2 '16 at 15:50
Great, please add your solution as an answer to resolve the question.
– MauroNigrele
Jan 2 '16 at 15:59
I can't answer my own question, but i updated the question. I think my solution is a workaround...
– Interpigeon
Jan 2 '16 at 16:14
Hey, you can answer your question is pretty common.
– MauroNigrele
Jan 2 '16 at 16:16
add a comment |
Sadly no. The OptionManager add(..) reparse the $option parameter and leave the 'delete' key empty, I don't no why... But I found another way....
– Interpigeon
Jan 2 '16 at 15:50
Great, please add your solution as an answer to resolve the question.
– MauroNigrele
Jan 2 '16 at 15:59
I can't answer my own question, but i updated the question. I think my solution is a workaround...
– Interpigeon
Jan 2 '16 at 16:14
Hey, you can answer your question is pretty common.
– MauroNigrele
Jan 2 '16 at 16:16
Sadly no. The OptionManager add(..) reparse the $option parameter and leave the 'delete' key empty, I don't no why... But I found another way....
– Interpigeon
Jan 2 '16 at 15:50
Sadly no. The OptionManager add(..) reparse the $option parameter and leave the 'delete' key empty, I don't no why... But I found another way....
– Interpigeon
Jan 2 '16 at 15:50
Great, please add your solution as an answer to resolve the question.
– MauroNigrele
Jan 2 '16 at 15:59
Great, please add your solution as an answer to resolve the question.
– MauroNigrele
Jan 2 '16 at 15:59
I can't answer my own question, but i updated the question. I think my solution is a workaround...
– Interpigeon
Jan 2 '16 at 16:14
I can't answer my own question, but i updated the question. I think my solution is a workaround...
– Interpigeon
Jan 2 '16 at 16:14
Hey, you can answer your question is pretty common.
– MauroNigrele
Jan 2 '16 at 16:16
Hey, you can answer your question is pretty common.
– MauroNigrele
Jan 2 '16 at 16:16
add a comment |
I ended up rewriting this entire answer using ObjectFactory methods suggested by Ryan H.
It ended up being a Helper Class that utilized some attributes I created on the customer object, but the idea is there on how to utilize EAV + ObjectFactories to manipulate attribute options
<?php
namespace SttiHealthdayHelper {
use MagentoEavModelEntityAttributeFactory;
use MagentoEavModelEntityAttributeOptionFactory;
use MagentoEavModelEntityAttributeOptionManagementFactory;
use MagentoFrameworkAppHelperAbstractHelper;
use MagentoFrameworkAppHelperContext;
use MagentoEavModelEntityAttribute;
use SttiHealthdayModelRelationFactory;
/**
* Eav data helper
*/
class Data extends AbstractHelper {
protected $optionFactory;
protected $attributeFactory;
protected $relationFactory;
protected $optionManagementFactory;
public function __construct(Context $context, AttributeFactory $attributeFactory, OptionFactory $optionFactory,
RelationFactory $relationFactory,
OptionManagementFactory $optionManagementFactory) {
$this->optionFactory = $optionFactory;
$this->attributeFactory = $attributeFactory;
$this->optionFactory = $optionFactory;
$this->relationFactory = $relationFactory;
$this->optionManagementFactory = $optionManagementFactory;
parent::__construct($context);
}
public function addRelationsHelper($answerJson, $attributeCode) {
// IMPORTANT: READ THIS OR THE CODE BELOW WONT MAKE SENSE!!!!
// Since magento's attribute option model was never meant to
// hold guids, we'll be saving the guid as the label. An option_id will
// get created, which can then be saved to the relationship table. Then
// the label in the attribute_option table can be changed to the actual 'word'
// by looking up all of the options, matching on the guid, and doing a replace.
// At that point, there will be a 1:1 relation between guid, option_id, and the 'word'
// Get the attribute requested
$attribute = $this->attributeFactory->create();
$attribute = $attribute->loadByCode("customer", $attributeCode);
$answers = json_decode($answerJson, true);
// Prepare vars
//$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$prekeys = array();
$prevalues = array();
foreach ($answers as $answer) {
$prekeys = $answer['Key'];
$prevalues = $answer['Value'];
}
// load up all relations
// generate an array of matching indexes so we can remove
// them from the array to process
$collection = $this->relationFactory->create()->getCollection();
$removalIds = array();
foreach ($collection as $relation) {
// if the item is already in the magento relations,
// don't attempt to add it to the attribute options
for($cnt = 0; $cnt < sizeof($answers); $cnt++) {
if ($relation['stti_guid'] == $prekeys[$cnt]) {
$removalIds = $cnt;
}
}
}
// Remove the values from the arrays we are going to process
foreach($removalIds as $removalId) {
unset($prekeys[$removalId]);
unset($prevalues[$removalId]);
}
// "reindex" the arrays
$keys = array_values($prekeys);
$values = array_values($prevalues);
// prepare the array that will be sent into the attribute model to
// update its option values
$updates = array();
$updates['attribute_id'] = $attribute->getId();
// This section utilizes the DI generated OptionFactory and OptionManagementFactory
// to add the options to the customer attribute specified in the parameters.
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option = $this->optionFactory->create();
$option->setLabel($keys[$cnt]);
$this->optionManagementFactory->create()->add("customer", $attributeCode, $option);
}
// After save, pull all attribute options, compare to the 'keys' array
// and create healthday/relation models if needed
$relationIds = $attribute->getOptions();
$updatedAttributeCount = 0;
$options = array();
$options['value'] = array();
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option_id = 0;
foreach($relationIds as $relationId) {
if ($relationId->getLabel() == $keys[$cnt]) {
$option_id = $relationId['value'];
break;
}
}
if ($option_id > 0) {
// Create the healthday relation utilizing our custom models DI generated ObjectFactories
$relation = $this->relationFactory->create();
$relation->setAttributeId($attribute->getId());
$relation->setOptionId($option_id);
$relation->setSttiGuid($keys[$cnt]);
$relation->save();
// Rename the attribute option value to the 'word'
$options['value'][$option_id] = $values[$cnt];
$updatedAttributeCount++;
}
}
if ($updatedAttributeCount > 0) {
$attribute->setData('option', $options);
$attribute->save();
}
// Save the relationship to the guid
return $updatedAttributeCount;
}
}
}
1
You should be injecting ObjectFactory and create instances of Object from that, not injecting Object itself. ORM objects are not to be injected directly.
– Ryan Hoerr
Apr 1 '16 at 17:04
Which ObjectFactory? Theres like 50. I'm looking at MagentoFrameworkApiObjectFactory but it just looks like a wrapper for ObjectManager. I'm not sure why I wouldn't just implement the objectmanager itself. Theres SO many wrappers for wrappers of things in this new version.
– CarComp
Apr 8 '16 at 12:56
1
I was speaking in the abstract. Inject the Factory for your given object, not literally 'ObjectFactory'. You should inject the factory for each specific type you use, and create them as needed. Yes, it seems messy at first... but there are very good reasons for it. Beside, ECG code standards all but prohibit direct use of ObjectManager. See Alan Storm's article explaining the whole subject: alanstorm.com/magento_2_object_manager_instance_objects
– Ryan Hoerr
Apr 8 '16 at 13:05
What should I do when the objects I want to use do not have a factory? For instance, I can't find a way to 'factory' the options management stuff. MagentoEavModelAttributeFactory also uses a weird ->createAttribute(vars) instead of just ->create(). I'm just saying, when you don't work with a product, or a category built in stuff, things get a little weird.
– CarComp
Apr 8 '16 at 13:53
1
Not all objects will require a factory. For ones that do, the factory may not exist out-of-box -- any that don't exist will be created at runtime (with DI generation), or during compilation. Read the article I linked. Any way about it, you need to learn to work with Magento2, not against it. Yes, there is a learning curve. If you don't already, I strongly recommend picking up PhpStorm or a similar IDE.
– Ryan Hoerr
Apr 8 '16 at 14:03
|
show 1 more comment
I ended up rewriting this entire answer using ObjectFactory methods suggested by Ryan H.
It ended up being a Helper Class that utilized some attributes I created on the customer object, but the idea is there on how to utilize EAV + ObjectFactories to manipulate attribute options
<?php
namespace SttiHealthdayHelper {
use MagentoEavModelEntityAttributeFactory;
use MagentoEavModelEntityAttributeOptionFactory;
use MagentoEavModelEntityAttributeOptionManagementFactory;
use MagentoFrameworkAppHelperAbstractHelper;
use MagentoFrameworkAppHelperContext;
use MagentoEavModelEntityAttribute;
use SttiHealthdayModelRelationFactory;
/**
* Eav data helper
*/
class Data extends AbstractHelper {
protected $optionFactory;
protected $attributeFactory;
protected $relationFactory;
protected $optionManagementFactory;
public function __construct(Context $context, AttributeFactory $attributeFactory, OptionFactory $optionFactory,
RelationFactory $relationFactory,
OptionManagementFactory $optionManagementFactory) {
$this->optionFactory = $optionFactory;
$this->attributeFactory = $attributeFactory;
$this->optionFactory = $optionFactory;
$this->relationFactory = $relationFactory;
$this->optionManagementFactory = $optionManagementFactory;
parent::__construct($context);
}
public function addRelationsHelper($answerJson, $attributeCode) {
// IMPORTANT: READ THIS OR THE CODE BELOW WONT MAKE SENSE!!!!
// Since magento's attribute option model was never meant to
// hold guids, we'll be saving the guid as the label. An option_id will
// get created, which can then be saved to the relationship table. Then
// the label in the attribute_option table can be changed to the actual 'word'
// by looking up all of the options, matching on the guid, and doing a replace.
// At that point, there will be a 1:1 relation between guid, option_id, and the 'word'
// Get the attribute requested
$attribute = $this->attributeFactory->create();
$attribute = $attribute->loadByCode("customer", $attributeCode);
$answers = json_decode($answerJson, true);
// Prepare vars
//$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$prekeys = array();
$prevalues = array();
foreach ($answers as $answer) {
$prekeys = $answer['Key'];
$prevalues = $answer['Value'];
}
// load up all relations
// generate an array of matching indexes so we can remove
// them from the array to process
$collection = $this->relationFactory->create()->getCollection();
$removalIds = array();
foreach ($collection as $relation) {
// if the item is already in the magento relations,
// don't attempt to add it to the attribute options
for($cnt = 0; $cnt < sizeof($answers); $cnt++) {
if ($relation['stti_guid'] == $prekeys[$cnt]) {
$removalIds = $cnt;
}
}
}
// Remove the values from the arrays we are going to process
foreach($removalIds as $removalId) {
unset($prekeys[$removalId]);
unset($prevalues[$removalId]);
}
// "reindex" the arrays
$keys = array_values($prekeys);
$values = array_values($prevalues);
// prepare the array that will be sent into the attribute model to
// update its option values
$updates = array();
$updates['attribute_id'] = $attribute->getId();
// This section utilizes the DI generated OptionFactory and OptionManagementFactory
// to add the options to the customer attribute specified in the parameters.
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option = $this->optionFactory->create();
$option->setLabel($keys[$cnt]);
$this->optionManagementFactory->create()->add("customer", $attributeCode, $option);
}
// After save, pull all attribute options, compare to the 'keys' array
// and create healthday/relation models if needed
$relationIds = $attribute->getOptions();
$updatedAttributeCount = 0;
$options = array();
$options['value'] = array();
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option_id = 0;
foreach($relationIds as $relationId) {
if ($relationId->getLabel() == $keys[$cnt]) {
$option_id = $relationId['value'];
break;
}
}
if ($option_id > 0) {
// Create the healthday relation utilizing our custom models DI generated ObjectFactories
$relation = $this->relationFactory->create();
$relation->setAttributeId($attribute->getId());
$relation->setOptionId($option_id);
$relation->setSttiGuid($keys[$cnt]);
$relation->save();
// Rename the attribute option value to the 'word'
$options['value'][$option_id] = $values[$cnt];
$updatedAttributeCount++;
}
}
if ($updatedAttributeCount > 0) {
$attribute->setData('option', $options);
$attribute->save();
}
// Save the relationship to the guid
return $updatedAttributeCount;
}
}
}
1
You should be injecting ObjectFactory and create instances of Object from that, not injecting Object itself. ORM objects are not to be injected directly.
– Ryan Hoerr
Apr 1 '16 at 17:04
Which ObjectFactory? Theres like 50. I'm looking at MagentoFrameworkApiObjectFactory but it just looks like a wrapper for ObjectManager. I'm not sure why I wouldn't just implement the objectmanager itself. Theres SO many wrappers for wrappers of things in this new version.
– CarComp
Apr 8 '16 at 12:56
1
I was speaking in the abstract. Inject the Factory for your given object, not literally 'ObjectFactory'. You should inject the factory for each specific type you use, and create them as needed. Yes, it seems messy at first... but there are very good reasons for it. Beside, ECG code standards all but prohibit direct use of ObjectManager. See Alan Storm's article explaining the whole subject: alanstorm.com/magento_2_object_manager_instance_objects
– Ryan Hoerr
Apr 8 '16 at 13:05
What should I do when the objects I want to use do not have a factory? For instance, I can't find a way to 'factory' the options management stuff. MagentoEavModelAttributeFactory also uses a weird ->createAttribute(vars) instead of just ->create(). I'm just saying, when you don't work with a product, or a category built in stuff, things get a little weird.
– CarComp
Apr 8 '16 at 13:53
1
Not all objects will require a factory. For ones that do, the factory may not exist out-of-box -- any that don't exist will be created at runtime (with DI generation), or during compilation. Read the article I linked. Any way about it, you need to learn to work with Magento2, not against it. Yes, there is a learning curve. If you don't already, I strongly recommend picking up PhpStorm or a similar IDE.
– Ryan Hoerr
Apr 8 '16 at 14:03
|
show 1 more comment
I ended up rewriting this entire answer using ObjectFactory methods suggested by Ryan H.
It ended up being a Helper Class that utilized some attributes I created on the customer object, but the idea is there on how to utilize EAV + ObjectFactories to manipulate attribute options
<?php
namespace SttiHealthdayHelper {
use MagentoEavModelEntityAttributeFactory;
use MagentoEavModelEntityAttributeOptionFactory;
use MagentoEavModelEntityAttributeOptionManagementFactory;
use MagentoFrameworkAppHelperAbstractHelper;
use MagentoFrameworkAppHelperContext;
use MagentoEavModelEntityAttribute;
use SttiHealthdayModelRelationFactory;
/**
* Eav data helper
*/
class Data extends AbstractHelper {
protected $optionFactory;
protected $attributeFactory;
protected $relationFactory;
protected $optionManagementFactory;
public function __construct(Context $context, AttributeFactory $attributeFactory, OptionFactory $optionFactory,
RelationFactory $relationFactory,
OptionManagementFactory $optionManagementFactory) {
$this->optionFactory = $optionFactory;
$this->attributeFactory = $attributeFactory;
$this->optionFactory = $optionFactory;
$this->relationFactory = $relationFactory;
$this->optionManagementFactory = $optionManagementFactory;
parent::__construct($context);
}
public function addRelationsHelper($answerJson, $attributeCode) {
// IMPORTANT: READ THIS OR THE CODE BELOW WONT MAKE SENSE!!!!
// Since magento's attribute option model was never meant to
// hold guids, we'll be saving the guid as the label. An option_id will
// get created, which can then be saved to the relationship table. Then
// the label in the attribute_option table can be changed to the actual 'word'
// by looking up all of the options, matching on the guid, and doing a replace.
// At that point, there will be a 1:1 relation between guid, option_id, and the 'word'
// Get the attribute requested
$attribute = $this->attributeFactory->create();
$attribute = $attribute->loadByCode("customer", $attributeCode);
$answers = json_decode($answerJson, true);
// Prepare vars
//$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$prekeys = array();
$prevalues = array();
foreach ($answers as $answer) {
$prekeys = $answer['Key'];
$prevalues = $answer['Value'];
}
// load up all relations
// generate an array of matching indexes so we can remove
// them from the array to process
$collection = $this->relationFactory->create()->getCollection();
$removalIds = array();
foreach ($collection as $relation) {
// if the item is already in the magento relations,
// don't attempt to add it to the attribute options
for($cnt = 0; $cnt < sizeof($answers); $cnt++) {
if ($relation['stti_guid'] == $prekeys[$cnt]) {
$removalIds = $cnt;
}
}
}
// Remove the values from the arrays we are going to process
foreach($removalIds as $removalId) {
unset($prekeys[$removalId]);
unset($prevalues[$removalId]);
}
// "reindex" the arrays
$keys = array_values($prekeys);
$values = array_values($prevalues);
// prepare the array that will be sent into the attribute model to
// update its option values
$updates = array();
$updates['attribute_id'] = $attribute->getId();
// This section utilizes the DI generated OptionFactory and OptionManagementFactory
// to add the options to the customer attribute specified in the parameters.
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option = $this->optionFactory->create();
$option->setLabel($keys[$cnt]);
$this->optionManagementFactory->create()->add("customer", $attributeCode, $option);
}
// After save, pull all attribute options, compare to the 'keys' array
// and create healthday/relation models if needed
$relationIds = $attribute->getOptions();
$updatedAttributeCount = 0;
$options = array();
$options['value'] = array();
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option_id = 0;
foreach($relationIds as $relationId) {
if ($relationId->getLabel() == $keys[$cnt]) {
$option_id = $relationId['value'];
break;
}
}
if ($option_id > 0) {
// Create the healthday relation utilizing our custom models DI generated ObjectFactories
$relation = $this->relationFactory->create();
$relation->setAttributeId($attribute->getId());
$relation->setOptionId($option_id);
$relation->setSttiGuid($keys[$cnt]);
$relation->save();
// Rename the attribute option value to the 'word'
$options['value'][$option_id] = $values[$cnt];
$updatedAttributeCount++;
}
}
if ($updatedAttributeCount > 0) {
$attribute->setData('option', $options);
$attribute->save();
}
// Save the relationship to the guid
return $updatedAttributeCount;
}
}
}
I ended up rewriting this entire answer using ObjectFactory methods suggested by Ryan H.
It ended up being a Helper Class that utilized some attributes I created on the customer object, but the idea is there on how to utilize EAV + ObjectFactories to manipulate attribute options
<?php
namespace SttiHealthdayHelper {
use MagentoEavModelEntityAttributeFactory;
use MagentoEavModelEntityAttributeOptionFactory;
use MagentoEavModelEntityAttributeOptionManagementFactory;
use MagentoFrameworkAppHelperAbstractHelper;
use MagentoFrameworkAppHelperContext;
use MagentoEavModelEntityAttribute;
use SttiHealthdayModelRelationFactory;
/**
* Eav data helper
*/
class Data extends AbstractHelper {
protected $optionFactory;
protected $attributeFactory;
protected $relationFactory;
protected $optionManagementFactory;
public function __construct(Context $context, AttributeFactory $attributeFactory, OptionFactory $optionFactory,
RelationFactory $relationFactory,
OptionManagementFactory $optionManagementFactory) {
$this->optionFactory = $optionFactory;
$this->attributeFactory = $attributeFactory;
$this->optionFactory = $optionFactory;
$this->relationFactory = $relationFactory;
$this->optionManagementFactory = $optionManagementFactory;
parent::__construct($context);
}
public function addRelationsHelper($answerJson, $attributeCode) {
// IMPORTANT: READ THIS OR THE CODE BELOW WONT MAKE SENSE!!!!
// Since magento's attribute option model was never meant to
// hold guids, we'll be saving the guid as the label. An option_id will
// get created, which can then be saved to the relationship table. Then
// the label in the attribute_option table can be changed to the actual 'word'
// by looking up all of the options, matching on the guid, and doing a replace.
// At that point, there will be a 1:1 relation between guid, option_id, and the 'word'
// Get the attribute requested
$attribute = $this->attributeFactory->create();
$attribute = $attribute->loadByCode("customer", $attributeCode);
$answers = json_decode($answerJson, true);
// Prepare vars
//$setup = new Mage_Eav_Model_Entity_Setup('core_setup');
$prekeys = array();
$prevalues = array();
foreach ($answers as $answer) {
$prekeys = $answer['Key'];
$prevalues = $answer['Value'];
}
// load up all relations
// generate an array of matching indexes so we can remove
// them from the array to process
$collection = $this->relationFactory->create()->getCollection();
$removalIds = array();
foreach ($collection as $relation) {
// if the item is already in the magento relations,
// don't attempt to add it to the attribute options
for($cnt = 0; $cnt < sizeof($answers); $cnt++) {
if ($relation['stti_guid'] == $prekeys[$cnt]) {
$removalIds = $cnt;
}
}
}
// Remove the values from the arrays we are going to process
foreach($removalIds as $removalId) {
unset($prekeys[$removalId]);
unset($prevalues[$removalId]);
}
// "reindex" the arrays
$keys = array_values($prekeys);
$values = array_values($prevalues);
// prepare the array that will be sent into the attribute model to
// update its option values
$updates = array();
$updates['attribute_id'] = $attribute->getId();
// This section utilizes the DI generated OptionFactory and OptionManagementFactory
// to add the options to the customer attribute specified in the parameters.
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option = $this->optionFactory->create();
$option->setLabel($keys[$cnt]);
$this->optionManagementFactory->create()->add("customer", $attributeCode, $option);
}
// After save, pull all attribute options, compare to the 'keys' array
// and create healthday/relation models if needed
$relationIds = $attribute->getOptions();
$updatedAttributeCount = 0;
$options = array();
$options['value'] = array();
for($cnt = 0; $cnt < sizeof($keys); $cnt++) {
$option_id = 0;
foreach($relationIds as $relationId) {
if ($relationId->getLabel() == $keys[$cnt]) {
$option_id = $relationId['value'];
break;
}
}
if ($option_id > 0) {
// Create the healthday relation utilizing our custom models DI generated ObjectFactories
$relation = $this->relationFactory->create();
$relation->setAttributeId($attribute->getId());
$relation->setOptionId($option_id);
$relation->setSttiGuid($keys[$cnt]);
$relation->save();
// Rename the attribute option value to the 'word'
$options['value'][$option_id] = $values[$cnt];
$updatedAttributeCount++;
}
}
if ($updatedAttributeCount > 0) {
$attribute->setData('option', $options);
$attribute->save();
}
// Save the relationship to the guid
return $updatedAttributeCount;
}
}
}
edited Apr 8 '16 at 20:52
answered Mar 31 '16 at 15:52
CarCompCarComp
8131026
8131026
1
You should be injecting ObjectFactory and create instances of Object from that, not injecting Object itself. ORM objects are not to be injected directly.
– Ryan Hoerr
Apr 1 '16 at 17:04
Which ObjectFactory? Theres like 50. I'm looking at MagentoFrameworkApiObjectFactory but it just looks like a wrapper for ObjectManager. I'm not sure why I wouldn't just implement the objectmanager itself. Theres SO many wrappers for wrappers of things in this new version.
– CarComp
Apr 8 '16 at 12:56
1
I was speaking in the abstract. Inject the Factory for your given object, not literally 'ObjectFactory'. You should inject the factory for each specific type you use, and create them as needed. Yes, it seems messy at first... but there are very good reasons for it. Beside, ECG code standards all but prohibit direct use of ObjectManager. See Alan Storm's article explaining the whole subject: alanstorm.com/magento_2_object_manager_instance_objects
– Ryan Hoerr
Apr 8 '16 at 13:05
What should I do when the objects I want to use do not have a factory? For instance, I can't find a way to 'factory' the options management stuff. MagentoEavModelAttributeFactory also uses a weird ->createAttribute(vars) instead of just ->create(). I'm just saying, when you don't work with a product, or a category built in stuff, things get a little weird.
– CarComp
Apr 8 '16 at 13:53
1
Not all objects will require a factory. For ones that do, the factory may not exist out-of-box -- any that don't exist will be created at runtime (with DI generation), or during compilation. Read the article I linked. Any way about it, you need to learn to work with Magento2, not against it. Yes, there is a learning curve. If you don't already, I strongly recommend picking up PhpStorm or a similar IDE.
– Ryan Hoerr
Apr 8 '16 at 14:03
|
show 1 more comment
1
You should be injecting ObjectFactory and create instances of Object from that, not injecting Object itself. ORM objects are not to be injected directly.
– Ryan Hoerr
Apr 1 '16 at 17:04
Which ObjectFactory? Theres like 50. I'm looking at MagentoFrameworkApiObjectFactory but it just looks like a wrapper for ObjectManager. I'm not sure why I wouldn't just implement the objectmanager itself. Theres SO many wrappers for wrappers of things in this new version.
– CarComp
Apr 8 '16 at 12:56
1
I was speaking in the abstract. Inject the Factory for your given object, not literally 'ObjectFactory'. You should inject the factory for each specific type you use, and create them as needed. Yes, it seems messy at first... but there are very good reasons for it. Beside, ECG code standards all but prohibit direct use of ObjectManager. See Alan Storm's article explaining the whole subject: alanstorm.com/magento_2_object_manager_instance_objects
– Ryan Hoerr
Apr 8 '16 at 13:05
What should I do when the objects I want to use do not have a factory? For instance, I can't find a way to 'factory' the options management stuff. MagentoEavModelAttributeFactory also uses a weird ->createAttribute(vars) instead of just ->create(). I'm just saying, when you don't work with a product, or a category built in stuff, things get a little weird.
– CarComp
Apr 8 '16 at 13:53
1
Not all objects will require a factory. For ones that do, the factory may not exist out-of-box -- any that don't exist will be created at runtime (with DI generation), or during compilation. Read the article I linked. Any way about it, you need to learn to work with Magento2, not against it. Yes, there is a learning curve. If you don't already, I strongly recommend picking up PhpStorm or a similar IDE.
– Ryan Hoerr
Apr 8 '16 at 14:03
1
1
You should be injecting ObjectFactory and create instances of Object from that, not injecting Object itself. ORM objects are not to be injected directly.
– Ryan Hoerr
Apr 1 '16 at 17:04
You should be injecting ObjectFactory and create instances of Object from that, not injecting Object itself. ORM objects are not to be injected directly.
– Ryan Hoerr
Apr 1 '16 at 17:04
Which ObjectFactory? Theres like 50. I'm looking at MagentoFrameworkApiObjectFactory but it just looks like a wrapper for ObjectManager. I'm not sure why I wouldn't just implement the objectmanager itself. Theres SO many wrappers for wrappers of things in this new version.
– CarComp
Apr 8 '16 at 12:56
Which ObjectFactory? Theres like 50. I'm looking at MagentoFrameworkApiObjectFactory but it just looks like a wrapper for ObjectManager. I'm not sure why I wouldn't just implement the objectmanager itself. Theres SO many wrappers for wrappers of things in this new version.
– CarComp
Apr 8 '16 at 12:56
1
1
I was speaking in the abstract. Inject the Factory for your given object, not literally 'ObjectFactory'. You should inject the factory for each specific type you use, and create them as needed. Yes, it seems messy at first... but there are very good reasons for it. Beside, ECG code standards all but prohibit direct use of ObjectManager. See Alan Storm's article explaining the whole subject: alanstorm.com/magento_2_object_manager_instance_objects
– Ryan Hoerr
Apr 8 '16 at 13:05
I was speaking in the abstract. Inject the Factory for your given object, not literally 'ObjectFactory'. You should inject the factory for each specific type you use, and create them as needed. Yes, it seems messy at first... but there are very good reasons for it. Beside, ECG code standards all but prohibit direct use of ObjectManager. See Alan Storm's article explaining the whole subject: alanstorm.com/magento_2_object_manager_instance_objects
– Ryan Hoerr
Apr 8 '16 at 13:05
What should I do when the objects I want to use do not have a factory? For instance, I can't find a way to 'factory' the options management stuff. MagentoEavModelAttributeFactory also uses a weird ->createAttribute(vars) instead of just ->create(). I'm just saying, when you don't work with a product, or a category built in stuff, things get a little weird.
– CarComp
Apr 8 '16 at 13:53
What should I do when the objects I want to use do not have a factory? For instance, I can't find a way to 'factory' the options management stuff. MagentoEavModelAttributeFactory also uses a weird ->createAttribute(vars) instead of just ->create(). I'm just saying, when you don't work with a product, or a category built in stuff, things get a little weird.
– CarComp
Apr 8 '16 at 13:53
1
1
Not all objects will require a factory. For ones that do, the factory may not exist out-of-box -- any that don't exist will be created at runtime (with DI generation), or during compilation. Read the article I linked. Any way about it, you need to learn to work with Magento2, not against it. Yes, there is a learning curve. If you don't already, I strongly recommend picking up PhpStorm or a similar IDE.
– Ryan Hoerr
Apr 8 '16 at 14:03
Not all objects will require a factory. For ones that do, the factory may not exist out-of-box -- any that don't exist will be created at runtime (with DI generation), or during compilation. Read the article I linked. Any way about it, you need to learn to work with Magento2, not against it. Yes, there is a learning curve. If you don't already, I strongly recommend picking up PhpStorm or a similar IDE.
– Ryan Hoerr
Apr 8 '16 at 14:03
|
show 1 more comment
UPDATE 2016-09-11: As quickshiftin pointed out, this solution does not work for M2.1+. Attempting to dependency-inject the CategorySetup
class outside of setup will give you a fatal error. See here for a more robust solution: https://magento.stackexchange.com/a/103951/1905
Use the MagentoCatalogSetupCategorySetup
class for this. It includes an addAttributeOption()
method, which works exactly the same way as eav/entity_setup::addAttributeOption()
in 1.x. There are some other attribute methods there that might be helpful as well.
You can use dependency injection to get this class at any time, even outside a setup process.
Specifically:
/**
* Constructor.
*
* @param MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository
* @param MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
*/
public function __construct(
MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository,
MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
) {
$this->attributeRepository = $attributeRepository;
$this->categorySetupFactory = $categorySetupFactory;
}
/**
* Create a matching attribute option
*
* @param string $attributeCode Attribute the option should exist in
* @param string $label Label to add
* @return void
*/
public function addOption($attributeCode, $label) {
$attribute = $this->attributeRepository->get($attributeCode);
$categorySetup = $this->categorySetupFactory->create();
$categorySetup->addAttributeOption(
[
'attribute_id' => $attribute->getAttributeId(),
'order' => [0],
'value' => [
[
0 => $label, // store_id => label
],
],
]
);
}
If desired, you could eliminate the attributeRepository
class and use getAttribute()
directly on categorySetup
. You'd just have to include the entity type ID each time.
Hi Ryan, I'm trying to use theCategorySetupFactory
to instantiate aCategorySetup
from aConsoleCommand
, however when I call$factory->setup()
a fatal error occurs:PHP Fatal error: Uncaught TypeError: Argument 1 passed to MagentoSetupModuleDataSetup::__construct() must be an instance of MagentoFrameworkModuleSetupContext, instance of MagentoFrameworkObjectManagerObjectManager given
– quickshiftin
Sep 10 '16 at 21:50
Ahh, I've now stumbled upon this thread in which you state this stopped working in Magento 2.1 (which I'm using). Revising my code now, but prob best to put a note on this answer to that effect as well...
– quickshiftin
Sep 10 '16 at 22:24
add a comment |
UPDATE 2016-09-11: As quickshiftin pointed out, this solution does not work for M2.1+. Attempting to dependency-inject the CategorySetup
class outside of setup will give you a fatal error. See here for a more robust solution: https://magento.stackexchange.com/a/103951/1905
Use the MagentoCatalogSetupCategorySetup
class for this. It includes an addAttributeOption()
method, which works exactly the same way as eav/entity_setup::addAttributeOption()
in 1.x. There are some other attribute methods there that might be helpful as well.
You can use dependency injection to get this class at any time, even outside a setup process.
Specifically:
/**
* Constructor.
*
* @param MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository
* @param MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
*/
public function __construct(
MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository,
MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
) {
$this->attributeRepository = $attributeRepository;
$this->categorySetupFactory = $categorySetupFactory;
}
/**
* Create a matching attribute option
*
* @param string $attributeCode Attribute the option should exist in
* @param string $label Label to add
* @return void
*/
public function addOption($attributeCode, $label) {
$attribute = $this->attributeRepository->get($attributeCode);
$categorySetup = $this->categorySetupFactory->create();
$categorySetup->addAttributeOption(
[
'attribute_id' => $attribute->getAttributeId(),
'order' => [0],
'value' => [
[
0 => $label, // store_id => label
],
],
]
);
}
If desired, you could eliminate the attributeRepository
class and use getAttribute()
directly on categorySetup
. You'd just have to include the entity type ID each time.
Hi Ryan, I'm trying to use theCategorySetupFactory
to instantiate aCategorySetup
from aConsoleCommand
, however when I call$factory->setup()
a fatal error occurs:PHP Fatal error: Uncaught TypeError: Argument 1 passed to MagentoSetupModuleDataSetup::__construct() must be an instance of MagentoFrameworkModuleSetupContext, instance of MagentoFrameworkObjectManagerObjectManager given
– quickshiftin
Sep 10 '16 at 21:50
Ahh, I've now stumbled upon this thread in which you state this stopped working in Magento 2.1 (which I'm using). Revising my code now, but prob best to put a note on this answer to that effect as well...
– quickshiftin
Sep 10 '16 at 22:24
add a comment |
UPDATE 2016-09-11: As quickshiftin pointed out, this solution does not work for M2.1+. Attempting to dependency-inject the CategorySetup
class outside of setup will give you a fatal error. See here for a more robust solution: https://magento.stackexchange.com/a/103951/1905
Use the MagentoCatalogSetupCategorySetup
class for this. It includes an addAttributeOption()
method, which works exactly the same way as eav/entity_setup::addAttributeOption()
in 1.x. There are some other attribute methods there that might be helpful as well.
You can use dependency injection to get this class at any time, even outside a setup process.
Specifically:
/**
* Constructor.
*
* @param MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository
* @param MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
*/
public function __construct(
MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository,
MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
) {
$this->attributeRepository = $attributeRepository;
$this->categorySetupFactory = $categorySetupFactory;
}
/**
* Create a matching attribute option
*
* @param string $attributeCode Attribute the option should exist in
* @param string $label Label to add
* @return void
*/
public function addOption($attributeCode, $label) {
$attribute = $this->attributeRepository->get($attributeCode);
$categorySetup = $this->categorySetupFactory->create();
$categorySetup->addAttributeOption(
[
'attribute_id' => $attribute->getAttributeId(),
'order' => [0],
'value' => [
[
0 => $label, // store_id => label
],
],
]
);
}
If desired, you could eliminate the attributeRepository
class and use getAttribute()
directly on categorySetup
. You'd just have to include the entity type ID each time.
UPDATE 2016-09-11: As quickshiftin pointed out, this solution does not work for M2.1+. Attempting to dependency-inject the CategorySetup
class outside of setup will give you a fatal error. See here for a more robust solution: https://magento.stackexchange.com/a/103951/1905
Use the MagentoCatalogSetupCategorySetup
class for this. It includes an addAttributeOption()
method, which works exactly the same way as eav/entity_setup::addAttributeOption()
in 1.x. There are some other attribute methods there that might be helpful as well.
You can use dependency injection to get this class at any time, even outside a setup process.
Specifically:
/**
* Constructor.
*
* @param MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository
* @param MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
*/
public function __construct(
MagentoCatalogApiProductAttributeRepositoryInterface $attributeRepository,
MagentoCatalogSetupCategorySetupFactory $categorySetupFactory
) {
$this->attributeRepository = $attributeRepository;
$this->categorySetupFactory = $categorySetupFactory;
}
/**
* Create a matching attribute option
*
* @param string $attributeCode Attribute the option should exist in
* @param string $label Label to add
* @return void
*/
public function addOption($attributeCode, $label) {
$attribute = $this->attributeRepository->get($attributeCode);
$categorySetup = $this->categorySetupFactory->create();
$categorySetup->addAttributeOption(
[
'attribute_id' => $attribute->getAttributeId(),
'order' => [0],
'value' => [
[
0 => $label, // store_id => label
],
],
]
);
}
If desired, you could eliminate the attributeRepository
class and use getAttribute()
directly on categorySetup
. You'd just have to include the entity type ID each time.
edited Apr 13 '17 at 12:55
Community♦
1
1
answered Feb 9 '16 at 18:27
Ryan HoerrRyan Hoerr
8,42433042
8,42433042
Hi Ryan, I'm trying to use theCategorySetupFactory
to instantiate aCategorySetup
from aConsoleCommand
, however when I call$factory->setup()
a fatal error occurs:PHP Fatal error: Uncaught TypeError: Argument 1 passed to MagentoSetupModuleDataSetup::__construct() must be an instance of MagentoFrameworkModuleSetupContext, instance of MagentoFrameworkObjectManagerObjectManager given
– quickshiftin
Sep 10 '16 at 21:50
Ahh, I've now stumbled upon this thread in which you state this stopped working in Magento 2.1 (which I'm using). Revising my code now, but prob best to put a note on this answer to that effect as well...
– quickshiftin
Sep 10 '16 at 22:24
add a comment |
Hi Ryan, I'm trying to use theCategorySetupFactory
to instantiate aCategorySetup
from aConsoleCommand
, however when I call$factory->setup()
a fatal error occurs:PHP Fatal error: Uncaught TypeError: Argument 1 passed to MagentoSetupModuleDataSetup::__construct() must be an instance of MagentoFrameworkModuleSetupContext, instance of MagentoFrameworkObjectManagerObjectManager given
– quickshiftin
Sep 10 '16 at 21:50
Ahh, I've now stumbled upon this thread in which you state this stopped working in Magento 2.1 (which I'm using). Revising my code now, but prob best to put a note on this answer to that effect as well...
– quickshiftin
Sep 10 '16 at 22:24
Hi Ryan, I'm trying to use the
CategorySetupFactory
to instantiate a CategorySetup
from a ConsoleCommand
, however when I call $factory->setup()
a fatal error occurs: PHP Fatal error: Uncaught TypeError: Argument 1 passed to MagentoSetupModuleDataSetup::__construct() must be an instance of MagentoFrameworkModuleSetupContext, instance of MagentoFrameworkObjectManagerObjectManager given
– quickshiftin
Sep 10 '16 at 21:50
Hi Ryan, I'm trying to use the
CategorySetupFactory
to instantiate a CategorySetup
from a ConsoleCommand
, however when I call $factory->setup()
a fatal error occurs: PHP Fatal error: Uncaught TypeError: Argument 1 passed to MagentoSetupModuleDataSetup::__construct() must be an instance of MagentoFrameworkModuleSetupContext, instance of MagentoFrameworkObjectManagerObjectManager given
– quickshiftin
Sep 10 '16 at 21:50
Ahh, I've now stumbled upon this thread in which you state this stopped working in Magento 2.1 (which I'm using). Revising my code now, but prob best to put a note on this answer to that effect as well...
– quickshiftin
Sep 10 '16 at 22:24
Ahh, I've now stumbled upon this thread in which you state this stopped working in Magento 2.1 (which I'm using). Revising my code now, but prob best to put a note on this answer to that effect as well...
– quickshiftin
Sep 10 '16 at 22:24
add a comment |
Magento 2 add Specific attribute option Value programmatically.
Run this Script in root directory of magento after url.
$objectManager = MagentoFrameworkAppObjectManager::getInstance(); // instance of object manager
try{
$entityType = 'catalog_product';
$attributeCode = 'manufacturer';
$attributeInfo = $objectManager->get(MagentoEavModelEntityAttribute::class)
->loadByCode($entityType, $attributeCode);
$attributeFactory = $objectManager->get('MagentoCatalogModelResourceModelEavAttribute');
$attributeId = $attributeInfo->getAttributeId();
//$manufacturer = $item->{'Manufacturer'};
$attribute_arr = ['aaa','bbb','ccc','ddd'];
$option = array();
$option['attribute_id'] = $attributeId;
foreach($attribute_arr as $key=>$value){
$option['value'][$value][0]=$value;
foreach($storeManager as $store){
$option['value'][$value][$store->getId()] = $value;
}
}
if ($option) {
$eavSetupFactory = $objectManager->create('MagentoEavSetupEavSetup');
print_r($eavSetupFactory->getAttributeOption());
die();
$eavSetupFactory->addAttributeOption($option);
}
}catch(Exception $e){
echo $e->getMessage();
}
add a comment |
Magento 2 add Specific attribute option Value programmatically.
Run this Script in root directory of magento after url.
$objectManager = MagentoFrameworkAppObjectManager::getInstance(); // instance of object manager
try{
$entityType = 'catalog_product';
$attributeCode = 'manufacturer';
$attributeInfo = $objectManager->get(MagentoEavModelEntityAttribute::class)
->loadByCode($entityType, $attributeCode);
$attributeFactory = $objectManager->get('MagentoCatalogModelResourceModelEavAttribute');
$attributeId = $attributeInfo->getAttributeId();
//$manufacturer = $item->{'Manufacturer'};
$attribute_arr = ['aaa','bbb','ccc','ddd'];
$option = array();
$option['attribute_id'] = $attributeId;
foreach($attribute_arr as $key=>$value){
$option['value'][$value][0]=$value;
foreach($storeManager as $store){
$option['value'][$value][$store->getId()] = $value;
}
}
if ($option) {
$eavSetupFactory = $objectManager->create('MagentoEavSetupEavSetup');
print_r($eavSetupFactory->getAttributeOption());
die();
$eavSetupFactory->addAttributeOption($option);
}
}catch(Exception $e){
echo $e->getMessage();
}
add a comment |
Magento 2 add Specific attribute option Value programmatically.
Run this Script in root directory of magento after url.
$objectManager = MagentoFrameworkAppObjectManager::getInstance(); // instance of object manager
try{
$entityType = 'catalog_product';
$attributeCode = 'manufacturer';
$attributeInfo = $objectManager->get(MagentoEavModelEntityAttribute::class)
->loadByCode($entityType, $attributeCode);
$attributeFactory = $objectManager->get('MagentoCatalogModelResourceModelEavAttribute');
$attributeId = $attributeInfo->getAttributeId();
//$manufacturer = $item->{'Manufacturer'};
$attribute_arr = ['aaa','bbb','ccc','ddd'];
$option = array();
$option['attribute_id'] = $attributeId;
foreach($attribute_arr as $key=>$value){
$option['value'][$value][0]=$value;
foreach($storeManager as $store){
$option['value'][$value][$store->getId()] = $value;
}
}
if ($option) {
$eavSetupFactory = $objectManager->create('MagentoEavSetupEavSetup');
print_r($eavSetupFactory->getAttributeOption());
die();
$eavSetupFactory->addAttributeOption($option);
}
}catch(Exception $e){
echo $e->getMessage();
}
Magento 2 add Specific attribute option Value programmatically.
Run this Script in root directory of magento after url.
$objectManager = MagentoFrameworkAppObjectManager::getInstance(); // instance of object manager
try{
$entityType = 'catalog_product';
$attributeCode = 'manufacturer';
$attributeInfo = $objectManager->get(MagentoEavModelEntityAttribute::class)
->loadByCode($entityType, $attributeCode);
$attributeFactory = $objectManager->get('MagentoCatalogModelResourceModelEavAttribute');
$attributeId = $attributeInfo->getAttributeId();
//$manufacturer = $item->{'Manufacturer'};
$attribute_arr = ['aaa','bbb','ccc','ddd'];
$option = array();
$option['attribute_id'] = $attributeId;
foreach($attribute_arr as $key=>$value){
$option['value'][$value][0]=$value;
foreach($storeManager as $store){
$option['value'][$value][$store->getId()] = $value;
}
}
if ($option) {
$eavSetupFactory = $objectManager->create('MagentoEavSetupEavSetup');
print_r($eavSetupFactory->getAttributeOption());
die();
$eavSetupFactory->addAttributeOption($option);
}
}catch(Exception $e){
echo $e->getMessage();
}
answered 2 mins ago
AB SaiyadAB Saiyad
594
594
add a comment |
add a comment |
Thanks for contributing an answer to Magento Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f95124%2fhow-magento2-add-attribute-option-programmatically-not-in-setup%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
option added any value as string not supported for integer
– Ajay Patel
Nov 22 '17 at 3:38