Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 93 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
| LemmyApiService | |
0.00% |
0 / 93 |
|
0.00% |
0 / 6 |
462 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| login | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
12 | |||
| getCommunityId | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
12 | |||
| syncChannelPosts | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
30 | |||
| createPost | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
42 | |||
| getLanguages | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
12 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace App\Modules\Lemmy\Services; |
| 4 | |
| 5 | use App\Enums\PlatformEnum; |
| 6 | use App\Models\PlatformChannelPost; |
| 7 | use App\Modules\Lemmy\LemmyRequest; |
| 8 | use Exception; |
| 9 | |
| 10 | class 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 | } |