Passed
Push — trunk ( c83b87...a87e38 )
by Christian
22:40 queued 02:13
created

ProductPageLoader::loadDefaultAdditions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 2
nop 4
dl 0
loc 17
rs 9.9666
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Shopware\Storefront\Page\Product;
4
5
use Shopware\Core\Content\Category\Exception\CategoryNotFoundException;
6
use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaCollection;
7
use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaEntity;
0 ignored issues
show
Bug introduced by
The type Shopware\Core\Content\Pr...edia\ProductMediaEntity was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Shopware\Core\Content\Product\Exception\ProductNotFoundException;
9
use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
10
use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionCollection;
11
use Shopware\Core\Content\Property\PropertyGroupCollection;
12
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
13
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
14
use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
15
use Shopware\Core\System\SalesChannel\SalesChannelContext;
16
use Shopware\Storefront\Page\GenericPageLoaderInterface;
17
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
18
use Symfony\Component\HttpFoundation\Request;
19
20
/**
21
 * @package storefront
22
 */
23
class ProductPageLoader
24
{
25
    private GenericPageLoaderInterface $genericLoader;
26
27
    private EventDispatcherInterface $eventDispatcher;
28
29
    private AbstractProductDetailRoute $productDetailRoute;
30
31
    /**
32
     * @internal
33
     */
34
    public function __construct(
35
        GenericPageLoaderInterface $genericLoader,
36
        EventDispatcherInterface $eventDispatcher,
37
        AbstractProductDetailRoute $productDetailRoute
38
    ) {
39
        $this->genericLoader = $genericLoader;
40
        $this->eventDispatcher = $eventDispatcher;
41
        $this->productDetailRoute = $productDetailRoute;
42
    }
43
44
    /**
45
     * @throws CategoryNotFoundException
46
     * @throws InconsistentCriteriaIdsException
47
     * @throws MissingRequestParameterException
48
     * @throws ProductNotFoundException
49
     */
50
    public function load(Request $request, SalesChannelContext $context): ProductPage
51
    {
52
        $productId = $request->attributes->get('productId');
53
        if (!$productId) {
54
            throw new MissingRequestParameterException('productId', '/productId');
55
        }
56
57
        $criteria = (new Criteria())
58
            ->addAssociation('manufacturer.media')
59
            ->addAssociation('options.group')
60
            ->addAssociation('properties.group')
61
            ->addAssociation('mainCategories.category')
62
            ->addAssociation('media');
63
64
        $this->eventDispatcher->dispatch(new ProductPageCriteriaEvent($productId, $criteria, $context));
65
66
        $result = $this->productDetailRoute->load($productId, $request, $context, $criteria);
67
        $product = $result->getProduct();
68
69
        if ($product->getMedia()) {
70
            $product->getMedia()->sort(function (ProductMediaEntity $a, ProductMediaEntity $b) {
71
                return $a->getPosition() <=> $b->getPosition();
72
            });
73
        }
74
75
        if ($product->getMedia() && $product->getCover()) {
76
            $product->setMedia(new ProductMediaCollection(array_merge(
77
                [$product->getCover()->getId() => $product->getCover()],
78
                $product->getMedia()->getElements()
79
            )));
80
        }
81
82
        if ($category = $product->getSeoCategory()) {
83
            $request->request->set('navigationId', $category->getId());
84
        }
85
86
        $page = $this->genericLoader->load($request, $context);
87
        /** @var ProductPage $page */
88
        $page = ProductPage::createFrom($page);
89
90
        $page->setProduct($product);
91
        $page->setConfiguratorSettings($result->getConfigurator() ?? new PropertyGroupCollection());
92
        $page->setNavigationId($product->getId());
93
94
        if ($cmsPage = $product->getCmsPage()) {
95
            $page->setCmsPage($cmsPage);
96
        }
97
98
        $this->loadOptions($page);
99
        $this->loadMetaData($page);
100
101
        $this->eventDispatcher->dispatch(
102
            new ProductPageLoadedEvent($page, $context, $request)
103
        );
104
105
        return $page;
106
    }
107
108
    private function loadOptions(ProductPage $page): void
109
    {
110
        $options = new PropertyGroupOptionCollection();
111
112
        if (($optionIds = $page->getProduct()->getOptionIds()) === null) {
113
            $page->setSelectedOptions($options);
114
115
            return;
116
        }
117
118
        foreach ($page->getConfiguratorSettings() as $group) {
119
            $groupOptions = $group->getOptions();
120
            if ($groupOptions === null) {
121
                continue;
122
            }
123
            foreach ($optionIds as $optionId) {
124
                $groupOption = $groupOptions->get($optionId);
125
                if ($groupOption !== null) {
126
                    $options->add($groupOption);
127
                }
128
            }
129
        }
130
131
        $page->setSelectedOptions($options);
132
    }
133
134
    private function loadMetaData(ProductPage $page): void
135
    {
136
        $metaInformation = $page->getMetaInformation();
137
138
        if (!$metaInformation) {
0 ignored issues
show
introduced by
$metaInformation is of type Shopware\Storefront\Page\MetaInformation, thus it always evaluated to true.
Loading history...
139
            return;
140
        }
141
142
        $metaDescription = $page->getProduct()->getTranslation('metaDescription')
143
            ?? $page->getProduct()->getTranslation('description');
144
        $metaInformation->setMetaDescription((string) $metaDescription);
145
146
        $metaInformation->setMetaKeywords((string) $page->getProduct()->getTranslation('keywords'));
147
148
        if ((string) $page->getProduct()->getTranslation('metaTitle') !== '') {
149
            $metaInformation->setMetaTitle((string) $page->getProduct()->getTranslation('metaTitle'));
150
151
            return;
152
        }
153
154
        $metaTitleParts = [$page->getProduct()->getTranslation('name')];
155
156
        foreach ($page->getSelectedOptions() as $option) {
157
            $metaTitleParts[] = $option->getTranslation('name');
158
        }
159
160
        $metaTitleParts[] = $page->getProduct()->getProductNumber();
161
162
        $metaInformation->setMetaTitle(implode(' | ', $metaTitleParts));
163
    }
164
}
165