Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.74% covered (success)
90.74%
49 / 54
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
CreateNewsEndpoint
90.74% covered (success)
90.74%
49 / 54
50.00% covered (danger)
50.00%
1 / 2
10.08
0.00% covered (danger)
0.00%
0 / 1
 configure
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 handle
90.20% covered (success)
90.20%
46 / 51
0.00% covered (danger)
0.00%
0 / 1
9.08
1<?php
2
3namespace Olz\News\Endpoints;
4
5use Olz\Api\OlzCreateEntityTypedEndpoint;
6use Olz\Entity\News\NewsEntry;
7use Olz\Entity\Users\User;
8use Symfony\Component\Mime\Email;
9
10/**
11 * @phpstan-import-type OlzNewsId from NewsEndpointTrait
12 * @phpstan-import-type OlzNewsData from NewsEndpointTrait
13 *
14 * TODO: Those should not be necessary!
15 * @phpstan-import-type OlzNewsFormat from NewsEndpointTrait
16 *
17 * @extends OlzCreateEntityTypedEndpoint<OlzNewsId, OlzNewsData, array{
18 *   captchaToken?: ?non-empty-string,
19 * }, array{
20 *   status: 'OK'|'DENIED'|'ERROR',
21 * }>
22 */
23class CreateNewsEndpoint extends OlzCreateEntityTypedEndpoint {
24    use NewsEndpointTrait;
25
26    public function configure(): void {
27        parent::configure();
28        $this->configureNewsEndpointTrait();
29        $this->phpStanUtils->registerTypeImport(NewsEndpointTrait::class);
30    }
31
32    protected function handle(mixed $input): mixed {
33        $input_data = $input['data'];
34        $format = $input_data['format'];
35
36        if ($format !== 'anonymous') {
37            $this->checkPermission('any');
38        }
39        if ($format === 'kaderblog') {
40            $this->checkPermission('kaderblog');
41        }
42        if ($format === 'aktuell') {
43            $this->checkIsStaff();
44        }
45
46        $token = $input['custom']['captchaToken'] ?? null;
47        $is_valid_token = $token ? $this->captchaUtils()->validateToken($token) : false;
48        if ($format === 'anonymous' && !$is_valid_token) {
49            return ['custom' => ['status' => 'DENIED'], 'id' => null];
50        }
51
52        $news_entry = new NewsEntry();
53        $this->entityUtils()->createOlzEntity($news_entry, $input['meta']);
54        $this->updateEntityWithData($news_entry, $input['data']);
55
56        $this->entityManager()->persist($news_entry);
57        $this->entityManager()->flush();
58        $this->persistUploads($news_entry, $input['data']);
59
60        if ($format === 'anonymous') {
61            $anonymous_user = new User();
62            $anonymous_user->setEmail($input_data['authorEmail'] ?? null);
63            $anonymous_user->setFirstName($input_data['authorName'] ?? '-');
64            $anonymous_user->setLastName('');
65
66            $delete_news_token = urlencode($this->emailUtils()->encryptEmailReactionToken([
67                'action' => 'delete_news',
68                'news_id' => $news_entry->getId(),
69            ]));
70            $base_url = $this->envUtils()->getBaseHref();
71            $code_href = $this->envUtils()->getCodeHref();
72            $news_url = "{$base_url}{$code_href}news/{$news_entry->getId()}";
73            $delete_news_url = "{$base_url}{$code_href}email_reaktion?token={$delete_news_token}";
74            $text = <<<ZZZZZZZZZZ
75                Hallo {$anonymous_user->getFirstName()},
76
77                Du hast soeben auf [{$base_url}]({$base_url}) einen [anonymen Forumseintrag]({$news_url}) erstellt.
78
79                Falls du deinen Eintrag wieder *löschen* willst, klicke [hier]({$delete_news_url}) oder auf folgenden Link:
80
81                {$delete_news_url}
82
83                ZZZZZZZZZZ;
84            $config = [
85                'no_unsubscribe' => true,
86            ];
87
88            try {
89                $email = (new Email())->subject("[OLZ] Dein Forumseintrag");
90                $email = $this->emailUtils()->buildOlzEmail($email, $anonymous_user, $text, $config);
91                $this->emailUtils()->send($email);
92                $this->log()->info("Forumseintrag email sent to {$anonymous_user->getEmail()}.");
93            } catch (\Exception $exc) {
94                $message = $exc->getMessage();
95                $this->log()->critical("Error sending Forumseintrag email to {$anonymous_user->getEmail()}.: {$message}");
96            }
97        }
98
99        return [
100            'custom' => ['status' => 'OK'],
101            'id' => $news_entry->getId(),
102        ];
103    }
104}