Programmatically (manually) creating Configurable Magento 2 Product - magento2

Programmatically (manually) creating Configurable Magento 2 Product :
The Product are generated correctly, but I am facing issue with, not generating product Configuration Details.
This Configuration details will help to generate the relation between Configurable product and associate Child Products, these part not working while programmatically create the Product.
Please suggest solution for this issue.
Please find my below code:
<?php
ini_set("display_errors",1);
$magentoDirPath=dirname(dirname(__FILE__));
use \Magento\Framework\App\Bootstrap;
include($magentoDirPath.'/app/bootstrap.php'); // File Path
// add bootstrap
$bootstraps = Bootstrap::create(BP, $_SERVER);
$object_Manager = $bootstraps->getObjectManager();
$app_state = $object_Manager->get('\Magento\Framework\App\State');
$app_state->setAreaCode('frontend');
//simple product
$simple_product = $object_Manager->create('\Magento\Catalog\Model\Product');
$simple_product->setSku('test-simple-randdd');
$simple_product->setName('test name simple');
$simple_product->setAttributeSetId(4);
$simple_product->setColor(4); // value id of S size
$simple_product->setStatus(1);
$simple_product->setTypeId('simple');
$simple_product->setPrice(10);
$simple_product->setWebsiteIds(array(1));
$simple_product->setCategoryIds(array(4,5));
$simple_product->setStockData(array(
'use_config_manage_stock' => 0, //'Use config settings' checkbox
'manage_stock' => 1, //manage stock
'min_sale_qty' => 1, //Minimum Qty Allowed in Shopping Cart
'max_sale_qty' => 2, //Maximum Qty Allowed in Shopping Cart
'is_in_stock' => 1, //Stock Availability
'qty' => 100 //qty
)
);
$simple_product->save();
$simple_product_id = $simple_product->getId();
echo "simple product id: ".$simple_product_id."\n";
//configurable product
$configurable_product = $object_Manager->create('\Magento\Catalog\Model\Product');
$configurable_product->setSku('test-configurable');
$configurable_product->setName('test name configurable');
$configurable_product->setAttributeSetId(4);
$configurable_product->setColor(4); // value id of S size
$configurable_product->setStatus(1);
$configurable_product->setTypeId('configurable');
$configurable_product->setPrice(11);
$configurable_product->setWebsiteIds(array(1));
$configurable_product->setCategoryIds(array(4,5));
$configurable_product->setStockData(array(
'use_config_manage_stock' => 0, //'Use config settings' checkbox
'manage_stock' => 1, //manage stock
'min_sale_qty' => 1, //Minimum Qty Allowed in Shopping Cart
'max_sale_qty' => 2, //Maximum Qty Allowed in Shopping Cart
'is_in_stock' => 1, //Stock Availability
'qty' => 100 //qty
)
);
$configurable_product->getTypeInstance()->setUsedProductAttributeIds(array(93),$configurable_product); //attribute ID of attribute 'size_general' in my store
$configurableAttributesData = $configurable_product->getTypeInstance()->getConfigurableAttributesAsArray($configurable_product);
$configurable_product->setCanSaveConfigurableAttributes(true);
$configurable_product->setConfigurableAttributesData($configurableAttributesData);
$configurableProductsData = array();
$configurableProductsData[$simple_product_id] = array(
'0' => array(
'label' => 'Color', //attribute label
'attribute_id' => '93', //attribute ID of attribute 'size_general' in my store
'value_index' => '4', //value of 'S' index of the attribute 'size_general'
'is_percent' => 0,
'pricing_value' => '10',
)
);
// 1 - Static ID of Product
$configurableProductsData['1'] = array(
'0' => array(
'label' => 'Color', //attribute label
'attribute_id' => '93', //attribute ID of attribute 'size_general' in my store
'value_index' => '5', //value of 'S' index of the attribute 'size_general'
'is_percent' => 0,
'pricing_value' => '10',
)
);
// 91 - Static ID of Product
$configurableProductsData['91'] = array(
'0' => array(
'label' => 'Color', //attribute label
'attribute_id' => '93', //attribute ID of attribute 'size_general' in my store
'value_index' => '6', //value of 'S' index of the attribute 'size_general'
'is_percent' => 0,
'pricing_value' => '10', ini_set("display_errors",1);
$magentoDirPath=dirname(dirname(__FILE__));
use \Magento\Framework\App\Bootstrap;
include($magentoDirPath.'/app/bootstrap.php'); // File Path
// add bootstrap
$bootstraps = Bootstrap::create(BP, $_SERVER);
$object_Manager = $bootstraps->getObjectManager();
$app_state = $object_Manager->get('\Magento\Framework\App\State');
$app_state->setAreaCode('frontend');
//simple product
$simple_product = $object_Manager->create('\Magento\Catalog\Model\Product');
$simple_product->setSku('test-simple-randdd');
$simple_product->setName('test name simple');
$simple_product->setAttributeSetId(4);
$simple_product->setColor(4); // value id of S size
$simple_product->setStatus(1);
$simple_product->setTypeId('simple');
$simple_product->setPrice(10);
$simple_product->setWebsiteIds(array(1));
$simple_product->setCategoryIds(array(4,5));
$simple_product->setStockData(array(
'use_config_manage_stock' => 0, //'Use config settings' checkbox
'manage_stock' => 1, //manage stock
'min_sale_qty' => 1, //Minimum Qty Allowed in Shopping Cart
'max_sale_qty' => 2, //Maximum Qty Allowed in Shopping Cart
'is_in_stock' => 1, //Stock Availability
'qty' => 100 //qty
)
);
$simple_product->save();
$simple_product_id = $simple_product->getId();
echo "simple product id: ".$simple_product_id."\n";
//configurable product
$configurable_product = $object_Manager->create('\Magento\Catalog\Model\Product');
$configurable_product->setSku('test-configurable');
$configurable_product->setName('test name configurable');
$configurable_product->setAttributeSetId(4);
$configurable_product->setColor(4); // value id of S size
$configurable_product->setStatus(1);
$configurable_product->setTypeId('configurable');
$configurable_product->setPrice(11);
$configurable_product->setWebsiteIds(array(1));
$configurable_product->setCategoryIds(array(4,5));
$configurable_product->setStockData(array(
'use_config_manage_stock' => 0, //'Use config settings' checkbox
'manage_stock' => 1, //manage stock
'min_sale_qty' => 1, //Minimum Qty Allowed in Shopping Cart
'max_sale_qty' => 2, //Maximum Qty Allowed in Shopping Cart
'is_in_stock' => 1, //Stock Availability
'qty' => 100 //qty
)
);
$configurable_product->getTypeInstance()->setUsedProductAttributeIds(array(93),$configurable_product); //attribute ID of attribute 'size_general' in my store
$configurableAttributesData = $configurable_product->getTypeInstance()->getConfigurableAttributesAsArray($configurable_product);
$configurable_product->setCanSaveConfigurableAttributes(true);
$configurable_product->setConfigurableAttributesData($configurableAttributesData);
$configurableProductsData = array();
$configurableProductsData[$simple_product_id] = array(
'0' => array(
'label' => 'Color', //attribute label
'attribute_id' => '93', //attribute ID of attribute 'size_general' in my store
'value_index' => '4', //value of 'S' index of the attribute 'size_general'
'is_percent' => 0,
'pricing_value' => '10',
)
);
// 1 - Static ID of Product
$configurableProductsData['1'] = array(
'0' => array(
'label' => 'Color', //attribute label
'attribute_id' => '93', //attribute ID of attribute 'size_general' in my store
'value_index' => '5', //value of 'S' index of the attribute 'size_general'
'is_percent' => 0,
'pricing_value' => '10',
)
);
// 91 - Static ID of Product
$configurableProductsData['91'] = array(
'0' => array(
'label' => 'Color', //attribute label
'attribute_id' => '93', //attribute ID of attribute 'size_general' in my store
'value_index' => '6', //value of 'S' index of the attribute 'size_general'
'is_percent' => 0,
'pricing_value' => '10',
)
);
$configurable_product->setConfigurableProductsData($configurableProductsData);
$associatedProductIds =array($simple_product_id,'1','91');
$configurable_product->setCanSaveConfigurableAttributes(true);
$configurable_product->getTypeInstance()->setUsedProductAttributeIds(array(93), $configurable_product);
$configurable_product->setNewVariationsAttributeSetId($configurable_product->getAttributeSetId());
$configurable_product->setAssociatedProductIds($associatedProductIds);
$configurable_product->setConfigurableAttributesData($configurableAttributesData);
$configurable_product->save();
$configProductId = $configurable_product->getId();
echo "Product id: ".$configurable_product->getId()."\n";
exit;
)
);
$configurable_product->setConfigurableProductsData($configurableProductsData);
$associatedProductIds =array($simple_product_id,'1','91');
$configurable_product->setCanSaveConfigurableAttributes(true);
$configurable_product->getTypeInstance()->setUsedProductAttributeIds(array(93), $configurable_product);
$configurable_product->setNewVariationsAttributeSetId($configurable_product->getAttributeSetId());
$configurable_product->setAssociatedProductIds($associatedProductIds);
$configurable_product->setConfigurableAttributesData($configurableAttributesData);
$configurable_product->save();
$configProductId = $configurable_product->getId();
echo "Product id: ".$configurable_product->getId()."\n";
exit;
?>

