2

I am developing a custom module for Magento 2.

Right now I have an error. When I run the Place Order in checkout page, it is supposed to redirect me to a page where it says "You will be redirected to somewhere" for 5 seconds, and then redirect to the "somewhere".

But, I am getting this error in var/report

Recoverable Error: Argument 1 passed to Magento\Framework\Data\Form::__construct() must be an instance of Magento\Framework\Data\Form\Element\Factory, none given, called in C:\Apache24\htdocs\mag\app\code\Asiapay\Pdcptb\Block\Redirect.php on line 34 and defined in C:\Apache24\htdocs\mag\vendor\magento\framework\Data\Form.php on line 59

I have no idea why it shows this. Is there anything that I missed? I've tried to delete the var/generation content, so I'm sure it is not the that problem.

Block file (app\code\Asiapay\Pdcptb\Block\Redirect.php):

<?php

namespace Asiapay\Pdcptb\Block;

use Asiapay\Pdcptb\Model\PdcptbFactory;
use Magento\Customer\Model\Session;
use Magento\Framework\Data\Form;
use Magento\Framework\Data\Form\Element\Factory;
use Magento\Framework\View\Element\AbstractBlock;
use Magento\Framework\View\Element\Template\Context;

//use Magento\Framework\View\Element\Context;

class Redirect extends AbstractBlock
{
    /**
     * @var PdcptbFactory
     */
    protected $_modelPdcptbFactory;

    public function __construct(
        Context $context,
        PdcptbFactory $modelPdcptbFactory,
        array $data = []
    ) {
        $this->_modelPdcptbFactory = $modelPdcptbFactory;

        parent::__construct($context, $data);
    }

    protected function _toHtml()
    {
        $pdcptb = $this->_modelPdcptbFactory->create();

        $form = new Form();
        $form->setAction($pdcptb->getUrl())
            ->setId('pdcptb_checkout')
            ->setName('pdcptb_checkout')
            ->setMethod('post')
            ->setUseContainer(true);
        foreach ($pdcptb->getCheckoutFormFields() as $field => $value) {
            $form->addField($field, 'hidden', ['name' => $field, 'value' => $value]);
        }
        $html = '<html><body>';
        $html .= __('You will be redirected to the payment gateway in a few     seconds.');
        $html .= $form->toHtml();
        $html .= '<script type="text/javascript">require(["jquery", "prototype"], function(jQuery) {document.getElementById("pdcptb_checkout").submit();})</script>';

        $html .= '</body></html>';

        return $html;

    }
}

Controller file (app\code\Asiapay\Pdcptb\Controller\Pdcptb\Redirect.php):

<?php

namespace Asiapay\Pdcptb\Controller\Pdcptb;

use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Controller\Result\Raw\Interceptor;
use Magento\Framework\Controller\Result\RawFactory;
use Magento\Framework\Data\Form\Element\Factory;
use Magento\Framework\View\LayoutFactory;
use Magento\Framework\View\LayoutInterface;

class Redirect extends AbstractPdcptb
{
    /**
     * @var RawFactory
     */
    protected $_resultRawFactory;

    /**
     * @var LayoutFactory
     */
    protected $_viewLayoutFactory;

    public function __construct(
        Context $context,
        RawFactory $resultRawFactory,
        LayoutFactory $viewLayoutFactory
    ) {
        $this->_resultRawFactory = $resultRawFactory;
        $this->_viewLayoutFactory = $viewLayoutFactory;

        parent::__construct($context);
    }

    /**
     * When a customer chooses Pdcptb on Checkout/Payment page
     */
    public function execute()
    {

        /*      METHOD 1        */

        $session = ObjectManager::getInstance()->get('Magento\Checkout\Model\Session');
        $session->setPdcptbQuoteId($session->getQuoteId());
        $this->_resultRawFactory->create()->setContents($this->_viewLayoutFactory->create()->createBlock('Asiapay\Pdcptb\Block\Redirect')->toHtml());
        $session->unsQuoteId();
    }
}

Template file (app\code\Asiapay\Pdcptb\view\frontend\templates\form.phtml):

<fieldset class="form-list">
    <?php $_code = $this->getMethodCode() ?>
    <ul id="payment_form_<?php echo $_code ?>" style="display:none">
        <li>
            <?php echo __('You will be redirected to a secure payment page.') ?>
        </li>
    </ul>
</fieldset>
5
  • Tried to delete var/generation folder? Jul 20, 2016 at 4:49
  • I suggest you to check to C:\Apache24\htdocs\mag\vendor\magento\framework\Data\Form.php because it giving error due to "new Form()" Jul 20, 2016 at 5:19
  • @KhoaTruongDinh i have mentioned i have tried doing so please read
    – Tine
    Jul 20, 2016 at 5:37
  • @BhupendraJadeja C:\Apache24\htdocs\mag\vendor\magento\framework\Data\Form.php is Magento's folder, not my custom module, u sure i need to modify this file?
    – Tine
    Jul 20, 2016 at 5:40
  • 1
    No i am not telling to change the file of Form.php but i think you will need to check for the reference as you are create new Form which is not object of that file Jul 20, 2016 at 6:02

2 Answers 2

3

You can't instantiate an object of form without passing argument. Please refer file Magento\Framework\Data\Form.php wherein construct function there are four arguments (one is an array) so you must pass three arguments during initiate object of Form:

 class Form extends \Magento\Framework\Data\Form\AbstractForm
 {
     public function __construct(
         Factory $factoryElement,
         ElementCollectionFactory $factoryCollection,
         FormKey $formKey,
         $data = []
     ) {
         parent::__construct($factoryElement, $factoryCollection, $data);
         $this->_allElements = $this->_factoryCollection-create(['container' => $this]);
         $this->formKey = $formKey;
     }
 }

Your argument is not matching with construct function.

1

I have modified your code. See injected form factory into constructor, see form creation in _toHtml() method:

class Redirect extends AbstractBlock
{
    /**
     * @var PdcptbFactory
     */
    protected $_modelPdcptbFactory;
    protected $_formFactory;

    public function __construct(
        Context $context,
        PdcptbFactory $modelPdcptbFactory,
        \Magento\Framework\Data\FormFactory $formFactory,
        array $data = []
    ) {
        $this->_modelPdcptbFactory = $modelPdcptbFactory;
        $this->_formFactory = $formFactory;
        parent::__construct($context, $data);
    }

    protected function _toHtml()
    {
        $pdcptb = $this->_modelPdcptbFactory->create();
        $form = $this->_formFactory->create(); // instead of "new Form()"
        $form->setAction($pdcptb->getUrl());

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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