• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sulu / SuluContentBundle / 11380658683

17 Oct 2024 07:50AM UTC coverage: 98.66% (-1.3%) from 100.0%
11380658683

Pull #271

github

web-flow
Merge a4038bc66 into a23a5b050
Pull Request #271: Draft: Base implementation of website content resolving

195 of 232 new or added lines in 13 files covered. (84.05%)

2725 of 2762 relevant lines covered (98.66%)

10.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.46
/Content/Application/ContentResolver/ContentResolver.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of Sulu.
7
 *
8
 * (c) Sulu GmbH
9
 *
10
 * This source file is subject to the MIT license that is bundled
11
 * with this source code in the file LICENSE.
12
 */
13

14
namespace Sulu\Bundle\ContentBundle\Content\Application\ContentResolver;
15

16
use Sulu\Bundle\ContentBundle\Content\Application\ContentResolver\Resolver\ResolverInterface;
17
use Sulu\Bundle\ContentBundle\Content\Application\ContentResolver\Resolver\TemplateResolver;
18
use Sulu\Bundle\ContentBundle\Content\Application\ContentResolver\Value\ContentView;
19
use Sulu\Bundle\ContentBundle\Content\Application\ContentResolver\Value\ResolvableResource;
20
use Sulu\Bundle\ContentBundle\Content\Application\ResourceLoader\ResourceLoaderProvider;
21
use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface;
22

