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.

Magento 2 add shipping price in condition on cart price rule

This blogpost provide you with the small code to add shipping price in condition on cart price rule. Sales price rule condition are in sales-rule module and can be found in below mentioned file

module-sales-rule\Model\Rule\Condition\Address.php

In this file you need to add a condition in loadAttributeOptions() function for shipping_amount as shown in below code:-

 $attributes = [
            'base_subtotal' => __('Subtotal'),
            'total_qty' => __('Total Items Quantity'),
            'weight' => __('Total Weight'),
            'payment_method' => __('Payment Method'),
            'shipping_method' => __('Shipping Method'),
            'postcode' => __('Shipping Postcode'),
            'region' => __('Shipping Region'),
            'region_id' => __('Shipping State/Province'),
            'country_id' => __('Shipping Country'),
            'shipping_amount' => __('Shipping Price'),
        ];

see the images below:-

Magento 2 add admin user Programatically

This blogpost has a code to add the admin user programatically, we just need to place the code in a file on our magento root directory.

<?php
// MAGENTO START
include('app\bootstrap.php');

use Magento\Framework\App\Bootstrap;

$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();

$appState = $objectManager->get("Magento\Framework\App\State");
$appState->setAreaCode("developer"); /* To set mode as developer */

$userFactory = $objectManager->create('\Magento\User\Model\UserFactory');
$adminInfo = [
    'username'  => 'arushi',
    'firstname' => 'arushi',
    'lastname'    => 'bansal',
    'email'     => 'arushi@w3solver.com',
    'password'  =>'hello@123',       
    'interface_locale' => 'en_US',
    'is_active' => 1
];

$userModel = $userFactory->create();
$userModel->setData($adminInfo);
$userModel->setRoleId(1);
 try{
   $userModel->save(); 
} catch (\Exception $ex) {
    $ex->getMessage();
}


Magento 2 some quick tips and code

Get value of any custom Attribute from customer or product

Sometime we face issue in fetching the custom attribute data from entities, thus to get that we have to join them as shown in below example:-
I want to fetch ‘code’ attribute data, which is a customer attribute. Then I have added a join to collection and specify the type of join we will be using

$this->object_manager->create('Magento\Customer\Model\Customer')->getCollection()
->addAttributeToSelect('code', 'left')
->getData();

Print the collection query

Most of the time we need to print collection query so that we can review what exactly is going on behind the scene, thus we will be using below code to do that:-

$collection->getSelect()->__toString();

Load a model using a different attribute such as sku

It is the most useful code, there are scenarios when we want to load module by using attribute other than id then we can simply use following code:-

$model->load(‘MAT-01’, ‘sku’);
// 1st parameter is the value and 2nd is the attribute code

Logging in magento2

Add a dependency injection of Logger Interface (\Psr\Log\LoggerInterface $logger) and then use below code:-

$this->_logger->emergency('some text or variable'); // when System is unusable
$this->_logger->alert('some text or variable'); // when Action must be taken immediately 
$this->_logger->critical('some text or variable'); // Critical conditions
$this->_logger->error('some text or variable'); //Runtime errors that do not require immediate action but should typically be logged and monitored.
$this->_logger->warning('some text or variable'); // Exceptional occurrences that are not errors
$this->_logger->notice('some text or variable'); // Normal but significant events
$this->_logger->info('some text or variable'); // Interesting events
$this->_logger->debug('some text or variable'); // Detailed debug information

Get collection of various entities

Get Customer Collection
$this->object_manager->create('Magento\Customer\Model\Customer')->getCollection();
Get Product Collection
$this->object_manager->create('Magento\Catalog\Model\Product')->getCollection()
Get Order Collection
$this->object_manager->create('Magento\Sales\Model\Order')
->getCollection()
Get Order payment Collection
$this->object_manager->create('Magento\Sales\Model\Order\Payment')
->getCollection()

Magento 2 QRCode Generator extension

QR code (Quick Response Code) is the matrix barcode which is a machine-readable optical label that contains information about the item in our case it will have url of the products.

General Features of the extension

