Showing posts with label Magento. Show all posts
Showing posts with label Magento. Show all posts

Friday 27 September 2019

Magento 2 Missing Table when transfer server Error "inventory_stock_1"

Error
Exception #0 (Zend_Db_Statement_Exception): SQLSTATE[42S02]: Base table or view not found: 1146 Table 'inventory_stock_1' doesn't exist, query was:........
Solution
1) Open your phpmyadmin
2) Remove your current "inventory_stock_1" if available
3) Run following query on sql
CREATE
SQL SECURITY INVOKER
VIEW `inventory_stock_1`
  AS
    SELECT
    DISTINCT 
      legacy_stock_status.product_id,
      legacy_stock_status.website_id,
      legacy_stock_status.stock_id,
      legacy_stock_status.qty quantity,
      legacy_stock_status.stock_status is_salable,
      product.sku
    FROM `cataloginventory_stock_status` `legacy_stock_status`
      INNER JOIN `catalog_product_entity` product
        ON legacy_stock_status.product_id = product.entity_id;

3) Reindex your store data then check your store.

Saturday 14 September 2019

After installed Magento 2, got Internal server error due to IfVersion < 2.4

Following .htaccess code is not working in Magento 2

<Files composer.json>
        <IfVersion < 2.4>
            order allow,deny
            deny from all
        </IfVersion>
        <IfVersion >= 2.4>
            Require all denied
        </IfVersion>
    </Files>

Ans.  Just enabled "mod_version" from your server

Tuesday 10 September 2019

How to get null attribute product value in magento 1 addAttributeToFilter Filter Query | Where condition

$collection = Mage::getModel('catalog/product')->getCollection()
        ->addAttributeToSelect(['entity_id'])
        ->addAttributeToFilter(
        array(
            array('attribute'=> 'pricegroup','null' => true),
            array('attribute'=> 'pricegroup','eq' => ''),
            array('attribute'=> 'pricegroup','eq' => 'NO FIELD')
        ),
        '',
        'left')
        ->addAttributeToFilter('status', ['eq' => 1]);
echo $collection->getSelect();
echo '<pre>';print_r($collection->getData());exit;

Thursday 24 January 2019

How to dump Magento 2 Enterprise Edition Database

  1. curl -sS https://accounts.magento.cloud/cli/installer | php
  2. magento-cloud list
  3. login without root
  4. magento-cloud db:dump
  5. Open login URL in browser like : http://127.0.0.1:5000
  6. Update to version 1.23.0? [Y/n] y
  7. Continue? [Y/n] y
  8. Enter a number to choose a project:
    1.  [0] ProjectName (Project) (tx2ia23dv5uk)
    2.   Environment ID [staging]: (Press enter key)
  9. Enter a number to choose a relationship:
    1.   [0] database
    2.   [1] database-slave
  10. (Press 0 and Enter key) 

Saturday 8 December 2018

How to log all | full SQL | Mysql queries in Magento 2

Show ALL | Full magento 2 query with Sorting, Pagination and Filter in Magento 2

Open : /var/www/html/magento/jaydip kansagra/app/etc/di.xml


Find 

<preference for="Magento\Framework\DB\LoggerInterface" 

Replace

<preference for="Magento\Framework\DB\LoggerInterface" type="Magento\Framework\DB\Logger\File"/>
 <type name="Magento\Framework\DB\Logger\File">
      <arguments>
          <argument name="logAllQueries" xsi:type="boolean">true</argument>
          <argument name="debugFile" xsi:type="string">log/sql.log</argument>
      </arguments>
 </type>


Open : /var/www/html/magento/frye-magento/var/log/sql.log

Order saving error: SQLSTATE[HY000]: General error: 1449 The user specified as a definer in Magento 2

Run following query into your phpmyadmin

GRANT ALL ON *.* TO 'username'@'%' IDENTIFIED BY 'Jaydip@123';
FLUSH PRIVILEGES;

Monday 26 November 2018

How to get filter data from report filter string | parameter URL in Magento 1




