Search code examples
entityparentchildrenshopwareshopware6

How to make use of the getChildren() and getParent() functions if they always return null?


I've noticed entities can implement a getParent and getChildren function like the ProductEntity. It always seems to return null when I try to use either of them, even when trying to add ->addAssociation('parent') or ->addAssociation('children'). How do i load both the children and the parent using the criteria object?


Solution

  • The getter for children will return null if a product simply has no children a.k.a. variants. Adding the associations should generally work. To test this you can try adding a filter to retrieve only results that should include children.

    $criteria = new Criteria();
    $criteria->addAssociation('children');
    $criteria->addFilter(new RangeFilter('childCount', [RangeFilter::GT => 0]));
    
    /** @var ProductCollection $products */
    $products = $this->productRepository->search($criteria, $context)->getEntities();
    var_dump($products->first()->getChildren());
    

    The parent association however is different. If you try adding it, the data abstraction layer should throw a ParentAssociationCanNotBeFetched exception:

    It is not possible to read the parent association directly. Please read the parents via a separate call over the repository
    

    You will have to resolve the parents programmatically and set them to their respective children, if you want to work with the getter later on in the stack.

    $criteria = new Criteria();
    $criteria->addFilter(new NotFilter(NotFilter::CONNECTION_AND, [new EqualsFilter('parentId', null)]));
    
    /** @var ProductCollection $products */
    $products = $this->productRepository->search($criteria, Context::createDefaultContext())->getEntities();
    
    $criteria = new Criteria($products->getParentIds());
    
    /** @var ProductCollection $parents */
    $parents = $this->productRepository->search($criteria, Context::createDefaultContext())->getEntities();
    
    /** @var ProductEntity $product */
    foreach ($products as $product) {
        $parent = $parents->get($product->getParentId());
        if (!$parent) {
            continue;
        }
    
        $product->setParent($parent);
    }
    
    var_dump($products->first()->getParent());