@artilingo/artiframe-cli 1.1.1 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/artiframe.js +1 -1
- package/package.json +1 -1
- package/src/Commands/AddCommand.php +2 -2
- package/src/Commands/MakeApiCommand.php +1 -1
- package/src/Commands/MakeClassCommand.php +1 -1
- package/src/Commands/MakeViewCommand.php +1 -1
- package/core-stubs/stubs/service/image.stub +0 -334
- package/core-stubs/stubs/service/iyzico.stub +0 -637
- package/core-stubs/stubs/service/jwt.stub +0 -312
- package/core-stubs/stubs/service/pusher.stub +0 -232
- package/core-stubs/stubs/service/redis.stub +0 -361
- package/core-stubs/stubs/service/s3.stub +0 -377
- package/core-stubs/stubs/service/sentry.stub +0 -139
- package/core-stubs/stubs/service/stripe.stub +0 -526
- package/core-stubs/stubs/service/twilio.stub +0 -361
|
@@ -1,377 +0,0 @@
|
|
|
1
|
-
<?php
|
|
2
|
-
|
|
3
|
-
namespace Service;
|
|
4
|
-
|
|
5
|
-
use Aws\S3\S3Client;
|
|
6
|
-
use Aws\S3\Exception\S3Exception;
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* S3Storage — Wrapper for AWS S3 SDK.
|
|
10
|
-
*
|
|
11
|
-
* Provides simple methods for uploading, downloading, deleting, listing,
|
|
12
|
-
* and managing files on Amazon S3, MinIO, DigitalOcean Spaces, or any
|
|
13
|
-
* S3-compatible object storage.
|
|
14
|
-
*
|
|
15
|
-
* Required ENV variables:
|
|
16
|
-
* AWS_ACCESS_KEY_ID — IAM access key
|
|
17
|
-
* AWS_SECRET_ACCESS_KEY — IAM secret key
|
|
18
|
-
* AWS_DEFAULT_REGION — e.g. "eu-central-1"
|
|
19
|
-
* AWS_BUCKET — Default bucket name
|
|
20
|
-
*
|
|
21
|
-
* Optional ENV variables:
|
|
22
|
-
* AWS_ENDPOINT — Custom endpoint URL (MinIO, Spaces, etc.)
|
|
23
|
-
*
|
|
24
|
-
* @package Service
|
|
25
|
-
*/
|
|
26
|
-
class S3Storage
|
|
27
|
-
{
|
|
28
|
-
/** @var S3Client AWS S3 client instance */
|
|
29
|
-
private S3Client $client;
|
|
30
|
-
|
|
31
|
-
/** @var string Default bucket name */
|
|
32
|
-
private string $bucket;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Create the S3 client from environment variables.
|
|
36
|
-
*
|
|
37
|
-
* When AWS_ENDPOINT is set the client connects to a custom
|
|
38
|
-
* S3-compatible service (MinIO, DigitalOcean Spaces, Cloudflare R2, etc.).
|
|
39
|
-
*/
|
|
40
|
-
public function __construct()
|
|
41
|
-
{
|
|
42
|
-
$region = $_ENV['AWS_DEFAULT_REGION'] ?? 'us-east-1';
|
|
43
|
-
$endpoint = $_ENV['AWS_ENDPOINT'] ?? null;
|
|
44
|
-
|
|
45
|
-
$config = [
|
|
46
|
-
'version' => 'latest',
|
|
47
|
-
'region' => $region,
|
|
48
|
-
'credentials' => [
|
|
49
|
-
'key' => $_ENV['AWS_ACCESS_KEY_ID'],
|
|
50
|
-
'secret' => $_ENV['AWS_SECRET_ACCESS_KEY'],
|
|
51
|
-
],
|
|
52
|
-
];
|
|
53
|
-
|
|
54
|
-
// Custom endpoint for S3-compatible services
|
|
55
|
-
if ($endpoint) {
|
|
56
|
-
$config['endpoint'] = $endpoint;
|
|
57
|
-
$config['use_path_style_endpoint'] = true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
$this->client = new S3Client($config);
|
|
61
|
-
$this->bucket = $_ENV['AWS_BUCKET'];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// ---------------------------------------------------------------
|
|
65
|
-
// Upload
|
|
66
|
-
// ---------------------------------------------------------------
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Upload a local file to S3.
|
|
70
|
-
*
|
|
71
|
-
* @param string $localPath Absolute path to the local file.
|
|
72
|
-
* @param string $remotePath Object key (path) in the bucket.
|
|
73
|
-
* @param string $acl Canned ACL: private, public-read, etc.
|
|
74
|
-
* @return array{status: bool, url: string|null, error: string|null}
|
|
75
|
-
*/
|
|
76
|
-
public function upload(string $localPath, string $remotePath, string $acl = 'private'): array
|
|
77
|
-
{
|
|
78
|
-
try {
|
|
79
|
-
$result = $this->client->putObject([
|
|
80
|
-
'Bucket' => $this->bucket,
|
|
81
|
-
'Key' => $remotePath,
|
|
82
|
-
'SourceFile' => $localPath,
|
|
83
|
-
'ACL' => $acl,
|
|
84
|
-
'ContentType' => mime_content_type($localPath) ?: 'application/octet-stream',
|
|
85
|
-
]);
|
|
86
|
-
|
|
87
|
-
return [
|
|
88
|
-
'status' => true,
|
|
89
|
-
'url' => $result['ObjectURL'] ?? $this->url($remotePath),
|
|
90
|
-
'error' => null,
|
|
91
|
-
];
|
|
92
|
-
} catch (S3Exception $e) {
|
|
93
|
-
error_log('[S3Storage::upload] ' . $e->getMessage());
|
|
94
|
-
return ['status' => false, 'url' => null, 'error' => $e->getMessage()];
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// ---------------------------------------------------------------
|
|
99
|
-
// Upload from String
|
|
100
|
-
// ---------------------------------------------------------------
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Upload content from a string directly to S3.
|
|
104
|
-
*
|
|
105
|
-
* Useful for storing generated data (JSON, CSV, HTML) without
|
|
106
|
-
* writing a temporary file to disk first.
|
|
107
|
-
*
|
|
108
|
-
* @param string $content The raw string content to store.
|
|
109
|
-
* @param string $remotePath Object key (path) in the bucket.
|
|
110
|
-
* @param string $contentType MIME type, e.g. "application/json".
|
|
111
|
-
* @param string $acl Canned ACL: private, public-read, etc.
|
|
112
|
-
* @return array{status: bool, url: string|null, error: string|null}
|
|
113
|
-
*/
|
|
114
|
-
public function uploadFromString(string $content, string $remotePath, string $contentType, string $acl = 'private'): array
|
|
115
|
-
{
|
|
116
|
-
try {
|
|
117
|
-
$result = $this->client->putObject([
|
|
118
|
-
'Bucket' => $this->bucket,
|
|
119
|
-
'Key' => $remotePath,
|
|
120
|
-
'Body' => $content,
|
|
121
|
-
'ACL' => $acl,
|
|
122
|
-
'ContentType' => $contentType,
|
|
123
|
-
]);
|
|
124
|
-
|
|
125
|
-
return [
|
|
126
|
-
'status' => true,
|
|
127
|
-
'url' => $result['ObjectURL'] ?? $this->url($remotePath),
|
|
128
|
-
'error' => null,
|
|
129
|
-
];
|
|
130
|
-
} catch (S3Exception $e) {
|
|
131
|
-
error_log('[S3Storage::uploadFromString] ' . $e->getMessage());
|
|
132
|
-
return ['status' => false, 'url' => null, 'error' => $e->getMessage()];
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// ---------------------------------------------------------------
|
|
137
|
-
// Download
|
|
138
|
-
// ---------------------------------------------------------------
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Download a file from S3 to a local path.
|
|
142
|
-
*
|
|
143
|
-
* @param string $remotePath Object key in the bucket.
|
|
144
|
-
* @param string $localPath Absolute local destination path.
|
|
145
|
-
* @return bool True on success.
|
|
146
|
-
*/
|
|
147
|
-
public function download(string $remotePath, string $localPath): bool
|
|
148
|
-
{
|
|
149
|
-
try {
|
|
150
|
-
$this->client->getObject([
|
|
151
|
-
'Bucket' => $this->bucket,
|
|
152
|
-
'Key' => $remotePath,
|
|
153
|
-
'SaveAs' => $localPath,
|
|
154
|
-
]);
|
|
155
|
-
|
|
156
|
-
return true;
|
|
157
|
-
} catch (S3Exception $e) {
|
|
158
|
-
error_log('[S3Storage::download] ' . $e->getMessage());
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// ---------------------------------------------------------------
|
|
164
|
-
// Delete
|
|
165
|
-
// ---------------------------------------------------------------
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Delete a single object from S3.
|
|
169
|
-
*
|
|
170
|
-
* @param string $remotePath Object key to delete.
|
|
171
|
-
* @return bool True on success.
|
|
172
|
-
*/
|
|
173
|
-
public function delete(string $remotePath): bool
|
|
174
|
-
{
|
|
175
|
-
try {
|
|
176
|
-
$this->client->deleteObject([
|
|
177
|
-
'Bucket' => $this->bucket,
|
|
178
|
-
'Key' => $remotePath,
|
|
179
|
-
]);
|
|
180
|
-
|
|
181
|
-
return true;
|
|
182
|
-
} catch (S3Exception $e) {
|
|
183
|
-
error_log('[S3Storage::delete] ' . $e->getMessage());
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Delete multiple objects from S3 in a single request.
|
|
190
|
-
*
|
|
191
|
-
* @param array<string> $remotePaths List of object keys to delete.
|
|
192
|
-
* @return bool True when all objects are deleted successfully.
|
|
193
|
-
*/
|
|
194
|
-
public function deleteMany(array $remotePaths): bool
|
|
195
|
-
{
|
|
196
|
-
try {
|
|
197
|
-
$objects = array_map(fn(string $key) => ['Key' => $key], $remotePaths);
|
|
198
|
-
|
|
199
|
-
$this->client->deleteObjects([
|
|
200
|
-
'Bucket' => $this->bucket,
|
|
201
|
-
'Delete' => [
|
|
202
|
-
'Objects' => $objects,
|
|
203
|
-
'Quiet' => true,
|
|
204
|
-
],
|
|
205
|
-
]);
|
|
206
|
-
|
|
207
|
-
return true;
|
|
208
|
-
} catch (S3Exception $e) {
|
|
209
|
-
error_log('[S3Storage::deleteMany] ' . $e->getMessage());
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// ---------------------------------------------------------------
|
|
215
|
-
// URL helpers
|
|
216
|
-
// ---------------------------------------------------------------
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Get the public URL for an object.
|
|
220
|
-
*
|
|
221
|
-
* @param string $remotePath Object key in the bucket.
|
|
222
|
-
* @return string The public URL.
|
|
223
|
-
*/
|
|
224
|
-
public function url(string $remotePath): string
|
|
225
|
-
{
|
|
226
|
-
return $this->client->getObjectUrl($this->bucket, $remotePath);
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Generate a pre-signed (temporary) URL for private objects.
|
|
231
|
-
*
|
|
232
|
-
* @param string $remotePath Object key in the bucket.
|
|
233
|
-
* @param int $minutes Link validity in minutes (default 60).
|
|
234
|
-
* @return string Pre-signed URL.
|
|
235
|
-
*/
|
|
236
|
-
public function signedUrl(string $remotePath, int $minutes = 60): string
|
|
237
|
-
{
|
|
238
|
-
$command = $this->client->getCommand('GetObject', [
|
|
239
|
-
'Bucket' => $this->bucket,
|
|
240
|
-
'Key' => $remotePath,
|
|
241
|
-
]);
|
|
242
|
-
|
|
243
|
-
$request = $this->client->createPresignedRequest($command, "+{$minutes} minutes");
|
|
244
|
-
|
|
245
|
-
return (string) $request->getUri();
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// ---------------------------------------------------------------
|
|
249
|
-
// Existence check
|
|
250
|
-
// ---------------------------------------------------------------
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Check whether an object exists in the bucket.
|
|
254
|
-
*
|
|
255
|
-
* @param string $remotePath Object key to check.
|
|
256
|
-
* @return bool True if the object exists.
|
|
257
|
-
*/
|
|
258
|
-
public function exists(string $remotePath): bool
|
|
259
|
-
{
|
|
260
|
-
try {
|
|
261
|
-
return $this->client->doesObjectExistV2($this->bucket, $remotePath);
|
|
262
|
-
} catch (S3Exception $e) {
|
|
263
|
-
error_log('[S3Storage::exists] ' . $e->getMessage());
|
|
264
|
-
return false;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// ---------------------------------------------------------------
|
|
269
|
-
// List objects
|
|
270
|
-
// ---------------------------------------------------------------
|
|
271
|
-
|
|
272
|
-
/**
|
|
273
|
-
* List objects under a given prefix (folder).
|
|
274
|
-
*
|
|
275
|
-
* Returns an array of associative arrays with key, size, and
|
|
276
|
-
* last_modified for each object.
|
|
277
|
-
*
|
|
278
|
-
* @param string $prefix Key prefix to filter by (e.g. "uploads/").
|
|
279
|
-
* @return array<int, array{key: string, size: int, last_modified: string}>
|
|
280
|
-
*/
|
|
281
|
-
public function list(string $prefix = ''): array
|
|
282
|
-
{
|
|
283
|
-
try {
|
|
284
|
-
$results = [];
|
|
285
|
-
$params = [
|
|
286
|
-
'Bucket' => $this->bucket,
|
|
287
|
-
'Prefix' => $prefix,
|
|
288
|
-
];
|
|
289
|
-
|
|
290
|
-
$paginator = $this->client->getPaginator('ListObjectsV2', $params);
|
|
291
|
-
|
|
292
|
-
foreach ($paginator as $page) {
|
|
293
|
-
$contents = $page['Contents'] ?? [];
|
|
294
|
-
foreach ($contents as $object) {
|
|
295
|
-
$results[] = [
|
|
296
|
-
'key' => $object['Key'],
|
|
297
|
-
'size' => $object['Size'],
|
|
298
|
-
'last_modified' => $object['LastModified']->format('Y-m-d H:i:s'),
|
|
299
|
-
];
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
return $results;
|
|
304
|
-
} catch (S3Exception $e) {
|
|
305
|
-
error_log('[S3Storage::list] ' . $e->getMessage());
|
|
306
|
-
return [];
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// ---------------------------------------------------------------
|
|
311
|
-
// Copy & Move
|
|
312
|
-
// ---------------------------------------------------------------
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Copy an object to a new key within the same bucket.
|
|
316
|
-
*
|
|
317
|
-
* @param string $from Source object key.
|
|
318
|
-
* @param string $to Destination object key.
|
|
319
|
-
* @return bool True on success.
|
|
320
|
-
*/
|
|
321
|
-
public function copy(string $from, string $to): bool
|
|
322
|
-
{
|
|
323
|
-
try {
|
|
324
|
-
$this->client->copyObject([
|
|
325
|
-
'Bucket' => $this->bucket,
|
|
326
|
-
'CopySource' => "{$this->bucket}/{$from}",
|
|
327
|
-
'Key' => $to,
|
|
328
|
-
]);
|
|
329
|
-
|
|
330
|
-
return true;
|
|
331
|
-
} catch (S3Exception $e) {
|
|
332
|
-
error_log('[S3Storage::copy] ' . $e->getMessage());
|
|
333
|
-
return false;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* Move an object to a new key (copy + delete).
|
|
339
|
-
*
|
|
340
|
-
* @param string $from Source object key.
|
|
341
|
-
* @param string $to Destination object key.
|
|
342
|
-
* @return bool True when copy and delete both succeed.
|
|
343
|
-
*/
|
|
344
|
-
public function move(string $from, string $to): bool
|
|
345
|
-
{
|
|
346
|
-
if ($this->copy($from, $to)) {
|
|
347
|
-
return $this->delete($from);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
return false;
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// ---------------------------------------------------------------
|
|
354
|
-
// File size
|
|
355
|
-
// ---------------------------------------------------------------
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Get the size of an object in bytes.
|
|
359
|
-
*
|
|
360
|
-
* @param string $remotePath Object key in the bucket.
|
|
361
|
-
* @return int File size in bytes, or -1 on failure.
|
|
362
|
-
*/
|
|
363
|
-
public function size(string $remotePath): int
|
|
364
|
-
{
|
|
365
|
-
try {
|
|
366
|
-
$result = $this->client->headObject([
|
|
367
|
-
'Bucket' => $this->bucket,
|
|
368
|
-
'Key' => $remotePath,
|
|
369
|
-
]);
|
|
370
|
-
|
|
371
|
-
return (int) ($result['ContentLength'] ?? 0);
|
|
372
|
-
} catch (S3Exception $e) {
|
|
373
|
-
error_log('[S3Storage::size] ' . $e->getMessage());
|
|
374
|
-
return -1;
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
<?php
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Sentry Error Tracking Configuration
|
|
5
|
-
*
|
|
6
|
-
* Initializes the Sentry SDK for error reporting and provides
|
|
7
|
-
* helper functions for capturing exceptions and messages.
|
|
8
|
-
*
|
|
9
|
-
* Required ENV variables:
|
|
10
|
-
* SENTRY_DSN — Sentry Data Source Name (project DSN from sentry.io)
|
|
11
|
-
*
|
|
12
|
-
* Optional ENV variables:
|
|
13
|
-
* APP_ENV — "0" for production, "1" for development (default: 0)
|
|
14
|
-
* APP_VERSION — Application version string, used as Sentry release tag
|
|
15
|
-
*
|
|
16
|
-
* Usage:
|
|
17
|
-
* require_once __DIR__ . '/sentry.php';
|
|
18
|
-
*
|
|
19
|
-
* // Capture an exception
|
|
20
|
-
* try { ... } catch (\Throwable $e) {
|
|
21
|
-
* $eventId = captureError($e);
|
|
22
|
-
* }
|
|
23
|
-
*
|
|
24
|
-
* // Capture an informational message
|
|
25
|
-
* captureMessage('Deployment completed', 'info');
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
// ---------------------------------------------------------------
|
|
29
|
-
// Guard — only initialize when a DSN is available
|
|
30
|
-
// ---------------------------------------------------------------
|
|
31
|
-
if (empty($_ENV['SENTRY_DSN'])) {
|
|
32
|
-
/**
|
|
33
|
-
* No-op fallback when Sentry is not configured.
|
|
34
|
-
*
|
|
35
|
-
* @param \Throwable $e The exception (ignored).
|
|
36
|
-
* @return string|null Always returns null.
|
|
37
|
-
*/
|
|
38
|
-
function captureError(\Throwable $e): ?string
|
|
39
|
-
{
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* No-op fallback when Sentry is not configured.
|
|
45
|
-
*
|
|
46
|
-
* @param string $message The message (ignored).
|
|
47
|
-
* @param string $level Severity level (ignored).
|
|
48
|
-
* @return string|null Always returns null.
|
|
49
|
-
*/
|
|
50
|
-
function captureMessage(string $message, string $level = 'info'): ?string
|
|
51
|
-
{
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// ---------------------------------------------------------------
|
|
59
|
-
// Determine environment & sample rate
|
|
60
|
-
// ---------------------------------------------------------------
|
|
61
|
-
|
|
62
|
-
/** @var bool Whether the application is running in production mode */
|
|
63
|
-
$isProduction = ($_ENV['APP_ENV'] ?? '0') === '0';
|
|
64
|
-
|
|
65
|
-
/** @var string Human-readable environment name for Sentry */
|
|
66
|
-
$environment = $isProduction ? 'production' : 'development';
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Sample rate:
|
|
70
|
-
* 1.0 — capture 100 % of events in production
|
|
71
|
-
* 0.0 — capture nothing in development (use captureError/captureMessage explicitly)
|
|
72
|
-
*/
|
|
73
|
-
$sampleRate = $isProduction ? 1.0 : 0.0;
|
|
74
|
-
|
|
75
|
-
// ---------------------------------------------------------------
|
|
76
|
-
// Sentry initialization
|
|
77
|
-
// ---------------------------------------------------------------
|
|
78
|
-
|
|
79
|
-
$options = [
|
|
80
|
-
'dsn' => $_ENV['SENTRY_DSN'],
|
|
81
|
-
'environment' => $environment,
|
|
82
|
-
'sample_rate' => $sampleRate,
|
|
83
|
-
];
|
|
84
|
-
|
|
85
|
-
// Attach release version when available
|
|
86
|
-
if (!empty($_ENV['APP_VERSION'])) {
|
|
87
|
-
$options['release'] = $_ENV['APP_VERSION'];
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
\Sentry\init($options);
|
|
91
|
-
|
|
92
|
-
// ---------------------------------------------------------------
|
|
93
|
-
// Helper functions
|
|
94
|
-
// ---------------------------------------------------------------
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Capture a Throwable and send it to Sentry.
|
|
98
|
-
*
|
|
99
|
-
* @param \Throwable $e The exception or error to report.
|
|
100
|
-
* @return string|null The Sentry event ID, or null on failure.
|
|
101
|
-
*/
|
|
102
|
-
function captureError(\Throwable $e): ?string
|
|
103
|
-
{
|
|
104
|
-
try {
|
|
105
|
-
$eventId = \Sentry\captureException($e);
|
|
106
|
-
return $eventId ? (string) $eventId : null;
|
|
107
|
-
} catch (\Throwable $inner) {
|
|
108
|
-
error_log('[Sentry::captureError] Failed to report: ' . $inner->getMessage());
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Capture a plain-text message and send it to Sentry.
|
|
115
|
-
*
|
|
116
|
-
* Supported severity levels: fatal, error, warning, info, debug.
|
|
117
|
-
*
|
|
118
|
-
* @param string $message Human-readable message to log.
|
|
119
|
-
* @param string $level Sentry severity level (default: info).
|
|
120
|
-
* @return string|null The Sentry event ID, or null on failure.
|
|
121
|
-
*/
|
|
122
|
-
function captureMessage(string $message, string $level = 'info'): ?string
|
|
123
|
-
{
|
|
124
|
-
try {
|
|
125
|
-
$severity = match ($level) {
|
|
126
|
-
'fatal' => \Sentry\Severity::fatal(),
|
|
127
|
-
'error' => \Sentry\Severity::error(),
|
|
128
|
-
'warning' => \Sentry\Severity::warning(),
|
|
129
|
-
'debug' => \Sentry\Severity::debug(),
|
|
130
|
-
default => \Sentry\Severity::info(),
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
$eventId = \Sentry\captureMessage($message, $severity);
|
|
134
|
-
return $eventId ? (string) $eventId : null;
|
|
135
|
-
} catch (\Throwable $inner) {
|
|
136
|
-
error_log('[Sentry::captureMessage] Failed to report: ' . $inner->getMessage());
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
}
|