must be done by product repository
working code below
ids of simples are defined here: $associatedProductIds=array(2042, 2044);
attribute is color, must be in default attribute set, can be more then 1 if you duplicate attributeValues array and add it here:
$configurableAttributesData = []
$ob = ObjectManager::getInstance();
/** #var $installer \Magento\Catalog\Setup\CategorySetup */
$installer = $ob->create('Magento\Catalog\Setup\CategorySetup');
/** #var ProductRepositoryInterface $productRepository */
$productRepository = $ob->create(ProductRepositoryInterface::class);
/** #var $installer CategorySetup */
$installer = $ob->create(CategorySetup::class);
/* Create simple products per each option value*/
/** #var AttributeOptionInterface[] $options */
$attributeSetId = $installer->getAttributeSetId('catalog_product', 'Default');
$eavConfig = $ob->get('Magento\Eav\Model\Config');
$attribute = $eavConfig->getAttribute('catalog_product', 'color');
$options = $attribute->getOptions();
array_shift($options); //remove the first option which is empty
$attributeValues = [];
foreach ($options as $option) {
$attributeValues[] = [
'label' => 'test',
'attribute_id' => $attribute->getId(),
'value_index' => $option->getValue(),
];
}
$associatedProductIds=array(2042, 2044);
/** #var Factory $optionsFactory */
$optionsFactory = $ob->create(Factory::class);
$configurableAttributesData = [
[
'attribute_id' => $attribute->getId(),
'code' => $attribute->getAttributeCode(),
'label' => $attribute->getStoreLabel(),
'position' => '0',
'values' => $attributeValues,
],
];
/** #var $product Product */
$product = $ob->create(Product::class);
$configurableOptions = $optionsFactory->create($configurableAttributesData);
$extensionConfigurableAttributes = $product->getExtensionAttributes();
$extensionConfigurableAttributes->setConfigurableProductOptions($configurableOptions);
$extensionConfigurableAttributes->setConfigurableProductLinks($associatedProductIds);
$product->setExtensionAttributes($extensionConfigurableAttributes);
$product->setTypeId(Configurable::TYPE_CODE)
->setAttributeSetId($attributeSetId)
->setWebsiteIds([1])
->setName('Connewfcolor')
->setSku('configcolor')
->setVisibility(Visibility::VISIBILITY_BOTH)
->setStatus(Status::STATUS_ENABLED)
->setStockData(['use_config_manage_stock' => 1, 'is_in_stock' => 1]);
$productRepository->save($product);

