Load variations for a given product with data coming from the search index.

@param Product $parentProduct Parent Product
@param array   $attributes    Attributes

@return bool|\Magento\Catalog\Api\Data\ProductInterface
428559
private function loadVariationsFromSearchIndex(Product $parentProduct, array $attributes)
    {
        $documentSource = $parentProduct->getDocumentSource();
        $childrenIds    = isset($documentSource['children_ids']) ? $documentSource['children_ids'] : [];
        $variation      = false;

        if (!empty($childrenIds)) {
            $childrenIds = array_map('intval', $childrenIds);

            $productCollection = $this->productCollectionFactory->create();
            $productCollection->addIdFilter($childrenIds);

            $configurableAttributes = $this->getAttributesFromConfigurable($parentProduct);
            $allAttributesArray     = [];

            foreach ($configurableAttributes as $attribute) {
                foreach ($attribute->getOptions() as $option) {
                    $allAttributesArray[$attribute['attribute_code']][] = (int) $option->getValue();
                }
            }

            $resultAttributesToFilter = array_merge($attributes, array_diff_key($allAttributesArray, $attributes));

            $this->addFilterByAttributes($productCollection, $resultAttributesToFilter);

            $variationProduct = $productCollection->getFirstItem();

            if ($variationProduct && $variationProduct->getId()) {
                $variation = $this->productRepository->getById($variationProduct->getId());
            }
        }

        return $variation;
    }
1339661
protected function initializeProduct(array $attr)
    {

        // initialize the product attributes
        $attr = parent::initializeProduct($attr);

        // query whether or not, we found a new product
        if ($attr[EntityStatus::MEMBER_NAME] === EntityStatus::STATUS_CREATE) {
            // if yes, initialize the additional Magento 2 EE product values
            $additionalAttr = array(
                MemberNames::ENTITY_ID  => $this->nextIdentifier(),
                MemberNames::CREATED_IN => 1,
                MemberNames::UPDATED_IN => strtotime('+20 years')
            );

            // merge and return the attributes
            $attr = array_merge($attr, $additionalAttr);
        }

        // otherwise simply return the attributes
        return $attr;
    }
369725
public static function queryByParentType( $parentType, $config = [] ) {

		$type	= isset( $config[ 'type' ] ) ? $config[ 'type' ] : self::TYPE_COMMENT;
		$status	= isset( $config[ 'status' ] ) ? $config[ 'status' ] : self::STATUS_APPROVED;

		return self::find()->where( [ 'parentType' => $parentType, 'type' => $type, 'status' => $status ] );
	}
544531
private function saveProductToDataBase($productId, $count, $attributesAndValues = null, $additionalProducts = null, $combinationId = null)
    {
        $order = $this->getIncompleteOrderFromDB();

        if (\Yii::$app->getModule('shop')->enableCombinations) {
            if (!empty($attributesAndValues)) {
                $combination = $this->getCombination($attributesAndValues, $productId);
                if (!empty($combination)) {
                    $orderProduct = $this->getOrderProduct($order->id, $productId, $combination->id);
                }
                else {
                    throw new Exception(\Yii::t('cart', 'Such attributes combination does not exist'));
                }
            }
            else if(!empty($combinationId)) {
                $orderProduct = $this->getOrderProduct($order->id, $productId, $combinationId);
            }
            else {
                $orderProduct = $this->getOrderProduct($order->id, $productId, null);
            }
        } else {
            $orderProduct = new OrderProduct();
            $orderProduct->product_id = $productId;
            $orderProduct->order_id = $order->id;
        }

        $orderProduct->count += $count;
        if ($orderProduct->validate()) {
            $orderProduct->save();

            if (!empty($additionalProducts)) {
                foreach ($additionalProducts as $additionalProduct) {
                    $orderProductAdditionalProduct = OrderProductAdditionalProduct::find()
                        ->where(['order_product_id' => $orderProduct->id, 'additional_product_id' => $additionalProduct['productId']])
                        ->one();
                    if (empty($orderProductAdditionalProduct)) {
                        $orderProductAdditionalProduct = new OrderProductAdditionalProduct();
                        $orderProductAdditionalProduct->order_product_id = $orderProduct->id;
                        $orderProductAdditionalProduct->additional_product_id = $additionalProduct['productId'];
                        $orderProductAdditionalProduct->number = $additionalProduct['number'];
                        if ($orderProductAdditionalProduct->validate()) $orderProductAdditionalProduct->save();
                    }
                    else {
                        $orderProductAdditionalProduct->number += $additionalProduct['number'];
                        if ($orderProductAdditionalProduct->validate()) $orderProductAdditionalProduct->save();

                    }
                }
            }
        } else die(var_dump($orderProduct->errors));
    }
