Magento 2 Add product attribute group and attribute programmatically

In this blogpost we will learn how to add product attribute group programmatically, Attribute group are created so that attributes can be clubbed in them and become more user friendly. As you can see in below image we have general, design, content etc as an attribute group.

Creating Attribute

Attribute group are managed in eav_attribute_group table and attributes are managed in eav_attribute. To add an attribute firstly you need to create an InstallData.php file as per the mentioned path

Vendor\Modulename\Setup\InstallData.php

Add the below code to create an attribute

<?php
namespace W3solver\Callforprice\Setup;

use Magento\Eav\Setup\EavSetupFactory;
use Magento\Catalog\Setup\CategorySetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface
{
    private $eavSetupFactory;
    private $categorySetupFactory;

    public function __construct(EavSetupFactory $eavSetupFactory, CategorySetupFactory $categorySetupFactory)
    {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->categorySetupFactory = $categorySetupFactory;
    }

    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        $eavSetup->addAttribute(
            \Magento\Catalog\Model\Product::ENTITY,
            'show_price',   /* Define the attribute code */
            [
                'type' => 'int', /*Define the datatype of attribute such as string, int*/
                'backend' => '',  /* Define the backend */
                'frontend' => '',
                'label' => 'Show Price', /* Provide the label of attribute to be used to show on frontend and admin*/
                'input' => 'select',  /*Define the formelement of attribute such as select,input,textbox */
                'class' => '', /* Add a class name if you want to provide any */
                'source' => 'Magento\Eav\Model\Entity\Attribute\Source\Boolean', /* If attribute is select or multiselect then to get the options detail provide the source */
                'global' => \Magento\Catalog\Model\ResourceModel\Eav\Attribute::SCOPE_GLOBAL,
                'visible' => true,
                'required' => false,
                'user_defined' => false,
                'default' => 0,
                'searchable' => false,
                'filterable' => false,
                'comparable' => false,
                'visible_on_front' => false,
                'used_in_product_listing' => false,
                'unique' => false,
                'apply_to' => ''
            ]
        );
     
    }
}

AddAttribute() function is responsible to add or create attribute to product, now let’s look how to show these attribute on product edit page in admin panel under a custom attribute group. In the install function after attribute group creation write the below code.

Creating attribute group

$groupName = 'Call For Price'; /* Label of your group*/
$entityTypeId = $eavSetup->getEntityTypeId('catalog_product'); /* get entity type id so that attribute are only assigned to catalog_product */
$attributeSetIds = $eavSetup->getAllAttributeSetIds($entityTypeId); /* Here we have fetched all attribute set as we want attribute group to show under all attribute set.*/

foreach($attributeSetIds as $attributeSetId) {
    $eavSetup->addAttributeGroup($entityTypeId, $attributeSetId, $groupName, 19);
    $attributeGroupId = $eavSetup->getAttributeGroupId($entityTypeId, $attributeSetId, $groupName);
    // Add existing attribute to group
    $attributeId = $eavSetup->getAttributeId($entityTypeId, 'show_price');
    $eavSetup->addAttributeToGroup($entityTypeId, $attributeSetId, $attributeGroupId, $attributeId, null);
}

Here you can view your attribute group and attributes in admin panel on product edit page

Note:- We can show attribute group by xml also which will have some custom html. We normally use setup file for adding those attributes to attribute group which we just want to get display under some different or custom group rather than predefined and for those group which we did not need to have any custom template.

Another way of creating attribute group

You can also create an attribute group and render a totally different view in it by using xml, for this you need to create an xml file catalog_product_edit.xml under mentioned path and add the below code

Vendorname\Modulename\view\adminhtml\layout
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceBlock name="product_form">
            <block class="W3solver\Callforprice\Block\Adminhtml\Catalog\Product\Edit\Tab\Callforprice" name="callforprice">
                <arguments>
                    <argument name="config" xsi:type="array">
                        <item name="label" xsi:type="string" translate="true">Call For Price</item>
                        <item name="collapsible" xsi:type="boolean">true</item>
                        <item name="opened" xsi:type="boolean">false</item>
                        <item name="sortOrder" xsi:type="string">19</item>
                        <item name="canShow" xsi:type="boolean">true</item>
                        <item name="componentType" xsi:type="string">fieldset</item>
                    </argument>
                </arguments>
            </block>
        </referenceBlock>
    </body>
</page>

Above code will add a callforprice group and in callforprice block class file we can define the name of template file we want to render.

Drop in the comment if you have any query, or found any discrepancy in the post.

PHP – Verify ZipCode using USPS service

United state postal service (USPS) is an independent agency of the United States federal government responsible for providing postal service in the United States. USPS has APIs you can use this API to validate the Zip Code.

How to use this:

You have to create your account on USPS. Once you will done with account creation you will get an email with your username and password.

http://production.shippingapis.com/ShippingAPI.dll?API=CityStateLookup&XML=<CityStateLookupRequest%20USERID=" xxxxxxxxxxxx"> 90210

But soon you will find that this URL will on on browser. You can’t access this URL, you will get error “URL not format properly”. Please find the solution below for this.

$input_xml = <<<EOXML
               <CityStateLookupRequest USERID=" 850BIGMO0558">
               <ZipCode ID= "0">
               <Zip5>$zipcode</Zip5>
               </ZipCode>
              </CityStateLookupRequest>
EOXML;

        $fields = array(
                'API' => 'CityStateLookup',
                'XML' => $input_xml
            );
        $url = 'http://production.shippingapis.com/ShippingAPITest.dll?' . http_build_query($fields);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 300);
        $data = curl_exec($ch);
        curl_close($ch);

    // Convert the XML result into array
    $array_data = json_decode(json_encode(simplexml_load_string($data)), true);
    echo  $array_data['ZipCode']['State'];

It will return the state name.