Related

How can I save dynamically created Gravity Form fields into entries content?

The code below successfully creates a dynamic field and for a Gravity Form, and on submission the dynamic field data is included in the email content sent. However the dynamic field isn't saved in the "entries" data for that form submission, only the fields created manually using the plugin are. Anyone know how to include this data in the entries data saved?
add_filter('gform_pre_render_5', 'populate_wines');
add_filter('gform_pre_validation_5', 'populate_wines');
function populate_wines($form) {
// create dynamic select field
$props = array(
'id' => 51,
'type' => 'select',
'label' => 'Dynamic field label',
'choices' => array(
array(
'text' => '',
'value' => '',
),
array(
'text' => '1',
'value' => '1',
),
array(
'text' => '2',
'value' => '2',
),
array(
'text' => '3',
'value' => '3',
),
)
);
$new_field = GF_Fields::create( $props );
$form['fields'][] = $new_field;
return $form;
}
Edit: Dave's solution below works great for the above function (thanks!!), but adding to the function to include the looped wine list (code below), it doesn't work, any ideas?
function populate_wines($form) {
// options for select lists
$select_choices = array(
array(
'text' => '',
'value' => '',
),
array(
'text' => '1',
'value' => '1',
),
array(
'text' => '2',
'value' => '2',
),
array(
'text' => '3',
'value' => '3',
),
);
// loop through wine list
if( have_rows('wine_options') ):
$wine_count = 50;
while( have_rows('wine_options') ) : the_row();
$wine_ID = get_sub_field('wine_option');
$wine_name = get_the_title($wine_ID);
// create wine select field
$props = array(
'id' => $wine_count,
'type' => 'select',
'label' => $wine_name,
'choices' => $select_choices
);
$new_field = GF_Fields::create( $props );
$form['fields'][] = $new_field;
$wine_count++;
endwhile;
endif;
if ( GFForms::get_page() !== 'form_editor' ) {
return $form;
}
}
You'll need to call the same function on the gform_admin_pre_render filter. My recommendation would be to also add a check to exclude it from being output in the form editor but you may want that. If you don't, it'd look something like this:
if ( GFForms::get_page() !== 'form_editor' ) {
return $form;
}

