Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Di:Compile - Compiled Codes Di has wrong Instances of Arguments for Construct #5954

Closed
antbates91 opened this issue Aug 3, 2016 · 14 comments

Comments

@antbates91
Copy link

antbates91 commented Aug 3, 2016

Preconditions

  1. Magento 2.1 Enterprise (https://github.com/magento/magento2/releases/tag/2.1.0)
  2. Dev Environment - PHP 7.0.8, MySQL 5.6.10
  3. Production Environment (Staging/Dev) - PHP 7.08, MySQL 5.6.28

Steps to reproduce

  1. Create a module extending the class Magento\Framework\View\Element\Html\Links
  2. Add the following construct.
public function __construct(Context $context, Session $session)
    {
        $this->session = $session;
        parent::__construct($context);
    }

Where the types are defined at the top of the file as:

use Magento\Framework\View\Element\Html\Links as MagentoLinks;
use Magento\Customer\Model\Session;
use Magento\Framework\View\Element\Template\Context;
  1. Run di:compile.
  2. Confirm the result is as follows:
php bin/magento setup:di:compile
Compilation was started.
Interception cache generation... 7/7 [============================] 100% 6 mins 318.0 MiBB0 MiB
Generated code and dependency injection configuration successfully.
  1. Load up a template with a Block type from your newly created Links class that extends the magento version in your browser.
  2. The following error is displayed:
Fatal error: Uncaught TypeError: Argument 1 passed to ModName\Framework\View\Element\Html\Links::__construct() must be an instance of Magento\Framework\View\Element\Template\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in /domains/***.com/___deploy/releases/20160728154029/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93 and defined in /domains/***.com/___deploy/releases/20160728154029/app/code/ModName/Framework/View/Element/Html/Links.php:20 Stack trace: #0 /domains/***.com/___deploy/releases/20160728154029/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php(93): ModName\Framework\View\Element\Html\Links->__construct(Object(Magento\Framework\ObjectManager\ObjectManager)) #1 /domains/***.com/___deploy/releases/20160728154029/vendor/magento/framework/ObjectManager/Factory/Compiled.php(88): Magento\Framework\ObjectManager\Factory\AbstractFactory->createObject('ModName in /domains/***.com/___deploy/releases/20160728154029/app/code/ModName/Framework/View/Element/Html/Links.php on line 20

I have a attached a screenshot of the arguments being passed into the create function for Magento\Framework\ObjectManager\Factory\Compiled.

arguments

Expected result

  1. The template file should load without an issue. It does before you use the compiler.

Actual result

  1. The frontend of Magento will error with the above message.

Delete the var/di directory and the file works fine, recompile again and it breaks. This happens on a local dev environment, and a production dev/staging environment.

@southerncomputer
Copy link
Contributor

Same thing with Plugin interceptor - Something must be going wrong during the DI:compile that is not being logged!

@SerhiyShkolyarenko
Copy link
Contributor

@antbates1991 could you please paste full class content here. I tried to reproduce and got an error on compilation.

@antbates91
Copy link
Author

namespace ModuleName\Framework\View\Element\Html;

use Magento\Framework\View\Element\Html\Links as MagentoLinks;
use Magento\Customer\Model\Session;
use Magento\Framework\View\Element\Template\Context;

/**
 * Class Links
 * @package ModuleName\Framework\View\Element\Html
 * @author Anthony Bates <anthony@wearejh.com>
 */
class Links extends MagentoLinks
{
    /**
     * @var Session $session
     */
    private $session;

    public function __construct(Context $context, Session $session)
    {
        $this->session = $session;
        parent::__construct($context);
    }

    public function isLoggedIn() : bool
    {
        return $this->session->isLoggedIn();
    }
}

@SerhiyShkolyarenko
Copy link
Contributor

The same error. I renamed the file to Linkz.php and the class accordingly.
On latest CE develop branch compilation fails with

Application code generator... 3/7 [============>---------------]  42% 18 secs 160.0 MiBPHP Fatal error:  Cannot use Magento\Customer\Model\Session as Session because the name is already in use in /media/data/sources/m2enterprize/ce/lib/internal/Magento/Framework/View/Element/Html/Linkz.php on line 9

Do you have the same result on the latest CE?

@antbates91
Copy link
Author

Sorry I completely forgot we have created a module on our installations so that the compiler works with php 7 return types. If you remove all php 7 return types from the class you will find it should compile.

@SerhiyShkolyarenko
Copy link
Contributor

Removed ": bool" for isLoggedIn() and got the same result: compilation fails. Am I doing anything wrong?

@antbates91
Copy link
Author

No that should work fine.

@SerhiyShkolyarenko
Copy link
Contributor

@antbates1991 I deployed Magento CE 2.1.0 from git tag and applied these changes(patch)
GitHub5954.patch.zip
Then I cleared cache, ran compilation and it was successful. The code returns "No" on the home page.
Does it work the same for you?

@antbates91
Copy link
Author

antbates91 commented Sep 27, 2016

@SerhiyShkolyarenko I have updated to Magento EE 2.1.1 and that has resolved this issue. The Di Compile now works correctly.

@pboisvert
Copy link

@antbates1991 If you are a developer for a merchant or a partner, please use the Support or Partner portal to file issues. Github does not have account level tracking for issues though we are responding to issues here but without any SLA.

@tkacheva
Copy link

@antbates1991 Seems that issues is no longer actual. Closing. Reopen if needed

@nastroth
Copy link

nastroth commented Dec 6, 2016

I am experiencing a similar issue:

Fatal error: Uncaught TypeError: Argument 1 passed to MyModule\Service\Controller\Module\Version::__construct() must be an instance of Magento\Framework\App\Action\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in /srv/www/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93

Magento Version: 2.1.2
PHP Version: 7.0.8

Here is my Controller:

`
namespace MyModule\Service\Controller\Module;

use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\App\ProductMetadataInterfaceFactory;
use MyModule\Service\Helper\Data;

class Version extends \MyModule\Service\Controller\Module {

protected $resultJsonFactory;
protected $productMetadataInterfaceFactory;
protected $helper;

/**
 * @param \Magento\Framework\App\Action\Context $context
 * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
 * @param \Magento\Framework\App\ProductMetadataInterfaceFactory $productMetadataInterfaceFactory
 * @param \MyModule\Service\Helper\Data $helper
 */
public function __construct(
    Context $context,
    JsonFactory $resultJsonFactory,
    ProductMetadataInterfaceFactory $productMetadataInterfaceFactory,
    Data $helper
) {

    $this->resultJsonFactory = $resultJsonFactory;
    $this->productMetadataInterfaceFactory = $productMetadataInterfaceFactory;
    $this->helper = $helper;
    parent::__construct($context);
    parent::initParams();

}

/**
 * @return \Magento\Framework\Controller\Result\Json
 */
public function execute()
{
    /** @var \Magento\Framework\Controller\Result\Json $result */
    $productMetadata = $this->productMetadataInterfaceFactory->create();

    $result = $this->resultJsonFactory->create();
    $data = new \stdClass();
    $data->modulePluginVersion = (string) $this->helper->getVersion();
    $data->magentoVersion = (string) $productMetadata->getVersion();
    $data->phpVersion = (string) phpversion();
    $data->moduleEnabled = $this->helper->getConfig()['enabled'];
    $data->apiVersion = "2.0";
    return $result->setData($data);
}

}
`

Everything works when I clear /di and /generation folders buy breaks again when I run

magento setup:di:compile

@hemant2586
Copy link

hemant2586 commented Feb 22, 2017

I am also having same issue with Magento 2.1.2 PHP Version 7.0.4. The code works fine without compilation but gives error after running compilation.

Fatal error: Uncaught TypeError: Argument 1 passed to Ktpl\Customergroups\Model\Plugin\CustomerExtractor::__construct() must be an instance of Magento\Customer\Model\Metadata\FormFactory, instance of Magento\Framework\ObjectManager\ObjectManager given, called in /var/www/webroot/beta.magedelight.com/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93 and defined in /var/www/webroot/beta.magedelight.com/app/code/Ktpl/CustomerGroups/Model/Plugin/CustomerExtractor.php:50 Stack trace: #0 /var/www/webroot/beta.magedelight.com/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php(93): Ktpl\Customergroups\Model\Plugin\CustomerExtractor->__construct(Object(Magento\Framework\ObjectManager\ObjectManager)) #1 /var/www/webroot/beta.magedelight.com/vendor/magento/framework/ObjectManager/Factory/Compiled.php(88): Magento\Framework\ObjectManager\Factory\AbstractFactory->createObject('Ktpl\CustomerGr...', Array) #2 /var/www/webroot/beta.magedelight.com/vendor/magento/framework/ObjectManager/Factory in /var/www/webroot/beta.magedelight.com/app/code/Ktpl/CustomerGroups/Model/Plugin/CustomerExtractor.php on line 50

My custom model class code is

`<?php
namespace Ktpl\Customergroups\Model\Plugin;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Customer\Api\GroupManagementInterface;
use Magento\Framework\App\RequestInterface;

class CustomerExtractor extends \Magento\Customer\Model\CustomerExtractor
{

protected $_request;

protected $uploader;

protected $filesystem;

protected $adapterFactory;

protected $_messageManager;

/**
 * @var \Magento\Customer\Model\Metadata\FormFactory
 */
protected $formFactory;

/**
 * @var \Magento\Customer\Api\Data\CustomerInterfaceFactory
 */
protected $customerFactory;

/**
 * @var \Magento\Store\Model\StoreManagerInterface
 */
protected $storeManager;

/**
 * @var GroupManagementInterface
 */
protected $customerGroupManagement;

/**
 * @var \Magento\Framework\Api\DataObjectHelper
 */
protected $dataObjectHelper;

/**
* @param \Magento\Framework\App\RequestInterface $request
*/
public function __construct(
    \Magento\Customer\Model\Metadata\FormFactory $context,
    \Magento\Framework\Image\AdapterFactory $adapterFactory,
    \Magento\MediaStorage\Model\File\UploaderFactory $uploader,
    \Magento\Framework\Filesystem $filesystem,
    \Magento\Framework\Message\ManagerInterface $messageManager,
    \Magento\Framework\App\RequestInterface $request,
    \Magento\Customer\Model\Metadata\FormFactory $formFactory,
    \Magento\Customer\Api\Data\CustomerInterfaceFactory $customerFactory,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    GroupManagementInterface $customerGroupManagement,
    \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
)
{
    $this->adapterFactory = $adapterFactory;
    $this->uploader = $uploader;
    $this->filesystem = $filesystem;
    $this->_request = $request;
    $this->_messageManager = $messageManager;
    $this->formFactory = $formFactory;
    $this->customerFactory = $customerFactory;
    $this->storeManager = $storeManager;
    $this->customerGroupManagement = $customerGroupManagement;
    $this->dataObjectHelper = $dataObjectHelper;
    return parent::__construct();
}

public function extract($formCode, RequestInterface $request)
{
    $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
    $data = $this->_request->getPostValue();
    // $customerData = $observer->getEvent()->getCustomer();
    // $customer = $objectManager->create('Magento\Customer\Model\Customer')->load($customerData['entity_id']);
    $mediaDirectory = $objectManager->get('Magento\Framework\Filesystem')
            ->getDirectoryRead(DirectoryList::MEDIA);
    $mediaFolder = 'partners/logo/';
    $path = $mediaDirectory->getAbsolutePath($mediaFolder);
    
    if(!empty($_FILES) && isset($_FILES['company_logo']) && ($_FILES['company_logo']['size'] > 0 )){
        try {
            $uploader = $this->uploader->create(
                ['fileId' => 'company_logo']
            );

            $file = $uploader->validateFile()['tmp_name'];
            $filename = $uploader->validateFile()['name'];
            $size = $uploader->validateFile()['size'];
            if(!empty($filename) && ($size == 0)){
                $error = true;
                $this->messageManager->addError('Please upload a valid file!');
            }
            if(!empty($filename) && ($size > 0)){
                $uploader->setAllowedExtensions(['jpg', 'jpeg', 'gif', 'png']);
                $fileAdapter = $this->adapterFactory->create();
                $uploader->addValidateCallback('company_logo', $fileAdapter, 'validateUploadedFile');
                $uploader->setAllowRenameFiles(true);
                $uploader->setFilesDispersion(false);
                $mediaDirectory = $this->filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA);
                $resultFile = $uploader->save(
                    $mediaDirectory->getAbsolutePath($mediaFolder)
                );
            }
        } catch (\Exception $e) {
            $this->_messageManager->addError($e->getMessage());
        }
    }

    $customerForm = $this->formFactory->create('customer', $formCode);
    $customerData = $customerForm->extractData($request);
    if(!empty($_FILES) && isset($_FILES['company_logo']) && ($_FILES['company_logo']['size'] > 0 ) && isset($resultFile['file']) && !empty($resultFile['file'])){
    	$customerData['company_logo']['name'] = $resultFile['file'];
    }
    $allowedAttributes = $customerForm->getAllowedAttributes();
    $isGroupIdEmpty = isset($allowedAttributes['group_id']);

    $customerDataObject = $this->customerFactory->create();
    $this->dataObjectHelper->populateWithArray(
        $customerDataObject,
        $customerData,
        '\Magento\Customer\Api\Data\CustomerInterface'
    );
    $store = $this->storeManager->getStore();
    if ($isGroupIdEmpty) {
        $customerDataObject->setGroupId(
            $this->customerGroupManagement->getDefaultGroup($store->getId())->getId()
        );
    }
    
    $customerDataObject->setWebsiteId($store->getWebsiteId());
    $customerDataObject->setStoreId($store->getId());

    return $customerDataObject;
}

}
`
Please let me know if anyone get it resolved or if there any patch/update.

@martynshanks
Copy link

martynshanks commented Mar 9, 2017

Same Issue:
Fatal error: Uncaught TypeError: Argument 1 passed to Test\Test\Model\Plugin\Test::__construct() must be an instance of Magento\Customer\Model**, instance of Magento\Framework\ObjectManager\ObjectManager given...

Magento 2.1.5 CE
Was on PHP 7.0.15, switched to 5.6.30 no difference. Deleted contents of Di and Generation folders, problem solved.

Then I ran:
php bin/magento setup:di:compile
The directory "/Applications/MAMP/htdocs/MagentoCE/var/generation/Magento" cannot be deleted Warning!rmdir(/Applications/MAMP/htdocs/MagentoCE/var/generation/Magento): Directory not empty#0 /Applications/MAMP/htdocs/MagentoCE/vendor/magento/framework/Filesystem/Driver/File.php(403): Magento\Framework\Filesystem\Driver\File->deleteDirectory('/Applications/M...')
/Applications/MAMP/htdocs/MagentoCE/setup/src/Magento/Setup/Console/CompilerPreparation.php(68): Magento\Framework\Filesystem\Driver\File->deleteDirectory('/Applications/M...')
/Applications/MAMP/htdocs/MagentoCE/vendor/magento/framework/Console/Cli.php(74): Magento\Setup\Console\CompilerPreparation->handleCompilerEnvironment()
/Applications/MAMP/htdocs/MagentoCE/bin/magento(22): Magento\Framework\Console\Cli->__construct('Magento CLI')
{main}

Fatal error: Uncaught Error: Class 'Cli' not found in /Applications/MAMP/htdocs/MagentoCE/bin/magento:31
Stack trace:
{main}
thrown in /Applications/MAMP/htdocs/MagentoCE/bin/magento on line 31

Then I deleted the Cache folder contents aswell and di:compile completed.

All working after that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants