Search code examples
phpwordpresswordpress-rest-apiwp-mail

WordPress API REST send mail with attachement send in HTTP request


I'm trying to send an email from the WordPress REST API. This email has some file attached to it, that are sent from a JavaScript front end. I can get the data and the file, but I can't attach those files to the mail, it returns me this error :

Fatal error: Uncaught TypeError: preg_match(): Argument #2 ($subject) must be of type string, array given in /var/www/html/wp-includes/PHPMailer/PHPMailer.php:1853
Stack trace:
#0 /var/www/html/wp-includes/PHPMailer/PHPMailer.php(1853): preg_match('#^[a-z][a-z\\d+....', Array)
#1 /var/www/html/wp-includes/PHPMailer/PHPMailer.php(1865): PHPMailer\PHPMailer\PHPMailer::isPermittedPath(Array)
#2 /var/www/html/wp-includes/PHPMailer/PHPMailer.php(3193): PHPMailer\PHPMailer\PHPMailer::fileIsAccessible(Array)
#3 /var/www/html/wp-includes/pluggable.php(522): PHPMailer\PHPMailer\PHPMailer->addAttachment(Array)
#4 /var/www/html/wp-content/plugins/my-project/views/API/email.php(100): wp_mail(Array, 'Demande de fina...', '\n\t<h1>Demande d...', Array, Array)
#5 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(1171): financement_email(Object(WP_REST_Request))
#6 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(1018): WP_REST_Server->respond_to_request(Object(WP_REST_Request), '/my-project/fin...', Array, NULL)
#7 /var/www/html/wp-includes/rest-api/class-wp-rest-server.php(442): WP_REST_Server->dispatch(Object(WP_REST_Request))
#8 /var/www/html/wp-includes/rest-api.php(410): WP_REST_Server->serve_request('/my-project/fin...')
#9 /var/www/html/wp-includes/class-wp-hook.php(308): rest_api_loaded(Object(WP))
#10 /var/www/html/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters('', Array)
#11 /var/www/html/wp-includes/plugin.php(565): WP_Hook->do_action(Array)
#12 /var/www/html/wp-includes/class-wp.php(399): do_action_ref_array('parse_request', Array)
#13 /var/www/html/wp-includes/class-wp.php(780): WP->parse_request('')
#14 /var/www/html/wp-includes/functions.php(1332): WP->main('')
#15 /var/www/html/wp-blog-header.php(16): wp()
#16 /var/www/html/index.php(17): require('/var/www/html/w...')
#17 {main}
  thrown in /var/www/html/wp-includes/PHPMailer/PHPMailer.php on line 1853

I get the files like this :

$files = $request->get_file_params();

I call the wp_mail function like this :

wp_mail( $to, $subject, $body, $headers, $files)

Solution

  • The fifth parameter to wp_mail expects only an array of absolute file paths.

    get_file_params() is basically a pass-through to the global $_FILES which contains an array of arrays with known keys, including tmp_name, which should be the absolute path on disk that the file temporarily lives.

    You should be able to use array_column to get an array of just absolute paths.

    $cleanFiles = array_column($files, 'tmp_name');
    

    Demo: https://3v4l.org/FS1kV