wp_mail not working in acf/pre_save_post or acf/save_post - advanced-custom-fields

I am trying to send a confirmation email once the user has used the form I am creating via acf.
Below is the code I am using in a plugin, but somehow the wp_email is not sending an email. Not receiving it, nor did I receive an error.
function my_pre_save_post( $post_id ) {
// check if this is to be a new post
if( $post_id != 'new_post' ) {
return $post_id;
}
// Create a new post
$post = array(
'id' => $post_id,
'post_status' => 'publish',
'post_title' => $_POST['acf']['_post_title'],
'email' => $_POST['acf']['field_5d49dcb49a31f'],
'bedrag' => $_POST['acf']['field_5d49dd749a321'],
'periodiek' => $_POST['acf']['field_5d49de569a322'],
);
// // insert the post
$post_id = wp_insert_post( $post );
add_filter( 'wp_mail_content_type', 'wpdocs_set_html_mail_content_type' );
$name = get_field('post_title', $post_id);
$email = get_field('email', $post_id);
$body_text = get_field('email_tekst', 'option');
$to = $name . ' <' . $email . '>' . "\r\n";
$headers = array('Content-Type: text/html; charset=UTF-8', 'From: Some name <info#somedomain.com> <noreply#'.$_SERVER['HTTP_HOST'].'>');
$subject = 'Bedankt voor uw donatie: ' . get_field('bedrag', $post_id) . ' ' . get_field('periodiek', $post_id);
$body = $body_text;
wp_mail($to, $subject, $body, $headers );
remove_filter( 'wp_mail_content_type', 'wpdocs_set_html_mail_content_type' );
// return the new ID
return $post_id;
}
add_filter('acf/pre_save_post' , 'my_pre_save_post');
Save the form works, as I see data in the backend.
But I am just not receiving the email.
To make sure that emails are send, I am using a plugin (wp mail smtp).
Do I miss anything?

Ok, I know what was going wrong.
I didn’t used the correct priority.
Now using the following code:
function wpdocs_set_html_mail_content_type() {
return 'text/html';
}
add_action('acf/save_post' , 'my_save_post', 15);
function my_save_post($post_id) {
if( get_post_type($post_id) !== 'donations' ) {
return;
}
add_filter( 'wp_mail_content_type', 'wpdocs_set_html_mail_content_type' );
$name = get_field('post_title', $post_id);
$email = get_field('email', $post_id);
$body_text = get_field('email_tekst', 'option');
$to = $email;
$headers = array('From: some name <some email> <noreply#'.$_SERVER['HTTP_HOST'].'>');
$subject = 'Bedankt voor uw donatie: ' . get_field('bedrag', $post_id) . ' ' . get_field('periodiek', $post_id);
$message = $body_text;
wp_mail($to, $subject, $message, $headers );
remove_filter( 'wp_mail_content_type', 'wpdocs_set_html_mail_content_type' );
}
The priority is now 15, so runs after the save was done.

Related

Post a not empty file to Dspace with Curl