• One of the good marketing tool to drive sales and provides a modern image to your brand
• Enticing the mobile consumers by letting them simply scan the QR code and shop even on the go
• Incorporate QR code poster ads, in-store display, print ads etc

Feature List

– QR Codes for every Product Detail Page
– QR Codes list page in admin to generate mass Qrcode and print option
– No other plugins needed
– Qrcode can be generated for individual product edit page

Qrcode User Guide

1.) Once installed you can review the Qrcode menu under (product > Qrcode > List Qrcode) and view all product list with Qrcode details. List page is created to provide an option to mass generate Qrcode or print them.

2.) You can also generate Qrcode from product edit page. There is a tab of Qrcode and button provided separately for each product.

3.) On frontend product detail page, Qrcode is also available under Qrcode tab similar to review tab.

Versions: I’ve tested the module with the version 2.1.5

click link to download the extension

Let me know if you found any issue or have any query.

Magento2 Add/Create and Get custom customer attribute value

To create a custom attribute for customer in magento, firstly we need to add a file in setup folder of our module and then add the given code. Below we are adding ‘is_vendor’ attribute which has two option yes/no.

 setup\InstallData.php 
namespace W3solver\Helloworld\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Customer\Model\Customer;
use Magento\Eav\Model\Entity\Attribute\Set as AttributeSet;
use Magento\Eav\Model\Entity\Attribute\SetFactory as AttributeSetFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface {
    
    const IS_VENDOR = 'is_vendor';
    private $eavSetupFactory;
    protected $customerSetupFactory;
    private $attributeSetFactory;

    public function __construct(
    EavSetupFactory $eavSetupFactory, CustomerSetupFactory $customerSetupFactory, AttributeSetFactory $attributeSetFactory
    ) {
        $this->eavSetupFactory = $eavSetupFactory;
        $this->customerSetupFactory = $customerSetupFactory;
        $this->attributeSetFactory = $attributeSetFactory;
    }

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

        $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
        $attributeSetId = $customerEntity->getDefaultAttributeSetId();

        $attributeSet = $this->attributeSetFactory->create();
        $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);

        $customerSetup->addAttribute(Customer::ENTITY, self::IS_VENDOR, [
            'type' => 'int',
            'label' => 'Is Vendor?',
            'input' => 'select',
            "source" => "W3solver\Helloworld\Model\Config\Source\CustomerYesNoOptions",
            'required' => false,
            'default' => '0',
            'visible' => true,
            'user_defined' => true,
            'sort_order' => 210,
            'position' => 210,
            'system' => false,
        ]);

        $is_vendor = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, self::IS_VENDOR)
                ->addData([
            'attribute_set_id' => $attributeSetId,
            'attribute_group_id' => $attributeGroupId,
            'used_in_forms' => ['adminhtml_customer', 'checkout_register', 'customer_account_create', 'customer_account_edit', 'adminhtml_checkout'],
        ]);

        $is_vendor->save();
        $setup->endSetup();
    }
}

Above code will add a new attribute to customer, it can be checked on customer edit page in admin panel. So lets see how to get the value of this attribute. Firstly you need to inject customer repository interface in constructor

\Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface

Now wherever you want to get the attribute value add the below code there:-

$customer = $this->customerRepositoryInterface->getById($customerId);
print_r($customer->getCustomAttribute('is_vendor')->getValue());


NOTE:-
Your code will only work for newly created customers because customer form has that attribute now and it will save its default value but already created customer did not have that attribute known to them, thus you need to write a small script to save all customer that were created previously and set whatever value you want for them. (this will be just one time process).

