phpstan-magento
phpstan-magento copied to clipboard
Generated class ProductExtension is passed on incorrectly to phpstan
Hi there! Just updated from v0.23.1 (and phpstan 1.7) to v0.24.0 (and phpstan 1.8). Since the update I'm getting the following error when running phpstan:
Child process error (exit code 255): PHP Fatal error: Declaration of
Magento\Catalog\Api\Data\ProductExtension::setWebsiteIds(?array
$websiteIds) must be compatible with
Magento\Catalog\Api\Data\ProductExtensionInterface::setWebsiteIds($websit
eIds) in
/tmp/phpstan/cache/PHPStan/95/c3/95c3cd23c340083ec99b41a2ad173115a2e32d1c
.php on line 109
Fatal error: Declaration of
Magento\Catalog\Api\Data\ProductExtension::setWebsiteIds(?array
$websiteIds) must be compatible with
Magento\Catalog\Api\Data\ProductExtensionInterface::setWebsiteIds($websit
eIds) in
/tmp/phpstan/cache/PHPStan/95/c3/95c3cd23c340083ec99b41a2ad173115a2e32d1c
.php on line 109
Those are two generated classes from Magento: ProductExtensionInterface
<?php
namespace Magento\Catalog\Api\Data;
/**
* ExtensionInterface class for @see \Magento\Catalog\Api\Data\ProductInterface
*/
interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
{
/**
* @return int[]|null
*/
public function getWebsiteIds();
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds);
ProductExtension
<?php
namespace Magento\Catalog\Api\Data;
/**
* Extension class for @see \Magento\Catalog\Api\Data\ProductInterface
*/
class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements ProductExtensionInterface
{
/**
* @return int[]|null
*/
public function getWebsiteIds()
{
return $this->_get('website_ids');
}
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds)
{
$this->setData('website_ids', $websiteIds);
return $this;
}
As we can see both classes are generated correctly. In the error message it says that Magento\Catalog\Api\Data\ProductExtension::setWebsiteIds(?array $websiteIds)
must be compatible with its interface declaration but in the actual code there is no typed parameter ?array
so it has to be somehow generated and passed to phpstan virtually.
FYI: I deleted the phpstan cache before running phpstan.
Looks like #266 is the source of the issue. In wonder why it seemed to work in my simple test case. Maybe I messed something up.
The error appears because the classes generated by this extension take precedence over Magento's generated classes.
Which version of Magento are you using?
I'm using Magento 2.4.5.
First of all I also thought that #266 is the source of the issue but #266 was introduced in v0.23.1 and there it's working fine. The issue only occurs on v0.24.0.
I'll go for a quick test with v0.24.0 and Magento 2.4.4.
Ok, good to know. Then I would assume the format of the generated classes changed slightly. That would be a total bummer and a bit tricky to fix.
Magento 2.4.4 is working fine v0.24.0 of this repository. The issue only occurs with Magento 2.4.5 and v0.24.0.
@oneserv-heuser thx a lot for the investigation! Need to figure out a way how to fix this properly.
Any chance you could attach the generated ProductExtensionInterface
and ProductExtension
files from 2.4.4 and 2.4.5?
Here are the two classes ProductExtension and ProductExtensionInterface as generated as of Magento 2.4.4 and 2.4.5:
Magento 2.4.4
ProductExtensionInterface
<?php
namespace Magento\Catalog\Api\Data;
/**
* ExtensionInterface class for @see \Magento\Catalog\Api\Data\ProductInterface
*/
interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
{
/**
* @return int[]|null
*/
public function getWebsiteIds();
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds);
/**
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]|null
*/
public function getCategoryLinks();
/**
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
* @return $this
*/
public function setCategoryLinks($categoryLinks);
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getStockItem();
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
* @return $this
*/
public function setStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem);
/**
* @return \Magento\Bundle\Api\Data\OptionInterface[]|null
*/
public function getBundleProductOptions();
/**
* @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions($bundleProductOptions);
/**
* @return \Magento\Downloadable\Api\Data\LinkInterface[]|null
*/
public function getDownloadableProductLinks();
/**
* @param \Magento\Downloadable\Api\Data\LinkInterface[] $downloadableProductLinks
* @return $this
*/
public function setDownloadableProductLinks($downloadableProductLinks);
/**
* @return \Magento\Downloadable\Api\Data\SampleInterface[]|null
*/
public function getDownloadableProductSamples();
/**
* @param \Magento\Downloadable\Api\Data\SampleInterface[] $downloadableProductSamples
* @return $this
*/
public function setDownloadableProductSamples($downloadableProductSamples);
/**
* @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]|null
*/
public function getConfigurableProductOptions();
/**
* @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[] $configurableProductOptions
* @return $this
*/
public function setConfigurableProductOptions($configurableProductOptions);
/**
* @return int[]|null
*/
public function getConfigurableProductLinks();
/**
* @param int[] $configurableProductLinks
* @return $this
*/
public function setConfigurableProductLinks($configurableProductLinks);
/**
* @return int|null
*/
public function getCalculationSchemaId();
/**
* @param int $calculationSchemaId
* @return $this
*/
public function setCalculationSchemaId($calculationSchemaId);
}
ProductExtension
<?php
namespace Magento\Catalog\Api\Data;
/**
* Extension class for @see \Magento\Catalog\Api\Data\ProductInterface
*/
class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements ProductExtensionInterface
{
/**
* @return int[]|null
*/
public function getWebsiteIds()
{
return $this->_get('website_ids');
}
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds)
{
$this->setData('website_ids', $websiteIds);
return $this;
}
/**
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]|null
*/
public function getCategoryLinks()
{
return $this->_get('category_links');
}
/**
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
* @return $this
*/
public function setCategoryLinks($categoryLinks)
{
$this->setData('category_links', $categoryLinks);
return $this;
}
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getStockItem()
{
return $this->_get('stock_item');
}
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
* @return $this
*/
public function setStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem)
{
$this->setData('stock_item', $stockItem);
return $this;
}
/**
* @return \Magento\Bundle\Api\Data\OptionInterface[]|null
*/
public function getBundleProductOptions()
{
return $this->_get('bundle_product_options');
}
/**
* @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions($bundleProductOptions)
{
$this->setData('bundle_product_options', $bundleProductOptions);
return $this;
}
/**
* @return \Magento\Downloadable\Api\Data\LinkInterface[]|null
*/
public function getDownloadableProductLinks()
{
return $this->_get('downloadable_product_links');
}
/**
* @param \Magento\Downloadable\Api\Data\LinkInterface[] $downloadableProductLinks
* @return $this
*/
public function setDownloadableProductLinks($downloadableProductLinks)
{
$this->setData('downloadable_product_links', $downloadableProductLinks);
return $this;
}
/**
* @return \Magento\Downloadable\Api\Data\SampleInterface[]|null
*/
public function getDownloadableProductSamples()
{
return $this->_get('downloadable_product_samples');
}
/**
* @param \Magento\Downloadable\Api\Data\SampleInterface[] $downloadableProductSamples
* @return $this
*/
public function setDownloadableProductSamples($downloadableProductSamples)
{
$this->setData('downloadable_product_samples', $downloadableProductSamples);
return $this;
}
/**
* @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]|null
*/
public function getConfigurableProductOptions()
{
return $this->_get('configurable_product_options');
}
/**
* @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[] $configurableProductOptions
* @return $this
*/
public function setConfigurableProductOptions($configurableProductOptions)
{
$this->setData('configurable_product_options', $configurableProductOptions);
return $this;
}
/**
* @return int[]|null
*/
public function getConfigurableProductLinks()
{
return $this->_get('configurable_product_links');
}
/**
* @param int[] $configurableProductLinks
* @return $this
*/
public function setConfigurableProductLinks($configurableProductLinks)
{
$this->setData('configurable_product_links', $configurableProductLinks);
return $this;
}
/**
* @return int|null
*/
public function getCalculationSchemaId()
{
return $this->_get('calculation_schema_id');
}
/**
* @param int $calculationSchemaId
* @return $this
*/
public function setCalculationSchemaId($calculationSchemaId)
{
$this->setData('calculation_schema_id', $calculationSchemaId);
return $this;
}
}
Magento 2.4.5
ProductExtensionInterface
<?php
namespace Magento\Catalog\Api\Data;
/**
* ExtensionInterface class for @see \Magento\Catalog\Api\Data\ProductInterface
*/
interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
{
/**
* @return int[]|null
*/
public function getWebsiteIds();
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds);
/**
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]|null
*/
public function getCategoryLinks();
/**
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
* @return $this
*/
public function setCategoryLinks($categoryLinks);
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getStockItem();
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
* @return $this
*/
public function setStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem);
/**
* @return \Magento\Bundle\Api\Data\OptionInterface[]|null
*/
public function getBundleProductOptions();
/**
* @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions($bundleProductOptions);
/**
* @return \Magento\Downloadable\Api\Data\LinkInterface[]|null
*/
public function getDownloadableProductLinks();
/**
* @param \Magento\Downloadable\Api\Data\LinkInterface[] $downloadableProductLinks
* @return $this
*/
public function setDownloadableProductLinks($downloadableProductLinks);
/**
* @return \Magento\Downloadable\Api\Data\SampleInterface[]|null
*/
public function getDownloadableProductSamples();
/**
* @param \Magento\Downloadable\Api\Data\SampleInterface[] $downloadableProductSamples
* @return $this
*/
public function setDownloadableProductSamples($downloadableProductSamples);
/**
* @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]|null
*/
public function getConfigurableProductOptions();
/**
* @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[] $configurableProductOptions
* @return $this
*/
public function setConfigurableProductOptions($configurableProductOptions);
/**
* @return int[]|null
*/
public function getConfigurableProductLinks();
/**
* @param int[] $configurableProductLinks
* @return $this
*/
public function setConfigurableProductLinks($configurableProductLinks);
/**
* @return \Magento\SalesRule\Api\Data\RuleDiscountInterface[]|null
*/
public function getDiscounts();
/**
* @param \Magento\SalesRule\Api\Data\RuleDiscountInterface[] $discounts
* @return $this
*/
public function setDiscounts($discounts);
/**
* @return int|null
*/
public function getCalculationSchemaId();
/**
* @param int $calculationSchemaId
* @return $this
*/
public function setCalculationSchemaId($calculationSchemaId);
}
ProductExtension
<?php
namespace Magento\Catalog\Api\Data;
/**
* Extension class for @see \Magento\Catalog\Api\Data\ProductInterface
*/
class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements ProductExtensionInterface
{
/**
* @return int[]|null
*/
public function getWebsiteIds()
{
return $this->_get('website_ids');
}
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds)
{
$this->setData('website_ids', $websiteIds);
return $this;
}
/**
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]|null
*/
public function getCategoryLinks()
{
return $this->_get('category_links');
}
/**
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
* @return $this
*/
public function setCategoryLinks($categoryLinks)
{
$this->setData('category_links', $categoryLinks);
return $this;
}
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getStockItem()
{
return $this->_get('stock_item');
}
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
* @return $this
*/
public function setStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem)
{
$this->setData('stock_item', $stockItem);
return $this;
}
/**
* @return \Magento\Bundle\Api\Data\OptionInterface[]|null
*/
public function getBundleProductOptions()
{
return $this->_get('bundle_product_options');
}
/**
* @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions($bundleProductOptions)
{
$this->setData('bundle_product_options', $bundleProductOptions);
return $this;
}
/**
* @return \Magento\Downloadable\Api\Data\LinkInterface[]|null
*/
public function getDownloadableProductLinks()
{
return $this->_get('downloadable_product_links');
}
/**
* @param \Magento\Downloadable\Api\Data\LinkInterface[] $downloadableProductLinks
* @return $this
*/
public function setDownloadableProductLinks($downloadableProductLinks)
{
$this->setData('downloadable_product_links', $downloadableProductLinks);
return $this;
}
/**
* @return \Magento\Downloadable\Api\Data\SampleInterface[]|null
*/
public function getDownloadableProductSamples()
{
return $this->_get('downloadable_product_samples');
}
/**
* @param \Magento\Downloadable\Api\Data\SampleInterface[] $downloadableProductSamples
* @return $this
*/
public function setDownloadableProductSamples($downloadableProductSamples)
{
$this->setData('downloadable_product_samples', $downloadableProductSamples);
return $this;
}
/**
* @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]|null
*/
public function getConfigurableProductOptions()
{
return $this->_get('configurable_product_options');
}
/**
* @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[] $configurableProductOptions
* @return $this
*/
public function setConfigurableProductOptions($configurableProductOptions)
{
$this->setData('configurable_product_options', $configurableProductOptions);
return $this;
}
/**
* @return int[]|null
*/
public function getConfigurableProductLinks()
{
return $this->_get('configurable_product_links');
}
/**
* @param int[] $configurableProductLinks
* @return $this
*/
public function setConfigurableProductLinks($configurableProductLinks)
{
$this->setData('configurable_product_links', $configurableProductLinks);
return $this;
}
/**
* @return \Magento\SalesRule\Api\Data\RuleDiscountInterface[]|null
*/
public function getDiscounts()
{
return $this->_get('discounts');
}
/**
* @param \Magento\SalesRule\Api\Data\RuleDiscountInterface[] $discounts
* @return $this
*/
public function setDiscounts($discounts)
{
$this->setData('discounts', $discounts);
return $this;
}
/**
* @return int|null
*/
public function getCalculationSchemaId()
{
return $this->_get('calculation_schema_id');
}
/**
* @param int $calculationSchemaId
* @return $this
*/
public function setCalculationSchemaId($calculationSchemaId)
{
$this->setData('calculation_schema_id', $calculationSchemaId);
return $this;
}
}
FYI: The functions getCalculationSchemaId and setCalculationSchemaId are added by us via ExtensionAttribute functionality.
Edit: Just did a text-compare, they are exactly the same, only the functions getDiscounts and setDiscounts are new, but they appear correctly in the Interface and the concrete class
Pfew, it gets even better. It seems like it's one of those problems that happens sometimes. Just executed it again and now everything works, even 2 times. Afterwards I cleaned the cache and then it failed. Executed it again and then it worked.
Just searched around in the cache files and found the problem: The class ProductExtension gets generated and put into the cache in the following way:
ProductExtension
<?php
namespace Magento\Catalog\Api\Data;
class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements ProductExtensionInterface
{
/**
* @return int|null
*/
public function getCalculationSchemaId()
{
}
/**
* @param int $calculationSchemaId
* @return $this
*/
public function setCalculationSchemaId(int $calculationSchemaId)
{
}
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getStockItem()
{
}
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
* @return $this
*/
public function setStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem)
{
}
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getTestStockItem()
{
}
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $testStockItem
* @return $this
*/
public function setTestStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $testStockItem)
{
}
/**
* @return string|null
*/
public function getTestStockItemQty()
{
}
/**
* @param string $testStockItemQty
* @return $this
*/
public function setTestStockItemQty(string $testStockItemQty)
{
}
/**
* @return \Magento\Bundle\Api\Data\OptionInterface[]|null
*/
public function getBundleProductOptions()
{
}
/**
* @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions(?array $bundleProductOptions)
{
}
/**
* @return int[]|null
*/
public function getWebsiteIds()
{
}
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds(?array $websiteIds)
{
}
/**
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]|null
*/
public function getCategoryLinks()
{
}
/**
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
* @return $this
*/
public function setCategoryLinks(?array $categoryLinks)
{
}
/**
* @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]|null
*/
public function getConfigurableProductOptions()
{
}
/**
* @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[]
* $configurableProductOptions
* @return $this
*/
public function setConfigurableProductOptions(?array $configurableProductOptions)
{
}
/**
* @return int[]|null
*/
public function getConfigurableProductLinks()
{
}
/**
* @param int[] $configurableProductLinks
* @return $this
*/
public function setConfigurableProductLinks(?array $configurableProductLinks)
{
}
/**
* @return \Magento\Downloadable\Api\Data\LinkInterface[]|null
*/
public function getDownloadableProductLinks()
{
}
/**
* @param \Magento\Downloadable\Api\Data\LinkInterface[] $downloadableProductLinks
* @return $this
*/
public function setDownloadableProductLinks(?array $downloadableProductLinks)
{
}
/**
* @return \Magento\Downloadable\Api\Data\SampleInterface[]|null
*/
public function getDownloadableProductSamples()
{
}
/**
* @param \Magento\Downloadable\Api\Data\SampleInterface[]
* $downloadableProductSamples
* @return $this
*/
public function setDownloadableProductSamples(?array $downloadableProductSamples)
{
}
/**
* @return \Magento\SalesRule\Api\Data\RuleDiscountInterface[]|null
*/
public function getDiscounts()
{
}
/**
* @param \Magento\SalesRule\Api\Data\RuleDiscountInterface[] $discounts
* @return $this
*/
public function setDiscounts(?array $discounts)
{
}
}
There you can see the problem:
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds(?array $websiteIds)
{
}
I got the ?array
syntax from #248. And since @torhoehn reported that patch would fix his issue, I thought everything is fine ;)
Comparing with your code, I feel that sometimes just the array
typehint is used and sometimes ?array
. This needs some more investigation how to figure out which syntax needs to be used.
Wouldn't it be an easy fix to also add the type hint to the interface? Then everything should be fine, no? Because at the moment the typehint is not added to the interface, only to the implementation.
Will need to do some testing. The logic for the extension attributes class and interfaces are identical. Not sure what's going on here.
Thanks for opening that issue @oneserv-heuser. I was running into the same issue again and again and could not figure out, what happens here, as I did not find the mentioned code snippet at all in the code.
I haven't forgotten about this, need to find the time for a more intense debugging session.
@shochdoerfer , awesome, thanks. Just a hint from my side as well. We're running on 2.4.2-p2
. So it's definitely not an issue with a specific Magento version. Hope, that helps you a bit during your debugging.
@oneserv-heuser @norgeindian could you people please test #274 and report back it that works for your use-cases?
@torhoehn I might need to roll back the array extension modification, your code example looked different than reported here. Do you remember which Magento & PHP version you were using? Mind also checking if the fix in #274 works for you?
@shochdoerfer Unfortunately the fix doesn't work, but atleast it's another error 😀
Error
-- ---------------------------------------------------------------------------
Child process error (exit code 255): PHP Fatal error: Declaration of
Magento\Catalog\Api\Data\ProductExtension::setCalculationSchemaId(int
$calculationSchemaId) must be compatible with
Magento\Catalog\Api\Data\ProductExtensionInterface::setCalculationSchemaI
d($calculationSchemaId) in
/tmp/phpstan/cache/PHPStan/95/c3/95c3cd23c340083ec99b41a2ad173115a2e32d1c
.php on line 185
Fatal error: Declaration of
Magento\Catalog\Api\Data\ProductExtension::setCalculationSchemaId(int
$calculationSchemaId) must be compatible with
Magento\Catalog\Api\Data\ProductExtensionInterface::setCalculationSchemaI
d($calculationSchemaId) in
/tmp/phpstan/cache/PHPStan/95/c3/95c3cd23c340083ec99b41a2ad173115a2e32d1c
.php on line 185
The error with the ?array type hint is now gone and this error now seems to be kinda weird as I cant see any difference in the declaration.
This is the file from the cache:
ProductExtension from the cache
<?php
namespace Magento\Catalog\Api\Data;
class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements ProductExtensionInterface
{
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getTestStockItem()
{
}
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $testStockItem
* @return $this
*/
public function setTestStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $testStockItem)
{
}
/**
* @return string|null
*/
public function getTestStockItemQty()
{
}
/**
* @param string $testStockItemQty
* @return $this
*/
public function setTestStockItemQty(string $testStockItemQty)
{
}
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getStockItem()
{
}
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
* @return $this
*/
public function setStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem)
{
}
/**
* @return \Magento\Downloadable\Api\Data\LinkInterface[]|null
*/
public function getDownloadableProductLinks()
{
}
/**
* @param \Magento\Downloadable\Api\Data\LinkInterface[] $downloadableProductLinks
* @return $this
*/
public function setDownloadableProductLinks($downloadableProductLinks)
{
}
/**
* @return \Magento\Downloadable\Api\Data\SampleInterface[]|null
*/
public function getDownloadableProductSamples()
{
}
/**
* @param \Magento\Downloadable\Api\Data\SampleInterface[]
* $downloadableProductSamples
* @return $this
*/
public function setDownloadableProductSamples($downloadableProductSamples)
{
}
/**
* @return \Magento\Bundle\Api\Data\OptionInterface[]|null
*/
public function getBundleProductOptions()
{
}
/**
* @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions($bundleProductOptions)
{
}
/**
* @return int[]|null
*/
public function getWebsiteIds()
{
}
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds)
{
}
/**
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]|null
*/
public function getCategoryLinks()
{
}
/**
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
* @return $this
*/
public function setCategoryLinks($categoryLinks)
{
}
/**
* @return \Magento\SalesRule\Api\Data\RuleDiscountInterface[]|null
*/
public function getDiscounts()
{
}
/**
* @param \Magento\SalesRule\Api\Data\RuleDiscountInterface[] $discounts
* @return $this
*/
public function setDiscounts($discounts)
{
}
/**
* @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]|null
*/
public function getConfigurableProductOptions()
{
}
/**
* @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[]
* $configurableProductOptions
* @return $this
*/
public function setConfigurableProductOptions($configurableProductOptions)
{
}
/**
* @return int[]|null
*/
public function getConfigurableProductLinks()
{
}
/**
* @param int[] $configurableProductLinks
* @return $this
*/
public function setConfigurableProductLinks($configurableProductLinks)
{
}
/**
* @return int|null
*/
public function getCalculationSchemaId()
{
}
/**
* @param int $calculationSchemaId
* @return $this
*/
public function setCalculationSchemaId(int $calculationSchemaId)
{
}
}
Here are the files from generated/code:
ProductExtensionInterface from generated/code
<?php
namespace Magento\Catalog\Api\Data;
/**
* ExtensionInterface class for @see \Magento\Catalog\Api\Data\ProductInterface
*/
interface ProductExtensionInterface extends \Magento\Framework\Api\ExtensionAttributesInterface
{
/**
* @return int[]|null
*/
public function getWebsiteIds();
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds);
/**
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]|null
*/
public function getCategoryLinks();
/**
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
* @return $this
*/
public function setCategoryLinks($categoryLinks);
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getStockItem();
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
* @return $this
*/
public function setStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem);
/**
* @return \Magento\Bundle\Api\Data\OptionInterface[]|null
*/
public function getBundleProductOptions();
/**
* @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions($bundleProductOptions);
/**
* @return \Magento\Downloadable\Api\Data\LinkInterface[]|null
*/
public function getDownloadableProductLinks();
/**
* @param \Magento\Downloadable\Api\Data\LinkInterface[] $downloadableProductLinks
* @return $this
*/
public function setDownloadableProductLinks($downloadableProductLinks);
/**
* @return \Magento\Downloadable\Api\Data\SampleInterface[]|null
*/
public function getDownloadableProductSamples();
/**
* @param \Magento\Downloadable\Api\Data\SampleInterface[] $downloadableProductSamples
* @return $this
*/
public function setDownloadableProductSamples($downloadableProductSamples);
/**
* @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]|null
*/
public function getConfigurableProductOptions();
/**
* @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[] $configurableProductOptions
* @return $this
*/
public function setConfigurableProductOptions($configurableProductOptions);
/**
* @return int[]|null
*/
public function getConfigurableProductLinks();
/**
* @param int[] $configurableProductLinks
* @return $this
*/
public function setConfigurableProductLinks($configurableProductLinks);
/**
* @return \Magento\SalesRule\Api\Data\RuleDiscountInterface[]|null
*/
public function getDiscounts();
/**
* @param \Magento\SalesRule\Api\Data\RuleDiscountInterface[] $discounts
* @return $this
*/
public function setDiscounts($discounts);
/**
* @return int|null
*/
public function getCalculationSchemaId();
/**
* @param int $calculationSchemaId
* @return $this
*/
public function setCalculationSchemaId($calculationSchemaId);
}
ProductExtension from generated/code
<?php
namespace Magento\Catalog\Api\Data;
/**
* Extension class for @see \Magento\Catalog\Api\Data\ProductInterface
*/
class ProductExtension extends \Magento\Framework\Api\AbstractSimpleObject implements ProductExtensionInterface
{
/**
* @return int[]|null
*/
public function getWebsiteIds()
{
return $this->_get('website_ids');
}
/**
* @param int[] $websiteIds
* @return $this
*/
public function setWebsiteIds($websiteIds)
{
$this->setData('website_ids', $websiteIds);
return $this;
}
/**
* @return \Magento\Catalog\Api\Data\CategoryLinkInterface[]|null
*/
public function getCategoryLinks()
{
return $this->_get('category_links');
}
/**
* @param \Magento\Catalog\Api\Data\CategoryLinkInterface[] $categoryLinks
* @return $this
*/
public function setCategoryLinks($categoryLinks)
{
$this->setData('category_links', $categoryLinks);
return $this;
}
/**
* @return \Magento\CatalogInventory\Api\Data\StockItemInterface|null
*/
public function getStockItem()
{
return $this->_get('stock_item');
}
/**
* @param \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem
* @return $this
*/
public function setStockItem(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem)
{
$this->setData('stock_item', $stockItem);
return $this;
}
/**
* @return \Magento\Bundle\Api\Data\OptionInterface[]|null
*/
public function getBundleProductOptions()
{
return $this->_get('bundle_product_options');
}
/**
* @param \Magento\Bundle\Api\Data\OptionInterface[] $bundleProductOptions
* @return $this
*/
public function setBundleProductOptions($bundleProductOptions)
{
$this->setData('bundle_product_options', $bundleProductOptions);
return $this;
}
/**
* @return \Magento\Downloadable\Api\Data\LinkInterface[]|null
*/
public function getDownloadableProductLinks()
{
return $this->_get('downloadable_product_links');
}
/**
* @param \Magento\Downloadable\Api\Data\LinkInterface[] $downloadableProductLinks
* @return $this
*/
public function setDownloadableProductLinks($downloadableProductLinks)
{
$this->setData('downloadable_product_links', $downloadableProductLinks);
return $this;
}
/**
* @return \Magento\Downloadable\Api\Data\SampleInterface[]|null
*/
public function getDownloadableProductSamples()
{
return $this->_get('downloadable_product_samples');
}
/**
* @param \Magento\Downloadable\Api\Data\SampleInterface[] $downloadableProductSamples
* @return $this
*/
public function setDownloadableProductSamples($downloadableProductSamples)
{
$this->setData('downloadable_product_samples', $downloadableProductSamples);
return $this;
}
/**
* @return \Magento\ConfigurableProduct\Api\Data\OptionInterface[]|null
*/
public function getConfigurableProductOptions()
{
return $this->_get('configurable_product_options');
}
/**
* @param \Magento\ConfigurableProduct\Api\Data\OptionInterface[] $configurableProductOptions
* @return $this
*/
public function setConfigurableProductOptions($configurableProductOptions)
{
$this->setData('configurable_product_options', $configurableProductOptions);
return $this;
}
/**
* @return int[]|null
*/
public function getConfigurableProductLinks()
{
return $this->_get('configurable_product_links');
}
/**
* @param int[] $configurableProductLinks
* @return $this
*/
public function setConfigurableProductLinks($configurableProductLinks)
{
$this->setData('configurable_product_links', $configurableProductLinks);
return $this;
}
/**
* @return \Magento\SalesRule\Api\Data\RuleDiscountInterface[]|null
*/
public function getDiscounts()
{
return $this->_get('discounts');
}
/**
* @param \Magento\SalesRule\Api\Data\RuleDiscountInterface[] $discounts
* @return $this
*/
public function setDiscounts($discounts)
{
$this->setData('discounts', $discounts);
return $this;
}
/**
* @return int|null
*/
public function getCalculationSchemaId()
{
return $this->_get('calculation_schema_id');
}
/**
* @param int $calculationSchemaId
* @return $this
*/
public function setCalculationSchemaId($calculationSchemaId)
{
$this->setData('calculation_schema_id', $calculationSchemaId);
return $this;
}
}
(Yes I cleared the cache before running phpstan.)
@oneserv-heuser sorry man, not exactly sure what is going on. Are you at mageuc22 by any chance? Maybe we can have a chat or you could even show me your code.
@shochdoerfer Unfortunately not.
@norgeindian Did #274 fixes the error for you? Maybe it's something very specific in our code. Are you adding any extension attribute to Products?
Unfortunately, the issue is still the same in my case, when trying it with your fix. @oneserv-heuser , yes, indeed, we do. Maybe that's the reason? @shochdoerfer , I can not come this weekend, but @sprankhub will be there and will be happy to show you the code. Do you have any idea, what we could check, to make it easier to debug for you?
@norgeindian @shochdoerfer Yes, the reason is definitly the addition of extension attributes. Just removed that part from our code and everything is working fine again. As I can only reproduce the error with Magento 2.4.5 and not 2.4.4, did they change anything in that part? Not sure about that. And also the generated classes are the same (see my comment). Weird
Getting closer to the real issue. Looks like with #248 I went a bit too far with adding the type hints. Will do some more tests and hopefully come up with a fix soonish.
@oneserv-heuser @norgeindian I found the source of the issue. I went a bit far when adding type hints to the generated classes. The PR reverted this. To simplify your testing effort, I merged the changes already in dev-master. Could you guys please check if things are working for you again?
@torhoehn could you also check if your issue in regards of the array handling still does work with dev-master?
@shochdoerfer Everything works fine now, thank you!
I've just published version 0.25.0 of the extension.
@shochdoerfer , thanks a lot. Indeed, everything seems to work now.
Hello there,
I installed version 0.25.0, but unfortunately still getting similar issue:
Child process error (exit code 255): PHP Fatal error: Declaration of
Magento\InventoryApi\Api\Data\SourceExtension::setIsPickupLocationActive(
boolean $isPickupLocationActive) must be compatible with
Magento\InventoryApi\Api\Data\SourceExtensionInterface::setIsPickupLocati
onActive($isPickupLocationActive) in
/tmp/phpstan/cache/PHPStan/b1/77/b177d8ee07a46464a792cb583eab2bd146ae8f42
.php on line 18
Fatal error: Declaration of
Magento\InventoryApi\Api\Data\SourceExtension::setIsPickupLocationActive(
boolean $isPickupLocationActive) must be compatible with
Magento\InventoryApi\Api\Data\SourceExtensionInterface::setIsPickupLocati
onActive($isPickupLocationActive) in
/tmp/phpstan/cache/PHPStan/b1/77/b177d8ee07a46464a792cb583eab2bd146ae8f42
.php on line 18
FYI: I deleted the phpstan cache before running phpstan.
@tszmyt apologies for this mess. I realize that the naive approach to simply generate the files based on the XML configuration is not enough. If extension interfaces already exist, we need to inspect them to see if typehints are used in the method declarations or not.
@tszmyt mind checking if the dev-master version works better now? I fixed a few things in #276. Looks much better now in my local sandbox environment.
Thanks for the update @shochdoerfer
It fixed the issue for me. After upgrading to dev-master + clearing phpstan cache, error is gone.
Finally ;) I'll create a new release soonish.
@tszmyt released the fix as 0.26.0 compatible with PHPStan 1.8 & 0.27.0 compatible with PHPStan 1.9 respectively