Skip to content

Cannot assign products to categories not under tree root #8970

Closed
@marius-bica

Description

@marius-bica

Preconditions

Magento version: 2.1.4 community edition
PHP version 7.0.15

Steps to reproduce

Try to assign some products to categories programmatically using a CategoryLinkManagement object. The code looks something like this:

    $this
        ->categoryLinkManagement
        ->assignProductToCategories(
             $someValidProduct->getSku(),
             [$someValidCategory->getId()]
         );

where the categoryLinkManagement property is injected via DI into the current class.

Expected result

The product gets assigned to the category.

Actual result

I get an error telling me that "Could not save product "2048" with position 0 to category 42"

What I think

After digging around in the code, it seems that the issue stems from this piece of code in the Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator class, the isCategoryProperForGenerating method:

if ($category->getParentId() != \Magento\Catalog\Model\Category::TREE_ROOT_ID) {
    list(, $rootCategoryId) = $category->getParentIds();
    return $rootCategoryId == $this->storeManager->getStore($storeId)->getRootCategoryId();
}

more specific,

    list(, $rootCategoryId) = $category->getParentIds();

From what I can tell, the code simply tries to get the first element from the array of category parent ids and assign it to $rootCategoryId, but it does that by relying on php 5 or less behavior. Here is what the php manual says about list:

Warning
In PHP 5, list() assigns the values starting with the right-most parameter. In PHP 7, list() starts with the left-most parameter.

They are even warning that list is unpredictable:

Generally speaking, it is advisable to avoid relying on a specific order of operation, as this may change again in the future.

So this code fails to get the root category in php 7 and it even generates a notice if the parent ids array has less than 2 elements, since there is no element with an index of 1.
Exception: Notice: Undefined offset: 1 in vendor/magento/module-catalog-url-rewrite/Model/ProductUrlRewriteGenerator.php on line 195
(here is a related issue detailing this: #7916)

Metadata

Metadata

Assignees

Labels

Component: CatalogFixed in 2.3.xThe issue has been fixed in 2.3 release lineIssue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentReproduced on 2.1.xThe issue has been reproduced on latest 2.1 releaseReproduced on 2.2.xThe issue has been reproduced on latest 2.2 releaseReproduced on 2.3.xThe issue has been reproduced on latest 2.3 releasebug report

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions