Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
LemmyApiService
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 6
462
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 login
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
 getCommunityId
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
12
 syncChannelPosts
0.00% covered (danger)
0.00%
0 / 34
0.00% covered (danger)
0.00%
0 / 1
30
 createPost
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
42
 getLanguages
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace App\Modules\Lemmy\Services;
4
5use App\Enums\PlatformEnum;
6use App\Models\PlatformChannelPost;
7use App\Modules\Lemmy\LemmyRequest;
8use Exception;
9
10class LemmyApiService
11{
12    private string $instance;
13
14    public function __construct(string $instance)
15    {
16        $this->instance = $instance;
17    }
18
19    public function login(string $username, string $password): ?string
20    {
21        try {
22            $request = new LemmyRequest($this->instance);
23            $response = $request->post('user/login', [
24                'username_or_email' => $username,
25                'password' => $password,
26            ]);
27
28            if (!$response->successful()) {
29                logger()->error('Lemmy login failed', [
30                    'status' => $response->status(),
31                    'body' => $response->body()
32                ]);
33                return null;
34            }
35
36            $data = $response->json();
37            return $data['jwt'] ?? null;
38        } catch (Exception $e) {
39            logger()->error('Lemmy login exception', ['error' => $e->getMessage()]);
40            return null;
41        }
42    }
43
44    public function getCommunityId(string $communityName, string $token): int
45    {
46        try {
47            $request = new LemmyRequest($this->instance, $token);
48            $response = $request->get('community', ['name' => $communityName]);
49
50            if (!$response->successful()) {
51                throw new Exception('Failed to fetch community: ' . $response->status());
52            }
53
54            $data = $response->json();
55            return $data['community_view']['community']['id'] ?? throw new Exception('Community not found');
56        } catch (Exception $e) {
57            logger()->error('Community lookup failed', ['error' => $e->getMessage()]);
58            throw $e;
59        }
60    }
61
62    public function syncChannelPosts(string $token, int $platformChannelId, string $communityName): void
63    {
64        try {
65            $request = new LemmyRequest($this->instance, $token);
66            $response = $request->get('post/list', [
67                'community_id' => $platformChannelId,
68                'limit' => 50,
69                'sort' => 'New'
70            ]);
71
72            if (!$response->successful()) {
73                logger()->warning('Failed to sync channel posts', [
74                    'status' => $response->status(),
75                    'platform_channel_id' => $platformChannelId
76                ]);
77                return;
78            }
79
80            $data = $response->json();
81            $posts = $data['posts'] ?? [];
82
83            foreach ($posts as $postData) {
84                $post = $postData['post'];
85
86                PlatformChannelPost::storePost(
87                    PlatformEnum::LEMMY,
88                    (string) $platformChannelId,
89                    $communityName,
90                    (string) $post['id'],
91                    $post['url'] ?? null,
92                    $post['name'] ?? null,
93                    isset($post['published']) ? new \DateTime($post['published']) : null
94                );
95            }
96
97            logger()->info('Synced channel posts', [
98                'platform_channel_id' => $platformChannelId,
99                'posts_count' => count($posts)
100            ]);
101
102        } catch (Exception $e) {
103            logger()->error('Exception while syncing channel posts', [
104                'error' => $e->getMessage(),
105                'platform_channel_id' => $platformChannelId
106            ]);
107        }
108    }
109
110    /**
111     * @return array<string, mixed>
112     */
113    public function createPost(string $token, string $title, string $body, int $platformChannelId, ?string $url = null, ?string $thumbnail = null, ?int $languageId = null): array
114    {
115        try {
116            $request = new LemmyRequest($this->instance, $token);
117
118            $postData = [
119                'name' => $title,
120                'body' => $body,
121                'community_id' => $platformChannelId,
122            ];
123
124            if ($url) {
125                $postData['url'] = $url;
126            }
127
128            if ($thumbnail) {
129                $postData['custom_thumbnail'] = $thumbnail;
130            }
131
132            if ($languageId) {
133                $postData['language_id'] = $languageId;
134            }
135
136            $response = $request->post('post', $postData);
137
138            if (!$response->successful()) {
139                throw new Exception('Failed to create post: ' . $response->status() . ' - ' . $response->body());
140            }
141
142            return $response->json();
143        } catch (Exception $e) {
144            logger()->error('Post creation failed', ['error' => $e->getMessage()]);
145            throw $e;
146        }
147    }
148
149    /**
150     * @return array<int, mixed>
151     */
152    public function getLanguages(): array
153    {
154        try {
155            $request = new LemmyRequest($this->instance);
156            $response = $request->get('site');
157
158            if (!$response->successful()) {
159                logger()->warning('Failed to fetch site languages', [
160                    'status' => $response->status()
161                ]);
162                return [];
163            }
164
165            $data = $response->json();
166            return $data['all_languages'] ?? [];
167        } catch (Exception $e) {
168            logger()->error('Exception while fetching languages', [
169                'error' => $e->getMessage()
170            ]);
171            return [];
172        }
173    }
174}