$filterData = Mage::helper('adminhtml')->prepareFilterString($this->getRequest()->getParam('filter', false));

print_r($filterData);exit;

SQLSTATE[42S22]: Column not found: 1054 Unknown column '' in 'having clause', query was: SELECT COUNT(*) in Magento 1

Step 1. Open Collection.php of that model : root/app/code/local/Jaydip/Kansagra/Model/Resource/Rebatecash/Collection.php
Step 2.  Create getSelectCountSql() function in Collection.php file
public function getSelectCountSql() {
        $this->_renderFilters();
        $select = clone $this->getSelect();
        $select->reset(Zend_Db_Select::ORDER);
        $select->reset(Zend_Db_Select::LIMIT_COUNT);
        $select->reset(Zend_Db_Select::LIMIT_OFFSET);       
        $countSelect = clone $this->getSelect();
        $countSelect->reset();
        $countSelect->from(array('a' => $select), 'COUNT(*)');
        return $countSelect;
    }

Saturday 24 November 2018

How to get only one record in Join Query in Magento

$orders->getSelect()->join(["Category" => "catalog_category_product"], "Category.category_id=(
    select category_id from catalog_category_product AS p1 where SFOI.product_id = p1.product_id limit 1
    ) AND SFOI.product_id=Category.product_id", []);

Tuesday 13 November 2018

How to override third party vendor block file in magento 2.2

If you need to override third party or Magento file from vendor directory

Here I override Block file "/var/www/html/magento/magentoproject/vendor/onestop/image-server/Block/Product/View/Gallery.php"

FYI : You need to create new extension when you wish to override default Vendor or Magento file

1. Create new Extension - Jaydip (Namespace)
2. Create Module directory - ImagegalleryAlt (Modulename)
3. Create new file like ( /var/www/html/magento/magentoproject/app/code/Jaydip/ImagegalleryAlt/etc/di.xml )

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
  <preference for="Onestop\ImageServer\Block\Product\View\Gallery" type="Jaydip\ImagegalleryAlt\Block\Product\View\Gallery" />
</config>
4. Create new directory "etc" and create file like : /var/www/html/magento/magentoproject/app/code/Jaydip/ImagegalleryAlt/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Jaydip_ImagegalleryAlt" setup_version="0.1.1">
        <sequence>
            <module name="Magento_Catalog"/>
            <module name="Onestop_ImageServer"/>
        </sequence>
    </module>
</config>
5. Create new directory "Block/Product/View" and create file like : /var/www/html/magento/magentoproject/app/code/Jaydip/ImagegalleryAlt/Block/Product/View/Gallery.php
  • Copy file from old directory and paste to : /var/www/html/magento/magentoproject/app/code/Jaydip/ImagegalleryAlt/Block/Product/View/Gallery.php
  • Open : /var/www/html/magento/magentoproject/app/code/Jaydip/ImagegalleryAlt/Block/Product/View/Gallery.php
  • Change namespace like : namespace Jaydip\ImagegalleryAlt\Block\Product\View;
6. Upgrade data in Magento 2
php -dmemory_limit=5G bin/magento setup:upgrade
7. Static Content Deploy data  in Magento 2
php -dmemory_limit=5G bin/magento setup:static-content:deploy -f
8. Finish!!!

Friday 5 October 2018

How to get list of all categories array tree view in Magento 1

Call Category function

$categories = $this->getTreeCategories(2, false);
print_r($categories);
Get All categories array tree view

