pestle
pestle copied to clipboard
Certain upgrade scripts cause setup:di:compile to fatal error
Preconditions
- Magento 2.2.0 EE
- Pestle 1.4.2
Steps to reproduce
- Use Pestle to create an upgrade script containing something similar to the following structure:
$eavSetup = $this->eavSetupFactory->create(['setup' => $setup]); $eavSetup->addAttribute( \Magento\Catalog\Model\Product::ENTITY, 'test', [ ... 'source' => \Magento\Eav\Model\Entity\Attribute\Source\Boolean::class, \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_GLOBAL, ... ] );
- Run
setup:di:compile
.
Expected result
DI is compiled.
Actual result
[Exception]
Notice: Undefined property: Magento\Setup\Module\Di\Code\Reader\ClassesScanner::$eavSetupFactory
in ... upgrade_scripts/data/0.0.5.php
Analysis
At the end of one line, there is the word 'class'
. In the following line, there is the word '\Magento'
. This triggers the following events:
-
\Magento\Setup\Module\Di\Code\Reader\FileClassScanner::extract
thinks the file containsclass Magento
, - Causing
\Magento\Setup\Module\Di\Code\Reader\ClassesScanner::includeClasses
to try to include the file, - Causing the file to be included with
$this
being\Magento\Setup\Module\Di\Code\Reader\ClassesScanner
, - Causing
$this->eavSetupFactory
to fatal error.
So upgrade scripts containing the following properties will fail:
- Contain the word "class" that is parsed as its own token.
- Contain another token that can be parsed as a class name.
- Call a property or function on
$this
thatMagento\Setup\Module\Di\Code\Reader\ClassesScanner
does not contain.
I am not sure if Pestle can fix this. I have filed a bug with Magento here.
makes long painful sigh that contains multitude of things better not said in public
Thanks for the bug report. I don't see a Magento\Setup\Module\Di\Code\Reader\FileClassScanner
class in Magento -- did you mean Magento\Setup\Module\Di\Code\Reader\FileScanner
? Or another class?
If I'm reading that all correctly it sounds like
- The presence of
Magento\Eav\Model\Entity\Attribute\Source\Boolean::class
, followed (eventually) byMagento
makes Magento's class scanner think this is a class source file. - Magento tries including the script in the context of its own class
- Explodo
I'm not sure there's much we can do here -- if Magento thinks a class file is not a class file and runs the code inside then bad undefined variable things will happen. I can think of some hack solutions (something like $pestleSetup = $this
in the class, replace all references to $this
with $pestleSetup
, and an if(isset($pestleSetup))
check at the top of the script but -- no.
We might be able to investigate if there's a way to format the include such that Magento identifies it as something other than a class.
The work-around is to use a 'Magento\Eav\Model\Entity\Attribute\Source\Boolean'
in your source instead of the more elegant Magento\Eav\Model\Entity\Attribute\Source\Boolean::class
I'll leave this to the billion dollar ecommence company to fix, but am open to pull requests from anyone that can come up with a solution.
Maybe an option to produce a script with something like this at the top (and a $setup = $this
in the include function)
if(!isset($setup) || !is_object($setup) || !isset($setup->pulseStormUpgradeClass))
{
return;
}
@jantzenw can you report the issue here https://github.com/magento/magento2/issues ? it is a bug in the Magento compiler.
@piotrekkaminski Yes it was reported here: https://github.com/magento/magento2/issues/11442
@astorm Magento\Setup\Module\Di\Code\Reader\FileClassScanner
is the correct class. I see that it exists in 2.2.0 EE but does not exist in at least 2.1.7 CE.
@jantzenw Looks like the class is there in M2.2 as well -- I must have been looking at an older version/the wrong folder when I was diagnosing things before. Thank you for clarifying!
https://github.com/magento/magento2/blob/2.2-develop/setup/src/Magento/Setup/Module/Di/Code/Reader/FileClassScanner.php