I am posting a file to dspace through dspace api, I am doing this with an action in php. With postman I send a form-data with the file, filename, bitstream id and token.
I am getting the temp file path with $_FILES and sending it by postfields curl option, but the file uploads empty, or with weird data, without its content.
public function actionSubirBitstream()
{
if (Yii::$app->request->isPost) {
$body = $_POST;
$prefijo = '/rest/items/';
$host = ConfiguracionDspace::find()->where("clave='host'")->one()->valor;
$puerto = ConfiguracionDspace::find()->where("clave='puerto'")->one()->valor;
$token = $body['token'];
$id = $body['id'];
$final = '/bitstreams';
$name = $body['name'];//nombre del archivo sin espacios
$params = "?name=$name";
$url = $host . ':' . $puerto . $prefijo . $id . $final . $params;
$file = $_FILES['file']['tmp_name'];
//$path = $body['path'];
//$file = new CURLFILE("$path");
$headers = array("Content-Type: application/json", 'Accept: application/json', "rest-dspace-token: " . $token);
$curl = curl_init($url);
$options = array(
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => array('file'=> $file,'name' => $name),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers
);
curl_setopt_array($curl, $options);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS => array('photo'=> new CURLFILE('/C:/Users/pfile3.jpeg'),'name' => $name),
this is the example of uploading a file with form key as photo and another key name
in your screen shot you have id and token in form data but in code its not inside POSTFIELDS
in postman you can generate equalent code of request in any language , try generating the PHP equalent code and see if it works:
To do this just click code link under the request url after saving the request
I already post the file by the $_FILE variable, But what I needed to do was to use CURLFILE to create a new file, and give it the temp path of the file in the server
$file = $_FILES['file']['tmp_name'];
and this in the postfields
CURLOPT_POSTFIELDS => array('file'=> new CURLFile("$file"),'name' => $name),
Thanks for the help friends
Here the code:
public function actionSubirBitstream()
{
if (Yii::$app->request->isPost) {
$body = $_POST;
$prefijo = '/rest/items/';
$host = ConfiguracionDspace::find()->where("clave='host'")->one()->valor;
$puerto = ConfiguracionDspace::find()->where("clave='puerto'")->one()->valor;
$token = $body['token'];
$id = $body['id'];
$final = '/bitstreams';
$name = $body['name'];//nombre del archivo sin espacios
$params = "?name=$name";
$url = $host . ':' . $puerto . $prefijo . $id . $final . $params;
$file = $_FILES['file']['tmp_name'];
//$path = $body['path'];
//$file = new CURLFILE("$path");
$headers = array("Content-Type: application/json", 'Accept: application/json', "rest-dspace-token: " . $token);
$curl = curl_init($url);
$options = array(
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => array('file'=> new CURLFile("$file"),'name' => $name),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $headers
);
curl_setopt_array($curl, $options);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}
The posted files with the rigth size(finally)
The form data I send by Postman, no need to use the field path

Array to string conversion C:\xampp\htdocs\8990API\register.php

As a beginner ionic dev I really don't have enough knowledge about the back-end especially arrays. I hope you guys takes time to answer this.
register.php
<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
// Access-Control headers are received during OPTIONS requests
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
require "dbconnect.php";
$data = file_get_contents("php://input");
if (isset($data)) {
$request = json_decode($data);
$firstname = $request->firstname;
$lastname = $request->lastname;
$username = $request->username;
$userrole = $request->userrole;
$userpass = $request->userpass;
}
$firstname = stripslashes($firstname);
$userpass = stripslashes($userpass);
$userpass = sha1($userpass."#la]#}^(dy*%-Ga=/,Ga!.");
$sql = "INSERT INTO useraccount (firstname, lastname, username, userrole, userpass)
VALUES ('$firstname', '$lastname', '$username', '$userrole', '$userpass')";
if ($con->query($sql) === TRUE) {
$status = "success";
$message = "New account created successfully";
}
else {
$status = "fail";
$message = "Error: " . $sql . "<br>" . $con->error;
}
echo json_encode(array('status' => $status, 'message' => $message, 'data' => $data));
?>
One of those variables in your VALUES clause ($userrole) is actually an array of values. You need to either select one of them:
VALUES ('$firstname', '$lastname', '$username', '$userrole[0]', '$userpass')";
or find some way to convert the array to a string e.g. using implode:
VALUES ('$firstname', '$lastname', '$username', '" . implode(',', $userrole) . "', '$userpass')";

ACF filter custom posts by subfield of repeater field

I'm following the official guide in ACF documentation but hasn't been able to get it right. I'm using Advanced custom fields and Custom post type UI plugins.
I have a custom post type named materials, each material has a files repeater field, one of the subfield is title. I want to query the posts based on the title and put the results onto the page using ajax.
Here's my functions.php:
function materialsSearchAjax() {
$html = "";
$keyword = $_POST['keyword'];
// args
$args = array(
'numberposts' => -1,
'posts_per_page' => -1,
'post_type' => 'materials',
'meta_key' => 'type',
'meta_value' => 'students',
'meta_query' =>
array(
'key' => 'files_%_title',
'compare' => 'LIKE',
'value' => $keyword,
)
);
$query = new WP_Query( $args );
$posts = array();
$html .= '<div class="Materials-students">';
while( $query->have_posts() ) : $query->the_post();
$html .= '<div class="Files-list u-padding-left--12">';
if( have_rows('files') ){
while ( have_rows('files') ) : the_row();
$html .= '<div class="Files-item u-margin-right--30 u-margin-bottom--18">';
$html .= '<div class="Files-itemImage"></div>';
$html .= '<a href="' . the_sub_field("document") . '" target="_blank" class="Files-itemLink">';
$html .= the_sub_field('title');
$html .= '</a>';
$html .= '</div>';
endwhile;
}
$html .= '</div>';
endwhile;
$html .= '</div>';
wp_reset_query();
return $html;
}
// filter
function materials_where( $where ) {
$where = str_replace("meta_key = 'files_%", "meta_key LIKE 'files_%", $where);
return $where;
}
function igs_scripts_styles() {
wp_enqueue_script( 'ajaxMaterialsSearch', get_template_directory_uri() . '/assets/scripts/ajaxMaterialsSearch.js', array(), false, true );
wp_localize_script( 'ajaxMaterialsSearch', 'ajax_data_object', array( 'url' => admin_url( 'admin-ajax.php' )) );
}
add_action('wp_ajax_nopriv_materialsSearchAjax', 'materialsSearchAjax');
add_action('wp_ajax_materialsSearchAjax', 'materialsSearchAjax');
add_filter('posts_where', 'materials_where');
add_action('wp_enqueue_scripts', 'igs_scripts_styles');
Here's my ajax:
(function($) {
// Trigger submit
$('.Search-magnifier').on('click', function(){
var $form = $(this).parent();
$($form).submit();
});
$('.Search-form').on('submit', function(event){
event.preventDefault();
var $form = $(this);
var searchKeyword = $($form).find('input[type="search"]').val();
console.log('keyword: ' + searchKeyword);
$.ajax({
type: 'POST',
url: ajax_data_object.url,
data: {action: 'materialsSearchAjax', keyword: searchKeyword},
success: function(textStatus) {
// update the content
console.log(textStatus);
$('.Materials-students').replaceWith(textStatus);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
console.log(errorThrown);
}
});
});
})(jQuery);
The ajax and query work fine if I query all the materials post without filtering the title so the only think that's wrong is the query itself. I followed the guide but been stuck for hours.
I guess your only mistake is within the meta_query itself. Besides the (optional) first-level relation, a meta_query has to be an array of array(s). Try:
$args = array(
'posts_per_page' => -1,
'post_type' => 'materials',
'meta_key' => 'type',
'meta_value' => 'students',
'meta_query' => array(
array(
'key' => 'files_%_title',
'compare' => 'LIKE',
'value' => $keyword,
)
)
);
From WP Codex:
meta_query (array) - Contains one or more arrays with the following keys: […]
I replicated your case (except for the Ajax) and the query worked fine, so I guess this should also work over Ajax calls.

Google Chrome notification works, but with wired message

I need your help with Google notifications sending which works correctly but with empty messages, title, message etc. are missing...
Any ideas ?
Here is picture how it looks like:
define( 'API_ACCESS_KEY', 'AIzaSyBBh4ddPa96rQQNxqiq_qQj7sq1JdsNQUQ' );
//$registrationIds = array( $_GET['id'] );
$user_device_key = 'eVuuhJNB3vs:APA91bGyf2iAcDEHMVe8MmYzUmNAVl08tfP4wHQFi0sIMhtlZ9PwljdEfZ8JhtfJ_O0rhXTvdJEiVbeRJaUfWn2qvHG6Gw7OjV2jSCmkUd1HK93dyocyC26_48xb0srxa5imUpqXSxMk';
$payload_info = create_payload_json("I know how to send push notifications!");
// API access key from Google API's Console
define('API_ACCESS_KEY', 'AIzaSyAjcvboyovxihsZBtrs2FmVkFbLs-bNk1k');
// prep the bundle
$msg = array
(
'message' => json_decode($payload_info)->aps->alert,
'title' => 'This is a title. title',
'subtitle' => 'This is a subtitle. subtitle',
'tickerText' => 'Ticker text here...Ticker text here...',
'vibrate' => 1,
'sound' => 1,
'largeIcon' => 'large_icon',
'smallIcon' => 'small_icon'
);
$fields = array
(
'registration_ids' => array($user_device_key),
'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send' );
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, false );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
echo $fields;
$result = curl_exec($ch);
curl_close($ch);
return $result > 0;
function create_payload_json($message) {
//Badge icon to show at users ios app icon after receiving notification
$badge = "0";
$sound = 'default';
$payload = array();
$payload['aps'] = array('alert' => $message, 'badge' => intval($badge),'sound' => $sound);
return json_encode($payload);
}

Using add_filter() inside of WP_Widget::widget()

I'm developing a Widget. I want to show all posts' from the last 30 days. I'll use this snippet (from CODEX) :
// Create a new filtering function that will add our where clause to the query
function filter_where( $where = '' ) {
// posts in the last 30 days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
return $where;
}
add_filter( 'posts_where', 'filter_where' );
$query = new WP_Query( $query_string );
remove_filter( 'posts_where', 'filter_where' );
Now this is my widget class :
class Okunma_Sayisina_Gore_Listele extends WP_Widget {
public function __construct() {
parent::__construct(
'okunma_sayisina_gore_listele', // Base ID
'Okunma_Sayisina_Gore_Listele', // Name
array( 'description' => 'Son n gün içinde yazılmış yazıları okunma sayılarına göre sıralayarak listeler', ) // Args
);
}
public function filter_where( $where = '' ) {
// posts in the last 30 days
$where .= " AND post_date > '" . date('Y-m-d', strtotime('-30 days')) . "'";
return $where;
}
public function widget( $args, $instance ) {
global $wpdb;
extract( $args );
$title = apply_filters( 'widget_title', $instance['title'] );
$n = intval($instance['n']);
echo $before_widget;
if ( ! empty( $title ) )
echo $before_title . $title . $after_title;
/* IT'S NOT WORKING */
add_filter( 'posts_where', array('this','filter_where') );
$posts = get_posts(array(
"number_posts" => $n,
"post_type" => "post",
));
remove_filter( 'posts_where', array('this','filter_where') );
foreach ($posts as $post)
{
echo $post->post_title;
}
echo $after_widget;
}
public function update( $new_instance, $old_instance ) {
...
}
public function form( $instance ) {
...
}
}
add_action( 'widgets_init', create_function( '', 'register_widget( "Okunma_Sayisina_Gore_Listele" );' ) );
Filter isn't working. This widget listing all post, not only from last 30 days.
Also, i tried
add_filter( 'posts_where', array('Okunma_Sayisina_Gore_Listele','filter_where') );
instead of
add_filter( 'posts_where', array('this','filter_where') );
but it is'nt not working, too.
OK, I found answer on Filter Reference . I forget 'suppress_filters' => FALSE .
$posts = get_posts(array(
"number_posts" => 4,
"post_type" => "post",
'suppress_filters' => FALSE
));