PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.1.1
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.1.1
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 / modules / files.php
ai-engine / classes / modules Last commit date
chatbot.php 2 years ago discussions.php 2 years ago files.php 2 years ago security.php 2 years ago utilities.php 2 years ago
files.php
248 lines
1 <?php
2
3 class Meow_MWAI_Modules_Files {
4 private $core = null;
5 private $wpdb = null;
6 private $namespace = 'mwai-ui/v1';
7 private $db_check = false;
8 private $table_files = null;
9
10 public function __construct( $core ) {
11 global $wpdb;
12 $this->core = $core;
13 $this->wpdb = $wpdb;
14 $this->table_files = $this->wpdb->prefix . 'mwai_files';
15 add_action( 'rest_api_init', [ $this, 'rest_api_init' ] );
16 if ( !wp_next_scheduled( 'mwai_files_cleanup' ) ) {
17 wp_schedule_event( time(), 'hourly', 'mwai_files_cleanup' );
18 }
19 add_action( 'mwai_files_cleanup', [ $this, 'cleanup_expired_files' ] );
20 }
21
22 public function cleanup_expired_files() {
23 if ( $this->check_db() ) {
24 $current_time = current_time( 'mysql' );
25 $expired_files = $this->wpdb->get_results(
26 "SELECT * FROM $this->table_files WHERE expires IS NOT NULL AND expires < '{$current_time}'"
27 );
28 }
29 $expired_posts = get_posts( [
30 'post_type' => 'attachment',
31 'meta_key' => '_mwai_file_expires',
32 'meta_value' => $current_time,
33 'meta_compare' => '<'
34 ] );
35 $fileIds = [];
36 foreach ( $expired_files as $file ) {
37 $fileIds[] = $file->fileId;
38 }
39 foreach ( $expired_posts as $post ) {
40 $fileIds[] = get_post_meta( $post->ID, '_mwai_file_id', true );
41 }
42 $this->files_processed( $fileIds );
43 }
44
45 public function files_processed( $fileIds ) {
46 if ( !is_array( $fileIds ) ) {
47 $fileIds = [ $fileIds ];
48 }
49 foreach ( $fileIds as $fileId ) {
50 $file = null;
51 if ( $this->check_db() ) {
52 $file = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT *
53 FROM $this->table_files
54 WHERE fileId = %s", $fileId
55 ) );
56 }
57 if ( $file ) {
58 $this->wpdb->delete( $this->table_files, [ 'fileId' => $fileId ] );
59 if ( file_exists( $file->path ) ) {
60 unlink( $file->path );
61 }
62 }
63 else {
64 $posts = get_posts( [ 'post_type' => 'attachment', 'meta_key' => '_mwai_file_id', 'meta_value' => $fileId ] );
65 if ( $posts ) {
66 foreach ( $posts as $post ) {
67 wp_delete_attachment( $post->ID, true );
68 }
69 }
70 }
71 }
72 }
73
74 public function get_path( $fileId ) {
75 $file = null;
76 if ( $this->check_db() ) {
77 $file = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT *
78 FROM $this->table_files
79 WHERE fileId = %s", $fileId
80 ) );
81 }
82 if ( $file ) {
83 return $file->path;
84 }
85 else {
86 $posts = get_posts( [ 'post_type' => 'attachment', 'meta_key' => '_mwai_file_id', 'meta_value' => $fileId ] );
87 if ( $posts ) {
88 foreach ( $posts as $post ) {
89 return get_attached_file( $post->ID );
90 }
91 }
92 }
93 return null;
94 }
95
96 public function get_base64_data( $fileId ) {
97 $path = $this->get_path( $fileId );
98 if ( $path ) {
99 $content = file_get_contents( $path );
100 $data = base64_encode( $content );
101 return $data;
102 }
103 return null;
104 }
105
106 public function get_url( $fileId ) {
107 $file = null;
108 if ( $this->check_db() ) {
109 $file = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT *
110 FROM $this->table_files
111 WHERE fileId = %s", $fileId
112 ) );
113 }
114 if ( $file ) {
115 return $file->url;
116 }
117 else {
118 $posts = get_posts( [ 'post_type' => 'attachment', 'meta_key' => '_mwai_file_id', 'meta_value' => $fileId ] );
119 if ( $posts ) {
120 foreach ( $posts as $post ) {
121 return wp_get_attachment_url( $post->ID );
122 }
123 }
124 }
125 return null;
126 }
127
128 #region REST endpoints
129
130 public function rest_api_init() {
131 register_rest_route( $this->namespace, '/files/upload', array(
132 'methods' => 'POST',
133 'callback' => array( $this, 'rest_upload' ),
134 'permission_callback' => array( $this->core, 'check_rest_nonce' )
135 ) );
136 register_rest_route( $this->namespace, '/files/delete', array(
137 'methods' => 'POST',
138 'callback' => array( $this, 'rest_delete' ),
139 'permission_callback' => array( $this->core, 'check_rest_nonce' )
140 ) );
141 }
142
143 public function rest_upload() {
144 require_once( ABSPATH . 'wp-admin/includes/image.php' );
145 require_once( ABSPATH . 'wp-admin/includes/file.php' );
146 require_once( ABSPATH . 'wp-admin/includes/media.php' );
147 $file = $_FILES['file'];
148 $error = null;
149 if ( empty( $file ) ) {
150 return new WP_REST_Response( [ 'success' => false, 'message' => 'No file provided.' ], 400 );
151 }
152
153 // File validation by WordPress Media Library
154 $fileTypeCheck = wp_check_filetype_and_ext( $file['tmp_name'], $file['name'] );
155 if ( !$fileTypeCheck['type'] ) {
156 return new WP_REST_Response( [ 'success' => false, 'message' => 'Invalid file type.' ], 400 );
157 }
158
159 $local_upload = $this->core->get_option( 'image_local_upload' );
160 $image_expires_seconds = $this->core->get_option( 'image_expires' );
161 $expires = ( empty( $image_expires_seconds ) || $image_expires_seconds === 'never' ) ? null :
162 date( 'Y-m-d H:i:s', time() + $image_expires_seconds );
163 $fileId = null;
164 $url = null;
165 if ( $local_upload === 'uploads' ) {
166 if ( !$this->check_db() ) {
167 return new WP_REST_Response( [ 'success' => false, 'message' => 'Could not create database table.' ], 500 );
168 }
169 $extension = pathinfo( $file['name'], PATHINFO_EXTENSION );
170 $randomFileName = wp_generate_password( 20, false ) . '.' . $extension;
171 $upload_dir = wp_upload_dir();
172 $path = $upload_dir['path'] . '/' . $randomFileName;
173 $filename = wp_unique_filename( $upload_dir['path'], $randomFileName );
174 $path = $upload_dir['path'] . '/' . $filename;
175 if ( !move_uploaded_file( $file['tmp_name'], $path ) ) {
176 return new WP_REST_Response( [ 'success' => false, 'message' => 'Could not move the file.' ], 500 );
177 }
178 $url = $upload_dir['url'] . '/' . $filename;
179 $fileId = md5( $url );
180 $this->wpdb->insert( $this->table_files, [
181 'fileId' => $fileId,
182 'type' => 'image',
183 'status' => 'uploaded',
184 'created' => date( 'Y-m-d H:i:s' ),
185 'updated' => date( 'Y-m-d H:i:s' ),
186 'expires' => $expires,
187 'path' => $path,
188 'url' => $url
189 ]);
190 }
191 else if ( $local_upload === 'library' ) {
192 $id = media_handle_upload( 'file', 0 );
193 if ( is_wp_error( $id ) ) {
194 $error = $id->get_error_message();
195 return new WP_REST_Response([ 'success' => false, 'message' => $error ], 500);
196 }
197 $url = wp_get_attachment_url( $id );
198 $fileId = md5( $url );
199 update_post_meta( $id, '_mwai_file_id', $fileId );
200 update_post_meta( $id, '_mwai_file_expires', $expires );
201 }
202 return new WP_REST_Response( [
203 'success' => true,
204 'data' => [ 'id' => $fileId, 'url' => $url ]
205 ], 200 );
206 }
207
208 #endregion
209
210 #region Database functions
211
212 function create_db() {
213 $charset_collate = $this->wpdb->get_charset_collate();
214 $sql = "CREATE TABLE $this->table_files (
215 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
216 fileId VARCHAR(64) NOT NULL,
217 type VARCHAR(32) NULL,
218 status VARCHAR(32) NULL,
219 created DATETIME NOT NULL,
220 updated DATETIME NOT NULL,
221 expires DATETIME NULL,
222 path TEXT NOT NULL,
223 url TEXT NULL,
224 metadata TEXT NULL,
225 PRIMARY KEY (id),
226 UNIQUE KEY unique_file_id (fileId)
227 ) $charset_collate;";
228 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
229 dbDelta( $sql );
230 }
231
232 function check_db() {
233 if ( $this->db_check ) {
234 return true;
235 }
236 $sql = $this->wpdb->prepare( "SHOW TABLES LIKE %s", $this->table_files );
237 $table_exists = strtolower( $this->wpdb->get_var( $sql )) === strtolower( $this->table_files );
238 if ( !$table_exists ) {
239 $this->create_db();
240 $table_exists = strtolower( $this->wpdb->get_var( $sql ) ) === strtolower( $this->table_files );
241 }
242 $this->db_check = $table_exists;
243 return $this->db_check;
244 }
245
246 #endregion
247
248 }