Ryan Hが提案したObjectFactoryメソッドを使用して、この答え全体を書き直しました。
最終的には、顧客オブジェクトで作成したいくつかの属性を使用するヘルパークラスになりましたが、EAV + ObjectFactoriesを使用して属性オプションを操作する方法についてのアイデアがあります
<?php
namespace Stti\Healthday\Helper {
use Magento\Eav\Model\Entity\AttributeFactory;
use Magento\Eav\Model\Entity\Attribute\OptionFactory;
use Magento\Eav\Model\Entity\Attribute\OptionManagementFactory;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Eav\Model\Entity\Attribute;
use Stti\Healthday\Model\RelationFactory;
/**
* 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;
}
}
}