@@ -22,7 +22,7 @@ class InlineFile implements FileInterface, WithJsonSchemaInterface
22
22
use HasMimeType;
23
23
24
24
/**
25
- * @var string The base64-encoded file data.
25
+ * @var string The plain base64-encoded file data (without data URI prefix) .
26
26
*/
27
27
private string $ base64Data ;
28
28
@@ -32,43 +32,63 @@ class InlineFile implements FileInterface, WithJsonSchemaInterface
32
32
* @since n.e.x.t
33
33
*
34
34
* @param string $base64Data The base64-encoded file data.
35
- * @param MimeType|string $mimeType The MIME type of the file.
35
+ * @param MimeType|string|null $mimeType The MIME type of the file.
36
36
*/
37
- public function __construct (string $ base64Data , $ mimeType )
37
+ public function __construct (string $ base64Data , $ mimeType = null )
38
38
{
39
39
// RFC 2397: dataurl := "data:" [ mediatype ] ";base64," data
40
- // mediatype is optional; if omitted, defaults to text/plain;charset=US-ASCII
41
- // We'll be more permissive and accept data URLs with or without MIME type
42
- $ pattern = '/^data:(?:([a-zA-Z0-9][a-zA-Z0-9!#$&\-\^_+.]*\/[a-zA-Z0-9][a-zA-Z0-9!#$&\-\^_+.]* '
40
+ $ dataUriPattern = '/^data:(?:([a-zA-Z0-9][a-zA-Z0-9!#$&\-\^_+.]*\/[a-zA-Z0-9][a-zA-Z0-9!#$&\-\^_+.]* '
43
41
. '(?:;[a-zA-Z0-9\-]+=[a-zA-Z0-9\-]+)*)?;)?base64,([A-Za-z0-9+\/]*={0,2})$/ ' ;
44
42
45
- if (!preg_match ($ pattern , $ base64Data , $ matches )) {
46
- throw new \InvalidArgumentException (
47
- 'Invalid base64 data provided. Expected format: data:[mimeType];base64,[data] '
48
- );
43
+ // Check if this is a data URI
44
+ if (preg_match ($ dataUriPattern , $ base64Data , $ matches )) {
45
+ $ this ->base64Data = $ matches [2 ];
46
+ $ this ->mimeType = $ this ->parseMimeType ($ mimeType , empty ($ matches [1 ]) ? null : $ matches [1 ]);
47
+ return ;
49
48
}
50
49
51
- $ this ->base64Data = $ base64Data ;
52
-
53
- if ($ mimeType instanceof MimeType) {
54
- $ this ->mimeType = $ mimeType ;
55
- } else {
56
- $ this ->mimeType = new MimeType ($ mimeType );
50
+ // Check if this is plain base64 data
51
+ if (preg_match ('/^[A-Za-z0-9+\/]*={0,2}$/ ' , $ base64Data )) {
52
+ if ($ mimeType === null ) {
53
+ throw new \InvalidArgumentException (
54
+ 'MIME type is required when providing plain base64 data without data URI format. '
55
+ );
56
+ }
57
+ $ this ->base64Data = $ base64Data ;
58
+ $ this ->mimeType = $ this ->parseMimeType ($ mimeType );
59
+ return ;
57
60
}
61
+
62
+ throw new \InvalidArgumentException (
63
+ 'Invalid base64 data provided. Expected either data URI format '
64
+ . '(data:[mimeType];base64,[data]) or plain base64 string. '
65
+ );
58
66
}
59
67
60
68
/**
61
69
* Gets the base64-encoded data.
62
70
*
63
71
* @since n.e.x.t
64
72
*
65
- * @return string The base64-encoded data.
73
+ * @return string The plain base64-encoded data (without data URI prefix) .
66
74
*/
67
75
public function getBase64Data (): string
68
76
{
69
77
return $ this ->base64Data ;
70
78
}
71
79
80
+ /**
81
+ * Gets the data as a data URL.
82
+ *
83
+ * @since n.e.x.t
84
+ *
85
+ * @return string The data URL in format: data:[mimeType];base64,[data].
86
+ */
87
+ public function getDataUrl (): string
88
+ {
89
+ return sprintf ('data:%s;base64,%s ' , (string ) $ this ->mimeType , $ this ->base64Data );
90
+ }
91
+
72
92
/**
73
93
* {@inheritDoc}
74
94
*
@@ -88,4 +108,33 @@ public static function getJsonSchema(): array
88
108
'required ' => ['mimeType ' , 'base64Data ' ],
89
109
];
90
110
}
111
+
112
+ /**
113
+ * Parses and validates the MIME type.
114
+ *
115
+ * @since n.e.x.t
116
+ *
117
+ * @param MimeType|string|null $providedMimeType The explicitly provided MIME type.
118
+ * @param string|null $extractedMimeType The MIME type extracted from data URI.
119
+ * @return MimeType The parsed MIME type.
120
+ */
121
+ private function parseMimeType ($ providedMimeType , ?string $ extractedMimeType = null ): MimeType
122
+ {
123
+ // Prefer explicitly provided MIME type
124
+ if ($ providedMimeType instanceof MimeType) {
125
+ return $ providedMimeType ;
126
+ }
127
+
128
+ if ($ providedMimeType !== null ) {
129
+ return new MimeType ($ providedMimeType );
130
+ }
131
+
132
+ // Use extracted MIME type from data URI
133
+ if ($ extractedMimeType !== null ) {
134
+ return new MimeType ($ extractedMimeType );
135
+ }
136
+
137
+ // RFC 2397: if mediatype is omitted in data URI, defaults to text/plain
138
+ return new MimeType ('text/plain ' );
139
+ }
91
140
}
0 commit comments