function getTreeCategories($parentId, $isChild) {
     
        $allCats = Mage::getModel('catalog/category')->getCollection()
                ->addAttributeToSelect('*')
                ->addAttributeToFilter('is_active', '1')
                ->addAttributeToFilter('include_in_menu', '1')
                ->addAttributeToFilter('parent_id', array('eq' => $parentId));
        $subcat = ($isChild) ? "&nbsp;&nbsp;-- " : "";
        foreach ($allCats as $category) {
            $options[] = array(
                'label' => Mage::helper('jaydip_attrfiltercount')->__($subcat.iconv(mb_detect_encoding($category->getName(), mb_detect_order(), true), "UTF-8", $category->getName())),
                'value' => $category->getId()
            );
            $subcats = $category->getChildren();
            if ($subcats != '') {
                $options[] = $this->getTreeCategories($category->getId(), true);
            }
        }
        $optiondata = array();
        foreach ($options as $option):
            if(isset($option[0])){
             
                foreach ($option as $value):
                    $optiondata[] = array(
                        'label' => $value['label'],
                        'value' => $value['value']
                    );
                endforeach;
             
            }else{
                $optiondata[] = array(
                    'label' => $option['label'],
                    'value' => $option['value']
                );
            }
        endforeach;
     
        return $optiondata;
    }

Tuesday 2 October 2018

Product image Still zoom if I remove mouse cursor from image in magento 2

You need to replace the code of lib/web/magnifier/magnifier.js in your theme as below.

Find

$(document).on('mousemove', onMousemove);
_init($box, gOptions);

Replace

$box.on('mousemove', onMousemove);
       
/*Code By Jaydip*/
$box.on('mouseleave', mouseleave);
    function mouseleave(e) {
         onThumbLeave();
         isOverThumb = false;
         $magnifierPreview.addClass(MagnifyCls.magnifyHidden);
    }
/*Code By Jaydip*/
       
 _init($box, customUserOptions);

Saturday 22 September 2018

How to Skip | Hide shipping address in checkout Magento 1.9

Step 1 :

Create config.xml file : app/code/local/Jaydip/Kansagra/etc/config.xml

