1

I have created module for exporting my product data to script outside of Magento2.

This is my Data.php

<?php
namespace Oktarin\Nabavanet\Helper;

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

  protected $markup=1.03;
  protected $markup_extra=1.02;
  protected $price_limit=1500.00;
  protected $pricefile;
  protected $prices;
  protected $pdv=0.25;
  protected $base_url="https://domain.com/index.php/catalog/product/view/id/";
  protected $base_image_url="https://domain.com/pub/media/catalog/product";
  protected $shipping_cost=35.00;
  protected $cats;
  protected $appState;
/*
  public function __construct(\Magento\Framework\App\Helper\Context $context,\Magento\Framework\App\State $state) {
    $this->appState = $state; 
    parent::__construct($context);
  }



  public function execute() {
    $originalArea = $this->state->getAreaCode();
    $this->appState->setAreaCode('frontend');
    //reset original code
    $this->appState->setAreaCode($originalArea);
  }
*/

  public function getProductCollection()
    {
        $collection = $this->_productCollectionFactory->create();
        return $collection;
    } // end of function getProductCollection


  public function makeXml(){
/*
*/
  //  $originalArea = $this->state->getAreaCode();


    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $this->appState= $objectManager->create('Magento\Framework\App\State');
    $this->appState->setAreaCode('frontend');
    $productCollection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
    $collection = $productCollection->create()
                ->addAttributeToSelect('*')
               // ->addAttributeToFilter('sku', array('like' => '%702638%'))
                ->load();
 $product=array();
    foreach ($collection as $product_data){
      if(!empty($product_data->getEntity_id())){


        //Load the product categories
        $categories1 = $product_data->getCategoryIds();
        //Select the last category in the list
        $categoryId = end($categories1);
        $categoryObject=\Magento\Framework\App\ObjectManager::getInstance();
        $category=$categoryObject->create('Oktarin\Nabavanet\Helper\CategoryTree');
        $categoryTreepath=$category->getTreeByCategoryId($categoryId);

        if(!empty($product_data->getspecial_price())){
            $price=$product_data->getspecial_price();
            $regular_price=$product_data->getprice();
         }
        else{
          $price=$product_data->getprice();
          $regular_price=false;
        }

        // Dostupnost proizvoda
          switch($product_data->getproduct_availability()){
              case "3929":
                // Po narudžbi
                $availability="Po narudžbi";
                break;
              case "3930":
                // Na stanju
                $availability="Raspoloživo";
                break;
              case "3931":
                // Zalihe pri kraju
                $availability="Raspoloživost potrebno provjeriti";
                break;      
            }

          $product[]=array(
            "internal_product_id" => $product_data->getEntity_id(),
            "sku" => $product_data->getsku(),
            "ean" => $product_data->getean(),
            "name" => $product_data->getName(),
            "url" => $this->base_url.$product_data->getEntity_id()."/s/".$product_data->geturl_key()."/",
            "availability" => $availability,
            "category" => $categoryTreepath,
            "image_url" => $this->base_image_url.$product_data->getimage(),
            "additional_image_url" => $this->base_image_url.$product_data->getsmall_image(),
            "description" => $product_data->getshort_description(),
            "shipping_cost" => $this->shipping_cost,
            "regular_price" => $regular_price,
            "brand" => $product_data->getbrand(),
            "part_number" => $product_data->getpart_number(),
            "warranty" => $product_data->getgarancija_proizvoda(),
            "price" => $price,
            "specialPrice" => $product_data->getspecial_price(),
            "tehnickaSpecifikacija" => $product_data->getdescription()
          );
        } // end of of entity_id isnt empty
      } // end of foreach 
        //reset original code
    $this->appState->setAreaCode($originalArea);
        return $product;
  } // end of function makeXml

} // end class

Method makeXml() I am calling from another script in file nabavanet-export.php that is designed to be run from cron/CLI/command line:

#!/usr/bin/php
<?php
(PHP_SAPI !== 'cli' || isset($_SERVER['HTTP_USER_AGENT'])) && die('cli only');
require_once __DIR__ . "/include.php";

$nabavanet=new Xml();

  /* MAGENTO start */
  // calling on Magento Helpers
  use Magento\Framework\App\Bootstrap;
  require '../app/bootstrap.php';
  $params = $_SERVER;
  $bootstrap = Bootstrap::create(BP, $params);
  $obj = $bootstrap->getObjectManager();
  $nabava = $obj->get('\Oktarin\Nabavanet\Helper\Data');
  // end of Magento Helpers
  /* END Magento */

try{
  $filename="nabavaexport";
  $xml=$nabavanet->createNabavanetXMLfile($nabava->createXml(),$filename);
if($xml==1){
    echo "XML ".$filename.".xml generated!\n";
  copy($filename.".xml", "../nabavanet/".$filename.".xml");
}
else{
    echo "XML ".$filename.".xml not generated\n";
}


} catch (PDOException $e) {
    // detaljan ispis grešaka slanjem
    // PDOException objekta preko varijable $e
    // PDO objekta preko varijable $db
    // PDOStatement objekta preko varijable $stmt
    showPDOErrors($e, $db_read, $stmt_read);
    showPDOErrors($e, $db_write, $stmt_write);
}           

?>

Script nabavanet-export.php was working fine when run through browser, however when I run it through command line I get this:

