Lines 100.00% 53 / 53
Methods 100.00% 8 / 8
Classes 100.00% 1 / 1
Covered by tests of size
Name Lines Methods CRAP
 __construct 100.00% 3 / 3 100.00% 1 / 1 1
 getProcessedNews 100.00% 12 / 12 100.00% 1 / 1 3
 processContent 100.00% 2 / 2 100.00% 1 / 1 1
 buildInformationLink 100.00% 7 / 7 100.00% 1 / 1 1
 getEditLink 100.00% 10 / 10 100.00% 1 / 1 2
 getCommentMessage 100.00% 8 / 8 100.00% 1 / 1 5
 formatNewsDate 100.00% 8 / 8 100.00% 1 / 1 2
 getAuthorInfo 100.00% 3 / 3 100.00% 1 / 1 2
35final class NewsService
36{
37    private News $news;
38
39    private Glossary $glossary;
40
41    private FaqHelper $faqHelper;
42
43    public function __construct(
44        private readonly Configuration $configuration,
45        private readonly CurrentUser $currentUser,
46    ) {
47        $this->news = new News($this->configuration);
48        $this->glossary = new Glossary($this->configuration);
49        $this->faqHelper = new FaqHelper($this->configuration);
50    }
51
52    /**
53     * Gets and processes news by ID.
54     *
55     * @return array<string, mixed>
56     */
57    public function getProcessedNews(int $newsId): array
58    {
59        $news = $this->news->get($newsId);
60        if ($news === []) {
61            return [];
62        }
63
64        // Process content with glossary
65        $news['processedContent'] = $this->processContent((string) ($news['content'] ?? ''));
66        $news['processedHeader'] = $this->processContent((string) ($news['header'] ?? ''));
67
68        // Add an information link if available
69        if ((string) ($news['link'] ?? '') !== '') {
70            $news['processedContent'] .= $this->buildInformationLink(
71                (string) ($news['link'] ?? ''),
72                (string) ($news['target'] ?? ''),
73                (string) ($news['linkTitle'] ?? ''),
74            );
75        }
76
77        return $news;
78    }
79
80    /**
81     * Processes content with glossary and cleanup.
82     */
83    private function processContent(string $content): string
84    {
85        $content = $this->glossary->insertItemsIntoContent($content);
86        return $this->faqHelper->cleanUpContent($content);
87    }
88
89    /**
90     * Builds the information link HTML.
91     */
92    private function buildInformationLink(string $link, string $target, string $linkTitle): string
93    {
94        return sprintf(
95            '</p><p>%s<a href="%s" target="%s">%s</a>',
96            Translation::getString('msgInfo'),
97            Strings::htmlentities($link),
98            $target,
99            Strings::htmlentities($linkTitle),
100        );
101    }
102
103    /**
104     * Checks if a user can edit news and returns an edit link.
105     */
106    public function getEditLink(int $newsId): string
107    {
108        if ($this->currentUser->perm->hasPermission(
109            $this->currentUser->getUserId(),
110            PermissionType::NEWS_EDIT->value,
111        )) {
112            return sprintf(
113                '<a href="./admin/news/edit/%d">%s</a>',
114                $newsId,
115                Translation::getString('ad_menu_news_edit'),
116            );
117        }
118
119        return '';
120    }
121
122    /**
123     * Gets a comment message based on permissions and news settings.
124     */
125    public function getCommentMessage(array $news): string
126    {
127        if (
128            -1 === $this->currentUser->getUserId() && !$this->configuration->get('records.allowCommentsForGuests')
129            || !$news['active']
130            || !$news['allowComments']
131        ) {
132            return Translation::getString('msgWriteNoComment');
133        }
134
135        return sprintf(
136            '<a href="#" data-bs-toggle="modal" data-bs-target="#pmf-modal-add-comment">%s</a>',
137            Translation::getString('newsWriteComment'),
138        );
139    }
140
141    /**
142     * Formats the news date.
143     */
144    public function formatNewsDate(array $news): string
145    {
146        if (!$news['active']) {
147            return '';
148        }
149
150        $date = new Date($this->configuration);
151        return sprintf(
152            '%s<span id="newsLastUpd">%s</span>',
153            Translation::getString('msgLastUpdateArticle'),
154            $date->format((string) ($news['date'] ?? '')),
155        );
156    }
157
158    /**
159     * Gets author information.
160     */
161    public function getAuthorInfo(array $news): string
162    {
163        if (!$news['active']) {
164            return '';
165        }
166
167        return Translation::getString('msgAuthor') . ': ' . (string) ($news['authorName'] ?? '');
168    }
169}