23
class ContentResolver implements ContentResolverInterface
24
{
25
    /**
26
     * @param iterable<ResolverInterface> $contentResolvers
27
     */
28
    public function __construct(
29
        private iterable $contentResolvers,
30
        private ResourceLoaderProvider $resourceLoaderProvider
31
    ) {
32
    }
1✔
33

34
    /**
35
     * @return array{
36
     *      resource: object,
37
     *      content: mixed,
38
     *      view: mixed[]
39
     *  }
40
     */
41
    public function resolve(DimensionContentInterface $dimensionContent): array
42
    {
43
        $contentViews = [];
1✔
44
        foreach ($this->contentResolvers as $key => $contentResolver) {
1✔
45
            $contentView = $contentResolver->resolve($dimensionContent);
1✔
46

47
            if ($contentResolver instanceof TemplateResolver) {
1✔
48
                /** @var mixed[] $content */
49
                $content = $contentView->getContent();
1✔
50
                $contentViews = \array_merge($contentViews, $content);
1✔
51
                continue;
1✔
52
            }
53

54
            $contentViews[$key] = $contentView;
1✔
55
        }
56

57
        $result = $this->resolveContentViews($contentViews);
1✔
58
        $resources = $this->loadResolvableResources($result['resolvableResources'], $dimensionContent->getLocale());
1✔
59
        \array_walk_recursive($result['content'], function(&$value) use ($resources) {
1✔
60
            if ($value instanceof ResolvableResource) {
1✔
NEW
61
                $value = $resources[$value->getResourceLoaderKey()][$value->getId()];
×
62
            }
63
        });
1✔
64

65
        return [
1✔
66
            'resource' => $dimensionContent->getResource(),
1✔
67
            'content' => $result['content'],
1✔
68
            'view' => $result['view'],
1✔
69
        ];
1✔
70
    }
71

72
    /**
73
     * @param ContentView[] $contentViews
74
     *
75
     * @return array{
76
     *     content: mixed[],
77
     *     view: mixed[],
78
     *     resolvableResources: array<string, array<int|string>>
79
     *     }
80
     */
81
    private function resolveContentViews(array $contentViews): array
82
    {
83
        $content = [];
1✔
84
        $view = [];
1✔
85
        $resolvableResources = [];
1✔
86

87
        foreach ($contentViews as $name => $contentView) {
1✔
88
            $result = $this->resolveContentView($contentView, $name);
1✔
89
            $content = \array_merge($content, $result['content']);
1✔
90
            $view = \array_merge($view, $result['view']);
1✔
91
            $resolvableResources = \array_merge_recursive($resolvableResources, $result['resolvableResources']);
1✔
92
        }
93

94
        return [
1✔
95
            'content' => $content,
1✔
96
            'view' => $view,
1✔
97
            'resolvableResources' => $resolvableResources,
1✔
98
        ];
1✔
99
    }
100

101
    /**
102
     * @param array<string, array<int|string>> $resolvableResourceIds
103
     *
104
     * @return array<string, mixed[]>
105
     */
106
    private function loadResolvableResources(array $resolvableResourceIds, ?string $locale): array
107
    {
108
        $resources = [];
1✔
109
        foreach ($resolvableResourceIds as $resourceLoaderKey => $ids) {
1✔
NEW
110
            $resourceLoader = $this->resourceLoaderProvider->getResourceLoader($resourceLoaderKey);
×
NEW
111
            if (!$resourceLoader) {
×
NEW
112
                throw new \RuntimeException(\sprintf('ResourceLoader with key "%s" not found', $resourceLoaderKey));
×
113
            }
114

NEW
115
            $resources[$resourceLoaderKey] = $resourceLoader->load($ids, $locale);
×
116
        }
117

118
        return $resources;
1✔
119
    }
120

121
    /**
122
     * @return array{
123
     *     content: mixed[],
124
     *     view: mixed[],
125
     *     resolvableResources: array<string, array<int|string>>
126
     *     }
127
     */
128
    private function resolveContentView(ContentView $contentView, string $name): array
129
    {
130
        $resolvableResources = [];
1✔
131
        $content[$name] = $contentView->getContent();
1✔
132
        $view[$name] = $contentView->getView();
1✔
133

134
        if (\is_array($content[$name])) {
1✔
135
            foreach ($content[$name] as $index => $value) {
1✔
136
                $contentViewValues = [];
1✔
137
                $otherValues = [];
1✔
138

139
                if (\is_array($value)) {
1✔
140
                    foreach ($value as $key => $entry) {
1✔
141
                        if ($entry instanceof ResolvableResource) {
1✔
NEW
142
                            $resolvableResources[$entry->getResourceLoaderKey()][] = $entry->getId();
×
143
                        }
144

145
                        match (true) {
1✔
146
                            $entry instanceof ContentView => $contentViewValues[$key] = $entry,
1✔
147
                            default => $otherValues[$key] = $entry,
1✔
148
                        };
1✔
149
                    }
150

151
                    $resolvedContentViews = $this->resolveContentViews($contentViewValues);
1✔
152
                    $result['content'] = \array_merge(
1✔
153
                        $resolvedContentViews['content'],
1✔
154
                        $otherValues,
1✔
155
                    );
1✔
156
                    $result['view'] = \array_merge(
1✔
157
                        $resolvedContentViews['view'],
1✔
158
                    );
1✔
159

160
                    $resolvableResources = \array_merge_recursive($resolvableResources, $resolvedContentViews['resolvableResources']);
1✔
161

162
                    $content[$name][$index] = $result['content'];
1✔
163
                    $view[$name][$index] = $result['view'];
1✔
164
                    continue;
1✔
165
                }
166

167
                if ($value instanceof ResolvableResource) {
1✔
NEW
168
                    $resolvableResources[$value->getResourceLoaderKey()][] = $value->getId();
×
169
                }
170

171
                $result = $value instanceof ContentView ?
1✔
172
                    $this->resolveContentView($value, $index) :
1✔
173
                    [
1✔
174
                        'content' => $value,
1✔
175
                        'view' => [],
1✔
176
                    ];
1✔
177

178
                // TODO this has to be refactored
179
                $content[$name] = \array_merge($content[$name], \is_array($result['content']) ? $result['content'] : [$index => $result['content']]); // @phpstan-ignore-line
1✔
180
                $view[$name] = \array_merge($view[$name], $result['view']);
1✔
181
            }
182
        }
183

184
        return [
1✔
185
            'content' => $content,
1✔
186
            'view' => $view,
1✔
187
            'resolvableResources' => $resolvableResources,
1✔
188
        ];
1✔
189
    }
190
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc