Completed
Push — master ( 009411...7fe99b )
by Rafał
18:49 queued 07:10
created

configureComponentTextStyles()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 47
rs 9.1563
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Superdesk Web Publisher Core Bundle.
7
 *
8
 * Copyright 2020 Sourcefabric z.ú. and contributors.
9
 *
10
 * For the full copyright and license information, please see the
11
 * AUTHORS and LICENSE files distributed with this source code.
12
 *
13
 * @copyright 2020 Sourcefabric z.ú
14
 * @license http://www.superdesk.org/license
15
 */
16
17
namespace SWP\Bundle\CoreBundle\AppleNews\Converter;
18
19
use SWP\Bundle\ContentBundle\Model\SlideshowItemInterface;
20
use SWP\Bundle\CoreBundle\AppleNews\Component\Byline;
21
use SWP\Bundle\CoreBundle\AppleNews\Component\Caption;
22
use SWP\Bundle\CoreBundle\AppleNews\Component\Gallery;
23
use SWP\Bundle\CoreBundle\AppleNews\Component\GalleryItem;
24
use SWP\Bundle\CoreBundle\AppleNews\Component\Intro;
25
use SWP\Bundle\CoreBundle\AppleNews\Component\Photo;
26
use SWP\Bundle\CoreBundle\AppleNews\Component\Title;
27
use SWP\Bundle\CoreBundle\AppleNews\Document\ArticleDocument;
28
use SWP\Bundle\CoreBundle\AppleNews\Document\ComponentLayout;
29
use SWP\Bundle\CoreBundle\AppleNews\Document\ComponentLayouts;
30
use SWP\Bundle\CoreBundle\AppleNews\Document\ComponentTextStyle;
31
use SWP\Bundle\CoreBundle\AppleNews\Document\ComponentTextStyles;
32
use SWP\Bundle\CoreBundle\AppleNews\Document\Layout;
33
use SWP\Bundle\CoreBundle\AppleNews\Document\LinkedArticle;
34
use SWP\Bundle\CoreBundle\AppleNews\Document\Margin;
35
use SWP\Bundle\CoreBundle\AppleNews\Document\Metadata;
36
use SWP\Bundle\CoreBundle\AppleNews\Document\TextStyle;
37
use SWP\Bundle\CoreBundle\AppleNews\Serializer\AppleNewsFormatSerializer;
38
use SWP\Bundle\CoreBundle\Factory\VersionFactory;
39
use SWP\Bundle\CoreBundle\Model\ArticleInterface;
40
use SWP\Bundle\CoreBundle\Model\TenantInterface;
41
use SWP\Bundle\CoreBundle\Routing\TenantAwareAbsoluteUrlRouter;
42
43
final class ArticleToAppleNewsFormatConverter
44
{
45
    private $serializer;
46
47
    private $router;
48
49
    private $versionFactory;
50
51
    private $articleBodyConverter;
52
53
    public function __construct(
54
        VersionFactory $versionFactory,
55
        AppleNewsFormatSerializer $serializer,
56
        TenantAwareAbsoluteUrlRouter $router,
57
        ArticleBodyToComponentsConverter $articleBodyConverter
58
    ) {
59
        $this->versionFactory = $versionFactory;
60
        $this->serializer = $serializer;
61
        $this->router = $router;
62
        $this->articleBodyConverter = $articleBodyConverter;
63
    }
64
65
    public function convert(ArticleInterface $article, TenantInterface $tenant): string
66
    {
67
        $version = $this->versionFactory->create();
68
69
        $metadata = new Metadata();
70
        $articleDocument = new ArticleDocument();
71
        $articleDocument->setTitle($article->getTitle());
72
        $articleDocument->setIdentifier((string) $article->getId());
73
        $articleDocument->setLanguage($article->getLocale());
74
75
        $articleDocument->addComponent(new Title($article->getTitle(), 'halfMarginBelowLayout'));
76
        $articleDocument->addComponent(new Intro($article->getLead(), 'halfMarginBelowLayout'));
77
        $articleDocument->addComponent($this->createBylineComponent($article));
78
79
        $featureMedia = $article->getFeatureMedia();
80
81
        if (null !== $featureMedia) {
82
            $featureMediaUrl = $this->router->generate(
83
                'swp_media_get',
84
                $tenant,
85
                [
86
                    'mediaId' => $featureMedia->getImage()->getAssetId(),
87
                    'extension' => $featureMedia->getImage()->getFileExtension(),
88
                ]
89
            );
90
91
            $articleDocument->addComponent(new Photo($featureMediaUrl, (string) $featureMedia->getDescription()));
92
            $articleDocument->addComponent(new Caption($featureMedia->getDescription(), 'marginBetweenComponents'));
93
            $metadata->setThumbnailURL($featureMediaUrl);
94
        }
95
96
        $components = $this->articleBodyConverter->convert($article->getBody());
97
        $components = $this->processGalleries($components, $article, $tenant);
98
        $links = $this->processRelatedArticles($article, $tenant);
99
100
        foreach ($components as $component) {
101
            $articleDocument->addComponent($component);
102
        }
103
104
        $articleDocument->setLayout(new Layout(20, 1024, 20, 60));
105
106
        $componentTextStyles = $this->configureComponentTextStyles();
107
        $articleDocument->setComponentTextStyles($componentTextStyles);
108
109
        $componentLayouts = $this->configureComponentLayouts();
110
        $articleDocument->setComponentLayouts($componentLayouts);
111
112
        $metadata->setAuthors($article->getAuthorsNames());
113
114
        $canonicalUrl = $this->router->generate(
115
            $article->getRoute()->getRouteName(),
116
            $tenant,
117
            [
118
                'slug' => $article->getSlug(),
119
            ]
120
        );
121
122
        $metadata->setCanonicalUrl($canonicalUrl);
123
        $metadata->setDateCreated($article->getCreatedAt());
124
        $metadata->setDatePublished($article->getPublishedAt());
125
126
        $metadata->setExcerpt($article->getLead() ?? '');
127
128
        $metadata->setGeneratorIdentifier('publisher');
129
        $metadata->setGeneratorName('Publisher');
130
        $metadata->setGeneratorVersion($version->getVersion());
131
132
        $metadata->setKeywords($article->getKeywordsNames());
133
        $metadata->setLinks($links);
134
135
        $articleDocument->setMetadata($metadata);
136
137
        return $this->serializer->serialize($articleDocument);
138
    }
139
140
    private function processGalleries(array $components, ArticleInterface $article, TenantInterface $tenant): array
141
    {
142
        if ($article->getSlideshows()->count() > 0) {
143
            foreach ($article->getSlideshows() as $slideshow) {
144
                $galleryComponent = new Gallery();
145
                /** @var SlideshowItemInterface $slideshowItem */
146
                foreach ($slideshow->getItems() as $slideshowItem) {
147
                    $media = $slideshowItem->getArticleMedia();
148
                    $caption = $media->getDescription();
149
                    $url = $this->router->generate(
150
                        'swp_media_get',
151
                        $tenant,
152
                        [
153
                            'mediaId' => $media->getImage()->getAssetId(),
154
                            'extension' => $media->getImage()->getFileExtension(),
155
                        ]
156
                    );
157
158
                    $galleryItem = new GalleryItem($url, $caption);
159
                    $galleryComponent->addItem($galleryItem);
160
                }
161
162
                $components[] = $galleryComponent;
163
            }
164
        }
165
166
        return $components;
167
    }
168
169
    private function processRelatedArticles(ArticleInterface $article, TenantInterface $tenant): array
170
    {
171
        $links = [];
172
        if ($article->getRelatedArticles()->count() > 0) {
173
            foreach ($article->getRelatedArticles() as $relatedArticle) {
174
                $relatedArticleRoute = $relatedArticle->getArticle()->getRoute();
175
176
                $url = $this->router->generate(
177
                    $relatedArticleRoute->getRouteName(),
178
                    $tenant,
179
                    [
180
                        'slug' => $relatedArticle->getArticle()->getSlug(),
181
                    ]
182
                );
183
184
                $linkedArticle = new LinkedArticle($url);
0 ignored issues
show
Bug introduced by
The call to LinkedArticle::__construct() misses a required argument $relationship.

This check looks for function calls that miss required arguments.

Loading history...
185
                $links[] = $linkedArticle;
186
            }
187
        }
188
189
        return $links;
190
    }
191
192
    private function configureComponentTextStyles(): ComponentTextStyles
193
    {
194
        $linkStyle = new TextStyle('#8a0b1f');
195
        $componentTextStyles = new ComponentTextStyles();
196
        $componentTextStylesBody = new ComponentTextStyle();
197
        $componentTextStylesBody->setBackgroundColor('#fff');
198
        $componentTextStylesBody->setFontName('IowanOldStyle-Roman');
199
        $componentTextStylesBody->setFontColor('#222222');
200
        $componentTextStylesBody->setFontSize(16);
201
        $componentTextStylesBody->setLineHeight(22);
202
        $componentTextStylesBody->setLinkStyle($linkStyle);
203
        $componentTextStyles->setDefault($componentTextStylesBody);
204
205
        $componentTextStylesBody = new ComponentTextStyle();
206
        $componentTextStylesBody->setFontName('IowanOldStyle-Roman');
207
        $componentTextStyles->setDefaultBody($componentTextStylesBody);
208
209
        $componentTextStylesTitle = new ComponentTextStyle();
210
        $componentTextStylesTitle->setFontName('DINAlternate-Bold');
211
        $componentTextStylesTitle->setFontSize(42);
212
        $componentTextStylesTitle->setLineHeight(44);
213
        $componentTextStylesTitle->setTextColor('#53585F');
214
        $componentTextStyles->setDefaultTitle($componentTextStylesTitle);
215
216
        $componentTextStylesIntro = new ComponentTextStyle();
217
        $componentTextStylesIntro->setFontName('DINAlternate-Bold');
218
        $componentTextStylesIntro->setFontSize(18);
219
        $componentTextStylesIntro->setLineHeight(22);
220
        $componentTextStylesIntro->setTextColor('#A6AAA9');
221
        $componentTextStyles->setDefaultIntro($componentTextStylesIntro);
222
223
        $componentTextStylesQuote = new ComponentTextStyle();
224
        $componentTextStylesQuote->setFontName('IowanOldStyle-Italic');
225
        $componentTextStylesQuote->setFontSize(30);
226
        $componentTextStylesQuote->setLineHeight(36);
227
        $componentTextStylesQuote->setTextColor('#A6AAA9');
228
        $componentTextStyles->setDefaultQuote($componentTextStylesQuote);
229
230
        $componentTextStylesByline = new ComponentTextStyle();
231
        $componentTextStylesByline->setFontName('DINAlternate-Bold');
232
        $componentTextStylesByline->setFontSize(15);
233
        $componentTextStylesByline->setLineHeight(18);
234
        $componentTextStylesByline->setTextColor('#53585F');
235
        $componentTextStyles->setDefaultByline($componentTextStylesByline);
236
237
        return $componentTextStyles;
238
    }
239
240
    private function configureComponentLayouts(): ComponentLayouts
241
    {
242
        $componentLayouts = new ComponentLayouts();
243
        $componentLayout = new ComponentLayout();
244
        $componentLayout->setColumnStart(0);
245
        $componentLayout->setMargin(new Margin(12));
246
        $componentLayouts->setHalfMarginBelowLayout($componentLayout);
247
248
        $componentLayout = new ComponentLayout();
249
        $componentLayout->setColumnStart(0);
250
        $componentLayout->setMargin(new Margin(12, 12));
251
        $componentLayouts->setMarginBetweenComponents($componentLayout);
252
253
        $componentLayout = new ComponentLayout();
254
        $componentLayout->setColumnStart(0);
255
        $componentLayout->setMargin(new Margin(24));
256
        $componentLayouts->setFullMarginBelowLayout($componentLayout);
257
258
        return $componentLayouts;
259
    }
260
261
    private function createBylineComponent(ArticleInterface $article): Byline
262
    {
263
        $routeName = $article->getRoute()->getName();
264
        $authorNames = trim(implode(', ', $article->getAuthorsNames()), ', ');
265
        $publishedAt = $article->getPublishedAt();
266
        $publishedAtString = $publishedAt->format('M d, Y g:i A');
267
268
        return new Byline("$authorNames | $publishedAtString | $routeName", 'fullMarginBelowLayout');
269
    }
270
}
271