363967
public function variationToProductAction($productId, $slug)
    {
        $request = $this->getCurrentRequest();
        $product = \is_object($productId) ? $productId : $this->get('sonata.product.set.manager')->findEnabledFromIdAndSlug($productId, $slug);

        if (!$product) {
            throw new NotFoundHttpException(sprintf('Unable to find the product with id=%d', $productId));
        }

        if (null !== $product->getParent()) {
            // We need the master product
            $product = $product->getParent();
        }

        $provider = $this->get('sonata.product.pool')->getProvider($product);

        $data = $request->query->get('sonata_product_variation_choices');

        $choices = $provider->getVariationsChoices($product, array_keys($data));

        $accessor = PropertyAccess::createPropertyAccessor();
        $currentValues = [];

        foreach ($choices as $field => $values) {
            $currentValues[$field] = array_search($accessor->getValue($product, $field), $values, true);
        }

        $form = $this->createForm(VariationChoiceType::class, $currentValues, [
            'product' => $product,
            'fields' => array_keys($data),
        ]);

        $form->handleRequest($request);

        $selectedVariation = $form->getData();

        // Retrieving correct values
        foreach ($selectedVariation as $key => $value) {
            $selectedVariation[$key] = $choices[$key][$value];
        }

        $variation = $provider->getVariation($product, $selectedVariation);

        $action = sprintf('%s:variationToProduct', $provider->getBaseControllerName());
        $response = $this->forward($action, [
            'product' => $product,
            'variation' => $variation,
        ]);

        if ($this->get('kernel')->isDebug() && !($response instanceof JsonResponse)) {
            $response->setContent(sprintf("\n<!-- [Sonata] Product code: %s, id: %s, action: %s  -->\n%s\n<!-- [Sonata] end product -->\n",
                $this->get('sonata.product.pool')->getProductCode($product),
                $product->getId(),
                $action,
                $response->getContent()
            ));
        }

        return $response;
    }
160485
private function getItemsData($quoteItem, $_product, $_parentProduct)
    {
        $totalPrice = (!isset($_parentProduct) ? $quoteItem->getBaseRowTotalInclTax() : $quoteItem->getParentItem()->getBaseRowTotalInclTax());
        $inStock = ($_product->isInStock())
            ? 'In Stock'
            : 'Out of stock';
        $total = $this->priceHelper->currency(
            $totalPrice,
            true,
            false
        );

        $productUrl = (isset($_parentProduct) ? $this->urlFinder->fetchFor($_parentProduct) : $this->urlFinder->fetchFor($_product));
        $grandTotal = $this->priceHelper->currency(
            $this->getGrandTotal(),
            true,
            false
        );
        $itemsData = [
            'grandTotal' => $grandTotal,
            'total' => $total,
            'inStock' => $inStock,
            'productUrl' => $productUrl,
            'product' => (isset($_parentProduct) ? $_parentProduct : $_product),
            'qty' => isset($_parentProduct) ? $quoteItem->getParentItem()->getQty() : $quoteItem->getQty(),
            'product_details' => $_product
        ];

        return $itemsData;
    }
810176
private function getAttributeTableFieldItems(
        $attributeTables,
        $minProductId,
        $maxProductId,
        $storeIds,
        $attributeMapper
    ) {
        $attributeQueries = [];

        foreach ($attributeTables as $attributeTable) {
            $attributeQueries[] = $this->_resource->getConnection()->select()
                ->from($this->getTable($attributeTable), ['attribute_id', 'store_id', 'entity_id', 'value'])
                ->where('entity_id >= ?', $minProductId)
                ->where('entity_id <= ?', $maxProductId)
                ->where('store_id IN (?)', $storeIds)
                ->where('attribute_id IN (?)', $attributeMapper);
        }

        try {
            $unionQuery = $this->_resource->getConnection()->select()
                ->union($attributeQueries, \Zend_Db_Select::SQL_UNION_ALL); // @codingStandardsIgnoreLine
            $this->iterator->walk(
                (string)$unionQuery,
                [[$this, 'handleAttributeDataTable']],
                [
                    'attributeMapper' => $attributeMapper,
                ],
                $this->_resource->getConnection()
            );
        } catch (\Exception $e) { // @codingStandardsIgnoreLine
        }

        return $this;
    }
82505
public function parameters(bool $parent = true)
    {
        $faker = Factory::create();

        $bag = new Bag();
        $bag->set('name', $faker->name);
        $bag->set('code', $faker->name);
        $bag->set('description', $faker->text);
        $bag->set('type', ProductTypeFaker::make()->parameters()->toArray());
        $bag->set('supplier', SupplierFaker::make()->parameters()->toArray());

        if ($parent) {
            $bag->set('parent', ProductFaker::make()->parameters(false)->toArray());
        }

        return $bag;
    }
277331
public function createProductAttribute(
        Attribute $attribute,
        ProductInterface $product,
        AttributeValue $attributeValue
    ) {
        $productAttribute = $this->productAttributeRepository->createNew();
        $productAttribute->setAttribute($attribute);
        $productAttribute->setProduct($product);
        $productAttribute->setAttributeValue($attributeValue);
        $this->entityManager->persist($productAttribute);

        $product->addProductAttribute($productAttribute);

        return $productAttribute;
    }
1171037
protected function setAddonData(
        ItemInterface $lastProcessedProductItem,
        ItemInterface $item,
        ProductInterface $parentItemProduct = null
    ) {
        $item->setParent($lastProcessedProductItem);

        $parentProduct = $lastProcessedProductItem->getProduct();
        $addonProduct = $item->getProduct();
        /** @var Addon $addon */
        $addon = $this->addonRepository->findOneBy(['product' => $parentProduct, 'addon' => $addonProduct]);

        // Check if parent product has an addon relation.
        if (!$addon && $parentItemProduct) {
            $addon = $this->addonRepository->findOneBy(['product' => $parentProduct, 'addon' => $parentItemProduct]);
        }

        if (!$addon) {
            throw new \Exception(
                'Addon id ' . $addonProduct->getId() . ' for product id ' . $parentProduct->getId() . ' not found.'
            );
        }
        $item->setAddon($addon);

        return $addon;
    }
709379
protected function createChildContext(array $parentContext, $attribute/*, string $format = null */)
    {
        if (isset($parentContext[self::ATTRIBUTES][$attribute])) {
            $parentContext[self::ATTRIBUTES] = $parentContext[self::ATTRIBUTES][$attribute];
        } else {
            unset($parentContext[self::ATTRIBUTES]);
        }

        return $parentContext;
    }
1013548
public static function fromAttributes(Model $parent, $attributes, $table, $exists = false)
    {
        $instance = new static;

        $instance->timestamps = $instance->hasTimestampAttributes($attributes);

        // The pivot model is a "dynamic" model since we will set the tables dynamically
        // for the instance. This allows it work for any intermediate tables for the
        // many to many relationship that are defined by this developer's classes.
        $instance->setConnection($parent->getConnectionName())
            ->setTable($table)
            ->forceFill($attributes)
            ->syncOriginal();

        // We store off the parent instance so we will access the timestamp column names
        // for the model, since the pivot model timestamps aren't easily configurable
        // from the developer's point of view. We can use the parents to get these.
        $instance->pivotParent = $parent;

        $instance->exists = $exists;

        return $instance;
    }
386228
public static function fromRawAttributes(Model $parent, $attributes, $table, $exists = false)
    {
        $instance = new static($attributes, $parent, $table, $exists);

        $instance->setRawAttributes($attributes, true);

        return $instance;
    }
835203
protected function prepareProductRelationAttributes()
    {

        // initialize and return the entity
        return $this->initializeEntity(
            array(
                MemberNames::PARENT_ID => $this->parentId,
                MemberNames::CHILD_ID  => $this->childId
            )
        );
    }
410101
public function bindParent($parent, $parentPropertyName = null)
    {
        $this->parent = $parent;
        $this->parentPropertyName = $parentPropertyName;
        return $this;
    }
582244
public function bindParent($parent, $parentPropertyName=NULL)
	{
		$this->_parent = $parent;
		$this->_parentPropertyName = $parentPropertyName;
		return $this;
	}
1311436
public function html(string $html, array $parentAttributes = [])
    {
        return $this->add(Html::raw($html)->setParentAttributes($parentAttributes));
    }