Fatal error: Uncaught Magento\Framework\Exception\LocalizedException: Area code is not set in /usr/www/users/shopyb/vendor/magento/framework/App/State.php:152
Stack trace:
#0 /usr/www/users/shopyb/vendor/magento/framework/Session/SessionManager.php(173): Magento\Framework\App\State->getAreaCode()
#1 /usr/www/users/shopyb/generated/code/Magento/Framework/Session/Generic/Interceptor.php(50): Magento\Framework\Session\SessionManager->start()
#2 /usr/www/users/shopyb/vendor/magento/framework/Session/SessionManager.php(130): Magento\Framework\Session\Generic\Interceptor->start()
#3 /usr/www/users/shopyb/generated/code/Magento/Framework/Session/Generic/Interceptor.php(14): Magento\Framework\Session\SessionManager->__construct(Object(Magento\Framework\App\Request\Http), Object(Magento\Framework\Session\SidResolver\Proxy), Object(Magento\Framework\Session\Config), Object(Magento\Framework\Session\SaveHandler), Object(Magento\Framework\Session\Validator), Object(Magento\Framework\Session\Storage), Object(Magento\Framework\Stdlib\C in /usr/www/users/shopyb/vendor/magento/framework/Session/SessionManager.php on line 175

As you can see I have tried implementing fix as said many times:

  public function __construct(\Magento\Framework\App\State $state, $name=null) {
    $this->appState = $state; 
    parent::__construct($name);
  }

But this also generated error

So I have tried modifing it like this but without success:

  public function __construct(\Magento\Framework\App\Helper\Context $context,\Magento\Framework\App\State $state) {
    $this->appState = $state; 
    parent::__construct($context);
  }

I hope someone can give me pointers how to make file nabavanet-export.php run as command line. I need that outside script because it is depending on other methods required for generating xml.


UPDATE 1

Fix by Sukumar Gorai worked for me however new problem occured, I got this error:

Fatal error: Uncaught Magento\Framework\Exception\NoSuchEntityException: No such entity with id =  in /usr/www/users//vendor/magento/framework/Exception/NoSuchEntityException.php:49

The script in Data.php should get product information, and it seems that it gets product without ID?


UPDATE 2

The problem with entity_id was due to false value returned while fetching categroy ids in another class. I have managed to get around it :).

Thank you all for great help!

1

You need to change your script nabavanet-export.php like below:

<?php
(PHP_SAPI !== 'cli' || isset($_SERVER['HTTP_USER_AGENT'])) && die('cli only');
require_once __DIR__ . "/include.php";

$nabavanet=new Xml();

/* MAGENTO start */
// calling on Magento Helpers
use Magento\Framework\App\Bootstrap;
require '../app/bootstrap.php';
$params = $_SERVER;
$bootstrap = Bootstrap::create(BP, $params);
$obj = $bootstrap->getObjectManager();
// Set area code
$state = $obj->get('Magento\Framework\App\State');
$state->setAreaCode('adminhtml');

$nabava = $obj->get('\Oktarin\Nabavanet\Helper\Data');
// end of Magento Helpers
/* END Magento */

try{
  $filename="nabavaexport";
  $xml=$nabavanet->createNabavanetXMLfile($nabava->createXml(),$filename);
if($xml==1){
    echo "XML ".$filename.".xml generated!\n";
  copy($filename.".xml", "../nabavanet/".$filename.".xml");
}
else{
    echo "XML ".$filename.".xml not generated\n";
}


} catch (PDOException $e) {
    // detaljan ispis grešaka slanjem
    // PDOException objekta preko varijable $e
    // PDO objekta preko varijable $db
    // PDOStatement objekta preko varijable $stmt
    showPDOErrors($e, $db_read, $stmt_read);
    showPDOErrors($e, $db_write, $stmt_write);
}           

?>
  • I have tried and got this error Fatal error: Uncaught TypeError: Argument 1 passed to Magento\Framework\App\Helper\AbstractHelper::__construct() must be an instance of Magento\Framework\App\Helper\Context, instance of Magento\Framework\App\State\Interceptor given, called in /usr/www/users//vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 111 and defined in /usr/www/users//vendor/magento/framework/App/Helper/AbstractHelper.php:84 – Oktarin Jun 24 at 16:23
  • This error is in helper class of your. Please check the helper class properly and run the di compile again and then test. – Sukumar Gorai Jun 24 at 16:40
  • it seems that it is working, after I ran setup:di:compile... however new problem occurs - please see "update" in original question – Oktarin Jun 24 at 16:52
  • Great. Does the error has been fixed of areacode? – Sukumar Gorai Jun 24 at 16:53
  • Yes - it seems that error has been fixed – Oktarin Jun 24 at 17:09
1

Call AreaCode frontend inside module like this

/** @var \Magento\Framework\App\State **/
private $state;

public function __construct(\Magento\Framework\App\State $state) {
    $this->state = $state;
    parent::__construct();
}

public function execute() {
    $this->state->setAreaCode(\Magento\Framework\App\Area::AREA_FRONTEND); // or \Magento\Framework\App\Area::AREA_ADMINHTML, depending on yexternals
}

Call AreaCode frontend in externel script like this

use Magento\Framework\App\Bootstrap;

require __DIR__ . '/app/bootstrap.php';

$params = $_SERVER;

$bootstrap = Bootstrap::create(BP, $params);

$objectManager = $bootstrap->getObjectManager();

$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
  • do I need to call AreaCode in both locations: module and external script? – Oktarin Jun 24 at 16:25
  • I have setup your code in both locations. Now I get this: Fatal error: Uncaught ArgumentCountError: Too few arguments to function Magento\Framework\App\Helper\AbstractHelper::__construct(), 0 passed in /usr/www/users/app/code/Oktarin/Nabavanet/Helper/Data.php on line 21 and exactly 1 expected in /usr/www/users/vendor/magento/framework/App/Helper/AbstractHelper.php:84 – Oktarin Jun 24 at 16:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.