<config>
   <global>
        <blocks>
            <jaydip_kansagra>
                <class>Jaydip_Kansagra_Block</class>
            </jaydip_kansagra>
            <!-- For Hide Shipping address-->
            <checkout>
                <rewrite>
                    <onepage>Jaydip_kansagra_Block_Kansagra_Checkout_Onepage</onepage>
                </rewrite>
            </checkout>
            <!-- For Hide Shipping address-->
       </blocks>
       ...........
       ...........
       ...........
       <!-- For Hide Shipping address-->
        <rewrite>
            <hideshippingadd> <!--This can be any unique id -->
                <from><![CDATA[#^/checkout/onepage/#]]></from>  <!-- the URL which u want to override-->
                <to>/kansagra/onepage/</to>  <!-- destination url -->
            </hideshippingadd>
        </rewrite>
        <!-- For Hide Shipping address-->
       ...........
       ...........
       ...........
   </global>
</config>


Step 2 : 

Create OnepageController.php file : app/code/local/Jaydip/Kansagra/controllers/OnepageController.php

<?php
require_once Mage::getModuleDir('controllers', "Mage_Checkout") . DS . "OnepageController.php";
class Jaydip_Kansagra_OnepageController extends Mage_Checkout_OnepageController {
    public function saveBillingAction() {
        if ($this->_expireAjax()) {
            return;
        }
        if ($this->getRequest()->isPost()) {
            $data = $this->getRequest()->getPost('billing', array());
            $customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
            if (isset($data['email'])) {
                $data['email'] = trim($data['email']);
            }
            $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
            if (!isset($result['error'])) {
                if ($this->getOnepage()->getQuote()->isVirtual()) {
                    $result['goto_section'] = 'payment';
                    $result['update_section'] = array(
                        'name' => 'payment-method',
                        'html' => $this->_getPaymentMethodsHtml()
                    );
                } elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
                    $result['goto_section'] = 'shipping_method';
                    $result['update_section'] = array(
                        'name' => 'shipping-method',
                        'html' => $this->_getShippingMethodsHtml()
                    );
                 
                } else {
                    $result['goto_section'] = 'shipping';
                }
            }
            $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
        }
    }
}

Step 3 :

Create Onepage.php file : app/code/local/Jaydip/Kansagra/Block/Kansagra/Checkout/Onepage.php

<?php
class Jaydip_Kansagra_Block_Kansagra_Checkout_Onepage extends Mage_Checkout_Block_Onepage {
    protected function _getStepCodes() {
        return array('login', 'billing', 'shipping_method', 'payment', 'review');
    }
}

Step 4 : 

And now you need to copy billing.phtml from app/design/frontend/base/default/checkout/onepage

folder into app/design/frontend/rwd/default/template/newgenray/checkout folder.

Find following code

<li class="control">
<input type="radio" name="billing[use_for_shipping]" id="billing:use_for_shipping_yes" value="1"<?php if ($this->isUseBillingAddressForShipping()) {?> checked="checked"<?php }?> title="<?php echo Mage::helper('core')->quoteEscape($this->__('Ship to this address')) ?>" onclick="$('shipping:same_as_billing').checked = true;" class="radio" /><label for="billing:use_for_shipping_yes"><?php echo  $this->__('Ship to this address') ?></label>
</li>
<li class="control">
<input type="radio" name="billing[use_for_shipping]" id="billing:use_for_shipping_no" value="0"<?php if (!$this->isUseBillingAddressForShipping()) {?> checked="checked"<?php }?> title="<?php echo Mage::helper('core')->quoteEscape($this->__('Ship to different address')) ?>" onclick="$('shipping:same_as_billing').checked = false;" class="radio" /><label for="billing:use_for_shipping_no"><?php echo $this->__('Ship to different address') ?></label>
</li>

and replace this by

<li class="control">
   <input type="hidden" name="billing[use_for_shipping]" id="billing:use_for_shipping_yes" value="1"  />
</li>

Friday 3 August 2018

How to add | update Shipping Price on existing order in Magento 1.9

$shippingamount = 10.00;
        try {
            $order = Mage::getModel('sales/order')->load(37881)
                    ->setShippingMethod('cstoreshipping_cstoreshipping')
                    ->setShippingAmount($shippingamount)
                    ->setBaseShippingAmount($shippingamount)
                    ->setShippingDescription('Shipping by third party');
            $order->setGrandTotal($order->getGrandTotal() + $shippingamount);
            $order->setBaseGrandTotal($order->getBaseGrandTotal() + $shippingamount);
            $order->save();
            pre($order->getData());
        } catch (Exception $e) {
            pre($e->getMessage());
        }

Tuesday 26 June 2018

How to create configurable product with simple products with attributes using controller in Magento 2 Programmatically | Custom | Custom Module

How to create configurable product with simple products in Magento 2


Step 1 : Create Cotroller

<?php

namespace Jaydip\Kansagra\Controller\Jaydip;

use Magento\Framework\App\Action\Context;

class Createproduct extends \Magento\Framework\App\Action\Action {

    protected $_resultpageFactory;
    protected $_eavAttributeFactory;
    protected $eavConfig;
    protected $directoryList;
    protected $file;

    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $pageFactory,
        \Magento\Framework\App\Filesystem\DirectoryList $directoryList,
        \Magento\Framework\Filesystem\Io\File $file) {

        $this->_resultpageFactory = $pageFactory;
        $this->directoryList = $directoryList;
        $this->file = $file;
        return parent::__construct($context);
    }

    public function execute() {

        /*$postdata = $this->_request->getPost('product');*/
        $postdata = array(
                    'name' => 'Jaydip Kansagra Test product',
                    'magentoid' => 0,
                    'description' => 'description',
                    'categoryid' => 3,
                    'handle'    => 'jaydipkansagra',
                    'image'     => 'https://domain.com/jaydipkansagra.jpg',
                    'variants' => array(
                        '7407003205687' => array(
                            'id' => 7407003205687,
                            'title' => 'Jaydip Kansagra Test product Child 1',
                            'magechildid' => 0,
                            'sku' => 'CASCADETANK-Black',
                            'inventory' => 1,
                            'price' => 31.95,
                            'c_price' => 0,
                            'weight' => 6.8079,
                            'barcode' => 0,
                            'images'    => array(
                                0 => 'https://domain.com/jaydipkansagra.jpg'
                            )

                        ),
                        '7407003238455' => array(
                            'id' => 7407003238455,
                            'title' => 'Jaydip Kansagra Test product child 2',
                            'magechildid' => 0,
                            'sku' => 'CASCADETANK-Rainbow',
                            'inventory' => 1,
                            'price' => 31.95,
                            'c_price' => 0,
                            'weight' => 6.8079,
                            'barcode' => 0,
                            'images'    => array(
                                0 => 'https://domain.com/jaydipkansagra.jpg'
                            )
                        )

                    ),
                    'options'=> array(
                        'name'=>'Color',
                        'value'=>array(
                            0=> 'Red',
                            1=> 'Green'
                        )
                    )
        );

        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $productattr = $objectManager->create('Jaydip\Kansagra\Helper\Productattr');
        $channelstore = $objectManager->create('Magento\Customer\Model\Session');
        $channelstore = $channelstore->getChannelStore();

        if($postdata['magentoid'] > 0){

            $productCollection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\Collection');
            $productCollection->addAttributeToSelect('*');
            $productCollection->addAttributeToFilter('entity_id', array('eq' => $postdata['magentoid']));
            $productCollection->addAttributeToFilter('type_id', array('eq' => 'configurable'));
            $magentoproduct = array();

            $magentoproduct['child'] = array();
            foreach ($productCollection as $product):
                if($product->getTypeId() == 'configurable'){
                    $_children = $product->getTypeInstance()->getUsedProducts($product);
                    foreach ($_children as $child){
                        $product = $objectManager->create('Magento\Catalog\Model\Product')->load($child->getId());
                        $magentoproduct['child'][] = json_decode(json_encode($product->getData()));
                    }
                }
            endforeach;
        }

        //Remove product from vapejuice which is removed
        if(isset($magentoproduct['child'])){
            foreach ($magentoproduct['child'] as $child):
                if(!isset($postdata['variants'][$child->source_variant_id])){
                    $registry = $objectManager->get('\Magento\Framework\Registry');
                    $registry->register('isSecureArea', true);
                    $removeproduct = $objectManager->create('\Magento\Catalog\Model\Product');
                    $removeproduct->load($child->entity_id);
                    $removeproduct->delete();
                }
            endforeach;
        }

        //Create / or get Attribute detail
        $attributes = $attrgroup = $associatedProductIds = array();
        foreach ($postdata['options'] as $j=>$option):
            $j++;
            foreach ($option['values'] as $value):
                try {
                    $attributes[$j][$value] = $productattr->createOrGetId($option['name'], $value);
                } catch (\Exception $e) {
                    echo $e->getMessage();
                }
            endforeach;

        endforeach;

        foreach ($postdata['variants'] as $variant): //Create Simple product

            $weight = $variant['weight'];
            $weight = ($weight!=0)?$weight:1;
            $price = $variant['price'];
            $inventory = $variant['inventory'];

            $product = $objectManager->create('\Magento\Catalog\Model\Product');
            if(isset($variant['magechildid']) && $variant['magechildid'] > 0){
                $product->load($variant['magechildid']);
            }

            $varianttitle = $variant['title'];
            $title = $postdata['name'].$varianttitle;
            $urltitle = str_replace(' ', '-', $title);
            $urlkey = preg_replace("#[^a-zA-Z0-9]+/[^a-zA-Z0-9]+#", "", strtolower($urltitle));
            $sku = ($variant['sku'] != '')?$variant['sku']:$urltitle;

            $product->setName($title);
            $product->setUrlKey($urlkey);
            $product->setSku($sku);
            $product->setAttributeSetId(4);
            $product->setStatus(1);
            $product->setWebsiteIds(array(1));
            $product->setWeight($weight);
            $product->setVisibility(1);
            $product->setTaxClassId(0);
            $product->setCategoryIds([$postdata['categoryid']]);
            $product->setTypeId('simple');
            $product->setPrice($price);

            //Set attribute value for simple product
            foreach ($attributes as $k=>$attribute):
                $attr = $attribute[$variant['option'.$k]];
                $attrlabel = 'set'.ucfirst(strtolower($attr['attrcode']));
                $product->$attrlabel($attr['optionid']);
                $attrgroup[] = $attr['attrid'];
            endforeach;

            $product->setStockData(
                array(
                    'use_config_manage_stock' => 1,
                    'manage_stock' => 1,
                    'is_in_stock' => 1,
                    'qty' => $inventory
                )
            );

            //Set Images
            foreach ($postdata['images'] as $simage):

                $imagePath = $simage;
                if (@getimagesize($imagePath)) {
                    $this->setImage($product, $imagePath, false, $imageType = ['image', 'small_image', 'thumbnail']);
                }

            endforeach;

            $product->save();

            $associatedProductIds[] = $product->getId();
            //pre(json_decode(json_encode($product->getData())));
        endforeach;

        $postproductnm = $postdata['name'];
        $postproductdesc = $postdata['description'];

        $attrgroup = array_unique($attrgroup);

        $mainurl = str_replace(' ', '-', strtolower($postdata['name']));

        //Create master simple product for make it configurable
        $product = $objectManager->create('\Magento\Catalog\Model\Product');
        if(isset($postdata['magentoid']) && $postdata['magentoid'] > 0){
            $product->load($postdata['magentoid']);
        }
        $product->setName($postproductnm); // Name of Product
        $product->setDescription($postproductdesc); // Description of Product
        $product->setSku($mainurl); // Set your sku here
        $product->setUrlKey($postdata['handle']); // Set your URL here
        $product->setAttributeSetId(4); // Attribute set id
        $product->setStatus(1); // Status on product enabled/ disabled 1/0
        $product->setCategoryIds([$postdata['categoryid']]);
        $product->setWebsiteIds(array(1)); // Website Ids
        $product->setWeight($variant['weight']); // weight of product
        $product->setVisibility(4); // visibilty of product (catalog / search / catalog, search / Not visible individually)
        $product->setTaxClassId(0); // Tax class id
        $product->setTypeId('simple'); // type of product (simple/virtual/downloadable/configurable)

        $product->setStockData(
            array(
                'use_config_manage_stock' => 1,
                'manage_stock' => 1,
                'is_in_stock' => 1,
                'qty' => 1
            )
        );

        if(isset($postdata['image'])){

            $imagePath = $postdata['image'];
            if (@getimagesize($imagePath)) {
                $this->setImage($product, $imagePath, false, $imageType = ['image', 'small_image', 'thumbnail']);
            }    
        }

        $product->save();

        //Create configurable which is Master simple product with assign simple product to Configurable product
        $productId = $product->getId(); // Master simple Product Id
        $product = $objectManager->create('Magento\Catalog\Model\Product')->load($productId); // Load Master simple Product
        $attributeModel = $objectManager->create('Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute');
        $position = 0;
        $attributes = $attrgroup; // Super Attribute Ids Used To Create Configurable Product
        foreach ($attributes as $attributeId) {
            $data = array('attribute_id' => $attributeId, 'product_id' => $productId, 'position' => $position);
            $position++;
            $attributeModel->setData($data)->save();
        }
        $product->setTypeId("configurable"); // Setting Product Type As Configurable
        $product->setAffectConfigurableProductAttributes(4);
        $objectManager->create('Magento\ConfigurableProduct\Model\Product\Type\Configurable')->setUsedProductAttributeIds($attributes, $product);
        $product->setNewVariationsAttributeSetId(4); // Setting Attribute Set Id
        $product->setAssociatedProductIds($associatedProductIds);// Setting Associated Products
        $product->setCanSaveConfigurableAttributes(true);
        $product->save();
        pre(json_encode($product->getData()));exit;
    }

    protected function getMediaDirTmpDir()
    {
        return $this->directoryList->getPath($this->directoryList::MEDIA) . DIRECTORY_SEPARATOR . 'tmp' . DIRECTORY_SEPARATOR;
    }

    protected function setImage($product, $imageUrl, $visible = false, $imageType = [])
    {
        /** @var string $tmpDir */
        $tmpDir = $this->getMediaDirTmpDir();
        /** create folder if it is not exists */
        $this->file->checkAndCreateFolder($tmpDir);
        /** @var string $newFileName */
        $newFileName = $tmpDir . baseName($imageUrl);

        /** read file from URL and copy it to the new destination */
        $result = $this->file->read($imageUrl, $newFileName);
        if ($result) {
            /** add saved file to the $product gallery */
            $product->addImageToMediaGallery($newFileName, $imageType, true, $visible);
        }
        return $result;
    }

}