Separates cart CodeIgniter based store

I am trying to build a cart system, after successfully entering the item to the cart. how can I display items according shop. I was a bit constrained here.
Controllers
function to_cart () {
$data = array(
array(
'id' => '1',
'qty' => 1,
'price' => 2.400,
'name' => 'Asus Eeepc',
'store' => 'My_store 1'
),
array(
'id' => '2',
'qty' => 1,
'price' => 1.500,
'name' => 'Accer AspireOne',
'store' => 'My_store 1'
),
array(
'id' => '3',
'qty' => 1,
'price' => 4.000,
'name' => 'Toshiba Satelite',
'store' => 'My_store 2'
),
array(
'id' => '4',
'qty' => 1,
'price' => 2.700,
'name' => 'Lenova ThinkCare',
'store' => 'My_store 1'
)
);
$this->cart->insert($data);
redirect($this->agent->referrer());
}
Views
<?php foreach ($this->cart->contents() as $item) {
echo '<td>'.$item['no'].'</td>';
echo '<td>'.$item['name'].'</td>';
echo '<td>'.$item['price'].'</td>';
echo '<td>'.$item['qty'].'</td>';
echo '<td>'.$item['store'].'</td>';
?>

Value from custom column in TCA select

I created a select in Typo3 TCA, it's looks like this:
'company_address' => array(
'exclude' => 1,
'label' => 'Company Address',
'config' => array(
'type' => 'select',
'foreign_table' => 'pages',
'foreign_table_where' => ' AND doktype = 75',
'items' => array(
array('', 0)
),
'maxitems' => 1
)
),
By default value = uid of record, how to change this ?
I need that value = my_column. Is it possible ?
You can use a itemProcFunc to build your select options like you need them to be. In your TCA you change the config:
'company_address' => array(
'config' => array(
'type' => 'select',
'itemsProcFunc' => 'Vendor\\MyExt\\UserFunc\\TcaProcFunc->companyAddressItems'
'maxitems' => 1
)
)
You can implement your custom function then. I'll give you an example
namespace Vendor\MyExt\UserFunc;
class TcaProcFunc
{
/**
* #param array $config
* #return array
*/
public function companyAddressItems($config)
{
$itemList = [];
$rows = $this->getMySpecialDokTypeRowsFromDb();
foreach ($rows as $row) {
$itemList[] = ['Label of the item', $row['my_column']];
}
$config['items'] = $itemList;
return $config;
}
}
Whatever you store in $config['items'] will be the item List in your select box. To make this (untested) example work you have of course implement the method getMySpecialDokTypeRowsFromDb().

new content element at content wizard

I have some problems with typo 7.6.2
I would like to add my own content elements to the content-element wizard.
My own extension with templates, partials, TypoScript... worked and the element is visible in the content-element wizard.
Content-element Wizard
If I choose the new element and click the place to add the following screen is shown.
(ext_tables.php):
TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile(
$_EXTKEY,
'Configuration/TypoScript',
'Template Extension'
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('
mod {
wizards.newContentElement.wizardItems.extra {
header = KCW Inhalte
elements {
mitglied {
icon = ../typo3/sysext/core/Resources/Public/Icons/T3Icons/content/content-header.svg
title = Mitglied
description = Ein Mitglied anlegen
tt_content_defValues {
CType = mitglied
}
}
}
show = *
}
}
');
"Configuration/TCA/Overrides/tt_content.php":
$TCA['mitglied'] = array(
'columns' => array(
'name' => array (
'exclude' => 1,
'label' => 'Vorname Name',
'config' => array (
'type' => 'input',
'size' => '20'
)
),
'spitzname' => array (
'exclude' => 1,
'label' => 'Spitzname',
'config' => array (
'type' => 'input',
'size' => '20'
)
),
'geburtstag' => array (
'exclude' => 1,
'label' => 'Geburtstag',
'config' => array (
'type' => 'input',
'size' => '10',
'eval' => 'date',
)
),
'posten' => array (
'exclude' => 1,
'label' => 'Posten',
'config' => array (
'type' => 'select',
'renderType' => 'selectSingle',
'items' => array (
array('Mitglied'),
array('Präsident'),
array('Kassenwart'),
array('Vergnügungsausschuss'),
),
'size' => 1,
'maxitems' => 1,
)
),
'foto' => array (
'exclude' => 1,
'label' => 'Foto',
'config' => array(
'type' => 'group',
'internal_type' => 'file',
'allowed' => 'jpg',
'max_size' => 1000,
'uploadfolder' => 'uploads/pics/',
'show_thumbs' => 1,
'size' => 3,
'minitems' => 1,
'maxitems' => 1,
'autoSizeMax' => 10,
)
),
),
'types' => array(
'0' => array('showitem' => 'name,spitzname,geburtstag,posten,foto')
)
);
\TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TCA']['tt_content'], $tcaTtContent);
I think the problem is located in these lines in ext_tables.php:
tt_content_defValues {
CType = mitglied
}
You have to allow the value mitglied as value of the field cType. The tt_content_devValues just sets the default values for the newly created content element.
TCEFORM.tt_content.cType.addItems.mitglied = Field title
https://docs.typo3.org/typo3cms/TSconfigReference/PageTsconfig/TCEform/Index.html#pagetceformconfobj

CakePHP Form Dropdown

I've got this table in my database that outputs this:
array(
(int) 0 => array(
'Price' => array(
'id' => '1',
'amount' => '20',
'price' => '180.00',
'type_id' => '1',
'active' => 'a'
)
),
(int) 1 => array(
'Price' => array(
'id' => '2',
'amount' => '30',
'price' => '232.50',
'type_id' => '1',
'active' => 'a'
)
),
...And so on.
I need a drop down in my form that displays the amount and price together (ie. "20 # 180.00"), but when selected, gets the "id" field.
I reworked a new array called $prices so it outputs like so...
array(
(int) 0 => array(
'id' => '1',
'amount' => '20',
'price' => '180.00',
'type_id' => '1',
'active' => 'a',
'display' => '20 # 180.00'
),
(int) 1 => array(
'id' => '2',
'amount' => '30',
'price' => '232.50',
'type_id' => '1',
'active' => 'a',
'display' => '30 # 232.50'
However, I'm not sure if that array is necessary.
But the main problem is that I don't know what to put in the Form options to make it select the "display" field.
echo $this->Form->input('Project.quantity', array(
'options' => $prices[?????]['display']
));
Simply adding the
'options' => $prices
displays a lot of stuff in the drop down (http://f.cl.ly/items/1e0X0m0D1f1c2o3K1n3h/Screen%20Shot%202013-05-08%20at%201.13.48%20PM.png).
Is there a better way of doing this?
You can use virtual fields.
In your model:
public $virtualFields = array(
'display' => 'CONCAT(amount, " # ", price)'
);
In the controller:
$prices = $this->Price->find('list', array(
'fields' => array('id', 'display')
));
Two ways to do this.
You said you reworked you array to $prices. Then, change that rework so the $prices array looks like this
array('1' => '4 # 6',
/*id*/ => /*price*/
/*etc*/);
and then pass it to the form
echo $this->Form->input('Project.quantity', array(
'options' => $prices
));
For a simple dropdown, retrieve the data with a find('list'). That will give you an array like the one you need to make a dropdown. To change the display field, create a virtual field like this in the model
public $virtualFields = array("display_price"=>"CONCAT(amount, ' # ' ,price)");
public $displayField = 'display_price';
And that way you don't have to rework your array.
If you have other drowpdowns of the same model in other forms, note that those will also change. That's the advantage of doing that in the model... Or disadvantage, if you only want to do it in one part... Like almost everything, it depends on what your need are :)