ReviewOS

also looking at this

meemalabs/meema-client-php

WIP: Upload Endpoint

#38
Merged glennmichael123 wants to merge upload-endpoint into main
6 files +172 -94
src/Models/Favorite.phpmodified+12-12
Changes to src/Models/Favorite.php
@@ -41,17 +41,17 @@ class Favorite
4141 /**
4242 * Get specific favorites.
4343 *
44 * @param int $id
44 * @param array $ids
4545 *
4646 * @return array
4747 */
48 public function get($id = null)
48 public function get($ids = null)
4949 {
50 if (! $id) {
50 if (! $ids) {
5151 return $this->all();
5252 }
5353
54 $ids = is_array($id) ? $id : func_get_args();
54 $ids = is_array($ids) ? $ids : func_get_args();
5555
5656 foreach ($ids as $id) {
5757 if (! is_int($id)) {
@@ -81,9 +81,9 @@ class Favorite
8181 }
8282
8383 /**
84 * Create folder.
84 * Create favorite.
8585 *
86 * @param string $name
86 * @param array $data
8787 *
8888 * @return array
8989 */
@@ -93,10 +93,10 @@ class Favorite
9393 }
9494
9595 /**
96 * Update folder.
96 * Update favorite.
9797 *
98 * @param string $name
9998 * @param int $id
99 * @param string $data
100100 *
101101 * @return array
102102 */
@@ -110,15 +110,15 @@ class Favorite
110110 }
111111
112112 /**
113 * Delete a folder.
113 * Delete a favorite.
114114 *
115 * @param int $id
115 * @param array $ids
116116 *
117117 * @return null
118118 */
119 public function delete($id)
119 public function delete($ids)
120120 {
121 $ids = is_array($id) ? $id : func_get_args();
121 $ids = is_array($ids) ? $ids : func_get_args();
122122
123123 foreach ($ids as $id) {
124124 if (! is_int($id)) {
src/Models/Folder.phpmodified+30-25
Changes to src/Models/Folder.php
@@ -69,6 +69,18 @@ class Folder
6969 return $this->client->request('GET', 'folders', ['folder_ids' => $ids]);
7070 }
7171
72 /**
73 * Search for specific folders.
74 *
75 * @param string $query
76 *
77 * @return array
78 */
79 public function search($query)
80 {
81 return $this->client->request('POST', 'folders/search', compact('query'));
82 }
83
7284 /**
7385 * Get specific folders.
7486 *
@@ -131,15 +143,15 @@ class Folder
131143 /**
132144 * Delete a folder.
133145 *
134 * @param int $id
146 * @param array $ids
135147 *
136148 * @return null
137149 *
138150 * @throws InvalidFormatException
139151 */
140 public function delete($id)
152 public function delete($ids)
141153 {
142 $ids = is_array($id) ? $id : func_get_args();
154 $ids = is_array($ids) ? $ids : func_get_args();
143155
144156 foreach ($ids as $id) {
145157 if (! is_int($id)) {
@@ -161,30 +173,18 @@ class Folder
161173 return $this->client->request('DELETE', "folders/{$id}");
162174 }
163175
164 /**
165 * Get specific folders.
166 *
167 * @param string $query
168 *
169 * @return array
170 */
171 public function search($query)
172 {
173 return $this->client->request('POST', 'folders/search', compact('query'));
174 }
175
176176 /**
177177 * Archive a folder.
178178 *
179 * @param int $id
179 * @param array $ids
180180 *
181181 * @return array
182182 *
183183 * @throws InvalidFormatException
184184 */
185 public function archive($id)
185 public function archive($ids)
186186 {
187 $ids = is_array($id) ? $id : func_get_args();
187 $ids = is_array($ids) ? $ids : func_get_args();
188188
189189 foreach ($ids as $id) {
190190 if (! is_int($id)) {
@@ -205,15 +205,15 @@ class Folder
205205 /**
206206 * Unarchive a folder.
207207 *
208 * @param int $id
208 * @param array $ids
209209 *
210210 * @return array
211211 *
212212 * @throws InvalidFormatException
213213 */
214 public function unarchive($id)
214 public function unarchive($ids)
215215 {
216 $ids = is_array($id) ? $id : func_get_args();
216 $ids = is_array($ids) ? $ids : func_get_args();
217217
218218 foreach ($ids as $id) {
219219 if (! is_int($id)) {
@@ -234,15 +234,15 @@ class Folder
234234 /**
235235 * Duplicate a folder.
236236 *
237 * @param int $id
237 * @param array $ids
238238 *
239239 * @return array
240240 *
241241 * @throws InvalidFormatException
242242 */
243 public function duplicate($id): array
243 public function duplicate($ids): array
244244 {
245 $ids = is_array($id) ? $id : func_get_args();
245 $ids = is_array($ids) ? $ids : func_get_args();
246246
247247 foreach ($ids as $id) {
248248 if (! is_int($id)) {
@@ -264,6 +264,7 @@ class Folder
264264 * Add folder to media.
265265 *
266266 * @param int $id
267 * @param string $name
267268 *
268269 * @return array
269270 *
@@ -314,7 +315,7 @@ class Folder
314315 /**
315316 * Initialize media model.
316317 *
317 * @param Meema\MeemaApi\Models\Folder $folder
318 * @param Meema\MeemaApi\Models\Tag $tag
318319 *
319320 * @return self
320321 */
@@ -338,6 +339,8 @@ class Folder
338339 /**
339340 * Initialize the media model.
340341 *
342 * @param int $id
343 *
341344 * @return Meema\MeemaApi\Models\Media
342345 */
343346 public function media($id = null): Media
@@ -350,6 +353,8 @@ class Folder
350353 /**
351354 * Initialize the tags model.
352355 *
356 * @param int $id
357 *
353358 * @return Meema\MeemaApi\Models\Tag
354359 */
355360 public function tags($id = null): Tag
src/Models/Media.phpmodified+95-27
Changes to src/Models/Media.php
@@ -2,6 +2,9 @@
22
33namespace Meema\MeemaApi\Models;
44
5use GuzzleHttp\Client as GuzzleClient;
6use GuzzleHttp\Psr7;
7use GuzzleHttp\Psr7\Request;
58use Meema\MeemaApi\Client;
69use Meema\MeemaApi\Exceptions\InvalidFormatException;
710use Meema\MeemaApi\Response\Response;
@@ -46,21 +49,23 @@ class Media
4649 /**
4750 * Get specific media.
4851 *
52 * @param array $ids
53 *
4954 * @return array
5055 *
5156 * @throws InvalidFormatException
5257 */
53 public function get($id = null)
58 public function get($ids = null)
5459 {
5560 if ($this->model) {
5661 return $this->fetchForModel();
5762 }
5863
59 if (! $id) {
64 if (! $ids) {
6065 return $this->all();
6166 }
6267
63 $ids = is_array($id) ? $id : func_get_args();
68 $ids = is_array($ids) ? $ids : func_get_args();
6469
6570 foreach ($ids as $id) {
6671 if (! is_int($id)) {
@@ -71,6 +76,18 @@ class Media
7176 return $this->client->request('GET', 'media', ['media_ids' => $ids]);
7277 }
7378
79 /**
80 * Search for specific media.
81 *
82 * @param string $query
83 *
84 * @return array
85 */
86 public function search($query)
87 {
88 return $this->client->request('POST', 'media/search', compact('query'));
89 }
90
7491 /**
7592 * Get specific media.
7693 *
@@ -129,15 +146,15 @@ class Media
129146 /**
130147 * Delete a media.
131148 *
132 * @param int $id
149 * @param array $ids
133150 *
134151 * @return null
135152 *
136153 * @throws InvalidFormatException
137154 */
138 public function delete($id)
155 public function delete($ids)
139156 {
140 $ids = is_array($id) ? $id : func_get_args();
157 $ids = is_array($ids) ? $ids : func_get_args();
141158
142159 foreach ($ids as $id) {
143160 if (! is_int($id)) {
@@ -156,29 +173,80 @@ class Media
156173 }
157174
158175 /**
159 * Get specific folders.
176 * Upload a media file.
160177 *
161 * @param string $query
178 * @param string $path
162179 *
163180 * @return array
164181 */
165 public function search($query)
182 public function upload($path)
166183 {
167 return $this->client->request('POST', 'media/search', compact('query'));
184 $file = fopen($path, 'r');
185 $stream = Psr7\stream_for($file);
186
187 $fileName = basename($path);
188 $mimeType = mime_content_type($file);
189
190 $vaporParams = ['content_type' => $mimeType];
191
192 $signedUrl = $this->client->request('POST', 'vapor/signed-storage-url', $vaporParams);
193
194 if (is_array($signedUrl) && $signedUrl['url']) {
195 $headers = $signedUrl['headers'];
196 unset($headers['Host']);
197
198 $this->uploadToS3($signedUrl['url'], $headers, $fileName, $stream);
199
200 $uploadData = ['key' => $signedUrl['key'], 'file_name' => $fileName];
201
202 $response = $this->client->request('POST', 'upload', $uploadData);
203 }
204
205 return $response;
206 }
207
208 /**
209 * Upload the file stream to s3.
210 *
211 * @param string $signedUrl
212 * @param array $headers
213 * @param string $fileName
214 * @param GuzzleHttp\Psr7 $stream
215 *
216 * @return void
217 */
218 protected function uploadToS3($signedUrl, $headers, $fileName, $stream)
219 {
220 $client = new GuzzleClient();
221 $request = new Request(
src/Models/Media.php:221
  1. chrisSun Oct 25 2026 00:09:39 GMT+0000 (Coordinated Universal Time)

    let's only pass the $signedUrl and not the array, please

222 'PUT',
223 $signedUrl,
224 ['headers' => json_encode($headers)],
225 new Psr7\MultipartStream(
226 [
227 [
228 'name' => $fileName,
229 'contents' => $stream,
230 ],
231 ]
232 )
233 );
234
235 $client->send($request);
168236 }
169237
170238 /**
171239 * Archive a media.
src/Models/Media.php:239
  1. chrisSun Oct 25 2026 00:09:39 GMT+0000 (Coordinated Universal Time)

    We should rename this var to $ids but at the same time we should also accept an int-value for just logical reasons and to cover this edge-case in case the user just enters an id.

172240 *
173 * @param int $id
241 * @param array $ids
174242 *
175243 * @return array
176244 *
177245 * @throws InvalidFormatException
178246 */
179 public function archive($id)
247 public function archive($ids)
180248 {
181 $ids = is_array($id) ? $id : func_get_args();
249 $ids = is_array($ids) ? $ids : func_get_args();
182250
183251 foreach ($ids as $id) {
184252 if (! is_int($id)) {
@@ -199,15 +267,15 @@ class Media
199267 /**
200268 * Unarchive a media.
201269 *
202 * @param int $id
270 * @param array $ids
203271 *
204272 * @return array
205273 *
206274 * @throws InvalidFormatException
207275 */
208 public function unarchive($id)
276 public function unarchive($ids)
209277 {
210 $ids = is_array($id) ? $id : func_get_args();
278 $ids = is_array($ids) ? $ids : func_get_args();
211279
212280 foreach ($ids as $id) {
213281 if (! is_int($id)) {
@@ -228,15 +296,15 @@ class Media
228296 /**
229297 * Make a media private.
230298 *
231 * @param int $id
299 * @param array $ids
232300 *
233301 * @return array
234302 *
235303 * @throws InvalidFormatException
236304 */
237 public function makePrivate($id)
305 public function makePrivate($ids)
238306 {
239 $ids = is_array($id) ? $id : func_get_args();
307 $ids = is_array($ids) ? $ids : func_get_args();
240308
241309 foreach ($ids as $id) {
242310 if (! is_int($id)) {
@@ -257,15 +325,15 @@ class Media
257325 /**
258326 * Make a media public.
259327 *
260 * @param int $id
328 * @param array $ids
261329 *
262330 * @return array
263331 *
264332 * @throws InvalidFormatException
265333 */
266 public function makePublic($id)
334 public function makePublic($ids)
267335 {
268 $ids = is_array($id) ? $id : func_get_args();
336 $ids = is_array($ids) ? $ids : func_get_args();
269337
270338 foreach ($ids as $id) {
271339 if (! is_int($id)) {
@@ -286,15 +354,15 @@ class Media
286354 /**
287355 * Duplicate a media.
288356 *
289 * @param int $id
357 * @param array $ids
290358 *
291359 * @return array
292360 *
293361 * @throws InvalidFormatException
294362 */
295 public function duplicate($id)
363 public function duplicate($ids)
296364 {
297 $ids = is_array($id) ? $id : func_get_args();
365 $ids = is_array($ids) ? $ids : func_get_args();
298366
299367 foreach ($ids as $id) {
300368 if (! is_int($id)) {
@@ -339,7 +407,7 @@ class Media
339407 /**
340408 * Fetch the media for the folder.
341409 *
342 * @param int $id
410 * @param Meema\MeemaApi\Models\Folder $folder
343411 *
344412 * @return self
345413 */
@@ -353,7 +421,7 @@ class Media
353421 /**
354422 * Initialize media model.
355423 *
356 * @param Meema\MeemaApi\Models\Folder $folder
424 * @param Meema\MeemaApi\Models\Tag $tag
357425 *
358426 * @return self
359427 */
src/Models/Tag.phpmodified+14-11
Changes to src/Models/Tag.php
@@ -46,21 +46,21 @@ class Tag
4646 /**
4747 * Get specific tags.
4848 *
49 * @param int $id
49 * @param array $ids
5050 *
5151 * @return array
5252 */
53 public function get($id = null): array
53 public function get($ids = null): array
5454 {
5555 if ($this->model) {
5656 return $this->fetchForModel();
5757 }
5858
59 if (! $id) {
59 if (! $ids) {
6060 return $this->all();
6161 }
6262
63 $ids = is_array($id) ? $id : func_get_args();
63 $ids = is_array($ids) ? $ids : func_get_args();
6464
6565 foreach ($ids as $id) {
6666 if (! is_int($id)) {
@@ -90,10 +90,10 @@ class Tag
9090 }
9191
9292 /**
93 * Update folder.
93 * Update a tag color.
9494 *
95 * @param string $name
9695 * @param int $id
96 * @param string $color
9797 *
9898 * @return array
9999 */
@@ -106,22 +106,21 @@ class Tag
106106 $data = [
107107 'color' => $color,
108108 'tag_id' => $id,
109 'team_id' => 1,
110109 ];
111110
112111 return $this->client->request('PATCH', 'tags/color', $data);
113112 }
114113
115114 /**
116 * Delete a folder.
115 * Delete tags.
117116 *
118 * @param int $id
117 * @param array $ids
119118 *
120119 * @return Response
121120 */
122 public function delete($id)
121 public function delete($ids)
123122 {
124 $ids = is_array($id) ? $id : func_get_args();
123 $ids = is_array($ids) ? $ids : func_get_args();
125124
126125 foreach ($ids as $id) {
127126 if (! is_int($id)) {
@@ -142,6 +141,8 @@ class Tag
142141 /**
143142 * Initialize the media model.
144143 *
144 * @param int $id
145 *
145146 * @return Meema\MeemaApi\Models\Media
146147 */
147148 public function media($id = null): Media
@@ -154,6 +155,8 @@ class Tag
154155 /**
155156 * Initialize the folder model.
156157 *
158 * @param int $id
159 *
157160 * @return Meema\MeemaApi\Models\Folder
158161 */
159162 public function folders($id = null): Folder
tests/MeemaFolderTest.phpmodified+11-9
Changes to tests/MeemaFolderTest.php
@@ -14,6 +14,17 @@ it('can fetch all folders', function () {
1414 $this->assertTrue(count($folders) > 0);
1515});
1616
17it('can search a folder', function () {
18 $folder = $this->client->folders()->find(1)->toArray();
19
20 $query = $folder['data']['name'];
21
22 $folders = $this->client->folders()->search($query);
23
24 $this->assertTrue(is_array($folders));
25 $this->assertTrue(str_contains($folders['data'][0]['name'], $query));
26});
27
1728it('can fetch specific group of folders', function () {
1829 $ids = [1, 2, 3];
1930
@@ -50,15 +61,6 @@ it('can update a folder', function () {
5061 $this->assertTrue($folders['data']['name'] === $name);
5162});
5263
53it('can search a folder', function () {
54 $query = 'Invoice';
55
56 $folders = $this->client->folders()->search($query);
57
58 $this->assertTrue(is_array($folders));
59 $this->assertTrue(str_contains($folders['data'][0]['name'], $query));
60});
61
6264it('can archive a folder', function () {
6365 $folders = $this->client->folders()->archive(1);
6466
tests/MeemaMediaTest.phpmodified+10-10
Changes to tests/MeemaMediaTest.php
@@ -14,6 +14,16 @@ it('can be fetch all media', function () {
1414 $this->assertTrue(count($media) > 0);
1515});
1616
17it('can search a media', function () {
18 $media = $this->client->media()->find(1)->toArray();
19 $query = $media['data']['name'];
20
21 $media = $this->client->media()->search($query);
22
23 $this->assertTrue(is_array($media));
24 $this->assertTrue(str_contains($media['data'][0]['name'], $query));
25});
26
1727it('can be fetch all media for a tag', function () {
1828 // 8 is the tag id for images
1929 $tag = $this->client->tags()->find(8);
@@ -61,16 +71,6 @@ it('can update a media', function () {
6171 $this->assertTrue($media['data']['name'] === $name);
6272});
6373
64it('can search a media', function () {
65 $mediaName = $this->client->media()->find(1)->toArray();
66 $query = $mediaName['name'];
67
68 $media = $this->client->media()->search($query);
69
70 $this->assertTrue(is_array($media));
71 $this->assertTrue(str_contains($media['data'][0]['name'], $query));
72});
73
7474it('can archive a media', function () {
7575 $media = $this->client->media()->archive(1);
7676