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!

asked Jun 24, 2019 at 13:41

2 Answers 2

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);
} 
?>
answered Jun 24, 2019 at 14:05
6
  • 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 Commented Jun 24, 2019 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. Commented Jun 24, 2019 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 Commented Jun 24, 2019 at 16:52
  • Great. Does the error has been fixed of areacode? Commented Jun 24, 2019 at 16:53
  • Yes - it seems that error has been fixed Commented Jun 24, 2019 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');
answered Jun 24, 2019 at 14:08
2
  • do I need to call AreaCode in both locations: module and external script? Commented Jun 24, 2019 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 Commented Jun 24, 2019 at 16:29

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.