PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.2.2
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.2.2
3.5.9 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 10 months ago feedback.php 10 months ago function.php 8 months ago image.php 8 months ago parameter.php 1 year ago text.php 8 months ago transcribe.php 8 months ago
dropped-file.php
206 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' ) {
69 throw new Exception( 'AI Engine: The file purpose can only be assistant, vision or files.' );
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 // For refId, fetch the URL from database and load the file
98 global $mwai_core;
99 $url = $mwai_core->files->get_url( $this->data );
100 if ( empty( $url ) ) {
101 throw new Exception( 'AI Engine: Could not find file URL for refId: ' . $this->data );
102 }
103 // Validate URL scheme to prevent SSRF attacks
104 $parts = wp_parse_url( $url );
105 if ( ! isset( $parts['scheme'] ) || ! in_array( $parts['scheme'], [ 'http', 'https' ], true ) ) {
106 throw new Exception( 'Invalid URL scheme; only HTTP/HTTPS allowed.' );
107 }
108 $this->rawData = file_get_contents( $url );
109 return $this->rawData;
110 }
111 else if ( $this->type === 'url' ) {
112 // Validate URL scheme to prevent SSRF attacks
113 $parts = wp_parse_url( $this->data );
114 if ( ! isset( $parts['scheme'] ) || ! in_array( $parts['scheme'], [ 'http', 'https' ], true ) ) {
115 throw new Exception( 'Invalid URL scheme; only HTTP/HTTPS allowed.' );
116 }
117
118 $this->rawData = file_get_contents( $this->data );
119 return $this->rawData;
120 }
121 else if ( $this->type === 'data' ) {
122 return $this->data;
123 }
124 throw new Exception( 'AI Engine: The file is not data or an URL.' );
125 }
126
127 public function get_data() {
128 if ( $this->type === 'provider_file_id' ) {
129 // Provider file IDs are just references, no data loading needed
130 throw new Exception( 'AI Engine: Cannot get data for provider file ID. Use get_refId() instead.' );
131 }
132 if ( $this->type === 'refId' || $this->type === 'url' ) {
133 return $this->get_raw_data();
134 }
135 else if ( $this->type === 'data' ) {
136 return $this->data;
137 }
138 throw new Exception( 'AI Engine: The file is not data or an URL.' );
139 }
140
141 public function get_base64() {
142 $data = $this->get_raw_data();
143 return base64_encode( $data );
144 }
145
146 // Will return something like "data:image/jpeg;base64,{data}"
147 public function get_inline_base64_url() {
148 $b64 = $this->get_base64();
149 return "data:{$this->mimeType};base64,{$b64}";
150 }
151
152 public function get_type() {
153 return $this->type;
154 }
155
156 public function get_purpose() {
157 return $this->purpose;
158 }
159
160 public function get_mimeType() {
161 return $this->mimeType;
162 }
163
164 public function is_image() {
165 return strpos( $this->mimeType, 'image' ) !== false;
166 }
167
168 public function get_fileId() {
169 return $this->fileId;
170 }
171
172 public function get_refId() {
173 if ( $this->type === 'refId' || $this->type === 'provider_file_id' ) {
174 return $this->data;
175 }
176 return null;
177 }
178
179 // Return a filename for this file. If the file is an URL, use the basename of
180 // its path. If the file is raw data, generate a generic name based on the mime type.
181 public function get_filename() {
182 // If we have an original path (from from_path), use its basename
183 if ( !empty( $this->originalPath ) ) {
184 return basename( $this->originalPath );
185 }
186 if ( $this->type === 'refId' ) {
187 global $mwai_core;
188 $path = $mwai_core->files->get_path( $this->data );
189 return basename( $path );
190 }
191 if ( $this->type === 'url' ) {
192 $path = parse_url( $this->data, PHP_URL_PATH );
193 return basename( $path );
194 }
195 if ( $this->type === 'data' ) {
196 if ( !empty( $this->mimeType ) ) {
197 $parts = explode( '/', $this->mimeType );
198 $ext = end( $parts );
199 return 'file.' . $ext;
200 }
201 return 'file.bin';
202 }
203 return 'file';
204 }
205 }
206