To set the value for the attribute to previous customer add the below code (try not to use object manager and inject those class through constructor:-

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $customerObj = $objectManager->create ('Magento\Customer\Model\Customer') ->getCollection ();
        foreach ($customerObj as $customerObjdata) {
            
            $customermodel = $objectManager->create ('Magento\Customer\Model\Customer');
            $customerData = $customermodel->getDataModel();
            $customerData->setId($customerObjdata->getData('entity_id'));
            $customerData->setCustomAttribute('is_vendor', 0);
            $customermodel->updateData($customerData);
            
            $customerResource = $objectManager->create ('\Magento\Customer\Model\ResourceModel\CustomerFactory')->create();
            $customerResource->saveAttribute($customermodel, 'is_vendor');
        }

Drop in your comments if you face any issue.

Magento add external URL to menu admin

I was just trying to add an external link on my admin menu panel and figured out that there is no direct option to add, we need to override some functionality to achieve this. So here is the solution I found out for the same. Unfortunately, we need to have a small module for this functionality:-

Firstly we need to overwrite the _buildMenuArray() function of Mage_Adminhtml_Block_Page_Menu class to add a condition for external url. So let’s start our modification:-

Create your config file to override the page menu class, as shown in below code:

<config>
    <modules>
        <W3solver_Menulink>
            <version>1.0.0</version>
        </W3solver_Menulink>
    </modules>
	
    <global>
        <blocks>
            <adminhtml>
                <rewrite>
                    <page_menu>W3solver_Menulink_Block_Adminhtml_Page_Menu</page_menu>
                </rewrite>
            </adminhtml>
        </blocks>
        <helpers>
            <menulink>
                <class>W3solver_Menulink_Helper</class> 
            </menulink>
        </helpers>
    </global>
</config>

Add a block file to override page menu, review line 40 for the modification:-

class W3solver_Menulink_Block_Adminhtml_Page_Menu extends Mage_Adminhtml_Block_Page_Menu {
    
    /**
     * Recursive Build Menu array
     *
     * @param Varien_Simplexml_Element $parent
     * @param string $path
     * @param int $level
     * @return array
     */
    protected function _buildMenuArray(Varien_Simplexml_Element $parent=null, $path='', $level=0)
    {
        if (is_null($parent)) {
            $parent = Mage::getSingleton('admin/config')->getAdminhtmlConfig()->getNode('menu');
        }

        $parentArr = array();
        $sortOrder = 0;
        foreach ($parent->children() as $childName => $child) {
            if (1 == $child->disabled) {
                continue;
            }

            $aclResource = 'admin/' . ($child->resource ? (string)$child->resource : $path . $childName);
            if (!$this->_checkAcl($aclResource) || !$this->_isEnabledModuleOutput($child)) {
                continue;
            }

            if ($child->depends && !$this->_checkDepends($child->depends)) {
                continue;
            }

            $menuArr = array();

            $menuArr['label'] = $this->_getHelperValue($child);

            $menuArr['sort_order'] = $child->sort_order ? (int)$child->sort_order : $sortOrder;

            /* condition added to manage external url*/
            if ($child->external_url) {
                $menuArr['url'] = (string)$child->external_url;
            } else if ($child->action) {
                $menuArr['url'] = $this->_url->getUrl((string)$child->action, array('_cache_secret_key' => true));
            } else {
                $menuArr['url'] = '#';
                $menuArr['click'] = 'return false';
            }

            $menuArr['active'] = ($this->getActive()==$path.$childName)
                || (strpos($this->getActive(), $path.$childName.'/')===0);

            $menuArr['level'] = $level;

            if ($child->children) {
                $menuArr['children'] = $this->_buildMenuArray($child->children, $path.$childName.'/', $level+1);
            }
            $parentArr[$childName] = $menuArr;

            $sortOrder++;
        }

        uasort($parentArr, array($this, '_sortMenu'));

        while (list($key, $value) = each($parentArr)) {
            $last = $key;
        }
        if (isset($last)) {
            $parentArr[$last]['last'] = true;
        }

        return $parentArr;
    }

 

Here is code of my menu:-

<config>
    <menu>
        <menulink translate="title" module="menulink">
            <title>Menu Link</title>
            <sort_order>400</sort_order>
            <children>
                <menulink translate="title" module="menulink">
                    <title>Menu Link</title>
                    <sort_order>1</sort_order>
                    <external_url>http:www.google.com</external_url>
                </menulink>
            </children>
        </menulink>
    </menu>
</config>

Just put down your comment if you face any issue.