Step 2 : Create Helper for attribute



<?php

/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Jaydip\Kansagra\Helper;

use Magento\Framework\Registry;

class Productattr extends \Magento\Framework\App\Helper\AbstractHelper {

    /**
     * @var \Magento\Catalog\Api\ProductAttributeRepositoryInterface
     */
    protected $attributeRepository;

    /**
     * @var array
     */
    protected $attributeValues;

    /**
     * @var \Magento\Eav\Model\Entity\Attribute\Source\TableFactory
     */
    protected $tableFactory;

    /**
     * @var \Magento\Eav\Api\AttributeOptionManagementInterface
     */
    protected $attributeOptionManagement;

    /**
     * @var \Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory
     */
    protected $optionLabelFactory;

    /**
     * @var \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory
     */
    protected $optionFactory;

    protected $eavAttributeFactory;

    protected $attributeManagement;

    protected $config;

    /**
     * Data constructor.
     *
     * @param \Magento\Framework\App\Helper\Context $context
     * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository
     * @param \Magento\Eav\Model\Entity\Attribute\Source\TableFactory $tableFactory
     * @param \Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManagement
     * @param \Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory $optionLabelFactory
     * @param \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionFactory
     */
    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Catalog\Model\Config $config,
        \Magento\Catalog\Api\ProductAttributeRepositoryInterface $attributeRepository,
        \Magento\Eav\Model\Entity\Attribute\Source\TableFactory $tableFactory,
        \Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManagement,
        \Magento\Eav\Api\Data\AttributeOptionLabelInterfaceFactory $optionLabelFactory,
        \Magento\Eav\Api\Data\AttributeOptionInterfaceFactory $optionFactory,
        \Magento\Eav\Api\AttributeManagementInterface $attributeManagement,
        \Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory $eavAttributeFactory
    ) {
        parent::__construct($context);

        $this->attributeRepository = $attributeRepository;
        $this->tableFactory = $tableFactory;
        $this->attributeOptionManagement = $attributeOptionManagement;
        $this->optionLabelFactory = $optionLabelFactory;
        $this->optionFactory = $optionFactory;
        $this->eavAttributeFactory = $eavAttributeFactory;
        $this->config = $config;
        $this->attributeManagement = $attributeManagement;
    }

    /**
     * Get attribute by code.
     *
     * @param string $attributeCode
     * @return \Magento\Catalog\Api\Data\ProductAttributeInterface
     */
    public function getAttribute($attributeCode) {
        try {
            return $this->attributeRepository->get($attributeCode);
        } catch (\Exception $e) {
            return false;
        }
    }

    public function addAttribute($attributecode, $attributelabel, $attroptions = array()) {

        $attributeData = array(
            'attribute_code' => $attributecode,
            'is_global' => 1,
            'frontend_label' => $attributelabel,
            'frontend_input' => 'select',
            'default_value_text' => '',
            'default_value_yesno' => 0,
            'default_value_date' => '',
            'default_value_textarea' => '',
            'is_unique' => 0,
            'apply_to' => 0,
            'is_required' => 0,
            'is_configurable' => 1,
            'is_searchable' => 1,
            'is_comparable' => 1,
            'is_visible_in_advanced_search' => 0,
            'is_used_for_price_rules' => 0,
            'is_wysiwyg_enabled' => 0,
            'is_html_allowed_on_front' => 0,
            'is_visible_on_front' => 0,
            'used_in_product_listing' => 0,
            'used_for_sort_by' => 0,
            'is_filterable' => 1,
            'is_filterable_in_search' => 0,
            'backend_type' => 'int',
            'is_user_defined' => 1,
            'group' => 'General',
            'option' => array()
        );
        foreach ($attroptions as $key=>$attroption):
            $attributeData['option']['value']['option_'.$key] = array($attroption, $attroption);
        endforeach;

        try {
            $model = $this->eavAttributeFactory->create();
            $model->addData($attributeData);
            $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
            $entityTypeID = $objectManager->create('Magento\Eav\Model\Entity')
            ->setType('catalog_product')
            ->getTypeId();
            $model->setEntityTypeId($entityTypeID);
            $model->save();

            $group_id = $this->config->getAttributeGroupId(4, 'Attribute Option');
            $this->attributeManagement->assign('catalog_product', 4, $group_id, $model->getAttributeCode(), null);

            return $model;
        } catch (\Exception $e) {
            return $e->getMessage();
        }       
    }

    /**
     * Find or create a matching attribute option
     *
     * @param string $attributeCode Attribute the option should exist in
     * @param string $label Label to find or add
     * @return int
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function createOrGetId($attributeCode, $label = '') {

        if (strlen($label) < 1) {
            throw new \Magento\Framework\Exception\LocalizedException(
            __('Label for %1 must not be empty.', $attributeCode)
            );
        }

        $label = ucfirst(strtolower($label));
        $attributeLabel = ucfirst(strtolower($attributeCode));
        $attributeCode = preg_replace("/[^a-zA-Z0-9]+/", "", strtolower($attributeCode));

        $attribute = $this->getAttribute($attributeCode);

        if(!$attribute){
            //Create new attribute
            $attribute = $this->addAttribute($attributeCode, $attributeLabel, array($label));
        }

        // Does it already exist?
        $optionId = $this->getOptionId($attributeCode, $label);
        if (!$optionId) {
            // If no, add it.

            /** @var \Magento\Eav\Model\Entity\Attribute\OptionLabel $optionLabel */
            $optionLabel = $this->optionLabelFactory->create();
            $optionLabel->setStoreId(0);
            $optionLabel->setLabel($label);

            $option = $this->optionFactory->create();
            $option->setLabel($optionLabel);
            $option->setStoreLabels([$optionLabel]);
            $option->setSortOrder(0);
            $option->setIsDefault(false);

            $this->attributeOptionManagement->add(
                    \Magento\Catalog\Model\Product::ENTITY, $this->getAttribute($attributeCode)->getAttributeId(), $option
            );

            // Get the inserted ID. Should be returned from the installer, but it isn't.
            $optionId = $this->getOptionId($attributeCode, $label, true);
        }

        return array('attrid'=>$attribute->getAttributeId(), 'attrcode'=>$attributeCode, 'optionid'=>$optionId);
    }

    /**
     * Find the ID of an option matching $label, if any.
     *
     * @param string $attributeCode Attribute code
     * @param string $label Label to find
     * @param bool $force If true, will fetch the options even if they're already cached.
     * @return int|false
     */
    public function getOptionId($attributeCode, $label, $force = false) {
        /** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
        $attribute = $this->getAttribute($attributeCode);

        // Build option array if necessary
        if ($force === true || !isset($this->attributeValues[$attribute->getAttributeId()])) {
            $this->attributeValues[$attribute->getAttributeId()] = [];

            // We have to generate a new sourceModel instance each time through to prevent it from
            // referencing its _options cache. No other way to get it to pick up newly-added values.

            /** @var \Magento\Eav\Model\Entity\Attribute\Source\Table $sourceModel */
            $sourceModel = $this->tableFactory->create();
            $sourceModel->setAttribute($attribute);

            foreach ($sourceModel->getAllOptions() as $option) {
                $this->attributeValues[$attribute->getAttributeId()][$option['label']] = $option['value'];
            }
        }

        // Return option ID if exists
        if (isset($this->attributeValues[$attribute->getAttributeId()][$label])) {
            return $this->attributeValues[$attribute->getAttributeId()][$label];
        }

        // Return false if does not exist
        return false;
    }

}