PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.2.7
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.2.7
3.5.8 3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.9 3.4.8 3.4.7 0.2.1 1.6.91 0.2.2 1.6.92 0.2.3 1.6.93 0.2.4 1.6.94 0.2.5 1.6.95 0.2.6 1.6.96 0.2.7 1.6.97 0.2.8 1.6.98 0.2.9 1.6.99 0.3.0 1.7.0 0.3.1 1.7.1 0.3.2 1.7.2 0.3.3 1.7.3 0.3.4 1.7.4 0.3.5 1.7.5 0.3.6 1.7.6 0.4.0 1.7.7 0.4.1 1.7.8 0.4.2 1.7.9 0.4.3 1.8.0 0.4.4 1.8.1 0.4.5 1.8.2 0.4.6 1.8.3 0.4.7 1.8.4 0.4.8 1.8.5 0.4.9 1.8.6 0.5.0 1.8.7 0.5.1 1.8.8 0.5.2 1.8.9 0.5.3 1.9.0 0.5.4 1.9.1 0.5.5 1.9.2 0.5.6 1.9.3 0.5.7 1.9.4 0.5.8 1.9.5 0.5.9 1.9.6 0.6.0 1.9.7 0.6.1 1.9.8 0.6.2 1.9.81 0.6.3 1.9.82 0.6.4 1.9.83 0.6.5 1.9.84 0.6.6 1.9.85 0.6.7 1.9.86 0.6.8 1.9.87 0.6.9 1.9.88 0.7.0 1.9.89 0.7.1 1.9.90 0.7.2 1.9.91 0.7.3 1.9.92 0.7.4 1.9.93 0.7.5 1.9.94 0.7.6 1.9.95 0.7.7 1.9.96 0.7.8 1.9.97 0.7.9 1.9.98 0.8.0 1.9.99 0.8.1 2.0.0 0.8.2 2.0.1 0.8.3 2.0.2 0.8.4 2.0.3 0.8.5 2.0.4 0.8.6 2.0.5 0.8.7 2.0.6 0.8.8 2.0.7 0.8.9 2.0.8 0.9.0 2.0.9 0.9.2 2.1.0 0.9.3 2.1.1 0.9.4 2.1.2 0.9.5 2.1.3 0.9.6 2.1.4 0.9.7 2.1.5 0.9.8 2.1.6 0.9.81 2.1.7 0.9.82 2.1.8 0.9.83 2.1.9 0.9.84 2.2.0 0.9.85 2.2.1 0.9.86 2.2.2 0.9.87 2.2.3 0.9.88 2.2.4 0.9.89 2.2.5 0.9.9 2.2.51 0.9.91 2.2.52 0.9.92 2.2.53 0.9.93 2.2.54 0.9.94 2.2.56 0.9.95 2.2.57 0.9.96 2.2.6 0.9.97 2.2.60 0.9.98 2.2.61 0.9.99 2.2.62 1.0.0 2.2.63 1.0.01 2.2.70 1.0.1 2.2.80 1.0.2 2.2.81 1.0.3 2.2.90 1.0.4 2.2.91 1.0.5 2.2.92 1.0.6 2.2.93 1.0.7 2.2.94 1.0.8 2.2.95 1.0.9 2.3.0 1.1.0 2.3.1 1.1.1 2.3.2 1.1.2 2.3.3 1.1.3 2.3.4 1.1.4 2.3.5 1.1.5 2.3.6 1.1.6 2.3.7 1.1.7 2.3.8 1.1.8 2.3.9 1.1.9 2.4.0 1.2.0 2.4.1 1.2.1 2.4.2 1.2.2 2.4.3 1.2.21 2.4.4 1.2.3 2.4.5 1.2.30 2.4.6 1.3.0 2.4.7 1.3.1 2.4.8 1.3.2 2.4.9 1.3.3 2.5.0 1.3.31 2.5.1 1.3.32 2.5.2 1.3.33 2.5.3 1.3.34 2.5.4 1.3.35 2.5.5 1.3.36 2.5.6 1.3.37 2.5.7 1.3.38 2.5.8 1.3.39 2.5.9 1.3.40 2.6.0 1.3.41 2.6.1 1.3.42 2.6.2 1.3.43 2.6.3 1.3.44 2.6.5 1.3.45 2.6.6 1.3.46 2.6.7 1.3.47 2.6.8 1.3.48 2.6.9 1.3.49 2.7.0 1.3.50 2.7.1 1.3.51 2.7.2 1.3.52 2.7.3 1.3.53 2.7.4 1.3.54 2.7.5 1.3.56 2.7.6 1.3.57 2.7.7 1.3.58 2.7.8 1.3.59 2.7.9 1.3.60 2.8.0 1.3.61 2.8.1 1.3.62 2.8.2 1.3.63 2.8.3 1.3.64 2.8.4 1.3.65 2.8.5 1.3.66 2.8.6 1.3.67 2.8.7 1.3.68 2.8.8 1.3.69 2.8.9 1.3.70 2.9.0 1.3.71 2.9.1 1.3.72 2.9.2 1.3.73 2.9.3 1.3.74 2.9.4 1.3.75 2.9.5 1.3.76 2.9.6 1.3.77 2.9.7 1.3.78 2.9.8 1.3.79 2.9.9 1.3.80 3.0.0 1.3.81 3.0.1 1.3.82 3.0.2 1.3.83 3.0.3 1.3.84 3.0.4 1.3.85 3.0.5 1.3.86 3.0.6 1.3.87 3.0.7 1.3.88 3.0.8 1.3.89 3.0.9 1.3.90 3.1.0 1.3.91 3.1.1 1.3.92 3.1.2 1.3.93 3.1.3 1.3.94 3.1.4 1.3.95 3.1.5 1.3.96 3.1.6 1.3.97 3.1.7 1.3.98 3.1.8 1.3.99 3.1.9 1.4.0 3.2.0 1.4.1 3.2.1 1.4.2 3.2.2 1.4.3 3.2.3 1.4.4 3.2.4 1.4.5 3.2.5 1.4.6 3.2.6 1.4.7 3.2.7 1.4.8 3.2.8 1.4.9 3.2.9 1.5.0 3.3.0 1.5.1 3.3.1 1.5.2 3.3.2 1.5.3 3.3.3 1.5.4 3.3.4 1.5.5 3.3.5 1.5.6 3.3.6 1.5.7 3.3.7 1.5.8 3.3.8 1.5.9 3.3.9 1.6.0 3.4.0 1.6.1 3.4.1 1.6.2 3.4.2 1.6.3 3.4.3 1.6.5 3.4.4 1.6.51 3.4.5 1.6.52 3.4.6 1.6.53 1.6.54 1.6.55 1.6.56 1.6.57 1.6.58 1.6.59 1.6.60 1.6.61 1.6.62 1.6.63 1.6.64 1.6.65 1.6.66 1.6.67 1.6.68 trunk 1.6.69 0.0.1 1.6.70 0.0.2 1.6.71 0.0.3 1.6.72 0.0.4 1.6.73 0.0.5 1.6.74 0.0.6 1.6.75 0.0.7 1.6.76 0.0.8 1.6.77 0.0.9 1.6.78 0.1.0 1.6.79 0.1.1 1.6.81 0.1.2 1.6.82 0.1.3 1.6.83 0.1.4 1.6.84 0.1.5 1.6.85 0.1.6 1.6.86 0.1.7 1.6.87 0.1.8 1.6.88 0.1.9 1.6.89 0.2.0 1.6.90
ai-engine / classes / query / dropped-file.php
ai-engine / classes / query Last commit date
assist-feedback.php 10 months ago assistant.php 8 months ago base.php 8 months ago dropped-file.php 7 months ago edit-image.php 8 months ago embed.php 7 months ago feedback.php 10 months ago function.php 8 months ago image.php 8 months ago parameter.php 1 year ago text.php 7 months ago transcribe.php 8 months ago
dropped-file.php
224 lines
1 <?php
2
3 class Meow_MWAI_Query_DroppedFile {
4 private $data;
5 private $rawData;
6 private $type; // Defines what the data is about ('refId', 'url', or 'data')
7 private $purpose; // Can be 'assistant', 'vision' or 'files' => this needs to be checked
8 private $mimeType; // 'image/jpeg' or any other mime type
9 private $fileId; // The ID of the file in the database
10 public $originalPath; // The original file path (for files loaded from disk)
11
12 public static function from_url( $url, $purpose, $mimeType = null, $fileId = null ) {
13 if ( empty( $mimeType ) ) {
14 $mimeType = Meow_MWAI_Core::get_mime_type( $url );
15 }
16 return new Meow_MWAI_Query_DroppedFile( $url, 'url', $purpose, $mimeType, $fileId );
17 }
18
19 public static function from_data( $data, $purpose, $mimeType = null ) {
20 return new Meow_MWAI_Query_DroppedFile( $data, 'data', $purpose, $mimeType );
21 }
22
23 public static function from_path( $path, $purpose, $mimeType = null ) {
24 // Sanitize path to prevent PHAR deserialization attacks
25 $path = Meow_MWAI_Core::sanitize_file_path( $path );
26 $data = file_get_contents( $path );
27 if ( empty( $mimeType ) ) {
28 $mimeType = Meow_MWAI_Core::get_mime_type( $path );
29 }
30 $droppedFile = new Meow_MWAI_Query_DroppedFile( $data, 'data', $purpose, $mimeType );
31 // Store the original path for filename extraction
32 $droppedFile->originalPath = $path;
33 return $droppedFile;
34 }
35
36 public static function from_refId( $refId, $purpose, $mimeType = null ) {
37 return new Meow_MWAI_Query_DroppedFile( $refId, 'refId', $purpose, $mimeType );
38 }
39
40 /**
41 * Create DroppedFile from provider file_id reference (OpenAI, Anthropic, etc.)
42 *
43 * For PDFs uploaded to provider Files APIs, we only store the file_id
44 * Examples: OpenAI 'file-xxx', Anthropic 'file_xxx'
45 * These are reference-only - the file data lives on the provider's servers
46 * Do NOT try to load file data from these - use get_refId() to get the file_id
47 */
48 public static function from_provider_file_id( $fileId, $purpose, $mimeType = null ) {
49 return new Meow_MWAI_Query_DroppedFile( $fileId, 'provider_file_id', $purpose, $mimeType );
50 }
51
52 /**
53 * @deprecated Use from_provider_file_id() instead
54 * Kept for backward compatibility
55 */
56 public static function from_openai_file_id( $fileId, $purpose, $mimeType = null ) {
57 return self::from_provider_file_id( $fileId, $purpose, $mimeType );
58 }
59
60 public function __construct( $data, $type, $purpose, $mimeType = null, $fileId = null ) {
61 // Support both old 'openai_file_id' and new 'provider_file_id' for backward compatibility
62 if ( $type === 'openai_file_id' ) {
63 $type = 'provider_file_id';
64 }
65 if ( !empty( $type ) && $type !== 'refId' && $type !== 'url' && $type !== 'data' && $type !== 'provider_file_id' ) {
66 throw new Exception( 'AI Engine: The file type can only be refId, url, data, or provider_file_id.' );
67 }
68 if ( !empty( $purpose ) && $purpose !== 'assistant-in' && $purpose !== 'vision' && $purpose !== 'files' && $purpose !== 'transcription' ) {
69 throw new Exception( 'AI Engine: The file purpose can only be assistant, vision, files, or transcription.' );
70 }
71 $this->data = $data;
72 $this->type = $type;
73 $this->purpose = $purpose;
74 $this->mimeType = $mimeType;
75 $this->fileId = $fileId;
76 }
77
78 public function get_url() {
79 if ( $this->type === 'url' ) {
80 return $this->data;
81 }
82 throw new Exception( 'AI Engine: The file is not an URL.' );
83 }
84
85 private function get_raw_data() {
86 if ( !empty( $this->rawData ) ) {
87 return $this->rawData;
88 }
89 if ( $this->type === 'provider_file_id' ) {
90 // Provider file IDs are reference-only (file data lives on provider's servers)
91 // Common mistake: trying to load file data for PDFs in conversation history
92 // Fix: Check file mime type before calling get_data()/get_base64()/get_inline_base64_url()
93 // For PDFs: use get_refId() to get the file_id string instead
94 throw new Exception( 'AI Engine: Cannot get raw data for provider file ID (file_id: ' . $this->data . '). Use get_refId() instead.' );
95 }
96 if ( $this->type === 'refId' ) {
97 global $mwai_core;
98
99 // Prefer loading from disk to avoid HTTP rewrites or CDN issues
100 $path = $mwai_core->files->get_path( $this->data );
101 if ( !empty( $path ) ) {
102 $path = Meow_MWAI_Core::sanitize_file_path( $path );
103 if ( file_exists( $path ) && is_readable( $path ) ) {
104 $data = file_get_contents( $path );
105 if ( $data === false ) {
106 throw new Exception( 'AI Engine: Failed to read file contents for refId: ' . $this->data );
107 }
108 $this->rawData = $data;
109 return $this->rawData;
110 }
111 }
112
113 // Fallback to the public URL if the local path is unavailable
114 $url = $mwai_core->files->get_url( $this->data );
115 if ( empty( $url ) ) {
116 throw new Exception( 'AI Engine: Could not find file URL for refId: ' . $this->data );
117 }
118 $parts = wp_parse_url( $url );
119 if ( ! isset( $parts['scheme'] ) || ! in_array( $parts['scheme'], [ 'http', 'https' ], true ) ) {
120 throw new Exception( 'Invalid URL scheme; only HTTP/HTTPS allowed.' );
121 }
122 $data = file_get_contents( $url );
123 if ( $data === false ) {
124 throw new Exception( 'AI Engine: Failed to download file contents for refId: ' . $this->data );
125 }
126 $this->rawData = $data;
127 return $this->rawData;
128 }
129 else if ( $this->type === 'url' ) {
130 // Validate URL scheme to prevent SSRF attacks
131 $parts = wp_parse_url( $this->data );
132 if ( ! isset( $parts['scheme'] ) || ! in_array( $parts['scheme'], [ 'http', 'https' ], true ) ) {
133 throw new Exception( 'Invalid URL scheme; only HTTP/HTTPS allowed.' );
134 }
135
136 $this->rawData = file_get_contents( $this->data );
137 return $this->rawData;
138 }
139 else if ( $this->type === 'data' ) {
140 return $this->data;
141 }
142 throw new Exception( 'AI Engine: The file is not data or an URL.' );
143 }
144
145 public function get_data() {
146 if ( $this->type === 'provider_file_id' ) {
147 // Provider file IDs are just references, no data loading needed
148 throw new Exception( 'AI Engine: Cannot get data for provider file ID. Use get_refId() instead.' );
149 }
150 if ( $this->type === 'refId' || $this->type === 'url' ) {
151 return $this->get_raw_data();
152 }
153 else if ( $this->type === 'data' ) {
154 return $this->data;
155 }
156 throw new Exception( 'AI Engine: The file is not data or an URL.' );
157 }
158
159 public function get_base64() {
160 $data = $this->get_raw_data();
161 return base64_encode( $data );
162 }
163
164 // Will return something like "data:image/jpeg;base64,{data}"
165 public function get_inline_base64_url() {
166 $b64 = $this->get_base64();
167 return "data:{$this->mimeType};base64,{$b64}";
168 }
169
170 public function get_type() {
171 return $this->type;
172 }
173
174 public function get_purpose() {
175 return $this->purpose;
176 }
177
178 public function get_mimeType() {
179 return $this->mimeType;
180 }
181
182 public function is_image() {
183 return strpos( $this->mimeType, 'image' ) !== false;
184 }
185
186 public function get_fileId() {
187 return $this->fileId;
188 }
189
190 public function get_refId() {
191 if ( $this->type === 'refId' || $this->type === 'provider_file_id' ) {
192 return $this->data;
193 }
194 return null;
195 }
196
197 // Return a filename for this file. If the file is an URL, use the basename of
198 // its path. If the file is raw data, generate a generic name based on the mime type.
199 public function get_filename() {
200 // If we have an original path (from from_path), use its basename
201 if ( !empty( $this->originalPath ) ) {
202 return basename( $this->originalPath );
203 }
204 if ( $this->type === 'refId' ) {
205 global $mwai_core;
206 $path = $mwai_core->files->get_path( $this->data );
207 return basename( $path );
208 }
209 if ( $this->type === 'url' ) {
210 $path = parse_url( $this->data, PHP_URL_PATH );
211 return basename( $path );
212 }
213 if ( $this->type === 'data' ) {
214 if ( !empty( $this->mimeType ) ) {
215 $parts = explode( '/', $this->mimeType );
216 $ext = end( $parts );
217 return 'file.' . $ext;
218 }
219 return 'file.bin';
220 }
221 return 'file';
222 }
223 }
224